{"id":13898303,"url":"https://github.com/LucHermitte/lh-tags","last_synced_at":"2025-07-17T15:33:09.928Z","repository":{"id":28648360,"uuid":"32167630","full_name":"LucHermitte/lh-tags","owner":"LucHermitte","description":"ctags base updating, and browsing from vim","archived":false,"fork":false,"pushed_at":"2021-08-12T00:07:59.000Z","size":2443,"stargazers_count":26,"open_issues_count":1,"forks_count":1,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-08-07T18:45:58.234Z","etag":null,"topics":["ctags","vim","vim-plugins","viml-functions","viml-library"],"latest_commit_sha":null,"homepage":"","language":"Vim script","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LucHermitte.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"License.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-13T16:38:06.000Z","updated_at":"2023-04-23T02:19:35.000Z","dependencies_parsed_at":"2022-09-04T18:12:26.721Z","dependency_job_id":null,"html_url":"https://github.com/LucHermitte/lh-tags","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucHermitte%2Flh-tags","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucHermitte%2Flh-tags/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucHermitte%2Flh-tags/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucHermitte%2Flh-tags/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LucHermitte","download_url":"https://codeload.github.com/LucHermitte/lh-tags/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226274819,"owners_count":17598860,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ctags","vim","vim-plugins","viml-functions","viml-library"],"created_at":"2024-08-06T18:04:13.282Z","updated_at":"2024-11-25T04:31:15.561Z","avatar_url":"https://github.com/LucHermitte.png","language":"Vim script","funding_links":[],"categories":["Vim Script"],"sub_categories":[],"readme":"# lh-tags : a ctags wrapper for Vim\n[![Last release](https://img.shields.io/github/tag/LucHermitte/lh-tags.svg)](https://github.com/LucHermitte/lh-tags/releases) [![Project Stats](https://www.openhub.net/p/21020/widgets/project_thin_badge.gif)](https://www.openhub.net/p/21020)\n\n## Introduction\n\nlh-tags is a ctags wrapper plugin for Vim.\n\nThis plugin has two main features:\n * The generation of `tags` files is simplified,\n * and tag selection is simplified (the support for overloads (when\n   _overloading_ is supported) is more ergonomic than what\n   [`:tselect`](http://vimhelp.appspot.com/tagsrch.txt.html#%3atselect)\n   permits)\n\nIt also provides a feature aimed at plugin developpers:\n * an [API](doc/API.md) to request information on the current file -- local\n   variables,\n   information on an enumeration, function boundaries... In other Words, the\n   API gives on-the-fly access to information that is not necesserally stored\n   in the current tag database.\n\n## Features\n\n### Tags generation\n * Is portable: the plugin is regularly used on nixes, windows (with or without\n   cygwin, and with\n   [`'shellslash'`](http://vimhelp.appspot.com/options.txt.html#%27shellslash%27)\n   on).\n * Is incremental: when a file under the watch of lh-tags is modified, only\n   this file is parsed -- its previous information is deleted from the current\n   `tags` file.\n * Can be run on the whole project, when needed.\n * Is, of course, [parametrisable](#options).\n * Can be run asynchronously (this is the default starting from Vim 7.4-1980).\n   When this happens, [airline](https://github.com/vim-airline/vim-airline)\n   will display information about the background jobs -- if _airline_ plugin is\n   installed, of course.\n * Can be done on a third-party project freshly cloned/checked out without a\n   need to define any configuration file for a\n   [local_vimrc](http://github.com/LucHermitte/local_vimrc) plugin.\n * Doesn't have external dependencies other than `ctags` and `cd`.\n   BTW, I highly recommend [universal ctags](http://github.com/universal-ctags/ctags)\n   over exhuberant ctags.\n * Is project friendly: i.e. multiple projects can be opened simultaneously in\n   a single vim session, and we can run `ctags` on each of them with different\n   specialized options to produced dedicaded tag files.\n * Tag files built can be used to (automatically) fill\n   [`'spellfile'`](http://vimhelp.appspot.com/options.txt.html#%27spellfile%27)\n   option with words to be ignored by vim spell checker.\n * Generated tags can also automatically be highlighted (see\n   `g:tags_options.auto_highlight`)\n\n### Tags selection\n * Presents all tags that match the selected text (`META-W-META-DOWN`), or the\n   pattern used (`:LHTags`).\n * Can hide, or show, functions signatures (on `s`).\n * Permits to sort the results by `K`ind, `N`ame, or `F`ilename.\n * Can filter the results on any (ctags) field (_kind_, _name_, _filename_,\n   _signature_, _namespace_, ...)\n * The selected tag can be jumped to in the current window (`CR`,\n   _double-click_), or in a split window (`o`) -- the tags stack is updated\n   along the way.\n\n![LHTags and filter demo](doc/screencast-LHTags.gif \":LHTags and filter demo\")\n\n## Usage\n\nIn order to use lh-tags, I highly recommend to use a plugin like\n[local_vimrc](http://github.com/LucHermitte/local_vimrc).\n\nIn the buffer local section, you can:\n * set some `(bpg):tags_options....` if the default values don't suit you -- I\n   use it to add exclusion lists in my projects.\n * force another root directory where to store the ctags database\n * ...\n\nThen, you'll have to generate the `tags` database once (`\u003cC-X\u003eta`), then you\ncan enjoy lh-tags automagic update of the database, and improved tag selection.\n\n## Options\nRegarding the conventions used in my plugins, and how to set options, see\nthe following\n[documentation](https://github.com/LucHermitte/lh-vim-lib/blob/master/doc/Options.md).\nI explain what I mean by `(bpg)`, what each scope covers, and how (and where)\nrelated variables can be set.\n\n### Directory and pathnames related options\nlh-tags can distinguish the directory where a tag database is stored from the\ndirectory where the source files are. By default, both directories will be the\nsame.\n\n#### Dirname to source code: `(bpg):paths.tags.src_dir`\n\nHow ever this directory name is deduced, its value will be cached in the\n[project variable](http://github.com/LucHermitte/lh-vim-lib/blob/master/doc/Project.md)\n`p:paths.tags.src_dir`.\n\nThe heuristic to deduce where the source code to index is located consists in\nsearching the first option which is set among:\n\n1. `(bpg):paths.tags.src_dir` -- cached, specific to lh-tags, permits to\n   override `(bpg):paths.sources` if need be\n2. `(bpg):tags_dirname` -- old (deprecated) options previously used by lh-tags\n   V2; kept for retro-compatibility\n3. `(bpg):paths.sources` -- where sources files are supposed to be found\n   according to lh-vim-lib _Project feature_.\n4. `b:project_source_dir` -- old option used by previous versions of\n   [mu-template](https://github.com/LucHermitte/mu-template/); kept for\n   retro-compatibility\n5. `(bpg):BTW_project_config._.paths.sources` -- internal information used by\n   [Build Tools Wrapper](https://github.com/LucHermitte/vim-build-tools-wrapper);\n   not meant to be set from lh-tags\n6. If none of the previous options is set, lh-tags will search a\n   parent directory which contains any sign of being under source control\n   (`.git/`, `.svn/`, `.hg/`...)\n7. Ultimately, lh-tags asks to the end-user where the source files to index are\n   stored (previous values are recorded in case several files from a same\n   project are opened).\n\n   Note: At this time, we cannot say _\"never ask for this directory\"_ as it's\n   possible with lh-vim-lib _Project feature_. I'm likelly to change the\n   current behaviour to the one used in lh-vim-lib.\n\n#### Name of the tag database: `(pbg):tags_filename`\nThe name defaults to `\"tags\"` with ctags indexers.\n\nThis option permits to have another name -- this can be useful when all tag\ndatabases are stored with a policy such as `projects/.tags/{projectname}.ctags`.\n\nIf you want to change the directory where the tag database is stored, it must\nbe done through this option. Relative pathnames are expressed relativelly to\nthe sources directory `(bpg):paths.tags.src_dir`.\n\n### Filetypes and languages related options\n\n#### Indexed filetype: `lh#tags#add_indexed_ft()`\n\nThis option helps managing the filetypes whose files will be indexed. Files of\nother types are ignored.\n\nInternally, this updates the project option `p:tags_options.indexed_ft` --\nprefer this function when using\n[local_vimrc](http://github.com/LucHermitte/local_vimrc) to configure a\nproject.\n\nIt's also possible to set the option `g:tags_options.indexed_ft` that'll be\nused instead. The global option is meant to be used when no project are\ndefined.\n\n```vim\n\" In this project we index only C and C++ files\n:call lh#tags#add_indexed_ft('c', 'cpp')\n```\n\n#### Language map: `lh#tags#set_lang_map()`\nManages the extensions associated to a filetype.\n\nThe point of this helper function is to set the options to the best possible\nvalue according to the current tag-indexer which could be exhuberant-ctags,\nuniversal-ctags, or eventually any other indexer like _global_.\n\n```vim\n:call lh#tags#set_lang_map('cpp', '+.txx')\n```\n\nSince version 3.0.0, it's best to avoid to directly set\n`b:tags_options.{ft}.flags` to either `--langmap=C++:+.txx` or\n`--map-C++=+.txx` as it's not _portable_ between the various flavours of ctags.\n\n### Option to highlight tags\n\n * `g:tags_options.auto_highlight` boolean option that tells to automatically\n   highlight tags with `TagsGroup` style -- which is linked to `Special` group.\n\n   Defaults to 0.\n\n   This option is best set in your `.vimrc`. If you want to change or toggle\n   its value, you'd best use the menu `Project-\u003eTags-\u003eAuto Highlight Tags` when running\n   gvim, or the `:Toggle` command:\n\n   ```vim\n   :Toggle ProjectTagsAutoHighlightTags\n   ```\n\nNotes:\n * At this point, there is a bug: the highlighting isn't propagated to all\n   buffers.\n * This feature can incur an observable slow down with current\n   non-multithreaded implementations of Vim.\n\n### Options to add tags to the list of correctly spelled words\n\n * `lh#tags#ignore_spelling()` option permits to add all the current tags to\n   Vim spellchecker ignore list. If no parameter is passed to the function, it\n   will assume the dictionary file to be named `code-symbols-spell.{enc}.add`.\n   If no file was specified in\n   [`'spellfile'`](http://vimhelp.appspot.com/options.txt.html#%27spellfile%27),\n   one is automatically added to contain words the end-user would want to\n   manually register with [`zg`](http://vimhelp.appspot.com/spell.txt.html#zg)\n   and all.\n\n * `g:tags_options.auto_spellfile_update` specifies whether spellfiles are\n   automatically generated from updated tag files:\n   - `0`    : _never_, use `CTRL-X_ts` instead.\n   - `1`    : _always_\n   - `\"all\"`: only when tags are regenerated for the whole project, never when\n            a file is saved.\n\n       Indeed, updating spellfile may be very long on some projects, and we may\n       not wish to see this task automated.\n\n * `(bg):tags_to_spellfile` has been deprecated since Version 2.0.0. Use\n   `lh#tags#ignore_spelling()` instead.\n\nNote:\n * This feature can incur an observable slow down with current\n   non-multithreaded implementations of Vim.\n\n### Tag selection (options)\n\n * `(bpg):tags_select` defaults to `'expand('\u003ccword\u003e')'`; this policy says how\n   the current word under the cursor is selected by normal mode mapping\n   `META-W-META-DOWN`.\n\n### Indexer related options\n\nSince V 3.0.0, lh-tags can support multiple indexers. At this time only\nindexers for ctags are supported. I'm likelly to eventually support _GNU\nglobal_. Any other indexer needs to be typically dropped into\n`{rtp}/autoload/lh/tags/indexers/{indexername}.vim`\n\nIf you want to contribute another indexer, check\n`autoload/lh/tags/indexers/interface.vim` and the implementation of ctags\nindexer.\n\n * `lh#tags#set_indexer(indexer [,scope])`\n\n    This function permits to change the current indexer. The indexer will be\n    binded to the specified scope (the default value is `\"p\"`).\n\n#### Options common to all indexers\n\n * (V3.0+) `(bpg):tags_options.excludes`\n   [List](http://vimhelp.appspot.com/eval.txt.html#List) of excluded patterns,\n   in `ctags` format.\n\n * (V3.0+) `(bpg):tags_options._...` and `(bpg):tags_options._.{\u0026ft}.... `\n    dictionaries of options. This is the prefered way to specify ctags\n    `--fields`, `--extra(s)` and `--kinds` parameters. The supported suboptions\n    are:\n\n    * all field names and shortcut names that can be obtained with `ctags\n      --list-field`. The plugin will try to find the best fit for each indexer\n      supported.\n    * `absolute_path` used to generate absolute path of tag locations\n    * `extract_local_variables`\n    * `extract_variables`\n    * TODO: add generic support for other kinds\n    * `recursive_or_all` used internally to work on all files of a directory\n    * `index_file` used internally to index a single file\n    * `ft` to force a filetype\n\n    Note: these options can also be injected while calling\n    `cmd_line()` method on indexers.\n\n    Indexers other than _ctags_ indexer are expected to translate the possible\n    values to something they could understand.\n\n#### Options specific to the ctags indexer\n\n * `(bpg):tags_executable` defaults to `\"ctags\"`; you should not need to change\n   it unless you want to play with different flavours of ctags installed on a\n   same system.\n\n * `(bpg):tags_must_go_recursive` defaults to 1; set it to 0 if you really want\n   to not explore subdirectories.\n\n * `g:tags_options.explicit_cmdline'` -- default: 0;\n    Tells to not rely on implicit options when indexing files. For instance,\n    many _fields_ are enabled or disabled by default with ctags; this options\n    will procude command line 100% explicit about which fields should produced,\n    or ignored.\n\n * `(wbpg):tags_options.flags` defaults to an empty string; It contains extra\n   flags you could pass to `ctags` execution. You may have to adjust these\n   options to your needs. Note that most options are already covered by the\n   indexer generic options: `(bpg):tags_options._...` and\n   `(bpg):tags_options._.{\u0026ft}....`.\n\n * (V2.0+) `(wbpg):tags_options.{ft}.flags` defaults to nothing since Version 3.0.\n   It can be  used to set anything specific to a filetype, yet prefer the new\n   dedicated interface to specify ctags `--fields`, `--extra(s)` and `--kinds`\n   parameters.\n\n   Note: This was renamed from `(bg):tags_options_{ft}` in version 2.0.0.\n\n### Other options\n * `(bpg):tags_options.no_auto` defaults to 1; set it to 0 if you want to enable the\n   automatic incremental update. IOW, if you want incremental update, force\n   this option to 0.\n   Note: this has changed in version 2.0.0; it used to be named\n   `(bg):LHT_no_auto`, and it had the opposite default value.\n\n * `g:tags_options.run_in_bg` ; set to 1 by default, if\n   |[+job](http://vimhelp.appspot.com/various.txt.html#%2bjob)|s are supported.\n   Tells to execute `\u003cPlug\u003eCTagsUpdateCurrent` and `\u003cPlug\u003eCTagsUpdateAll` in\n   background (through\n   |[+job](http://vimhelp.appspot.com/various.txt.html#%2bjob)| feature).\n\n   This option is best set in your `.vimrc`. If you want to change or toggle\n   its value, you'd best use the menu `Project-\u003eTags-\u003eGenerate` when running\n   gvim, or the `:Toggle` command:\n\n   ```vim\n   :Toggle ProjectTagsGenerate\n   ```\n\n  * `lh#tags#update_tagfiles()` instructs the plugin to automatically set\n   `'tags'` with the current tagfile.\n   This may be deprecated in the future for something less cumbersome to use.\n\n### Example\n\nA typical configuration file for\n[local_vimrc](http://github.com/LucHermitte/local_vimrc) will be:\n\n```vim\n\" #### In _vimrc_local.vim\n\n\" Define the project\nProject --define FooBar\n\n...\n\" ======================[ tags generation {{{2\n\n\" Be sure tags are automatically updated on the current file\nLetIfUndef p:tags_options.no_auto 0\n\n\" Declare the indexed filetypes\ncall lh#tags#add_indexed_ft('c', 'cpp')\n\n\" Files and directories to ignore\nLetIfUndef p:tags_options.excludes = ['\"tests/*\"', 'aspecificdir']\n\n\" Update Vim \u0026tags option w/ the tag file produced for the current project\n\" (the folowing line is the only one which is required in all projects)\ncall lh#tags#update_tagfiles() \" uses b:project_sources_dir/BTW_project_config\n\n\" Register ITK/OTB extensions as C++ extensions\ncall lh#tags#set_lang_map('cpp', '+.txx')\n\n\" Instruct to ignore spelling of code constructs\ncall lh#tags#ignore_spelling()\n\n\" But automatically when a file has been saved (this is too slow on OTB!)\nLetIfUndef g:tags_options.auto_spellfile_update 'all'\n```\n\n## Mappings and commands\n\n * The tags for the current file can be explicitly updated with `CTRL-X_tc` --\n   this mappings defaults to `\u003cPlug\u003eCTagsUpdateCurrent`\n * All the tags for the current project can be explicitly updated with\n   `CTRL-X_ta` -- this mappings defaults to `\u003cPlug\u003eCTagsUpdateAll`\n * The list of words to ignore with the spellchecker can be updated on demand\n   with `CTRL-X_ts` -- bound by default to `\u003cPlug\u003eCTagsUpdateSpell`\n   This requires `lh#tags#ignore_spelling()` to have been explicitly called.\n   Otherwise nothing will be done.\n * Tags matching the current word (or selection) will be presented on\n   `META-W-META-DOWN` -- these two mappings default to `\u003cPlug\u003eCTagsSplitOpen`\n\n * We can also present the tags that match a pattern with `:LHTags` command\n   (this command supports auto-completion on tag names)\n\n## To Do\n\n * Tag selection\n     * Have behaviour similar to the one from the quickfix mode (possibility to\n       close and reopen the search window; prev\u0026next moves)\n     * Show/hide declarations -- merge declaration and definitions\n     * Pluggable filters (that will check the number of parameters, their type, etc)\n * Tag generation\n     * Get rid of `lh#tags#update_tagfiles()` is possible.\n     * Be able to specify a directory to store all spellfiles automatically.\n       `{prjroot}/spell/`, `{prjroot}/.spell/`?\n     * `g:tags_options.auto_spellfile_update` should be overridable for each\n       project.\n     * See to update spellfile in the background thanks to Python.\n     * Auto-update on other events like `CursorHold`\n * Auto-highlight tags\n     * Cache tag list generated for spell file (as long it's not generated in\n     background in another vim instance)\n     * `g:tags_options.auto_highlight` should be overridable for each project.\n     * Different highlighting for different Identifier kind (type, function,\n     variable, ...)\n     * Specify syn hl.\n     * Incrementally add/remove highlighted keywords when tags are incrementally\n     updated.\n       * And do the same for ignored words\n\n## Design Choices\n\n * 100% in Vim script language\n * [API](doc/API.md) usable from other plugins -- to extract function\n   boundaries, local variables...\n * Avoid dependencies other than [lh-vim-lib](http://github.com/LucHermitte/lh-vim-lib)\n * Support project specific settings (options may differ from one project to\n   the other)\n\n## Installation\n  * Requirements: Vim 7.2-295, [lh-vim-lib](http://github.com/LucHermitte/lh-vim-lib) v5.0.0\n  * With [vim-addon-manager](https://github.com/MarcWeber/vim-addon-manager), install lh-tags (this is the preferred method because of the dependencies)\n\n    ```vim\n    ActivateAddons lh-tags\n    ```\n\n  * or with [vim-flavor](http://github.com/kana/vim-flavor) which also supports dependencies\n\n    ```\n    flavor 'LucHermitte/lh-tags'\n    ```\n\n  * or you can clone the git repositories\n\n    ```bash\n    git clone git@github.com:LucHermitte/lh-vim-lib.git\n    git clone git@github.com:LucHermitte/lh-tags.git\n    ```\n\n  * or with Vundle/NeoBundle:\n\n    ```vim\n    Bundle 'LucHermitte/lh-vim-lib'\n    Bundle 'LucHermitte/lh-tags'\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLucHermitte%2Flh-tags","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLucHermitte%2Flh-tags","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLucHermitte%2Flh-tags/lists"}