Skip to content

Instantly share code, notes, and snippets.

@jchros
Last active February 21, 2022 10:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jchros/bf856b0265c6013a4aeb53515b62c892 to your computer and use it in GitHub Desktop.
Save jchros/bf856b0265c6013a4aeb53515b62c892 to your computer and use it in GitHub Desktop.
" Parses Vimscript commands
" Caveats:
" - Assumes that "a:source" is a well-formed single-line Vim command; it doesn't always fail gracefully otherwise
" - Assumes there is only one command (i.e. "|"s are part of the arguments of the command and aren't used as separators)
" - For ":!" commands, "cmd" is an empty string, "has_bang" is TRUE, and "args" is the entire shell command
func ParseCmd(source) abort
" sorry.
let res = matchlist(a:source, '^[ \t:]*\%(\(\%([%.$,;]\|[''\\].\|[-+]\?\d\+\%(\s*match\)\@!\|\([/?]\).\{-\}[^//]\%(\\\\\)*\%(\2\|$\)\)*\)\s*\(\%(\a\|\d\)*\)\(!\?\)\s*\(.*\)\&[^"#]\)')
return empty(res) ? {} : #{
\ source: res[0],
\ range: res[1],
\ cmd: substitute(res[3], '^\(\d\+\)\s*\(.*\)', '\1\2', ''),
\ has_bang: !empty(res[4]),
\ args: res[5],
\ }
endfunc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment