# HG changeset patch # User Steve Losh # Date 1460743563 0 # Node ID f13a2b1ddedf8c5cf48ee62e69bd7f30e8476852 # Parent 1b4778f1a32a8204253a1adbe194db7e7ba3d8a5 Do some horrifying things with lisp folding diff -r 1b4778f1a32a -r f13a2b1ddedf bin/ccl-rlwrap --- a/bin/ccl-rlwrap Tue Apr 12 22:01:41 2016 +0000 +++ b/bin/ccl-rlwrap Fri Apr 15 18:06:03 2016 +0000 @@ -1,3 +1,5 @@ #!/usr/bin/env bash -rlwrap ros -L ccl-bin run -l ~/.ccl-init.lisp "$@" +# rlwrap ros -L ccl-bin run -l ~/.ccl-init.lisp "$@" +# roswell performance ccl is fucked atm, see here https://github.com/roswell/roswell/issues/141 +rlwrap /usr/local/bin/ccl64 "$@" diff -r 1b4778f1a32a -r f13a2b1ddedf ccl-init.lisp --- a/ccl-init.lisp Tue Apr 12 22:01:41 2016 +0000 +++ b/ccl-init.lisp Fri Apr 15 18:06:03 2016 +0000 @@ -9,8 +9,8 @@ (setf ccl:*listener-prompt-format* #'sjl-lisp-prompt-format) ;;; The following lines added by ql:add-to-init-file: -; #-quicklisp -; (let ((quicklisp-init (merge-pathnames ".quicklisp/setup.lisp" (user-homedir-pathname)))) -; (when (probe-file quicklisp-init) -; (load quicklisp-init))) +#-quicklisp +(let ((quicklisp-init (merge-pathnames ".quicklisp/setup.lisp" (user-homedir-pathname)))) + (when (probe-file quicklisp-init) + (load quicklisp-init))) diff -r 1b4778f1a32a -r f13a2b1ddedf lispwords --- a/lispwords Tue Apr 12 22:01:41 2016 +0000 +++ b/lispwords Fri Apr 15 18:06:03 2016 +0000 @@ -6,7 +6,7 @@ (1 test) ; optima -(1 match) +(1 match ematch) ; defstar (2 defun*) diff -r 1b4778f1a32a -r f13a2b1ddedf vim/ftplugin/lisp/lispfolding.vim --- a/vim/ftplugin/lisp/lispfolding.vim Tue Apr 12 22:01:41 2016 +0000 +++ b/vim/ftplugin/lisp/lispfolding.vim Fri Apr 15 18:06:03 2016 +0000 @@ -1,60 +1,173 @@ -if exists('loaded_lispfolding') || &cp - finish -endif +" if exists('loaded_lispfolding') || &cp +" finish +" endif let loaded_lispfolding=1 -" --------------------------------------------------------------------------- -" Automagic Lisp folding on defn's and defmacro's -" +let s:lispfold_flet_re = '\vlabels|flet' + +function! LispFoldingFormIsFlet() + " Return whether the form the cursor is on is a fletlike. + let old_z = @z + + " Yank the next word. + normal! l + silent normal! "zyiw + let word = @z + + let @z = old_z + + " See if that next word is a fletlike thing. + if word =~ s:lispfold_flet_re + return 1 + else + return 0 + endif +endfunction + +function! LispFoldingStartFlet(lnum) + " Return 1 when the given line is the start of a multi-line flet'ed + " function definition. We want to fold those. Return -1 if it's + " a single-line fletted definition. Return 0 if it's neither. + " + " Relies on things being indented correctly to help the speed. + " + " Basically this thing is a total shitshow, turn back now. + " + " TODO: the function definitions have to be indented, fix that + let l = getline(a:lnum) + let save_cursor = getpos('.') + + try + " A foldable flet looks like this: + " + " (flet + " ((foo () + " ...) + " (bar () + " ...)) + " body) + " + + " Make sure the cursor's on the current line. + call setpos('.', [0, a:lnum, 1, 1]) + + " Check if the line starts with ( or ((, and move to the appropriate + " "start of the function form" character. + if l =~ '\v^\s\s\s\s+\(\(\k+( \(|$)' + normal! ^l + elseif l =~ '\v^\s\s\s\s\s+\(\k+( \(|$)' + normal! ^ + else + return 0 + endif -function! GetLispFold() + let save_start = getpos('.') + + " Pop up two levels in the paren stack. + " TODO: make sure we actually do, not that it matters in practice + call searchpair('(', '', ')', 'b') + call searchpair('(', '', ')', 'b') + + if !LispFoldingFormIsFlet() + return 0 + endif + + " We know this is a fletthing, but if it only spans one line, bail. + call setpos('.', save_start) + if searchpairpos('(', '', ')')[0] == a:lnum + return -1 + end + + " congrats, u made it + return 1 + finally + call setpos('.', save_cursor) + endtry +endfunction + +function! LispFoldingEndFlet(lnum) + " Return whether we're at the last line of a multi-line fletted function. + let l = getline(a:lnum) + let save_cursor = getpos('.') + + try + if l =~ '\v\)\)$' + call setpos('.', [0, a:lnum, len(l) - 1, 1]) + let start_line = searchpairpos('(', '', ')', 'b')[0] + + let r = LispFoldingStartFlet(start_line) + if r == 1 + return 1 + elseif r == -1 + return 0 + endif + endif + + if l =~ '\v\)$' + call setpos('.', [0, a:lnum, len(l), 1]) + let start_line = searchpairpos('(', '', ')', 'b')[0] + + if LispFoldingStartFlet(start_line) == 1 + return 1 + endif + endif + + return 0 + finally + call setpos('.', save_cursor) + endtry +endfunction + +function! GetLispFold(lnum) let inline_fn_comment_re = '\v^ *;;( .*)?$' - if getline(v:lnum) =~ '^;;;; ' + if getline(a:lnum) =~ '^;;;; ' + " Never fold top-level header comments return "0" - elseif getline(v:lnum) =~ '^;;; ' + elseif getline(a:lnum) =~ '^;;; ' + " Subheader top level comments should get folded together in level 1 return "1" - elseif getline(v:lnum) =~ inline_fn_comment_re - if getline(v:lnum + 1) =~ inline_fn_comment_re - return "2" + elseif getline(a:lnum) =~ inline_fn_comment_re + " Inline function comments should increment the fold level + let prev = getline(a:lnum - 1) =~ inline_fn_comment_re + let next = getline(a:lnum + 1) =~ inline_fn_comment_re + + if (!prev) && next + return "a1" + elseif prev && (!next) + return "s1" else - return "<2" + return "=" endif - elseif getline(v:lnum) =~ '^; ' - return "0" - elseif getline(v:lnum) =~ '^(let[*]? ' - " let over lambda + elseif getline(a:lnum) =~ '^; ' + " don't include commentary-commented lines in deeper folds than necessary + return "-1" + elseif getline(a:lnum) =~ '^(test ' + " (test ...) folds at the top level return ">1" - elseif getline(v:lnum) =~ '^(test ' - return ">1" - elseif getline(v:lnum) =~ '^(def\S\+ ' + elseif getline(a:lnum) =~ '^(def\S\+ ' " fuck it just fold everything that looks kinda deffy return ">1" - elseif getline(v:lnum) =~ '^\s*$' - let my_lispnum = v:lnum - let my_lispmax = line("$") - - while (1) - let my_lispnum = my_lispnum + 1 - if my_lispnum > my_lispmax - return "<1" - endif - - let my_lispdata = getline(my_lispnum) - - " If we match an empty line, stop folding - if my_lispdata =~ '^$' - return "<1" - else - return "=" - endif - endwhile + elseif getline(a:lnum) =~ '^$' && getline(a:lnum - 1) =~ '^$' + return "0" + elseif getline(a:lnum) =~ '^$' + " Single blank lines fold along with the previous line, so that the + " blank line after a defun gets folded into the defun. + return "=" + elseif LispFoldingStartFlet(a:lnum) == 1 + " if this is a function definition in a labels/flet/etc, we want to + " start a new deeper fold + return ">2" + elseif LispFoldingEndFlet(a:lnum) + " if this is the END of a flet definition, we should pop a foldlevel + return "<2" else return "=" endif endfunction function! TurnOnLispFolding() - setlocal foldexpr=GetLispFold() + setlocal foldexpr=GetLispFold(v:lnum) setlocal foldmethod=expr + " nnoremap qq :echo GetLispFold(getpos('.')[1]) endfunction