Skip to content

Instantly share code, notes, and snippets.

@roachsinai
Last active June 12, 2024 08:30
Show Gist options
  • Save roachsinai/92f1841d2d4940be789f0a5b434b113c to your computer and use it in GitHub Desktop.
Save roachsinai/92f1841d2d4940be789f0a5b434b113c to your computer and use it in GitHub Desktop.
minimal vimrc
"
" A (not so) minimal vimrc.
" https://github.com/mhinz/vim-galore/blob/master/static/minimal-vimrc.vim
"
" You want Vim, not vi. When Vim finds a vimrc, 'nocompatible' is set anyway.
" We set it explicitely to make our position clear!
set nocompatible
filetype plugin indent on " Load plugins according to detected filetype.
syntax on " Enable syntax highlighting.
set autoindent " Indent according to previous line.
set pastetoggle =<F2> " https://zhuanlan.zhihu.com/p/652837014
set expandtab " Use spaces instead of tabs.
set tabstop =4
set shiftwidth =4 " >> indents by 4 spaces.
set softtabstop =4
set shiftround " >> indents to next multiple of 'shiftwidth'.
set backspace =indent,eol,start " Make backspace work as you would expect.
set hidden " Switch between buffers without having to save first.
set laststatus =2 " Always show statusline.
set display =lastline " Show as much as possible of the last line.
set showmode " Show current mode in command-line.
set showcmd " Show already typed keys when more are expected.
set ttyfast " Faster redrawing.
set lazyredraw " Only redraw when necessary.
set splitbelow " Open new windows below the current window.
set splitright " Open new windows right of the current window.
set ignorecase smartcase
set number
highlight LineNr term=bold cterm=NONE ctermfg=DarkGrey ctermbg=NONE gui=NONE guifg=DarkGrey guibg=NONE
" set cursorline " Find the current line quickly.
set wrapscan " Searches wrap around end-of-file.
set report =0 " Always report changed lines.
set synmaxcol =200 " Only highlight the first 200 columns.
set list " Show non-printable characters.
if has('multi_byte') && &encoding ==# 'utf-8'
let &listchars = 'tab:▸ ,extends:❯,precedes:❮,nbsp:±'
else
let &listchars = 'tab:> ,extends:>,precedes:<,nbsp:.'
endif
" The fish shell is not very compatible to other shells and unexpectedly
" breaks things that use 'shell'.
if &shell =~# 'fish$'
set shell=/bin/bash
endif
" https://gist.github.com/meskarune/57b613907ebd1df67eb7bdb83c6e6641
" status bar colors
au InsertEnter * hi statusline guifg=black guibg=#d7afff ctermfg=black ctermbg=magenta
au InsertLeave * hi statusline guifg=black guibg=#8fbfdc ctermfg=black ctermbg=cyan
hi statusline guifg=black guibg=#8fbfdc ctermfg=black ctermbg=cyan
" Status line
" default: set statusline=%f\ %h%w%m%r\ %=%(%l,%c%V\ %=\ %P%)
" Status Line Custom
let g:currentmode={
\ 'n' : 'Normal',
\ 'no' : 'Normal·Operator Pending',
\ 'v' : 'Visual',
\ 'V' : 'V·Line',
\ '' : 'V·Block',
\ 's' : 'Select',
\ 'S' : 'S·Line',
\ '' : 'S·Block',
\ 'i' : 'Insert',
\ 'R' : 'Replace',
\ 'Rv' : 'V·Replace',
\ 'c' : 'Command',
\ 'cv' : 'Vim Ex',
\ 'ce' : 'Ex',
\ 'r' : 'Prompt',
\ 'rm' : 'More',
\ 'r?' : 'Confirm',
\ '!' : 'Shell',
\ 't' : 'Terminal'
\}
function! StatuslineGit()
" use tirm above vim 7.4, if not trim will show garbled code: ^[[?12;4$y
let l:branchname = \
substitute(system('git rev-parse --abbrev-ref HEAD 2>/dev/null'), '^\s*\(.\{-}\)\s*$', '\1', '')
return strlen(l:branchname) > 0?' '.l:branchname.' ':''
endfunction
function! ShrinkHome(path)
let home = expand('~')
let result = substitute(a:path, '^' . home, '~', '')
return result
endfunction
set laststatus=2
set noshowmode
set statusline=
set statusline+=%0*\ %{toupper(g:currentmode[mode()])}\ " The current mode
set statusline+=%0*\ %n\ " Buffer number
set statusline+=%1*\ %{pathshorten(ShrinkHome(expand('%:f')))}%m%r%h%w\ " File path, modified, readonly, helpfile, preview
"set statusline+=%{StatuslineGit()}
set statusline+=%3*│ " Separator
set statusline+=%2*\ %Y\ " FileType
set statusline+=%3*│ " Separator
set statusline+=%2*\ %{''.(&fenc!=''?&fenc:&enc).''} " Encoding
set statusline+=\ (%{&ff}) " FileFormat (dos/unix..)
set statusline+=%= " Right Side
set statusline+=%2*\ col:\ %02v\ " Colomn number
set statusline+=%3*│ " Separator
set statusline+=%1*\ ln:\ %02l/%L\ (%3p%%)\ " Line number / total lines, percentage of document
set statusline+=%{&paste?'PASTE':''}
" https://stackoverflow.com/questions/5375240/a-more-useful-statusline-in-vim
hi User1 ctermfg=007 ctermbg=239 guibg=#4e4e4e guifg=#adadad
hi User2 ctermfg=007 ctermbg=236 guibg=#303030 guifg=#adadad
hi User3 ctermfg=236 ctermbg=236 guibg=#303030 guifg=#303030
hi User4 ctermfg=239 ctermbg=239 guibg=#4e4e4e guifg=#4e4e4e
" https://jeffkreeftmeijer.com/vim-number/
set number
augroup numbertoggle
autocmd!
autocmd BufEnter,FocusGained,InsertLeave,WinEnter * if &nu && mode() != "i" | set rnu | endif
autocmd BufLeave,FocusLost,InsertEnter,WinLeave * if &nu | set nornu | endif
augroup END
" mac os
" set clipboard=unnamed
let mapleader=" "
nmap <leader>q :q<CR>
nmap <leader>w :w<CR>
nmap <leader>wq :wq<CR>
nmap <tab>q :qall<CR>
xnoremap < <gv
xnoremap > >gv
nmap <leader>d "+d
nmap <leader>p "+p
vmap <leader>d "+d
nmap <leader>; %
if exists('$TMUX')
nmap <leader>y <Plug>OSCYankOperator
nmap <leader>yy <leader>y_
vmap <leader>y <Plug>OSCYankVisual
else
nmap <leader>y "+y
vmap <leader>y "+y
endif
" let g:fcitx5_remote = $HOME . '/.local/bin/fcitx-remote'
" let g:fcitx5_remote = '/usr/local/bin/im-select'
let g:fcitx5_remote = '/opt/homebrew/bin/im-select'
if filereadable(expand('~/.vim/autoload/plug.vim'))
call plug#begin()
if filereadable(g:fcitx5_remote)
Plug 'roachsinai/fcitx.vim', { 'branch': 'macos' }
endif
Plug 'ojroques/vim-oscyank', {'branch': 'main'}
call plug#end()
endif
if !has('gui_running') && !(has('win32') || has('win64'))
" set t_kb
endif
inoremap <C-h> <left>
inoremap <C-j> <down>
inoremap <C-k> <up>
inoremap <C-l> <right>
inoremap <c-a> <home>
inoremap <c-e> <end>
inoremap <c-d> <del>
inoremap <c-_> <c-k>
inoremap <c-b> <c-left>
inoremap <c-f> <c-right>
cnoremap <c-h> <left>
cnoremap <c-j> <down>
cnoremap <c-k> <up>
cnoremap <c-l> <right>
cnoremap <c-a> <home>
cnoremap <c-e> <end>
cnoremap <c-d> <del>
cnoremap <c-_> <c-k>
cnoremap <c-b> <c-left>
cnoremap <c-f> <c-right>
" show commands begin with current inputs
cnoremap <m-f> <c-d>
" https://vi.stackexchange.com/a/3029/16299
function! Preserve(command)
" Preparation: save window state
let l:saved_winview = winsaveview()
" Run the command:
execute a:command
" Clean up: restore previous window position
call winrestview(l:saved_winview)
endfunction
nnoremap <leader>sw :call Preserve("%s/\\s\\+$//e")<CR>
xnoremap <leader>sw :call Preserve("'<,'>s/\\s\\+$//e")<CR>
hi TrailingWhitespace ctermbg=red guibg=red
call matchadd("TrailingWhitespace", '\v\s+$')
" needed in macos using iTerm2
if $TMUX != ''
set ttimeoutlen=20
elseif &ttimeoutlen > 60 || &ttimeoutlen <= 0
set ttimeoutlen=60
endif
" Get the directory of a file
" - On Ex command lines, returns the directory of the file ('./' for new files)
" - On other command lines (/,?) returns the keymap used to trigger it
function! CommandDir(keymap) abort
let l:command_type = getcmdtype()
if l:command_type isnot# ':'
return a:keymap
endif
let l:dir = expand('%:h')
if empty(l:dir)
let l:dir = '.'
endif
return l:dir . '/'
endfunction
" Quickly input the directory of the current file on the command line
cnoremap <expr> %% CommandDir('%%')
" Need 'recursive' mapping here for %%
nmap <leader>n :e %%
function! GotoLineWithString(str)
let l:line_number = 1
while l:line_number <= line("$")
if getline(l:line_number) == a:str
call setpos('.', [0, l:line_number, 1, 0])
return
endif
let l:line_number += 1
endwhile
echo "No matching line found."
endfunction
" https://stackoverflow.com/a/60643538/6074780
" |¦┆┊│⎸ ▏
set fillchars+=vert:\│
hi clear VertSplit
hi VertSplit guifg=black ctermfg=darkGrey
" https://vi.stackexchange.com/a/21800/16299
" https://vonheikemen.github.io/devlog/tools/using-netrw-vim-builtin-file-explorer/
" Explore
let g:NetrwIsOpen=0
function! ToggleNetrw(...)
if g:NetrwIsOpen
let g:NetrwIsOpen=0
let i = bufnr("$")
while (i >= 1)
if (getbufvar(i, "&filetype") == "netrw")
silent exe "bwipeout " . i
endif
let i-=1
endwhile
else
let g:NetrwIsOpen=1
let g:prev_fname = expand("%:t")
if a:0 > 0
silent exe "Vexplore " . a:1
else
" https://github.com/vim/vim/tags?after=v7.4.001
silent Vexplore " no Lexplore on 7.4
endif
call GotoLineWithString(g:prev_fname)
endif
endfunction
if has('mac')
" https://github.com/vim/vim/issues/4738#issuecomment-856925080
let g:netrw_http_cmd = 'open'
endif
let g:netrw_keepdir = 0
let g:netrw_winsize = 15
let g:netrw_banner = 0
let g:netrw_list_hide = '\(^\|\s\s\)\zs\.\S\+'
let g:netrw_localcopydircmd = 'cp -r'
hi! link netrwMarkFile Search
nnoremap <leader>l :call ToggleNetrw("%:p:h")<CR>
nnoremap <leader>L :call ToggleNetrw()<CR>
function! NetrwLExp()
let l:filename = getline(".")
let l:lastchar = l:filename[-1:]
if index(["@", "*", "/"], l:lastchar) >= 0
let l:filename = l:filename[:-2]
endif
let l:filename = expand('%:p:h') . '/' . l:filename
if !isdirectory(l:filename)
wincmd p
" else
" exec "normal! \<Plug>NetrwLocalBrowseCheck"
endif
exec 'edit ' . l:filename
if &hlsearch
set nohlsearch
endif
endfunction
function! NetrwMapping()
" nmap must reset each time swith to netrw window on 7.4
nmap <buffer> H u
nmap <buffer> h -^
nmap <buffer> l <CR>
nmap <buffer> <CR> :call NetrwLExp()<CR>
nmap <buffer> . gh
nmap <buffer> P <C-w>z
nmap <buffer> <c-l> :vertical resize +5<cr>
" must move call GotoLineWithString(g:prev_fname)
" to TmuxMove, as not work at here on 7.4
endfunction
augroup netrw_mapping
autocmd!
autocmd FileType netrw call NetrwMapping() " filetype not working on 7.4
augroup END
set directory^=$HOME/.vim/swap//
set undofile
set undodir=$HOME/.vim/undo
" if !isdirectory(&undodir)
" call mkdir(&undodir, 'p', 0755)
" endif
" https://stackoverflow.com/a/14449484/6074780
autocmd BufReadPost *
\ if line("'\"") > 0 && line("'\"") <= line("$") |
\ exe "normal! g`\"" |
\ endif
nmap <leader>cs :.s/\[\zs.*\ze]/\=substitute(submatch(0), '_', '\\_', 'g')/<CR>
nmap <leader>zs k0Di[]<esc>PJxDa()<esc>P0
" https://github.com/vim-scripts/BufOnly.vim/blob/master/plugin/BufOnly.vim
command! -nargs=? -complete=buffer -bang Bonly
\ :call BufOnly('<args>', '<bang>')
command! -nargs=? -complete=buffer -bang BOnly
\ :call BufOnly('<args>', '<bang>')
command! -nargs=? -complete=buffer -bang Bufonly
\ :call BufOnly('<args>', '<bang>')
command! -nargs=? -complete=buffer -bang BufOnly
\ :call BufOnly('<args>', '<bang>')
function! BufOnly(buffer, bang)
if a:buffer == ''
" No buffer provided, use the current buffer.
let buffer = bufnr('%')
elseif (a:buffer + 0) > 0
" A buffer number was provided.
let buffer = bufnr(a:buffer + 0)
else
" A buffer name was provided.
let buffer = bufnr(a:buffer)
endif
if buffer == -1
echohl ErrorMsg
echomsg "No matching buffer for" a:buffer
echohl None
return
endif
let last_buffer = bufnr('$')
let delete_count = 0
let n = 1
while n <= last_buffer
if n != buffer && buflisted(n)
if a:bang == '' && getbufvar(n, '&modified')
echohl ErrorMsg
echomsg 'No write since last change for buffer'
\ n '(add ! to override)'
echohl None
else
silent exe 'bdel' . a:bang . ' ' . n
if ! buflisted(n)
let delete_count = delete_count+1
endif
endif
endif
let n = n+1
endwhile
if delete_count == 1
echomsg delete_count "buffer deleted"
elseif delete_count > 1
echomsg delete_count "buffers deleted"
endif
endfunction
" delete buffer without losing the split window
nnoremap <silent> <leader>bd :bp\|bd #<CR>
" delete all buffers except current
" command! BufOnly silent! execute "%bd|e#|bd#"
nnoremap <silent> <leader>bo :BufOnly<CR>
nnoremap <leader>co :copen<CR>
nnoremap <leader>cc :cclose<CR>
" https://www.zhihu.com/question/636018229/answer/3386613023
" Vim 7.4 not support function execute()
command! -range ExecVimL call ExecVimLRange(<line1>, <line2>)
command! -range ExecLua call ExecLuaRange(<line1>, <line2>)
function! ExecVimLRange(line1, line2)
let l:vim_code = join(getline(a:line1, a:line2), "\n")
" https://vi.stackexchange.com/a/29508/16299
let l:vim_code = substitute(l:vim_code, '\n\s*\\\s*', ' ', 'g')
execute l:vim_code
endfunction
function! ExecLuaRange(line1, line2)
let l:lua_code = join(getline(a:line1, a:line2), "\n")
execute 'lua ' . l:lua_code
endfunction
" [S]ource
nnoremap <silent> <expr> <leader>s ((&ft=='lua' ? ':ExecLua' : ':ExecVimL') . '<cr>:<c-u>echo "Current line executed"<cr>')
xnoremap <silent> <expr> <leader>s ((&ft=='lua' ? ':ExecLua' : ':ExecVimL') . '<cr>:<c-u>echo "Selected range executed"<cr>')
" https://stackoverflow.com/a/16679182/6074780
" delete file from Disk
" shfit+d in :Ex
nnoremap <leader>rm :call delete(expand('%')) \| bdelete!<CR>
" https://vi.stackexchange.com/a/2187/16299
" buffer list
nnoremap <leader>bl :set nomore <Bar> :ls <Bar> :set more <CR>:b<Space>
" https://skywind3000.com/blog/archives/2021/ <leader>zs not work
" https://blog.lilydjwg.me/posts/23574.html '.' not work
" https://github.com/skywind3000/vim/blob/master/plugin/altmeta.vim#L25
function! Set_key(key, keyCode)
if get(g:, 'altmeta_skip_meta', 0) == 0
execute "set " . a:key . "=" . a:keyCode
endif
endfunc
function! Init_meta_letters()
let c = 'a'
while c <= 'z'
call Set_key("<M-" . c . ">", "\e" . c)
let c = nr2char(char2nr(c) + 1)
endwhile
endfunc
call Init_meta_letters()
let g:prev_fname = ''
" https://www.zhihu.com/question/278228687/answer/413375553
" https://gist.github.com/mislav/5189704?permalink_comment_id=3312967#gistcomment-3312967
function! TmuxMove(direction)
if a:direction == 'h'
" suppose current buffer is not netrw
let g:prev_fname = expand("%:t")
endif
if &hlsearch
set nohlsearch
redraw
endif
let wnr = winnr()
silent! execute 'wincmd ' . a:direction
" If the winnr is still the same after we moved, it is the last pane
if wnr == winnr()
call system('tmux select-pane -' . tr(a:direction, 'phjkl', 'lLDUR'))
elseif &filetype == "netrw"
if line('$') == 2 && getline(1) == getline(2)
exec "normal! \<Plug>NetrwRefresh"
endif
call GotoLineWithString(g:prev_fname)
end
endfunction
nnoremap <silent> <m-h> :call TmuxMove('h')<cr>
nnoremap <silent> <m-j> :call TmuxMove('j')<cr>
nnoremap <silent> <m-k> :call TmuxMove('k')<cr>
nnoremap <silent> <m-l> :call TmuxMove('l')<cr>
inoremap <m-h> <esc>:call TmuxMove('h')<cr>
inoremap <m-l> <esc>:call TmuxMove('j')<cr>
inoremap <m-j> <esc>:call TmuxMove('k')<cr>
inoremap <m-k> <esc>:call TmuxMove('l')<cr>
noremap <m-H> <c-w>H
noremap <m-L> <c-w>L
noremap <m-J> <c-w>J
noremap <m-K> <c-w>K
inoremap <m-H> <esc><c-w>H
inoremap <m-L> <esc><c-w>L
inoremap <m-J> <esc><c-w>J
inoremap <m-K> <esc><c-w>K
if has('terminal') && exists(':terminal') == 2 && has('patch-8.1.1')
" vim 8.1 支持 termwinkey ,不需要把 terminal 切换成 normal 模式
" 设置 termwinkey 为 CTRL 加减号(GVIM),有些终端下是 CTRL+?
" 后面四个键位是搭配 termwinkey 的,如果 termwinkey 更改,也要改
set termwinkey=<c-_>
tnoremap <m-h> <c-_>h
tnoremap <m-l> <c-_>l
tnoremap <m-j> <c-_>j
tnoremap <m-k> <c-_>k
tnoremap <m-q> <c-\><c-n>
elseif has('nvim')
" neovim 没有 termwinkey 支持,必须把 terminal 切换回 normal 模式
tnoremap <m-h> <c-\><c-n><c-w>h
tnoremap <m-l> <c-\><c-n><c-w>l
tnoremap <m-j> <c-\><c-n><c-w>j
tnoremap <m-k> <c-\><c-n><c-w>k
tnoremap <m-q> <c-\><c-n>
endif
nnoremap <c-l> :vertical resize +5<cr>
nnoremap <c-k> :resize +5<cr>
nnoremap <c-j> :resize -5<cr>
nnoremap <c-h> :vertical resize -5<cr>
" insert tab at beginning of each line of current buffer
nnoremap <leader>it :%s/^/\t/g<CR>
" format zhihu share
nmap <leader>zs k0Di[]<esc>PJxDa()<esc>P0
" format csdn link/share
nmap <leader>cs :.s/\[\zs.*\ze]/\=substitute(submatch(0), '_', '\\_', 'g')/<CR>
" https://stackoverflow.com/a/61624228/6074780
vnoremap al :<C-U>normal 0v$h<CR>
omap al :normal val<CR>
vnoremap il :<C-U>normal ^vg_<CR>
omap il :normal vil<CR>
vnoremap ae :<C-U>normal ggVG<CR>
omap ae :normal vae<CR>
vnoremap ie :<C-U>normal ggvG$<CR>
omap ie :normal vie<CR>
function! GetRootDir()
let l:current_file = expand('%:p')
while l:current_file != '/'
let l:current_file = fnamemodify(l:current_file, ':h')
if filereadable(l:current_file . '/.git') || filereadable(l:current_file . '/.root')
return l:current_file
endif
endwhile
return getcwd()
endfunction
" https://dev.to/pbnj/interactive-fuzzy-finding-in-vim-without-plugins-4kkj
function! FZF() abort
let l:tempname = tempname()
" fzf | awk '{ print $1":1:0" }' > file
let l:cwd = fnameescape(GetRootDir())
if l:cwd == getcwd()
execute 'silent !fzf --multi ' . '| sed ''s/$/:1:0/'' > ' . fnameescape(l:tempname)
else
execute 'silent !find ' . l:cwd . ' -mindepth 1 | fzf --multi ' . '| sed ''s/$/:1:0/'' > ' . fnameescape(l:tempname)
endif
try
execute 'cfile ' . l:tempname
redraw!
finally
call delete(l:tempname)
endtry
endfunction
" :Files
command! -nargs=* Files call FZF()
nnoremap <leader>e :Files<cr>
function! RG(args) abort
let l:tempname = tempname()
let l:pattern = '.'
if len(a:args) > 0
let l:pattern = a:args
endif
let l:cwd = fnameescape(GetRootDir())
" rg --vimgrep <pattern> | fzf -m > file
execute 'silent !rg --vimgrep ''' . l:pattern . ''' ' . l:cwd . ' | fzf -m > ' . fnameescape(l:tempname)
try
execute 'cfile ' . l:tempname
redraw!
finally
call delete(l:tempname)
endtry
endfunction
" :Rg [pattern]
command! -nargs=* Rg call RG(<q-args>)
nnoremap <Leader>aw :Rg <cword><cr>
nnoremap <Leader>ai :Rg<space>
highlight MatchParen
\ cterm=underline,bold ctermbg=NONE ctermfg=lightblue
\ gui=underline,bold guibg=NONE guifg=lightblue
highlight Search
\ cterm=reverse,bold ctermfg=108 ctermbg=235
\ gui=reverse,bold guifg=#8ec07c guibg=#282828
hi Visual cterm=none ctermbg=darkgrey ctermfg=cyan
set incsearch " Highlight while searching with / or ?.
set nohlsearch " disable explicitely as hlsearch on default in Vim 7.4
" same effect as: highlight clear Search
" https://www.reddit.com/r/neovim/comments/j6ugb4/comment/g91ru7q
" highlight last searched until CursorMoved
function! HLNext()
" SpellRare when select only one character
let l:higroup = matchend(getline('.'), '\c'.@/, col('.')-1) == col('.')
\ ? 'SpellRare' : 'IncSearch'
let b:match_id = matchadd(l:higroup, '\c\%#'.@/, 101)
if !&hlsearch
set hlsearch
redraw
call HLNextAug()
endif
endfunction
function! HLSearch()
let b:hlsearch_on = 1
if !&hlsearch
set hlsearch
redraw
call HLNextAug()
endif
endfunction
function! HLNextAug()
augroup HLNext
autocmd!
autocmd CursorMoved <buffer> call RemoveHighlight()
augroup END
endfunction
function! RemoveHighlight()
if exists('b:match_id')
silent! call matchdelete(b:match_id)
unlet b:match_id
if &hlsearch
set nohlsearch
redraw
endif
endif
if exists('b:hlsearch_on')
let l:search_reg = getreg("/")
let l:current_line = getline('.')
let l:cursor_col = col('.')
let l:content_after_cursor = current_line[cursor_col - 1 : cursor_col + len(l:search_reg) - 2]
if l:content_after_cursor == l:search_reg
return
endif
unlet b:hlsearch_on
if &hlsearch
set nohlsearch
redraw
endif
endif
endfunction
nnoremap <silent> * *:call HLNext()<CR>
nnoremap <silent> # #:call HLNext()<CR>
nnoremap <silent> n n:call HLNext()<CR>
nnoremap <silent> N N:call HLNext()<CR>
" Set the search register '@/' to the last or current visually selected text
function! VSetSearchReg()
let temp = @s
norm! gv"sy
let @/ = '\V' . substitute(escape(@s, '/\'), '\n', '\\n', 'g')
let @s = temp
endfunction
xnoremap <silent> * :<C-u>call VSetSearchReg()<CR>/<C-R>/<CR>:call HLNext()<CR>
xnoremap <silent> # :<C-u>call VSetSearchReg()<CR>?<C-R>/<CR>:call HLNext()<CR>
nnoremap / :call HLSearch()<CR>/
nnoremap ? :call HLSearch()<CR>?
" https://stackoverflow.com/a/10362177/6074780
" https://stackoverflow.com/a/20836543/6074780
command! -bar -nargs=1 -bang -complete=file Rename :
\ let s:file = expand('%:p') |
\ setlocal modified |
\ keepalt saveas<bang> <args> |
\ if s:file !=# expand('%:p') |
\ call delete(s:file) |
\ endif |
\ unlet s:file
nnoremap <leader>m :call FileOperationMenu()<CR>
function! FileOperationMenu()
let l:prev_cwd = getcwd()
execute 'cd' fnameescape(expand('%:p:h'))
let l:file_name = expand("%:t")
let l:cwd = getcwd()
let l:pcwd = l:prev_cwd
if has('win32') || has('win16') || has('win64') || has('win95')
let l:cwd = substitute(l:cwd, "\\", '/', 'g')
let l:pcwd = substitute(l:prev_cwd, "\\", '/', 'g') . '/'
endif
let l:actions = [':e ', ':Rename ', ':Move ', ':Chmod ', ':Delete!']
let l:action_prompts = ['Create file: ',
\ 'Rename file to: ' . l:cwd . '/',
\ 'Move file to: ',
\ 'Input permission: ']
let l:action_default_parameter = [l:cwd . '/', l:file_name, l:pcwd, '']
let l:count = len(l:actions) - 1
execute 'cd' l:prev_cwd
let l:choice = confirm('Action?', "&New file/directory\n&Rename\n&Move\n&Chmod\n&Delete", 0)
redraw
if l:choice == 0 | return | endif
" Delete 一个没有保存到硬盘上的 buffer 会报错,通常是一个新建的 blank buffer
if getbufvar('%', '&mod') && (l:choice == 2 || l:choice == 4 || l:choice == 5)
echo "Please save buffer first!"
return
endif
let l:choice -= 1
if l:choice != l:count
let l:text = l:action_default_parameter[l:choice]
let l:command_arg = input(l:action_prompts[l:choice], l:text)
if l:command_arg == "" || l:command_arg ==# l:text
redraw
echo "No file operation."
return
endif
else
let l:command_arg = ""
endif
exe l:actions[l:choice] . command_arg
endfunction
" https://gist.github.com/voyeg3r/223f148a115c17a02a15660cc7335f4c
" Plugin https://github.com/tpope/vim-commentary
function! s:surroundings() abort
return split(get(b:, 'commentary_format', substitute(substitute(substitute(
\ &commentstring, '^$', '%s', ''), '\S\zs%s',' %s', '') ,'%s\ze\S', '%s ', '')), '%s', 1)
endfunction
function! s:strip_white_space(l,r,line) abort
let [l, r] = [a:l, a:r]
if l[-1:] ==# ' ' && stridx(a:line,l) == -1 && stridx(a:line,l[0:-2]) == 0
let l = l[:-2]
endif
if r[0] ==# ' ' && (' ' . a:line)[-strlen(r)-1:] != r && a:line[-strlen(r):] == r[1:]
let r = r[1:]
endif
return [l, r]
endfunction
function! s:go(...) abort
if !a:0
let &operatorfunc = matchstr(expand('<sfile>'), '[^. ]*$')
return 'g@'
elseif a:0 > 1
let [lnum1, lnum2] = [a:1, a:2]
else
let [lnum1, lnum2] = [line("'["), line("']")]
endif
let [l, r] = s:surroundings()
let uncomment = 2
let force_uncomment = a:0 > 2 && a:3
for lnum in range(lnum1,lnum2)
let line = matchstr(getline(lnum),'\S.*\s\@<!')
let [l, r] = s:strip_white_space(l,r,line)
if len(line) && (stridx(line,l) || line[strlen(line)-strlen(r) : -1] != r)
let uncomment = 0
endif
endfor
if get(b:, 'commentary_startofline')
let indent = '^'
else
let indent = '^\s*'
endif
let lines = []
for lnum in range(lnum1,lnum2)
let line = getline(lnum)
if strlen(r) > 2 && l.r !~# '\\'
let line = substitute(line,
\'\M' . substitute(l, '\ze\S\s*$', '\\zs\\d\\*\\ze', '') . '\|' . substitute(r, '\S\zs', '\\zs\\d\\*\\ze', ''),
\'\=substitute(submatch(0)+1-uncomment,"^0$\\|^-\\d*$","","")','g')
endif
if force_uncomment
if line =~ '^\s*' . l
let line = substitute(line,'\S.*\s\@<!','\=submatch(0)[strlen(l):-strlen(r)-1]','')
endif
elseif uncomment
let line = substitute(line,'\S.*\s\@<!','\=submatch(0)[strlen(l):-strlen(r)-1]','')
else
let line = substitute(line,'^\%('.matchstr(getline(lnum1),indent).'\|\s*\)\zs.*\S\@<=','\=l.submatch(0).r','')
endif
call add(lines, line)
endfor
call setline(lnum1, lines)
let modelines = &modelines
try
set modelines=0
silent doautocmd User CommentaryPost
finally
let &modelines = modelines
endtry
return ''
endfunction
function! s:textobject(inner) abort
let [l, r] = s:surroundings()
let lnums = [line('.')+1, line('.')-2]
for [index, dir, bound, line] in [[0, -1, 1, ''], [1, 1, line('$'), '']]
while lnums[index] != bound && line ==# '' || !(stridx(line,l) || line[strlen(line)-strlen(r) : -1] != r)
let lnums[index] += dir
let line = matchstr(getline(lnums[index]+dir),'\S.*\s\@<!')
let [l, r] = s:strip_white_space(l,r,line)
endwhile
endfor
while (a:inner || lnums[1] != line('$')) && empty(getline(lnums[0]))
let lnums[0] += 1
endwhile
while a:inner && empty(getline(lnums[1]))
let lnums[1] -= 1
endwhile
if lnums[0] <= lnums[1]
execute 'normal! 'lnums[0].'GV'.lnums[1].'G'
endif
endfunction
command! -range -bar -bang Commentary call s:go(<line1>,<line2>,<bang>0)
xnoremap <expr> <Plug>Commentary <SID>go()
nnoremap <expr> <Plug>Commentary <SID>go()
nnoremap <expr> <Plug>CommentaryLine <SID>go() . '_'
onoremap <silent> <Plug>Commentary :<C-U>call <SID>textobject(get(v:, 'operator', '') ==# 'c')<CR>
nnoremap <silent> <Plug>ChangeCommentary c:<C-U>call <SID>textobject(1)<CR>
if !hasmapto('<Plug>Commentary') || maparg('gc','n') ==# ''
xmap gc <Plug>Commentary
nmap gc <Plug>Commentary
omap gc <Plug>Commentary
nmap gcc <Plug>CommentaryLine
nmap gcu <Plug>Commentary<Plug>Commentary
endif
nmap <silent> <Plug>CommentaryUndo :echoerr "Change your <Plug>CommentaryUndo map to <Plug>Commentary<Plug>Commentary"<CR>
" Plugin end
" https://stackoverflow.com/questions/2109503/how-to-jump-to-the-beginning-of-the-current-function-body-in-vim#comment113077038_2109620
nnoremap <silent> [f [m[{
nnoremap <silent> ]f ]m]}
@roachsinai
Copy link
Author

'�' in \ '�' : 'V·Block', is Ctrl V, Ctrl V.

and Ctrl V, Ctrl S in \ '�' : 'S·Block',.

@roachsinai
Copy link
Author

mkdir ~/.vim/swap
mkdir ~/.vim/undo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment