Welcome to the Power Users community on Codidact!
Power Users is a Q&A site for questions about the usage of computer software and hardware. We are still a small site and would like to grow, so please consider joining our community. We are looking forward to your questions and answers; they are the building blocks of a repository of knowledge we are building together.
How to indent list items in Vim
Problem
How do I indent a list item in Vim the following way? Ideally I want
this to happen automatically upon wrap, but will settle for something
like ESC TAB
doing the trick.
Have
This is a list:
1. This is a list item.
2. This is a long list item that I am wrapping at 72 characters which
contains nonsense to hit that limit.
3. This is a list item that emphasizes the effect.
Want
This is a list:
1. This is a list item.
2. This is a long list item that I am wrapping at 72 characters
which contains nonsense to hit that limit.
3. This is a list item that emphasizes the effect.
Tried
I have the following in my .vimrc
:
set tw=72
set autoindent
set smartindent
set autoindent
will correctly indent subsequent lines if I manually
indent the first wrapped line. I have not observed a difference with
set smartindent
.
Notes
I am using Vim and spacemacs, but only need an answer for Vim.
In spacemacs I can TAB
the first line to the right place in
text-mode
; in markdown-mode
, the line is wrapped (auto-filled)
correctly without action.
1 answer
You don't need smartindent
, but you need autoindent
plus n
in formatoptions
: setlocal formatoptions+=n
. This is what its documentation (:h fo-table
, for format options) says:
When formatting text, recognize numbered lists. This actually uses the 'formatlistpat' option, thus any kind of list can be used. The indent of the text after the number is used for the next line. The default is to find a number, optionally followed by '.', ':', ')', ']' or '}'. Note that 'autoindent' must be set too. Doesn't work well together with "2".
"2" means:
When formatting text, use the indent of the second line of a paragraph for the rest of the paragraph, instead of the indent of the first line. This supports paragraphs in which the first line has a different indent than the rest. Note that 'autoindent' must be set too.
So if you want to mix both behaviors, or to do anything more complex, you would have to define indentexpr
, which can be set to a function that calculates the indentation for the current line. You can look for examples on Vim's source code. For instance, here is what Vim itself does to indent reStructuredText:
function GetRSTIndent()
let lnum = prevnonblank(v:lnum - 1)
if lnum == 0
return 0
endif
let ind = indent(lnum)
let line = getline(lnum)
if line =~ s:itemization_pattern
let ind += 2
elseif line =~ s:enumeration_pattern
let ind += matchend(line, s:enumeration_pattern)
endif
let line = getline(v:lnum - 1)
" Indent :FIELD: lines. Don’t match if there is no text after the field or
" if the text ends with a sent-ender.
if line =~ '^:.\+:\s\{-1,\}\S.\+[^.!?:]$'
return matchend(line, '^:.\{-1,}:\s\+')
endif
if line =~ '^\s*$'
execute lnum
call search('^\s*\%([-*+]\s\|\%(\d\+\|#\)\.\s\|\.\.\|$\)', 'bW')
let line = getline('.')
if line =~ s:itemization_pattern
let ind -= 2
elseif line =~ s:enumeration_pattern
let ind -= matchend(line, s:enumeration_pattern)
elseif line =~ '^\s*\.\.'
let ind -= 3
endif
endif
return ind
endfunction
1 comment thread