0

In bash shell, alt + . inserts the last argument of the previous command. and there are alt + (number) + . and alt + , variations.

I like to do the same while editing shell script in vim, i.e. I want to insert the last word from previous line when I press alt + . in insert mode. (alt + , as well if possible. alt + , after alt + .changes the last word to 2nd last and 3rd, and so on)

Line continuation using back slash is not considered at the moment and just the previous line as shown on the screen.

How can I do this? Is there a plugin for this?

1
  • 2
    A mapping might suffice (something like k$yawj$p); interactively, I’m more likely to use !$ which expands to the last word of the last command with history expansion enabled.
    – D. Ben Knoble
    Mar 5, 2022 at 15:34

1 Answer 1

0

I was curious about how alt+, could work in Vim so I made a quick and dirty proof of concept which you might find helpful to come up with your complete solution:

" Get the (last-count) word of the previous line and insert it
function MetaPoint(count)
    " Get the words of the previous line in a list
    let words=split(getline(line(".")-1), " ")
    " Get the index based on the count
    let index=len(words) - 1 - a:count

    if (index < 0)
        return
    endif

    " Insert the word after the cursor
    execute "normal! a" . words[index]
endfunction

" Delete the current word and replace it by the previous word of the previous line
function MetaComma()
    let g:prev_line_counter+=1
    normal! diW
    call MetaPoint(g:prev_line_counter)
endfunction

inoremap <M-.> <C-o>:let g:prev_line_counter=0 \| call MetaPoint(0)<CR>
inoremap <M-,> <C-o>:call MetaComma()<CR>

I think the comments make the code fairly easy to read but here are the important points:

  • MetaPoint() simply parses the previous line (It doesn't handle the case where you are on the first line), gets the count-th word starting for the end and uses :h :execute to add it after the cursor.
  • MetaComma() increments a counter, delete the word under the cursor and call MetaPoint() with the updated cursor. This is the mechanism we will use to delete the previous insertion and replace it by the previous word. Edge cases: If you didn't add a white space before call the function your previous word will be deleted. It also won't play nice if you have character directly after the cursor without white space.
  • The alt+. and alt+, are writtent <M-.> and <M-,> in Vim.
  • <M-.> reset the counter used to call MetaPoint from MetaComma this way each time you want to do a new insertion with <M-.> you reset to the last word. And when you use <M-,> after that you go back in the words.

There are many edge cases I didn't take into consideration to make the code robust but that might give you some inspiration to code up with you own complete and working code.

1
  • Thanks. I have no experience with vim script, but i will try. This would be good staring point.
    – auditory
    Mar 11, 2022 at 9:16

Your Answer

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

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