Ultisnips: Correct the indention of `item` in TeX

Created on 23 Nov 2017  路  7Comments  路  Source: SirVer/ultisnips

I find ultisnips' has a latex.snippets which defined the itemize LaTeX environment:

snippet item "Itemize" b
\begin{itemize}
    \item $0
\end{itemize}
endsnippet

snippet it "Individual item" b
\item ${1}
endsnippet

The problem is that it will have the indention when we type it<tab> for the second item, that means, item<tab> expands to:

\begin{itemize}
    \item 
\end{itemize}
\begin{itemize}
    \item Some items here.
                it<tab>
\end{itemize}

expands to:

\begin{itemize}
    \item Some items here.
                \item 
\end{itemize}

Thus I have to fix the second item's indention by hand.

I find that ultisnips has a pre_expand function and can use !v indent(".') to compute the current indent. But how can I integrate them together to make the indention fix automatically?

answered or workaround exists triaged user question

Most helpful comment

This works, as long as indentkeys has ^F (usually does). I'm sure it could be shorter (no need for a function), but I don't know ultisnips quote escaping rules.

global !p
def fix_indent(snip):
    vim.eval('feedkeys("\<c-f>")')
endglobal

post_expand "fix_indent(snip)"
snippet it "Individual item" b
\item $0
endsnippet

All 7 comments

I tried this, but it does not quite work:

~~~
global !p
def cut_indent(snip):
line = int(vim.eval('line(".")')) - 1
sw = int(vim.eval("&sw"))
indent = ' ' * sw
if snip.buffer[line].startswith(indent):
col = snip.column
snip.buffer[line] = snip.buffer[line][sw:]
snip.cursor.set(snip.line, col - sw)
endglobal

pre_expand "cut_indent(snip)"
snippet it "Individual item" b
\item ${1}
endsnippet
~~~

@seletskiy Maybe you have a better idea?

I have the same issue.

I use the ftplugin vimtex which adjust indentation settings for LaTeX files in
https://github.com/lervag/vimtex/blob/master/indent/tex.vim

This contains following line:

setlocal indentkeys+=[,(,{,),},],\&,=item,=else,=fi

:h 'indentkeys' says

                        *'indentkeys'* *'indk'*
'indentkeys' 'indk' string  (default "0{,0},:,0#,!^F,o,O,e")
    A list of keys that, when typed in Insert mode, cause reindenting of
    the current line.  Only happens if 'indentexpr' isn't empty.
    The format is identical to 'cinkeys', see |indentkeys-format|.
    See |C-indenting| and |indent-expression|.

IMHO the issue is that after a UltiSnips expansion the described reindentation is not triggered.

In my case this looks like

\begin{itemize}
  \item 
    it
\end{itemize} 

will expand

\begin{itemize}
  \item 
    \item 
\end{itemize} 

If I find the time, I want to compare the behavior of other snippet plugins such as snipmate, xptemplate or neosnippet. mu-template claims to support re-indentation.

This works, as long as indentkeys has ^F (usually does). I'm sure it could be shorter (no need for a function), but I don't know ultisnips quote escaping rules.

global !p
def fix_indent(snip):
    vim.eval('feedkeys("\<c-f>")')
endglobal

post_expand "fix_indent(snip)"
snippet it "Individual item" b
\item $0
endsnippet

I apologize if this is a very stupid question, but should this solution still work?

I have the same problem as the OP, and @andymass鈥榮 solution does not work for me. (I get an error telling me Invalid line 'global !p'.)

@telemachus you're probably seeing this message because your snippets are parsed using snipmate syntax.

Check out how to avoid it in UltiSnips help document: type :h g:UltiSnipsEnableSnipMate in vim's command line.

@seletskiy You are absolutely right. I've been using UltiSnips all along with snipmate syntax, but I never really noticed until today when I tried to add a more complex snippet. Thank you and sorry for the noise!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Industrial picture Industrial  路  8Comments

ghost picture ghost  路  8Comments

raorm picture raorm  路  4Comments

9mm picture 9mm  路  4Comments

codybuell picture codybuell  路  4Comments