Skip to content

Instantly share code, notes, and snippets.

@erdg
Last active January 22, 2022 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erdg/ebf4556382bc1bbbaf534c4ebd927322 to your computer and use it in GitHub Desktop.
Save erdg/ebf4556382bc1bbbaf534c4ebd927322 to your computer and use it in GitHub Desktop.
My current config for the VIP editor
(de *F8
(evCmd (size (s-expr))) )
# utils
(local) (posChar? prevChar nextChar posLine prevLine nextLine beforeCursor
afterCursor move1 moveSearchForward moveSearchBackward moveIn moveOut
moveDownExpr moveUpExpr moveFirstExpr moveLastExpr moveEndLisp endLisp?
insert-i insert-a insert-I insert-A insertLisp-i insertLisp-a insertLisp-I
insertLisp-A lispmode insLispMode jumpPar diffPars ind@nt indentationLevel
removeEndPars closeEndPars closeParsUp dangleEndPars deleteText lispCut lispJoin
lispSplice countNestedSublists wrapLine wrapLineAnd wrapLineOr wrapForm
wrapFormsBelow wrapFormsAbove insertFormEnd setMark *ClipExpr)
(de deleteText Prg
(let *Change "d"
(run Prg) ) )
(de posChar? @
(member (posChar) (rest)) )
(de prevChar (N)
(default N 1)
(get (: buffer text)
(: posY)
(- (: posX) N) ) )
(de nextChar (N)
(default N 1)
(get (: buffer text)
(: posY)
(+ (: posX) N) ) )
# current word
(de posWord ()
(cons (posChar) (car (split (afterCursor) " "))) )
# current line
(de posLine ()
(get (: buffer text) (: posY)) )
(de beforeCursor ()
(head (- (: posX) 1) (posLine)) )
(de afterCursor ()
(tail (- (: posX)) (posLine)) )
(de prevLine (N)
(default N 1)
(get (: buffer text) (- (: posY) N)) )
(de nextLine (N)
(default N 1)
(get (: buffer text) (+ (: posY) N)) )
# movement helpers
(de move1 ()
# move to first non-space char
(move 'goAbs 1 (: posY))
(while (and (posChar? " ") (nextChar))
(move 'goRight 1) ) )
(de moveSearchForward (Str N)
(default N 1)
(macro
(move
'goForward
(lit '((L) (match '(^(chop Str) @) L)))
N ) ) )
(de moveSearchBackward (Str N)
(default N 1)
(macro
(move
'goBackward
(lit '((L) (match '(^(chop Str) @) L)))
N ) ) )
(de moveEndLisp ()
# move to end of lisp line, before comments
(unless (fully gt0 (mapcar val (posLine)))
(move 'goRight T)
(while (or (gt0 (val (posChar))) (posChar? " "))
(move 'goLeft 1) ) ) )
(de endLisp? ()
# cursor at end of lisp line or in a comment?
(fully '((X) (or (= X " ") (gt0 (val X))))
(afterCursor) ) )
(de indentationLevel (Line)
(default Line (posLine))
(let N 0
(while (= " " (++ Line))
(inc 'N) )
(/ N 3) ) )
(de moveIn (X)
# move in 1 level of indentation (down / right)
(default X 1)
(do X
(let (N 1 I (indentationLevel))
(loop
(NIL (nextLine N) (zero N))
(T (= (indentationLevel (nextLine N)) (inc I)))
(inc 'N) )
(move 'goDown N)
(move1) ) ) )
(de moveOut (X)
# move out 1 level of indentation (up / left)
(default X 1)
(do X
(let (N 1 I (indentationLevel))
(loop
(NIL (prevLine N) (zero N))
(T (= (indentationLevel (prevLine N)) (dec I)))
(inc 'N) )
(move 'goUp N)
(move1) ) ) )
(de moveDownExpr (X)
# move down to next expr at same indentation
(default X 1)
(do X
(let (N 1
I (indentationLevel) )
(loop
(NIL (nextLine N) (off N))
(T (<= (indentationLevel (nextLine N)) I))
(inc 'N) )
(if N
(move 'goDown N)
(let N 1
(loop
(NIL (nextLine N) (setq N 1))
(T (<= (indentationLevel) (nextLine N)) (inc I))
(inc 'N) )
(move 'goDown N) ) )
(move1) ) ) )
(de moveUpExpr (X)
# move up to prev expr at same indentation
(default X 1)
(do X
(let (N 1
I (indentationLevel) )
(loop
(NIL (prevLine N) (off N))
(T (<= (indentationLevel (prevLine N)) I))
(inc 'N) )
(if N
(move 'goUp N)
(let N 1
(loop
(NIL (prevLine N) (setq N 1))
(T (<= (indentationLevel) (prevLine N)) (inc I))
(inc 'N) )
(move 'goUp N) ) )
(move1) ) ) )
(de moveFirstExpr ()
# move to first expr at same indentation
(moveOut)
(moveIn) )
(de moveLastExpr ()
# move to last expr at same indentation
(let I (indentationLevel)
(move 'goDown 1)
(while (and (nextLine) (>= (indentationLevel) I))
(move 'goDown 1) )
(until (= (indentationLevel) I)
(move 'goUp 1) )
(move1) ) )
(de moveInGroup ()
# move in to next indentation level with multiple expressions
(let N 0
(loop
(moveIn)
(T (multipleExprs?))
(inc 'N)
(T (> N 12)) ) ) ) # hack to avoid infinite loop
(de moveOutGroup ()
(let N 0
(loop
(moveOut)
(T (multipleExprs?))
(inc 'N)
(T (> N 12) (moveOut)) ) ) )
(de multipleExprs? (I)
# multiple expressions at same indent level?
(nil (moveOut))
(nil (moveIn))
(default I (indentationLevel))
(let (N 1 C 0)
(loop
(NIL (nextLine N))
(T (< (indentationLevel (nextLine N)) I))
(T (= (indentationLevel (nextLine N)) I)
(inc 'C) )
(inc 'N) )
(> C 0) ) )
# insert helpers
(de insert-i ()
(when (insMode)
(setq *Repeat (list 'paste (lit @))) ) )
(de insert-a ()
(when (get (: buffer text) (: posY) 1)
(inc (:: posX)) )
(when (insMode 1)
(setq *Repeat (list 'paste (lit @) T)) ) )
(de insert-I ()
(goto 1 (: posY))
(when (insMode)
(setq *Repeat (list 'paste (lit @) 0)) ) )
(de insert-A ()
(goto
(inc (length (get (: buffer text) (: posY))))
(: posY)
T )
(when (insMode 1)
(setq *Repeat (list 'paste (lit @) T)) ) )
(de insertLisp-i ()
(when (insLispMode)
(setq *Repeat (list 'paste (lit @))) ) )
(de insertLisp-I ()
(goto 1 (: posY))
(when (insLispMode)
(setq *Repeat (list 'paste (lit @) 0)) ) )
(de insertLisp-a ()
(when (get (: buffer text) (: posY) 1)
(inc (:: posX)) )
(when (insLispMode 1)
(setq *Repeat (list 'paste (lit @) 1)) ) )
(de insertLisp-A ()
(goto
(inc (length (get (: buffer text) (: posY))))
(: posY)
T )
(when (insLispMode 1)
(setq *Repeat (list 'paste (lit @) T)) ) )
# lispMode - a modified 'insMode'
#
# - balanced parens
# - line editing shortcuts (ctrl prefix with motion)
# e.g. "^X" to delete char under cursor
# - indents code as you go
(de lispMode ()
(while @@
(move 'goUp 1)
(indent)
(move 'goDown 1)
(let [I (indentationLevel)
P (indentationLevel (prevLine)) ]
(cond
((=0 I)
(paste (list (need (* P 3) " ")))
(insertLisp-a) )
(T
(move1)
(insertLisp-i) ) ) ) ) )
(de insLispMode (Flg Win Rpl . @)
(change
(let (P (or Pos (=: buffer text (cons))) Chg)
(cond
((=0 Flg)
(con P (cons (car P) (cdr P)))
(set P)
(goto 1 (: posY)) )
((=1 Flg))
(Flg
(setq P (con P (cons NIL (cdr P))))
(goto 1 (inc (: posY)))
(setq Chg (0)) ) )
(cursor)
(off *Complete)
(while
(case (or (next) (getch))
(NIL (off @@))
(("\n" "\r")
(cond
(Rpl (beep) T)
((== This *CmdWin)
(nil (command (or Win This) (car P))) )
(T
(push 'Chg 0)
(con P
(cons (nth (car P) (: posX)) (cdr P)) )
(set P (head (dec (: posX)) (car P)))
(setq P (cdr P))
(goto 1 (inc (: posY)))
(cursor)
(on @@) # pop out to 'lispMode' to indent
NIL ) ) )
# line editing motions (ctrl prefix)
("^L"
(move 'goRight 1)
(cursor) )
("^W"
(move 'goForward 'word 1)
(cursor) )
("^B"
(move 'goBackward 'word 1)
(cursor) )
("^E"
(move 'goForward 'end 1)
(cursor) )
("^X"
(deleteText (move 'goRight 1))
(cursor) )
("^D"
(deleteText (move 'goForward 'end 1))
(cursor) )
# backspace
(("^H" "^?")
(cond
((= (prevChar) ")")
(move 'goLeft 1)
(cursor) )
((= (prevChar) "]")
(move 'goLeft 1)
(cursor) )
((posChar? ")")
(when (= (prevChar) "(")
(deleteText
(move 'goRight 1) ) )
(when (and (posChar? "(") (not (nextChar)))
(when (get (: buffer text) (: posY) 1)
(inc (:: posX)) ) )
(_bs)
(chgLine (car P)) )
((posChar? "]")
(when (= (prevChar) "[")
(deleteText
(move 'goRight 1) ) )
(when (and (posChar? "[") (not (nextChar)))
(when (get (: buffer text) (: posY) 1)
(inc (:: posX)) ) )
(_bs)
(chgLine (car P)) )
((and Chg (n0 (car Chg)))
(_bs)
(chgLine (car P)) ) )
T )
(T
(let S (list @)
(cond
((<> @ "\t") (off *Complete))
((= '(":" " ") (get (: buffer text) (: posY)))
(setq S
(chop (car (rot (setq *Complete (history))))) ) )
((or Rpl (nor *Complete (setq S (pack (getWord)))))
(setq S
(make
(do (- 3 (% (dec (: posX)) 3))
(link (name " ")) ) ) ) )
(T
(default *Complete (cons S (flip (all* S))))
(do (length (car *Complete)) (_bs))
(setq S (chop (car (rot *Complete)))) ) )
(when (= "^V" (car S))
(set S (or (next) (getch2 "^V"))) )
(for C S
(cond # insert balanced parens
((= C "(")
(paste '((")"))) )
((= C ")")
(cond
((not (nextChar))
(deleteText (move 'goRight 1))
(when (get (: buffer text) (: posY) 1)
(inc (:: posX)) ) )
((posChar? ")")
(deleteText (move 'goRight 1)) ) ) )
((= C "[")
(paste '(("]"))) )
((= C "]")
(cond
((not (nextChar))
(deleteText (move 'goRight 1))
(when (get (: buffer text) (: posY) 1)
(inc (:: posX)) ) )
((posChar? "]")
(deleteText (move 'goRight 1)) ) ) ) )
(push 'Chg C)
(set P
((if (and Rpl (car P)) place insert)
(: posX)
(car P)
C ) )
(inc (:: posX)) )
(goto (: posX) (: posY) T) )
(chgLine (car P))
T ) ) )
(=: posX (max 1 (dec (: posX))))
(cond
((=0 Flg) (push 'Chg 0))
((=1 Flg) (and (> PosX1 1) (dec 'PosX1))) )
(split (reverse Chg) 0) ) ) )
(de jumpPar ()
(case (posChar)
("(" (parMatch 'goForward 1 0 "(" ")" "[" "]"))
("[" (parMatch 'goForward 0 (0 . 0) "(" ")" "[" "]"))
(")" (parMatch 'goBackward 1 0 ")" "(" "]" "["))
("]" (parMatch 'goBackward 0 (0 . 0) ")" "(" "]" "["))
(T (beep)) ) )
(de diffPars (L)
# returns difference of open and closed parens
(default L (posLine))
(let [Line (filter '((X) (not (val X))) L) # no comments or transient symbols
Open (length (filter '((X) (or (= X "(") (= X "["))) Line))
Clsd (length (filter '((X) (or (= X ")") (= X "]"))) Line)) ]
(- Open Clsd) ) )
(de ind@nt ()
# indent entire paragraph without moving, set mark '@'
(setMark '@)
(move 'goPBack 1)
(move 'goDown 1)
(indent)
(jmpMark "@" "`") )
(de removeEndPars ()
# remove all parens from end of line, without touching comments
(moveEndLisp)
(deleteText
(while (posChar? " " ")")
(move 'goRight 1) ) ) )
(de closeEndPars ()
# close all parens on line
(removeEndPars)
(paste (list (need (diffPars) ")")) 1) )
(de dangleEndPars ()
# close all but N parens on line
(removeEndPars)
(paste (list (need (- (diffPars) *Cnt) ")")) 1) )
(de closeParsUp ()
# close all parens on line and up N levels
(removeEndPars)
(closeEndPars)
(do *Cnt
(paste '((" " ")")) 1) ) )
(de lispSplice ()
(cond # move to start
((posChar? "("))
((posChar? ")") (jumpPar))
(T (moveSearchBackward "(") ) )
(let N (/ (countPars (s-expr)) 2)
(deleteText (move 'goRight 1))
(setMark '@)
(do N
(moveSearchForward ")")
(until (and (posChar? ")") (not (val (posChar))))
(moveSearchForward ")") ) )
(deleteText
(move 'goRight 1)
(when (and (posChar? " ") (member (nextChar) '(")" NIL)))
(move 'goRight 1) ) )
(jmpMark "@" "`") ) )
(de countPars (Lst)
(cond
((not Lst) 2)
((atom Lst) 0)
((pair (car Lst))
(+ (countPars (car Lst)) (countPars (cdr Lst))) )
(T (countPars (cdr Lst))) ) )
(de lispCut ()
# move rest of line to new line below and indent
(deleteText
(unless (= (posChar) " ")
(move 'goLeft 1) )
(move 'goRight T) )
(paste (lit '(())) T)
(paste (val *Clip) 1)
(move 'goUp 1)
(indent)
(move 'goDown 1)
(move1) )
(de lispJoin ()
# join line to end of line above
(if (fully sp? (posLine))
(prog
(cutN 1)
(move 'goUp 1) )
(prog
(move 'goUp 1)
(join 1)) )
(move1) )
(de wrapForm ()
# wrap current form with parens, enter insert mode
(let I (indentationLevel)
(move 'goUp 1)
(paste (lit '(())) T)
(paste (list (append (need (* I 3) " ") '("("))))
(move 'goDown 1)
(move1)
(jumpPar)
(paste '((" " ")")) 1)
(jumpPar)
(when (=0 I) (move 'goUp 1))
(indent)
(insertLisp-A)
(lispMode) ) )
(de wrapFormsBelow ()
# wrap current form and all forms below (at same indentation)
(let I (indentationLevel)
(move 'goUp 1)
(paste (lit '(())) T)
(paste (list (append (need (* I 3) " ") '("("))))
(moveLastExpr)
(jumpPar)
(paste '((" " ")")) 1)
(jumpPar)
(indent)
(insertLisp-A)
(lispMode) ) )
(de wrapFormsAbove ()
# wrap current form and all forms above (at same indentation)
(let I (indentationLevel)
(move1)
(jumpPar)
(paste '((" " ")")) 1)
(move 'goLeft 2)
(jumpPar)
(until (or (not (posChar)) (< (indentationLevel) I))
(move 'goUp 1) )
(paste (lit '(())) T)
(paste (list (append (need (* I 3) " ") '("("))))
(indent)
(insertLisp-A)
(lispMode) ) )
(de insertFormEnd ()
# insert form after last expr (at same indentation)
(let I (indentationLevel)
(moveLastExpr)
(jumpPar)
(move 'goForward 'word 1)
(lispCut)
(paste '(("(" ")" " ")))
(move1)
(insertLisp-a)
(lispMode) ) )
(de wrapLine ()
# wrap left of cursor to end of line, insert at beginning of wrap
(when (posChar? " ") (move1))
(setMark '@)
(paste '(("(" " ")))
(moveEndLisp)
(while (and (posChar? ")") (sp? (prevChar)))
(move 'goLeft 2) )
(paste '((")")) 1)
(jmpMark "@" "`")
(insertLisp-a)
(lispMode) )
(de wrapLineAnd ()
# wraps current element with '(and ... |)', insert at end
(paste '(`(chop "(and ")))
(move 'goRight 1) # cursor on original element
(cond
((sp? (nextChar)))
((posChar? "(") (jumpPar))
((and (posChar? "'") (= (nextChar) "("))
(move 'goRight 1)
(jumpPar) )
(T (move 'goForward 'end 1)) )
(paste '((" " ")")) 1)
(insertLisp-i)
(lispMode) )
(de wrapLineOr ()
# wrap left of cursor to end of line with '(or ... |)', insert at end
(paste '(`(chop "(or ")))
(move 'goRight 1)
(cond
((= (nextChar) " "))
((posChar? "(") (jumpPar))
((and (posChar? "'") (= (nextChar) "("))
(move 'goRight 1)
(jumpPar) )
(T (move 'goForward 'end 1)) )
(paste '((" " ")")) 1)
(insertLisp-i)
(lispMode) )
(de insertFormBelow ()
# open form below current line
(move 'goDown 1)
(let I (indentationLevel)
(move 'goUp 1)
(paste (lit (list (append (need (* I 3) " ") '("(" ")")))) T)
(insertLisp-i)
(lispMode) ) )
(de insertFormAbove ()
# open form above current line
(let I (indentationLevel)
(move 'goUp 1)
(paste (lit (list (append (need (* I 3) " ") '("(" ")")))) T)
(insertLisp-i)
(lispMode) ) )
(de killBackwardsSplice ()
(let Indent (indentationLevel)
(move 'goUp 1)
(until (< (indentationLevel) Indent)
(cutN 1)
(move 'goUp 1) )
(cutN 1)
(move1)
(setMark '@)
(let I (indentationLevel)
(while (>= (indentationLevel) I)
(move 'goDown 1) )
(move 'goUp 1)
(moveEndLisp)
(deleteText
(move 'goRight 1)
(when (posChar? " ")
(move 'goRight 1) ) )
(jmpMark "@" "`")
(ind@nt) ) ) )
(de setMark (M)
(put (: buffer) M (cons (: posX) (: posY))) )
[de *KeyMap
("\^" # ^ or ## - search word under cursor backwards ('#' is masked)
(and (getWord T) (moveSearch 'goBackward (wordFun @))) )
# used for formatting generated docs
("") #
("F" # F - move to first char N lines down
(move 'goDown *Cnt)
(move1) )
("H" # H - go to first non-space char, then (press again) jump indentation level up/left
(ifn (fully sp? (beforeCursor))
(move1)
(if (posChar? " ")
(move1)
(moveOut) ) ) )
("L" # L - go to end of lisp line, then (press again) end of line
(ifn (endLisp?)
(moveEndLisp)
(move 'goRight T) ) )
("T" # T - move to next opening paren
(do *Cnt
(moveSearchForward "(")
(until (and (posChar? "(") (not (val (posChar))))
(moveSearchForward "(") ) ) )
("U" # U - undo lisp cut (append current line to end of previous line)
(lispJoin) )
("V" # V - lisp cut (move rest of line to new line below)
(lispCut) )
("_"
(do (or (and (> *Cnt 1) *Cnt) 20)
(cond
((=1 ( : lines)))
((: prev)
(chgwin (dec (: lines)))
(with (: prev)
(chgwin (inc (: lines)) (dec (: top))) ) )
(T
(chgwin (dec (: lines)) (inc (: top)))
(with (: next)
(chgwin (inc (: lines))) ) ) ) )
(if (or (: prev) (: next)) (setq *Window @)) )
("[" # [ - like '{', but goes to first char of paragraph
(move 'goUp 1)
(move 'goPBack *Cnt)
(until (posChar) (move 'goDown 1))
(move1) )
("]" # ] - like '}', but goes to first char of paragraph
(move 'goPFore *Cnt 0)
(unless (= (: posY) (length (: buffer text))) # last line
(until (posChar)
(move 'goDown 1) ) )
(move1) )
("^L" # ^L - indent paragraph, set mark "@"
(ind@nt) )
("^N" # ^N - insert empty line below current line
(paste (lit '(())) T) )
("^P" # ^P - insert empty line above current line
(move 'goUp 1)
(paste (lit '(())) T) )
("") #
("(" # ( - prefix for opening forms
(case (getch)
("(" # (( - insert single '('
(paste '(("(")))
(move 'goRight 1) )
(">" # (> - move paren right (barf)
(when (and (posChar? "(") (not (val (posChar))))
(deleteText (move 'goRight 1))
(move 'goForward 'lword 1)
(while (or (=T (val (posChar))) (gt0 (val (posChar))))
(move 'goForward 'lword 1) )
(paste '(("("))) ) )
("<" # (< - move paren left (slurp)
(when (and (posChar? "(") (not (val (posChar))))
(deleteText (move 'goRight 1))
(move 'goBackward 'lword 1)
(while (or (=T (val (posChar))) (gt0 (val (posChar))))
(move 'goBackward 'lword 1) )
(paste '(("("))) ) )
(("$" ".") # ($ or (. - wrap to end of line, insert at beginning
(wrapLine) )
("i" # (i - wrap element (atom or list), insert at beginning
(cond
((pre? "'(" (posWord))
(paste '(("(" " ")))
(move 'goRight 2)
(jumpPar)
(paste '((")")) 1)
(jumpPar)
(insertLisp-a)
(lispMode) )
((= (posChar) "(")
(paste '(("(" " ")))
(move 'goRight 1)
(jumpPar)
(paste '((")")) 1)
(jumpPar)
(insertLisp-a)
(lispMode) )
((=1 (length (getWord T)))
(paste '(("(" " ")))
(move 'goRight 1)
(paste '((")")) 1)
(jumpPar)
(insertLisp-a)
(lispMode) )
(T
(paste '(("(" " ")))
(move 'goRight 1)
(until (or (posChar? " " ")") (not (nextChar)))
(move 'goRight 1) )
(paste '((")")))
(jumpPar)
(insertLisp-a)
(lispMode) ) ) )
("a" # (a - wrap element, insert at end
(cond
((pre? "'(" (posWord)) # quoted list
(paste '(("(")))
(move 'goRight 2)
(jumpPar)
(paste '((" " ")")) 1)
(insertLisp-i)
(lispMode) )
((= (posChar) "(")
(paste '(("(")))
(move 'goRight 1)
(jumpPar)
(paste '((" " ")")) 1)
(insertLisp-i)
(lispMode) )
((=1 (length (getWord T)))
(paste '(("(")))
(move 'goRight 1)
(paste '((" " ")")) 1)
(insertLisp-i)
(lispMode) )
(T
(paste '(("(")))
(until (or (posChar? " " ")") (not (nextChar)))
(move 'goRight 1) )
(paste '((" " ")")))
(insertLisp-i)
(lispMode) ) ) )
("o" # (o - insert form below current line
(insertFormBelow) )
("O" # (O - insert form above current line
(insertFormAbove) )
("&" # (& - wrap element with 'and', insert at end
(wrapLineAnd) )
("|" # (| - wrap element with 'or', insert at end
(wrapLineOr) )
(")" # () - wrap form
(wrapForm) )
("`" # (` - wrap parent form
(moveOut)
(wrapForm) )
("," # (, - wrap all child forms
(moveIn)
(wrapFormsBelow) )
("*" # (* - wrap all forms (at same indentation)
(moveOut)
(moveIn)
(wrapFormsBelow) )
("/" # (/ - wrap form and all forms above (at same indentation)
(wrapFormsAbove) )
("\\" # (\ - wrap form and all forms below (at same indentation)
(wrapFormsBelow) )
(("_" "0") # (_ or (0 - insert form as last (at same indentation)
(insertFormEnd) ) ) )
("") #
(")" # ) - prefix for closing forms
(case (getch)
(")" # )) - insert single ')'
(if (posChar? " ")
(paste '((")")))
(paste '((")")) 1) ) )
(">" # )> - move paren right (slurp)
(when (and (posChar? ")") (not (val (posChar))))
(when (nextChar)
(deleteText (move 'goRight 1))
(move 'goRight 1)
(when (nextChar)
(move 'goForward 'lend 1) )
(while (or (=T (val (posChar))) (gt0 (val (posChar))))
(move 'goForward 'lend 1) )
(paste '((")")) 1) ) ) )
("<" # )< - move paren left (barf)
(when (and (posChar? ")") (not (val (posChar))))
(deleteText
(move 'goRight 1)
(when (and (posChar? " ") (not (nextChar)))
(move 'goRight 1) ) )
(unless (= (prevChar) " ")
(move 'goBackward 'lword 1) )
(while (or (=T (val (posChar))) (gt0 (val (posChar))))
(move 'goBackward 'lword 1) )
(if (fully sp? (beforeCursor))
(paste '((")")) 1)
(prog
(move 'goLeft 1)
(paste '((")"))) ) ) ) )
(("!" "0") # )! or )0 - remove trailing parens on line
(removeEndPars) )
(("$" ".") # )$ or ). - close parens on line
(closeEndPars) )
(("~" ",") # N)~ or ), - close all but N parens on line (default 1)
(dangleEndPars) )
("`" # N)` - close parens on current line and up N levels
(closeParsUp) )
("?" # )? - close parens to search backwards
(use (N1 N2) # opening / closing indentation level
(setMark '@)
(setq N1 (indentationLevel))
(cmdMode (name "?"))
(setq N2 (indentationLevel))
(jmpMark "@" "`") # return to mark
(closeEndPars)
(do (- N1 N2) (paste '((" " ")")) 1)) ) )
("'" # )' - close parens to first quote on line
(let Line (beforeCursor)
(when (member "'" Line)
(paste
(list
(need
(diffPars (seek '((X) (= (car X) "'")) Line))
")") )
1 ) ) ) )
("+" # N)+ - add N parens to end of line
(moveEndLisp)
(do *Cnt
(paste '((" " ")")) 1) ) )
("-" # N)- - remove N parens from end of line
(moveEndLisp)
(do *Cnt
(deleteText
(move 'goRight 1)
(when (posChar? " ")
(move 'goRight 1) ) ) ) )
("}" # )} - indent and close all parens (at end of paragraph)
(use (N1 N2) # opening / closing indentation level
(move 'goPBack 1)
(until (posChar? "(" "~" "`" "'")
(move 'goDown 1)
(move1) )
(indent)
(setq N1 (indentationLevel))
(move 'goPFore 1 0)
(unless (posChar) (move 'goUp 1))
(setq N2 (indentationLevel))
(closeEndPars)
(do (- N2 N1)
(paste '((" " ")")) 1) ) ) ) ) )
("") #
("@" # @ - prefix for moving / refactoring forms
(case (getch)
("w" # @w - move element forward on line
(unless (= (posChar) " ")
(let *Change "d"
(cond # delete element, set *ClipExpr
((=0 (val (posChar))) # transient symbol
(move 'goForward (lit '((L) (match '("\"" @) L))) 1)
(setq *ClipExpr (car (val *Clip))) )
((and (= (posChar) "'") (= (nextChar) "(")) # quoted list
(move 'goRight 1)
(jumpPar)
(setq *ClipExpr (cons "'" (car (val *Clip)))) )
((and (member (prevChar) '(" " "(" ")")) (member (nextChar) '(" " "(" ")"))) # single char
(move 'goRight 1)
(setq *ClipExpr (car (val *Clip))) )
((member (posChar) '("(" ")")) # list
(jumpPar)
(setq *ClipExpr (car (val *Clip))) )
(T # symbol
(move 'goForward 'end 1)
(setq *ClipExpr (car (val *Clip))) ) )
(when (and (= (posChar) " ") (not (val (posChar))))
(move 'goRight 1) ) )
(cond # re-insert into form according to next elem
((and (= (posChar) "'") (= (nextChar) "(")) # quoted list
(move 'goRight 1)
(jumpPar)
(paste (list (cons " " *ClipExpr)) 1) )
((=0 (val (posChar))) # transient symbol
(move 'goForward (lit '((L) (match '("\"" @) L))) 1)
(until (=0 (val (posChar)))
(move 'goForward (lit '((L) (match '("\"" @) L))) 1) )
(paste (list (cons " " *ClipExpr)) 1) )
((= (posChar) ")")
(paste (list *ClipExpr)) )
((= (nextChar) NIL) # end of line
(paste (list *ClipExpr) 1) )
((= (nextChar) " ") # single char elem
(paste (list (cons " " *ClipExpr)) 1) )
((= (posChar) "(") # list
(jumpPar)
(paste (list (cons " " *ClipExpr)) 1) )
(T # symbol
(unless (or (member (posChar) '("(" ")")) (member (nextChar) '("(" ")")))
(move 'goForward 'end 1) )
(paste (list (cons " " *ClipExpr)) 1) ) )
(cond # return cursor to start of elem
((=1 (length *ClipExpr)) NIL)
((pre? "\"" *ClipExpr)
(move 'goBackward (lit '((L) (match '("\"" @) L))) 1) )
((pre? "(" *ClipExpr)
(jumpPar) )
((pre? "'(" *ClipExpr)
(jumpPar)
(move 'goLeft 1) )
(T (move 'goBackward 'lword 1)) ) ) )
("j" # @j - move form down (at same indentation)
(use Flg # flag for trailing parens / comment at destination
(move1)
(deleteText (jumpPar))
(setq *ClipExpr (lit (val *Clip)))
(cutN 1)
(move1)
(jumpPar)
(when (nextChar)
(unless (= (nextChar 3) "#")
(on Flg)
(move 'goRight 1)
(deleteText (move 'goRight T)) ) )
(paste *ClipExpr T)
(when Flg
(paste (lit (val *Clip)) 1)
(when (fully '((X) (or (member X '(" " ")")) (gt0 (val X)))) (posLine))
(move 'goUp 1) )
(evRpt (list 'join *Cnt)) )
(jumpPar)
(move 'goUp 1)
(indent)
(move 'goDown 1)
(move1) ) )
("k" # @k - move form up (at same indentation)
(let I (indentationLevel)
(unless (< (indentationLevel (prevLine)) I)
(move1)
(deleteText (jumpPar))
(setq *ClipExpr (lit (val *Clip)))
(lispJoin)
(until (= (indentationLevel) I)
(moveOut) )
(move 'goUp 1)
(paste *ClipExpr T)
(jumpPar)
(move 'goUp 1)
(indent)
(move 'goDown 1)
(move1) ) ) )
(("y" "Y") # N@y or @Y - yank (N) form(s at same indentation)
(move1)
(setMark '@)
(let (C *Cnt
I (indentationLevel) )
(do *Cnt
(let N (/ (countPars (s-expr)) 2)
(do N # because 'jumpPar' has strange behaviour with *Cnt
(moveSearchForward ")")
(until (and (posChar? ")") (not (val (posChar))))
(moveSearchForward ")") ) ) )
(dec 'C)
(T (=0 C))
(NIL (nextLine))
(T (< (indentationLevel (nextLine)) I))
(move 'goDown 1)
(move1) ) )
(when (get (: buffer text) (: posY) 1) # append space to yank last paren
(inc (:: posX)) )
(let *Change "y" (jmpMark "@" "`"))
(setq *ClipExpr (lit (val *Clip)))
(move1) )
("p" # @p - paste form(s) below current line
(paste *ClipExpr T)
(ind@nt) )
("P" # @P - paste form(s) above current line
(move 'goUp 1)
(paste *ClipExpr T)
(ind@nt) )
("~" # @~ - splice element / form (remove surrounding parens)
(lispSplice) )
("`" # @` - expand form to wrap parent form ("convolute" from paredit)
(use Flg
(move1)
(when (= (afterCursor) (chop "let")) # Flag for no letargs on opening line
(on Flg)
(join 1) )
(let (Indent (indentationLevel)
Curr (posWord) )
(case (diffPars)
(1
(jumpPar)
(deleteText (move 'goRight 2))
(moveSearchBackward (pack Curr))
(cutN 1)
(until (= (indentationLevel) (- Indent 1))
(move 'goUp 1) )
(move 'goUp 1)
(paste (lit (val *Clip)) T)
(move 'goUp 1)
(cutN 1)
(ind@nt)
(moveIn)
(jumpPar)
(paste '((" " ")")) 1)
(jumpPar)
(ind@nt) )
(2
(jumpPar)
(deleteText (move 'goRight 2))
(moveSearchBackward (pack Curr))
(move 'goForward 'lword 1)
(jumpPar)
(goto
(inc (length (get (: buffer text) (: posY))))
(: posY)
T )
(deleteText
(moveSearchBackward (pack Curr)) )
(setq *ClipExpr (lit (val *Clip)))
(cutN 1)
(until (= (indentationLevel) (- Indent 1))
(move 'goUp 1) )
(move 'goUp 1)
(paste *ClipExpr T)
(ind@nt)
(moveSearchBackward (pack Curr))
(moveIn)
(jumpPar)
(paste '((" " ")")) 1)
(jumpPar)
(ind@nt) ) ) )
(when Flg # clean up let with no args on opening line
(move 'goForward 'lword 1)
(lispCut)
(move 'goUp 1)
(move1) ) ) )
("?" # @? - refactor (multi-line) 'if' (with else clause) to 'cond'
(unless (pre? "(if" (posWord))
(moveSearchBackward "(if" 1) )
(when (= (afterCursor) (chop "if"))
(join 1) )
(move 'goRight 1)
(deleteText (move 'goForward 'end 1))
(paste '((~(chop "cond"))))
(move 'goForward 'lword 1)
(lispCut)
(paste '(("(")))
(move 'goRight 1)
(jumpPar)
(move 'goForward 'lword 1)
(jumpPar)
(paste '((" " ")")) 1)
(move 'goForward 'lword 1)
(paste '((~(chop "(T "))))
(move 'goForward 'lword 1)
(jumpPar)
(paste '((" " ")")) 1)
(ind@nt)
(moveEndLisp)
(jumpPar) )
("") #
("!" # @! - prefix for killing forms
(case (getch)
("!" # N@!! - kill (N) form(s at same indentation)
(setq *ClipExpr '(T))
(do *Cnt
(move1)
(setMark '@)
(let N (/ (countPars (s-expr)) 2)
(do N # because 'jumpPar' has strange behaviour with *Cnt
(moveSearchForward ")")
(until (and (posChar? ")") (not (val (posChar))))
(moveSearchForward ")") ) )
(when (get (: buffer text) (: posY) 1)
(inc (:: posX)) )
(deleteText (jmpMark "@" "`"))
(setq *ClipExpr (append *ClipExpr (val *Clip)))
(lispJoin)
(move 'goDown 1) ) )
(move1) )
("`" # @!` - splice killing backwards
(killBackwardsSplice) )
("~" # @!~ - kill form, splicing children
(moveIn)
(killBackwardsSplice) )
("*" # @!* - kill all forms at same indentation
(setq *ClipExpr '(T))
(moveOut)
(moveIn)
(while (= (posChar) "(")
(deleteText (jumpPar))
(setq *ClipExpr (append *ClipExpr (val *Clip)))
(when (fully sp? (posLine))
(cutN 1) )
(move1) )
(deleteText (move 'goLeft 1)) )
(("/") # @!/ - kill all forms above at same indentation
(off *ClipExpr)
(let Indent (indentationLevel)
(move 'goUp 1)
(until (or (< (indentationLevel) Indent) (not (posChar)))
(cutN 1)
(push '*ClipExpr (cadr (val *Clip)))
(move 'goUp 1) )
(push '*ClipExpr T)
(move 'goDown 1)
(move1) ) )
("\\" # @!\ - kill current form and all forms below at same indentation
(setq *ClipExpr '(T))
(while (= (posChar) "(")
(deleteText (jumpPar))
(setq *ClipExpr (append *ClipExpr (val *Clip)))
(when (fully sp? (posLine))
(cutN 1) )
(move1) )
(deleteText (move 'goLeft 1)) ) ) ) ) )
("") #
("#" # # - prefix for comments
(case (getch)
("#" # ## - search word under cursor backwards
(and (getWord T) (moveSearch 'goBackward (wordFun @))) )
(("~" ".") # #~ or #. - toggle leading '#' on (N) line(s)
(move1)
(if (= (posChar) "#")
(prog
(deleteText (move 'goRight 2))
(when *Cnt
(do (- *Cnt 1)
(move 'goDown 1)
(deleteText (move 'goRight 2)) ) ) )
(prog
(paste '(("#" " ")))
(move 'goLeft 1)
(when *Cnt
(do (- *Cnt 1)
(move 'goDown 1)
(paste '(("#" " ")))
(move 'goLeft 1) ) ) ) ) )
("$" # #$ - (re)write end of line comment
(ifn (member "#" (filter '((X) (gt0 (val X))) (posLine)))
(prog
(move 'goRight T)
(paste '((~(chop " # "))) 1)
(insert-a) )
(prog
(move 'goRight T)
(moveSearchBackward " # " 1)
(deleteText (move 'goRight T))
(paste '((~(chop " # "))) 1)
(move 'goRight T)
(insert-a) ) ) )
("!" # #! - delete end of line comment (paste comment with '$p')
(when (member "#" (filter '((X) (gt0 (val X))) (posLine)))
(move 'goRight T)
(moveSearchBackward " # " 1)
(deleteText (move 'goRight T)) ) )
("\^" # #^ - move end of line comment to new line above
(when (member "#" (filter '((X) (gt0 (val X))) (posLine)))
(move 'goRight T)
(moveSearchBackward " # ")
(deleteText (move 'goRight T))
(move 'goUp 1)
(paste (lit (val *Clip)) T)
(ind@nt) ) )
("@" # #@ - remove surrounding comment wrap
(when (gt0 (val (posChar)))
(if (= (nextChar) "{")
(prog
(deleteText (move 'goRight 2))
(moveSearchForward "}#" 1)
(deleteText (move 'goRight 2))
(when (posChar? " ") (move 'goLeft 1)) )
(prog
(moveSearchBackward "#{" 1)
(deleteText (move 'goRight 2))
(moveSearchForward "}#" 1)
(deleteText (move 'goRight 2)) ) ) ) )
("%" # #% - comment wrap to matching paren
(case (posChar)
(("[" "(")
(jumpPar)
(paste '(("}" "#")) 1)
(move 'goLeft 2)
(jumpPar)
(paste '(("#" "{")))
(move 'goLeft 1) )
(("]" ")")
(paste '(("}" "#")) 1)
(move 'goLeft 2)
(jumpPar)
(paste '(("#" "{")))
(move 'goLeft 1) ) ) )
("*" # #* - comment wrap all forms at same indentation
(setMark '@)
(moveLastExpr)
(jumpPar)
(paste '(("}" "#")) 1)
(moveFirstExpr)
(paste '(("#" "{")))
(jmpMark "@" "`") )
("/" # #/ - comment wrap all forms above current form at same indentation
(setMark '@)
(moveUpExpr)
(setMark 'C)
(jumpPar)
(paste '(("}" "#")) 1)
(jmpMark "C" "`")
(moveFirstExpr)
(paste '(("#" "{")))
(jmpMark "@" "`") )
("\\" # #\ - comment wrap current form and all forms below at same indentation
(move1)
(setMark 'C)
(moveLastExpr)
(jumpPar)
(paste '(("}" "#")) 1)
(jmpMark "C" "`")
(paste '(("#" "{"))) )
("}" # #} - comment wrap paragraph forward (wax on)
(until (posChar) (move 'goDown 1))
(move 'goUp 1)
(paste (lit '(())) T)
(paste '(("#" "{")) 0)
(move 'goPFore 1 0)
(paste '(("}" "#")) 0)
(paste (lit '(())) T) )
("{" # #{ - uncomment paragraph backward (wax off)
(until (posChar) (move 'goUp 1))
(when (posChar? "}")
(deleteText (move 'goDown 1))
(move 'goPBack 1)
(move 'goDown 1)
(deleteText (move 'goDown 1))
(move 'goUp 1) ) )
("]" # #] - comment paragraph forward block-style (wax on)
(until (posChar) (move 'goDown 1))
(move1)
(paste '(("#" " ")))
(while (nextLine)
(move 'goLeft 1)
(move 'goDown 1)
(paste '(("#" " "))) ) )
("[" # #[ - uncomment paragraph backward block-style (wax off)
(until (posChar) (move 'goUp 1))
(move1)
(when (posChar? "#")
(deleteText (move 'goRight 2))
(move 'goUp 1)
(while (posChar? "#")
(deleteText (move 'goRight 2))
(move 'goUp 1) ) ) )
]
[de *KeyMap-g
# g@ - ever-changing output check function
("@"
(let *Change "y"
(jumpPar) ) )
("") #
("r"
(case (getch)
("c" # grc - edit viprc
(reload (rplFile "~/.pil/viprc")) )
("e" # gre - reload viprc
(symbols '(vip pico)
(when (: buffer file)
(when (dirty> (: buffer) This)
(save> (: buffer) This) )
(evCmd (load (: buffer file))) ) ) )
# gru - go ruby prefix
("u"
(case (getch)
("c"
(vip~evCmd
(macro
(pico~ruby-check (^(vip~s-expr))) ) ) )
("d"
(vip~evCmd
(macro
(pico~ruby-run '((^(vip~s-expr)))) ) ) )
("r"
(vip~evCmd
(macro
(pico~irb (^(vip~s-expr)))) ) ) ) ) ) )
("") #
("") # lisp mode (balanced parens, auto-indent, etc)
("i" # gi - insert
(insertLisp-i)
(lispMode) )
("I" # gI - insert at beginning of line
(insertLisp-I)
(lispMode) )
("a" # ga - append
(insertLisp-a)
(lispMode) )
("A" # gA - append to end of line
(insertLisp-A)
(lispMode) )
("o" # go - open new line below current line
(let I (indentationLevel (nextLine))
(paste (lit '(())) T)
(paste (list (need (* I 3) " ")) 1)
(insertLisp-a)
(lispMode) ) )
("O" # gO - open new line above current line
(move 'goUp 1)
(let I (indentationLevel (nextLine))
(paste (lit '(())) T)
(paste (list (need (* I 3) " ")) 1)
(insertLisp-a)
(lispMode) ) )
("") #
("'" # g' - insert quote from normal mode
(paste '(("'"))) )
("\"" # g" - insert double quote from normal mode
(cond
((member (nextChar) '(")" " " NIL))
(paste '(("\"")) 1) )
((=T (val (posChar)))
(paste '(("\\\""))) )
(T (paste '(("\""))) ) ) )
(" " # g<spc> - insert space to left of cursor
(paste '((" ")))
(move 'goRight 1) )
("") #
("") # additional lisp motions
("j" # gj - move down expr at same indentation
(moveDownExpr *Cnt) )
("k" # gk - move up expr at same indentation
(moveUpExpr *Cnt) )
("l" # gl - move in to next indentation level with multiple forms
(moveInGroup) )
("") # g1 to g8 - move to Nth form at same indentation
~(make
(for N 8
(link
(list
(sym N)
(list 'moveOut)
(list 'moveIn)
(list 'moveDownExpr (dec N)) ) ) ) )
("9" # g9 - move to penultimate form at same indentation
(moveLastExpr)
(moveUpExpr) )
("0" # g0 - move to last form at same indentation
(moveLastExpr) )
(")" # g) - move to next end of multi-line form
(unless (val (posChar))
(moveEndLisp)
(moveSearchForward ") )") ) )
("") #
("h" # gh - view docs for word under cursor
(let @W (intern (pack (getWord T)))
(macro
(if (num? (fun? @W))
(doc '@W)
(evCmd (fun? @W)) ) ) ) )
("?" # g? - view docs for this viprc
(reload "~/.pil/viprc-docs") )
# sonic pi stuff
("p"
(case (getch)
# gps - stop sonic pi (go pi stop)
("s"
(call 'sh "-c" "sonic-pi-tool.py stop") )
# gpr - run sonic pi expr (go pi run)
("r"
(symbols '(vip pico)
(evCmd
(macro (pico~sp-run (^(s-expr)))) ) ) ) ) )
]
(de *KeyMap-q)
# light theme
(setq ULINE 4)
(setq U-OFF 24)
(setq PAR 2)
(setq TXT 0)
(setq COM 36)
#{
# dark theme
(setq ULINE "37;4")
(setq U-OFF "37;22;24")
(setq PAR "37;2")
(setq PAR "90;1")
(setq TXT "37;22")
(setq COM "36;22")
}#
# with hooks for text / paren colors
(setq addLine
'((Y L N)
(cup (+ (: top) Y) 1)
(clreol)
(let Line (nth L (: winX))
(for (I . C) Line
(T (lt0 (dec 'N)))
(cond
((: buffer flat))
((=T (val C))
(ifn (>= "^_" C "^A")
(attr NIL T)
(setq C (char (+ 64 (char C))))
(attr ERR T) ) )
((>= "^_" C "^A")
(setq C (char (+ 64 (char C))))
(attr ERR) )
((gt0 (val C))
(attr COM) )
((member C '("(" ")" "[" "]"))
(attr PAR) )
(T (attr TXT)) )
(prin C) ) )
(attr) ) )
(t
(out "~/.pil/viprc-docs"
(mapc prinl
(and (filter pair (: buffer text))
(mapcar clip @)
(filter
'((L)
(and
(not (val (car L)))
(or (pre? "(\"" L) (pre? "((\"" L))
(sub? " #" L) ) )
@ )
(filter
'((L)
(find
'((X) (and (= X "#") (gt0 (val X))))
L ) )
@ )
(mapcar
'((L) (seek '((X) (and (= (car X) "#") (gt0 (val (car X))))) L))
@ )
(mapcar pack @) ) ) ) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment