Ctags: How to parse the tagname and kind from output of ctags -R -x

Created on 12 Mar 2019  ·  8Comments  ·  Source: universal-ctags/ctags


The name of the parser: any one

The command line you used to run ctags:

$ ctags --options=NONE -R -x

The content of input file:

$ git clone https://github.com/liuchengxu/vista.vim
$ cd vista.vim
$ ctags --options=NONE -R -x

The tags output you are not satisfied with:

I have no idea how to parse the output of ctags -R -x. I want to filter the tagname and scope from the output of ctags -R -x, but don't know how to do properly.

The tags output you expect:

It's viable if there is also a specific format for ctags -R:

{tagname}<Tab>{tagfile}<Tab>{tagaddress}[;"<Tab>{tagfield}..]

The version of ctags:

$ ctags --version
Universal Ctags 0.0.0(1208e45), Copyright (C) 2015 Universal Ctags Team
Universal Ctags is derived from Exuberant Ctags.
Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
  Compiled: Mar 11 2019, 17:01:27
  URL: https://ctags.io/
  Optional compiled features: +wildcards, +regex, +iconv, +option-directory, +xpath, +case-insensitive-filenames, +packcc

How do you get ctags binary:

brew install ctags on macOS

All 8 comments

I don't understand your question.

Are you satisfied with the output of ctags -R? If yes, why don't you use -x option?
I would like to know the background of the use case more to answer your question.

I don't know vim script. However, as far as reading vim.c, the vim parser of ctags, it doesn't fill scope fields. If you think it is a bug, tell us the vim parser fills scope field for what kind of input.

Sorry for not making it clear.

why use -x option?

Although ctags -R would meet my need, I don't want to the generate the tag file, so I use the -x option.

my use case.

Currently vista.vim only supports show the tags in some file, but some users would like to show all the tags in a project(https://github.com/liuchengxu/vista.vim/issues/14). I tried to add ctags -R support, but don't know how to extract these output correctly.

In a word, how to extract vista#util#Trim, function, 18, autoload/vista/util.vim, vista#util#Trim(str) respectively?

ctags -R -x:

...
vista#util#Trim  function     18 autoload/vista/util.vim function! vista#util#Trim(str)
vista#util#Truncate function     13 autoload/vista/util.vim function! vista#util#Truncate(msg) abort
vista#util#Warning function     90 autoload/vista/util.vim function! vista#util#Warning(msg) abort
vista#viewer#Display function     90 autoload/vista/viewer.vim function! vista#viewer#Display(data) abort
vista#viewer#Render function     86 autoload/vista/viewer.vim function! vista#viewer#Render(data) abort
vista#viewer#prefixes function     94 autoload/vista/viewer.vim function! vista#viewer#prefixes() abort

With -o - option, ctags emits the output to stdout like:

[yamato@slave]/tmp/vista.vim% u-ctags -R -o - | head 
/   ftplugin/vista.vim  /^nnoremap <buffer> <silent> \/    :<c-u>call vista#finder#fzf#Run()<CR>$/;"    m
<CR>    ftplugin/vista.vim  /^nnoremap <buffer> <silent> <CR> :<c-u>call vista#cursor#FoldOrJump()<CR>$/;"  m
Commands    README.md   /^### Commands$/;"  S
Contributing    README.md   /^## Contributing$/;"   s
Features    README.md   /^## Features$/;"   s
Installation    README.md   /^## Installation$/;"   s
Introduction    README.md   /^## Introduction$/;"   s
License README.md   /^## License$/;"    s
NeoVim  README.md   /^#### NeoVim$/;"   t
Options README.md   /^### Options$/;"   S

You can customize the output with --_xformat= option:

 u-ctags -R -x --_xformat='TAGNAME:%N @@@ KIND:%K !!! LINE:%n +++ INPUT-FILE:%F === PATTERN:%P' | head
TAGNAME:/ @@@ KIND:map !!! LINE:38 +++ INPUT-FILE:ftplugin/vista.vim === PATTERN:/^nnoremap <buffer> <silent> \/    :<c-u>call vista#finder#fzf#Run()<CR>$/
TAGNAME:<CR> @@@ KIND:map !!! LINE:37 +++ INPUT-FILE:ftplugin/vista.vim === PATTERN:/^nnoremap <buffer> <silent> <CR> :<c-u>call vista#cursor#FoldOrJump()<CR>$/
TAGNAME:Commands @@@ KIND:subsection !!! LINE:101 +++ INPUT-FILE:README.md === PATTERN:/^### Commands$/
TAGNAME:Contributing @@@ KIND:section !!! LINE:164 +++ INPUT-FILE:README.md === PATTERN:/^## Contributing$/
TAGNAME:Features @@@ KIND:section !!! LINE:37 +++ INPUT-FILE:README.md === PATTERN:/^## Features$/
TAGNAME:Installation @@@ KIND:section !!! LINE:69 +++ INPUT-FILE:README.md === PATTERN:/^## Installation$/
TAGNAME:Introduction @@@ KIND:section !!! LINE:25 +++ INPUT-FILE:README.md === PATTERN:/^## Introduction$/
TAGNAME:License @@@ KIND:section !!! LINE:168 +++ INPUT-FILE:README.md === PATTERN:/^## License$/
TAGNAME:NeoVim @@@ KIND:subsubsection !!! LINE:90 +++ INPUT-FILE:README.md === PATTERN:/^#### NeoVim$/
TAGNAME:Options @@@ KIND:subsection !!! LINE:113 +++ INPUT-FILE:README.md === PATTERN:/^### Options$/

See http://docs.ctags.io/en/latest/news.html?highlight=--_xformat#customizing-xref-output .

If you don't want to write a parser, --output-format=json can be a choice:

u-ctags -R --output-format=json | head
{"_type": "tag", "name": "/", "path": "ftplugin/vista.vim", "pattern": "/^nnoremap <buffer> <silent> \\/    :<c-u>call vista#finder#fzf#Run()<CR>$/", "kind": "map"}
{"_type": "tag", "name": "<CR>", "path": "ftplugin/vista.vim", "pattern": "/^nnoremap <buffer> <silent> <CR> :<c-u>call vista#cursor#FoldOrJump()<CR>$/", "kind": "map"}
{"_type": "tag", "name": "Commands", "path": "README.md", "pattern": "/^### Commands$/", "kind": "subsection"}
{"_type": "tag", "name": "Contributing", "path": "README.md", "pattern": "/^## Contributing$/", "kind": "section"}
{"_type": "tag", "name": "Features", "path": "README.md", "pattern": "/^## Features$/", "kind": "section"}
{"_type": "tag", "name": "Installation", "path": "README.md", "pattern": "/^## Installation$/", "kind": "section"}
{"_type": "tag", "name": "Introduction", "path": "README.md", "pattern": "/^## Introduction$/", "kind": "section"}
{"_type": "tag", "name": "License", "path": "README.md", "pattern": "/^## License$/", "kind": "section"}
{"_type": "tag", "name": "NeoVim", "path": "README.md", "pattern": "/^#### NeoVim$/", "kind": "subsubsection"}
{"_type": "tag", "name": "Options", "path": "README.md", "pattern": "/^### Options$/", "kind": "subsection"}

Thank you! I would try the --_xformat= option, since ctags installed by brew doesn't support --output-format=json by default, whether brew install ctags or brew install --HEAD universal-ctags/universal-ctags/universal-ctags .

@KazuakiM, isn't it possile to link ctags to libjansson.so.4?
u-ctags has json output mode. It is available if u-ctags is linked to libjansson.
Tell me if I should report this as a new issue on homebrew-universal-ctags repo.

@liuchengxu, tags file, the native format of ctags can be parserd with functions in readtags.c.
readtags command and python-ctags3, a python library uses readtags.c.

@masatake
Hi, homebrew-universal-ctags supportes jansson.

$ brew info universal-ctags
universal-ctags/universal-ctags/universal-ctags: HEAD
Maintained ctags implementation
https://github.com/universal-ctags/ctags
Conflicts with:
  ctags (because this formula installs the same executable as the ctags formula)
/usr/local/Cellar/universal-ctags/HEAD-1b747b3 (325 files, 4.3MB) *
  Built from source on 2019-02-02 at 16:45:17
From: https://github.com/universal-ctags/homebrew-universal-ctags/blob/master/universal-ctags.rb
==> Dependencies
Build: autoconf ✔, automake ✔, pkg-config ✔
Optional: jansson ✔, libyaml ✔
==> Options
--with-jansson
        Build with jansson support
--with-libyaml
        Build with libyaml support
--without-doc
        Compile without man pages
--without-xml
        Compile without libxml2
--HEAD
        Install HEAD version
==> Caveats
Under some circumstances, emacs and ctags can conflict. By default,
emacs provides an executable `ctags` that would conflict with the
executable of the same name that ctags provides. To prevent this,
Homebrew removes the emacs `ctags` and its manpage before linking.
However, if you install emacs with the `--keep-ctags` option, then
the `ctags` emacs provides will not be removed. In that case, you
won't be able to install ctags successfully. It will build but not
link.

@KazuakiM Good catch, I missed the help. JSON support needs the option --with-jansson.

$ brew reinstall --with-jansson universal-ctags/universal-ctags/universal-ctags
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jespinal picture jespinal  ·  8Comments

cweagans picture cweagans  ·  13Comments

JulienPivard picture JulienPivard  ·  16Comments

softinio picture softinio  ·  6Comments

cweagans picture cweagans  ·  8Comments