0

In this question: VIM Latex Suite repeating symbols with subscripts and superscripts Anthony created this magnificent vimscript code:

function! <SID>SubSuperscripts(keyOne, keyTwo)
  let l = strpart(getline("."), col(".")-4, 3)
  if len(l) == 3 && l[2] == a:keyOne
    return join(["\<bs>\<bs>\<bs>_", l[0], "^",  l[1]], "")
  else
    return a:keyTwo
  endif
endfunction
inoremap <buffer> <silent> & <C-R>=<SID>SubSuperscripts("^", "&")<CR>

With this, whenever I type x12^& I get "instamagically" x_1^2! This is a life saver! I do not know vimscript but I definitely need to learn some basic stuff there. In the meantime, can please somebody transform the above script to these variants?:

  • Typing p1x1 and then something like ^* to produce p_1(x_1)
  • Typing p12x12 and then something like ^( to produce p_1^2(x_1^2)

I have tried some things but they end with a mess. :)

2

Short answer

Copy the following into your ~/.vim/ftplugin/tex.vim file.

Typing p1x1 followed by ^* gives p_1(x_1):

function! <SID>SubBrackets(keyOne, keyTwo)
  let l = strpart(getline("."), col(".")-5, 4)
  if len(l) == 4 && l[3] == a:keyOne
    return join(["\<bs>\<bs>\<bs>\<bs>_", l[0], "(",  l[1], "_", l[2], ")"], "")
  else
    return a:keyTwo
  endif
endfunction
inoremap <buffer> <silent> * <C-R>=<SID>SubBrackets("^", "*")<CR>

You may want to ask yourself if you will ever need to type ^* before committing this key binding to muscle memory! Remember that you can change these key bindings.

Typing p12x12 followed by ^( gives p_1^2(x_1^2):

function! <SID>SubSuperBrackets(keyOne, keyTwo)
  let l = strpart(getline("."), col(".")-7, 6)
  if len(l) == 6 && l[5] == a:keyOne
    return join(["\<bs>\<bs>\<bs>\<bs>\<bs>\<bs>_", l[0], "^",  l[1],
          \ "(", l[2], "_", l[3], "^", l[4], ")"], "")
  else
    return a:keyTwo
  endif
endfunction
inoremap <buffer> <silent> ( <C-R>=<SID>SubSuperBrackets("^", "(")<CR>

How it works

I actually learnt Vimscript for the purposes of answering your previous question because I thought that it would be fun. For that reason, I don't completely understand some of the finer details, but I'll try to explain how the main parts of the first mapping works.

Throughout, let us assume that we have inserted p1x1 and then pressed ^*.

The most important part is:

inoremap <buffer> <silent> * <C-R>=<SID>SubBrackets("^", "*")<CR>

This is a key mapping that is called when * is pressed in insert mode (the i in inoremap is for insert mode). In short, this line tells vim to call the SubBrackets function with parameters "^" and "*".

Now for the body of the SubBrackets function.

  let l = strpart(getline("."), col(".")-5, 4)

If we have p1x1^, this line stores 1x1^ in the variable l, ignoring the leading p because it does not need to be manipulated.

  if len(l) == 4 && l[3] == a:keyOne

This is to check that there are 4 characters in l (for robustness) and to ensure that the previous character inserted (l[3]) is a:keyOne, which we chose to be "^". This explains how typing ^* in insert mode works.

(The a: prefix tells vim that keyOne is a local variable. A g: prefix refers to a global variable.)

Now, for where the magic happens:

    return join(["\<bs>\<bs>\<bs>\<bs>_", l[0], "(",  l[1], "_", l[2], ")"], "")

Remember that we want p_1(x_1) to replace p1x1^ after pressing *. By the way that these mappings work, we need the function to return a string; the join function allows us to concatenate the parts in the square brackets.

In the square brackets, we simply list the keystrokes that you would need to perform to transform p1x1^ into p_1(x_1). To insert a backspace, we use \<bs>. I am sure you can figure the rest out.

The final part of the function:

  else
    return a:keyTwo
  endif

ensures that * is inserted when the preceding character is not ^.

  • 1
    I don't use VIM, but you've clearly put a lot of effort into this answer. +1 Welcome to the site. – Steven B. Segletes Apr 8 '15 at 18:41
  • "You learnt vimscript for answering my question"? I am very flattered! vimscript seems "cryptic" (although a lot of people say it's not so difficult as it seems). I officially declare I'm in love with ViM. I use LaTeX for over a decade, but learning to edit in ViM is a breathtaking experience! Many thanks once again! – Konstantinos Apr 8 '15 at 19:30
  • 1
    Thank you both for your kind comments! Vim and LaTeX has also been a great combination for me in the last few years, so learning a little to answer your question was very educational for myself as well! – Anthony Apr 8 '15 at 20:21

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.