diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f2747f7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,14 @@ +BSD 0-clause license, "Zero Clause BSD", SPDX: 0BSD + +Copyright (C) 2022 by Daniel C. Nygren + +Permission to use, copy, modify, and/or distribute this software for any purpose +with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. diff --git a/README b/README index b70c423..3a5ee0d 100644 --- a/README +++ b/README @@ -1,9 +1,25 @@ -This is a mirror of http://www.vim.org/scripts/script.php?script_id=157 +This Vim plugin is based on prior work from a number of authors. See the +cscope_helper.vim comment header block for details. -This plugin will automatically load cscope.out databases into vim when you open a C file. (headers included) +Save this file as ~/.vim/plugin/cscope_helper.vim so you can invoke vim/gvim in +subdirectories and still get cscope.out loaded. -It does a search starting at the directory that the file is in, and checking the parent directories until it find the cscope.out file. The idea being that you can start editing a source file deep in a project dir, and it will find the correct cscope database a couple dirs up. +A prerequisite for use is that an initial Cscope database has been generated. +Cscope can be executed on the command line, or a script like cscope_db_gen can +be used to generate the database. See https://github.com/dnygren/cscope_db_gen +for an example of how to generate a Cscope database for C/C++. -This version also creates some macros and a menu that can be useful. If you don't like them, you can set g:autocscope_menus to 0 and they won't load. +This plugin will automatically load a cscope.out database (created manually in +the base directory of a source code file tree) into Vim when you open a file. +It performs a search starting at the directory that the edited file is in, +checking the parent directories until it finds the cscope.out file. Therefore +you can start editing a file deep in a project directory, and it will find the +correct Cscope database. It will also automatically update the cscope database +after file saves. If new files are created, the cscope.out database must be +recreated manually. +Keystroke macros and a pull down menu are provided to invoke the Cscope +functions. + +A cheatsheet is provided to assist in executing the keystroke macros. diff --git a/cheatsheet.txt b/cheatsheet.txt new file mode 100644 index 0000000..6567e8c --- /dev/null +++ b/cheatsheet.txt @@ -0,0 +1,24 @@ +"""""""""""""" Jason Duell's Cscope/Vim Key Mappings Cheat Sheet """"""""""""""" +" (Based on http://cscope.sourceforge.net/cscope_maps.vim with light edits.) +" The following maps all invoke one of the following Cscope search types: +" +" 's' symbol Find all references to the token under cursor +" 'g' global Find global definition(s) of the token under cursor +" 'c' calls Find all calls to the function name under cursor +" 'd' called Find functions that function under cursor calls +" 't' text Find all instances of the text under cursor +" 'e' egrep Find egrep pattern for the word under cursor +" 'f' file Open the filename under cursor +" 'i' includes Find files that include the filename under cursor +" +" The starting keys for the searches are: +" CTRL-\ (Control Backslash) jumps the whole Vim window to the search result, +" CTRL-H (Control H) splits the Vim window horizontally to display the result, +" CTRL-V (Control V) splits the Vim window vertically to display the result. +" CTRL-T (Control T) jumps back to where the search began. +" +" To do the first type of search, hit 'CTRL-\', followed by one of the Cscope +" search types above (s,g,c,d,t,e,f,i). Use CTRL-T to go back to where the +" searching began. The second and third types of search use CTRL-H or CTRL-V +" to split the window horizontally or vertically to display the search result. +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" diff --git a/plugin/autoload_cscope.vim b/plugin/autoload_cscope.vim deleted file mode 100644 index 6e8d96d..0000000 --- a/plugin/autoload_cscope.vim +++ /dev/null @@ -1,184 +0,0 @@ -" Vim global plugin for autoloading cscope databases. -" Last Change: Wed Jan 26 10:28:52 Jerusalem Standard Time 2011 -" Maintainer: Michael Conrad Tadpol Tilsra -" Revision: 0.5 - -if exists("loaded_autoload_cscope") - finish -endif -let loaded_autoload_cscope = 1 - -" requirements, you must have these enabled or this is useless. -if( !has('cscope') || !has('modify_fname') ) - finish -endif - -let s:save_cpo = &cpo -set cpo&vim - -" If you set this to anything other than 1, the menu and macros will not be -" loaded. Useful if you have your own that you like. Or don't want my stuff -" clashing with any macros you've made. -if !exists("g:autocscope_menus") - let g:autocscope_menus = 1 -endif - -"== -" windowdir -" Gets the directory for the file in the current window -" Or the current working dir if there isn't one for the window. -" Use tr to allow that other OS paths, too -function s:windowdir() - if winbufnr(0) == -1 - let unislash = getcwd() - else - let unislash = fnamemodify(bufname(winbufnr(0)), ':p:h') - endif - return tr(unislash, '\', '/') -endfunc -" -"== -" Find_in_parent -" find the file argument and returns the path to it. -" Starting with the current working dir, it walks up the parent folders -" until it finds the file, or it hits the stop dir. -" If it doesn't find it, it returns "Nothing" -function s:Find_in_parent(fln,flsrt,flstp) - let here = a:flsrt - while ( strlen( here) > 0 ) - if filereadable( here . "/" . a:fln ) - return here - endif - let fr = match(here, "/[^/]*$") - if fr == -1 - break - endif - let here = strpart(here, 0, fr) - if here == a:flstp - break - endif - endwhile - return "Nothing" -endfunc -" -"== -" Cycle_macros_menus -" if there are cscope connections, activate that stuff. -" Else toss it out. -" TODO Maybe I should move this into a seperate plugin? -let s:menus_loaded = 0 -function s:Cycle_macros_menus() - if g:autocscope_menus != 1 - return - endif - if cscope_connection() - if s:menus_loaded == 1 - return - endif - let s:menus_loaded = 1 - set csto=0 - set cst - silent! map s :cs find s =expand("") - silent! map g :cs find g =expand("") - silent! map d :cs find d =expand("") - silent! map c :cs find c =expand("") - silent! map t :cs find t =expand("") - silent! map e :cs find e =expand("") - silent! map f :cs find f =expand("") - silent! map i :cs find i =expand("") - if has("menu") - nmenu &Cscope.Find.Symbols - \ :cs find s =expand("") - nmenu &Cscope.Find.Definitiong - \ :cs find g =expand("") - nmenu &Cscope.Find.Calledd - \ :cs find d =expand("") - nmenu &Cscope.Find.Callingc - \ :cs find c =expand("") - nmenu &Cscope.Find.Assignmentt - \ :cs find t =expand("") - nmenu &Cscope.Find.Egrepe - \ :cs find e =expand("") - nmenu &Cscope.Find.Filef - \ :cs find f =expand("") - nmenu &Cscope.Find.Includingi - \ :cs find i =expand("") -" nmenu &Cscope.Add :cs add -" nmenu &Cscope.Remove :cs kill - nmenu &Cscope.Reset :cs reset - nmenu &Cscope.Show :cs show - " Need to figure out how to do the add/remove. May end up writing - " some container functions. Or tossing them out, since this is supposed - " to all be automatic. - endif - else - let s:menus_loaded = 0 - set nocst - silent! unmap s - silent! unmap g - silent! unmap d - silent! unmap c - silent! unmap t - silent! unmap e - silent! unmap f - silent! unmap i - if has("menu") " would rather see if the menu exists, then remove... - silent! nunmenu Cscope - endif - endif -endfunc -" -"== -" Unload_csdb -" drop cscope connections. -function s:Unload_csdb() - if exists("b:csdbpath") - if cscope_connection(3, "out", b:csdbpath) - let save_csvb = &csverb - set nocsverb - exe "cs kill " . b:csdbpath - set csverb - let &csverb = save_csvb - endif - endif -endfunc -" -"== -" Cycle_csdb -" cycle the loaded cscope db. -function s:Cycle_csdb() - if exists("b:csdbpath") - if cscope_connection(3, "out", b:csdbpath) - return - "it is already loaded. don't try to reload it. - endif - endif - let newcsdbpath = s:Find_in_parent("cscope.out",s:windowdir(),$HOME) -" echo "Found cscope.out at: " . newcsdbpath -" echo "Windowdir: " . s:windowdir() - if newcsdbpath != "Nothing" - let b:csdbpath = newcsdbpath - if !cscope_connection(3, "out", b:csdbpath) - let save_csvb = &csverb - set nocsverb - exe "cs add " . b:csdbpath . "/cscope.out " . b:csdbpath - set csverb - let &csverb = save_csvb - endif - " - else " No cscope database, undo things. (someone rm-ed it or somesuch) - call s:Unload_csdb() - endif -endfunc - -" auto toggle the menu -augroup autoload_cscope - au! - au BufEnter *.[chly] call Cycle_csdb() | call Cycle_macros_menus() - au BufEnter *.cc call Cycle_csdb() | call Cycle_macros_menus() - au BufUnload *.[chly] call Unload_csdb() | call Cycle_macros_menus() - au BufUnload *.cc call Unload_csdb() | call Cycle_macros_menus() -augroup END - -let &cpo = s:save_cpo - diff --git a/plugin/cscope_helper.vim b/plugin/cscope_helper.vim new file mode 100644 index 0000000..a4aed23 --- /dev/null +++ b/plugin/cscope_helper.vim @@ -0,0 +1,430 @@ +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" +" cscope_helper.vim: Vim global plugin for Cscope databases +" +" Based on revision: 0.5 of autoload_cscope.vim by Michael Conrad Tadpol Tilsra +" https://www.vim.org/scripts/script.php?script_id=157 +" https://github.com/vim-scripts/autoload_cscope.vim +" and based on Jason Duell's cscope_macros.vim 2.0.0 +" https://www.vim.org/scripts/script.php?script_id=51 +" http://cscope.sourceforge.net/cscope_maps.vim +" with additions from ckelau & ufengzh for .cpp suffix files +" with additions from Code-Monky & ckelau for .java suffix files +" with additions for .hpp suffix files by Dan Nygren +" with additions for Python and Go by xin3liang +" See pull requests at https://github.com/vim-scripts/autoload_cscope.vim +" with additions for automatically updating cscope database after saves by Flynn +" https://vim.fandom.com/wiki/Script:157 +" CC BY-SA license +" +" Combined by: Dan Nygren +" Email: nygren@msss.com +" Permanent Email: dan.nygren@gmail.com +" Copyright (c) 2022 Dan Nygren. +" BSD 0-clause license, "Zero Clause BSD", SPDX: 0BSD +" +" Save this file as ~/.vim/plugin/cscope_helper.vim so you can invoke +" vim/gvim in subdirectories and still get cscope.out loaded. It performs a +" search starting at the directory that the edited file is in, checking the +" parent directories until it finds the cscope.out file. Therefore you can +" start editing a file deep in a project directory, and it will find the +" correct Cscope database. +" A prerequisite for use is that a Cscope database has been generated. Cscope +" can be executed on the command line, or a script like cscope_db_gen can be +" used to generate the database. See https://github.com/dnygren/cscope_db_gen +" for an example of how to generate a Cscope database for C/C++. +" This plugin also adds a Cscope selection to gvim's menu bar. +" +" CALL SEQUENCE Place in ~/.vim/plugin directory to call +" +" EXAMPLES N/A +" +" TARGET SYSTEM Unix vim / gvim +" +" DEVELOPED ON Linux +" +" CALLS cscope, cscope_db_gen, global, gtags-cscope +" +" CALLED BY vim / gvim +" +" INPUTS autocscope_auto_update, loaded_autoload_cscope +" +" OUTPUTS (Parameters modified, include global/static data) +" +" RETURNS (Type and meaning of return value, if any) +" +" ERROR HANDLING (Describe how errors are handled) +" +" SECURE CODING (List methods used to prevent exploits against this code) +" +" WARNINGS 1) A Cscope database must exist in a parent directory. +" 2) If new files are created, create a new list of files +" (e.g. cscope.files) in the repository's base directory by +" running cscope_db_gen without flags or a similar command. +" 3) Cscope's global function definition search does not work +" with '__attribute__((unused))' in function definitions because +" Cscope cannot tolerate arbitrary use of () characters in the +" argument list. +" (N. Describe anything a maintainer should be aware of) +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +"""""""""""""" Jason Duell's Cscope/Vim Key Mappings Cheat Sheet """"""""""""""" +" (Based on http://cscope.sourceforge.net/cscope_maps.vim with light edits.) +" The following maps all invoke one of the following Cscope search types: +" +" 's' symbol Find all references to the token under cursor +" 'g' global Find global definition(s) of the token under cursor +" 'c' calls Find all calls to the function name under cursor +" 'd' called Find functions that function under cursor calls +" 't' text Find all instances of the text under cursor +" 'e' egrep Find egrep pattern for the word under cursor +" 'f' file Open the filename under cursor +" 'i' includes Find files that include the filename under cursor +" +" The starting keys for the searches are: +" CTRL-\ (Control Backslash) jumps the whole Vim window to the search result, +" CTRL-H (Control H) splits the Vim window horizontally to display the result, +" CTRL-V (Control V) splits the Vim window vertically to display the result. +" CTRL-T (Control T) jumps back to where the search began. +" +" To do the first type of search, hit 'CTRL-\', followed by one of the Cscope +" search types above (s,g,c,d,t,e,f,i). Use CTRL-T to go back to where the +" searching began. The second and third types of search use CTRL-H or CTRL-V +" to split the window horizontally or vertically to display the search result. +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +" If this script is already loaded, skip loading the script again. +if exists("loaded_autoload_cscope") + finish +endif +let loaded_autoload_cscope = 1 + +" The default Cscope path component (cspc) value of "0" displays the entire +" path, which usually doesn't fit the screen and so gets be abbreviated to just +" the starting path (usually useless) and the ending path (most already known). +" The below construct sets cspc to a more reasonable value if cscp hasn't been +" changed from the default in the user's .vimrc file. +" +if &cspc == "0" + set cspc=4 +endif + +" If set to 1, auto update your cscope/gtags database and reset the Cscope +" connection when a file is saved. +" The default is 1, update the cscope/gtags database and reset the connection. +if !exists("g:autocscope_auto_update") + let g:autocscope_auto_update = 1 +endif + +" If set to 1, the menu and macros will be loaded. +" The default is 1, use menus. Set value to 0 if they are not wanted. +if !exists("g:autocscope_menus") + let g:autocscope_menus = 1 +endif + +" If set to 1, use gtags-cscope which is faster than cscope / cscope_bd_gen. +" The default is 0, do not use gtags-cscope, use cscope / cscope_db_gen instead. +if !exists("g:autocscope_use_gtags") + let g:autocscope_use_gtags = 0 +endif + +" If set to 1, use the cscope database generator script "cscope_db_gen" which +" can examine more that Cscope's C (.c & .h), lex (.l), and yacc (.y) files. +" The default is 1, use cscope_db_gen. Set value to 0 if cscope is wanted. +if !exists("g:autocscope_use_cscope_db_gen") + let g:autocscope_use_cscope_db_gen = 1 +endif + +" """"""""""""" key map timeouts """"""""""""" +" " +" " By default Vim will only wait 1 second for each keystroke in a mapping. +" " You may find that too short with the above typemaps. If so, you should +" " either turn off mapping timeouts via 'notimeout'. +" " +" "set notimeout +" " +" " Or, you can keep timeouts, by uncommenting the timeoutlen line below, +" " with your own personal favorite value (in milliseconds): +" " +" "set timeoutlen=4000 +set timeoutlen=3000 +" " +" " Either way, since mapping timeout settings by default also set the +" " timeouts for multicharacter 'keys codes' (like ), you should also +" " set ttimeout and ttimeoutlen: otherwise, you will experience strange +" " delays as vim waits for a keystroke after you hit ESC (it will be +" " waiting to see if the ESC is actually part of a key code like ). +" " +" "set ttimeout +set ttimeout +" " +" " A tenth of a second works well for key code timeouts. If you +" " experience problems and have a slow terminal or network connection +" " set it higher. If you don't set ttimeoutlen, a sluggish value for +" " timeoutlent (default: 1000 = 1 second) is used. +" " +" "set ttimeoutlen=100 +set ttimeoutlen=100 + +" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +" ^^^^^^^^^^ Place code that may need modification above this point. ^^^^^^^^^^ +" ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +" Vim must have these enabled or this plugin is useless. +if( !has('cscope') || !has('modify_fname') ) + finish +endif + +let s:save_cpo = &cpo +set cpo&vim + +"== +" windowdir +" Gets the directory for the file in the current window +" Or the current working dir if there isn't one for the window. +" Use tr to allow that other OS paths, too +function s:windowdir() + if winbufnr(0) == -1 + let unislash = getcwd() + else + let unislash = fnamemodify(bufname(winbufnr(0)), ':p:h') + endif + return tr(unislash, '\', '/') +endfunc +" +"== +" Find_in_parent +" find the file argument and returns the path to it. +" Starting with the current working dir, it walks up the parent folders +" until it finds the file, or it hits the stop dir. +" If it doesn't find it, it returns "Nothing" +function s:Find_in_parent(fln,flsrt,flstp) + let here = a:flsrt + while ( strlen( here) > 0 ) + if filereadable( here . "/" . a:fln ) + return here + endif + let fr = match(here, "/[^/]*$") + if fr == -1 + break + endif + let here = strpart(here, 0, fr) + if here == a:flstp + break + endif + endwhile + return "Nothing" +endfunc +" +"== +" Cycle_macros_menus +" if there are Cscope connections, activate that stuff. +" Else toss it out. +" TODO Maybe I should move this into a separate plugin? +let s:menus_loaded = 0 +function s:Cycle_macros_menus() + if g:autocscope_menus != 1 + return + endif + if cscope_connection() + if s:menus_loaded == 1 + return + endif + let s:menus_loaded = 1 + set csto=0 + set cst +" Update the cheat sheet if the mappings are changed. + silent! map s :cs find s =expand("") + silent! map g :cs find g =expand("") + silent! map c :cs find c =expand("") + silent! map d :cs find d =expand("") + silent! map t :cs find t =expand("") + silent! map e :cs find e =expand("") + silent! map f :cs find f =expand("") + silent! map i :cs find i =expand("") +" Split screen horizontally with CTRL h + silent! map s :scs find s =expand("") + silent! map g :scs find g =expand("") + silent! map c :scs find c =expand("") + silent! map d :scs find d =expand("") + silent! map t :scs find t =expand("") + silent! map e :scs find e =expand("") + silent! map f :scs find f =expand("") + silent! map i :scs find i =expand("") +" End Split screen horizontally +" Split screen vertically with CTRL v +" Line continuation. See :help line-continuation + silent! map s + \ :vert scs find s =expand("") + silent! map g + \ :vert scs find g =expand("") + silent! map c + \ :vert scs find c =expand("") + silent! map d + \ :vert scs find d =expand("") + silent! map t + \ :vert scs find t =expand("") + silent! map e + \ :vert scs find e =expand("") + silent! map f + \ :vert scs find f =expand("") + silent! map i + \ :vert scs find i =expand("") +" End Split screen vertically + if has("menu") +" Line continuation. See :help line-continuation + nmenu &Cscope.Find.Symbols + \ :cs find s =expand("") + nmenu &Cscope.Find.Definitiong + \ :cs find g =expand("") + nmenu &Cscope.Find.Callingc + \ :cs find c =expand("") + nmenu &Cscope.Find.Calledd + \ :cs find d =expand("") + nmenu &Cscope.Find.Assignmentt + \ :cs find t =expand("") + nmenu &Cscope.Find.Egrepe + \ :cs find e =expand("") + nmenu &Cscope.Find.Filef + \ :cs find f =expand("") + nmenu &Cscope.Find.Includingi + \ :cs find i =expand("") +" nmenu &Cscope.Add :cs add +" nmenu &Cscope.Remove :cs kill + nmenu &Cscope.Reset :cs reset + nmenu &Cscope.Show :cs show + " Need to figure out how to do the add/remove. May end up writing + " some container functions. Or tossing them out, since this is supposed + " to all be automatic. + endif + else + let s:menus_loaded = 0 + set nocst + silent! unmap s + silent! unmap g + silent! unmap c + silent! unmap d + silent! unmap t + silent! unmap e + silent! unmap f + silent! unmap i + if has("menu") " would rather see if the menu exists, then remove... + silent! nunmenu Cscope + endif + endif +endfunc +" +"== +" Unload_csdb +" drop Cscope connections. +function s:Unload_csdb() + if exists("b:csdbpath") + if cscope_connection(3, "out", b:csdbpath) + let save_csvb = &csverb + set nocsverb + exe "cs kill " . b:csdbpath + set csverb + let &csverb = save_csvb + endif + endif +endfunc +" +"== +" Cycle_csdb +" cycle the loaded Cscope db. +function s:Cycle_csdb() + if exists("b:csdbpath") + if cscope_connection(3, "out", b:csdbpath) + return + "it is already loaded. don't try to reload it. + endif + endif + let newcsdbpath = s:Find_in_parent("cscope.out",s:windowdir(),$HOME) +" echo "Found cscope.out at: " . newcsdbpath +" echo "Windowdir: " . s:windowdir() + if newcsdbpath != "Nothing" + let b:csdbpath = newcsdbpath + if !cscope_connection(3, "out", b:csdbpath) + let save_csvb = &csverb + set nocsverb + exe "cs add " . b:csdbpath . "/cscope.out " . b:csdbpath + set csverb + let &csverb = save_csvb + endif + " + else " No Cscope database, undo things. (someone rm-ed it or ...?) + call s:Unload_csdb() + endif +endfunc + +" If enabled, auto update your cscope/gtags database and reset the Cscope +" connection when a file is saved. +function s:Update_csdb() + if g:autocscope_auto_update != 1 + return + endif + if exists("b:csdbpath") + if cscope_connection(3, g:autocscope_tagfile_name, b:csdbpath) + if g:autocscope_use_gtags == 1 + exe "silent !cd " . b:csdbpath . " && global -u" + " The cscope_db_gen script allows source files other than the + " Cscope defaults to be examined by Cscope (C++ files etc.). When + " called with the -q "quick" flag, cscope_db_gen uses the existing + " cscope.files list of files. So if new files are created, + " cscope_db_gen without flags must be executed in the repository's + " base directory. + elseif g:autocscope_use_cscope_db_gen == 1 + exe "silent !cd " . b:csdbpath . " && cscope_db_gen -q" + " Cscope only examines C (.c & .h), lex (.l), and yacc (.y) files. + else + exe "silent !cd " . b:csdbpath . " && cscope -Rbq" + endif + set nocsverb + exe "cs reset" + set csverb + endif + endif +endfunc + +if g:autocscope_use_gtags == 1 + let g:autocscope_tagfile_name = "GTAGS" + set cscopeprg=gtags-cscope +else + let g:autocscope_tagfile_name = "cscope.out" + set cscopeprg=cscope +endif + +" By default, Cscope examines C (.c & .h), lex (.l), and yacc (.y) source files. +" Additions made for C++ source files (.cc, .cpp, .hpp). +" Additions made for Java source files (.java). +" auto toggle the menu +augroup autoload_cscope + au! + au BufEnter *.[chly] call Cycle_csdb() | call Cycle_macros_menus() + au BufEnter *.cc call Cycle_csdb() | call Cycle_macros_menus() + au BufEnter *.[ch]pp call Cycle_csdb() | call Cycle_macros_menus() + au BufEnter *.java call Cycle_csdb() | call Cycle_macros_menus() + au BufEnter *.py call Cycle_csdb() | call Cycle_macros_menus() + au BufEnter *.go call Cycle_csdb() | call Cycle_macros_menus() +" Line continuation. See :help line-continuation + au BufWritePost *.[chly] call Update_csdb() | call + \ Cycle_macros_menus() + au BufWritePost *.cc call Update_csdb() | call + \ Cycle_macros_menus() + au BufWritePost *.[ch]pp call Update_csdb() | call + \ Cycle_macros_menus() + au BufWritePost *.java call Update_csdb() | call + \ Cycle_macros_menus() + au BufWritePost *.py call Update_csdb() | call + \ Cycle_macros_menus() + au BufWritePost *.go call Update_csdb() | call + \ Cycle_macros_menus() +" + au BufUnload *.[chly] call Unload_csdb() | call Cycle_macros_menus() + au BufUnload *.cc call Unload_csdb() | call Cycle_macros_menus() + au BufUnload *.[ch]pp call Unload_csdb() | call Cycle_macros_menus() + au BufUnload *.java call Unload_csdb() | call Cycle_macros_menus() + au BufUnload *.py call Unload_csdb() | call Cycle_macros_menus() + au BufUnload *.go call Unload_csdb() | call Cycle_macros_menus() +augroup END + +let &cpo = s:save_cpo