FocusedWolf

Vim: Windows common keyboard shortcuts

Mar 21st, 2016 (edited)
213
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. " Windows common keyboard shortcuts and pasting behavior {{{
  2.  
  3. " Online posts:
  4. " http://superuser.com/questions/321547/how-do-i-replace-paste-yanked-text-in-vim-without-yanking-the-deleted-lines
  5. " http://pastebin.com/aBEsm5mV
  6.  
  7. " SOURCE: https://stackoverflow.com/questions/1533565/how-to-get-visually-selected-text-in-vimscript
  8. "function! s:GetVisualSelection()
  9. "    let [lnum1, col1] = getpos("'<")[1:2]
  10. "    let [lnum2, col2] = getpos("'>")[1:2]
  11. "    let lines = getline(lnum1, lnum2)
  12. "    if strchars(lines) == 0 "len(lines) == 0
  13. "        return ''
  14. "    endif
  15. "    let lines[-1] = lines[-1][: col2 - (&selection ==? 'inclusive' ? 1 : 2)]
  16. "    let lines[0] = lines[0][col1 - 1:]
  17. "    return join(lines, "\n")
  18. "endfunction
  19.  
  20. " SOURCE: http://stackoverflow.com/questions/17838700/vimscript-get-visual-mode-selection-text-in-mapping
  21. "function! s:GetVisualSelection()
  22. "    let l=getline("'<")
  23. "    let [line1,col1] = getpos("'<")[1:2]
  24. "    let [line2,col2] = getpos("'>")[1:2]
  25. "    return l[col1 - 1: col2 - 1]
  26. "endfunction
  27. "
  28. " Not sure i need GetVisualSelection() but here is an example of usage
  29. " If selection is one character
  30. " if strchars(GetVisualSelection()) == 1
  31. "    let cmd = 'P'
  32.  
  33. " Uncomment to enable debugging.
  34. " Check debug output with :messages
  35. "let s:debug_smart_cut = 1
  36. "let s:debug_smart_copy = 1
  37. "let s:debug_smart_paste = 1
  38.  
  39. function! SmartCut()
  40.    execute 'normal! gv"+c'
  41.  
  42.     if visualmode() != "\<C-v>" " If not Visual-Block mode
  43.         " Trim the last \r\n | \n | \r character in the '+' buffer
  44.         " NOTE: This messes up Visual-Block pasting.
  45.         let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
  46.     endif
  47.  
  48.     if exists("s:debug_smart_cut") && s:debug_smart_cut
  49.         echomsg "SmartCut '+' buffer: " . @+
  50.     endif
  51. endfunction
  52.  
  53. function! SmartCopy()
  54.     execute 'normal! gv"+y'
  55.  
  56.     if visualmode() != "\<C-v>" " If not Visual-Block mode
  57.         " Trim the last \r\n | \n | \r character in the '+' buffer
  58.         " NOTE: This messes up Visual-Block pasting.
  59.         let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
  60.     endif
  61.  
  62.     if exists("s:debug_smart_copy") && s:debug_smart_copy
  63.         echomsg "SmartCopy '+' buffer: " . @+
  64.     endif
  65. endfunction
  66.  
  67. " Delete to black hole register before pasting. This function is a smarter version of "_d"+P or "_dp to handle special cases better.
  68. " SOURCE: http://stackoverflow.com/questions/12625722/vim-toggling-buffer-overwrite-behavior-when-deleting
  69. function! SmartPaste()
  70.     let mode = 'gv'
  71.  
  72.     let delete = '"_d'
  73.  
  74.     let reg = '"+'
  75.  
  76.     " See :help '> for more information. Hint: if you select some text and press ':' you will see :'<,'>
  77.     " SOURCE: http://superuser.com/questions/723621/how-can-i-check-if-the-cursor-is-at-the-end-of-a-line
  78.     " SOURCE: http://stackoverflow.com/questions/7262536/vim-count-lines-in-selected-range
  79.     " SOURCE: https://git.zug.fr/config/vim/blob/master/init.vim
  80.     " SOURCE: https://git.zug.fr/config/vim/blob/master/after/plugin/zzzmappings.vim
  81.     let currentColumn = col(".")
  82.     let currentLine = line(".")
  83.     let lastVisibleLetterColumn = col("$") - 1
  84.     let lastLineOfBuffer = line("$")
  85.     let selectionEndLine = line("'>")
  86.     let selectionEndLineLength = strchars(getline(selectionEndLine))
  87.     let nextLineLength = strchars(getline(currentLine + 1))
  88.     let selectionStartColumn = col("'<")
  89.     let selectionEndColumn = col("'>")
  90.  
  91.     " If selection does not include or go beyond the last visible character of the line (by also selecting the invisible EOL character)
  92.     if selectionEndColumn < selectionEndLineLength
  93.         let cmd = 'P'
  94.  
  95.         if exists("s:debug_smart_paste") && s:debug_smart_paste
  96.             echomsg "SmartPaste special case #1"
  97.         endif
  98.  
  99.     " If attempting to paste on a blank last line
  100.     elseif selectionEndLineLength == 0 && selectionEndLine == lastLineOfBuffer
  101.         let cmd = 'P'
  102.  
  103.         if exists("s:debug_smart_paste") && s:debug_smart_paste
  104.             echomsg "SmartPaste special case #2"
  105.         endif
  106.  
  107.     " If selection ends after the last visible character of the line (by also selecting the invisible EOL character) and next line is not blank and not the last line
  108.     elseif selectionEndColumn > selectionEndLineLength && nextLineLength > 0 && selectionEndLine != lastLineOfBuffer
  109.         let cmd = 'P'
  110.  
  111.         if exists("s:debug_smart_paste") && s:debug_smart_paste
  112.             echomsg "SmartPaste special case #3"
  113.         endif
  114.  
  115.     " If selection ends after the last visible character of the line (by also selecting the invisible EOL character), or the line is visually selected (Shift + V), and next line is the last line
  116.     elseif selectionEndColumn > selectionEndLineLength && selectionEndLine == lastLineOfBuffer
  117.         " SOURCE:  http://vim.wikia.com/wiki/Quickly_adding_and_deleting_empty_lines
  118.  
  119.         " Fixes bug where if the last line is fully selected (Shift + V) and a paste occurs, that the paste appears to insert after the first character of the line above it because the delete operation [which occurs before the paste]
  120.         " is causing the caret to go up a line, and then 'p' cmd causes the paste to occur after the caret, thereby pasting after the first letter of that line.
  121.         " However this but does not occur if there's a blank line underneath the selected line, prior to deleting it, as the cursor goes down after the delete in that situation.
  122.         "
  123.         " Silent was added to suppress "W10: Warning: Changing a readonly file"
  124.         " I got this message while trying to edit a file that was not actually readonly but rather only administrator-editable because it was located in a protected Windows folder.
  125.         " Another way to fix this it is to do "set noro" (if &readonly), and reapply the readonly state after the append with "set ro" (if was readonly).
  126.         " NOTE: "silent!" hides error messages and normal messages, and "silent" just hides normal messages.
  127.         silent call append(selectionEndLine, "")
  128.  
  129.         let cmd = 'p'
  130.  
  131.         if exists("s:debug_smart_paste") && s:debug_smart_paste
  132.             echomsg "SmartPaste special case #4"
  133.         endif
  134.  
  135.     else
  136.         let cmd = 'p'
  137.  
  138.         if exists("s:debug_smart_paste") && s:debug_smart_paste
  139.             echomsg "SmartPaste default case"
  140.         endif
  141.     endif
  142.  
  143.     if exists("s:debug_smart_paste") && s:debug_smart_paste
  144.         echomsg "SmartPaste debug info:"
  145.         echomsg "    currentColumn: " . currentColumn
  146.         echomsg "    currentLine: " . currentLine
  147.         echomsg "    lastVisibleLetterColumn: " . lastVisibleLetterColumn
  148.         echomsg "    lastLineOfBuffer: " . lastLineOfBuffer
  149.         echomsg "    selectionEndLine: " . selectionEndLine
  150.         echomsg "    selectionEndLineLength: " . selectionEndLineLength
  151.         echomsg "    nextLineLength: " . nextLineLength
  152.         echomsg "    selectionStartColumn: " . selectionStartColumn
  153.         echomsg "    selectionEndColumn: " . selectionEndColumn
  154.         echomsg "    cmd: " . cmd
  155.         echo [getpos("'<")[1:2], getpos("'>")[1:2]]
  156.         echo "visualmode(): " . visualmode()
  157.         echo "mode(): " . mode()
  158.     endif
  159.  
  160.     if visualmode() != "\<C-v>" " If not Visual-Block mode
  161.         " Trim the last \r\n | \n | \r character in the '+' buffer
  162.         " NOTE: This messes up Visual-Block pasting.
  163.         let @+ = substitute(@+,'\(\r\?\n\|\r\)$','','g')
  164.     endif
  165.  
  166.     try
  167.         execute 'normal! ' . mode . delete . reg . cmd
  168.     catch /E353:\ Nothing\ in\ register\ +/
  169.     endtry
  170.  
  171.     " Move caret one position to right
  172.     call cursor(0, col(".") + 1)
  173. endfunction
  174.  
  175. " p or P delete to black hole register before pasting
  176. " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
  177. vnoremap <silent> p :<C-u>call SmartPaste()<CR>
  178. vnoremap <silent> P :<C-u>call SmartPaste()<CR>
  179.  
  180. " MiddleMouse delete to black hole register before pasting
  181. nnoremap <MiddleMouse> "+p " Changes default behavior from 'P' mode to 'p' mode for normal mode middle-mouse pasting
  182. " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
  183. vnoremap <silent> <MiddleMouse> :<C-u>call SmartPaste()<CR>
  184. inoremap <MiddleMouse> <C-r><C-o>+
  185.  
  186. " Copy :messages to the clipboard.
  187. " NOTE: This is a workaround for not being able to select-all + copy messages.
  188. nnoremap <silent> <Leader>m :redir @*<BAR>silent execute ':messages'<BAR>redir END<CR>
  189.  
  190. " Disable weird multi-click things you can do with middle mouse button
  191. " SOURCE: http://vim.wikia.com/wiki/Mouse_wheel_for_scroll_only_-_disable_middle_button_paste
  192. noremap <2-MiddleMouse> <NOP>
  193. inoremap <2-MiddleMouse> <NOP>
  194. noremap <3-MiddleMouse> <NOP>
  195. inoremap <3-MiddleMouse> <NOP>
  196. noremap <4-MiddleMouse> <NOP>
  197. inoremap <4-MiddleMouse> <NOP>
  198.  
  199. if os != "mac" " NOTE: MacVim provides Command+C|X|V|A|S and undo/redo support and also can Command+C|V to the command line by default.
  200.     " SOURCE: https://opensource.apple.com/source/vim/vim-62.41.2/runtime/macmap.vim.auto.html
  201.     " NOTE: Only copy and paste are possible in the command line from what i can tell.
  202.     "       Their is no undo for text typed in the command line and you cannot paste text onto a selection of text to replace it.
  203.     cnoremap <C-c> <C-y>
  204.     cnoremap <C-v> <C-r>+
  205.  
  206.     " Cut, copy, and paste support for visual and insert mode (not for normal mode)
  207.     " SOURCE: http://superuser.com/questions/10588/how-to-make-cut-copy-paste-in-gvim-on-ubuntu-work-with-ctrlx-ctrlc-ctrlv
  208.     " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
  209.     vnoremap <silent> <C-x> :<C-u>call SmartCut()<CR>
  210.     vnoremap <silent> <C-c> :<C-u>call SmartCopy()<CR>
  211.     vnoremap <silent> <C-v> :<C-u>call SmartPaste()<CR>
  212.     inoremap <C-v> <C-r><C-o>+
  213.  
  214.     " Select-all support for normal, visual, and insert mode
  215.     " http://vim.wikia.com/wiki/Using_standard_editor_shortcuts_in_Vim
  216.     nnoremap <C-a> ggVG
  217.     vnoremap <C-a> ggVG
  218.     inoremap <C-a> <Esc>ggVG
  219.  
  220.     " Save file support for normal, visual, and insert mode
  221.     " SOURCE: http://vim.wikia.com/wiki/Map_Ctrl-S_to_save_current_or_new_files
  222.     " If the current buffer has never been saved, it will have no name,
  223.     " call the file browser to save it, otherwise just save it.
  224.     command -nargs=0 -bar Update if &modified |
  225.                                 \    if empty(bufname('%')) |
  226.                                 \        browse confirm write |
  227.                                 \    else |
  228.                                 \        confirm write |
  229.                                 \    endif |
  230.                                 \endif
  231.     nnoremap <silent> <C-s> :update<CR>
  232.     " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
  233.     vnoremap <silent> <C-s> :<C-u>update<CR>V
  234.     " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
  235.     "inoremap <silent> <C-s> <C-o>:update<CR>
  236.     "
  237.     " <C-o> doesn't seem to work while also using the "Open the OmniCompletion menu as you type" code while the menu is visible.
  238.     " Doing "call feedkeys("\<C-x>\<C-o>", "n")" to perform omni completion seems to be the issue.
  239.     " However doing "call feedkeys("\<C-x>\<C-i>", "n")" to perform keywork completion seems to work without issue.
  240.     "
  241.     " Workaround will exit insert mode to execute the command and then enter insert mode.
  242.     inoremap <silent> <C-s> <Esc>:update<CR>I
  243.  
  244.     " Undo and redo support for normal, visual, and insert mode
  245.     " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
  246.     nnoremap <C-z> <Esc>u
  247.     vnoremap <C-z> :<C-u>uV
  248.     inoremap <C-z> <Esc>uI
  249.  
  250.     nnoremap <C-y> <Esc><C-r>
  251.     vnoremap <C-y> :<C-u><C-r>V
  252.     inoremap <C-y> <Esc><C-r>I
  253.  
  254.     " Disable Vim normal-mode undo/redo keys.
  255.     " NOTE: Disabled in part because <C-z> and <C-y> are mapped to undo/redo and also because visual-mode 'u' and 'U' manipulating the selected text case is useful, but also having 'u' as normal-mode undo is an accident waiting to happen.
  256.     " SOURCE: https://stackoverflow.com/questions/57714401/vi-vim-remap-or-unmap-built-in-command-the-u-key-in-visual-mode
  257.     nnoremap u <NOP>
  258.     nnoremap <C-r> <NOP>
  259.  
  260.     function! Find()
  261.         let wordUnderCursor = expand('<cword>')
  262.         if strchars(wordUnderCursor) > 0
  263.             execute 'promptfind ' . wordUnderCursor
  264.         else
  265.             execute 'promptfind'
  266.         endif
  267.     endfunction
  268.  
  269.     function! Replace()
  270.         let wordUnderCursor = expand('<cword>')
  271.         if strchars(wordUnderCursor) > 0
  272.             execute 'promptrepl ' . wordUnderCursor
  273.         else
  274.             execute 'promptrepl'
  275.         endif
  276.     endfunction
  277.  
  278.     " Find and Find/Replace support for normal, visual, and insert mode
  279.     nnoremap <silent> <C-f> :call Find()<CR>
  280.     nnoremap <silent> <C-h> :call Replace()<CR>
  281.  
  282.     " NOTE: <C-u> removes the '<,'> visual-selection from the command line. See :h c_CTRL-u
  283.     vnoremap <silent> <C-f> :<C-u>call Find()<CR>
  284.     vnoremap <silent> <C-h> :<C-u>call Replace()<CR>
  285.  
  286.     " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
  287.     inoremap <silent> <C-f> <C-o>:call Find()<CR>
  288.     inoremap <silent> <C-h> <C-o>:call Replace()<CR>
  289. endif
  290.  
  291. " }}} Windows common keyboard shortcuts and pasting behavior
  292.  
RAW Paste Data