1

Is there any way that UltiSnips can be made to seek for a text in document and execute some snippet at the position of text?

Explanation of Intent :-

Say I have the following text file

abcde
klsdfl

| %cursor

unique_text

Now, what I want is that if I write trigger and press the expand key (Tab in my case) then the snippet would write some_text and then look for unique_text (which is always unique and located at the bottom of my document), insert two blank lines above it and write anything there and just after some_text position as well?

Bare structure of MWE :-

snippet trigger "you_dont_need_this" wmA
some_text ${1:anything}
#code for seeking unique_text
$1
endsnippet

Expected DryRun :-

abcde
klsdfl

trigger %pressing Tab now

unique_text

Snippet executes.

abcde
klsdfl

some_text anything
          %blank line already existing
anything
          %blank line no 1
          %blank line no 2
unique_text

Edit 1 : Actual usage - I am using snippets for LaTeX documents and wanted to write the bibliography while giving citations immediately. The snippet should go down towards the very end of the document and find \end{thebibliography} and create a \bibitem{cite_key} directly as soon as I expand my snippet for \cite{cite_key} and then I would write the reference (which are often my own thoughts and questions) and then I could use Ctrl-O key-binding from my text editor Vim to jump to the previous location. This would save me a lot of time, specially with large documents.

7
  • 2
    It may be possible to hack your way there with a snippet containing Python code but I don't think this is how snippets are intended to be used. (Presumably you've not seen any other snippets do anything like this or else you'd probably have emulated it.) They operate on text in the immediate vicinity of the cursor not at arbitrary locations in the document. You'd probably be better served by doing this with a bit of Vimscript and a mapping.
    – B Layer
    Commented Jun 23, 2020 at 22:35
  • 1
    Indeed, in mu-template (another template/snippet engine), I have dedicated hooks to operate modifications not in the vicinity of the cursor -- that I mainly use to add import/include statements at the start of the document. I don't know if your snippet engine supports this. May be, as you wish to modify the text after cursor position, you should be able to do it by simply calling setline() on the position found -- expecting your snippet engine has the same kind of constraints as mine: the number of lines before the cursor shall not be modified by templates/snippets. Commented Jun 23, 2020 at 23:41
  • Out of curiosity I plumbed the depths of the UltiSnips docs and there are some arcane features that seem to make this kind of thing possible without hacks. I'll take a closer look when I get the chance.
    – B Layer
    Commented Jun 24, 2020 at 0:53
  • @BLayer I actually had Python script in mind but do not know how to make it work. Will keep looking. Thanks.
    – Nitin
    Commented Jun 24, 2020 at 0:54
  • @LucHermitte I am using UltiSnips and will check for the functionality you mention. Thanks.
    – Nitin
    Commented Jun 24, 2020 at 0:55

1 Answer 1

2
global !p
def insert_before_unique(name):
    vim.command('/unique_text')
    snip.expand_anon(name + '\n\n\n')
endglobal

post_jump "if snip.tabstop == 0: insert_before_unique(snip.tabstops[1].current_text)"
snippet trigger "tricky stuff"
$1
endsnippet

This seems to do the trick. Or close to it.

If you type trigger and hit tab you'll be prompted to enter text at the one tabstop. Hit tab again and it will also insert whatever you just entered two lines above the line containing unique_text.

Rather than try to get this exactly right for your (just updated) problem description it'll probably be best for you to do the fine tuning (or request in a comment a specific change you need and I can do it).

You can modify the static text in the snippet part however you want. You can also tweak or add vim.commands if needed. You can put any command-line/ex command in those.

5
  • Oh, I just posted an edit before I saw your accept. Oh well, no harm no foul. Cheers.
    – B Layer
    Commented Jun 24, 2020 at 1:45
  • Thanks a lot. I can make this work now. Just needed the bare bones. :)
    – Nitin
    Commented Jun 24, 2020 at 1:47
  • 1
    Awesome. Glad I could help. And I have a new found appreciation for the power of Ultisnips. :)
    – B Layer
    Commented Jun 24, 2020 at 1:47
  • 1
    Just to add to the UltiSnips part get this. I have defined a snippet notes and whenever I open a new document and write the word notes and press tab then my default LaTeX template for notes is printed and pressing more tabs I can cycle through the title, author etc and within less than 5 seconds my document is ready with nice fonts and title is nicely colored and enveloped in a box and so on. I daresay that this is as fast as writing notes in any format across all available tools and platforms. Sometimes it takes me longer to find a pen and paper!
    – Nitin
    Commented Jun 24, 2020 at 2:13
  • LOL. Fantastic!
    – B Layer
    Commented Jun 24, 2020 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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