Skip to content

Commit

Permalink
merge: add g:vimtex_parser_cmd_separator_check
Browse files Browse the repository at this point in the history
refer: #2628
  • Loading branch information
lervag committed Feb 15, 2023
2 parents cb1460f + d6e2fb8 commit aa55f52
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 18 deletions.
27 changes: 15 additions & 12 deletions autoload/vimtex/cmd.vim
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,12 @@ endfunction

" }}}1

function! vimtex#cmd#parser_separator_check(separator_string) abort " {{{1
return a:separator_string =~# '\v^%(\n\s*)?$'
endfunction

" }}}1

function! s:get_frac_toggled(origin, numerator, denominator) abort " {{{1
let l:target = get(g:vimtex_toggle_fractions, a:origin, 'INLINE')

Expand Down Expand Up @@ -686,18 +692,15 @@ function! s:get_cmd_part(part, start_pos) abort " {{{1
call vimtex#pos#set_cursor(a:start_pos)
let l:open = vimtex#delim#get_next('delim_tex', 'open')
call vimtex#pos#set_cursor(l:save_pos)
if empty(l:open) | return | endif

"
" Ensure that the delimiter
" 1) is of the right type,
" 2) and is the next non-whitespace character.
"
let l:separate = s:text_between(a:start_pos, l:open)
let l:newlines = count(l:separate, "\n")
if l:open.match !=# a:part
\ || strlen(substitute(l:separate, '\_s\+', '', 'g')) != 0
\ || l:newlines > 1

" Ensure that the next delimiter is found and is of the right type
if empty(l:open) || l:open.match !=# a:part | return {} | endif

" Ensure that the delimiter is the next non-whitespace character according to
" a configurable rule
if ! call(g:vimtex_parser_cmd_separator_check, [
\ s:text_between(a:start_pos, l:open)
\])
return {}
endif

Expand Down
2 changes: 2 additions & 0 deletions autoload/vimtex/options.vim
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,8 @@ function! vimtex#options#init() abort " {{{1
\ '-n1 -n3 -n8 -n25 -n36')

call s:init_option('vimtex_parser_bib_backend', 'bibtex')
call s:init_option('vimtex_parser_cmd_separator_check',
\ 'vimtex#cmd#parser_separator_check')

call s:init_option('vimtex_quickfix_enabled', 1)
call s:init_option('vimtex_quickfix_method', 'latexlog')
Expand Down
76 changes: 70 additions & 6 deletions doc/vimtex.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1266,14 +1266,75 @@ OPTIONS *vimtex-options*
<
Default value: `bibtex`

*g:vimtex_parser_cmd_separator_check*
This option specifies the policy for deciding whether successive groups of
`[opt]` and `{arg}` following a `\command` should be recognized as arguments
to that `\command`.

In fact, parsing a LaTeX command without additional knowledge is a hard
problem. When we read `\foo{bar}{baz}` — is `{baz}` going to be consumed as
an argument to `\foo`? The only way to know this is to read the definition
of the `\foo` command/macro.

A pragmatic choice when we write a parser, therefore, is to rely on some
heuristics and common practises. This will never be perfect, but it can be
good enough for practical use. In VimTeX, the core heuristics are that
a command will look like this: >tex

\foo<overlay>[[opt]{arg}]...
\begin{name}<overlay>[[opt]{arg}]...
<
The parser greedily swallows as many groups of `[opt]` and `{arg}` as
possible as long as the function specified via this option returns true for
the text between successive such groups.

The default function will allow a line break and possibly white space on the
preceding line before a new group. E.g.: >tex

% command number of args
% ------- --------------
\foo{bar}{baz} % 2
\foo{bar} {baz} % 1
\foo{bar}
{baz} % 2
\foo{bar}
{baz} % 2
\foo{bar}__
{baz} % 1 (_ indicates spaces)
<
The option should be either the name of the function (a string) or
a |Funcref|. The function takes a single argument, which is the string
between successive `[opt]` and `{arg}` groups. It should return |v:true|
if the parser should continue and |v:false| if the parser should stop.

A user may want to change this behaviour e.g. to specify that all whitespace
should be allowed, including and up to a single newline: >vim

function! MyCmdSeparatorRule(separator_string)
return a:separator_string =~# '^\_s\+$'
\ && count(a:separator_string, "\n") < 2
endfunction

let g:vimtex_parser_cmd_separator_check = 'MyCmdSeparatorRule'
<
Note: This option is relevant for any feature that relies on the parsing of
a command. This includes, but is not limited to the
|<plug>(vimtex-ac)| text object (|vimtex-text-objects|).

Note: |Funcref|s are only possible when it is used with neovim Lua
configuration, because in Vimscript, variable names must be
capitalized in order to point to |Funcref|s.

Default: `'vimtex#cmd#parser_separator_check'`

*g:vimtex_bibliography_commands*
A list of command names for commands that include bibliography files.
Each list entry is interpreted as a pattern (very magic, see |/\v|) to
match a particular command name. This option may be useful if one defines
custom commands that includes bibliography files.
A list of command names for commands that include bibliography files. Each
list entry is interpreted as a pattern (very magic, see |/\v|) to match
a particular command name. This option may be useful if one defines custom
commands that includes bibliography files.

Default value: >
['%(no)?bibliography', 'add%(bibresource|globalbib|sectionbib)']
Default value: >
['%(no)?bibliography', 'add%(bibresource|globalbib|sectionbib)']
*g:vimtex_complete_bib*
This option is a dictionary for controlling the citation completion. The
Expand Down Expand Up @@ -3778,6 +3839,9 @@ cursor position before the operation. >
\item hello moon| dam \end{itemize}
\end{itemize}
Note: The "greediness" of the command text objects (`ic` and `ac`) can be
controlled with |g:vimtex_parser_cmd_separator_check|.

Note: Some of the text objects rely on syntax highlighting (|vimtex-syntax|)
to work. That is, some text objects check the syntax groups to determine
the proper regions. Examples include the math text objects (e.g.
Expand Down

0 comments on commit aa55f52

Please sign in to comment.