"---------------------------------------------------------------- " _ " _ __(_)___ ___ __________ " | | / / / __ `__ \/ ___/ ___/ " _| |/ / / / / / / / / / /__ " (_)___/_/_/ /_/ /_/_/ \___/ " "---------------------------------------------------------------- " Version : 3.0.1 " License : MIT " Author : Gerard Bajona " URL : https://github.com/gerardbm/vimrc "---------------------------------------------------------------- " Index: " 1. General settings " 2. Plugins (Plug) " 3. Plugins settings " 4. User interface " 5. Scheme and colors " 6. Files and backup " 7. Buffers management " 8. Tabs management " 9. Multiple windows " 10. Indentation tabs " 11. Moving around lines " 12. Paste mode " 13. Search, vimgrep and grep " 14. Text edition " 15. Make settings " 16. Filetype settings " 17. Helper functions " 18. External tools integration "---------------------------------------------------------------- "---------------------------------------------------------------- " 1. General settings "---------------------------------------------------------------- " Disable vi compatibility if !has("nvim") set nocompatible endif " Reload .vimrc nnoremap :so $MYVIMRC " Enable local .vimrc config set exrc set secure " Lines of memory to remember set history=10000 " Leader key to add extra key combinations let mapleader = ',' let g:mapleader = ',' " Time delay on key set timeoutlen=3000 ttimeoutlen=100 " Update time set updatetime=250 " Trigger InsertLeave autocmd inoremap " No need for Ex mode nnoremap Q " Open help in a vertical window cnoreabbrev help vert help " Terminal if has("terminal") nnoremap :call ToggleTerminal() tnoremap :wincmd p tnoremap endif " Set inc/dec set nrformats-=octal "---------------------------------------------------------------- " 2. Plugins (Plug) "---------------------------------------------------------------- " List of plugins installed call plug#begin('~/.vim/plugged') " Statusbar Plug 'vim-airline/vim-airline' " Plug 'vim-airline/vim-airline-themes' Plug 'gerardbm/vim-airline-themes' " Git tools Plug 'airblade/vim-gitgutter' Plug 'tpope/vim-fugitive' " Sessions Plug 'xolox/vim-session' Plug 'xolox/vim-misc' " Tools Plug 'preservim/nerdcommenter' Plug 'preservim/nerdtree' Plug 'valloric/listtoggle' Plug 'majutsushi/tagbar' Plug 'dense-analysis/ale' Plug 'junegunn/fzf' Plug 'junegunn/fzf.vim' Plug 'mbbill/undotree' " LSP and autocompletion Plug 'neoclide/coc.nvim', {'branch': 'release'} Plug 'honza/vim-snippets' " Go support Plug 'fatih/vim-go', " Ruby support Plug 'vim-ruby/vim-ruby' Plug 'tpope/vim-rails' Plug 'tpope/vim-endwise' Plug 'tpope/vim-liquid' " JavaScript support Plug 'othree/jspc.vim' Plug 'maksimr/vim-jsbeautify' " Twig support Plug 'lumiliet/vim-twig' " Additional syntax files Plug 'othree/html5.vim' Plug 'vim-language-dept/css-syntax.vim' Plug 'pangloss/vim-javascript' Plug 'mboughaba/i3config.vim' Plug 'aklt/plantuml-syntax' Plug 'gerardbm/asy.vim' Plug 'gerardbm/eukleides.vim' Plug 'zaid/vim-rec' Plug 'sirtaj/vim-openscad' " Edition Plug 'junegunn/vim-easy-align' Plug 'godlygeek/tabular' Plug 'jiangmiao/auto-pairs' Plug 'alvan/vim-closetag' Plug 'tpope/vim-surround' Plug 'tpope/vim-repeat' Plug 'tpope/vim-capslock' Plug 'wellle/targets.vim' Plug 'christoomey/vim-sort-motion' Plug 'terryma/vim-expand-region' Plug 'Valloric/MatchTagAlways' Plug 'FooSoft/vim-argwrap' Plug 'gerardbm/vim-md-headings' Plug 'gerardbm/vim-md-checkbox' Plug 'matze/vim-move' " Misc Plug 'christoomey/vim-tmux-navigator' Plug 'tpope/vim-characterize' Plug 'tyru/open-browser.vim' Plug 'junegunn/goyo.vim' Plug 'mattn/webapi-vim' Plug 'mattn/emmet-vim' Plug 'vimwiki/vimwiki', { 'branch': 'master' } Plug 'chrisbra/colorizer' " Color schemes Plug 'gerardbm/vim-atomic' Plug 'gerardbm/vim-cosmic' call plug#end() "---------------------------------------------------------------- " 3. Plugins settings "---------------------------------------------------------------- " --- Statusbar --- " Airline settings let g:airline_theme = 'atomic' let g:airline_powerline_fonts = 1 let g:airline#extensions#tabline#enabled = 1 let g:airline#extensions#tabline#fnamemod = ':t' let g:airline_section_z = airline#section#create([ \ '%1p%% ', \ 'Ξ%l%', \ '\⍿%c']) call airline#parts#define_accent('mode', 'black') " --- Git tools --- " Gitgutter settings let g:gitgutter_max_signs = 5000 let g:gitgutter_sign_added = '+' let g:gitgutter_sign_modified = '»' let g:gitgutter_sign_removed = '_' let g:gitgutter_sign_modified_removed = '»╌' let g:gitgutter_map_keys = 0 let g:gitgutter_diff_args = '--ignore-space-at-eol' nmap j (GitGutterNextHunk)zz nmap k (GitGutterPrevHunk)zz nnoremap :call ToggleGGPrev()zz nnoremap ga :GitGutterStageHunk nnoremap gu :GitGutterUndoHunk " Fugitive settings nnoremap :call ToggleGstatus() nnoremap gv :Gvdiffsplit:windo set wrap nnoremap gh :Gvdiffsplit HEAD:windo set wrap nnoremap gb :Git blame " Searching for text added or removed by a commit nnoremap gg :call GrepWrapper('Gclog', '-i -G', '--') " --- Sessions --- " Vim-session settings let g:session_autosave = 'no' let g:session_autoload = 'no' let g:session_directory = '~/.vim/sessions/' " --- Tools --- " NERDCommenter settings let g:NERDDefaultAlign = 'left' let g:NERDSpaceDelims = 1 let g:NERDCompactSexyComs = 1 let g:NERDCommentEmptyLines = 0 let g:NERDCreateDefaultMappings = 0 let g:NERDCustomDelimiters = { \ 'python': {'left': '#'}, \ } nnoremap cc :call nerdcommenter#Comment(0, 'toggle') vnoremap cc :call nerdcommenter#Comment(0, 'toggle') " NERDTree settings nnoremap :call ToggleNERDTree() " Listtoggle settings let g:lt_location_list_toggle_map = 'e' let g:lt_quickfix_list_toggle_map = 'q' " Tagbar toggle (custom function) nnoremap :call ToggleTagbar() let g:tagbar_autofocus = 1 let g:tagbar_show_linenumbers = 2 let g:tagbar_sort = 0 " ALE settings let g:ale_enabled = 0 let g:ale_sign_error='✗' let g:ale_sign_warning='•' let g:ale_sign_info='ℹ' let g:ale_virtualtext_cursor=0 " FZF settings let $FZF_DEFAULT_COMMAND = "ag --hidden --ignore .git -g ''" let $FZF_PREVIEW_COMMAND = 'cat {}' let g:fzf_preview_window = ['right', 'ctrl-i'] nnoremap :Files nnoremap :Buffers nnoremap gz :Commits nnoremap uh :History nnoremap ul :BLines nnoremap um :BMarks nnoremap uu :BTags nnoremap uf \ :call fzf#vim#buffer_tags('', \ { 'options': ['--nth', '..-2,-1', '--query', '^f$ '] }) nnoremap uv \ :call fzf#vim#buffer_tags('', \ { 'options': ['--nth', '..-2,-1', '--query', '^v$ '] }) nnoremap ut :Tags " Undotree toggle nnoremap U :UndotreeToggle " --- LSP and autocompletion --- " Coc.nvim settings set signcolumn=yes let g:coc_diagnostic_enable = 1 let g:coc_snippet_next = '' let g:coc_snippet_prev = '' imap (coc-snippets-expand-jump) smap (coc-snippets-expand-jump) xmap (coc-snippets-select) inoremap \ coc#pum#visible() ? coc#_select_confirm() : \ coc#expandableOrJumpable() ? \ "\=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\" : \ CheckBackspace() ? "\" : \ coc#refresh() nnoremap E :CocDiagnostics --all nnoremap cod (coc-definition) nnoremap cot (coc-type-definition) nnoremap coc (coc-implementation) nnoremap cor (coc-references) " Navigate between errors nnoremap h :lpreviouszz nnoremap l :lnextzz " --- Languages --- " Go settings let g:go_highlight_functions = 1 let g:go_highlight_methods = 1 let g:go_highlight_fields = 1 let g:go_highlight_types = 1 let g:go_highlight_operators = 1 let g:go_highlight_build_constraints = 1 let g:go_bin_path = expand('~/.gotools') let g:go_list_type = 'quickfix' " CSS3 settings augroup VimCSS3Syntax autocmd! autocmd FileType css setlocal iskeyword+=- augroup END " Javascript settings let g:javascript_plugin_jsdoc = 1 let g:javascript_plugin_ngdoc = 1 let g:javascript_plugin_flow = 0 " JS-Beautify let g:config_Beautifier = {} let g:config_Beautifier['js'] = {} let g:config_Beautifier['js'].indent_style = 'tab' let g:config_Beautifier['jsx'] = {} let g:config_Beautifier['jsx'].indent_style = 'tab' let g:config_Beautifier['json'] = {} let g:config_Beautifier['json'].indent_style = 'tab' let g:config_Beautifier['css'] = {} let g:config_Beautifier['css'].indent_style = 'tab' let g:config_Beautifier['html'] = {} let g:config_Beautifier['html'].indent_style = 'tab' augroup beautify autocmd! autocmd FileType javascript nnoremap bf :call JsBeautify() autocmd FileType javascript vnoremap bf :call RangeJsBeautify() autocmd FileType json nnoremap bf :call JsonBeautify() autocmd FileType json vnoremap bf :call RangeJsonBeautify() autocmd FileType jsx nnoremap bf :call JsxBeautify() autocmd FileType jsx vnoremap bf :call RangeJsxBeautify() autocmd FileType html nnoremap bf :call HtmlBeautify() autocmd FileType html vnoremap bf :call RangeHtmlBeautify() autocmd FileType css nnoremap bf :call CSSBeautify() autocmd FileType css vnoremap bf :call RangeCSSBeautify() augroup end " For conceal markers if has('conceal') set conceallevel=0 concealcursor=niv nnoremap coi :set conceallevel=0:set concealcursor=niv nnoremap coo :set conceallevel=2:set concealcursor=vc nnoremap cop :set conceallevel=2:set concealcursor=niv nnoremap com :set conceallevel=3:set concealcursor=niv endif " --- Edition --- " Easy align settings xmap gi (EasyAlign) nmap gi (EasyAlign) " Tabularize (e.g. /= or /:) vnoremap x :Tabularize / " Tabularize only the first match on the line (e.g. /=.*/) vnoremap X :Tabularize /.*/ " Auto-pairs settings " Maps for normal and insert modes let g:AutoPairsFlyMode = 0 let g:AutoPairsMultilineClose = 0 let g:AutoPairsShortcutJump = '' let g:AutoPairsShortcutToggle = '' " Workaround to fix an Auto-pairs bug until it gets fixed if has("nvim") autocmd VimEnter,BufEnter,BufWinEnter * silent! iunmap endif " Closetag settings let g:closetag_filenames = '*.html,*.xhtml,*.phtml,*.xml,*.html.erb,*.md' " Surround settings " Use 'yss?', 'yss%' or 'yss=' to surround a line autocmd FileType php let b:surround_{char2nr('p')} = "" autocmd FileType erb let b:surround_{char2nr('=')} = "<%= \r %>" autocmd FileType erb let b:surround_{char2nr('-')} = "<% \r %>" autocmd FileType html,markdown,liquid let b:surround_{char2nr('p')} = "{% \r %}" autocmd FileType markdown,liquid let b:surround_{char2nr('i')} = "_\r_" autocmd FileType markdown,liquid let b:surround_{char2nr('o')} = "**\r**" autocmd FileType markdown,liquid let b:surround_{char2nr('x')} = "«\r»" autocmd FileType markdown,liquid let b:surround_{char2nr('h')} = "\[\r\]\(//\)" autocmd FileType markdown,liquid let b:surround_{char2nr('j')} = "!\[\r\] \\(/images/\){: .align-}" autocmd FileType markdown,liquid let b:surround_{char2nr('e')} = "\[\r\] \\(\){:rel=\"noopener noreferrer\" target=\"_blank\"}" autocmd FileType markdown,liquid let b:surround_{char2nr('y')} = "\r<\/a>" " Caps Lock settings imap CapsLockToggle cmap CapsLockToggle " Expand region settings vmap v (expand_region_expand) vmap m (expand_region_shrink) " MatchTagAlways settings let g:mta_filetypes = { \ 'html' : 1, \ 'xhtml' : 1, \ 'xml' : 1, \ 'jinja' : 1, \ 'php' : 1, \ } " ArgWrap settings let g:argwrap_tail_comma = 1 let g:argwrap_padded_braces = '[{' nnoremap W :ArgWrap " Vim-move settings. Use Shift let g:move_key_modifier = 'S' let g:move_key_modifier_visualmode = 'S' " --- Misc --- " Vim-tmux navigator settings let g:tmux_navigator_no_mappings = 1 " Open-browser settings let g:openbrowser_browser_commands = [{ \ 'name': 'w3m', \ 'args': 'tmux new-window w3m {uri}', \ }] nmap gl (openbrowser-open) " Goyo settings let g:goyo_width = "80" let g:goyo_height = "100%" let g:goyo_linenr = 1 nnoremap :Goyo " Vimwiki settings let g:vimwiki_url_maxsave = 0 let g:vimwiki_global_ext = 0 let g:vimwiki_list = [ \ {'path': '~/Workspace/vimwiki'}, \ {'path': '~/Workspace/vimwiki/Articles'}, \ {'path': '~/Workspace/vimwiki/Codes'}, \ {'path': '~/Workspace/vimwiki/Notes'}, \ {'path': '~/Workspace/vimwiki/Projects'}, \ {'path': '~/Workspace/vimwiki/Studies'}, \ {'path': '~/Workspace/vimwiki/ToDos'}, \ {'path': '~/Workspace/vimwiki/Unix'} \ ] nnoremap we :VimwikiToggleListItem vnoremap we :VimwikiToggleListItem "---------------------------------------------------------------- " 4. User interface "---------------------------------------------------------------- " Set X lines to the cursor when moving vertically set scrolloff=0 " Always show mode set showmode " Show command keys pressed set showcmd " Enable the WiLd menu set wildmenu " Show the current position set ruler " Command bar height set cmdheight=2 " Backspace works on Insert mode set backspace=eol,start,indent " Don't redraw while executing macros (good performance config) set lazyredraw " Show matching brackets when text indicator is over them set showmatch " How many tenths of a second to blink when matching brackets set matchtime=2 " No annoying sound on errors set noerrorbells set novisualbell " Mouse set mouse=a " Highlight cursor line and cursor column set cursorline set nocursorcolumn " Always show the status line set laststatus=2 " Change the cursor shape if !has("nvim") if &term != "linux" let &t_SI = "\[6 q" let &t_SR = "\[4 q" let &t_EI = "\[2 q" endif else set guicursor=n-v:block-Cursor/lCursor-blinkon0 set guicursor+=i-ci-c:ver100-Cursor/lCursor-blinkon0 set guicursor+=r-cr:hor100-Cursor/lCursor-blinkon0 endif " Omni completion if has('autocmd') && exists('+omnifunc') autocmd Filetype * \ if &omnifunc == "" | \ setlocal omnifunc=syntaxcomplete#Complete | \ endif endif " Fix italics issue if !has("nvim") let &t_ZH="\e[3m" let &t_ZR="\e[23m" endif "---------------------------------------------------------------- " 5. Scheme and colors "---------------------------------------------------------------- " True color " if !has("nvim") " if has("termguicolors") " let &t_8f = "\[38;2;%lu;%lu;%lum" " let &t_8b = "\[48;2;%lu;%lu;%lum" " set termguicolors " endif " else " set termguicolors " endif " Syntax highlighting syntax enable " Color scheme let g:cosmic_matchparen = 0 colorscheme cosmic " Show syntax highlighting groups nnoremap B :call SynStack() "---------------------------------------------------------------- " 6. Files and backup "---------------------------------------------------------------- " Disable swap files set noswapfile " No backup (use Git instead) set nobackup " Prevents automatic write backup set nowritebackup " Use UTF-8 as default encoding set encoding=utf8 " Use Unix as the standard file type set fileformats=unix,dos,mac " Autoread a file when it is changed from the outside set autoread " Reload a file when it is changed from the outside let g:f5msg = 'Buffer reloaded.' nnoremap :e:echo g:f5msg " Enable filetype plugins filetype plugin on filetype indent on " Allow us to use Ctrl-s and Ctrl-q as keybinds " Restore default behaviour when leaving Vim. if !has("nvim") silent !stty -ixon autocmd VimLeave * silent !stty ixon endif " Save the current buffer nnoremap s :update " Save all buffers nnoremap S :bufdo update " :W sudo saves the file " (useful for handling the permission-denied error) cnoremap WW w !sudo tee > /dev/null % " Rename file nnoremap :call RenameFile() " Work on buffer nnoremap yab :%y nnoremap dab :%d nnoremap vab ggVG "---------------------------------------------------------------- " 7. Buffers management "---------------------------------------------------------------- " Buffer hidden when it is abandoned set hidden " Close the current buffer nnoremap bd :call CustomCloseBuffer() " Move between buffers nnoremap :bprev nnoremap :bnext " Edit and explore buffers nnoremap bb :edit =expand("%:p:h")/ nnoremap bg :buffers:buffer " Copy the filepath to clipboard nnoremap by :let @+=expand("%:p") " Switch CWD to the directory of the current buffer nnoremap dd :lcd %:p:h:pwd " Switch CWD to git root directory nnoremap dg :call GitRoot() " Ignore case when autocompletes when browsing files set fileignorecase " Specify the behavior when switching between buffers try set switchbuf=useopen,usetab,newtab set showtabline=2 catch endtry " Remember info about open buffers on close " set viminfo^=% "---------------------------------------------------------------- " 8. Tabs management "---------------------------------------------------------------- " Create and close tabs nnoremap td :tabclose nnoremap to :tabonly " Open a new tab with the current buffer's path " Useful when editing files in the same directory nnoremap tt :tabedit =expand("%:p:h")/ " Move tabs position nnoremap tr :execute 'silent! tabmove ' . (tabpagenr()-2) nnoremap ty :execute 'silent! tabmove ' . tabpagenr() "---------------------------------------------------------------- " 9. Multiple windows "---------------------------------------------------------------- " Remap wincmd map , set winminheight=0 set winminwidth=0 set splitbelow set splitright set fillchars+=stlnc:―,vert:│,fold:―,diff:― " Split windows map - :split map . :vsplit map j :close map x :q! map , = " Resize windows if bufwinnr(1) map + :resize +1 map - :resize -1 map < :vertical resize +1 map > :vertical resize -1 endif " Toggle resize window nnoremap f :call ToggleResize() " Last, previous and next window; and only one window nnoremap l :wincmd p:echo "Last window." nnoremap p :wincmd w:echo "Previous window." nnoremap n :wincmd W:echo "Next window." nnoremap o :wincmd o:echo "Only one window." " Move between Vim windows and Tmux panes " - It requires the corresponding configuration into Tmux. " - Check it at my .tmux.conf from my dotfiles repository. " - URL: https://github.com/gerardbm/dotfiles/blob/master/tmux/.tmux.conf " - Plugin required: https://github.com/christoomey/vim-tmux-navigator if !has("nvim") set =h set =j set =k set =l endif nnoremap :TmuxNavigateLeft nnoremap :TmuxNavigateDown nnoremap :TmuxNavigateUp nnoremap :TmuxNavigateRight " Remove the Windows ^M - when the encodings gets messed up noremap mmHmt:%s///ge'tzt`m " Close the preview window nnoremap . :pclose " Scroll the preview window if !has("nvim") set =d set =u endif nnoremap :wincmd P5:wincmd p nnoremap :wincmd P5:wincmd p "---------------------------------------------------------------- " 10. Indentation tabs "---------------------------------------------------------------- " Enable autoindent & smartindent set autoindent set smartindent " Use tabs, no spaces set noexpandtab " Be smart when using tabs set smarttab " Tab size (in spaces) set shiftwidth=2 set tabstop=2 " Remap indentation nnoremap >> nnoremap << vnoremap >gv vnoremap :set list!:echo g:f6msg " Show tabs and end-of-lines set listchars=tab:┊\ ,trail:¬ "---------------------------------------------------------------- " 11. Moving around lines "---------------------------------------------------------------- " Specify which commands wrap to another line set whichwrap+=<,>,h,l " Many jump commands move the cursor to the start of line set nostartofline " Wrap lines into the window set wrap " Don't break the words " Only works if I set nolist (F6) set linebreak set showbreak=↳\ " Stop automatic wrapping set textwidth=0 " Column at 80 width set colorcolumn=80 " Listings don't pause set nomore " Color column let g:f10msg = 'Toggle colorcolumn.' nnoremap :call ToggleColorColumn():echo g:f10msg " Show line numbers set number set numberwidth=2 let g:f3msg = 'Toggle line numbers.' nnoremap :set number!:echo g:f3msg " Set relative line numbers set relativenumber let g:f4msg = 'Toggle relative line numbers.' nnoremap :set norelativenumber!:echo g:f4msg " Treat long lines as break lines (useful when moving around in them) nnoremap k (v:count == 0 ? 'gk' : 'k') nnoremap j (v:count == 0 ? 'gj' : 'j') vnoremap k (v:count == 0 ? 'gk' : 'k') vnoremap j (v:count == 0 ? 'gj' : 'j') nnoremap g^ nnoremap g$ vnoremap g^ vnoremap g$ " Toggle the cursor position start/end of the line nnoremap ñ :call ToggleCPosition('') vnoremap ñ :call ToggleCPosition('normal! gv') " Join / split lines nnoremap J nnoremap i " Duplicate a line nnoremap cx yyP nnoremap cv yyp " Folding set foldmethod=marker " Return to last edit position when opening files autocmd BufReadPost * \ if line("'\"") > 0 && line("'\"") <= line("$") | \ exe "normal! g`\"" | \ endif " --- Readline commands --- "---------------------------------------------------------------- " Move the cursor to the line start inoremap 0 " Move the cursor to the line end inoremap $ " Moves the cursor back one character inoremap " Moves the cursor forward one character inoremap " Remove one character inoremap " Command Mode cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap cnoremap " cnoremap "---------------------------------------------------------------- " 12. Paste mode "---------------------------------------------------------------- " Bracketed paste mode " - Source: https://ttssh2.osdn.jp/manual/en/usage/tips/vim.html if !has("nvim") if has("patch-8.0.0238") if &term =~ "screen" let &t_BE = "\e[?2004h" let &t_BD = "\e[?2004l" exec "set t_PS=\e[200~" exec "set t_PE=\e[201~" endif endif endif "---------------------------------------------------------------- " 13. Search, vimgrep and grep "---------------------------------------------------------------- " Highlight search results set hlsearch " Makes search act like search in modern browsers set incsearch " Search, wrap around the end of the buffer set wrapscan " Ignore case when searching set ignorecase " When searching try to be smart about cases set smartcase " For regular expressions turn magic on set magic " Maximum amount of memory in Kbyte used for pattern matching set maxmempattern=1000 " --- Highlight --- "---------------------------------------------------------------- " Map to / (search) nnoremap / nnoremap ? " Highlight the word under the cursor and don't jump to next nnoremap :let @/='\<=expand("")\>':set hlsearch " Highlight the selected text and don't jump to next vnoremap :call VSetSearch():set hlsearch " Disable highlight nnoremap m :noh " Next and prev centered nnoremap n nzz nnoremap N Nzz " Search into a Visual selection vnoremap :call RangeSearch('/') \ :if strlen(g:srchstr) > 0 \ \|exec '/'.g:srchstr\|endifn vnoremap ? :call RangeSearch('?') \ :if strlen(g:srchstr) > 0 \ \|exec '?'.g:srchstr\|endifN " --- Vimgrep and grep --- "---------------------------------------------------------------- " Vimgrep the highlight in the current file nnoremap vg :vimgrep ///j % " Vimgrep the highlight in the current directory and subdirectories nnoremap vf :vimgrep ///j **/*. autocmd QuickfixCmdPre grep,grepadd,vimgrep,vimgrepadd,helpgrep copen " Grep settings set grepprg=grep\ -nHi " Current buffer nnoremap vv :call GrepWrapper('grep!', '', '%') " Current working directory nnoremap vn :call GrepWrapper('grep!', '-R \ --exclude-dir={.git,.svn,.jekyll-cache,_site} \ --exclude=LICENSE', '') " Current buffer (grepadd) nnoremap vm :call GrepWrapper('grepadd!', '', '%') " Current arglist nnoremap va :call GrepWrapper('grep!', '', '##') " Navigate between grep and vimgrep results nnoremap n :cnextzz nnoremap N :cprevzz " Jump to the results in buffers (first open window), not tabs set switchbuf=useopen " --- Replace --- "---------------------------------------------------------------- " Replace the highlight in the current file nnoremap r :%s////g " Replace the highlight in the visual selection " Flag \%V --> Match only inside the visual selection vnoremap r :s/\%V/\%V//g " Replace the highlight to all loaded buffers and arglist nnoremap R :bufdo %s////ge " Replace the highlight to each valid entry in the quickfix nnoremap Q :cdo %s////ge " Populate the arglist nnoremap aa :argadd nnoremap ad :argdelete nnoremap an :args **/*. nnoremap al :call DisplayArglist():argument "---------------------------------------------------------------- " 14. Text edition "---------------------------------------------------------------- " Toggle case nnoremap z ~ vnoremap z y:call setreg('', ToggleCase(@"), getregtype(''))gv""Pgv vnoremap ~ y:call setreg('', ToggleCase(@"), getregtype(''))gv""Pgv " Toggle and untoggle spell checking let g:f8msg = 'Toggle spell checking.' nnoremap :setlocal spell!:echo g:f8msg " Toggle spell dictionary nnoremap :call ToggleSpelllang() " Move to next misspelled word nnoremap zl ]s " Find the misspelled word before the cursor nnoremap zh [s " Suggest correctly spelled words nnoremap zp z= " Copy text into the clipboard vnoremap y "+y " Paste text from the clipboard nnoremap p "+p " Quickly select the text pasted from the clipboard nnoremap gV `[v`] " Yank everything from the cursor to the EOL nnoremap Y y$ " Yank the last pasted text automatically vnoremap p pgvy " Retab the selected text nnoremap tf :retab! vnoremap tf :retab! " Isolate the current line nnoremap o m`okO`` " Enter a new line Down from 'Normal Mode' nnoremap f mao`a " Enter a new line Up from 'Normal Mode' nnoremap F maO`a " Insert brackets faster using the ISO-ES layout inoremap ñr [] inoremap ñb () inoremap ñB {} inoremap ññ {{ }} inoremap ñl \ autocmd FileType html,markdown,liquid inoremap ñp {% %} autocmd FileType html,markdown,liquid inoremap ñ- {%- -%} " Enter Vim's expression register (math) inoremap ñm = "---------------------------------------------------------------- " 15. Make settings "---------------------------------------------------------------- " Set makeprg if !filereadable(expand('%:p:h').'/Makefile') autocmd FileType c setlocal makeprg=gcc\ %\ &&\ ./a.out endif " Go to the error line set errorformat=%m\ in\ %f\ on\ line\ %l " Use the correct cursor shape via 'edit-command-line' (zle) augroup zsh autocmd! if !has("nvim") autocmd Filetype zsh silent! exec "! echo -ne '\e[2 q'" endif augroup end " Run code in a tmux window augroup tmuxy autocmd! autocmd FileType javascript,lua,perl,php,python,ruby,sh \ nnoremap ij \ :call Tmuxy() augroup end " Run code in the preview window augroup scripty autocmd! autocmd FileType javascript,lua,perl,php,python,ruby,sh \ nnoremap ii \ :call Scripty() augroup end " Work with Sqlite databases augroup sqlite autocmd! autocmd FileType sql nnoremap ia \ :call SqliteDatabase() autocmd FileType sql nnoremap ii \ :call SQLExec('n') autocmd FileType sql vnoremap ii \ :call SQLExec('v') augroup end " Work with maxima (symbolic mathematics) augroup maxima autocmd! autocmd BufRead,BufNewFile *.max set filetype=maxima autocmd FileType maxima nnoremap ii \ :call MaximaExec('n') autocmd FileType maxima vnoremap ii \ :call MaximaExec('v') augroup end " Convert LaTeX to PDF augroup latex autocmd! autocmd FileType tex nnoremap ii \ :call Generator('.pdf', &ft) augroup end " Convert markdown to PDF, HTML and EPUB augroup markdown autocmd! autocmd FileType markdown nnoremap ii \ :call Generator('.pdf', &ft) autocmd FileType markdown nnoremap ih \ :call Generator('.html', &ft) autocmd FileType markdown nnoremap ij \ :call Generator('.epub', &ft) augroup end " Draw with PlantUML augroup uml autocmd! autocmd FileType plantuml nnoremap ii \ :call Generator('.png', &ft) autocmd FileType plantuml nnoremap ij \ :call Generator('.svg', &ft) augroup end " Draw with Graphviz augroup dot autocmd! autocmd FileType dot nnoremap ii \ :call Generator('.png', &ft) augroup end " Draw with Eukleides augroup eukleides autocmd! autocmd BufRead,BufNewFile *.euk set filetype=eukleides autocmd FileType eukleides nnoremap ii \ :call Generator('.png', &ft) augroup end " Draw with Asymptote augroup asymptote autocmd! autocmd BufRead,BufNewFile *.asy set filetype=asy autocmd FileType asy nnoremap ii \ :call Generator('.png', &ft) augroup end " Draw with pp3 augroup pp3 autocmd! autocmd BufRead,BufNewFile *.pp3 set filetype=pp3 autocmd FileType pp3 nnoremap ii \ :call Generator('.png', &ft) augroup end " Draw with Gnuplot augroup gnuplot autocmd! autocmd BufRead,BufNewFile *.plt set filetype=gnuplot autocmd FileType gnuplot nnoremap ii \ :call Generator('.png', &ft) augroup end " Draw with POV-Ray augroup povray autocmd! autocmd FileType pov nnoremap ii \ :call Generator('.png', &ft) augroup end " Run Jekyll (liquid.markdown) augroup liquid autocmd! autocmd FileType liquid.markdown,html,yaml set wildignore+=*/.jekyll-cache/*, \*/_site/*,*/images/*,*/timg/*,*/icons/*,*/logo/*,*/where/* autocmd FileType liquid.markdown setlocal spell spelllang=es colorcolumn=0 autocmd FileType liquid.markdown,yaml nnoremap ii \ :call ToggleJekyll() autocmd FileType liquid.markdown nnoremap ij \ :call ViewJekyllPost() augroup end "---------------------------------------------------------------- " 16. Filetype settings "---------------------------------------------------------------- " Delete trailing white spaces func! s:DeleteTrailing() exe 'normal mz' %s/\s\+$//ge exe 'normal `z' echo 'Trailing white spaces have been removed.' noh endfunc nnoremap dt :call DeleteTrailing() " Binary augroup binary autocmd! autocmd BufReadPre *.bin let &bin=1 autocmd BufReadPost *.bin if &bin | %!xxd autocmd BufReadPost *.bin set ft=xxd | endif autocmd BufWritePre *.bin if &bin | %!xxd -r autocmd BufWritePre *.bin endif autocmd BufWritePost *.bin if &bin | %!xxd autocmd BufWritePost *.bin set nomod | endif augroup end " Mail augroup mail autocmd! autocmd FileType mail setl spell autocmd FileType mail setl spelllang=ca augroup end " SQL (it requires sqlparse) augroup sql let g:omni_sql_no_default_maps = 1 autocmd FileType sql nnoremap bf \ :%!sqlformat --reindent --keywords upper --identifiers upper - autocmd FileType sql vnoremap bf \ :%!sqlformat --reindent --keywords upper --identifiers upper - augroup end " XML (it requires tidy) augroup xml autocmd FileType xml nnoremap bf \ :%!tidy -q -i -xml --show-errors 0 -wrap 0 --indent-spaces 4 augroup end " MD augroup md autocmd FileType markdown,liquid,text,yaml set expandtab autocmd FileType markdown,liquid,text \ nnoremap cc :call KeywordDensity() autocmd FileType markdown,liquid,text nnoremap cx g autocmd FileType markdown,liquid,text vnoremap cx g autocmd FileType markdown,liquid,text \ nnoremap gl :call search('\v\[[^]]*]\([^)]*\)', 'W') autocmd FileType markdown,liquid,text \ nnoremap gh :call search('\v\[[^]]*]\([^)]*\)', 'bW') autocmd FileType markdown,liquid,text \ nnoremap gd :call RemoveMdLink() autocmd FileType markdown,liquid,text \ :command! -range Enes ,!trans en:es -brief autocmd FileType markdown,liquid,text \ :command! -range Esen ,!trans es:en -brief autocmd FileType markdown,liquid,text \ nnoremap gx :call CustomGx() augroup end " CSV augroup csv autocmd! autocmd BufRead,BufNewFile *.csv set filetype=csv augroup end " New file headers augroup headers autocmd! autocmd BufNewFile *.py 0put =\"#!/usr/bin/env python\\# \ -*- coding: utf-8 -*-\\"|$ autocmd BufNewFile *.rb 0put =\"#!/usr/bin/env ruby\\"|$ autocmd BufNewFile *.pl 0put =\"#!/usr/bin/env perl\\"|$ autocmd BufNewFile *.sh 0put =\"#!/usr/bin/env bash\\"|$ autocmd BufNewFile *.js 0put =\"#!/usr/bin/env node\\"|$ augroup end "---------------------------------------------------------------- " 17. Helper functions "---------------------------------------------------------------- " Toggle Terminal function! s:ToggleTerminal() if bufexists('terminal') call win_gotoid(s:winZsh) norm! i else execute ':terminal' keepalt file terminal let s:winZsh = win_getid() norm! i endif endfunction " Show syntax highlighting groups function! s:SynStack() if !exists('*synstack') return endif echo map(synstack(line('.'), col('.')), 'synIDattr(v:val, "name")') endfunction " Rename file function! s:RenameFile() let l:old_name = expand('%') let l:new_name = input('New file name: ', expand('%'), 'file') if l:new_name !=# '' && l:new_name !=# l:old_name exec ':saveas ' . l:new_name exec ':silent !rm ' . l:old_name redraw! endif endfunction " Don't close window when deleting a buffer function! s:CustomCloseBuffer() let l:currentBufNum = bufnr('%') let l:alternateBufNum = bufnr('#') if buflisted(l:alternateBufNum) buffer # else bnext endif if bufnr('%') == l:currentBufNum new endif if buflisted(l:currentBufNum) exec ':bdelete! ' . l:currentBufNum endif endfunction " Close the last buffer if it's the last window " - For 'quickfix' and 'nofile' autocmd BufEnter * call CloseLastBuffer() function! s:CloseLastBuffer() if &buftype ==# 'quickfix' || &buftype ==# 'nofile' if winnr('$') < 2 quit! endif endif endfunction " Display the arglist vertically function! s:DisplayArglist() abort let l:argnum = 0 let l:lenargc = len(argc()) for l:arg in argv() let l:argnum += 1 let l:filename = fnamemodify(l:arg, ':t') let l:changed = \ getbufinfo(bufname('^' . l:arg . '$'))[0].changed == 1 \ ? '+' \ : ' ' let l:current = expand('%') ==# l:arg ? '%' : ' ' echo printf( '%-*d %s%s %s', \ l:lenargc, l:argnum, l:current, l:changed, l:filename) endfor endfunction " Toggle maximize window and resize windows function! s:ToggleResize() abort if winnr('$') > 1 if exists('t:zoomed') && t:zoomed execute t:zoom_winrestcmd let t:zoomed = 0 echo 'Windows resized.' else let t:zoom_winrestcmd = winrestcmd() resize vertical resize let t:zoomed = 1 echo 'Window maximized.' endif endif endfunction autocmd VimEnter * autocmd WinEnter * let t:zoomed = 0 " Search into a Visual selection function! s:RangeSearch(direction) call inputsave() let g:srchstr = input(a:direction) call inputrestore() if strlen(g:srchstr) > 0 let g:srchstr = g:srchstr. \ '\%>'.(line("'<")-1).'l'. \ '\%<'.(line("'>")+1).'l' else let g:srchstr = '' endif endfunction " Highlight the selected text (visual mode) " Source: https://github.com/nelstrom/vim-visual-star-search " (You can install it as a plugin) function! s:VSetSearch() let l:temp = @@ norm! gvy let @/ = '\V' . substitute(escape(@@, '\'), '\n', '\\n', 'g') let @@ = l:temp endfunction " Count grep matches function! QFCounter() abort let l:results = len(getqflist()) if l:results > 0 copen else cclose endif echo 'Found ' . l:results . ' matches.' endfunction " Grep wrapper function! s:GrepWrapper(cmd, dir, scope) abort cclose let l:pattern = substitute(@/, '\\V', '', '') let l:pattern = substitute(pattern, '\\<', '', '') let l:pattern = substitute(pattern, '\\>', '', '') let l:pattern = escape(pattern, '"') let l:pattern = escape(pattern, '%') let l:pattern = escape(pattern, '#') silent execute a:cmd . ' ' . a:dir . ' "' . l:pattern . '" ' . a:scope redraw! set hlsearch call QFCounter() endfunction " Toggle case function! ToggleCase(str) if a:str ==# toupper(a:str) let l:result = tolower(a:str) elseif a:str ==# tolower(a:str) let l:result = substitute(a:str,'\(\<\w\+\>\)', '\u\1', 'g') else let l:result = toupper(a:str) endif return l:result endfunction " Toggle spell dictionary function! ToggleSpelllang() if (&spelllang =~# '^en') set spelllang=ca echo 'Català' elseif (&spelllang =~# '^ca') set spelllang=es echo 'Castellano' elseif (&spelllang =~# '^es') set spelllang=en_us,en_gb echo 'English' endif set spelllang? endfunction " New :windo command to return to the last current window " - Default :windo cycles through all the open windows " - Use 'Windo' instead of 'windo' to avoid it command! -nargs=+ -complete=command Windo \ let s:currentWindow = winnr() | \ execute 'windo ' | \ exe s:currentWindow . 'wincmd w' " Toggle colorcolumn function! s:ToggleColorColumn() if !exists('s:color_column_old') || s:color_column_old == 0 let s:color_column_old = &colorcolumn Windo let &colorcolumn = 0 else Windo let &colorcolumn = s:color_column_old let s:color_column_old = 0 endif endfunction " Toggle the cursor position start/end function! s:ToggleCPosition(mode) execute a:mode if !exists('s:togglecp') let s:togglecp = 0 endif if col('.') >= col('$') - 1 let s:togglecp = 1 norm! ^ else let s:togglecp = 0 norm! $ endif endfunction " Toggle GitGutterPreviewHunk function! s:ToggleGGPrev() if getwinvar(winnr('#'), '&pvw') == 1 \ && exists('s:curr') && line(".") == s:curr \ || gitgutter#hunk#in_hunk(line(".")) == 0 pclose else GitGutterPreviewHunk let s:curr = line(".") endif endfunction " Switch CWD to git root directory function! s:GitRoot() abort execute ':lcd %:p:h' let l:isgit = system('git rev-parse --is-inside-work-tree 2>/dev/null') if v:shell_error == 0 let l:path = system('git rev-parse --show-toplevel 2>/dev/null') execute ':lcd ' . l:path execute ':pwd' else echo "You're not in a git directory." endif endfunction " Toggle Gstatus window function! s:ToggleGstatus() abort for l:winnr in range(1, winnr('$')) if !empty(getwinvar(l:winnr, 'fugitive_status')) exe l:winnr 'close' return endif endfor keepalt Git endfunction " Better toggle for NERDTree function! s:ToggleNERDTree() abort if bufname('%') != "" if exists("g:NERDTree") && g:NERDTree.IsOpen() if &filetype ==# 'nerdtree' execute ':NERDTreeClose' else execute ':NERDTreeFocus' endif else execute ':NERDTreeFind' endif else execute ':NERDTreeToggleVCS' endif endfunction " Get Tagbar buffer name function! s:TagbarBufName() abort if !exists('t:tagbar_buf_name') let s:buffer_seqno += 1 let t:tagbar_buf_name = '__Tagbar__.' . s:buffer_seqno endif return t:tagbar_buf_name endfunction " Better toggle for Tagbar function! s:ToggleTagbar() abort let tagbarwinnr = bufwinnr(s:TagbarBufName()) if tagbarwinnr != -1 if &modifiable execute tagbarwinnr 'wincmd w' else execute ':TagbarClose' endif else execute ':TagbarOpen' endif endfunction " Keyword density checker function! s:KeywordDensity() abort silent update " Words count " > Strip the front matter, comments, HTML tags and count the words let s:sf = " | sed '1 { /^---/ { :a N; /\\n---/! ba; d } }'" let s:sc = " | sed 's/{% comment.*endcomment %}//g'" let s:sh = " | sed 's/<[^>]*.//g'" let s:wc = " | wc -w" let s:get_words = system("cat " . expand('%') . s:sf. s:sc . s:sh . s:wc) let s:int_words = str2nr(s:get_words) let s:str_words = string(s:int_words) " Highlight count let s:match_count = "" redir => s:match_count silent exec '%s/' . @/ . '//gne' redir END if ! empty(s:match_count) let s:str_keys = split(s:match_count)[0] let s:flt_keys = str2float(s:str_keys) " Density let s:flt_dens = (s:flt_keys/s:int_words)*100 let s:str_dens = string(s:flt_dens) echo '> ' . s:str_keys . ' of ' . s:str_words . ' (' . s:str_dens . '%)' else echo '> 0 of ' . s:str_words . ' (0%, pattern not found)' endif endfunction " Remove markdown link function! s:RemoveMdLink() abort let [l, c] = searchpos('\v\[[^]]*]\([^)]*\)', 'ncW') if l > 0 && c > 0 if getline(".")[col(".")-1] ==# "[" norm! xf]vf)d else call cursor(l, c) endif endif endfunction " Custom gx to preview images in markdown function! s:CustomGx() let l:src = expand("") execute "silent !feh " . substitute(l:src, '^/', '', 'g') . " &" redraw! endfunction function! CheckBackspace() abort let col = col('.') - 1 return !col || getline('.')[col - 1] =~# '\s' endfunction "---------------------------------------------------------------- " 18. External tools integration "---------------------------------------------------------------- " Run code into a tmux window function! s:Tmuxy() abort if exists('$TMUX') update let s:runner = Runners() let s:cmdk = 'tmux kill-window -t run' let s:cmdn = 'tmux new-window -n run' let s:cmds = " '" . s:runner . " " . expand("%:p") . " ; read'" call system(s:cmdk) call system(s:cmdn . s:cmds) else echo 'Tmux is not running.' endif endfunction " Run code in the preview window function! s:Scripty() abort update let s:runner = Runners() let s:cmd = s:runner . " " . expand("%:p") call Commander(s:cmd) endfunction " Define the runners function! s:Runners() abort if &filetype =~# 'javascript' let s:run = 'node' elseif &filetype =~# 'lua' let s:run = 'lua' elseif &filetype =~# 'perl' let s:run = 'perl' elseif &filetype =~# 'php' let s:run = 'php' elseif &filetype =~# 'python' let s:run = 'python3' elseif &filetype =~# 'ruby' let s:run = 'ruby' elseif &filetype =~# 'sh' let s:run = 'bash' else let s:run = 'empty' endif return s:run endfunction " Generator function function! s:Generator(ext, ft) abort update let l:inp = expand('%') let l:out = expand('%:r') . a:ext if a:ft ==# 'tex' let l:cmd = system('pdflatex ' . l:inp) elseif a:ft ==# 'markdown' if a:ext ==# '.html' let l:opt = '--mathjax ' elseif a:ext ==# '.epub' let l:opt = '-t epub2 --webtex ' elseif a:ext ==# '.pdf' let l:opt = '-V fontsize=12pt \ -V papersize=a4 \ -V geometry:margin=2.5cm ' endif let l:cmd = system('pandoc -s ' . l:opt . l:inp . ' -o ' . l:out) elseif a:ft ==# 'plantuml' if a:ext ==# '.png' let l:cmd = system('plantuml ' . l:inp) elseif a:ext ==# '.svg' let l:cmd = system('plantuml -tsvg ' . l:inp) endif elseif a:ft ==# 'dot' let l:cmd = system('dot -Tpng ' . l:inp . ' -o ' . l:out) elseif a:ft ==# 'eukleides' let l:eps = expand('%:r') . '.eps' let l:cmd = system('eukleides ' . l:inp) elseif a:ft ==# 'asy' let l:eps = expand('%:r') . '.eps' let l:cmd = system('asy ' . l:inp) elseif a:ft ==# 'pp3' let l:eps = expand('%:r') . '.eps' let l:cmd = system('pp3 ' . l:inp) elseif a:ft ==# 'gnuplot' let l:opt = ' -e "set terminal png; set output ''' . l:out . '''" ' let l:cmd = system('gnuplot' . l:opt . l:inp) elseif a:ft ==# 'pov' let l:cmd = system('povray -D ' . l:inp) endif if v:shell_error == 0 pclose if a:ft =~# '\(eukleides\|asy\|pp3\)' call EPS2PNG(l:eps, l:out) endif call Previewer(l:out, a:ext) else call WinPreview() exec '0put =l:cmd' call ResizeWinPreview() endif endfunction " Convert from EPS to PNG function! s:EPS2PNG(eps, out) abort let l:opt_bef = ' -density 150 ' let l:opt_aft = ' -flatten -alpha off -colorspace hsl ' call system('convert' . l:opt_bef . a:eps . l:opt_aft . a:out) endfunction " Preview EPUB, HTML & PNG with mupdf " Preview PDF with zathura function! s:Previewer(out, ft) abort if a:ft ==# '.pdf' let l:tool = 'zathura' elseif a:ft ==# '.svg' let l:tool = 'geeqie' " 'eog' is also a good option else let l:tool = 'mupdf' endif let l:dev = ' 2>/dev/null' let l:checkps = system('ps -ef \ | grep -v grep \ | grep '. l:tool .' \ | grep -o ' . a:out . l:dev) if l:checkps ==# '' call system(l:tool . ' ' . a:out . ' &') else if l:tool ==# 'mupdf' call system('pkill -HUP mupdf') endif endif endfunction " Configure a sqlite database function! s:SqliteDatabase() abort let t:path = input('Database: ') endfunction " Execute SQL queries function! s:SQLExec(opt) abort if a:opt ==# 'n' silent norm! yy elseif a:opt ==# 'v' silent norm! gvy endif if !exists('t:path') call SqliteDatabase() endif if filereadable(t:path) let t:sql = @ let t:sql = substitute(t:sql, '\n', ' ', 'g') let t:format = " | column -t -s '|'" if t:sql =~? '^select' let t:cmd = t:path . ' "' . escape(t:sql, '"') . '"' . t:format else let t:cmd = t:path . ' "' . escape(t:sql, '"') . '"' endif let s:cmd = "sqlite3 -list -batch " . t:cmd call Commander(s:cmd) else echo "\nThis database does not exist!" endif endfunction " Execute Maxima instructions function! s:MaximaExec(opt) abort if a:opt ==# 'n' silent norm! yy elseif a:opt ==# 'v' silent norm! gvy endif let b:equ = @ let b:equ = substitute(b:equ, '\n', ' ', 'g') let b:equ = substitute(b:equ, '\s$', '', 'g') let b:equ = substitute(b:equ, '%', '\\%', 'g') if b:equ !~# ';$' let b:equ = substitute(b:equ, '$', ';', 'g') endif let s:cmd = 'maxima --very-quiet --batch-string "' . b:equ . '"' call Commander(s:cmd) endfunction " Window previewer function! s:WinPreview() abort silent! wincmd P if !&previewwindow exec 'new' setlocal previewwindow setlocal buftype=nowrite bufhidden=wipe setlocal nobuflisted noswapfile nowrap nnoremap q :pclose endif exec '%delete' endfunction " Commander function! s:Commander(cmd) abort call WinPreview() exec '0read !' . a:cmd call ResizeWinPreview() endfunction " Resize the preview window function! s:ResizeWinPreview() abort exec '$d' let s:size = line('$') if s:size < 10 exec 'resize ' . line('$') else exec 'resize 10' endif norm! gg wincmd p endfunction command! -nargs=1 Commander call Commander() " Toggle Jekyll server in the background function! s:ToggleJekyll() abort call system('lsof -i :4000 | grep -i listen') if v:shell_error silent exec "!(bundle exec jekyll serve -q -l -I &) > /dev/null" call system("touch /tmp/jekyll.ps") call system("notify-send -t 2 'Executing Jekyll server...'") else silent exec "!(pkill -f jekyll &) > /dev/null" call system("rm -f /tmp/jekyll.ps") call system("notify-send -t 2 'Jekyll server was stoped!'") endif redraw! endfunction " Preview the current post in the web broswer function! s:ViewJekyllPost() abort silent update let s:grep = expand("grep '^permalink: ' ") let s:file = expand('%') let s:sed = expand(" | sed 's/permalink: //g'") let s:permalink = system(s:grep . s:file . s:sed) call system("google-chrome http://localhost:4000" . s:permalink) endfunction " Shell output to the buffer command! -nargs=1 SH :r ! hi Normal guibg=NONE ctermbg=NONE