Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- " Windows common keyboard shortcuts and pasting behavior {{{
- " Online posts:
- " http://superuser.com/questions/321547/how-do-i-replace-paste-yanked-text-in-vim-without-yanking-the-deleted-lines
- " http://pastebin.com/aBEsm5mV
- " Recommended vimrc settings:
- " Set clipboard like this:
- " NOTE: Use ^= to prepend a value to a comma-separated list. See :h set^=
- " set clipboard^=unnamedplus " Works on Linux but has issues yanking on Windows.
- " set clipboard^=unnamed,unnamedplus " Works on Linux and Windows (and probably MacVim which needed the unnamed option the last time i used it).
- "
- " Set mouse like this:
- " set mouse=a " Ensures mouse binds work in all modes.
- "
- " Disable autoselect:
- " NOTE: This forces MiddleMouse clicks in other programs to paste the contents of Vim's "+ unnamedplus register instead of the "* unnamed selection register. See :h go-a
- " set guioptions-=a
- " set guioptions-=A
- "
- " NOTE: On Linux you need to keep the source-window of a copy-operation open for a paste to occur inside another window.
- " Unused code {{{
- " SOURCE: https://stackoverflow.com/questions/1533565/how-to-get-visually-selected-text-in-vimscript
- " SOURCE: http://stackoverflow.com/questions/17838700/vimscript-get-visual-mode-selection-text-in-mapping
- " function! s:GetVisualSelection()
- " let [line_start, column_start] = getpos("'<")[1:2]
- " let [line_end, column_end] = getpos("'>")[1:2]
- " let lines = getline(line_start, line_end)
- " if len(lines) == 0
- " return ''
- " endif
- " let lines[-1] = lines[-1][: column_end - (&selection ==? 'inclusive' ? 1 : 2)]
- " let lines[0] = lines[0][column_start - 1:]
- " return join(lines, "\n")
- " endfunction
- "
- " Example:
- " If selection is one character.
- " if strchars(GetVisualSelection()) == 1
- " endif
- " Move cursor one position to right
- " call cursor(0, col(".") + 1)
- " }}} Unused code
- " Functions {{{
- " Uncomment to enable debugging.
- " Check debug output with :messages
- " let s:debug_smart_cut = 1
- " let s:debug_smart_copy = 1
- " let s:debug_smart_paste = 1
- function! SmartCut() " {{{
- if !has('clipboard')
- echoerr 'Clipboard support is required to use this function.'
- return
- endif
- let clipboard_register = '+'
- " Restore the visual selection with 'gv' and delete the selection into the clipboard.
- " NOTE: 'd' (delete) is better than 'c' (copy) because it moves the caret to the right for us.
- execute 'normal! gv"' . clipboard_register . 'd'
- " Enter insert mode.
- startinsert
- " Gets the value if it exists, else returns 0.
- if get(s:, 'debug_smart_cut')
- echomsg "SmartCut"
- echomsg " clipboard contents: " . getreg(clipboard_register)
- endif
- endfunction " }}}
- function! SmartCopy() " {{{
- if !has('clipboard')
- echoerr 'Clipboard support is required to use this function.'
- return
- endif
- let clipboard_register = '+'
- " Restore the visual selection with 'gv' and yank the selection into the clipboard.
- execute 'normal! gv"' . clipboard_register . 'y'
- " Gets the value if it exists, else returns 0.
- if get(s:, 'debug_smart_copy')
- echomsg "SmartCopy"
- echomsg " clipboard contents: " . getreg(clipboard_register)
- endif
- endfunction " }}}
- function! SmartPaste() " {{{
- if !has('clipboard')
- echoerr 'Clipboard support is required to use this function.'
- return
- endif
- if !&modifiable
- return
- endif
- " See :help '> for more information. Hint: if you select some text and press ':' you will see :'<,'>
- " SOURCE: http://superuser.com/questions/723621/how-can-i-check-if-the-cursor-is-at-the-end-of-a-line
- " SOURCE: http://stackoverflow.com/questions/7262536/vim-count-lines-in-selected-range
- " SOURCE: https://git.zug.fr/config/vim/blob/master/init.vim
- " SOURCE: https://git.zug.fr/config/vim/blob/master/after/plugin/zzzmappings.vim
- let currentColumn = col(".")
- let currentLine = line(".")
- let lastVisibleLetterColumn = col("$") - 1
- let lastLineOfBuffer = line("$")
- let selectionEndLine = line("'>")
- let selectionEndLineLength = strchars(getline(selectionEndLine))
- let nextLineLength = strchars(getline(currentLine + 1))
- let selectionStartColumn = col("'<")
- let selectionEndColumn = col("'>")
- " If selection does not include or go beyond the last visible character of the line (by also selecting the invisible EOL character).
- if selectionEndColumn < selectionEndLineLength
- let pee = 'P'
- " Gets the value if it exists, else returns 0.
- if get(s:, 'debug_smart_paste')
- echomsg "SmartPaste special case #1"
- endif
- " If attempting to paste on a blank last line.
- elseif selectionEndLineLength == 0 && selectionEndLine == lastLineOfBuffer
- let pee = 'P'
- " Gets the value if it exists, else returns 0.
- if get(s:, 'debug_smart_paste')
- echomsg "SmartPaste special case #2"
- endif
- " 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 the next line is not blank,
- " and selection does not end on the last line.
- elseif selectionEndColumn > selectionEndLineLength && nextLineLength > 0 && selectionEndLine != lastLineOfBuffer
- let pee = 'P'
- " Gets the value if it exists, else returns 0.
- if get(s:, 'debug_smart_paste')
- echomsg "SmartPaste special case #3"
- endif
- else
- let pee = 'p'
- " Gets the value if it exists, else returns 0.
- if get(s:, 'debug_smart_paste')
- echomsg "SmartPaste default case"
- endif
- endif
- let clipboard_register = '+'
- " Gets the value if it exists, else returns 0.
- if get(s:, 'debug_smart_paste')
- echomsg "SmartPaste"
- echomsg " clipboard contents: " . getreg(clipboard_register)
- echomsg " currentColumn: " . currentColumn
- echomsg " currentLine: " . currentLine
- echomsg " lastVisibleLetterColumn: " . lastVisibleLetterColumn
- echomsg " lastLineOfBuffer: " . lastLineOfBuffer
- echomsg " selectionEndLine: " . selectionEndLine
- echomsg " selectionEndLineLength: " . selectionEndLineLength
- echomsg " nextLineLength: " . nextLineLength
- echomsg " selectionStartColumn: " . selectionStartColumn
- echomsg " selectionEndColumn: " . selectionEndColumn
- echomsg " pee: " . pee
- echomsg " selection bounds" . string([getpos("'<")[1:2], getpos("'>")[1:2]])
- echomsg " visualmode(): " . visualmode()
- echomsg " mode(): " . mode()
- echomsg " getpos('.'): " . string(getpos('.'))
- endif
- try
- " Enter paste mode.
- " NOTE: This prevents InsertCharPre autocommands from running repeatedly for each character in the pasted string.
- set paste
- " Backup clipboard.
- let clipboard_contents = getreg(clipboard_register)
- let clipboard_type = getregtype(clipboard_register)
- " If clipboard type is linewise.
- if clipboard_type[0] == 'V'
- " Change clipboard register to characterwise mode.
- call setreg(clipboard_register, clipboard_contents, 'v')
- endif
- " Restore the visual selection with 'gv' and paste the clipboard contents there.
- execute 'normal! gv"' . clipboard_register . pee
- " Restore clipboard.
- call setreg(clipboard_register, clipboard_contents, clipboard_type)
- catch /E353:\ Nothing\ in\ register/
- finally
- " Exit paste mode.
- set nopaste
- endtry
- endfunction " }}}
- function! SmartFind(...) " {{{
- let l:mode = get(a:000, 0, mode())
- if s:IsNormalMode(l:mode)
- let wordUnderCursor = expand('<cword>')
- if wordUnderCursor == ''
- execute 'promptfind'
- else
- execute 'promptfind' wordUnderCursor
- endif
- else
- let [line_start, column_start] = getpos("'<")[1:2]
- let [line_end, column_end] = getpos("'>")[1:2]
- let lines = getline(line_start, line_end)
- if len(lines) == 0
- execute 'promptfind'
- return
- endif
- let lines[-1] = lines[-1][: column_end - (&selection ==? 'inclusive' ? 1 : 2)]
- let lines[0] = lines[0][column_start - 1:]
- execute 'promptfind' lines[0]
- endif
- endfunction " }}}
- function! SmartReplace(...) " {{{
- let l:mode = get(a:000, 0, mode())
- if s:IsNormalMode(l:mode)
- let wordUnderCursor = expand('<cword>')
- if wordUnderCursor == ''
- execute 'promptrepl'
- else
- execute 'promptrepl' wordUnderCursor
- endif
- else
- let [line_start, column_start] = getpos("'<")[1:2]
- let [line_end, column_end] = getpos("'>")[1:2]
- let lines = getline(line_start, line_end)
- if len(lines) == 0
- execute 'promptrepl'
- return
- endif
- let lines[-1] = lines[-1][: column_end - (&selection ==? 'inclusive' ? 1 : 2)]
- let lines[0] = lines[0][column_start - 1:]
- execute 'promptrepl' lines[0]
- endif
- endfunction " }}}
- function! SmartSaveFile() " {{{
- " SOURCE: http://vim.wikia.com/wiki/Map_Ctrl-S_to_save_current_or_new_files
- " If file is saved.
- if !&modified
- return
- endif
- try
- " If the current buffer has no name.
- if empty(bufname('%'))
- " Display a save dialog so the user can specify a file name.
- browse confirm write
- else
- " Force a write even if a file exists with that name.
- confirm write
- endif
- catch /E212:\ Can't\ open\ file\ for\ writing/
- if has("win32") || has("win64")
- echomsg "ERROR: You lack write permission for this directory or the file name is not valid."
- else
- " NOTE: The [browse confirm write] call above will establish the filename in the case of an empty buffer.
- " NOTE: Try-catch needed because [redraw!] may erase an error message.
- try
- " A hack that uses tee to output the buffer to the % filename with sudo permissions.
- " SOURCE: https://stackoverflow.com/questions/2600783/how-does-the-vim-write-with-sudo-trick-work
- execute("w !sudo tee %")
- if v:shell_error
- throw 'Failed to save file.'
- else
- " Reload the file, otherwise vim will detect the file changed and ask you for permission to reload the file.
- silent edit!
- " Clears the command-line and removes 'Press ENTER or type command to continue' prompt.
- " SOURCE: https://vim.fandom.com/wiki/Avoiding_the_%22Hit_ENTER_to_continue%22_prompts
- redraw!
- endif
- catch /.*/
- echoerr 'SmartSaveFile() Unhandled Exception: ' . v:exception
- endtry
- endif
- endtry
- endfunction " }}}
- function! SmartCopyMessageHistory() " {{{
- redir @+
- silent execute(':messages')
- redir END
- endfunction " }}}
- " }}} Functions
- " Binds {{{
- " Paste for MiddleMouse in terminal, normal, visual, and insert mode {{{
- tnoremap <silent> <MiddleMouse> <C-w>"+
- " NOTE: <C-u> removes the '<,'> visual-selection from the command-line. See :h c_CTRL-u
- nnoremap <silent> <MiddleMouse> <C-v>:<C-u>call SmartPaste()<CR>
- " NOTE: <C-u> removes the '<,'> visual-selection from the command-line. See :h c_CTRL-u
- vnoremap <silent> <MiddleMouse> :<C-u>call SmartPaste()<CR>
- " Characterwise paste for insert mode.
- " SOURCE: https://vim.fandom.com/wiki/Pasting_registers
- " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
- " NOTE: <C-r>+ inserts the contents of the unnamedplus register during insert mode. See :h i_CTRL-R
- " NOTE: <C-r>+ doesn't work for Ctrl-v yanked and pasted columns of text. It forces characterwise selections to be linewise pasted. <C-r><C-o>+ works though.
- " [bad, triggers InsertCharPre for each pasted letter] inoremap <silent> <MiddleMouse> <C-r><C-r>+
- " [works] inoremap <silent> <MiddleMouse> <C-o>"+<MiddleMouse>
- " [works, but no need for paste mode i think because it doesn't trigger InsertCharPre events for each pasted letter] inoremap <silent> <MiddleMouse> <C-o>:set paste<CR><C-r><C-o>+<C-o>:set nopaste<CR>
- inoremap <silent> <MiddleMouse> <C-r><C-o>+
- " Disable weird multi-click things you can do with middle mouse button.
- " SOURCE: http://vim.wikia.com/wiki/Mouse_wheel_for_scroll_only_-_disable_middle_button_paste
- tnoremap <2-MiddleMouse> <Nop>
- nnoremap <2-MiddleMouse> <Nop>
- inoremap <2-MiddleMouse> <Nop>
- vnoremap <2-MiddleMouse> <Nop>
- tnoremap <3-MiddleMouse> <Nop>
- nnoremap <3-MiddleMouse> <Nop>
- inoremap <3-MiddleMouse> <Nop>
- vnoremap <3-MiddleMouse> <Nop>
- tnoremap <4-MiddleMouse> <Nop>
- nnoremap <4-MiddleMouse> <Nop>
- inoremap <4-MiddleMouse> <Nop>
- vnoremap <4-MiddleMouse> <Nop>
- " }}} Paste for MiddleMouse in terminal, normal, visual, and insert mode
- " If OS is not mac.
- if system('uname') !~ 'Darwin' " NOTE: MacVim provides Command+C|X|V|A|S and undo/redo functionality and also can Command+C|V to the command-line by default.
- " Paste functionality for terminal mode {{{
- tnoremap <silent> <C-v> <C-w>"+
- " }}} Paste functionality for terminal mode
- " Copy, paste, and select-all functionality for command-line {{{
- " SOURCE: https://opensource.apple.com/source/vim/vim-62.41.2/runtime/macmap.vim.auto.html
- " NOTE: Only copy and paste are possible in the command-line from what i can tell.
- " Their is no undo for text typed in the command-line and you cannot paste text onto a selection of text to replace it.
- cnoremap <C-c> <C-y>
- cnoremap <C-v> <C-r>+
- " Everyone seems to bind this. No way to select-all, but we can move the caret all the way to the left of the command-line. Yay.
- cnoremap <C-A> <Home>
- " Copy message history to the clipboard.
- " NOTE: This is a workaround for not being able to select all.
- nnoremap <silent> <Leader>m :<C-u>call SmartCopyMessageHistory()<CR>
- " }}} Copy, paste, select-all functionality for command-line
- " Cut, copy, paste functionality for visual and insert mode {{{
- " Cut, copy, and paste functionality for visual mode.
- " SOURCE: http://superuser.com/questions/10588/how-to-make-cut-copy-paste-in-gvim-on-ubuntu-work-with-ctrlx-ctrlc-ctrlv
- " NOTE: <C-u> removes the '<,'> visual-selection from the command-line. See :h c_CTRL-u
- vnoremap <silent> <C-x> :<C-u>call SmartCut()<CR>
- vnoremap <silent> <C-c> :<C-u>call SmartCopy()<CR>
- vnoremap <silent> <C-v> :<C-u>call SmartPaste()<CR>
- " Characterwise paste for insert mode.
- " SOURCE: https://vim.fandom.com/wiki/Pasting_registers
- " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
- " NOTE: <C-r>+ inserts the contents of the unnamedplus register during insert mode. See :h i_CTRL-R
- " NOTE: <C-r>+ doesn't work for Ctrl-v yanked and pasted columns of text. It forces characterwise selections to be linewise pasted. <C-r><C-o>+ works though.
- " [works, but no need for paste mode i think because it doesn't trigger InsertCharPre events for each pasted letter] inoremap <silent> <C-v> <C-o>:set paste<CR><C-r><C-o>+<C-o>:set nopaste<CR>
- inoremap <silent> <C-v> <C-r><C-o>+
- " }}} Cut, copy, paste functionality for visual and insert mode
- " Select-all functionality for normal, visual, and insert mode {{{
- " SOURCE: http://vim.wikia.com/wiki/Using_standard_editor_shortcuts_in_Vim
- nnoremap <C-a> ggVG
- vnoremap <C-a> ggVG
- inoremap <C-a> <Esc>ggVG
- " }}} Select-all functionality for normal, visual, and insert mode
- " Save functionality for normal, visual, and insert mode {{{
- nnoremap <silent> <C-s> :call SmartSaveFile()<CR>
- " NOTE: <C-u> removes the '<,'> visual-selection from the command-line. See :h c_CTRL-u
- vnoremap <silent> <C-s> :<C-u>call SmartSaveFile()<CR>gv
- " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
- inoremap <silent> <C-s> <C-o>:call SmartSaveFile()<CR>
- " }}} Save functionality for normal, visual, and insert mode
- " Undo and redo functionality for normal, visual, and insert mode {{{
- nnoremap <C-z> <Esc>u
- nnoremap <C-y> <Esc><C-r>
- " NOTE: <C-u> removes the '<,'> visual-selection from the command-line. See :h c_CTRL-u
- vnoremap <C-z> :<C-u>uV
- vnoremap <C-y> :<C-u><C-r>V
- inoremap <C-z> <Esc>uI
- inoremap <C-y> <Esc><C-r>I
- " Disable Vim normal-mode undo/redo keys.
- " Having a single key for undo is an accident waiting to happen, especially when 'u' and 'U' are also used as visual-mode character case toggles.
- " SOURCE: https://stackoverflow.com/questions/57714401/vi-vim-remap-or-unmap-built-in-command-the-u-key-in-visual-mode
- nnoremap u <NOP>
- nnoremap <C-r> <NOP>
- " }}} Undo and redo functionality for normal, visual, and insert mode
- " Find and Replace functionality for normal, visual, and insert mode {{{
- nnoremap <silent> <C-f> :call SmartFind('n')<CR>
- nnoremap <silent> <C-h> :call SmartReplace('n')<CR>
- " NOTE: <C-u> removes the '<,'> visual-selection from the command-line. See :h c_CTRL-u
- vnoremap <silent> <C-f> :<C-u>call SmartFind('v')<CR>
- vnoremap <silent> <C-h> :<C-u>call SmartReplace('v')<CR>
- " NOTE: <C-o> executes a normal-mode command without leaving insert mode. See :help ins-special-special
- inoremap <silent> <C-f> <C-o>:call SmartFind('i')<CR>
- inoremap <silent> <C-h> <C-o>:call SmartReplace('i')<CR>
- " }}} Find and Replace functionality for normal, visual, and insert mode
- endif
- " }}} Binds
- " }}} Windows common keyboard shortcuts and pasting behavior
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement