1

I have created a guard snippet (ultisnips) in order to add on my existing functions:

snippet guard "add guard to functions" b
if !exists('*${1:func_name}')
   ${VISUAL}
endif
${0:jump here <C-j>}
endsnippet

At the moment I have to type the "func_name" at the top and it has to be equal at the name captured in the visual section, anyone have a better suggestion or any improvement to this?

1

Try this:

snippet guard "add guard to functions" b
if !exists('*`!p snip.rv = re.search('\S+\s+(\S+)\(', snip.v.text.splitlines()[0]).group(1)`')
    ${VISUAL}
endif
${0:jump here <C-j>}
endsnippet

The `!p snip.rv = ...` part is a python interpolation. The evaluation of the expression to the right of the assignment operator after snip.rv replaces everything between the backticks.

Here the expression is:

re.search('\S+\s+(\S+)\(', snip.v.text.splitlines()[0]).group(1)
  • snip.v.text allows you to refer to the last visually-selected text in a python interpolation.
  • .splitlines() allows you to split the lines of the visual selection in a list.

  • snip.v.text.splitlines()[0] grabs the first line in the selection.

  • re.search('\S+\s+(\S+)\(', ...).group(1) extracts the function name from this line.

If you make a mistake when selecting the function, the first line may not match the regex, in which case an error will be raised.

Inside the python interpolation, you can use a try, except construct to catch the error:

snippet guard "add guard to functions" b
if !exists('*`!p
try:
    func_name = re.search('\S+\s+(\S+)\(', snip.v.text.splitlines()[0]).group(1)
except AttributeError:
    func_name = ''
snip.rv = func_name
`')
    ${VISUAL}
endif
${0:jump here <C-j>}
endsnippet
  • The regex could be less permissive? While a function could be function or fun or functi, it must start with fu, so you could instead use r'\bfu\S*\s+(\S+)\(' to ensure it starts with 'fu' (and \b to prevent matching something like :Snafu). (There's lots of other possibilities for false positives, but this seems like the most important fix.) – idbrii May 13 at 23:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.