0

I am trying to replicate the behavior of beg abbreviation shown on the page https://castel.dev/post/lecture-notes-1/ with vimscript. That means I want to make it so that when I type "beg" in insert mode at the beginning of the line, it calls a function that i choose.

I tried to make it with iabbrev, but it doesn't expand until i hit space, and space is typed after my abbreviation. It also doesn't recognize if it is the beginning of a line.

Another approach I tried is with an auto command. I added to my init.vim the following

function SayHello ()
  if (getline('.') =~ "\s*beg$")
    s/^\(\s*\)beg/\1\\begin{}\r\r\\end{}/
  endif
endfunction

autocmd TextChangedI *.tex call SayHello ()

This almost works, but for one problem. It doesn't work if the autocomplete popup is active, which is always because of a plugin I use. So the effect of this code is that as i first type beg, there is no effect, but if i backspace one letter and add it again, it works as intended. I tried to remedy it by adding the command

autocmd CompleteChanged *.tex call SayHello ()

so that it works anyway if there is autocomplete. Unfortunately it doesn't work, because it tries to edit the buffer of the popup. I tried making the function exit the popup to no effect.

How can I make it work like on the site?

Especially useful would be knowing how to use the TextChangedI command regardless of autocomplete because that would make other useful things possible.

  • "How can I make it work like on the site?" How it works on the site is different from how you want it to work (the snippet on the site doesn't care about being at the beginning of a line). So what do you want exactly? – romainl Apr 22 '22 at 15:16
  • @romainl The snippet on the site does care about being at the beginning of a line. Look at the snippet for beg. It has 'b' argument, which means quoting the site "that this snippet will only be expanded at the beginning of a line". – Don'tDownVote Apr 22 '22 at 16:03
  • OK, I'm familiar enough with UltiSnips to recognise it's syntax but not enough to understand it (and I didn't read the accompanying paragraph, which doesn't help). So it looks like that snippet does exactly what you want, no? If yes, why not use it directly? Or do you want additional features? – romainl Apr 22 '22 at 16:34
  • @romainl There are a couple of reasons. First of all I want it to be more customizable. Also, the ultisnips work a bit buggy for me. Lastly I don't really use that many features of Ultisnips and i feel like using it just for two features is a big overkill. – Don'tDownVote Apr 22 '22 at 16:41
  • Well, take it from a plugin minimalist, the core feature—snippet expansion—is well worth the "price". But maybe not that much if it's buggy ¯\\_(ツ)_/¯ – romainl Apr 22 '22 at 18:41

1 Answers1

0
  1. Create a harmless insert mode mapping:

    inoremap beg beg
    

    It inserts beg when you type beg. Cool.

  2. Turn it into an equally harmless "expression mapping":

    inoremap <expr> beg 'beg'
    

    In an expression mapping, the right-hand side is an expression that is evaluated when you press the left-hand side in order to produce the macro that is going to be executed for you. Here, the expression is the string beg so the mapping works just like the first one.

  3. Experiment with logic in the RHS:

    inoremap <expr> beg &filetype == 'foo' ? 'beg' : 'geb'
    

    Here, you either get a beg or a geb, depending on the current filetype. Cool, it's getting interesting!

  4. Make it insert a crude snippet only when at the beginning of a line:

    inoremap <expr> beg col('.') == 1 ? 'begin{}<CR>end{}<C-o>O' : 'beg'
    

    one

  5. Make it possible to name the environment "dynamically":

    inoremap <expr> beg col('.') == 1 ? substitute('\begin{+++}<CR>\end{+++}','+++',input('environment: '),'g').'<C-o>O' : 'beg'
    

    two

OK. It works, but it feels clunky.

That's where one usually starts to wonder whether it is actually worth it to roll one's own when existing plugins already handle all that much more elegantly.

romainl
  • 186,200
  • 21
  • 280
  • 313
  • Thank you. That is terrifying, but i don't think it can be done better. For now I disabled continuous autocomplete, and made code with autocommands that makes what I wanted. – Don'tDownVote Apr 22 '22 at 21:24