7

I am about to re-read my 400-page book and mark certain words for indexing.

I'm looking for a set of VIM macros that would help me quickly go through the text marking words and group of words to be indexed. The ideas I have are:

  • A keystroke that index the current word (whether the cursor is on the first or any other letter). foobar becomes \alsoindex{foobar}
  • A keystroke that would index the word and the one that follows it. (foo bar becomes \alsoindex{foo bar})
  • A keystroke that indexes this and the next word as the key word (foo bar becomes foo bar\index{bar|foo})
  • A keystroke that indexes whatever text is highlighted

If I can really dream, I'd like the \index to be inserted after the punctuation. For example foo bar. Baz becomes foo bar.\index{bar} Baz

Is this beyond what VIM macros can do?

  • I'm pretty sure Emacs + AucTeX could do this. – Geremia Apr 21 '14 at 21:45
  • See, e.g., this that it can do. – Geremia Apr 21 '14 at 21:54
  • While RefTeX is the best tool for the job, this Q is very specific to vim. – Sean Allred May 3 '14 at 1:28
6

This can most certainly be done in Vim. Let me first give you methods for your four bullet points. I have made them all to be the shortcus <leader>i (i for index). If you do not know about <leader> I have made a small explanation below. The explanation of the commands are give below, as well.

  • A keystroke that index the current word:

    :nmap <leader>i "zdiwi\alsoindex{}<ESC>P
    
  • A keystroke that would index the word and the one that follows it:

    :nmap <leader>i "zd3iwi\alsoindex{}<ESC>P
    
  • A keystroke that indexes this and the next word as the key word:

    nmap <leader>i "zyiww"xyiwea\index{\|<ESC>"xPl"zpa}
    
  • A keystroke that indexes whatever text is highlighted:

    vmap <leader>i "zy`>a\index{}<ESC>"zP
    

And for the last question: I'm not shure exactly how distinguish between punctuation and other characters, but the command

nmap <leader>i "zyiwf i\index{}<ESC>"zP

will index the word under the cursor, but insert the \index command before the next whitespace


Now some notes:

Leader: The leader (or mapleader) is a key then it is a special key (you may choose which), that you can use to make easy shortcuts with, which can be set by the user (default is a backslash), and surplies an easy way to produce shortcuts. If the leader is a backslash, then <leader>i is the same as \i. More about leaders can be fond in :help leader or here.

Definition of words: Naturally the answer to your questions depend on the definition of a word. Vim has to different definitions of words. One is called a word and one is called a WORD. The first one is a string of letters, and the latter is strings seperated by whitespace. See :help word and :help WORD for the precise definitions. To change the commands from dealing with word's to deal with WORD's, every w should be changed to a W.

Registers: In the above commads z and x refers to registers (in all the cases), so they can be changed, to use different registers.

Mappings The commands only work in normal mode, except one which ony works in visual mode. This is the role of nmap and vmap. How these commands work and more about keymappings can be found here and here

Disclaimer: These commands only works if they are used when the cursor is placed on a word, and some only if there is a word after that one on the same line might do unexpected things if used in special cases. Also, the third command does not work properly if the last word is only one character long, and the fifth command does not work properly if the word is only one character long.

Explanations: Now for the explanations! They are actually all quite similar. Let's start with the top one, and then continue downwards.

  • The part "zdiw deletes the word under the cursor and stores it in register z. Try to take a look at :help iw. The part i\alsoindex{} sets Vim in insert mode and types \alsoindex{}. The part <ESC>P leaves insert mode and pastes the text in between the curly braces.

  • This one is the same as the previous, but now the part 3iw refers to the word under the curser and the next word (with the command iw spaces are also counted as words, and therefore it is 3iw instead of 2iw).

  • The part "zyiw yanks the word under the cursor to the register z, the part w moves the cursor to the begining og the next word, the part "xyiw yanks the new word under the cursor to the register x, the part ea moves to the end of the word and enters insert mode, the part \index{\| types \index{|, the part <ESC>"xP pastes the contents of register x inbetween { and |, the part l"zp moves the cursor one forward and pastes the contents of register z, and the part a} inserts the last }.

  • The part "zy yanks what's in the visual to the register z, the part `> moves the cursor to the end of the visual (which was just there), the part a\index{} goes into insert mode and types \index{}, and the part <ESC>"zP inserts the contents of register z between the curly braces.

Now for the explanation of the last command. This one is again as the others. The part "zyiw yanks the word under the cursor to register z, the part f i moves the cursor to the next whitespace and puts Vim in insert mode, and the part \index{}<ESC>"zP inserts the index commands with the contents of register z in it.

  • A tiny addition to this excellent answer: ) is the motion "to the next sentence", so instead of "forward to next whitespace" (f ) in the last mapping you could do "zyiw)hi\index{}<ESC>"zP where )hi means "next sentence, back one char, insert". – jjaderberg Mar 11 '15 at 18: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.