" Vimball Archiver by Charles E. Campbell, Jr., Ph.D. UseVimball finish doc/trag.txt [[[1 1538 *trag.txt* A language-aware file scanner Author: Tom Link, micathom at gmail com This plugin uses ad-hoc searches to find strings in files. For certain languages, it can also find variable/function/class definitions, function calls etc. Other than |tags| or |cscope|, it doesn't build a database to speed up searches but always scans all files. It can make use of external tools like `git grep`, `ack`, or `ag` though, in order to gain acceptable performance for medium-sized projects. The builtin vimscript-based version file scanner and also |vimgrep| are suitable for small projects. See |g:trag#grep_type| for available options. Usage~ First, define which files belong to your project. See |g:trag#file_sources| for available sources. If the variable contains "vcs" and the current buffer is under control of a supported VCS, trag will scan the files in the VCS. Maybe your project's source files are already registered in your tags files, in which case those will be used. Secondly, use |:Trag| or |:Traggrep| to scan your project's files. You can restrict searches to certain "kinds" like only variable definitions or only function calls. See |trag-kinds| for details. You can also type r# to search for the word under cursor (see |g:trag_map_leader| and |TragInstallMap()| for details on maps). In supported filetypes, rd will search for the definition of the word under cursor. Currently the following filetypes are supported: - java - javascript - json - make - r - ruby - viki - vim Run `:echo globpath(&rtp, 'ftplugin/*/trag.vim')` to get a full listing of supported filetypes. NOTE: Some kinds are available only for a subset of known filetypes. ----------------------------------------------------------------------- Install~ Edit the vba file and type: > :so % See :help vimball for details. If you have difficulties or use vim 7.0, please make sure, you have the current version of vimball (vimscript #1502) installed. This script requires tlib (vimscript #1863) to be installed. ----------------------------------------------------------------------- *trag-kinds* Kinds~ Certain commands take a "kind" as argument. A "kind" in the context of trag means a way how the expression is interpreted and (in the future) how the lines are scanned. The meaning of the letter is specific for a certain filetype. In general, the following list should serve as a common base: c ... class definitions d ... function/method definitions f ... function calls i ... ignored lines, comments etc. l ... variable definition m ... module definitions r ... variable assignment (e.g. "= WORD") u ... uses of word (ignore comments) w ... find as word x ... subclasses fuzzy ... use a typo-tolerant regexp todo ... TODO markers etc. Modifiers: # ... escape a literal expression as regexp (place it somewhere in the kinds argument) Negation: -, ! ... negate/skip uninteresting lines. Positive (must match) and negative (must not match) patterns are joined with "-" or "!". Positive and negative conditions must both be satisfied. The positive regexp determines the speed of the operation. I.e. trag first searches for matching lines and only then decides whether to skip "bad" ones. POSITIVE1,POSITIVE2a.POSITIVE2b...-NEGATIVE... Note: If you use negations, you should also give a positive kind (use . as fallback). The use of negations causes trag to use it's own grep procedure which is slightly slower than the standard vimgrep command. EXPERIMENTAL: Kinds can be joined as comma-separated list (OR) of period-seprated list (CONTAIN). This may be unintuitive but that's the way it is. Order in CONTAIN-patterns matters, i.e. w.i doesn't make too much sense (a word that CONTAINs a comment, which could only be the word itself) but i.w does (a comment that CONTAINs a word, which is quite possible). The way this has done has changed from version 0.1 to 0.2 with the effect that the current solution is less well tested. If you stumble over wrong search result, please tell me about the problem. Most likely it's a problem with the regexp not being properly updated. Example: i ... comment/ignored text that CONTAINs a word i.w ... comment/ignored text that CONTAINs a word l,r ... a word either on the left OR right hand side of an assignment w-i ... word that is NOT contained in a comment w-i,l,r ... word but NOT in assignments (left OR right hand) OR in comments More examples: File contents: > #1 function Foo() {} #2 function FooBar() {} #3 let x = FooBar() #4 let x = Foo() < :TRag * Foo => Find "Foo": 1-4 :TRag w Foo => Find the __w__ords "Foo": 1, 4 :TRag d Foo => Find __d__efinitions of "Foo": 1, 2 :TRag d.w Foo => Find __d__efinitions of the __w__ord "Foo": 1 :TRag f Foo => Find (__f__unction) calls of "Foo": 3, 4 :TRag f.w Foo => Find (__f__unction) calls of the __w__ord "Foo": 4 Not every kind is defined for every filetype. Currenty, support for the following filetype(s) is somewhat above average: - ruby - vim Note: I'd appreciate if you sent me sophisticated kind definitions for more filetypes so that I can include them in future releases. A kind is best defined using the |:TRagDefKind| command. If you want to run a command without kinds, use "*" or "." as argument, whatever if more convenient to type on your keyboard. See |trag#Grep()| for details of how to use this. ======================================================================== Contents~ g:trag_map_leader ....................... |g:trag_map_leader| g:trag_extension_filetype ............... |g:trag_extension_filetype| g:trag_kinds_ignored_comments ........... |g:trag_kinds_ignored_comments| :TRagDefKind ............................ |:TRagDefKind| :TRagKeyword ............................ |:TRagKeyword| :TRagDefFiletype ........................ |:TRagDefFiletype| :Trag ................................... |:Trag| :Tragfile ............................... |:Tragfile| :Tragcw ................................. |:Tragcw| :Traglw ................................. |:Traglw| :Tragsearch ............................. |:Tragsearch| :Traggrep ............................... |:Traggrep| :Tragsetfiles ........................... |:Tragsetfiles| :Tragaddfiles ........................... |:Tragaddfiles| :Tragclearfiles ......................... |:Tragclearfiles| :TragGitFiles ........................... |:TragGitFiles| :TragRepoFiles .......................... |:TragRepoFiles| TragInstallMap .......................... |TragInstallMap()| TragInstallKindMap ...................... |TragInstallKindMap()| g:trag#grep_type ........................ |g:trag#grep_type| g:trag_get_files ........................ |g:trag_get_files| g:trag_get_files_java ................... |g:trag_get_files_java| g:trag_get_files_c ...................... |g:trag_get_files_c| g:trag_get_files_cpp .................... |g:trag_get_files_cpp| g:trag#file_sources ..................... |g:trag#file_sources| g:trag#use_buffer ....................... |g:trag#use_buffer| g:trag#check_vcs ........................ |g:trag#check_vcs| trag#HasFiletype ........................ |trag#HasFiletype()| trag#SetFiletype ........................ |trag#SetFiletype()| trag#GetFiletype ........................ |trag#GetFiletype()| g:trag_files ............................ |g:trag_files| g:trag_glob ............................. |g:trag_glob| g:trag_project_ruby ..................... |g:trag_project_ruby| g:trag_project .......................... |g:trag_project| g:trag_git .............................. |g:trag_git| trag#InitListBuffer ..................... |trag#InitListBuffer()| trag#Balloon ............................ |trag#Balloon()| trag#ClearFiles ......................... |trag#ClearFiles()| trag#AddFiles ........................... |trag#AddFiles()| trag#GetProjectFiles .................... |trag#GetProjectFiles()| trag#GetGitFiles ........................ |trag#GetGitFiles()| trag#SetRepoFiles ....................... |trag#SetRepoFiles()| trag#SetGitFiles ........................ |trag#SetGitFiles()| trag#SetFiles ........................... |trag#SetFiles()| trag#FindGitRepos ....................... |trag#FindGitRepos()| trag#Edit ............................... |trag#Edit()| trag#Grep ............................... |trag#Grep()| trag#ClearCachedRx ...................... |trag#ClearCachedRx()| trag#QuickList .......................... |trag#QuickList()| trag#QuickListMaybe ..................... |trag#QuickListMaybe()| trag#BrowseList ......................... |trag#BrowseList()| trag#LocList ............................ |trag#LocList()| trag#AgentEditQFE ....................... |trag#AgentEditQFE()| trag#AgentPreviewQFE .................... |trag#AgentPreviewQFE()| trag#AgentGotoQFE ....................... |trag#AgentGotoQFE()| trag#AgentWithSelected .................. |trag#AgentWithSelected()| trag#RunCmdOnSelected ................... |trag#RunCmdOnSelected()| trag#AgentSplitBuffer ................... |trag#AgentSplitBuffer()| trag#AgentTabBuffer ..................... |trag#AgentTabBuffer()| trag#AgentVSplitBuffer .................. |trag#AgentVSplitBuffer()| trag#AgentEditLine ...................... |trag#AgentEditLine()| trag#EditLine ........................... |trag#EditLine()| trag#AgentRefactor ...................... |trag#AgentRefactor()| trag#CWord .............................. |trag#CWord()| trag#RefactorRename ..................... |trag#RefactorRename()| trag#SetFollowCursor .................... |trag#SetFollowCursor()| trag#IsSupported ........................ |trag#IsSupported()| trag#general#Rename ..................... |trag#general#Rename()| trag#viki#Rename ........................ |trag#viki#Rename()| trag#rename#Rename ...................... |trag#rename#Rename()| g:trag#external#ack#opts ................ |g:trag#external#ack#opts| g:trag#external#ack#supported_kinds ..... |g:trag#external#ack#supported_kinds| trag#external#ack#IsSupported ........... |trag#external#ack#IsSupported()| trag#external#ack#Run ................... |trag#external#ack#Run()| g:trag#external#vcs#options_git ......... |g:trag#external#vcs#options_git| g:trag#external#vcs#supported_kinds ..... |g:trag#external#vcs#supported_kinds| trag#external#vcs#IsSupported ........... |trag#external#vcs#IsSupported()| trag#external#vcs#Run ................... |trag#external#vcs#Run()| trag#external#vcs#ConvertFilename_git ... |trag#external#vcs#ConvertFilename_git()| g:trag#external#ag#opts ................. |g:trag#external#ag#opts| g:trag#external#ag#supported_kinds ...... |g:trag#external#ag#supported_kinds| trag#external#ag#IsSupported ............ |trag#external#ag#IsSupported()| trag#external#ag#Run .................... |trag#external#ag#Run()| g:trag#external#grep#args ............... |g:trag#external#grep#args| g:trag#external#grep#supported_kinds .... |g:trag#external#grep#supported_kinds| trag#external#grep#IsSupported .......... |trag#external#grep#IsSupported()| trag#external#grep#Run .................. |trag#external#grep#Run()| trag#rx#ConvertRx ....................... |trag#rx#ConvertRx()| trag#rx#ConvertRx_git ................... |trag#rx#ConvertRx_git()| trag#rx#ConvertRx_perl .................. |trag#rx#ConvertRx_perl()| g:trag#utils#cmdline_max ................ |g:trag#utils#cmdline_max| trag#utils#GrepaddFiles ................. |trag#utils#GrepaddFiles()| trag#java#Rename ........................ |trag#java#Rename()| g:trag#grep_type ........................ |g:trag#grep_type| g:trag_get_files ........................ |g:trag_get_files| g:trag_get_files_java ................... |g:trag_get_files_java| g:trag_get_files_c ...................... |g:trag_get_files_c| g:trag_get_files_cpp .................... |g:trag_get_files_cpp| g:trag#file_sources ..................... |g:trag#file_sources| g:trag#use_buffer ....................... |g:trag#use_buffer| g:trag#check_vcs ........................ |g:trag#check_vcs| trag#HasFiletype ........................ |trag#HasFiletype()| trag#SetFiletype ........................ |trag#SetFiletype()| trag#GetFiletype ........................ |trag#GetFiletype()| g:trag_files ............................ |g:trag_files| g:trag_glob ............................. |g:trag_glob| g:trag_project_ruby ..................... |g:trag_project_ruby| g:trag_project .......................... |g:trag_project| g:trag_git .............................. |g:trag_git| trag#InitListBuffer ..................... |trag#InitListBuffer()| trag#Balloon ............................ |trag#Balloon()| trag#ClearFiles ......................... |trag#ClearFiles()| trag#AddFiles ........................... |trag#AddFiles()| trag#GetProjectFiles .................... |trag#GetProjectFiles()| trag#GetGitFiles ........................ |trag#GetGitFiles()| trag#SetRepoFiles ....................... |trag#SetRepoFiles()| trag#SetGitFiles ........................ |trag#SetGitFiles()| trag#SetFiles ........................... |trag#SetFiles()| trag#FindGitRepos ....................... |trag#FindGitRepos()| trag#Edit ............................... |trag#Edit()| trag#Grep ............................... |trag#Grep()| trag#ClearCachedRx ...................... |trag#ClearCachedRx()| trag#QuickList .......................... |trag#QuickList()| trag#QuickListMaybe ..................... |trag#QuickListMaybe()| trag#BrowseList ......................... |trag#BrowseList()| trag#LocList ............................ |trag#LocList()| trag#AgentEditQFE ....................... |trag#AgentEditQFE()| trag#AgentPreviewQFE .................... |trag#AgentPreviewQFE()| trag#AgentGotoQFE ....................... |trag#AgentGotoQFE()| trag#AgentWithSelected .................. |trag#AgentWithSelected()| trag#RunCmdOnSelected ................... |trag#RunCmdOnSelected()| trag#AgentSplitBuffer ................... |trag#AgentSplitBuffer()| trag#AgentTabBuffer ..................... |trag#AgentTabBuffer()| trag#AgentVSplitBuffer .................. |trag#AgentVSplitBuffer()| trag#AgentEditLine ...................... |trag#AgentEditLine()| trag#EditLine ........................... |trag#EditLine()| trag#AgentRefactor ...................... |trag#AgentRefactor()| trag#CWord .............................. |trag#CWord()| trag#RefactorRename ..................... |trag#RefactorRename()| trag#SetFollowCursor .................... |trag#SetFollowCursor()| trag#IsSupported ........................ |trag#IsSupported()| ======================================================================== plugin/trag.vim~ *g:trag_map_leader* g:trag_map_leader (default: 'r') Trag map leader. See also |TragInstallMap()|. *g:trag_extension_filetype* g:trag_extension_filetype (default: {}) A dictionary FILENAME_EXTENSION => FILETYPE On systems without has('fname_case') (see |feature-list|), FILENAME_EXTENSION should be a lower-case string. *g:trag_kinds_ignored_comments* g:trag_kinds_ignored_comments (default: ['c', 'd', 'f', 'l', 'r', 'u']) A list of kinds for which |TragInstallKindMap()| will install maps that ignore comments. *:TRagDefKind* :TRagDefKind[!] KIND FILETYPE /REGEXP_FORMAT/ The regexp argument is no real regexp but a format string. % thus have to be escaped with % (see |printf()| for details). The REGEXP_FORMAT should contain at least one %s. With the [!], reset the regexp definitions. Examples: > TRagDefKind v * /\C\<%s\>\s*=[^=~<>]/ TRagDefKind v ruby /\C\<%s\>\(\s*,\s*[[:alnum:]_@$]\+\s*\)*\s*=[^=~<>]/ < *:TRagKeyword* TRagKeyword FILETYPE KEYWORD_CHARS Override 'iskeyword' for a certain filetype. See also |trag#CWord()|. *:TRagDefFiletype* TRagDefFiletype FILETYPE EXTENSION ... FILENAME ... In order to recognize files based on their extension, you have to declare filetypes first. If a file has no extension, the whole filename is used. On systems where the case of the filename doesn't matter (check :echo has('fname_case')), EXTENSION should be defined in lower case letters. Examples: > TRagDefFiletype html html htm xhtml < *:Trag* :Trag[!] KIND [REGEXP] Run |:Tragsearch| and instantly display the result with |:Tragcw|. See |trag#Grep()| for help on the arguments. If the kind rx doesn't contain %s (e.g. todo), you can skip the regexp. Examples: > " Find any matches Trag . foo " Find variable definitions (word on the left-hand): foo = 1 Trag l foo " Find variable __or__ function/method definitions Trag d,l foo " Find function calls like: foo(a, b) Trag f foo " Find TODO markers Trag todo < *:Tragfile* :Tragfile Edit a file registered in your tag files. *:Tragcw* :Tragcw Display a quick fix list using |tlib#input#ListD()|. *:Traglw* :Traglw Display a |location-list| using |tlib#input#ListD()|. *:Tragsearch* :Tragsearch[!] KIND REGEXP Scan the files registered in your tag files for REGEXP. Generate a quickfix list. With [!], append to the given list. The quickfix list can be viewed with commands like |:cw| or |:Tragcw|. The REGEXP has to match a single line. This uses |readfile()| and the scans the lines. This is an alternative to |:vimgrep|. If you choose your identifiers wisely, this should guide you well through your sources. See |trag#Grep()| for help on the arguments. *:Traggrep* :Traggrep REGEXP [GLOBPATTERN] A 99%-replacement for grep. The glob pattern is optional. Example: > :Traggrep foo *.vim :Traggrep bar < *:Tragsetfiles* :Tragsetfiles [GLOB PATTERN] The file list is set only once per buffer. If the list of the project files has changed, you have to run this command on order to reset the per-buffer list. If no filelist is given, collect the files in your tags files. Examples: > :Tragsetfiles :Tragsetfiles foo*.txt < *:Tragaddfiles* :Tragaddfiles FILELIST Add more files to the project list. *:Tragclearfiles* :Tragclearfiles Remove any files from the project list. *:TragGitFiles* :TragGitFiles GIT_REPOS *:TragRepoFiles* :TragRepoFiles *TragInstallMap()* TragInstallMap(leader) Install the following maps: # ........ Search word under cursor . ........ :Trag * - ........ :Tragfile The following maps might be defined only after the first invocation: ... Search word under cursor of KIND See |g:trag_kinds| E.g. d searches for the definition of the word under cursor. *TragInstallKindMap()* TragInstallKindMap(leader, kind) ======================================================================== autoload/trag.vim~ *g:trag#grep_type* g:trag#grep_type (default: 'trag') A comma-separated list of preferred grep programs: - trag - vimgrep - vcs (use the VCS's grep function; see |trag#external#vcs#Run()|, this option always searches all files in the VCS); for a list of supported VCSs see |trag#external#vcs#Run()| - external:CMD (CMD defaults to grep; use vimgrep as fallback) - ack - ag - grep (uses 'grepprg') The first valid option is used. E.g. if the value is "vcs,trag" and if the buffer belongs to a supported VCS (see |trag#external#vcs#Run()|, the VCS's grep function is used. Otherwise trag's own version of grep is used. trag & vimgrep should work everywhere. *b:trag_grep_type* b:trag_grep_type overrides this global variable. *g:trag_get_files* g:trag_get_files (default: 'split(glob("*"), "\n")') If no project files are defined, evaluate this expression as fallback-strategy. *g:trag_get_files_java* g:trag_get_files_java (default: 'split(glob("**/*.java"), "\n")') *g:trag_get_files_c* g:trag_get_files_c (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag_get_files_cpp* g:trag_get_files_cpp (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag#file_sources* g:trag#file_sources (default: ['vcs', 'project', 'files', 'glob', 'tags']) A list of sources. Possible values: vcs ....... Use g:trag#check_vcs git ....... Use b:trag_git or g:trag_git tags ...... Use files listed in 'tags' files ..... Use b:trag_files or g:trag_files glob ...... Use b:trag_glob or g:trag_glob project ... Use b:trag_project_{'filetype'} or g:trag_project_{'filetype'} *b:trag_file_sources* b:trag_file_sources overrides this global variable. *g:trag#use_buffer* g:trag#use_buffer (default: 1) If true, use an already loaded buffer instead of the file on disk in certain situations. This implies that if a buffer is dirty, the non-saved version in memory will be preferred over the version on disk. *g:trag#check_vcs* g:trag#check_vcs (default: 1) If true, try to detect whether the current file is under an VCS and use that later on. *trag#HasFiletype()* trag#HasFiletype(name) Return true, if a filetype for "name" (an extension or a filename) is defined. *trag#SetFiletype()* trag#SetFiletype(filetype, name) Define that filenames ("name" can be either an extension or a filename) are of a certain filetype. *trag#GetFiletype()* trag#GetFiletype(name) Get the filetype for "name" (either an extension of a filename). The following variables provide alternatives to collecting your project's file list on the basis of you tags files. These variables are tested in the order as listed here. If the value of a variable is non-empty, this one will be used instead of the other methods. The tags file is used as a last ressort. *g:trag_files* g:trag_files (default: []) 1. A list of files. Can be buffer local. *g:trag_glob* g:trag_glob (default: '') 2. A glob pattern -- this should be an absolute path and may contain ** (see |glob()| and |wildcards|). Can be buffer local. *g:trag_project_ruby* g:trag_project_ruby (default: 'Manifest.txt') 3. Filetype-specific project files. *g:trag_project* g:trag_project (default: '') 4. The name of a file containing the projects file list. This file could be generated via make. Can be buffer local. *g:trag_git* g:trag_git (default: '') 5. The name of a git repository that includes all files of interest. If the value is "*", trag will search from the current directory (|getcwd()|) upwards for a .git directory. If the value is "finddir", use |finddir()| to find a .git directory. Can be buffer local. *trag#InitListBuffer()* trag#InitListBuffer() *trag#Balloon()* trag#Balloon() *trag#ClearFiles()* trag#ClearFiles() *trag#AddFiles()* trag#AddFiles(files) *trag#GetProjectFiles()* trag#GetProjectFiles(manifest) *trag#GetGitFiles()* trag#GetGitFiles(repos) *trag#SetRepoFiles()* trag#SetRepoFiles() Set the files list to the files in the current VCS repository. *trag#SetGitFiles()* trag#SetGitFiles(repos) Set the files list from the files included in a given git repository. *trag#SetFiles()* trag#SetFiles(?files=[]) *trag#FindGitRepos()* trag#FindGitRepos() *trag#Edit()* trag#Edit() Edit a file from the project catalog. See |g:trag_project| and |:TRagfile|. *trag#Grep()* trag#Grep(args, ?replace=1, ?files=[], ?filetype='') args: A string with the format: KIND REGEXP KIND1,KIND2 REGEXP If the variables [bg]:trag_rxf_{kind}_{&filetype} or [bg]:trag_rxf_{kind} exist, these will be taken as format string (see |printf()|) to format REGEXP. EXAMPLE: trag#Grep('v foo') will find by default take g:trag_rxf_v and find lines that looks like "\\s*=[^=~]", which most likely is a variable definition in many programming languages. I.e. it will find lines like: > foo = 1 < but not: > def foo(bar) call foo(bar) if foo == 1 < *trag#ClearCachedRx()* trag#ClearCachedRx() *trag#QuickList()* trag#QuickList(?world={}, ?suspended=0) Display the |quickfix| list with |tlib#input#ListW()|. *trag#QuickListMaybe()* trag#QuickListMaybe(anyway) *trag#BrowseList()* trag#BrowseList(world_dict, list, ...) *trag#LocList()* trag#LocList(...) Display the |location-list| with |tlib#input#ListW()|. *trag#AgentEditQFE()* trag#AgentEditQFE(world, selected, ...) *trag#AgentPreviewQFE()* trag#AgentPreviewQFE(world, selected) *trag#AgentGotoQFE()* trag#AgentGotoQFE(world, selected) *trag#AgentWithSelected()* trag#AgentWithSelected(world, selected, ...) *trag#RunCmdOnSelected()* trag#RunCmdOnSelected(world, selected, cmd, ...) *trag#AgentSplitBuffer()* trag#AgentSplitBuffer(world, selected) *trag#AgentTabBuffer()* trag#AgentTabBuffer(world, selected) *trag#AgentVSplitBuffer()* trag#AgentVSplitBuffer(world, selected) *trag#AgentEditLine()* trag#AgentEditLine(world, selected) *trag#EditLine()* trag#EditLine(lnum) *trag#AgentRefactor()* trag#AgentRefactor(world, selected) Invoke an refactor command. Currently only one command is supported: rename *trag#CWord()* trag#CWord() *trag#RefactorRename()* trag#RefactorRename(world, selected) *trag#SetFollowCursor()* trag#SetFollowCursor(world, selected) *trag#IsSupported()* trag#IsSupported(supported_kinds, kinds) *g:trag#grep_type* g:trag#grep_type (default: 'trag') A comma-separated list of preferred grep programs: - trag - vimgrep - vcs (use the VCS's grep function; see |trag#external#vcs#Run()|, this option always searches all files in the VCS); for a list of supported VCSs see |trag#external#vcs#Run()| - external:CMD (CMD defaults to grep; use vimgrep as fallback) - ack - ag - grep (uses 'grepprg') The first valid option is used. E.g. if the value is "vcs,trag" and if the buffer belongs to a supported VCS (see |trag#external#vcs#Run()|, the VCS's grep function is used. Otherwise trag's own version of grep is used. trag & vimgrep should work everywhere. *b:trag_grep_type* b:trag_grep_type overrides this global variable. *g:trag_get_files* g:trag_get_files (default: 'split(glob("*"), "\n")') If no project files are defined, evaluate this expression as fallback-strategy. *g:trag_get_files_java* g:trag_get_files_java (default: 'split(glob("**/*.java"), "\n")') *g:trag_get_files_c* g:trag_get_files_c (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag_get_files_cpp* g:trag_get_files_cpp (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag#file_sources* g:trag#file_sources (default: ['vcs', 'project', 'files', 'glob', 'tags']) A list of sources. Possible values: vcs ....... Use g:trag#check_vcs git ....... Use b:trag_git or g:trag_git tags ...... Use files listed in 'tags' files ..... Use b:trag_files or g:trag_files glob ...... Use b:trag_glob or g:trag_glob project ... Use b:trag_project_{'filetype'} or g:trag_project_{'filetype'} *b:trag_file_sources* b:trag_file_sources overrides this global variable. *g:trag#use_buffer* g:trag#use_buffer (default: 1) If true, use an already loaded buffer instead of the file on disk in certain situations. This implies that if a buffer is dirty, the non-saved version in memory will be preferred over the version on disk. *g:trag#check_vcs* g:trag#check_vcs (default: 1) If true, try to detect whether the current file is under an VCS and use that later on. *trag#HasFiletype()* trag#HasFiletype(name) Return true, if a filetype for "name" (an extension or a filename) is defined. *trag#SetFiletype()* trag#SetFiletype(filetype, name) Define that filenames ("name" can be either an extension or a filename) are of a certain filetype. *trag#GetFiletype()* trag#GetFiletype(name) Get the filetype for "name" (either an extension of a filename). The following variables provide alternatives to collecting your project's file list on the basis of you tags files. These variables are tested in the order as listed here. If the value of a variable is non-empty, this one will be used instead of the other methods. The tags file is used as a last ressort. *g:trag_files* g:trag_files (default: []) 1. A list of files. Can be buffer local. *g:trag_glob* g:trag_glob (default: '') 2. A glob pattern -- this should be an absolute path and may contain ** (see |glob()| and |wildcards|). Can be buffer local. *g:trag_project_ruby* g:trag_project_ruby (default: 'Manifest.txt') 3. Filetype-specific project files. *g:trag_project* g:trag_project (default: '') 4. The name of a file containing the projects file list. This file could be generated via make. Can be buffer local. *g:trag_git* g:trag_git (default: '') 5. The name of a git repository that includes all files of interest. If the value is "*", trag will search from the current directory (|getcwd()|) upwards for a .git directory. If the value is "finddir", use |finddir()| to find a .git directory. Can be buffer local. *trag#InitListBuffer()* trag#InitListBuffer() *trag#Balloon()* trag#Balloon() *trag#ClearFiles()* trag#ClearFiles() *trag#AddFiles()* trag#AddFiles(files) *trag#GetProjectFiles()* trag#GetProjectFiles(manifest) *trag#GetGitFiles()* trag#GetGitFiles(repos) *trag#SetRepoFiles()* trag#SetRepoFiles() Set the files list to the files in the current VCS repository. *trag#SetGitFiles()* trag#SetGitFiles(repos) Set the files list from the files included in a given git repository. *trag#SetFiles()* trag#SetFiles(?files=[]) *trag#FindGitRepos()* trag#FindGitRepos() *trag#Edit()* trag#Edit() Edit a file from the project catalog. See |g:trag_project| and |:TRagfile|. *trag#Grep()* trag#Grep(args, ?replace=1, ?files=[], ?filetype='') args: A string with the format: KIND REGEXP KIND1,KIND2 REGEXP If the variables [bg]:trag_rxf_{kind}_{&filetype} or [bg]:trag_rxf_{kind} exist, these will be taken as format string (see |printf()|) to format REGEXP. EXAMPLE: trag#Grep('v foo') will find by default take g:trag_rxf_v and find lines that looks like "\\s*=[^=~]", which most likely is a variable definition in many programming languages. I.e. it will find lines like: > foo = 1 < but not: > def foo(bar) call foo(bar) if foo == 1 < *trag#ClearCachedRx()* trag#ClearCachedRx() *trag#QuickList()* trag#QuickList(?world={}, ?suspended=0) Display the |quickfix| list with |tlib#input#ListW()|. *trag#QuickListMaybe()* trag#QuickListMaybe(anyway) *trag#BrowseList()* trag#BrowseList(world_dict, list, ...) *trag#LocList()* trag#LocList(...) Display the |location-list| with |tlib#input#ListW()|. *trag#AgentEditQFE()* trag#AgentEditQFE(world, selected, ...) *trag#AgentPreviewQFE()* trag#AgentPreviewQFE(world, selected) *trag#AgentGotoQFE()* trag#AgentGotoQFE(world, selected) *trag#AgentWithSelected()* trag#AgentWithSelected(world, selected, ...) *trag#RunCmdOnSelected()* trag#RunCmdOnSelected(world, selected, cmd, ...) *trag#AgentSplitBuffer()* trag#AgentSplitBuffer(world, selected) *trag#AgentTabBuffer()* trag#AgentTabBuffer(world, selected) *trag#AgentVSplitBuffer()* trag#AgentVSplitBuffer(world, selected) *trag#AgentEditLine()* trag#AgentEditLine(world, selected) *trag#EditLine()* trag#EditLine(lnum) *trag#AgentRefactor()* trag#AgentRefactor(world, selected) Invoke an refactor command. Currently only one command is supported: rename *trag#CWord()* trag#CWord() *trag#RefactorRename()* trag#RefactorRename(world, selected) *trag#SetFollowCursor()* trag#SetFollowCursor(world, selected) *trag#IsSupported()* trag#IsSupported(supported_kinds, kinds) ======================================================================== autoload/trag/general.vim~ *trag#general#Rename()* trag#general#Rename(world, selected, rx, subst) ======================================================================== autoload/trag/viki.vim~ *trag#viki#Rename()* trag#viki#Rename(world, selected, from, to) ======================================================================== autoload/trag/rename.vim~ *trag#rename#Rename()* trag#rename#Rename(world, selected, from, to, suffix) ======================================================================== autoload/trag/external/ack.vim~ *g:trag#external#ack#opts* g:trag#external#ack#opts (default: {'grepprg': 'ack', 'args': '-Hns --nocolor --nogroup %s --'}) *g:trag#external#ack#supported_kinds* g:trag#external#ack#supported_kinds (default: ['identity', 'w', 'todo']) *trag#external#ack#IsSupported()* trag#external#ack#IsSupported(kinds) *trag#external#ack#Run()* trag#external#ack#Run(rx, files) ======================================================================== autoload/trag/external/vcs.vim~ *g:trag#external#vcs#options_git* g:trag#external#vcs#options_git (default: {'args': 'grep -Hn -G %s --'}) *g:trag#external#vcs#supported_kinds* g:trag#external#vcs#supported_kinds (default: ['identity', 'w', 'todo']) *trag#external#vcs#IsSupported()* trag#external#vcs#IsSupported(kinds) *trag#external#vcs#Run()* trag#external#vcs#Run(rx, files) Currently only git is supported. For other VCSs, I'd recommend to use "ag". *trag#external#vcs#ConvertFilename_git()* trag#external#vcs#ConvertFilename_git(type, filename) ======================================================================== autoload/trag/external/ag.vim~ *g:trag#external#ag#opts* g:trag#external#ag#opts (default: {'grepprg': 'ag', 'args': '-U -f --line-numbers --nogroup --nocolor -- %s'}) *g:trag#external#ag#supported_kinds* g:trag#external#ag#supported_kinds (default: ['identity', 'w', 'todo']) *trag#external#ag#IsSupported()* trag#external#ag#IsSupported(kinds) *trag#external#ag#Run()* trag#external#ag#Run(rx, files) ======================================================================== autoload/trag/external/grep.vim~ *g:trag#external#grep#args* g:trag#external#grep#args (default: '-Hn -E %s --') *g:trag#external#grep#supported_kinds* g:trag#external#grep#supported_kinds (default: ['identity', 'w', 'todo']) *trag#external#grep#IsSupported()* trag#external#grep#IsSupported(kinds) *trag#external#grep#Run()* trag#external#grep#Run(rx, files, ...) ======================================================================== autoload/trag/rx.vim~ *trag#rx#ConvertRx()* trag#rx#ConvertRx(rx, type, ...) *trag#rx#ConvertRx_git()* trag#rx#ConvertRx_git(type, rx) *trag#rx#ConvertRx_perl()* trag#rx#ConvertRx_perl(type, rx) ======================================================================== autoload/trag/utils.vim~ *g:trag#utils#cmdline_max* g:trag#utils#cmdline_max (default: g:tlib#sys#windows ? 7000 : 2000000) *trag#utils#GrepaddFiles()* trag#utils#GrepaddFiles(args, files) ======================================================================== autoload/trag/java.vim~ *trag#java#Rename()* trag#java#Rename(world, selected, from, to) ======================================================================== autoload/trag.vim~ *g:trag#grep_type* g:trag#grep_type (default: 'trag') A comma-separated list of preferred grep programs: - trag - vimgrep - vcs (use the VCS's grep function; see |trag#external#vcs#Run()|, this option always searches all files in the VCS); for a list of supported VCSs see |trag#external#vcs#Run()| - external:CMD (CMD defaults to grep; use vimgrep as fallback) - ack - ag - grep (uses 'grepprg') The first valid option is used. E.g. if the value is "vcs,trag" and if the buffer belongs to a supported VCS (see |trag#external#vcs#Run()|, the VCS's grep function is used. Otherwise trag's own version of grep is used. trag & vimgrep should work everywhere. *b:trag_grep_type* b:trag_grep_type overrides this global variable. *g:trag_get_files* g:trag_get_files (default: 'split(glob("*"), "\n")') If no project files are defined, evaluate this expression as fallback-strategy. *g:trag_get_files_java* g:trag_get_files_java (default: 'split(glob("**/*.java"), "\n")') *g:trag_get_files_c* g:trag_get_files_c (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag_get_files_cpp* g:trag_get_files_cpp (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag#file_sources* g:trag#file_sources (default: ['vcs', 'project', 'files', 'glob', 'tags']) A list of sources. Possible values: vcs ....... Use g:trag#check_vcs git ....... Use b:trag_git or g:trag_git tags ...... Use files listed in 'tags' files ..... Use b:trag_files or g:trag_files glob ...... Use b:trag_glob or g:trag_glob project ... Use b:trag_project_{'filetype'} or g:trag_project_{'filetype'} *b:trag_file_sources* b:trag_file_sources overrides this global variable. *g:trag#use_buffer* g:trag#use_buffer (default: 1) If true, use an already loaded buffer instead of the file on disk in certain situations. This implies that if a buffer is dirty, the non-saved version in memory will be preferred over the version on disk. *g:trag#check_vcs* g:trag#check_vcs (default: 1) If true, try to detect whether the current file is under an VCS and use that later on. *trag#HasFiletype()* trag#HasFiletype(name) Return true, if a filetype for "name" (an extension or a filename) is defined. *trag#SetFiletype()* trag#SetFiletype(filetype, name) Define that filenames ("name" can be either an extension or a filename) are of a certain filetype. *trag#GetFiletype()* trag#GetFiletype(name) Get the filetype for "name" (either an extension of a filename). The following variables provide alternatives to collecting your project's file list on the basis of you tags files. These variables are tested in the order as listed here. If the value of a variable is non-empty, this one will be used instead of the other methods. The tags file is used as a last ressort. *g:trag_files* g:trag_files (default: []) 1. A list of files. Can be buffer local. *g:trag_glob* g:trag_glob (default: '') 2. A glob pattern -- this should be an absolute path and may contain ** (see |glob()| and |wildcards|). Can be buffer local. *g:trag_project_ruby* g:trag_project_ruby (default: 'Manifest.txt') 3. Filetype-specific project files. *g:trag_project* g:trag_project (default: '') 4. The name of a file containing the projects file list. This file could be generated via make. Can be buffer local. *g:trag_git* g:trag_git (default: '') 5. The name of a git repository that includes all files of interest. If the value is "*", trag will search from the current directory (|getcwd()|) upwards for a .git directory. If the value is "finddir", use |finddir()| to find a .git directory. Can be buffer local. *trag#InitListBuffer()* trag#InitListBuffer() *trag#Balloon()* trag#Balloon() *trag#ClearFiles()* trag#ClearFiles() *trag#AddFiles()* trag#AddFiles(files) *trag#GetProjectFiles()* trag#GetProjectFiles(manifest) *trag#GetGitFiles()* trag#GetGitFiles(repos) *trag#SetRepoFiles()* trag#SetRepoFiles() Set the files list to the files in the current VCS repository. *trag#SetGitFiles()* trag#SetGitFiles(repos) Set the files list from the files included in a given git repository. *trag#SetFiles()* trag#SetFiles(?files=[]) *trag#FindGitRepos()* trag#FindGitRepos() *trag#Edit()* trag#Edit() Edit a file from the project catalog. See |g:trag_project| and |:TRagfile|. *trag#Grep()* trag#Grep(args, ?replace=1, ?files=[], ?filetype='') args: A string with the format: KIND REGEXP KIND1,KIND2 REGEXP If the variables [bg]:trag_rxf_{kind}_{&filetype} or [bg]:trag_rxf_{kind} exist, these will be taken as format string (see |printf()|) to format REGEXP. EXAMPLE: trag#Grep('v foo') will find by default take g:trag_rxf_v and find lines that looks like "\\s*=[^=~]", which most likely is a variable definition in many programming languages. I.e. it will find lines like: > foo = 1 < but not: > def foo(bar) call foo(bar) if foo == 1 < *trag#ClearCachedRx()* trag#ClearCachedRx() *trag#QuickList()* trag#QuickList(?world={}, ?suspended=0) Display the |quickfix| list with |tlib#input#ListW()|. *trag#QuickListMaybe()* trag#QuickListMaybe(anyway) *trag#BrowseList()* trag#BrowseList(world_dict, list, ...) *trag#LocList()* trag#LocList(...) Display the |location-list| with |tlib#input#ListW()|. *trag#AgentEditQFE()* trag#AgentEditQFE(world, selected, ...) *trag#AgentPreviewQFE()* trag#AgentPreviewQFE(world, selected) *trag#AgentGotoQFE()* trag#AgentGotoQFE(world, selected) *trag#AgentWithSelected()* trag#AgentWithSelected(world, selected, ...) *trag#RunCmdOnSelected()* trag#RunCmdOnSelected(world, selected, cmd, ...) *trag#AgentSplitBuffer()* trag#AgentSplitBuffer(world, selected) *trag#AgentTabBuffer()* trag#AgentTabBuffer(world, selected) *trag#AgentVSplitBuffer()* trag#AgentVSplitBuffer(world, selected) *trag#AgentEditLine()* trag#AgentEditLine(world, selected) *trag#EditLine()* trag#EditLine(lnum) *trag#AgentRefactor()* trag#AgentRefactor(world, selected) Invoke an refactor command. Currently only one command is supported: rename *trag#CWord()* trag#CWord() *trag#RefactorRename()* trag#RefactorRename(world, selected) *trag#SetFollowCursor()* trag#SetFollowCursor(world, selected) *trag#IsSupported()* trag#IsSupported(supported_kinds, kinds) *g:trag#grep_type* g:trag#grep_type (default: 'trag') A comma-separated list of preferred grep programs: - trag - vimgrep - vcs (use the VCS's grep function; see |trag#external#vcs#Run()|, this option always searches all files in the VCS); for a list of supported VCSs see |trag#external#vcs#Run()| - external:CMD (CMD defaults to grep; use vimgrep as fallback) - ack - ag - grep (uses 'grepprg') The first valid option is used. E.g. if the value is "vcs,trag" and if the buffer belongs to a supported VCS (see |trag#external#vcs#Run()|, the VCS's grep function is used. Otherwise trag's own version of grep is used. trag & vimgrep should work everywhere. *b:trag_grep_type* b:trag_grep_type overrides this global variable. *g:trag_get_files* g:trag_get_files (default: 'split(glob("*"), "\n")') If no project files are defined, evaluate this expression as fallback-strategy. *g:trag_get_files_java* g:trag_get_files_java (default: 'split(glob("**/*.java"), "\n")') *g:trag_get_files_c* g:trag_get_files_c (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag_get_files_cpp* g:trag_get_files_cpp (default: 'split(glob("**/*.[ch]"), "\n")') *g:trag#file_sources* g:trag#file_sources (default: ['vcs', 'project', 'files', 'glob', 'tags']) A list of sources. Possible values: vcs ....... Use g:trag#check_vcs git ....... Use b:trag_git or g:trag_git tags ...... Use files listed in 'tags' files ..... Use b:trag_files or g:trag_files glob ...... Use b:trag_glob or g:trag_glob project ... Use b:trag_project_{'filetype'} or g:trag_project_{'filetype'} *b:trag_file_sources* b:trag_file_sources overrides this global variable. *g:trag#use_buffer* g:trag#use_buffer (default: 1) If true, use an already loaded buffer instead of the file on disk in certain situations. This implies that if a buffer is dirty, the non-saved version in memory will be preferred over the version on disk. *g:trag#check_vcs* g:trag#check_vcs (default: 1) If true, try to detect whether the current file is under an VCS and use that later on. *trag#HasFiletype()* trag#HasFiletype(name) Return true, if a filetype for "name" (an extension or a filename) is defined. *trag#SetFiletype()* trag#SetFiletype(filetype, name) Define that filenames ("name" can be either an extension or a filename) are of a certain filetype. *trag#GetFiletype()* trag#GetFiletype(name) Get the filetype for "name" (either an extension of a filename). The following variables provide alternatives to collecting your project's file list on the basis of you tags files. These variables are tested in the order as listed here. If the value of a variable is non-empty, this one will be used instead of the other methods. The tags file is used as a last ressort. *g:trag_files* g:trag_files (default: []) 1. A list of files. Can be buffer local. *g:trag_glob* g:trag_glob (default: '') 2. A glob pattern -- this should be an absolute path and may contain ** (see |glob()| and |wildcards|). Can be buffer local. *g:trag_project_ruby* g:trag_project_ruby (default: 'Manifest.txt') 3. Filetype-specific project files. *g:trag_project* g:trag_project (default: '') 4. The name of a file containing the projects file list. This file could be generated via make. Can be buffer local. *g:trag_git* g:trag_git (default: '') 5. The name of a git repository that includes all files of interest. If the value is "*", trag will search from the current directory (|getcwd()|) upwards for a .git directory. If the value is "finddir", use |finddir()| to find a .git directory. Can be buffer local. *trag#InitListBuffer()* trag#InitListBuffer() *trag#Balloon()* trag#Balloon() *trag#ClearFiles()* trag#ClearFiles() *trag#AddFiles()* trag#AddFiles(files) *trag#GetProjectFiles()* trag#GetProjectFiles(manifest) *trag#GetGitFiles()* trag#GetGitFiles(repos) *trag#SetRepoFiles()* trag#SetRepoFiles() Set the files list to the files in the current VCS repository. *trag#SetGitFiles()* trag#SetGitFiles(repos) Set the files list from the files included in a given git repository. *trag#SetFiles()* trag#SetFiles(?files=[]) *trag#FindGitRepos()* trag#FindGitRepos() *trag#Edit()* trag#Edit() Edit a file from the project catalog. See |g:trag_project| and |:TRagfile|. *trag#Grep()* trag#Grep(args, ?replace=1, ?files=[], ?filetype='') args: A string with the format: KIND REGEXP KIND1,KIND2 REGEXP If the variables [bg]:trag_rxf_{kind}_{&filetype} or [bg]:trag_rxf_{kind} exist, these will be taken as format string (see |printf()|) to format REGEXP. EXAMPLE: trag#Grep('v foo') will find by default take g:trag_rxf_v and find lines that looks like "\\s*=[^=~]", which most likely is a variable definition in many programming languages. I.e. it will find lines like: > foo = 1 < but not: > def foo(bar) call foo(bar) if foo == 1 < *trag#ClearCachedRx()* trag#ClearCachedRx() *trag#QuickList()* trag#QuickList(?world={}, ?suspended=0) Display the |quickfix| list with |tlib#input#ListW()|. *trag#QuickListMaybe()* trag#QuickListMaybe(anyway) *trag#BrowseList()* trag#BrowseList(world_dict, list, ...) *trag#LocList()* trag#LocList(...) Display the |location-list| with |tlib#input#ListW()|. *trag#AgentEditQFE()* trag#AgentEditQFE(world, selected, ...) *trag#AgentPreviewQFE()* trag#AgentPreviewQFE(world, selected) *trag#AgentGotoQFE()* trag#AgentGotoQFE(world, selected) *trag#AgentWithSelected()* trag#AgentWithSelected(world, selected, ...) *trag#RunCmdOnSelected()* trag#RunCmdOnSelected(world, selected, cmd, ...) *trag#AgentSplitBuffer()* trag#AgentSplitBuffer(world, selected) *trag#AgentTabBuffer()* trag#AgentTabBuffer(world, selected) *trag#AgentVSplitBuffer()* trag#AgentVSplitBuffer(world, selected) *trag#AgentEditLine()* trag#AgentEditLine(world, selected) *trag#EditLine()* trag#EditLine(lnum) *trag#AgentRefactor()* trag#AgentRefactor(world, selected) Invoke an refactor command. Currently only one command is supported: rename *trag#CWord()* trag#CWord() *trag#RefactorRename()* trag#RefactorRename(world, selected) *trag#SetFollowCursor()* trag#SetFollowCursor(world, selected) *trag#IsSupported()* trag#IsSupported(supported_kinds, kinds) vim:tw=78:fo=w2croql:isk=!-~,^*,^|,^":ts=8:ft=help:norl: plugin/trag.vim [[[1 208 " trag.vim -- Jump to a file registered in your tags " @Author: Tom Link (micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Created: 2007-09-29. " @Last Change: 2014-07-03. " @Revision: 673 " GetLatestVimScripts: 2033 1 trag.vim if &cp || exists("loaded_trag") finish endif if !exists('g:loaded_tlib') || g:loaded_tlib < 111 runtime plugin/02tlib.vim if !exists('g:loaded_tlib') || g:loaded_tlib < 111 echoerr 'tlib >= 0.111 is required' finish endif endif let loaded_trag = 100 let s:save_cpo = &cpo set cpo&vim " :nodoc: TLet g:trag_kinds = {} " :nodoc: TLet g:trag_keyword_chars = {} " Trag map leader. See also |TragInstallMap()|. TLet g:trag_map_leader = 'r' " A dictionary FILENAME_EXTENSION => FILETYPE " On systems without has('fname_case') (see |feature-list|), " FILENAME_EXTENSION should be a lower-case string. TLet g:trag_extension_filetype = {} " A list of kinds for which |TragInstallKindMap()| will install maps that ignore comments. TLet g:trag_kinds_ignored_comments = ['c', 'd', 'f', 'l', 'r', 'u'] " :display: :TRagDefKind[!] KIND FILETYPE /REGEXP_FORMAT/ " The regexp argument is no real regexp but a format string. % thus have " to be escaped with % (see |printf()| for details). The REGEXP_FORMAT " should contain at least one %s. " " With the [!], reset the regexp definitions. " " Examples: > " TRagDefKind v * /\C\<%s\>\s*=[^=~<>]/ " TRagDefKind v ruby /\C\<%s\>\(\s*,\s*[[:alnum:]_@$]\+\s*\)*\s*=[^=~<>]/ command! -bang -nargs=1 TRagDefKind call trag#TRagDefKind(, !empty("")) " :display: TRagKeyword FILETYPE KEYWORD_CHARS " Override 'iskeyword' for a certain filetype. See also |trag#CWord()|. command! -nargs=+ TRagKeyword if len([]) == 2 \ | let g:trag_keyword_chars[[][0]] = [][1] \ | else \ | echoerr 'Expected "FILETYPE KEYWORDRX", but got: ' \ | endif " :display: TRagDefFiletype FILETYPE EXTENSION ... FILENAME ... " In order to recognize files based on their extension, you have to " declare filetypes first. " If a file has no extension, the whole filename is used. " On systems where the case of the filename doesn't matter (check :echo " has('fname_case')), EXTENSION should be defined in lower case letters. " Examples: > " TRagDefFiletype html html htm xhtml command! -nargs=+ TRagDefFiletype call trag#DefFiletype([]) " :display: :Trag[!] KIND [REGEXP] " Run |:Tragsearch| and instantly display the result with |:Tragcw|. " See |trag#Grep()| for help on the arguments. " If the kind rx doesn't contain %s (e.g. todo), you can skip the " regexp. " " Examples: > " " Find any matches " Trag . foo " " " Find variable definitions (word on the left-hand): foo = 1 " Trag l foo " " " Find variable __or__ function/method definitions " Trag d,l foo " " " Find function calls like: foo(a, b) " Trag f foo " " " Find TODO markers " Trag todo command! -nargs=1 -bang -bar Trag Tragsearch | Tragcw " :display: :Tragfile " Edit a file registered in your tag files. command! Tragfile call trag#Edit() " :display: :Tragcw " Display a quick fix list using |tlib#input#ListD()|. command! -bang -nargs=? Tragcw call trag#QuickListMaybe(!empty("")) " :display: :Traglw " Display a |location-list| using |tlib#input#ListD()|. command! -nargs=? Traglw call trag#LocList() " :display: :Tragsearch[!] KIND REGEXP " Scan the files registered in your tag files for REGEXP. Generate a " quickfix list. With [!], append to the given list. The quickfix list " can be viewed with commands like |:cw| or |:Tragcw|. " " The REGEXP has to match a single line. This uses |readfile()| and the " scans the lines. This is an alternative to |:vimgrep|. " If you choose your identifiers wisely, this should guide you well " through your sources. " See |trag#Grep()| for help on the arguments. command! -nargs=1 -bang -bar Tragsearch call trag#Grep(, empty("")) " :display: :Traggrep REGEXP [GLOBPATTERN] " A 99%-replacement for grep. The glob pattern is optional. " " Example: > " :Traggrep foo *.vim " :Traggrep bar command! -nargs=+ -bang -bar -complete=file Traggrep \ let g:trag_grepargs = ['.', ] \ | call trag#Grep(g:trag_grepargs[0] .' '. g:trag_grepargs[1], empty(""), g:trag_grepargs[2:-1]) \ | unlet g:trag_grepargs \ | Tragcw " :display: :Tragsetfiles [GLOB PATTERN] " The file list is set only once per buffer. If the list of the project " files has changed, you have to run this command on order to reset the " per-buffer list. " " If no filelist is given, collect the files in your tags files. " " Examples: > " :Tragsetfiles " :Tragsetfiles foo*.txt command! -nargs=? -bar -complete=file Tragsetfiles call trag#SetFiles() " :display: :Tragaddfiles FILELIST " Add more files to the project list. command! -nargs=1 -bar -complete=file Tragaddfiles call trag#AddFiles() " :display: :Tragclearfiles " Remove any files from the project list. command! Tragclearfiles call trag#ClearFiles() " :display: :TragGitFiles GIT_REPOS command! -nargs=1 -bar -complete=dir TragGitFiles call trag#SetGitFiles() command! -bar TragRepoFiles call trag#SetRepoFiles() " Install the following maps: " " # ........ Search word under cursor " . ........ :Trag * " - ........ :Tragfile " " The following maps might be defined only after the first invocation: " " ... Search word under cursor of KIND " See |g:trag_kinds| " " E.g. d searches for the definition of the word under " cursor. function! TragInstallMap(leader) "{{{3 " TLogVAR a:leader exec 'noremap' a:leader .'. :Trag * ' exec 'noremap' a:leader .'- :Tragfile' exec 'noremap ' a:leader .'# :Trag #w =trag#CWord()' for kind in keys(g:trag_kinds) call TragInstallKindMap(leader, kind) endfor endf function! TragInstallKindMap(leader, kind) "{{{3 " TLogVAR a:leader, a:kind if len(a:kind) == 1 let kind = a:kind if index(g:trag_kinds_ignored_comments, kind) != -1 let kind .= ',-i' endif exec 'nnoremap' a:leader . a:kind ':Trag #'. kind '=trag#CWord()' exec 'vnoremap' a:leader . a:kind 'y:Trag #'. kind '"' endif endf if !empty(g:trag_map_leader) call TragInstallMap(g:trag_map_leader) endif let &cpo = s:save_cpo unlet s:save_cpo autoload/trag.vim [[[1 1240 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Last Change: 2014-07-03. " @Revision: 1388 " call tlog#Log('Load: '. expand('')) " vimtlib-sfile " A comma-separated list of preferred grep programs: " " - trag " - vimgrep " - vcs (use the VCS's grep function; see |trag#external#vcs#Run()|, " this option always searches all files in the VCS); for a list of " supported VCSs see |trag#external#vcs#Run()| " - external:CMD (CMD defaults to grep; use vimgrep as fallback) " - ack " - ag " - grep (uses 'grepprg') " " The first valid option is used. E.g. if the value is "vcs,trag" and if " the buffer belongs to a supported VCS (see |trag#external#vcs#Run()|, " the VCS's grep function is used. Otherwise trag's own version of grep " is used. " " trag & vimgrep should work everywhere. " *b:trag_grep_type* " b:trag_grep_type overrides this global variable. TLet g:trag#grep_type = 'trag' " If no project files are defined, evaluate this expression as " fallback-strategy. TLet g:trag_get_files = 'split(glob("*"), "\n")' TLet g:trag_get_files_java = 'split(glob("**/*.java"), "\n")' TLet g:trag_get_files_c = 'split(glob("**/*.[ch]"), "\n")' TLet g:trag_get_files_cpp = 'split(glob("**/*.[ch]"), "\n")' " A list of sources. " Possible values: " vcs ....... Use g:trag#check_vcs " git ....... Use b:trag_git or g:trag_git " tags ...... Use files listed in 'tags' " files ..... Use b:trag_files or g:trag_files " glob ...... Use b:trag_glob or g:trag_glob " project ... Use b:trag_project_{'filetype'} or " g:trag_project_{'filetype'} " *b:trag_file_sources* " b:trag_file_sources overrides this global variable. TLet g:trag#file_sources = ['vcs', 'project', 'files', 'glob', 'tags'] " If true, use an already loaded buffer instead of the file on disk in " certain situations. This implies that if a buffer is dirty, the " non-saved version in memory will be preferred over the version on " disk. TLet g:trag#use_buffer = 1 " If true, try to detect whether the current file is under an VCS and " use that later on. TLet g:trag#check_vcs = 1 " :nodoc: function! trag#DefFiletype(args) "{{{3 let ft = a:args[0] for name in a:args[1:-1] call trag#SetFiletype(ft, name) endfor endf " Return true, if a filetype for "name" (an extension or a filename) is " defined. function! trag#HasFiletype(name) "{{{3 let name = has('fname_case') ? a:name : tolower(a:name) return has_key(g:trag_extension_filetype, name) endf " Define that filenames ("name" can be either an extension or a " filename) are of a certain filetype. function! trag#SetFiletype(filetype, name) "{{{3 let name = has('fname_case') ? a:name : tolower(a:name) " TLogVAR name, a:filetype let g:trag_extension_filetype[name] = a:filetype endf " Get the filetype for "name" (either an extension of a filename). function! trag#GetFiletype(name) "{{{3 let name = has('fname_case') ? a:name : tolower(a:name) " TLogVAR name, get(g:trag_extension_filetype,name,"") return get(g:trag_extension_filetype, name, '') endf " :nodoc: function! trag#TRagDefKind(args, ...) "{{{3 TVarArg ['replace', 0] " TLogVAR a:args " TLogDBG string(matchlist(a:args, '^\(\S\+\)\s\+\(\S\+\)\s\+/\(.\{-}\)/$')) let ml = matchlist(a:args, '^\(\S\+\)\s\+\(\S\+\)\s\+/\(.\{-}\)/$') if empty(ml) throw 'TRagDefKind: Malformed arguments: '. a:args else let [match, kind, filetype, regexp; rest] = ml " TLogVAR kind, filetype, regexp let var = ['g:trag_rxf', kind] if filetype != '*' && filetype != '.' call add(var, filetype) endif let varname = join(var, '_') if !exists(varname) || replace let {varname} = substitute(regexp, '\\/', '/', 'g') else let {varname} = '\%('. {varname} .'\|'. substitute(regexp, '\\/', '/', 'g') .'\)' endif if has_key(g:trag_kinds, kind) call add(g:trag_kinds[kind], filetype) else let g:trag_kinds[kind] = [filetype] if !empty(g:trag_map_leader) call TragInstallKindMap(g:trag_map_leader, kind) endif endif endif endf """ Known Types {{{1 TRagDefKind identity * /\C%s/ " Left hand side value in an assignment. " Examples: " l foo =~ foo = 1 TRagDefKind l * /\C%s\s*[^=]*=[^=~<>]/ " Right hand side value in an assignment. " Examples: " r foo =~ bar = foo TRagDefKind r * /\C[^!=~<>]=.\{-}%s/ " Markers: TODO, TBD, FIXME, OPTIMIZE TRagDefKind todo * /\C\%(TBD\|TODO\|FIXME\|OPTIMIZE\)/ " A mostly general rx format string for function calls. TRagDefKind f * /\C%s\s*(/ " The same as w, but is listed in |g:trag_kinds_ignored_comments|. TRagDefKind u * /\C\<%s\>/ " A mostly general rx format string for words. TRagDefKind w * /\C\<%s\>/ TRagDefKind W * /\C.\{-}%s.\{-}/ TRagDefKind fuzzy * /\c%{fuzzyrx}/ runtime! ftplugin/*/trag.vim """ File sets {{{1 " :doc: " The following variables provide alternatives to collecting " your project's file list on the basis of you tags files. " " These variables are tested in the order as listed here. If the value " of a variable is non-empty, this one will be used instead of the other " methods. " " The tags file is used as a last ressort. " 1. A list of files. Can be buffer local. TLet g:trag_files = [] " 2. A glob pattern -- this should be an absolute path and may contain ** " (see |glob()| and |wildcards|). Can be buffer local. TLet g:trag_glob = '' " 3. Filetype-specific project files. TLet g:trag_project_ruby = 'Manifest.txt' " 4. The name of a file containing the projects file list. This file could be " generated via make. Can be buffer local. TLet g:trag_project = '' " 5. The name of a git repository that includes all files of interest. " If the value is "*", trag will search from the current directory " (|getcwd()|) upwards for a .git directory. " If the value is "finddir", use |finddir()| to find a .git directory. " Can be buffer local. TLet g:trag_git = '' """ input#List {{{1 " :nodoc: TLet g:trag_edit_world = { \ 'type': 's', \ 'query': 'Select file', \ 'pick_last_item': 1, \ 'scratch': '__TRagEdit__', \ 'return_agent': 'tlib#agent#ViewFile', \ } " :nodoc: TLet g:trag_qfl_world = { \ 'type': 'mi', \ 'query': 'Select entry', \ 'pick_last_item': 0, \ 'resize_vertical': 0, \ 'resize': 20, \ 'scratch': '__TRagQFL__', \ 'tlib_UseInputListScratch': 'call trag#InitListBuffer()', \ 'key_handlers': [ \ {'key': 5, 'agent': 'trag#AgentWithSelected', 'key_name': '', 'help': 'Run a command on selected lines'}, \ {'key': 6, 'agent': 'trag#AgentRefactor', 'key_name': '', 'help': 'Run a refactor command'}, \ {'key': 16, 'agent': 'trag#AgentPreviewQFE', 'key_name': '', 'help': 'Preview'}, \ {'key': 60, 'agent': 'trag#AgentGotoQFE', 'key_name': '<', 'help': 'Jump (don''t close the list)'}, \ {'key': 19, 'agent': 'trag#AgentSplitBuffer', 'key_name': '', 'help': 'Show in split buffer'}, \ {'key': 20, 'agent': 'trag#AgentTabBuffer', 'key_name': '', 'help': 'Show in tab'}, \ {'key': 22, 'agent': 'trag#AgentVSplitBuffer', 'key_name': '', 'help': 'Show in vsplit buffer'}, \ {'key': 12, 'agent': 'trag#AgentEditLine', 'key_name': '', 'help': 'Edit selected line(s)'}, \ {'key': "\", 'agent': 'trag#SetFollowCursor', 'key_name': '', 'help': 'Toggle trace cursor'}, \ ], \ 'return_agent': 'trag#AgentEditQFE', \ } " \ {'key': 23, 'agent': 'trag#AgentOpenBuffer', 'key_name': '', 'help': 'View in window'}, """ Functions {{{1 let s:grep_rx = '' function! trag#InitListBuffer() "{{{3 let syntax = get(s:world, 'trag_list_syntax', '') let nextgroup = get(s:world, 'trag_list_syntax_nextgroup', '') if !empty(syntax) exec printf('runtime syntax/%s.vim', syntax) endif syn match TTagedFilesFilename / \zs.\{-}\ze|\d\+| / nextgroup=TTagedFilesLNum if !empty(nextgroup) exec 'syn match TTagedFilesLNum /|\d\+|\s\+/ nextgroup='. nextgroup else syn match TTagedFilesLNum /|\d\+|/ endif hi def link TTagedFilesFilename Directory hi def link TTagedFilesLNum LineNr if has('balloon_eval') setlocal ballooneval balloonexpr=trag#Balloon() endif endf function! trag#Balloon() "{{{3 let world = getbufvar(v:beval_bufnr, 'tlibDisplayListWorld') let current = max([1, world.offset]) + v:beval_lnum - 1 if current > len(world.table) let current = len(world.table) endif let baseidx = world.GetBaseIdx0(current) " TLogVAR world.offset, v:beval_lnum, current, baseidx let item = world.qfl[baseidx] " TLogVAR item if item.bufnr == 0 return '' else let lines = [printf("%d#%d: %s", item.bufnr, item.lnum, bufname(item.bufnr))] if has('balloon_multiline') let desc = {'nr': 'Error number', 'type': 'Error type', 'text': ''} for key in ['nr', 'type', 'text'] if has_key(item, key) && !empty(item[key]) let keydesc = get(desc, key, key) if empty(keydesc) let text = item[key] else let text = printf("%s: %s", key, item[key]) endif call add(lines, text) endif endfor endif return join(lines, "\n") endif " v:beval_bufnr number of the buffer in which balloon is going to show " v:beval_winnr number of the window " v:beval_lnum line number " v:beval_col column number (byte index) " v:beval_text word under or after the mouse pointer endf function! s:GetFiles() "{{{3 if !exists('b:trag_files_') call trag#SetFiles() endif if empty(b:trag_files_) " echohl Error " echoerr 'TRag: No project files' " echohl NONE let trag_get_files = tlib#var#Get('trag_get_files_'. &filetype, 'bg', '') " TLogVAR trag_get_files if empty(trag_get_files) let trag_get_files = tlib#var#Get('trag_get_files', 'bg', '') " TLogVAR trag_get_files endif echom 'TRag: No project files ... use: '. trag_get_files let b:trag_files_ = eval(trag_get_files) endif " TLogVAR b:trag_files_ return b:trag_files_ endf function! trag#ClearFiles() "{{{3 let b:trag_files_ = [] endf function! trag#AddFiles(files) "{{{3 if tlib#type#IsString(a:files) let files_ = eval(a:files) else let files_ = a:files endif if !tlib#type#IsList(files_) echoerr 'trag_files must result in a list: '. string(a:files) elseif exists('b:trag_files_') let b:trag_files_ += files_ else let b:trag_files_ = files_ endif unlet files_ endf function! trag#GetProjectFiles(manifest) "{{{3 if filereadable(a:manifest) " TLogVAR a:manifest let files = readfile(a:manifest) let cwd = getcwd() try call tlib#dir#CD(fnamemodify(a:manifest, ':h'), 1) call map(files, 'fnamemodify(v:val, ":p")') return files finally call tlib#dir#CD(cwd, 1) endtry endif return [] endf function! trag#GetGitFiles(repos) "{{{3 let repos = tlib#dir#PlainName(a:repos) let basedir = substitute(repos, '[\/]\.git\%([\/]\)\?$', '', '') " TLogVAR repos, basedir " TLogVAR getcwd() call tlib#dir#Push(basedir) " TLogVAR getcwd() try let files = split(system('git ls-files'), '\n') " TLogVAR files call map(files, 'basedir . g:tlib#dir#sep . v:val') return files finally call tlib#dir#Pop() endtry return [] endf " Set the files list to the files in the current VCS repository. function! trag#SetRepoFiles() "{{{3 let [type, dir] = tlib#vcs#FindVCS(expand('%')) if empty(type) echom 'No supported VCS repository found.' else let files = tlib#vcs#Ls('', [type, dir]) let b:trag_files_ = files echom len(files) 'files from the' type 'repository.' endif endf " Set the files list from the files included in a given git repository. function! trag#SetGitFiles(repos) "{{{3 let files = trag#GetGitFiles(a:repos) if !empty(files) call trag#ClearFiles() let b:trag_files_ = files echom len(files) ." files from the git repository." endif endf " :def: function! trag#SetFiles(?files=[]) function! trag#SetFiles(...) "{{{3 TVarArg ['files', []] call trag#ClearFiles() if empty(files) for source in tlib#var#Get('trag#file_sources', 'bg', []) if source == 'files' let files = tlib#var#Get('trag_files', 'bg', []) elseif source == 'glob' let glob = tlib#var#Get('trag_glob', 'bg', '') if !empty(glob) " TLogVAR glob let files = split(glob(glob), '\n') endif elseif source == 'project' let proj = tlib#var#Get('trag_project_'. &filetype, 'bg', tlib#var#Get('trag_project', 'bg', '')) " TLogVAR proj if !empty(proj) " let proj = fnamemodify(proj, ':p') let proj = findfile(proj, '.;') let files = trag#GetProjectFiles(proj) endif elseif source == 'tags' let filenames = {} for tag in taglist('.') let filenames[tag.filename] = 1 endfor let files = keys(filenames) elseif source == 'git' let git_repos = tlib#var#Get('trag_git', 'bg', '') if git_repos == '*' let git_repos = trag#FindGitRepos() elseif git_repos == "finddir" let git_repos = finddir('.git') endif if !empty(git_repos) let files = trag#GetGitFiles(git_repos) endif elseif source == 'vcs' if g:trag#check_vcs let files = tlib#vcs#Ls() end endif if !empty(files) break endif endfor endif " TLogVAR files if !empty(files) call map(files, 'fnamemodify(v:val, ":p")') " TLogVAR files call trag#AddFiles(files) endif " TLogVAR b:trag_files_ if empty(b:trag_files_) let files0 = taglist('.') " Filter bogus entry? call filter(files0, '!empty(v:val.kind)') call map(files0, 'v:val.filename') call sort(files0) let last = '' try call tlib#progressbar#Init(len(files0), 'TRag: Collect files %s', 20) let fidx = 0 for f in files0 call tlib#progressbar#Display(fidx) let fidx += 1 " if f != last && filereadable(f) if f != last call add(b:trag_files_, f) let last = f endif endfor finally call tlib#progressbar#Restore() endtry endif endf function! trag#FindGitRepos() "{{{3 let dir = fnamemodify(getcwd(), ':p') let git = tlib#file#Join([dir, '.git']) while !isdirectory(git) let dir1 = fnamemodify(dir, ':h') if dir == dir1 break else let dir = dir1 endif let git = tlib#file#Join([dir, '.git']) endwh if isdirectory(git) return git else return '' endif endf " Edit a file from the project catalog. See |g:trag_project| and " |:TRagfile|. function! trag#Edit() "{{{3 let w = tlib#World#New(copy(g:trag_edit_world)) let w.base = s:GetFiles() let w.show_empty = 1 let w.pick_last_item = 0 call w.SetInitialFilter(matchstr(expand('%:t:r'), '^\w\+')) call w.Set_display_format('filename') " TLogVAR w.base call tlib#input#ListW(w) endf " Test j trag " Test n tragfoo " Test j trag(foo) " Test n tragfoo(foo) " Test j trag " Test n tragfoo " :def: function! trag#Grep(args, ?replace=1, ?files=[], ?filetype='') " args: A string with the format: " KIND REGEXP " KIND1,KIND2 REGEXP " " If the variables [bg]:trag_rxf_{kind}_{&filetype} or " [bg]:trag_rxf_{kind} exist, these will be taken as format string (see " |printf()|) to format REGEXP. " " EXAMPLE: " trag#Grep('v foo') will find by default take g:trag_rxf_v and find " lines that looks like "\\s*=[^=~]", which most likely is a " variable definition in many programming languages. I.e. it will find " lines like: > " foo = 1 " < but not: > " def foo(bar) " call foo(bar) " if foo == 1 function! trag#Grep(args, ...) "{{{3 TVarArg ['replace', 1], ['files', []], ['filetype', ''] " TLogVAR a:args, replace, files, filetype let [kindspos, kindsneg, rx] = s:SplitArgs(a:args) " TLogVAR kindspos, kindsneg, rx, a:args if empty(rx) let rx = '.\{-}' " throw 'Malformed arguments (should be: "KIND REGEXP"): '. string(a:args) endif " TAssertType rx, 'string' let s:grep_rx = rx if empty(files) let files = s:GetFiles() else let files = split(join(map(files, 'glob(v:val)'), "\n"), '\n') endif " TLogVAR files " TAssertType files, 'list' call s:DoAutoCmd('QuickFixCmdPre') call tlib#progressbar#Init(len(files), 'TRag: Grep %s', 20) if replace call setqflist([]) endif let scratch = {} try let qfl_top = len(getqflist()) let grep_defs = map(copy(files), 's:GetGrepDef(v:val, kindspos, kindsneg, rx, filetype)') let grep_defs = filter(grep_defs, '!empty(v:val)') let done = 0 let trag_type = tlib#var#Get('trag#grep_type', 'bg') for grep_name in split(trag_type, ',\s*') " TLogVAR grep_name let ml = matchlist(grep_name, '^\(\w\+\):\s*\(.\{-}\)\s*$') if empty(ml) let grep_type = grep_name let grep_opts = '' else let grep_type = ml[1] let grep_opts = ml[2] endif let strip = grep_type == 'vimgrep' " TLogVAR grep_type, grep_opts " TLogVAR grep_defs if s:GrepWith_{grep_type}(grep_defs, grep_opts) let done = 1 break endif endfor " TLogVAR len(getqflist()) if !done throw 'TRag: Unsupported value for g:trag#grep_type: '. trag_type endif if strip let qfl1 = getqflist() if !empty(qfl1) " TLogVAR qfl_top, qfl1 let qfl1[qfl_top : -1] = map(qfl1[qfl_top : -1], 's:StripText(v:val)') call setqflist(qfl1, 'r') endif endif call s:DoAutoCmd('QuickFixCmdPost') " TLogDBG 'qfl:'. string(getqflist()) let qfl2 = getqflist() return qfl2[qfl_top : -1] finally if !empty(scratch) call tlib#scratch#CloseScratch(scratch) let &lazyredraw = lazyredraw endif call tlib#progressbar#Restore() endtry endf function! s:GetGrepDef(filename, kindspos, kindsneg, rx, filetype) "{{{3 let ff = fnamemodify(a:filename, ':p') if filereadable(ff) " TLogVAR f, kindspos, kindsneg let [rxpos, filetype0] = s:GetRx(ff, a:kindspos, a:rx, '.', a:filetype) " TLogVAR a:rx, rxpos if !empty(rxpos) let [rxneg, filetype1] = s:GetRx(ff, a:kindsneg, '', '', filetype0) " TLogVAR rxneg let ft = empty(filetype0) ? '*' : filetype0 return { \ 'f': a:filename, \ 'ff': ff, \ 'kindspos': a:kindspos, \ 'rx': a:rx, \ 'rxpos': rxpos, \ 'rxneg': rxneg, \ 'filetype': ft \ } endif endif return {} endf function! s:GrepWith_trag(grep_defs, grep_opts) "{{{3 let fidx = 0 for grep_def in a:grep_defs let fidx += 1 call tlib#progressbar#Display(fidx, ' '. pathshorten(grep_def.f)) let qfl = {} let lnum = 1 let bnum = bufnr(grep_def.ff) if g:trag#use_buffer && bnum != -1 && bufloaded(bnum) " TLogVAR bnum, a:filename, bufname(bnum) let lines = getbufline(bnum, 1, '$') else let lines = readfile(grep_def.ff) endif " TLogVAR grep_def.rxpos, grep_def.rxneg for line in lines if line =~ grep_def.rxpos && (empty(grep_def.rxneg) || line !~ grep_def.rxneg) let qfl[lnum] = {"filename": grep_def.ff, "lnum": lnum, "text": tlib#string#Strip(line)} endif let lnum += 1 endfor " TLogVAR qfl if !empty(qfl) call setqflist(values(qfl), 'a') endif endfor return 1 endf function! s:GrepWith_vimgrep(grep_defs, grep_opts) "{{{3 let rxnegs = {} let fidx = 0 for grep_def in a:grep_defs let fidx += 1 call tlib#progressbar#Display(fidx, ' '. pathshorten(grep_def.f)) let qfll = len(getqflist()) silent! exec 'noautocmd vimgrepadd' '/'. escape(grep_def.rxpos, '/') .'/j' tlib#arg#Ex(grep_def.ff) " TLogVAR qfll, len(getqflist()) if qfll != len(getqflist()) let bufnr = bufnr(grep_def.ff) " TLogVAR bufnr, grep_def.rxneg if !empty(grep_def.rxneg) && !has_key(rxnegs, bufnr) let rxnegs[bufnr] = grep_def.rxneg endif endif endfor call s:FilterRxNegs(rxnegs) return 1 endf function! s:GrepWith_ack(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'ack '. a:grep_opts) endf function! s:GrepWith_ag(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'ag '. a:grep_opts) endf function! s:GrepWith_grep(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'grep '. a:grep_opts) endf function! s:GrepWith_vcs(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'vcs '. a:grep_opts) endf function! s:GrepWith_external(grep_defs, grep_opts) "{{{3 let opts = tlib#arg#StringAsKeyArgsEqual(a:grep_opts) let grep_cmd = get(opts, 0, 'grep') " TLogVAR grep_cmd let group_defs = {} let must_filter = {} for grep_def in a:grep_defs let ft = grep_def.filetype " TLogVAR ft if !has_key(group_defs, ft) " TLogVAR grep_def.kindspos, trag#external#{grep_cmd}#IsSupported(grep_def.kindspos) let group_defs[ft] = {'rxpos': grep_def.rxpos, \ 'must_filter': 0, \ 'kindspos': grep_def.kindspos, \ 'files': []} if !trag#external#{grep_cmd}#IsSupported(grep_def.kindspos) let must_filter[ft] = grep_def.rxpos let group_defs[ft].use_rx = grep_def.rx endif endif call add(group_defs[ft].files, grep_def.ff) endfor for group_def in values(group_defs) let rx = get(group_def, 'use_rx', group_def.rxpos) let ok = trag#external#{grep_cmd}#Run(rx, group_def.files) " TLogVAR len(getqflist()) if !ok echohl WarningMsg echom 'Trag: Error when using external grep:' grep_cmd echom v:exception echohl NONE return 0 endif endfor if !empty(must_filter) let qfl = getqflist() " TLogVAR qfl for [ft, rxpos] in items(must_filter) " TLogVAR ft, rxpos let bufnrs = map(copy(group_defs[ft].files), 'bufnr(v:val)') let bufnrs = filter(bufnrs, 'v:val > 0') let bufnrs = sort(bufnrs) " TLogVAR bufnrs " TLogVAR map(copy(qfl), 'v:val.bufnr') let qfl = filter(qfl, 'index(bufnrs, v:val.bufnr) == -1 || v:val.text =~ rxpos') " TLogVAR qfl endfor call setqflist(qfl) endif let rxnegs = {} for grep_def in a:grep_defs if !empty(grep_def.rxneg) let bufnr = bufnr(grep_def.ff) if bufnr > 0 && !has_key(rxnegs, bufnr) let rxnegs[bufnr] = grep_def.rxneg endif endif endfor call s:FilterRxNegs(rxnegs) return 1 endf function! s:FilterRxNegs(rxnegs) "{{{3 " TLogVAR a:rxnegs if !empty(a:rxnegs) let qfl = getqflist() let qfl = filter(qfl, '!has_key(a:rxnegs, v:val.bufnr) || v:val.text !~ a:rxnegs[v:val.bufnr]') call setqflist(qfl) endif endf function! s:DoAutoCmd(event) "{{{3 redir => aus exec 'silent! autocmd' a:event 'trag' redir END let au = split(aus, '\n') if len(au) > 1 exec 'doautocmd' a:event 'trag' endif endf function! s:AddCurrentLine(file, qfl, rxneg) "{{{3 " TLogVAR a:file, a:rxneg let lnum = line('.') let text = getline(lnum) " TLogVAR lnum, text if empty(a:rxneg) || text !~ a:rxneg let a:qfl[lnum] = {"filename": a:file, "lnum": lnum, "text": tlib#string#Strip(text)} endif endf function! s:StripText(rec) "{{{3 let a:rec['text'] = tlib#string#Strip(a:rec['text']) return a:rec endf function! s:SplitArgs(args) "{{{3 " TLogVAR a:args let kind = matchstr(a:args, '^\S\+') if kind == '.' || kind == '*' let kind = '' endif let rx = matchstr(a:args, '\s\zs.*') if stridx(kind, '#') != -1 let kind = substitute(kind, '#', '', 'g') let rx = tlib#rx#Escape(rx) endif let kinds = split(kind, '[!-]', 1) let kindspos = s:SplitArgList(get(kinds, 0, ''), [['identity']]) let kindsneg = s:SplitArgList(get(kinds, 1, ''), []) " TLogVAR a:args, kinds, kind, rx, kindspos, kindsneg return [kindspos, kindsneg, rx] endf function! s:SplitArgList(string, default) "{{{3 let rv = map(split(a:string, ','), 'reverse(split(v:val, ''\.'', 1))') if empty(rv) return a:default else return rv endif endf function! trag#ClearCachedRx() "{{{3 let s:rx_cache = {} endf call trag#ClearCachedRx() let s:fnameftypes = {} function! s:GetRx(filename, kinds, rx, default, filetype) "{{{3 " TLogVAR a:filename, a:kinds, a:rx, a:default if empty(a:filetype) if has_key(s:fnameftypes, a:filename) let ftdef = s:fnameftypes[a:filename] let prototype = ftdef.proto let filetype = ftdef.ft else let prototype = '' for needle in [ \ fnamemodify(a:filename, ':p'), \ fnamemodify(a:filename, ':t'), \ fnamemodify(a:filename, ':e') \ ] let filetype = trag#GetFiletype(needle) " TLogVAR needle, filetype if !empty(filetype) let prototype = needle break endif endfor let s:fnameftypes[a:filename] = {'ft': filetype, 'proto': prototype} endif else let prototype = a:filename let filetype = a:filetype endif if empty(a:kinds) let rv = a:default else let rxacc = [] let id = filetype .'*'.string(a:kinds).'*'.a:rx " TLogVAR prototype, filetype, id if has_key(s:rx_cache, id) let rv = s:rx_cache[id] else for kindand in a:kinds let rx = a:rx for kind in kindand let rxf = tlib#var#Get('trag_rxf_'. kind, 'bg') " TLogVAR rxf if !empty(filetype) let rxf = tlib#var#Get('trag_rxf_'. kind .'_'. filetype, 'bg', rxf) endif " TLogVAR rxf if empty(rxf) if &verbose > 1 if empty(filetype) echom 'Unknown kind '. kind .' for unregistered filetype; skip files like '. prototype else echom 'Unknown kind '. kind .' for ft='. filetype .'; skip files like '. prototype endif endif return ['', filetype] else " TLogVAR rxf " If the expression is no word, ignore word boundaries. if rx =~ '\W$' && rxf =~ '%\@' let rxf = substitute(rxf, '%\@', '%s', 'g') endif if rx =~ '^\W' && rxf =~ '\\<%s' let rxf = substitute(rxf, '\\<%s', '%s', 'g') endif " TLogVAR rxf, rx let rx = tlib#string#Printf1(rxf, rx) endif endfor call add(rxacc, rx) endfor let rv = s:Rx(rxacc, a:default) let s:rx_cache[id] = rv endif endif " TLogVAR rv return [rv, filetype] endf function! s:Rx(rxacc, default) "{{{3 if empty(a:rxacc) let rx = a:default elseif len(a:rxacc) == 1 let rx = a:rxacc[0] else let rx = '\('. join(a:rxacc, '\|') .'\)' endif return rx endf function! s:GetFilename(qfe) "{{{3 let filename = get(a:qfe, 'filename') if empty(filename) let filename = bufname(get(a:qfe, 'bufnr')) endif return filename endf function! s:FormatQFLE(qfe) "{{{3 let filename = s:GetFilename(a:qfe) if get(s:world, 'trag_short_filename', '') let filename = pathshorten(filename) endif " let err = get(v:val, "type") . get(v:val, "nr") " return printf("%20s|%d|%s: %s", filename, v:val.lnum, err, get(v:val, "text")) return printf("%s|%d| %s", filename, a:qfe.lnum, get(a:qfe, "text")) endf " :display: trag#QuickList(?world={}, ?suspended=0) " Display the |quickfix| list with |tlib#input#ListW()|. function! trag#QuickList(...) "{{{3 TVarArg ['world', {}], ['suspended', 0] call trag#BrowseList(world, getqflist(), 0, suspended) endf function! trag#QuickListMaybe(anyway) "{{{3 call trag#BrowseList({}, getqflist(), a:anyway) endf function! trag#BrowseList(world_dict, list, ...) "{{{3 TVarArg ['anyway', 0], ['suspended', 0] " TLogVAR a:world_dict, a:list " TLogVAR anyway, suspended " TVarArg ['sign', 'TRag'] " if !empty(sign) && !empty(g:trag_sign) " " call tlib#signs#ClearAll(sign) " " call tlib#signs#Mark(sign, getqflist()) " endif " if !anyway && empty(filter(copy(a:list), 'v:val.nr != -1')) if !anyway && empty(a:list) return endif let s:world = copy(g:trag_qfl_world) if !empty(a:world_dict) call extend(s:world, a:world_dict) endif let s:world = tlib#World#New(s:world) " echom "DBG s:world" string(sort(keys(s:world))) let s:world.qfl = copy(a:list) " TLogVAR s:world.qfl call s:FormatBase(s:world) " TLogVAR s:world.base call tlib#input#ListW(s:world, suspended ? 'hibernate' : '') endf " Display the |location-list| with |tlib#input#ListW()|. function! trag#LocList(...) "{{{3 TVarArg ['world', {}], ['suspended', 0] " TLogVAR world, suspended " TVarArg ['sign', 'TRag'] " if !empty(sign) && !empty(g:trag_sign) " " call tlib#signs#ClearAll(sign) " " call tlib#signs#Mark(sign, getqflist()) " endif call trag#BrowseList(world, getloclist(0), 0, suspended) endf function! s:FormatBase(world) "{{{3 let a:world.base = map(copy(a:world.qfl), 's:FormatQFLE(v:val)') endf function! trag#AgentEditQFE(world, selected, ...) "{{{3 TVarArg ['cmd_edit', 'edit'], ['cmd_buffer', 'buffer'] " TLogVAR a:selected if empty(a:selected) call a:world.RestoreOrigin() " call a:world.ResetSelected() else call a:world.RestoreOrigin() for idx in a:selected let idx -= 1 " TLogVAR idx if idx >= 0 " TLogVAR a:world.qfl " call tlog#Debug(string(map(copy(a:world.qfl), 's:GetFilename(v:val)'))) " call tlog#Debug(string(map(copy(a:world.qfl), 'v:val.bufnr'))) " TLogVAR idx, a:world.qfl[idx] let qfe = a:world.qfl[idx] " let back = a:world.SwitchWindow('win') " TLogVAR cmd_edit, cmd_buffer, qfe let fn = s:GetFilename(qfe) " TLogVAR cmd_edit, cmd_buffer, fn call tlib#file#With(cmd_edit, cmd_buffer, [fn], a:world) " TLogDBG bufname('%') " TLogVAR &filetype call tlib#buffer#ViewLine(qfe.lnum) " call a:world.SetOrigin() " exec back endif endfor endif return a:world endf function! trag#AgentPreviewQFE(world, selected) "{{{3 " TLogVAR a:selected let back = a:world.SwitchWindow('win') call trag#AgentEditQFE(a:world, a:selected[0:0]) exec back redraw let a:world.state = 'redisplay' return a:world endf function! trag#AgentGotoQFE(world, selected) "{{{3 if !empty(a:selected) if a:world.win_wnr != winnr() let world = tlib#agent#Suspend(a:world, a:selected) exec a:world.win_wnr .'wincmd w' endif call trag#AgentEditQFE(a:world, a:selected[0:0]) endif return a:world endf function! trag#AgentWithSelected(world, selected, ...) "{{{3 let cmd = a:0 >= 1 ? a:1 : input('Ex command: ', '', 'command') if !empty(cmd) call trag#RunCmdOnSelected(a:world, a:selected, cmd) else let a:world.state = 'redisplay' endif return a:world endf function! trag#RunCmdOnSelected(world, selected, cmd, ...) "{{{3 let close_scratch = a:0 >= 1 ? a:1 : 1 if close_scratch call a:world.CloseScratch() endif " TLogVAR a:cmd for entry in a:selected " TLogVAR entry, a:world.GetBaseItem(entry) call trag#AgentEditQFE(a:world, [entry]) " TLogDBG bufname('%') exec a:cmd " let item = a:world.qfl[a:world.GetBaseIdx(entry - 1)] " <+TODO+> let item = a:world.qfl[entry - 1] " TLogVAR entry, item, getline('.') if has_key(a:world, 'GetBufferLines') let lines = a:world.GetBufferLines('.', '.') else let lines = getline('.', '.') endif let item['text'] = tlib#string#Strip(lines[0]) endfor if has_key(a:world, 'AfterRunCmd') if bufnr('%') == a:world.bufnr call a:world.AfterRunCmd() else " <+TODO+> Run in other buffer endif endif call s:FormatBase(a:world) call a:world.RestoreOrigin() let a:world.state = 'reset' return a:world endf function! trag#AgentSplitBuffer(world, selected) "{{{3 call a:world.CloseScratch() return trag#AgentEditQFE(a:world, a:selected, 'split', 'sbuffer') endf function! trag#AgentTabBuffer(world, selected) "{{{3 call a:world.CloseScratch() return trag#AgentEditQFE(a:world, a:selected, 'tabedit', 'tab sbuffer') endf function! trag#AgentVSplitBuffer(world, selected) "{{{3 call a:world.CloseScratch() return trag#AgentEditQFE(a:world, a:selected, 'vertical split', 'vertical sbuffer') endf " function! trag#AgentOpenBuffer(world, selected) "{{{3 " endf function! trag#AgentEditLine(world, selected) "{{{3 call a:world.CloseScratch() let cmd = 'call trag#EditLine(".")' return trag#RunCmdOnSelected(a:world, a:selected, cmd) let a:world.state = 'reset' return a:world endf function! trag#EditLine(lnum) "{{{3 call inputsave() let line = input('', getline(a:lnum)) call inputrestore() if !empty(line) call setline(line(a:lnum), line) endif endf " Invoke an refactor command. " Currently only one command is supported: rename function! trag#AgentRefactor(world, selected) "{{{3 call a:world.CloseScratch() let cmds = ['Rename'] let cmd = tlib#input#List('s', 'Select command', cmds) if !empty(cmd) return trag#Refactor{cmd}(a:world, a:selected) endif let a:world.state = 'reset' return a:world endf function! trag#CWord() "{{{3 if has_key(g:trag_keyword_chars, &filetype) let rx = '['. g:trag_keyword_chars[&filetype] .']\+' let line = getline('.') let col = col('.') if col == 1 let pre = '' else let pre = matchstr(line[0 : col - 2], rx.'$') endif let post = matchstr(line[col - 1 : -1], '^'.rx) let word = pre . post " TLogVAR word, pre, post, line, col else let word = expand('') " TLogVAR word endif return word endf function! trag#RefactorRename(world, selected) "{{{3 " TLogVAR a:selected let from = input('Rename ', s:grep_rx) if !empty(from) let to = input('Rename '. from .' to: ', from) if !empty(to) let ft = a:world.filetype let fn = 'trag#'. ft .'#Rename' " TLogVAR ft, exists('*'. fn) try return call(fn, [a:world, a:selected, from, to]) catch /^Vim\%((\a\+)\)\=:E117/ " TLogDBG "General" return trag#general#Rename(a:world, a:selected, from, to) endtry endif endif let a:world.state = 'reset' return a:world endf function! trag#SetFollowCursor(world, selected) "{{{3 if empty(a:world.follow_cursor) let a:world.follow_cursor = 'trag#AgentPreviewQFE' else let a:world.follow_cursor = '' endif let a:world.state = 'redisplay' return a:world endf function! trag#IsSupported(supported_kinds, kinds) "{{{3 let kinds = tlib#list#Flatten(a:kinds) let not_supported = filter(kinds, 'index(a:supported_kinds, v:val) == -1') " TLogVAR a:supported_kinds, a:kinds, not_supported return empty(not_supported) endf autoload/trag/general.vim [[[1 13 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Last Change: 2009-02-25. " @Revision: 7 function! trag#general#Rename(world, selected, rx, subst) "{{{3 let cmd = 's/\C\<'. escape(tlib#rx#Escape(a:rx), '/') .'\>/'. escape(tlib#rx#EscapeReplace(a:subst), '/') .'/ge' " let cmd = 's/\C'. escape(a:rx, '/') .'/'. escape(tlib#rx#EscapeReplace(a:subst), '/') .'/ge' return trag#RunCmdOnSelected(a:world, a:selected, cmd) endf autoload/trag/viki.vim [[[1 12 " @Author: Thomas Link (mailto:micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Last Change: 2009-02-27. " @Revision: 6 function! trag#viki#Rename(world, selected, from, to) "{{{3 let suffix = tlib#var#Get('vikiNameSuffix', 'bg', '') return trag#rename#Rename(a:world, a:selected, a:from, a:to, suffix) endf autoload/trag/rename.vim [[[1 34 " @Author: Thomas Link (mailto:micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Last Change: 2009-02-27. " @Revision: 4 function! trag#rename#Rename(world, selected, from, to, suffix) "{{{3 let rv = trag#general#Rename(a:world, a:selected, a:from, a:to) let from_file = a:from . a:suffix let to_file = a:to . a:suffix let bnr = bufnr(from_file) " TLogVAR from_file, to_file, bnr if filereadable(to_file) echom 'TRag: Cannot rename file, file already exists: '. to_file elseif filereadable(from_file) call rename(from_file, to_file) echom 'TRag: Renamed file '. from_file .' -> '. to_file endif if bnr != -1 if bufnr(to_file) != -1 call tlib#notify#Echo('TRag: Cannot rename buffer, buffer already exists: '. to_file, 'Error') else exec 'buffer '. bnr exec 'file! '. fnameescape(to_file) w! echom 'TRag: Renamed buffer '. from_file .' -> '. to_file if filereadable(from_file) && !filereadable(to_file) call tlib#notify#Echo('TRag: Inconsistent state. Please rename the file '. from_file .' -> '. to_file, 'Error') endif endif endif return rv endf autoload/trag/external/ack.vim [[[1 23 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 13 if !exists('g:trag#external#ack#opts') let g:trag#external#ack#opts = {'grepprg': 'ack', 'args': '-Hns --nocolor --nogroup %s --'} "{{{2 endif if !exists('g:trag#external#ack#supported_kinds') let g:trag#external#ack#supported_kinds = ['identity', 'w', 'todo'] "{{{2 endif function! trag#external#ack#IsSupported(kinds) "{{{3 return trag#IsSupported(g:trag#external#ack#supported_kinds, a:kinds) endf function! trag#external#ack#Run(rx, files) "{{{3 return trag#external#grep#Run(a:rx, a:files, g:trag#external#ack#opts) endf autoload/trag/external/vcs.vim [[[1 99 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Last Change: 2014-07-03. " @Revision: 203 if !exists('g:trag#external#vcs#options_git') let g:trag#external#vcs#options_git = {'args': 'grep -Hn -G %s --'} "{{{2 endif " if !exists('g:trag#external#vcs#options_hg') " let g:trag#external#vcs#options_hg = {'args': 'grep -n %s --', " \ 'convert_rx': 'trag#rx#ConvertRx_perl', " \ 'gfm': '%f:%*[^:]:%l:%m'} "{{{2 " endif if !exists('g:trag#external#vcs#supported_kinds') let g:trag#external#vcs#supported_kinds = ['identity', 'w', 'todo'] "{{{2 endif function! trag#external#vcs#IsSupported(kinds) "{{{3 return trag#IsSupported(g:trag#external#vcs#supported_kinds, a:kinds) endf " Currently only git is supported. " For other VCSs, I'd recommend to use "ag". function! trag#external#vcs#Run(rx, files) "{{{3 " TLogVAR a:rx if exists('b:trag_support_vcs') if empty(b:trag_support_vcs) return 0 else let [type, dir, bin] = b:trag_support_vcs endif else let b:trag_support_vcs = [] let [type, dir] = tlib#vcs#FindVCS(expand('%')) if empty(type) return 0 endif if !exists('g:trag#external#vcs#options_'. type) " echom 'Trag: Unsupported VCS type:' type return 0 endif let bin = tlib#vcs#Executable(type) " TLogVAR bin if empty(bin) " echom 'Trag: Unsupported VCS type:' type return 0 endif let b:trag_support_vcs = [type, dir, bin] " TLogVAR b:trag_support_vcs endif " TLogVAR type, dir, bin let ddir = fnamemodify(dir, ':p:h:h') let cd = getcwd() " TLogVAR type, dir, ddir, cd let gfm = &gfm let grepprg = &grepprg try let opts = g:trag#external#vcs#options_{type} " TLogVAR opts let rx = trag#rx#ConvertRx(a:rx, type, opts) " TLogVAR a:rx, rx let cmd = bin .' '. printf(get(opts, 'args', '%s'), \ shellescape(rx, 1)) let &grepprg = cmd " let &gfm = get(opts, 'gfm', '%m') let &gfm = get(opts, 'gfm', '%f:%l:%m') " TLogVAR &grepprg, &gfm let files = copy(a:files) let convert_filename = get(opts, 'convert_filename', 'trag#external#vcs#ConvertFilename_'. type) if exists('*'. convert_filename) let files = map(files, 'call(convert_filename, [type, v:val])') endif exec 'cd!' fnameescape(ddir) " TLogVAR getcwd() call trag#utils#GrepaddFiles('', files) return 1 finally if getcwd() != cd exec 'cd!' fnameescape(cd) endif let &gfm = gfm let &grepprg = grepprg endtry return 0 endf function! trag#external#vcs#ConvertFilename_git(type, filename) "{{{3 return substitute(a:filename, '\\', '/', 'g') endf autoload/trag/external/ag.vim [[[1 23 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 19 if !exists('g:trag#external#ag#opts') let g:trag#external#ag#opts = {'grepprg': 'ag', 'args': '-U -f --line-numbers --nogroup --nocolor -- %s'} "{{{2 endif if !exists('g:trag#external#ag#supported_kinds') let g:trag#external#ag#supported_kinds = ['identity', 'w', 'todo'] "{{{2 endif function! trag#external#ag#IsSupported(kinds) "{{{3 return trag#IsSupported(g:trag#external#ag#supported_kinds, a:kinds) endf function! trag#external#ag#Run(rx, files) "{{{3 return trag#external#grep#Run(a:rx, a:files, g:trag#external#ag#opts) endf autoload/trag/external/grep.vim [[[1 51 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Last Change: 2014-07-03. " @Revision: 94 if !exists('g:trag#external#grep#args') let g:trag#external#grep#args = '-Hn -E %s --' "{{{2 endif if !exists('g:trag#external#grep#supported_kinds') let g:trag#external#grep#supported_kinds = ['identity', 'w', 'todo'] "{{{2 endif function! trag#external#grep#IsSupported(kinds) "{{{3 return trag#IsSupported(g:trag#external#grep#supported_kinds, a:kinds) endf function! trag#external#grep#Run(rx, files, ...) "{{{3 let grep_params = a:0 >= 1 ? a:1 : {} let grep_prg0 = &grepprg let grep_format0 = &grepformat let grep_prg1 = get(grep_params, 'grepprg', grep_prg0) let grep_format1 = get(grep_params, 'grepformat', grep_format0) let rx = trag#rx#ConvertRx(a:rx, 'perl', grep_params) " TLogVAR a:rx, rx let args = get(grep_params, 'args', g:trag#external#grep#args) let args = tlib#string#Printf1(args, shellescape(rx, 1)) if grep_prg0 != grep_prg1 let &grepprg = grep_prg1 endif if grep_format0 != grep_format1 let &grepformat = grep_format1 endif " TLogVAR &grepprg, &grepformat, args try call trag#utils#GrepaddFiles(args, a:files) return 1 finally if grep_prg0 != grep_prg1 let &grepprg = grep_prg0 endif if grep_format0 != grep_format1 let &grepformat = grep_format0 endif endtry endf autoload/trag/rx.vim [[[1 48 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 13 function! trag#rx#ConvertRx(rx, type, ...) "{{{3 let opts = a:0 >= 1 ? a:1 : {} " TLogVAR a:rx, a:type, opts let convert_rx = get(opts, 'convert_rx', 'trag#rx#ConvertRx_'. a:type) " TLogVAR convert_rx if exists('*'. convert_rx) let rx = call(convert_rx, [a:type, a:rx]) else let rx = a:rx endif " TLogVAR rx return rx endf function! trag#rx#ConvertRx_git(type, rx) "{{{3 let rx = substitute(a:rx, '\\C', '', 'g') " let rx = substitute(a:rx, '\\{-}', '\\+\\?', 'g') return rx endf function! trag#rx#ConvertRx_perl(type, rx) "{{{3 let rx = substitute(a:rx, '\\C', '', 'g') let rx = substitute(rx, '\\[<>]', '\\b', 'g') let rx = substitute(rx, '\\{-}', '*?', 'g') let rxl = [] " TLogVAR rx for part in split(rx, '[()|+?]\zs') " TLogVAR 1, part if part =~ '\\\@')) " vimtlib-sfile " A comma-separated list of preferred grep programs: " " - trag " - vimgrep " - vcs (use the VCS's grep function; see |trag#external#vcs#Run()|, " this option always searches all files in the VCS); for a list of " supported VCSs see |trag#external#vcs#Run()| " - external:CMD (CMD defaults to grep; use vimgrep as fallback) " - ack " - ag " - grep (uses 'grepprg') " " The first valid option is used. E.g. if the value is "vcs,trag" and if " the buffer belongs to a supported VCS (see |trag#external#vcs#Run()|, " the VCS's grep function is used. Otherwise trag's own version of grep " is used. " " trag & vimgrep should work everywhere. " *b:trag_grep_type* " b:trag_grep_type overrides this global variable. TLet g:trag#grep_type = 'trag' " If no project files are defined, evaluate this expression as " fallback-strategy. TLet g:trag_get_files = 'split(glob("*"), "\n")' TLet g:trag_get_files_java = 'split(glob("**/*.java"), "\n")' TLet g:trag_get_files_c = 'split(glob("**/*.[ch]"), "\n")' TLet g:trag_get_files_cpp = 'split(glob("**/*.[ch]"), "\n")' " A list of sources. " Possible values: " vcs ....... Use g:trag#check_vcs " git ....... Use b:trag_git or g:trag_git " tags ...... Use files listed in 'tags' " files ..... Use b:trag_files or g:trag_files " glob ...... Use b:trag_glob or g:trag_glob " project ... Use b:trag_project_{'filetype'} or " g:trag_project_{'filetype'} " *b:trag_file_sources* " b:trag_file_sources overrides this global variable. TLet g:trag#file_sources = ['vcs', 'project', 'files', 'glob', 'tags'] " If true, use an already loaded buffer instead of the file on disk in " certain situations. This implies that if a buffer is dirty, the " non-saved version in memory will be preferred over the version on " disk. TLet g:trag#use_buffer = 1 " If true, try to detect whether the current file is under an VCS and " use that later on. TLet g:trag#check_vcs = 1 " :nodoc: function! trag#DefFiletype(args) "{{{3 let ft = a:args[0] for name in a:args[1:-1] call trag#SetFiletype(ft, name) endfor endf " Return true, if a filetype for "name" (an extension or a filename) is " defined. function! trag#HasFiletype(name) "{{{3 let name = has('fname_case') ? a:name : tolower(a:name) return has_key(g:trag_extension_filetype, name) endf " Define that filenames ("name" can be either an extension or a " filename) are of a certain filetype. function! trag#SetFiletype(filetype, name) "{{{3 let name = has('fname_case') ? a:name : tolower(a:name) " TLogVAR name, a:filetype let g:trag_extension_filetype[name] = a:filetype endf " Get the filetype for "name" (either an extension of a filename). function! trag#GetFiletype(name) "{{{3 let name = has('fname_case') ? a:name : tolower(a:name) " TLogVAR name, get(g:trag_extension_filetype,name,"") return get(g:trag_extension_filetype, name, '') endf " :nodoc: function! trag#TRagDefKind(args, ...) "{{{3 TVarArg ['replace', 0] " TLogVAR a:args " TLogDBG string(matchlist(a:args, '^\(\S\+\)\s\+\(\S\+\)\s\+/\(.\{-}\)/$')) let ml = matchlist(a:args, '^\(\S\+\)\s\+\(\S\+\)\s\+/\(.\{-}\)/$') if empty(ml) throw 'TRagDefKind: Malformed arguments: '. a:args else let [match, kind, filetype, regexp; rest] = ml " TLogVAR kind, filetype, regexp let var = ['g:trag_rxf', kind] if filetype != '*' && filetype != '.' call add(var, filetype) endif let varname = join(var, '_') if !exists(varname) || replace let {varname} = substitute(regexp, '\\/', '/', 'g') else let {varname} = '\%('. {varname} .'\|'. substitute(regexp, '\\/', '/', 'g') .'\)' endif if has_key(g:trag_kinds, kind) call add(g:trag_kinds[kind], filetype) else let g:trag_kinds[kind] = [filetype] if !empty(g:trag_map_leader) call TragInstallKindMap(g:trag_map_leader, kind) endif endif endif endf """ Known Types {{{1 TRagDefKind identity * /\C%s/ " Left hand side value in an assignment. " Examples: " l foo =~ foo = 1 TRagDefKind l * /\C%s\s*[^=]*=[^=~<>]/ " Right hand side value in an assignment. " Examples: " r foo =~ bar = foo TRagDefKind r * /\C[^!=~<>]=.\{-}%s/ " Markers: TODO, TBD, FIXME, OPTIMIZE TRagDefKind todo * /\C\%(TBD\|TODO\|FIXME\|OPTIMIZE\)/ " A mostly general rx format string for function calls. TRagDefKind f * /\C%s\s*(/ " The same as w, but is listed in |g:trag_kinds_ignored_comments|. TRagDefKind u * /\C\<%s\>/ " A mostly general rx format string for words. TRagDefKind w * /\C\<%s\>/ TRagDefKind W * /\C.\{-}%s.\{-}/ TRagDefKind fuzzy * /\c%{fuzzyrx}/ runtime! ftplugin/*/trag.vim """ File sets {{{1 " :doc: " The following variables provide alternatives to collecting " your project's file list on the basis of you tags files. " " These variables are tested in the order as listed here. If the value " of a variable is non-empty, this one will be used instead of the other " methods. " " The tags file is used as a last ressort. " 1. A list of files. Can be buffer local. TLet g:trag_files = [] " 2. A glob pattern -- this should be an absolute path and may contain ** " (see |glob()| and |wildcards|). Can be buffer local. TLet g:trag_glob = '' " 3. Filetype-specific project files. TLet g:trag_project_ruby = 'Manifest.txt' " 4. The name of a file containing the projects file list. This file could be " generated via make. Can be buffer local. TLet g:trag_project = '' " 5. The name of a git repository that includes all files of interest. " If the value is "*", trag will search from the current directory " (|getcwd()|) upwards for a .git directory. " If the value is "finddir", use |finddir()| to find a .git directory. " Can be buffer local. TLet g:trag_git = '' """ input#List {{{1 " :nodoc: TLet g:trag_edit_world = { \ 'type': 's', \ 'query': 'Select file', \ 'pick_last_item': 1, \ 'scratch': '__TRagEdit__', \ 'return_agent': 'tlib#agent#ViewFile', \ } " :nodoc: TLet g:trag_qfl_world = { \ 'type': 'mi', \ 'query': 'Select entry', \ 'pick_last_item': 0, \ 'resize_vertical': 0, \ 'resize': 20, \ 'scratch': '__TRagQFL__', \ 'tlib_UseInputListScratch': 'call trag#InitListBuffer()', \ 'key_handlers': [ \ {'key': 5, 'agent': 'trag#AgentWithSelected', 'key_name': '', 'help': 'Run a command on selected lines'}, \ {'key': 6, 'agent': 'trag#AgentRefactor', 'key_name': '', 'help': 'Run a refactor command'}, \ {'key': 16, 'agent': 'trag#AgentPreviewQFE', 'key_name': '', 'help': 'Preview'}, \ {'key': 60, 'agent': 'trag#AgentGotoQFE', 'key_name': '<', 'help': 'Jump (don''t close the list)'}, \ {'key': 19, 'agent': 'trag#AgentSplitBuffer', 'key_name': '', 'help': 'Show in split buffer'}, \ {'key': 20, 'agent': 'trag#AgentTabBuffer', 'key_name': '', 'help': 'Show in tab'}, \ {'key': 22, 'agent': 'trag#AgentVSplitBuffer', 'key_name': '', 'help': 'Show in vsplit buffer'}, \ {'key': 12, 'agent': 'trag#AgentEditLine', 'key_name': '', 'help': 'Edit selected line(s)'}, \ {'key': "\", 'agent': 'trag#SetFollowCursor', 'key_name': '', 'help': 'Toggle trace cursor'}, \ ], \ 'return_agent': 'trag#AgentEditQFE', \ } " \ {'key': 23, 'agent': 'trag#AgentOpenBuffer', 'key_name': '', 'help': 'View in window'}, """ Functions {{{1 let s:grep_rx = '' function! trag#InitListBuffer() "{{{3 let syntax = get(s:world, 'trag_list_syntax', '') let nextgroup = get(s:world, 'trag_list_syntax_nextgroup', '') if !empty(syntax) exec printf('runtime syntax/%s.vim', syntax) endif syn match TTagedFilesFilename / \zs.\{-}\ze|\d\+| / nextgroup=TTagedFilesLNum if !empty(nextgroup) exec 'syn match TTagedFilesLNum /|\d\+|\s\+/ nextgroup='. nextgroup else syn match TTagedFilesLNum /|\d\+|/ endif hi def link TTagedFilesFilename Directory hi def link TTagedFilesLNum LineNr if has('balloon_eval') setlocal ballooneval balloonexpr=trag#Balloon() endif endf function! trag#Balloon() "{{{3 let world = getbufvar(v:beval_bufnr, 'tlibDisplayListWorld') let current = max([1, world.offset]) + v:beval_lnum - 1 if current > len(world.table) let current = len(world.table) endif let baseidx = world.GetBaseIdx0(current) " TLogVAR world.offset, v:beval_lnum, current, baseidx let item = world.qfl[baseidx] " TLogVAR item if item.bufnr == 0 return '' else let lines = [printf("%d#%d: %s", item.bufnr, item.lnum, bufname(item.bufnr))] if has('balloon_multiline') let desc = {'nr': 'Error number', 'type': 'Error type', 'text': ''} for key in ['nr', 'type', 'text'] if has_key(item, key) && !empty(item[key]) let keydesc = get(desc, key, key) if empty(keydesc) let text = item[key] else let text = printf("%s: %s", key, item[key]) endif call add(lines, text) endif endfor endif return join(lines, "\n") endif " v:beval_bufnr number of the buffer in which balloon is going to show " v:beval_winnr number of the window " v:beval_lnum line number " v:beval_col column number (byte index) " v:beval_text word under or after the mouse pointer endf function! s:GetFiles() "{{{3 if !exists('b:trag_files_') call trag#SetFiles() endif if empty(b:trag_files_) " echohl Error " echoerr 'TRag: No project files' " echohl NONE let trag_get_files = tlib#var#Get('trag_get_files_'. &filetype, 'bg', '') " TLogVAR trag_get_files if empty(trag_get_files) let trag_get_files = tlib#var#Get('trag_get_files', 'bg', '') " TLogVAR trag_get_files endif echom 'TRag: No project files ... use: '. trag_get_files let b:trag_files_ = eval(trag_get_files) endif " TLogVAR b:trag_files_ return b:trag_files_ endf function! trag#ClearFiles() "{{{3 let b:trag_files_ = [] endf function! trag#AddFiles(files) "{{{3 if tlib#type#IsString(a:files) let files_ = eval(a:files) else let files_ = a:files endif if !tlib#type#IsList(files_) echoerr 'trag_files must result in a list: '. string(a:files) elseif exists('b:trag_files_') let b:trag_files_ += files_ else let b:trag_files_ = files_ endif unlet files_ endf function! trag#GetProjectFiles(manifest) "{{{3 if filereadable(a:manifest) " TLogVAR a:manifest let files = readfile(a:manifest) let cwd = getcwd() try call tlib#dir#CD(fnamemodify(a:manifest, ':h'), 1) call map(files, 'fnamemodify(v:val, ":p")') return files finally call tlib#dir#CD(cwd, 1) endtry endif return [] endf function! trag#GetGitFiles(repos) "{{{3 let repos = tlib#dir#PlainName(a:repos) let basedir = substitute(repos, '[\/]\.git\%([\/]\)\?$', '', '') " TLogVAR repos, basedir " TLogVAR getcwd() call tlib#dir#Push(basedir) " TLogVAR getcwd() try let files = split(system('git ls-files'), '\n') " TLogVAR files call map(files, 'basedir . g:tlib#dir#sep . v:val') return files finally call tlib#dir#Pop() endtry return [] endf " Set the files list to the files in the current VCS repository. function! trag#SetRepoFiles() "{{{3 let [type, dir] = tlib#vcs#FindVCS(expand('%')) if empty(type) echom 'No supported VCS repository found.' else let files = tlib#vcs#Ls('', [type, dir]) let b:trag_files_ = files echom len(files) 'files from the' type 'repository.' endif endf " Set the files list from the files included in a given git repository. function! trag#SetGitFiles(repos) "{{{3 let files = trag#GetGitFiles(a:repos) if !empty(files) call trag#ClearFiles() let b:trag_files_ = files echom len(files) ." files from the git repository." endif endf " :def: function! trag#SetFiles(?files=[]) function! trag#SetFiles(...) "{{{3 TVarArg ['files', []] call trag#ClearFiles() if empty(files) for source in tlib#var#Get('trag#file_sources', 'bg', []) if source == 'files' let files = tlib#var#Get('trag_files', 'bg', []) elseif source == 'glob' let glob = tlib#var#Get('trag_glob', 'bg', '') if !empty(glob) " TLogVAR glob let files = split(glob(glob), '\n') endif elseif source == 'project' let proj = tlib#var#Get('trag_project_'. &filetype, 'bg', tlib#var#Get('trag_project', 'bg', '')) " TLogVAR proj if !empty(proj) " let proj = fnamemodify(proj, ':p') let proj = findfile(proj, '.;') let files = trag#GetProjectFiles(proj) endif elseif source == 'tags' let filenames = {} for tag in taglist('.') let filenames[tag.filename] = 1 endfor let files = keys(filenames) elseif source == 'git' let git_repos = tlib#var#Get('trag_git', 'bg', '') if git_repos == '*' let git_repos = trag#FindGitRepos() elseif git_repos == "finddir" let git_repos = finddir('.git') endif if !empty(git_repos) let files = trag#GetGitFiles(git_repos) endif elseif source == 'vcs' if g:trag#check_vcs let files = tlib#vcs#Ls() end endif if !empty(files) break endif endfor endif " TLogVAR files if !empty(files) call map(files, 'fnamemodify(v:val, ":p")') " TLogVAR files call trag#AddFiles(files) endif " TLogVAR b:trag_files_ if empty(b:trag_files_) let files0 = taglist('.') " Filter bogus entry? call filter(files0, '!empty(v:val.kind)') call map(files0, 'v:val.filename') call sort(files0) let last = '' try call tlib#progressbar#Init(len(files0), 'TRag: Collect files %s', 20) let fidx = 0 for f in files0 call tlib#progressbar#Display(fidx) let fidx += 1 " if f != last && filereadable(f) if f != last call add(b:trag_files_, f) let last = f endif endfor finally call tlib#progressbar#Restore() endtry endif endf function! trag#FindGitRepos() "{{{3 let dir = fnamemodify(getcwd(), ':p') let git = tlib#file#Join([dir, '.git']) while !isdirectory(git) let dir1 = fnamemodify(dir, ':h') if dir == dir1 break else let dir = dir1 endif let git = tlib#file#Join([dir, '.git']) endwh if isdirectory(git) return git else return '' endif endf " Edit a file from the project catalog. See |g:trag_project| and " |:TRagfile|. function! trag#Edit() "{{{3 let w = tlib#World#New(copy(g:trag_edit_world)) let w.base = s:GetFiles() let w.show_empty = 1 let w.pick_last_item = 0 call w.SetInitialFilter(matchstr(expand('%:t:r'), '^\w\+')) call w.Set_display_format('filename') " TLogVAR w.base call tlib#input#ListW(w) endf " Test j trag " Test n tragfoo " Test j trag(foo) " Test n tragfoo(foo) " Test j trag " Test n tragfoo " :def: function! trag#Grep(args, ?replace=1, ?files=[], ?filetype='') " args: A string with the format: " KIND REGEXP " KIND1,KIND2 REGEXP " " If the variables [bg]:trag_rxf_{kind}_{&filetype} or " [bg]:trag_rxf_{kind} exist, these will be taken as format string (see " |printf()|) to format REGEXP. " " EXAMPLE: " trag#Grep('v foo') will find by default take g:trag_rxf_v and find " lines that looks like "\\s*=[^=~]", which most likely is a " variable definition in many programming languages. I.e. it will find " lines like: > " foo = 1 " < but not: > " def foo(bar) " call foo(bar) " if foo == 1 function! trag#Grep(args, ...) "{{{3 TVarArg ['replace', 1], ['files', []], ['filetype', ''] " TLogVAR a:args, replace, files, filetype let [kindspos, kindsneg, rx] = s:SplitArgs(a:args) " TLogVAR kindspos, kindsneg, rx, a:args if empty(rx) let rx = '.\{-}' " throw 'Malformed arguments (should be: "KIND REGEXP"): '. string(a:args) endif " TAssertType rx, 'string' let s:grep_rx = rx if empty(files) let files = s:GetFiles() else let files = split(join(map(files, 'glob(v:val)'), "\n"), '\n') endif " TLogVAR files " TAssertType files, 'list' call s:DoAutoCmd('QuickFixCmdPre') call tlib#progressbar#Init(len(files), 'TRag: Grep %s', 20) if replace call setqflist([]) endif let scratch = {} try let qfl_top = len(getqflist()) let grep_defs = map(copy(files), 's:GetGrepDef(v:val, kindspos, kindsneg, rx, filetype)') let grep_defs = filter(grep_defs, '!empty(v:val)') let done = 0 let trag_type = tlib#var#Get('trag#grep_type', 'bg') for grep_name in split(trag_type, ',\s*') " TLogVAR grep_name let ml = matchlist(grep_name, '^\(\w\+\):\s*\(.\{-}\)\s*$') if empty(ml) let grep_type = grep_name let grep_opts = '' else let grep_type = ml[1] let grep_opts = ml[2] endif let strip = grep_type == 'vimgrep' " TLogVAR grep_type, grep_opts " TLogVAR grep_defs if s:GrepWith_{grep_type}(grep_defs, grep_opts) let done = 1 break endif endfor " TLogVAR len(getqflist()) if !done throw 'TRag: Unsupported value for g:trag#grep_type: '. trag_type endif if strip let qfl1 = getqflist() if !empty(qfl1) " TLogVAR qfl_top, qfl1 let qfl1[qfl_top : -1] = map(qfl1[qfl_top : -1], 's:StripText(v:val)') call setqflist(qfl1, 'r') endif endif call s:DoAutoCmd('QuickFixCmdPost') " TLogDBG 'qfl:'. string(getqflist()) let qfl2 = getqflist() return qfl2[qfl_top : -1] finally if !empty(scratch) call tlib#scratch#CloseScratch(scratch) let &lazyredraw = lazyredraw endif call tlib#progressbar#Restore() endtry endf function! s:GetGrepDef(filename, kindspos, kindsneg, rx, filetype) "{{{3 let ff = fnamemodify(a:filename, ':p') if filereadable(ff) " TLogVAR f, kindspos, kindsneg let [rxpos, filetype0] = s:GetRx(ff, a:kindspos, a:rx, '.', a:filetype) " TLogVAR a:rx, rxpos if !empty(rxpos) let [rxneg, filetype1] = s:GetRx(ff, a:kindsneg, '', '', filetype0) " TLogVAR rxneg let ft = empty(filetype0) ? '*' : filetype0 return { \ 'f': a:filename, \ 'ff': ff, \ 'kindspos': a:kindspos, \ 'rx': a:rx, \ 'rxpos': rxpos, \ 'rxneg': rxneg, \ 'filetype': ft \ } endif endif return {} endf function! s:GrepWith_trag(grep_defs, grep_opts) "{{{3 let fidx = 0 for grep_def in a:grep_defs let fidx += 1 call tlib#progressbar#Display(fidx, ' '. pathshorten(grep_def.f)) let qfl = {} let lnum = 1 let bnum = bufnr(grep_def.ff) if g:trag#use_buffer && bnum != -1 && bufloaded(bnum) " TLogVAR bnum, a:filename, bufname(bnum) let lines = getbufline(bnum, 1, '$') else let lines = readfile(grep_def.ff) endif " TLogVAR grep_def.rxpos, grep_def.rxneg for line in lines if line =~ grep_def.rxpos && (empty(grep_def.rxneg) || line !~ grep_def.rxneg) let qfl[lnum] = {"filename": grep_def.ff, "lnum": lnum, "text": tlib#string#Strip(line)} endif let lnum += 1 endfor " TLogVAR qfl if !empty(qfl) call setqflist(values(qfl), 'a') endif endfor return 1 endf function! s:GrepWith_vimgrep(grep_defs, grep_opts) "{{{3 let rxnegs = {} let fidx = 0 for grep_def in a:grep_defs let fidx += 1 call tlib#progressbar#Display(fidx, ' '. pathshorten(grep_def.f)) let qfll = len(getqflist()) silent! exec 'noautocmd vimgrepadd' '/'. escape(grep_def.rxpos, '/') .'/j' tlib#arg#Ex(grep_def.ff) " TLogVAR qfll, len(getqflist()) if qfll != len(getqflist()) let bufnr = bufnr(grep_def.ff) " TLogVAR bufnr, grep_def.rxneg if !empty(grep_def.rxneg) && !has_key(rxnegs, bufnr) let rxnegs[bufnr] = grep_def.rxneg endif endif endfor call s:FilterRxNegs(rxnegs) return 1 endf function! s:GrepWith_ack(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'ack '. a:grep_opts) endf function! s:GrepWith_ag(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'ag '. a:grep_opts) endf function! s:GrepWith_grep(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'grep '. a:grep_opts) endf function! s:GrepWith_vcs(grep_defs, grep_opts) "{{{3 return s:GrepWith_external(a:grep_defs, 'vcs '. a:grep_opts) endf function! s:GrepWith_external(grep_defs, grep_opts) "{{{3 let opts = tlib#arg#StringAsKeyArgsEqual(a:grep_opts) let grep_cmd = get(opts, 0, 'grep') " TLogVAR grep_cmd let group_defs = {} let must_filter = {} for grep_def in a:grep_defs let ft = grep_def.filetype " TLogVAR ft if !has_key(group_defs, ft) " TLogVAR grep_def.kindspos, trag#external#{grep_cmd}#IsSupported(grep_def.kindspos) let group_defs[ft] = {'rxpos': grep_def.rxpos, \ 'must_filter': 0, \ 'kindspos': grep_def.kindspos, \ 'files': []} if !trag#external#{grep_cmd}#IsSupported(grep_def.kindspos) let must_filter[ft] = grep_def.rxpos let group_defs[ft].use_rx = grep_def.rx endif endif call add(group_defs[ft].files, grep_def.ff) endfor for group_def in values(group_defs) let rx = get(group_def, 'use_rx', group_def.rxpos) let ok = trag#external#{grep_cmd}#Run(rx, group_def.files) " TLogVAR len(getqflist()) if !ok echohl WarningMsg echom 'Trag: Error when using external grep:' grep_cmd echom v:exception echohl NONE return 0 endif endfor if !empty(must_filter) let qfl = getqflist() " TLogVAR qfl for [ft, rxpos] in items(must_filter) " TLogVAR ft, rxpos let bufnrs = map(copy(group_defs[ft].files), 'bufnr(v:val)') let bufnrs = filter(bufnrs, 'v:val > 0') let bufnrs = sort(bufnrs) " TLogVAR bufnrs " TLogVAR map(copy(qfl), 'v:val.bufnr') let qfl = filter(qfl, 'index(bufnrs, v:val.bufnr) == -1 || v:val.text =~ rxpos') " TLogVAR qfl endfor call setqflist(qfl) endif let rxnegs = {} for grep_def in a:grep_defs if !empty(grep_def.rxneg) let bufnr = bufnr(grep_def.ff) if bufnr > 0 && !has_key(rxnegs, bufnr) let rxnegs[bufnr] = grep_def.rxneg endif endif endfor call s:FilterRxNegs(rxnegs) return 1 endf function! s:FilterRxNegs(rxnegs) "{{{3 " TLogVAR a:rxnegs if !empty(a:rxnegs) let qfl = getqflist() let qfl = filter(qfl, '!has_key(a:rxnegs, v:val.bufnr) || v:val.text !~ a:rxnegs[v:val.bufnr]') call setqflist(qfl) endif endf function! s:DoAutoCmd(event) "{{{3 redir => aus exec 'silent! autocmd' a:event 'trag' redir END let au = split(aus, '\n') if len(au) > 1 exec 'doautocmd' a:event 'trag' endif endf function! s:AddCurrentLine(file, qfl, rxneg) "{{{3 " TLogVAR a:file, a:rxneg let lnum = line('.') let text = getline(lnum) " TLogVAR lnum, text if empty(a:rxneg) || text !~ a:rxneg let a:qfl[lnum] = {"filename": a:file, "lnum": lnum, "text": tlib#string#Strip(text)} endif endf function! s:StripText(rec) "{{{3 let a:rec['text'] = tlib#string#Strip(a:rec['text']) return a:rec endf function! s:SplitArgs(args) "{{{3 " TLogVAR a:args let kind = matchstr(a:args, '^\S\+') if kind == '.' || kind == '*' let kind = '' endif let rx = matchstr(a:args, '\s\zs.*') if stridx(kind, '#') != -1 let kind = substitute(kind, '#', '', 'g') let rx = tlib#rx#Escape(rx) endif let kinds = split(kind, '[!-]', 1) let kindspos = s:SplitArgList(get(kinds, 0, ''), [['identity']]) let kindsneg = s:SplitArgList(get(kinds, 1, ''), []) " TLogVAR a:args, kinds, kind, rx, kindspos, kindsneg return [kindspos, kindsneg, rx] endf function! s:SplitArgList(string, default) "{{{3 let rv = map(split(a:string, ','), 'reverse(split(v:val, ''\.'', 1))') if empty(rv) return a:default else return rv endif endf function! trag#ClearCachedRx() "{{{3 let s:rx_cache = {} endf call trag#ClearCachedRx() let s:fnameftypes = {} function! s:GetRx(filename, kinds, rx, default, filetype) "{{{3 " TLogVAR a:filename, a:kinds, a:rx, a:default if empty(a:filetype) if has_key(s:fnameftypes, a:filename) let ftdef = s:fnameftypes[a:filename] let prototype = ftdef.proto let filetype = ftdef.ft else let prototype = '' for needle in [ \ fnamemodify(a:filename, ':p'), \ fnamemodify(a:filename, ':t'), \ fnamemodify(a:filename, ':e') \ ] let filetype = trag#GetFiletype(needle) " TLogVAR needle, filetype if !empty(filetype) let prototype = needle break endif endfor let s:fnameftypes[a:filename] = {'ft': filetype, 'proto': prototype} endif else let prototype = a:filename let filetype = a:filetype endif if empty(a:kinds) let rv = a:default else let rxacc = [] let id = filetype .'*'.string(a:kinds).'*'.a:rx " TLogVAR prototype, filetype, id if has_key(s:rx_cache, id) let rv = s:rx_cache[id] else for kindand in a:kinds let rx = a:rx for kind in kindand let rxf = tlib#var#Get('trag_rxf_'. kind, 'bg') " TLogVAR rxf if !empty(filetype) let rxf = tlib#var#Get('trag_rxf_'. kind .'_'. filetype, 'bg', rxf) endif " TLogVAR rxf if empty(rxf) if &verbose > 1 if empty(filetype) echom 'Unknown kind '. kind .' for unregistered filetype; skip files like '. prototype else echom 'Unknown kind '. kind .' for ft='. filetype .'; skip files like '. prototype endif endif return ['', filetype] else " TLogVAR rxf " If the expression is no word, ignore word boundaries. if rx =~ '\W$' && rxf =~ '%\@' let rxf = substitute(rxf, '%\@', '%s', 'g') endif if rx =~ '^\W' && rxf =~ '\\<%s' let rxf = substitute(rxf, '\\<%s', '%s', 'g') endif " TLogVAR rxf, rx let rx = tlib#string#Printf1(rxf, rx) endif endfor call add(rxacc, rx) endfor let rv = s:Rx(rxacc, a:default) let s:rx_cache[id] = rv endif endif " TLogVAR rv return [rv, filetype] endf function! s:Rx(rxacc, default) "{{{3 if empty(a:rxacc) let rx = a:default elseif len(a:rxacc) == 1 let rx = a:rxacc[0] else let rx = '\('. join(a:rxacc, '\|') .'\)' endif return rx endf function! s:GetFilename(qfe) "{{{3 let filename = get(a:qfe, 'filename') if empty(filename) let filename = bufname(get(a:qfe, 'bufnr')) endif return filename endf function! s:FormatQFLE(qfe) "{{{3 let filename = s:GetFilename(a:qfe) if get(s:world, 'trag_short_filename', '') let filename = pathshorten(filename) endif " let err = get(v:val, "type") . get(v:val, "nr") " return printf("%20s|%d|%s: %s", filename, v:val.lnum, err, get(v:val, "text")) return printf("%s|%d| %s", filename, a:qfe.lnum, get(a:qfe, "text")) endf " :display: trag#QuickList(?world={}, ?suspended=0) " Display the |quickfix| list with |tlib#input#ListW()|. function! trag#QuickList(...) "{{{3 TVarArg ['world', {}], ['suspended', 0] call trag#BrowseList(world, getqflist(), 0, suspended) endf function! trag#QuickListMaybe(anyway) "{{{3 call trag#BrowseList({}, getqflist(), a:anyway) endf function! trag#BrowseList(world_dict, list, ...) "{{{3 TVarArg ['anyway', 0], ['suspended', 0] " TLogVAR a:world_dict, a:list " TLogVAR anyway, suspended " TVarArg ['sign', 'TRag'] " if !empty(sign) && !empty(g:trag_sign) " " call tlib#signs#ClearAll(sign) " " call tlib#signs#Mark(sign, getqflist()) " endif " if !anyway && empty(filter(copy(a:list), 'v:val.nr != -1')) if !anyway && empty(a:list) return endif let s:world = copy(g:trag_qfl_world) if !empty(a:world_dict) call extend(s:world, a:world_dict) endif let s:world = tlib#World#New(s:world) " echom "DBG s:world" string(sort(keys(s:world))) let s:world.qfl = copy(a:list) " TLogVAR s:world.qfl call s:FormatBase(s:world) " TLogVAR s:world.base call tlib#input#ListW(s:world, suspended ? 'hibernate' : '') endf " Display the |location-list| with |tlib#input#ListW()|. function! trag#LocList(...) "{{{3 TVarArg ['world', {}], ['suspended', 0] " TLogVAR world, suspended " TVarArg ['sign', 'TRag'] " if !empty(sign) && !empty(g:trag_sign) " " call tlib#signs#ClearAll(sign) " " call tlib#signs#Mark(sign, getqflist()) " endif call trag#BrowseList(world, getloclist(0), 0, suspended) endf function! s:FormatBase(world) "{{{3 let a:world.base = map(copy(a:world.qfl), 's:FormatQFLE(v:val)') endf function! trag#AgentEditQFE(world, selected, ...) "{{{3 TVarArg ['cmd_edit', 'edit'], ['cmd_buffer', 'buffer'] " TLogVAR a:selected if empty(a:selected) call a:world.RestoreOrigin() " call a:world.ResetSelected() else call a:world.RestoreOrigin() for idx in a:selected let idx -= 1 " TLogVAR idx if idx >= 0 " TLogVAR a:world.qfl " call tlog#Debug(string(map(copy(a:world.qfl), 's:GetFilename(v:val)'))) " call tlog#Debug(string(map(copy(a:world.qfl), 'v:val.bufnr'))) " TLogVAR idx, a:world.qfl[idx] let qfe = a:world.qfl[idx] " let back = a:world.SwitchWindow('win') " TLogVAR cmd_edit, cmd_buffer, qfe let fn = s:GetFilename(qfe) " TLogVAR cmd_edit, cmd_buffer, fn call tlib#file#With(cmd_edit, cmd_buffer, [fn], a:world) " TLogDBG bufname('%') " TLogVAR &filetype call tlib#buffer#ViewLine(qfe.lnum) " call a:world.SetOrigin() " exec back endif endfor endif return a:world endf function! trag#AgentPreviewQFE(world, selected) "{{{3 " TLogVAR a:selected let back = a:world.SwitchWindow('win') call trag#AgentEditQFE(a:world, a:selected[0:0]) exec back redraw let a:world.state = 'redisplay' return a:world endf function! trag#AgentGotoQFE(world, selected) "{{{3 if !empty(a:selected) if a:world.win_wnr != winnr() let world = tlib#agent#Suspend(a:world, a:selected) exec a:world.win_wnr .'wincmd w' endif call trag#AgentEditQFE(a:world, a:selected[0:0]) endif return a:world endf function! trag#AgentWithSelected(world, selected, ...) "{{{3 let cmd = a:0 >= 1 ? a:1 : input('Ex command: ', '', 'command') if !empty(cmd) call trag#RunCmdOnSelected(a:world, a:selected, cmd) else let a:world.state = 'redisplay' endif return a:world endf function! trag#RunCmdOnSelected(world, selected, cmd, ...) "{{{3 let close_scratch = a:0 >= 1 ? a:1 : 1 if close_scratch call a:world.CloseScratch() endif " TLogVAR a:cmd for entry in a:selected " TLogVAR entry, a:world.GetBaseItem(entry) call trag#AgentEditQFE(a:world, [entry]) " TLogDBG bufname('%') exec a:cmd " let item = a:world.qfl[a:world.GetBaseIdx(entry - 1)] " <+TODO+> let item = a:world.qfl[entry - 1] " TLogVAR entry, item, getline('.') if has_key(a:world, 'GetBufferLines') let lines = a:world.GetBufferLines('.', '.') else let lines = getline('.', '.') endif let item['text'] = tlib#string#Strip(lines[0]) endfor if has_key(a:world, 'AfterRunCmd') if bufnr('%') == a:world.bufnr call a:world.AfterRunCmd() else " <+TODO+> Run in other buffer endif endif call s:FormatBase(a:world) call a:world.RestoreOrigin() let a:world.state = 'reset' return a:world endf function! trag#AgentSplitBuffer(world, selected) "{{{3 call a:world.CloseScratch() return trag#AgentEditQFE(a:world, a:selected, 'split', 'sbuffer') endf function! trag#AgentTabBuffer(world, selected) "{{{3 call a:world.CloseScratch() return trag#AgentEditQFE(a:world, a:selected, 'tabedit', 'tab sbuffer') endf function! trag#AgentVSplitBuffer(world, selected) "{{{3 call a:world.CloseScratch() return trag#AgentEditQFE(a:world, a:selected, 'vertical split', 'vertical sbuffer') endf " function! trag#AgentOpenBuffer(world, selected) "{{{3 " endf function! trag#AgentEditLine(world, selected) "{{{3 call a:world.CloseScratch() let cmd = 'call trag#EditLine(".")' return trag#RunCmdOnSelected(a:world, a:selected, cmd) let a:world.state = 'reset' return a:world endf function! trag#EditLine(lnum) "{{{3 call inputsave() let line = input('', getline(a:lnum)) call inputrestore() if !empty(line) call setline(line(a:lnum), line) endif endf " Invoke an refactor command. " Currently only one command is supported: rename function! trag#AgentRefactor(world, selected) "{{{3 call a:world.CloseScratch() let cmds = ['Rename'] let cmd = tlib#input#List('s', 'Select command', cmds) if !empty(cmd) return trag#Refactor{cmd}(a:world, a:selected) endif let a:world.state = 'reset' return a:world endf function! trag#CWord() "{{{3 if has_key(g:trag_keyword_chars, &filetype) let rx = '['. g:trag_keyword_chars[&filetype] .']\+' let line = getline('.') let col = col('.') if col == 1 let pre = '' else let pre = matchstr(line[0 : col - 2], rx.'$') endif let post = matchstr(line[col - 1 : -1], '^'.rx) let word = pre . post " TLogVAR word, pre, post, line, col else let word = expand('') " TLogVAR word endif return word endf function! trag#RefactorRename(world, selected) "{{{3 " TLogVAR a:selected let from = input('Rename ', s:grep_rx) if !empty(from) let to = input('Rename '. from .' to: ', from) if !empty(to) let ft = a:world.filetype let fn = 'trag#'. ft .'#Rename' " TLogVAR ft, exists('*'. fn) try return call(fn, [a:world, a:selected, from, to]) catch /^Vim\%((\a\+)\)\=:E117/ " TLogDBG "General" return trag#general#Rename(a:world, a:selected, from, to) endtry endif endif let a:world.state = 'reset' return a:world endf function! trag#SetFollowCursor(world, selected) "{{{3 if empty(a:world.follow_cursor) let a:world.follow_cursor = 'trag#AgentPreviewQFE' else let a:world.follow_cursor = '' endif let a:world.state = 'redisplay' return a:world endf function! trag#IsSupported(supported_kinds, kinds) "{{{3 let kinds = tlib#list#Flatten(a:kinds) let not_supported = filter(kinds, 'index(a:supported_kinds, v:val) == -1') " TLogVAR a:supported_kinds, a:kinds, not_supported return empty(not_supported) endf ftplugin/make/trag.vim [[[1 15 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 13 if !exists('g:loaded_trag') || exists('g:ftplugin_trag_make') finish endif let g:ftplugin_trag_make = 1 TRagDefFiletype make Makefile TRagDefKind i make /\C^\s*#.\{-}%s/ TRagDefKind d make /\C^%s\s*[:=]/ TRagDefKind l make /\C^\s*\<%s\s*=[^=<>]/ TRagDefKind r make /\C[^=!<>]=.\{-}%s/ ftplugin/java/trag.vim [[[1 19 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 4 if !exists('g:loaded_trag') || exists('g:ftplugin_trag_java') finish endif let g:ftplugin_trag_java = 1 TRagDefFiletype java java let s:java_mod = '\%(\<\%(final\|public\|protected\|private\|synchronized\|volatile\|abstract\)\s\+\)*' let s:java_type = '\%(boolean\|byte\|short\|int\|long\|float\|double\|char\|void\|\u[[:alnum:]_.]*\)\s\+' exec 'TRagDefKind c java /\C^\s*'. s:java_mod .'class\s\+%s/' exec 'TRagDefKind d java /\C^\s*'. s:java_mod .'\%(\w\+\%(\[\]\)*\)\s\+%s\s*(/' exec 'TRagDefKind f java /\%(\%(;\|{\|^\)\s*'. s:java_mod . s:java_type .'\)\@/ TRagDefKind W ruby /\C[^;()]\{-}%s[^;()]\{-}/ TRagDefKind c ruby /\C\/ TRagDefKind d ruby /\C\<\%(def\s\+\%(\u\w*\.\)*\|attr\%(_\w\+\)\?\s\+\%(:\w\+,\s\+\)*:\)%s/ TRagDefKind f ruby /\<%s\>/ TRagDefKind i ruby /\C^\s*#%s/ TRagDefKind m ruby /\C\]/ TRagDefKind x ruby /\C\s\*class\>.\{-}<\s*%s/ ftplugin/r/trag.vim [[[1 18 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 3 if !exists('g:loaded_trag') || exists('g:ftplugin_trag_r') finish endif let g:ftplugin_trag_r = 1 TRagDefFiletype r r TRagDefKind i r /\C^\s*#%s/ TRagDefKind d r /\C^\s*\%(%s\s*<-\s*function\>\|setMethod\s*("%s"\)/ TRagDefKind c r /\C\%(\<%s\s*<-\s*set\%(Ref\)\?Class\>\|\s*<-\s*set\%(Ref\)\?Class\s*(\s*"%s"\)/ TRagDefKind l r /\C\%(^\s*%s\s*<<\?-\s*\|\<%s\s*=[^=]\)/ TRagDefKind r r /\C\s*<<\?-\s*%s/ TRagDefKind f r /\C\<%s\s*(/ ftplugin/json/trag.vim [[[1 15 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 6 if !exists('g:loaded_trag') || exists('g:ftplugin_trag_json') finish endif let g:ftplugin_trag_json = 1 TRagDefFiletype json json TRagDefKind d json /\C^\s\+"%s"\s*:/ TRagDefKind l json /\C^\s\+"%s"\s*:/ TRagDefKind r json /\C^\s\+".\{-}"\s*:.\{-}%s/ ftplugin/vim/trag.vim [[[1 19 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 5 if !exists('g:loaded_trag') || exists('g:ftplugin_trag_vim') finish endif let g:ftplugin_trag_vim = 1 TRagDefFiletype vim vim .vimrc _vimrc TRagKeyword vim [:alnum:]_:# TRagDefKind W vim /\C[^|]\{-}%s[^|]\{-}/ TRagDefKind d vim /\C\<\%(fu\%%[nction]!\?\s\+\|com\%%[mand]!\?\s\+\%(-\S\+\s\+\)*\)%s/ TRagDefKind f vim /\C\%(\\s*(/ TRagDefKind i vim /\C^\s*"%s/ TRagDefKind r vim /\C^\s*let\s\+\S\+\s*=[^|]\{-}%s/ TRagDefKind l vim /\C^\s*let\s\+%s\>/ ftplugin/javascript/trag.vim [[[1 17 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 6 if !exists('g:loaded_trag') || exists('g:ftplugin_trag_javascript') finish endif let g:ftplugin_trag_javascript = 1 TRagDefFiletype javascript js TRagDefKind i javascript /\C^\s*\%(\/\/\|\/\*\).\{-}%s/ TRagDefKind d javascript /\C\%(\<%s\s*[:=]\s*function\>\|\\)/ TRagDefKind l javascript /\C\<%s\s*=[^=<>]/ TRagDefKind r javascript /\C[^=!<>]=\s*%s/ TRagDefKind f javascript /\C\(\