Skip to content

Instantly share code, notes, and snippets.

@lehmacdj
Last active August 6, 2019 10:00
Show Gist options
  • Save lehmacdj/b3c897ab46af34574b2947f8dc4e937d to your computer and use it in GitHub Desktop.
Save lehmacdj/b3c897ab46af34574b2947f8dc4e937d to your computer and use it in GitHub Desktop.
Evil mode for nEXT browser
(in-package :next)
(defparenstatic scroll-half-page-down
(ps:chain window (scroll-by 0 (/ (ps:@ window inner-height) 2))))
(defparenstatic scroll-half-page-up
(ps:chain window (scroll-by 0 (/ (ps:@ window inner-height) -2))))
(defparenstatic scroll-page-down
(ps:chain window (scroll-by 0 (ps:@ window inner-height))))
(defparenstatic scroll-page-up
(ps:chain window (scroll-by 0 (- (ps:@ window inner-height)))))
; evil mode replicates all of the history functionality of document-mode
; because it overwrites document mode
(defvar *evil-mode-map* (make-hash-table :test 'equalp))
(defclass evil-mode (mode)
((active-history-node :accessor active-history-node :initarg :active-node)
(link-hints :accessor link-hints)))
(defun evil-mode ()
"Vim-like document-mode replacement"
(let* ((root (make-node :data "about:blank"))
(mode (make-instance 'evil-mode
:name "Evil-Mode"
:keymap *evil-mode-map*
:active-node root)))
mode))
(defmethod setup ((mode evil-mode) buffer)
(call-next-method)
(interface:web-view-set-url-loaded-callback
(view buffer)
(lambda () (add-or-traverse-history mode))))
;; insert-mode does almost nothing and should be enabled to interact with
;; web-pages using the keyboard
(defvar *insert-mode-map* (make-hash-table :test 'equalp))
(defclass insert-mode (mode) ())
(defun insert-mode ()
"Vim-like application mode, with some maps for changing modes back"
(make-instance 'insert-mode
:name "Insert-Mode"
:keymap *insert-mode-map*))
; interface
(define-key *evil-mode-map*
(kbd "Z Z")
'interface:kill)
;; use this because nEXT users definitely expect this at least
(define-key *evil-mode-map*
(kbd "C-x C-c")
'interface:kill)
; navigation
(define-key *evil-mode-map*
(kbd "j")
'scroll-down)
(define-key *evil-mode-map*
(kbd "k")
'scroll-up)
(define-key *evil-mode-map*
(kbd "l")
'scroll-right)
(define-key *evil-mode-map*
(kbd "h")
'scroll-left)
(define-key *evil-mode-map*
(kbd "G")
'scroll-to-bottom)
(define-key *evil-mode-map*
(kbd "g g")
'scroll-to-top)
(define-key *evil-mode-map*
(kbd "d")
'scroll-half-page-down)
(define-key *evil-mode-map*
(kbd "u")
'scroll-half-page-up)
; zoom
(define-key *evil-mode-map*
(kbd "z i")
'zoom-in-page)
(define-key *evil-mode-map*
(kbd "z o")
'zoom-out-page)
(define-key *evil-mode-map*
(kbd "z 0")
'unzoom-page)
; buffer navigation
(define-key *evil-mode-map*
(kbd "g t")
'switch-buffer-next)
(define-key *evil-mode-map*
(kbd "L")
'history-forwards)
(define-key *evil-mode-map*
(kbd "H")
'history-backwards)
(define-key *evil-mode-map*
(kbd "J")
'switch-buffer-next)
(define-key *evil-mode-map*
(kbd "K")
'switch-buffer-previous)
(define-key *evil-mode-map*
(kbd "g T")
'switch-buffer-previous)
(define-key *evil-mode-map*
(kbd "x")
'delete-active-buffer)
(define-key *evil-mode-map*
(kbd "B")
(:input-complete *minibuffer* switch-buffer buffer-complete))
(define-key *evil-mode-map*
(kbd "o")
(:input-complete *minibuffer* set-url history-typed-complete :empty-complete t))
(define-key *evil-mode-map*
(kbd "t")
(:input-complete *minibuffer* set-url-new-buffer history-typed-complete :empty-complete t))
(define-key *evil-mode-map*
(kbd "b")
(:input-complete *minibuffer* set-url bookmark-complete))
; link-hints
(define-key *evil-mode-map* (kbd "f") (:input *minibuffer* go-anchor :setup #'setup-anchor :cleanup #'remove-link-hints))
(define-key *evil-mode-map*
(kbd "F")
(:input *minibuffer* go-anchor-new-buffer :setup #'setup-anchor :cleanup #'remove-link-hints))
(define-key *evil-mode-map*
(kbd "g f")
(:input *minibuffer* go-anchor-new-buffer-focus :setup #'setup-anchor))
; mode switching
(define-key *evil-mode-map* (kbd "i")
(lambda () (add-or-switch-to-mode *active-buffer* (insert-mode))))
(define-key *insert-mode-map* (kbd "C-[")
(lambda () (add-or-switch-to-mode *active-buffer* (evil-mode))))
(define-key *insert-mode-map* (kbd "ESCAPE")
(lambda () (add-or-switch-to-mode *active-buffer* (evil-mode))))
; overwrite the generator for document mode to replace it with evil-mode
(defun document-mode () (evil-mode))
@charlesdaniels
Copy link

Fails on next version 1.1.0 built from source under OpenBSD 6.4. Unfortunately, I'm not familiar with lisp to provide much insight beyond uploading the error log.


; file: /home/cad/.config/next/init.lisp
; in: DEFUN EVIL-MODE
;     (NEXT::MAKE-NODE :DATA "about:blank")
; 
; caught STYLE-WARNING:
;   undefined function: MAKE-NODE
; 
; compilation unit finished
;   Undefined function:
;     MAKE-NODE
;   caught 1 STYLE-WARNING condition
Unhandled SB-C::INPUT-ERROR-IN-LOAD:
  READ error during LOAD:

    Package INTERFACE does not exist.

      Line: 33, Column: -1, File-Position: 1179

      Stream: #<SB-INT:FORM-TRACKING-STREAM for "file /home/cad/.config/next/init.lisp" {1003962FF3}>

Backtrace for: #<SB-THREAD:THREAD "main thread" RUNNING {10005E85B3}>
0: (SB-DEBUG::DEBUGGER-DISABLED-HOOK #<SB-C::INPUT-ERROR-IN-LOAD {10039CDA93}> #<unused argument> :QUIT T)
1: (SB-DEBUG::RUN-HOOK SB-EXT:*INVOKE-DEBUGGER-HOOK* #<SB-C::INPUT-ERROR-IN-LOAD {10039CDA93}>)
2: (INVOKE-DEBUGGER #<SB-C::INPUT-ERROR-IN-LOAD {10039CDA93}>)
3: (UIOP/IMAGE:HANDLE-FATAL-CONDITION #<SB-C::INPUT-ERROR-IN-LOAD {10039CDA93}>)
4: (SB-KERNEL::%SIGNAL #<SB-C::INPUT-ERROR-IN-LOAD {10039CDA93}>)
5: (ERROR #<SB-C::INPUT-ERROR-IN-LOAD {10039CDA93}>)
6: (SB-C:COMPILER-ERROR SB-C::INPUT-ERROR-IN-LOAD :CONDITION #<SB-INT:SIMPLE-READER-PACKAGE-ERROR "Package ~A does not exist." {10039CDA33}> :STREAM #<SB-INT:FORM-TRACKING-STREAM for "file /home/cad/.config/next/init.lisp" {1003962FF3}>)
7: (SB-C::%DO-FORMS-FROM-INFO #<CLOSURE (LAMBDA (SB-KERNEL:FORM &KEY :CURRENT-INDEX &ALLOW-OTHER-KEYS) :IN SB-INT:LOAD-AS-SOURCE) {1003964EEB}> #<SB-C::SOURCE-INFO {1003964EA3}> SB-C::INPUT-ERROR-IN-LOAD)
8: (SB-INT:LOAD-AS-SOURCE #<SB-INT:FORM-TRACKING-STREAM for "file /home/cad/.config/next/init.lisp" {1003962FF3}> :VERBOSE NIL :PRINT NIL :CONTEXT "loading")
9: ((FLET SB-FASL::THUNK :IN LOAD))
10: (SB-FASL::CALL-WITH-LOAD-BINDINGS #<CLOSURE (FLET SB-FASL::THUNK :IN LOAD) {2C9607A3B}> #<SB-INT:FORM-TRACKING-STREAM for "file /home/cad/.config/next/init.lisp" {1003962FF3}>)
11: ((FLET SB-FASL::LOAD-STREAM :IN LOAD) #<SB-INT:FORM-TRACKING-STREAM for "file /home/cad/.config/next/init.lisp" {1003962FF3}> NIL)
12: (LOAD #P"/home/cad/.config/next/init.lisp" :VERBOSE NIL :PRINT NIL :IF-DOES-NOT-EXIST NIL :EXTERNAL-FORMAT :DEFAULT)
13: (START :WITH-PLATFORM-PORT-P T)
14: ((LAMBDA NIL :IN UIOP/IMAGE:RESTORE-IMAGE))
15: (UIOP/IMAGE:CALL-WITH-FATAL-CONDITION-HANDLER #<CLOSURE (LAMBDA NIL :IN UIOP/IMAGE:RESTORE-IMAGE) {100385594B}>)
16: ((FLET SB-UNIX::BODY :IN SB-EXT:SAVE-LISP-AND-DIE))
17: ((FLET "WITHOUT-INTERRUPTS-BODY-27" :IN SB-EXT:SAVE-LISP-AND-DIE))
18: ((LABELS SB-IMPL::RESTART-LISP :IN SB-EXT:SAVE-LISP-AND-DIE))

unhandled condition in --disable-debugger mode, quitting

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment