Skip to content

Instantly share code, notes, and snippets.

@AndrewRadev
Last active July 30, 2023 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrewRadev/f8670f7d2f9a7f1bea809e3366440a79 to your computer and use it in GitHub Desktop.
Save AndrewRadev/f8670f7d2f9a7f1bea809e3366440a79 to your computer and use it in GitHub Desktop.
Create a normal-mode Vim mapping to append characters to a line, respecting comments
" Place this file in autoload/put_at_end.vim.
"
" Create mappings in normal mode that call the function with the string to append:
"
" nnoremap <silent> z, :call put_at_end#Mapping(',')<cr>
" nnoremap <silent> z; :call put_at_end#Mapping(';')<cr>
" nnoremap <silent> z) :call put_at_end#Mapping('),')<cr>
"
" If you have repeat.vim installed, you can repeat the append with a .
"
function! put_at_end#Mapping(string) abort
let saved_view = winsaveview()
defer winrestview(saved_view)
defer s:Repeat(a:string)
if &commentstring == ''
exe 'normal! A' .. a:string
return
endif
if &commentstring == '/*%s*/'
let comment_regex = '//.*'
else
let comment_regex = substitute(&commentstring, '%s', '.*', '')
endif
call search('\S\s*\%(' .. comment_regex .. '\)\=$', 'Wc', line('.'))
let prefix = strpart(getline('.'), 0, col('.'))
if prefix !~# '\V'.escape(a:string, '\').'\m$'
exe 'normal! a' .. a:string
endif
endfunction
function! s:Repeat(string)
let mapping = ":silent call put_at_end#Mapping('" .. escape(a:string, "'") .. "')\<cr>"
silent! call repeat#set(mapping)
endfunction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment