Skip to content

Commit 35e0234

Browse files
committed
Add basic function parameter alignment indentation
This likely still needs a lot of improvements.
1 parent 101c9a4 commit 35e0234

File tree

1 file changed

+48
-10
lines changed

1 file changed

+48
-10
lines changed

indent/clojure.vim

Lines changed: 48 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,56 @@ function! s:StringIndent(delim_pos)
159159
endfunction
160160

161161
function! s:ListIndent(delim_pos)
162-
" let lns = getline(delim_pos[0], v:lnum - 1)
163-
let ln1 = getline(a:delim_pos[0])
164-
let delim_col = a:delim_pos[1]
165-
let sym = get(split(ln1[delim_col:], '[[:space:],;()\[\]{}@\\"^~`]', 1), 0, -1)
166-
if sym != -1 && ! empty(sym) && match(sym, '^[0-9:]') == -1
167-
" TODO: align indentation.
168-
" TODO: lookup rules.
169-
return delim_col + 1 " 2 space indentation
162+
" TODO: attempt to extend "s:InsideForm" to provide information about
163+
" the subforms within the form being formatted to avoid second parsing
164+
" step.
165+
166+
" TODO: The overcomplicated list indentation rules in Clojure!
167+
" 1. If starts with a symbol or keyword: extract it.
168+
" 1.1. Look up in rules table.
169+
" 1.1.1. See number for forms forward to lookup.
170+
" 1.1.2. Start parsing forwards "x" forms. (Skip metadata)
171+
" 1.1.3. Apply indentation.
172+
" 1.2. Not found, goto 2.
173+
" 2. Else, format like a function.
174+
" 2.1. Is first operand on the same line? (Treat metadata as args)
175+
" 2.1.1. Indent subsequent lines to align with first operand.
176+
" 2.2. Else.
177+
" 2.2.1. Indent 1 or 2 spaces.
178+
179+
call cursor(a:delim_pos)
180+
let ln = getline(a:delim_pos[0])
181+
let base_indent = a:delim_pos[1]
182+
183+
" 1. TODO: Macro/rule indentation
184+
" let syms = split(ln[base_indent:], '[[:space:],;()\[\]{}@\\"^~`]', 1)
185+
" TODO: complex indentation (e.g. letfn)
186+
" TODO: namespaces.
187+
188+
" 2. Function indentation
189+
let cur_pos = [a:delim_pos[0], a:delim_pos[1] + 1]
190+
call cursor(cur_pos)
191+
192+
let ch = ln[cur_pos[1] - 1]
193+
if ch =~# '[([{]'
194+
normal! %w
195+
elseif ch !~# '[;"]'
196+
normal! w
170197
endif
171198

172-
" TODO: switch between 1 vs 2 space indentation.
173-
return delim_col " 1 space indentation
199+
let new_cur_pos = getcurpos()[1:2]
200+
201+
" TODO: option to disable operand-alignment.
202+
if cur_pos[0] == new_cur_pos[0] && cur_pos[1] != new_cur_pos[1]
203+
" Align operands
204+
return new_cur_pos[1] - 1
205+
endif
206+
207+
" TODO: create an alternative option with a better name.
208+
" <https://github.com/clojure-emacs/clojure-mode/#indentation-of-function-forms>
209+
" Base indentation for forms. When "clojure_align_subforms" is "1",
210+
" use 1 space indentation, otherwise 2 space indentation.
211+
return base_indent + ! s:Conf('clojure_align_subforms', 1)
174212
endfunction
175213

176214
function! s:ClojureIndent()

0 commit comments

Comments
 (0)