9

Is it possible to start insertion in the end of word with a single keystroke? Currently I am using ea, but it does not allow me to use . to repeat the same action.

I really love A and I which operate with a line. Is there the same alternative, which operates with a word either w or W?

Let's say I have these lines:

object_name = "foo"
another_long_object_name = "bar"
again_different_length_word_which_needs_same_modification = "spam"

I would like to press a keystroke when standing in the middle of object_name and add a suffix _id then repeat the j. command two times to get this result:

object_name_id = "foo"
another_long_object_name_id = "bar"
again_different_length_word_which_needs_same_modification_id = "spam"
10
  • You could try to create a mapping but the repeatable part might be tricky. So what about using a macro? First qq to start recording in the q buffer, then ea_id to add _id at the end of the word, then optionally j0 to go at the beginning of the next line and finally q again to stop recording. You can then use @q to execute the macro once or 5@q to run it 5 times (that's when the j0 becomes useful). Or if the situation allows it (like in your example) a simple substitution command :%s/\w\+/&_id
    – statox
    Jan 10 at 13:19
  • @statox sounds like an answer!
    – D. Ben Knoble
    Jan 10 at 13:38
  • Ooh. If only you were dealing with words rather than WORDS because this would do, I think: nnoremap <leader>X a<c-g>U<c-right><c-g>U<left>
    – B Layer
    Jan 10 at 13:40
  • @D.BenKnoble Since you already posted an answer feel free to add the macro and substitution solutions in it I'm completely fine with that :)
    – statox
    Jan 10 at 15:36
  • 2
    @niekas I just remember about a pretty complete answer I wrote a while back on the question "Multiple cursors at desired location". I think you'll probably want to read it because that might give you a few ideas.
    – statox
    Jan 10 at 15:38

4 Answers 4

10
object_name = "foo"
another_long_object_name = "bar"
again_different_length_word_which_needs_same_modification = "spam"

I would like to press a keystroke when standing in the middle of object_name and add a suffix _id then repeat the j. command two times to get this result:

The way I do that is ce<Ctrl-r>-_id. You can repeat that with . since it's a single normal mode operation. The steps are:

  1. ce change to end of word, stay in insert mode
  2. <Ctrl-r>- insert what you just deleted with ce (the contents of the - register)
  3. continue inserting _id

Here's what ce<Ctrl-R>-_id<Esc>j.j. gets you:

object_name_id = "foo"
another_long_object_name_id = "bar"
again_different_length_word_which_needs_same_modification_id = "spam"

I really love A and I which operate with a line. Is there the same alternative, which operates with a word either w or W?

Unfortunately, all keys have other uses. You could :nmap operations like ea, bi, etc. to a new key sequence, or overwrite a single key's previous use. However, . would only repeat the last native normal-mode operation, rather than the whole mapping. There seems to be a repeat.vim plugin that allows repeating whole mappings with ., though. EDIT: This plugin won't work for this use-case though, because it requires appending a function call to the mapping and we can't do that because we want it to leave us in insert mode.

I and A are only shortcuts of ^i and $a because those movement and operation combinations are so common. I don't think ea, bi, Ea, and Bi are equally as common to justify getting a separate single-keystroke equivalent each when vim is already lacking keys. The only real benefit I think would be simpler repeatability, but that can be worked around like I described above with ce for ea and cE for Ea. For bi and Bi, you can typically do <Ctrl-v><vertical-movements>I, though you could also do cbfoo_<Ctrl-r>-<Esc>j.j. for bi and with cB for Bi if that's somehow better:

foo_object_name = "foo"
foo_another_long_object_name = "bar"
foo_again_different_length_word_which_needs_same_modification = "spam"
2
  • I was able to achieve A alternative for w and W with mappings map <a-a> ce<c-r>- and map <a-A> cE<c-r>-. Now I can press Alt+a to append to word. However, I would like to have the same shortcuts for I, but cb<c-r>- and cB<c-r>- does not work, because <c-r> moves the cursor after the pasted content. Any ideas how to solve it?
    – niekas
    Jan 11 at 20:42
  • @niekas No. You'd just have to type out cb<your-prefix><c-r>- when you want this. Even the repeat.vim plugin I mentioned won't let you create a repeatable mapping for bi because it requires appending a function call to end of the mapping, and you can't do that because you want it to leave you in insert mode. If you really, really want this mapping, I would suggest looking into modifying repeat.vim to see if it's possible to work around that requirement to let you prepend the function call instead, or by this point it may be simpler to modify the vim source code to add the commands.
    – JoL
    Jan 11 at 22:16
6

An alternative: use a search motion for “move and repeat” (n.):

/^\w\+\>/e<cr>a_id<esc>n.n.

A simpler search pattern in this case might be / =.

6

From @statox in the comments:

You could try to create a mapping but the repeatable part might be tricky. So what about using a macro? First qq to start recording in the q buffer, then ea_id to add _id at the end of the word, then optionally j0 to go at the beginning of the next line and finally q again to stop recording. You can then use @q to execute the macro once or 5@q to run it 5 times (that's when the j0 becomes useful). Or if the situation allows it (like in your example) a simple substitution command :%s/\w\+/&_id

3

For things like this I often reach for :normal. I imagine a q & @ would also work here:

:%norm ea_id

The idea is to run a set of normal command on a given range (whole buffer, %, in the above example). So go to the end of the first word, e, and append _id via a_id

You can use visual mode if you want with :normal to supply a range

For more help see:

:h :normal

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.