Skip to content

Commit bd3040c

Browse files
committed
Make vim respect the tab width settings
Somehow the dune filetype in neovim ends up with the "lisp" option set despite this not being explicitly configured. Without this setting indentation of dune files does not happen at all, as it's needed for vim to indent lines based on parentheses. Unfortunately when "lisp" is set, it also causes the softtabstop and shiftwidth settings to be ignored, presumably to allow for indentation conventions in lisp where elements of lists are aligned to the first element of the list, regardless of its indentation. The default behaviour with "lisp" enabled also effectively uses a softtabstop of 2, and this can't be overriden by setting the softtabstop variable. This makes it frustrating to edit dune files in vim, as the indentation inserted by the editor won't match the 1-space indentation commonly found in dune files. The workaround is to to set lispoptions=expr:1 which allows vim to use a custom indentexpr when "lisp" is set, and to supply a custom indentexpr function which changes the indentation based on unmatched parentheses, which is an approximation of the behaviour of `dune format-dune-file`. Signed-off-by: Stephen Sherratt <[email protected]>
1 parent 81be9d0 commit bd3040c

File tree

1 file changed

+24
-2
lines changed

1 file changed

+24
-2
lines changed

indent/dune.vim

+24-2
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,36 @@
22
" Language: dune
33
" Maintainers: Markus Mottl <[email protected]>
44
" URL: https://github.com/ocaml/vim-ocaml
5-
" Last Change: 2020 Dec 31
5+
" Last Change: 2024 Nov 8 - Make vim respect the tab width settings (Stephen Sherratt)
6+
" 2020 Dec 31
67

78
if exists("b:did_indent")
89
finish
910
endif
1011
let b:did_indent = 1
1112

13+
" A rough approximation of the indentation behaviour implemented by
14+
" `dune format-dune-file`.
15+
function! DuneIndent()
16+
let prev_line = getline(v:lnum - 1)
17+
let prev_indent = indent(v:lnum - 1)
18+
let current_indent = prev_indent
19+
for i in range(len(prev_line))
20+
if prev_line[i] == '('
21+
let current_indent += &shiftwidth
22+
endif
23+
if prev_line[i] == ')'
24+
let current_indent -= &shiftwidth
25+
endif
26+
endfor
27+
return current_indent
28+
endfunction
29+
1230
" dune format-dune-file uses 1 space to indent
13-
setlocal softtabstop=1 shiftwidth=1 expandtab
31+
" Explicitly set "lisp" since without this setting vim will not auto indent
32+
" sexp files like dune files at all. When "lisp" is enabled, vim doesn't
33+
" respect softtabstop or shiftwidth by default, so a custom indentexpr is
34+
" needed.
35+
setlocal softtabstop=1 shiftwidth=1 expandtab lisp indentexpr=DuneIndent() lispoptions=expr:1
1436

1537
let b:undo_indent = "setl et< sts< sw<"

0 commit comments

Comments
 (0)