From e237bf6f1584eab02d3f1b4ecf57963e4364bbf7 Mon Sep 17 00:00:00 2001 From: Jason Felice Date: Fri, 28 Sep 2018 12:28:21 +0100 Subject: [PATCH] Better Lisp and Clojure indent Algol-like indenting doesn't work for Lisp as we tend to open (and close) many forms on one line. This generally puts the cursor where it should be, though it is probably confused by strings with brackets and things. --- rc/base/clojure.kak | 27 ++++++++++++++++++++++++++- rc/base/lisp.kak | 24 +++++++++++++++++++----- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/rc/base/clojure.kak b/rc/base/clojure.kak index 8d448a57..19c31bc9 100644 --- a/rc/base/clojure.kak +++ b/rc/base/clojure.kak @@ -158,7 +158,32 @@ evaluate-commands %sh{ # ‾‾‾‾‾‾‾‾ define-command -hidden clojure-filter-around-selections lisp-filter-around-selections -define-command -hidden clojure-indent-on-new-line lisp-indent-on-new-line + +declare-option \ + -docstring 'regex matching the head of forms which have options *and* indented bodies' \ + regex clojure_special_indent_forms \ + '(?:def.*|doseq|for|fn\*?|if(-.*|)|let.*|loop|ns|testing|with-.*|when(-.*|))' + +define-command -hidden clojure-indent-on-new-line %{ + # registers: i = best align point so far; w = start of first word of form + evaluate-commands -draft -save-regs '/"|^@iw' -itersel %{ + execute-keys -draft 'gk"iZ' + try %{ + execute-keys -draft '[bl"i"wZ' + + try %{ + # If a special form, indent another space + execute-keys -draft '"wze\A' %opt{clojure_special_indent_forms} '\zs.\K.*;"i' + } catch %{ + # If not special and parameter appears on line 1, indent to parameter + execute-keys -draft '"wzes\h\K[^\s].*;"i' + } + } + try %{ execute-keys -draft '[rl"i' } + try %{ execute-keys -draft '[Bl"i' } + execute-keys -draft '"ia&' + } +} # Initialization # ‾‾‾‾‾‾‾‾‾‾‾‾‾‾ diff --git a/rc/base/lisp.kak b/rc/base/lisp.kak index bbba5db6..46a08d17 100644 --- a/rc/base/lisp.kak +++ b/rc/base/lisp.kak @@ -31,12 +31,26 @@ define-command -hidden lisp-filter-around-selections %{ try %{ execute-keys -draft -itersel s \h+$ d } } +declare-option \ + -docstring 'regex matching the head of forms which have options *and* indented bodies' \ + regex lisp_special_indent_forms \ + '(?:def.*|if(-.*|)|let.*|lambda|with-.*|when(-.*|))' + define-command -hidden lisp-indent-on-new-line %{ - evaluate-commands -draft -itersel %{ - # preserve previous line indent - try %{ execute-keys -draft \; K } - # indent when matches opening paren - try %{ execute-keys -draft [( \A\([^\n]+\n[^\n]*\n?\z \; } + # registers: i = best align point so far; w = start of first word of form + evaluate-commands -draft -save-regs '/"|^@iw' -itersel %{ + execute-keys -draft 'gk"iZ' + try %{ + execute-keys -draft '[bl"i"wZ' + + try %{ execute-keys -draft '"wzs.\K.*;"i' } + + # If not "special" form and parameter appears on line 1, indent to parameter + execute-keys -draft '"wze\A' %opt{lisp_special_indent_forms} '\z' 's\h\K[^\s].*;"i' + } + try %{ execute-keys -draft '[rl"i' } + try %{ execute-keys -draft '[Bl"i' } + execute-keys -draft '"ia&' } }