I've successfully gotten vim to understand my language's syntax for highlighting, but I'm unsure how to get it to automatically indent my code properly. The language itself is somewhat Lisp-like, but it uses both brackets []
and parentheses ()
as delimiters. The resulting code indentation should look something like this:
[foo [bar baz] [qux
[do a thing]
[more doing a thing]
[^ ()
; some stuff here
[foobar]]]]
[back to here]
Basically, each unclosed bracket or parenthesis should indent the line by two spaces. Closing said delimiter should decrease the following lines by the same amount.
I've looked into autoindent
, but it doesn't seem sufficient for what I'd like to do, unless I'm missing something. The alternative, indentexpr
, seems more promising, but I don't think I understand how to use it.
How can I get a working indentation system for my syntax?
Have you tried 'lisp'
option? It produces
[foo [bar baz] [qux
[do a thing]
[more doing a thing]
[^ ()
; some stuff here
[foobar]]]]
[back to here]
on your example.
You can also construct your own indentexpr
. Very simple one will be
if exists("b:did_indent")
finish
endif
let b:did_indent = 1
if exists('*shiftwidth')
let s:shiftwidth=function('shiftwidth')
else
function s:shiftwidth()
return &shiftwidth
endfunction
endif
function! YourLangIndent(lnum)
if a:lnum==1
return 0
endif
let line=getline(a:lnum-1)
return indent(prevnonblank(a:lnum-1))+s:shiftwidth()*(len(substitute(line, '[^[]', '', 'g'))-len(substitute(line, '[^]]', '', 'g')))
endfunction
setlocal indentexpr=YourLangIndent(v:lnum)
let b:undo_indent='setlocal indentexpr<'
. Its result:
[foo [bar baz] [qux
[do a thing]
[more doing a thing]
[^ ()
; some stuff here
[foobar]]]]
[back to here]
(for &sw
set to 4, half the amount of spaces for &sw
set to 2).