Skip to main content

Vim as IDE again

Posted in

Along with studying Qt Creator I'm trying to keep on using vim and some changes have been made since my last post about vim as IDE. I would like to share some new functionality with you. Some code might look familiar to you - that's right, I got it from vim.wikia.com modified a little bit where it was required for me. This is sort of a continue for the previous post about vim but I'll start with a list of plugins I use because there have been some changes:

  • code_complete
  • taglist
  • grep
  • bufferlist
  • NERDTree
  • cscope_vim
  • omnicppcomplete

I have to use both FreeBSD and Linux and I've got different encodings, so I need a way to determine which encoding to set. I have done this check because I want to use the only .vimrc file on different OSes without doing any changes to it.

  1. let g:OS = substitute(system('uname'), "\n", "", "")
  2. if g:OS == "Linux"
  3.     set encoding=utf-8
  4.     set termencoding=utf-8
  5. elseif g:OS == "FreeBSD"
  6.     set encoding=koi8-r
  7.     set termencoding=koi8-r
  8. else
  9.     echohl WarningMsg | echomsg "Warning: Unknown OS!" | echohl None
  10. endif

I don't think that horizontal tabs are good for displaying opened files. I like vertical tabs, just like Tree Style Tab extension for Firefox. So I picked bufferlist for this. Whenever I press Tab key the list of opened files shows up and I can jump to any previously opened file.

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ Buffer List """
  3. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  4. let g:BufferListWidth = 25
  5. let g:BufferListMaxWidth = 50
  6. hi BufferSelected term=reverse ctermfg=white ctermbg=black cterm=bold
  7. hi BufferNormal term=NONE ctermfg=black ctermbg=darkcyan cterm=NONE

NERDTree is used heavily when working on a project, not just single file. Note that ` is mapped in such a way so that an active file is immediately found in the tree and the mouse can be used for navigating through the tree. I don't use mouse too often. Sometimes I do, especially when I need to open a file in a directory different from the current one, but sometimes I prefer to use C-f shortcut.

Here below you can see that I specify a set of files that has to be ignored. I think you agree that editting media files, binary and temporary files make no sense.

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ NERDTree """
  3. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  4. map ` :NERDTreeFind <CR> :set mouse=a <CR>
  5.  
  6. let NERDChristmasTree = 1
  7. """ files to ignore """
  8. let NERDTreeIgnore = ['.*\.o$']
  9. let NERDTreeIgnore += ['.*\~$']
  10. let NERDTreeIgnore += ['.*\.out$']
  11. let NERDTreeIgnore += ['.*\.so$', '.*\.a$', '.*\.dll$']
  12. " audio/video "
  13. let NERDTreeIgnore += ['.*\.ogv$', '.*\.ogg$', '.*\.mp3$', '.*\.avi$']
  14. let NERDTreeIgnore += ['.*\.mp4$', '.*\.wmv$', '.*\.wma$', '.*\.mp([eE])?g$']
  15. " pics "
  16. let NERDTreeIgnore += ['.*\.[pP][nN][gG]$', '.*\.[jJ][pP]([eE])?[gG]$', '.*\.[gG][iI][fF]$']
  17. " tarballs "
  18. let NERDTreeIgnore += ['.*\.bz2$', '.*\.gz$', '.*\.tar$', '.*\.zip$', '.*\.tgz$', '.*\.rar$']
  19. " packages "
  20. let NERDTreeIgnore += ['.*\.deb$', '.*\.ipk$', '.*\.rpm$', '.*\.tbz$']
  21. " flash "
  22. let NERDTreeIgnore += ['.*\.[sS][wW][fF]$']
  23. " libtool archives and objs "
  24. let NERDTreeIgnore += ['.*\.lo', '.*\.la']
  25.  
  26. " java's binary files "
  27. let NERDTreeIgnore += ['.*\.class']
  28. " tags "
  29. let NERDTreeIgnore += ['tags']

I don't use taglist very often, but I prefer to keep it, because it has some useful functionality. Though taglist is often sits there and does nothing I nevertheless keep it, just in case I need some day.

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ TAGLIST """
  3. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  4. let Tlist_Exist_OnlyWindow = 1 " if you are the last, kill yourself "
  5. let Tlist_Use_Right_Window = 1 " split to the right side of the screen "
  6. let Tlist_Sort_Type = "order" " sort by order or name "
  7. "let Tlist_Display_Prototype = 0 " do not show prototypes and not tags in the taglist window. "
  8. let Tlist_Compart_Format = 1 " Remove extra information and blank lines from the taglist window. "
  9. let Tlist_GainFocus_On_ToggleOpen = 1 " Jump to taglist window on open. "
  10. let Tlist_Display_Tag_Scope = 1 " Show tag scope next to the tag name. "
  11. let Tlist_Close_On_Select = 1 " Close the taglist window when a file or tag is selected. "
  12. let Tlist_Enable_Fold_Column = 0 " Don't Show the fold indicator column in the taglist window "
  13. let Tlist_Auto_Highlight_Tag = 1
  14. let Tlist_Auto_Update = 1

I started using code_complete plugin not so long ago after I unexpectedly bumped into it on the web and decided that I want this plugin installed. It is extremely helpful for suggesting function's parameters, especially when these functions are written by someone and I'm using them, i.e. someone's library functions. The default completion shortcut was mapped on Tab. But Tab is already tken for my buffer list, so I have chosen Ctrl+Down. The plugin was also modified by me to support completion for more C++ statements snd structures. I suggest everybody using this plugin.

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ CODE COMPLETE """
  3. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  4. "let g:completekey = "s<C-@>""
  5. let g:completekey = "<C-Down>"

Good old OmniCppComplete. It assists me in all my development. This plugin is one of those "must have" plugins that kept me from using IDE insted of vim. If there were no completion in vim I would have gone with some IDE already... or maybe someone would have implemented such completion and everything would have stayed unchanged :).

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """"" OMNI CPP COMPLETE
  3. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  4. imap <C-@> <C-X><C-O>
  5. """ctags -R --c++-kinds=+p --fields=+iaS --extra=+q /usr/include/gtkmm-2.4/
  6. "map ctags :!ctags -V -R --c++-kinds=+p --fields=+iaS --extra=+q . <CR><Esc>
  7. map ctags :!ctags -L tags.files -V --c++-kinds=+p --fields=+iaS --extra=+q <CR><Esc>
  8. "set tags+=~/.vim/dev_tags/usr_include.ctags
  9. "set tags+=~/.vim/dev_tags/qt46.ctags
  10. "set tags+=~/.vim/dev_tags/qt47.ctags
  11. "set tags+=~/.vim/dev_tags/gtk.ctags
  12. "set tags+=~/.vim/dev_tags/gtkmm.ctags
  13. "set tags+=~/.vim/dev_tags/boost.ctags
  14.  
  15. let OmniCpp_NamespaceSearch = 1
  16. let OmniCpp_GlobalScopeSearch = 1
  17. let OmniCpp_ShowAccess = 1
  18. let OmniCpp_ShowPrototypeInAbbr = 1 " show function parameters
  19. let OmniCpp_MayCompleteDot = 0 " autocomplete after .
  20. let OmniCpp_MayCompleteArrow = 0 " autocomplete after ->
  21. let OmniCpp_MayCompleteScope = 0 " autocomplete after ::
  22. let OmniCpp_DefaultNamespaces = ["std", "_GLIBCXX_STD"]
  23. " automatically open and close the popup menu / preview window
  24. au CursorMovedI,InsertLeave * if pumvisible() == 0|silent! pclose|endif
  25. set completeopt=menuone,menu,longest,preview

For those of you who have never heard about Artistic Style, it is a source code beautifier. It is just a map for my convenience.

  1. """ Artisitc Style """
  2. map restyle :w<CR>:!astyle -s4 -cKLvjbUH --mode=c --align-pointer=type %<CR>:edit!<CR>

I'm still wondering why did I add these maps for spell checking, because I have nvere used it. Well, I used it couple of times when I tested these shortcuts, but I don't use them in my everyday life. Looks like I keep them in case I need them, just like I do with taglist.

  1. """ Spelling """
  2.  
  3. map ruspell :set spell spelllang=ru<CR>
  4. map enspell :set spell spelllang=en_us<CR>

  • ]s - next misspelled word
  • [s - prev misspelled word
  • zg - add misspelled word to dic
  • zw - remove misspelled word from dic
  • z= - suggestions

Ooh... too many mappings for just one person... ok. Commenting block with '//' is understood by all C/C++ developers and I think by those who develop in other languages. The rest mapping seem self explanatory. At least I hope they are. The first thing I would like to note is F3 mapping. I use it for searching through files for a string that I type in. It will prompt you to type that string and the mask of files to search in. Basically, this is the same as using grep. The next mapping is C-f which looks for a file, which is actually a wrapper for find.

  1. map // :CommentBlock<CR>
  2.  
  3. let g:C_f_cmd = "find . -iwholename '*INPUT*' | egrep -v \"(svn|~)\""
  4. map <C-f> :call ExecWithNavigableResultList(substitute(g:C_f_cmd, "INPUT", input("File to find => "), "g"), "", "%f")<CR>
  5.  
  6. map <F1> :echo "F1 - help\nF2 - NOTUSED\nF3 - Rgrep\nF4 - HexView\nF5 - man\nF6 - Cscope\nF7 - filencoding\nF8 - RotateEnc\nF9 - make\nF10 - line_num\n"<CR>
  7. map <F2> :echo "Not used!"<CR>
  8. map <F3> :call ExecWithNavigableResultList("egrep -nir '".input("String to find => ")."' `find . -iname '*".input("Mask => ")."'`", "", "")<CR>
  9. map <F4> :execute HexView()<CR>
  10. map <S-F4> :w<CR> :execute Toggle_H_CPP()<CR> :loadview<CR>
  11. map <F5> :! man <cword><CR>
  12. imap <F5> <ESC>:! man <cword><CR>
  13. map <F6> :cs find s <C-R>=expand("<cword>")<CR><CR>
  14. map <F7> :let &fileencoding=&encoding<CR>
  15. map <F8> :execute RotateEnc()<CR>
  16. """
  17. "map <F9> :write<CR>:make<CR>
  18. map <F9> :execute RunMake()<CR><C-l><CR>
  19. """"
  20. map <F10> :%s/^/\=line('.').' '/<CR>
  21. map <F11> :echo "Not used!"<CR>
  22. map <F12> :execute Run()<CR>
  23.  
  24. """ Folding
  25. map <C-Left> :set foldenable<CR>:set foldmethod=manual<CR>[{v]}:fold<CR>
  26. map <C-Right> zo
  27. """"""
  28.  
  29. """ Window resizing
  30. map <C-M-Up> :resize -1<CR>
  31. map <C-M-Down> :resize +1<CR>
  32. map <C-M-Left> :vertical resize -1<CR>
  33. map <C-M-Right> :vertical resize +1<CR>

I guess everything is clear here.

  1. " remove blank lines
  2. command! -range=% DBL        :<line1>,<line2>g/^\s*$/:delete
  3. " remove trailing white spaces
  4. command! -range=% DTB        :<line1>,<line2>s/\s\s*$//
  5. " C style comments
  6. command! -range CommentBlock :noh|execute CommentRange(<line1>, <line2>)

And here starts the magic that makes my custom functionality to work.

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ FUNCTIONS
  3. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  4. " Execute cmd and get a result list of files + jump to a file by pressing "Enter"
  5. function! ExecWithNavigableResultList(cmd, action, err_file_fmt)
  6.     let cmd_output = system(a:cmd)
  7.  
  8.     if cmd_output == ""
  9.         echohl WarningMsg | echomsg "Error: Nothing was found" | echohl None
  10.         return
  11.     endif
  12.  
  13.     let tmpfile = tempname()
  14.     let old_verbose = &verbose
  15.  
  16.     set verbose&vim
  17.  
  18.     exe "redir! > " . tmpfile
  19.     silent echon '[Searching files by cmd: ' . a:cmd . "]\n"
  20.     silent echon "[=====================================]\n"
  21.     silent echon cmd_output
  22.     redir END
  23.  
  24.     let &verbose = old_verbose
  25.  
  26.     let old_efm = &efm
  27.  
  28.     if a:err_file_fmt == ""
  29.         set efm=%f:%\\s%#%l:%m
  30.     else
  31.         let &efm=a:err_file_fmt
  32.     endif
  33.  
  34.     if v:version >= 700 && a:action == 'add'
  35.         execute "silent! caddfile " . tmpfile
  36.     else
  37.         if exists(":cgetfile")
  38.             execute "silent! cgetfile " . tmpfile
  39.         else
  40.             execute "silent! cfile " . tmpfile
  41.         endif
  42.     endif
  43.  
  44.     let &efm = old_efm
  45.  
  46.     botright copen
  47.  
  48.     silent call matchadd('RedBg', "\\\\bug.*$")
  49.     silent call matchadd('YellowBg', "\\\\fixme.*$")
  50.     silent call matchadd('GreenBg', "\\\\todo.*$")
  51.  
  52.     call delete(tmpfile)
  53. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ CommentRange()
  3. """
  4. """ param[in] start - Start of selected block
  5. """ param[in] stop - End of selected block
  6. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  7. function! CommentRange(start, stop)
  8.     execute ":mkview"
  9.     if strpart(getline(a:start), 0, 2) == "//"
  10.         return ":" . a:start. "," . a:stop . 's/\/\///|noh|loadview'
  11.     else
  12.         return ":" . a:start. "," . a:stop . 's/^/\/\//|noh|loadview'
  13.     endif
  14. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ ReTag() - Rebuild tags and save them to the project's top dir
  3. """
  4. """ code - operation code
  5. """      "load" - find tags file and set it
  6. """      "retag" - update tags for the current file
  7. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  8. let g:projectFile = expand("$HOME")."/.vim_projects"
  9. function! ReTag(code)
  10.     if a:code == ""
  11.         return
  12.     endif
  13.  
  14.     let l:projectPath = GetProjectForFile(expand("%:p"))
  15.  
  16.     if l:projectPath != ""
  17.         if a:code == "retag"
  18.             " retag the file to l:projectPath/tags
  19.             execute "silent! :!ctags -R -a --sort=no --c++-kinds=+p --fields=+iaS --extra=+q -f ".l:projectPath."/tags ".expand("%:p")
  20.         elseif a:code == "load"
  21.             " if the tags hasn't been added yet
  22.             if stridx(&tags, l:projectPath) == -1
  23.                 execute "silent! set tags+=".l:projectPath."/tags"
  24.             endif
  25.         endif
  26.     endif
  27. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ HexView() - Toggle hex view of the file
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. let s:hflag = 0
  6. function! HexView()
  7.     if s:hflag == 0
  8.         let s:hflag = 1
  9.         return ":%!xxd"
  10.     else
  11.         let s:hflag = 0
  12.         return ":%!xxd -r"
  13.     endif
  14. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ CscopeSetup
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. function! CscopeSetup()
  6.     let l:projectPath = GetProjectForFile(expand("%:p"))
  7.     if l:projectPath == ""
  8.         let l:projectPath = getcwd()
  9.     endif
  10.     let l:usedShell = expand("$SHELL")
  11.  
  12.     execute "!find . -name '*.cpp' -o -name '*.c' -o -name '*.C' -o -name '*.cc' -o -name '*.h' > cscope.files"
  13.     execute '!cscope -q -b'
  14.     " if [t]csh
  15.     if stridx(l:usedShell, 'csh') >= 0
  16.         execute ':!setenv CSCOPE_DB '.l:projectPath.'/cscope.out'
  17.     else
  18.         execute ':!export CSCOPE_DB='.l:projectPath.'/cscope.out'
  19.     endif
  20.  
  21.     return
  22. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ Run() - runs executable
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. function! Run()
  6.     let l:name = getcwd()
  7.     let l:beg = strridx(l:name, "/")
  8.     "echo s:beg
  9.     let l:name = strpart(l:name, l:beg + 1)
  10.     "echo s:name
  11.     return ":! ./".l:name
  12. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ RotateEnc()
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. let b:encindex = 0
  6. function! RotateEnc()
  7.     let y = -1
  8.     while y == -1
  9.         let encstring = "#8bit-cp1251#8bit-cp866#utf-8#koi8-r#utf-16#"
  10.         let x = match(encstring,"#",b:encindex)
  11.         let y = match(encstring,"#",x+1)
  12.         let b:encindex = x+1
  13.         if y == -1
  14.             let b:encindex = 0
  15.         else
  16.             let str = strpart(encstring,x+1,y-x-1)
  17.             return ":set encoding=".str
  18.         endif
  19.     endwhile
  20. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ Toggle_H_CPP() - Jump to source/header
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. function! Toggle_H_CPP()
  6. "    execute ":mkview"
  7.  
  8.     let l:projectPath = GetProjectForFile(expand("%:p"))
  9.     if l:projectPath == ""
  10.         let l:projectPath = "."
  11.     endif
  12.  
  13.     let l:ext = ".".expand("%:e")
  14.     let l:dirname = expand("%:p:h")
  15.     let l:basename = substitute(system("basename ".expand("%:p")." ".l:ext), "\n", "", "g")
  16.     let l:fname = l:dirname."/".l:basename
  17.  
  18.     let l:ext = tolower(l:ext)
  19.     "echo l:ext
  20.  
  21.     let l:sourceExt = [".c", ".cc", ".cpp", ".cxx"]
  22.     let l:headerExt = [".h", ".hpp"]
  23.  
  24.     let l:new_ext = ""
  25.     "if l:ext == "c" || l:ext == "cc" || l:ext == "cpp" || l:ext == "cxx"
  26.     if index(l:sourceExt, l:ext) != -1
  27.         let l:new_ext = "h"
  28.  
  29.         " try to find the header that is located near the source
  30.         for l:extension in l:headerExt
  31.             if getftype(l:fname.l:extension) != ""
  32.                 execute "find ".l:fname.l:extension
  33.                 return
  34.             endif
  35.         endfor
  36.  
  37.     elseif index(l:headerExt, l:ext) != -1
  38.         let l:new_ext = "c"
  39.  
  40.         " try to find the source that is located near the header
  41.         for l:extension in l:sourceExt
  42.             if getftype(l:fname.l:extension) != ""
  43.                 execute "find ".l:fname.l:extension
  44.                 return
  45.             endif
  46.         endfor
  47.  
  48.     else
  49.         return
  50.     endif
  51.  
  52.     let l:ignore_list = "(~|\.svn)"
  53.     let l:cmd = "find ".l:projectPath."/ -name '".expand("%:t:r").".*' | egrep -v \"".l:ignore_list."\" | grep -i '\\.".l:new_ext."' | perl -ne 'print \"$.\\t$_\"'"
  54.  
  55.     let l:list = system(l:cmd)
  56.     let l:num = strlen(substitute(l:list, "[^\n]", "", "g"))
  57.     if l:num < 1
  58.         echo "'".a:name."' not found"
  59.         return
  60.     endif
  61.  
  62.     if l:num != 1
  63.         echo l:list
  64.         let l:input = input("Which ? (CR=nothing)\n")
  65.         if strlen(l:input) == 0
  66.             return
  67.         endif
  68.         if strlen(substitute(l:input, "[0-9]", "", "g")) > 0
  69.             echo "Not a number"
  70.             return
  71.         endif
  72.         if l:input < 1 || l:input > l:num
  73.             echo "Out of range"
  74.             return
  75.         endif
  76.         let l:line = matchstr("\n".l:list, "\n".l:input."\t[^\n]*")
  77.     else
  78.         let l:line = l:list
  79.     endif
  80.  
  81.  
  82.     "let l:line = substitute(l:line, "^[^\t]*\t./", "", "")
  83.     let l:line = substitute(l:line, "^[^\t]*\t", "", "")
  84.  
  85.     """sf %:t:r.c
  86.     execute "find ".l:line
  87. "    execute ":loadview"
  88. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ RunMake() - runs make
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. function! RunMake()
  6.     silent !/bin/sh -c '(make > /dev/null) 2> ./.make.out' &
  7.     "silent !/bin/sh -c 'make -j3 | tee ./.build_out.orig' &
  8.     "return ":Shell tail -f ./.make.out"
  9. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ ShowMakeResults()
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. function! ShowMakeResults()
  6.  
  7.     try
  8.         silent !/bin/sh -c "tr -cd '\11\12\40-\176' < ./.make.out > ./.make.out.strip"
  9.         cgetfile .make.out.strip
  10.         copen 20
  11.     "catch /E484:/
  12.     catch
  13.         echo "File .make.out cannot be found"
  14.     finally
  15.         "asdfasdf
  16.     endtry
  17.  
  18.     return
  19. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ RunShellCommand()
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. command! -complete=shellcmd -nargs=+ Shell call s:RunShellCommand(<q-args>)
  6. function! s:RunShellCommand(cmdline)
  7.     echo a:cmdline
  8.     let l:expanded_cmdline = a:cmdline
  9.     for part in split(a:cmdline, ' ')
  10.         if part[0] =~ '\v[%#<]'
  11.             let l:expanded_part = fnameescape(expand(part))
  12.             let l:expanded_cmdline = substitute(l:expanded_cmdline, part, l:expanded_part, '')
  13.         endif
  14.     endfor
  15.     botright new
  16.     setlocal buftype=nofile bufhidden=wipe nobuflisted noswapfile nowrap
  17.     call setline(1, 'You entered:    ' . a:cmdline)
  18.     call setline(2, 'Expanded Form:  ' .l:expanded_cmdline)
  19.     call setline(3, substitute(getline(2),'.','=','g'))
  20.     execute '$read !'. l:expanded_cmdline
  21.     setlocal nomodifiable
  22.     1
  23. endfunction

  1. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  2. """ GetProjectForFile()
  3. """
  4. """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
  5. function! GetProjectForFile(filePath)
  6.     if a:filePath == ""
  7.         return ""
  8.     endif
  9.  
  10.     " read projects file
  11.     for sLine in readfile(g:projectFile)
  12.         " if line is not empty
  13.         if l:sLine !~ '^\s*$' && l:sLine !~ '^\s*\#.*$'
  14.  
  15.             " trim
  16.             let l:projectPath = l:sLine
  17.             "l:projectPath = substitute(l:projectPath, "^\s*", "", "")
  18.             "l:projectPath = substitute(l:projectPath, "\s*", "", "")
  19.  
  20.             if stridx(a:filePath, l:projectPath) == 0
  21.                 return l:projectPath
  22.             endif
  23.         endif
  24.     endfor
  25.  
  26.     return ""
  27. endfunction

  1. " Custom file types detection
  2. augroup FileTypeDetectionGrp
  3.     au!
  4.     au BufNewFile,BufRead *.qml setfiletype qml
  5.     au BufNewFile,BufRead *.jcs setfiletype c
  6. augroup END

  1. augroup WhiteSpaceGrp
  2.     au!
  3.     " highlight trailing spaces
  4.     au BufNewFile,BufRead * let b:mtrailingws=matchadd('ErrorMsg', '\s\+$', -1)
  5.     " highlight tabs between spaces
  6.     au BufNewFile,BufRead * let b:mtabbeforesp=matchadd('ErrorMsg', '\v(\t+)\ze( +)', -1)
  7.     au BufNewFile,BufRead * let b:mtabaftersp=matchadd('ErrorMsg', '\v( +)\zs(\t+)', -1)
  8. augroup END

  1. augroup CtagsGrp
  2.     au!
  3.     au BufWritePost * if &modifiable | silent call ReTag("retag") | redraw!
  4.     "au BufNew * if &modifiable | silent call ReTag("load") | redraw!
  5.     au BufEnter * if &modifiable | silent call ReTag("load") | redraw!
  6.  
  7. augroup END

  1. augroup ViewGrp
  2.     au!
  3.     "au BufWritePost * if &modifiable | silent mkview
  4.     au WinLeave,BufWritePost * if &modifiable | silent mkview
  5.  
  6.     "au BufReadPost * if &modifiable | silent loadview
  7.     au WinEnter,BufReadPost * if &modifiable | silent loadview
  8. augroup END

  1. " if vim 7.3 and higher
  2. if v:version >= 703
  3.     set undodir=~/.vim/undo
  4.     set textwidth=90
  5.     set cc=+1
  6.     hi ColorColumn ctermbg=green guibg=lightgrey
  7.  
  8.     set undofile
  9. else
  10.     " highlight 91st column if the line exceeds 90 char width
  11.     highlight WidthStop ctermbg=green guibg=green
  12.     highlight AfterWidthStop ctermbg=black guibg=black
  13.  
  14.     au BufWinEnter * let w:m2=matchadd('WidthStop', '\%>90v.\+', -1)
  15.     au BufWinEnter * let w:m2=matchadd('AfterWidthStop', '\%>91v.\+', -1)
  16. endif

Here come application specific mappings. The ones that you have seen above were common mappings, and these are for vimdiff, gvim and vim. My favorite here is Alt+4 for exploring my todo list.

  1. """""""""""
  2. """ VIMDIFF
  3. """""""""""
  4. if v:progname =~? "vimdiff"
  5.     map <F1> :echo "F1 - help\nF2 - NOTUSED\nF3 - Rgrep\nF4 - HexView\nF5 - man\nF6 - DiffPut\nF7 - DiffGet\nF8 - RotateEnc\nF9 - make\nF10 - line_num\n"<CR>
  6.     map <F6> :DiffPut<CR>
  7.     map <F7> :DiffGet<CR>
  8.  
  9.     command! -range DiffPut :noh|execute DiffPutRange(<line1>, <line2>)
  10.     command! -range DiffGet :noh|execute DiffGetRange(<line1>, <line2>)
  11.  
  12.     function! DiffPutRange(start, stop)
  13.     return ":" . a:start. "," . a:stop . 'diffput|noh|diffupdate'
  14.     endfunction
  15.  
  16.     function! DiffGetRange(start, stop)
  17.     return ":" . a:start. "," . a:stop . 'diffget|noh|diffupdate'
  18.     endfunction
  19.  
  20. """"""""
  21. """ GVIM
  22. """"""""
  23. elseif v:progname =~? "gvim"
  24.     set guitablabel=%!expand(\"\%:p\")
  25.     colorscheme torte
  26.  
  27.     """"""""
  28.     """ MAPS
  29.     """"""""
  30.     map <C-Tab> :call BufferList()<CR>
  31.  
  32.     """ Alt + <Num>
  33.     map <A-0> :NERDTreeToggle .<CR>
  34.     map <A-1> :execute ShowMakeResults()<CR><C-l>
  35.     "map <A-2> :TlistToggle<CR>:TlistAddFilesRecursive . *.{cpp,c,C,h,hpp,cc,cxx}<CR>
  36.     map <A-2> :TlistToggle<CR>:TlistAddFiles %<CR>
  37.     map <A-3> :echo "Shortcut is not used!"<CR>
  38.     map <A-4> :echo "Shortcut is not used!"<CR>
  39.     map <A-5> :echo "Shortcut is not used!"<CR>
  40.     map <A-6> :echo "Shortcut is not used!"<CR>
  41.     map <A-7> :echo "Shortcut is not used!"<CR>
  42.     map <A-8> :echo "Shortcut is not used!"<CR>
  43.     map <A-9> :echo "Shortcut is not used!"<CR>
  44.  
  45. "    let g:vimim_ctrl_space_to_toggle = 0
  46.     imap <C-Space> <C-X><C-O>
  47.     " Open new tab
  48.     map <C-t> :tabnew <CR>
  49.     imap <C-t> <ESC>:tabnew <CR>
  50.  
  51. """""""
  52. """ VIM
  53. """""""
  54. elseif v:progname =~? "vim"
  55. """"""""""""""""""""""""
  56. """""" track line length
  57. """"""""""""""""""""""""
  58.     highlight LineNr ctermbg=blue guibg=blue
  59.  
  60.     highlight RedBg ctermbg=red guibg=red
  61.     highlight YellowBg ctermbg=yellow guibg=yellow
  62.     highlight GreenBg ctermbg=green guibg=green
  63.  
  64.     au BufWinEnter * set mouse=""
  65.  
  66.     """"""""
  67.     """ MAPS
  68.     """"""""
  69.     " Ctrl + Tab
  70.     map <C-I> :call BufferList()<CR>
  71.     """ Alt + <Num>
  72.     map ^[0 :NERDTreeToggle .<CR>
  73.     map ^[1 :execute ShowMakeResults()<CR><C-l>
  74.     "map ^[2 :TlistToggle<CR>:TlistAddFilesRecursive . *.{cpp,c,C,h,hpp,cc,cxx}<CR>
  75.     map ^[2 :TlistToggle<CR>:TlistAddFiles %<CR>
  76.     map ^[3 :echo "Shortcut is not used!"<CR>
  77.     map ^[4 :silent call ExecWithNavigableResultList("egrep -rni '\\\\\(todo\|fixme\|bug\|note\)' * \| egrep -v \"\(~\|Binary \|.svn\)\"", "", "")<CR><CR>
  78.     map ^[5 :echo "Shortcut is not used!"<CR>
  79.     map ^[6 :echo "Shortcut is not used!"<CR>
  80.     map ^[7 :echo "Shortcut is not used!"<CR>
  81.     map ^[8 :echo "Shortcut is not used!"<CR>
  82.     map ^[9 :echo "Shortcut is not used!"<CR>
  83. endif

This is probably the most mystic part. The first check is used to find out if we have a directory for an unlimited undo lists, which were introduced in vim 7.3. If not, we create it. As for the second check, then we look at .vim_projects file that I use. I added these file for registering all projects I work with. This file holds the paths of top directories for projects which are used in some functions listed above. I know there are index and projects plugins, but I feel comfortable with my own limited implementation, because I don't need all functionality they provide.

  1. " Paths that have to be created before using vim:
  2. if v:version >= 703 && getftype(&undodir) == ""
  3.     "echo "Undo directory doesn't exist"
  4.     execute mkdir(&undodir)
  5. endif
  6.  
  7. if getftype(g:projectFile) == ""
  8.     "echo "Projects file doesn't exist"
  9.     execute system("/usr/bin/touch ".g:projectFile)
  10. endif

Post new comment

The content of this field is kept private and will not be shown publicly.
CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
pun_tuatio_: