diff options
Diffstat (limited to 'ctags/man/ctags-client-tools.7.html')
-rw-r--r-- | ctags/man/ctags-client-tools.7.html | 869 |
1 files changed, 869 insertions, 0 deletions
diff --git a/ctags/man/ctags-client-tools.7.html b/ctags/man/ctags-client-tools.7.html new file mode 100644 index 0000000..1ddb80c --- /dev/null +++ b/ctags/man/ctags-client-tools.7.html @@ -0,0 +1,869 @@ +<?xml version="1.0" encoding="utf-8" ?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" /> +<title>ctags-client-tools</title> +<style type="text/css"> + +/* +:Author: David Goodger (goodger@python.org) +:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ +:Copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. + +See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to +customize this style sheet. +*/ + +/* used to remove borders from tables and images */ +.borderless, table.borderless td, table.borderless th { + border: 0 } + +table.borderless td, table.borderless th { + /* Override padding for "table.docutils td" with "! important". + The right padding separates the table cells. */ + padding: 0 0.5em 0 0 ! important } + +.first { + /* Override more specific margin styles with "! important". */ + margin-top: 0 ! important } + +.last, .with-subtitle { + margin-bottom: 0 ! important } + +.hidden { + display: none } + +.subscript { + vertical-align: sub; + font-size: smaller } + +.superscript { + vertical-align: super; + font-size: smaller } + +a.toc-backref { + text-decoration: none ; + color: black } + +blockquote.epigraph { + margin: 2em 5em ; } + +dl.docutils dd { + margin-bottom: 0.5em } + +object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { + overflow: hidden; +} + +/* Uncomment (and remove this text!) to get bold-faced definition list terms +dl.docutils dt { + font-weight: bold } +*/ + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.admonition, div.attention, div.caution, div.danger, div.error, +div.hint, div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.admonition p.admonition-title, div.hint p.admonition-title, +div.important p.admonition-title, div.note p.admonition-title, +div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title, .code .error { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +/* Uncomment (and remove this text!) to get reduced vertical space in + compound paragraphs. +div.compound .compound-first, div.compound .compound-middle { + margin-bottom: 0.5em } + +div.compound .compound-last, div.compound .compound-middle { + margin-top: 0.5em } +*/ + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em ; + margin-right: 2em } + +div.footer, div.header { + clear: both; + font-size: smaller } + +div.line-block { + display: block ; + margin-top: 1em ; + margin-bottom: 1em } + +div.line-block div.line-block { + margin-top: 0 ; + margin-bottom: 0 ; + margin-left: 1.5em } + +div.sidebar { + margin: 0 0 0.5em 1em ; + border: medium outset ; + padding: 1em ; + background-color: #ffffee ; + width: 40% ; + float: right ; + clear: right } + +div.sidebar p.rubric { + font-family: sans-serif ; + font-size: medium } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, +h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { + margin-top: 0.4em } + +h1.title { + text-align: center } + +h2.subtitle { + text-align: center } + +hr.docutils { + width: 75% } + +img.align-left, .figure.align-left, object.align-left, table.align-left { + clear: left ; + float: left ; + margin-right: 1em } + +img.align-right, .figure.align-right, object.align-right, table.align-right { + clear: right ; + float: right ; + margin-left: 1em } + +img.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left } + +.align-center { + clear: both ; + text-align: center } + +.align-right { + text-align: right } + +/* reset inner alignment in figures */ +div.align-right { + text-align: inherit } + +/* div.align-center * { */ +/* text-align: left } */ + +.align-top { + vertical-align: top } + +.align-middle { + vertical-align: middle } + +.align-bottom { + vertical-align: bottom } + +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + +p.attribution { + text-align: right ; + margin-left: 50% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.rubric { + font-weight: bold ; + font-size: larger ; + color: maroon ; + text-align: center } + +p.sidebar-title { + font-family: sans-serif ; + font-weight: bold ; + font-size: larger } + +p.sidebar-subtitle { + font-family: sans-serif ; + font-weight: bold } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font: inherit } + +pre.literal-block, pre.doctest-block, pre.math, pre.code { + margin-left: 2em ; + margin-right: 2em } + +pre.code .ln { color: grey; } /* line numbers */ +pre.code, code { background-color: #eeeeee } +pre.code .comment, code .comment { color: #5C6576 } +pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } +pre.code .literal.string, code .literal.string { color: #0C5404 } +pre.code .name.builtin, code .name.builtin { color: #352B84 } +pre.code .deleted, code .deleted { background-color: #DEB0A1} +pre.code .inserted, code .inserted { background-color: #A3D289} + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +span.section-subtitle { + /* font-size relative to parent (h1..h6 element) */ + font-size: 80% } + +table.citation { + border-left: solid 1px gray; + margin-left: 1px } + +table.docinfo { + margin: 2em 4em } + +table.docutils { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.footnote { + border-left: solid 1px black; + margin-left: 1px } + +table.docutils td, table.docutils th, +table.docinfo td, table.docinfo th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +table.docutils th.field-name, table.docinfo th.docinfo-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap ; + padding-left: 0 } + +/* "booktabs" style (no vertical lines) */ +table.docutils.booktabs { + border: 0px; + border-top: 2px solid; + border-bottom: 2px solid; + border-collapse: collapse; +} +table.docutils.booktabs * { + border: 0px; +} +table.docutils.booktabs th { + border-bottom: thin solid; + text-align: left; +} + +h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, +h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { + font-size: 100% } + +ul.auto-toc { + list-style-type: none } + +</style> +</head> +<body> +<div class="document" id="ctags-client-tools"> +<span id="ctags-client-tools-7"></span> +<h1 class="title">ctags-client-tools</h1> +<h2 class="subtitle" id="hints-for-developing-a-tool-using-ctags-command-and-tags-output">Hints for developing a tool using ctags command and tags output</h2> +<table class="docinfo" frame="void" rules="none"> +<col class="docinfo-name" /> +<col class="docinfo-content" /> +<tbody valign="top"> +<tr><th class="docinfo-name">Version:</th> +<td>5.9.0</td></tr> +<tr class="manual-group field"><th class="docinfo-name">Manual group:</th><td class="field-body">Universal Ctags</td> +</tr> +<tr class="manual-section field"><th class="docinfo-name">Manual section:</th><td class="field-body">7</td> +</tr> +</tbody> +</table> +<div class="section" id="synopsis"> +<h1>SYNOPSIS</h1> +<div class="line-block"> +<div class="line"><strong>ctags</strong> [options] [file(s)]</div> +<div class="line"><strong>etags</strong> [options] [file(s)]</div> +</div> +</div> +<div class="section" id="description"> +<h1>DESCRIPTION</h1> +<p><strong>Client tool</strong> means a tool running the ctags command +and/or reading a tags file generated by ctags command. +This man page gathers hints for people who develop client tools.</p> +</div> +<div class="section" id="pseudo-tags"> +<h1>PSEUDO-TAGS</h1> +<p><strong>Pseudo-tags</strong>, stored in a tag file, indicate how +ctags generated the tags file: whether the +tags file is sorted or not, which version of tags file format is used, +the name of tags generator, and so on. The opposite term for +pseudo-tags is <strong>regular-tags</strong>. A regular-tag is for a language +object in an input file. A pseudo-tag is for the tags file +itself. Client tools may use pseudo-tags as reference for processing +regular-tags.</p> +<p>A pseudo-tag is stored in a tags file in the same format as +regular-tags as described in tags(5), except that pseudo-tag names +are prefixed with "!_". For the general information about +pseudo-tags, see "TAG FILE INFORMATION" in tags(5).</p> +<p>An example of a pseudo tag:</p> +<pre class="literal-block"> +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +</pre> +<p>The value, "2", associated with the pseudo tag "TAG_PROGRAM_NAME", is +used in the field for input file. The description, "Derived from +Exuberant Ctags", is used in the field for pattern.</p> +<p>Universal Ctags extends the naming scheme of the classical pseudo-tags +available in Exuberant Ctags for emitting language specific +information as pseudo tags:</p> +<pre class="literal-block"> +!_{pseudo-tag-name}!{language-name} {associated-value} /{description}/ +</pre> +<p>The language-name is appended to the pseudo-tag name with a separator, "!".</p> +<p>An example of pseudo tag with a language suffix:</p> +<pre class="literal-block"> +!_TAG_KIND_DESCRIPTION!C f,function /function definitions/ +</pre> +<p>This pseudo-tag says "the function kind of C language is enabled +when generating this tags file." <tt class="docutils literal"><span class="pre">--pseudo-tags</span></tt> is the option for +enabling/disabling individual pseudo-tags. When enabling/disabling a +pseudo tag with the option, specify the tag name only +"TAG_KIND_DESCRIPTION", without the prefix ("!_") or the suffix ("!C").</p> +<div class="section" id="options-for-pseudo-tags"> +<h2>Options for Pseudo-tags</h2> +<dl class="docutils"> +<dt><tt class="docutils literal"><span class="pre">--extras=+p</span></tt> (or <tt class="docutils literal"><span class="pre">--extras=+{pseudo}</span></tt>)</dt> +<dd><p class="first">Forces writing pseudo-tags.</p> +<p class="last">ctags emits pseudo-tags by default when writing tags +to a regular file (e.g. "tags'.) However, when specifying <tt class="docutils literal"><span class="pre">-o</span> -</tt> +or <tt class="docutils literal"><span class="pre">-f</span> -</tt> for writing tags to standard output, +ctags doesn't emit pseudo-tags. <tt class="docutils literal"><span class="pre">--extras=+p</span></tt> or +<tt class="docutils literal"><span class="pre">--extras=+{pseudo}</span></tt> will force pseudo-tags to be written.</p> +</dd> +<dt><tt class="docutils literal"><span class="pre">--list-pseudo-tags</span></tt></dt> +<dd><p class="first">Lists available types of pseudo-tags and shows whether they are enabled or disabled.</p> +<p class="last">Running ctags with <tt class="docutils literal"><span class="pre">--list-pseudo-tags</span></tt> option +lists available pseudo-tags. Some of pseudo-tags newly introduced +in Universal Ctags project are disabled by default. Use +<tt class="docutils literal"><span class="pre">--pseudo-tags=...</span></tt> to enable them.</p> +</dd> +<dt><tt class="docutils literal"><span class="pre">--pseudo-tags=[+|-]names|*</span></tt></dt> +<dd><p class="first">Specifies a list of pseudo-tag types to include in the output.</p> +<p>The parameters are a set of pseudo tag names. Valid pseudo tag names +can be listed with <tt class="docutils literal"><span class="pre">--list-pseudo-tags</span></tt>. Surround each name in the set +with braces, like "{TAG_PROGRAM_AUTHOR}". You don't have to include the "!_" +pseudo tag prefix when specifying a name in the option argument for <tt class="docutils literal"><span class="pre">--pseudo-tags=</span></tt> +option.</p> +<p>pseudo-tags don't have a notation using one-letter flags.</p> +<p class="last">If a name is preceded by either the '+' or '-' characters, that +tags's effect has been added or removed. Otherwise the names replace +any current settings. All entries are included if '*' is given.</p> +</dd> +<dt><tt class="docutils literal"><span class="pre">--fields=+E</span></tt> (or <tt class="docutils literal"><span class="pre">--fields=+{extras}</span></tt>)</dt> +<dd><p class="first">Attach "extras:pseudo" field to pseudo-tags.</p> +<p>An example of pseudo tags with the field:</p> +<pre class="literal-block"> +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ extras:pseudo +</pre> +<p class="last">If the name of a normal tag in a tag file starts with "!_", a +client tool cannot distinguish whether the tag is a regular-tag or +pseudo-tag. The fields attached with this option help the tool +distinguish them.</p> +</dd> +</dl> +</div> +<div class="section" id="list-of-notable-pseudo-tags"> +<h2>List of notable pseudo-tags</h2> +<p>Running ctags with <tt class="docutils literal"><span class="pre">--list-pseudo-tags</span></tt> option lists available types +of pseudo-tags with short descriptions. This subsection shows hints +for using notable ones.</p> +<dl class="docutils"> +<dt><tt class="docutils literal">TAG_EXTRA_DESCRIPTION</tt> (new in Universal Ctags)</dt> +<dd><p class="first">Indicates the names and descriptions of enabled extras:</p> +<pre class="literal-block"> +!_TAG_EXTRA_DESCRIPTION {extra-name} /description/ +!_TAG_EXTRA_DESCRIPTION!{language-name} {extra-name} /description/ +</pre> +<p>If your tool relies on some extra tags (extras), refer to +the pseudo-tags of this type. A tool can reject the tags file that +doesn't include expected extras, and raise an error in an early +stage of processing.</p> +<p>An example of the pseudo-tags:</p> +<pre class="literal-block"> +$ ctags --extras=+p --pseudo-tags='{TAG_EXTRA_DESCRIPTION}' -o - input.c +!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/ +!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/ +!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/ +!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/ +... +</pre> +<p class="last">A client tool can know "{anonymous}", "{fileScope}", "{pseudo}", +and "{subparser}" extras are enabled from the output.</p> +</dd> +<dt><tt class="docutils literal">TAG_FIELD_DESCRIPTION</tt> (new in Universal Ctags)</dt> +<dd><p class="first">Indicates the names and descriptions of enabled fields:</p> +<pre class="literal-block"> +!_TAG_FIELD_DESCRIPTION {field-name} /description/ +!_TAG_FIELD_DESCRIPTION!{language-name} {field-name} /description/ +</pre> +<p>If your tool relies on some fields, refer to the pseudo-tags of +this type. A tool can reject a tags file that doesn't include +expected fields, and raise an error in an early stage of +processing.</p> +<p>An example of the pseudo-tags:</p> +<pre class="literal-block"> +$ ctags --fields-C=+'{macrodef}' --extras=+p --pseudo-tags='{TAG_FIELD_DESCRIPTION}' -o - input.c +!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/ +!_TAG_FIELD_DESCRIPTION input /input file/ +!_TAG_FIELD_DESCRIPTION name /tag name/ +!_TAG_FIELD_DESCRIPTION pattern /pattern/ +!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/ +!_TAG_FIELD_DESCRIPTION!C macrodef /macro definition/ +... +</pre> +<p class="last">A client tool can know "{file}", "{input}", "{name}", "{pattern}", +and "{typeref}" fields are enabled from the output. +The fields are common in languages. In addition to the common fields, +the tool can known "{macrodef}" field of C language is also enabled.</p> +</dd> +<dt><tt class="docutils literal">TAG_FILE_ENCODING</tt> (new in Universal Ctags)</dt> +<dd>TBW</dd> +<dt><tt class="docutils literal">TAG_FILE_FORMAT</tt></dt> +<dd>See also tags(5).</dd> +<dt><tt class="docutils literal">TAG_FILE_SORTED</tt></dt> +<dd>See also tags(5).</dd> +<dt><tt class="docutils literal">TAG_KIND_DESCRIPTION</tt> (new in Universal Ctags)</dt> +<dd><p class="first">Indicates the names and descriptions of enabled kinds:</p> +<pre class="literal-block"> +!_TAG_KIND_DESCRIPTION!{language-name} {kind-letter},{kind-name} /description/ +</pre> +<p>If your tool relies on some kinds, refer to the pseudo-tags of +this type. A tool can reject the tags file that doesn't include +expected kinds, and raise an error in an early stage of +processing.</p> +<p>Kinds are language specific, so a language name is always +appended to the tag name as suffix.</p> +<p>An example of the pseudo-tags:</p> +<pre class="literal-block"> +$ ctags --extras=+p --kinds-C=vfm --pseudo-tags='{TAG_KIND_DESCRIPTION}' -o - input.c +!_TAG_KIND_DESCRIPTION!C f,function /function definitions/ +!_TAG_KIND_DESCRIPTION!C m,member /struct, and union members/ +!_TAG_KIND_DESCRIPTION!C v,variable /variable definitions/ +... +</pre> +<p class="last">A client tool can know "{function}", "{member}", and "{variable}" +kinds of C language are enabled from the output.</p> +</dd> +<dt><tt class="docutils literal">TAG_KIND_SEPARATOR</tt> (new in Universal Ctags)</dt> +<dd>TBW</dd> +<dt><tt class="docutils literal">TAG_OUTPUT_EXCMD</tt> (new in Universal Ctags)</dt> +<dd>Indicates the specified type of EX command with <tt class="docutils literal"><span class="pre">--excmd</span></tt> option.</dd> +<dt><tt class="docutils literal">TAG_OUTPUT_FILESEP</tt> (new in Universal Ctags)</dt> +<dd>TBW</dd> +<dt><tt class="docutils literal">TAG_OUTPUT_MODE</tt> (new in Universal Ctags)</dt> +<dd>TBW</dd> +<dt><tt class="docutils literal">TAG_PATTERN_LENGTH_LIMIT</tt> (new in Universal Ctags)</dt> +<dd>TBW</dd> +<dt><tt class="docutils literal">TAG_PROC_CWD</tt> (new in Universal Ctags)</dt> +<dd><p class="first">Indicates the working directory of ctags during processing.</p> +<p>This pseudo-tag helps a client tool solve the absolute paths for +the input files for tag entries even when they are tagged with +relative paths.</p> +<p>An example of the pseudo-tags:</p> +<pre class="literal-block"> +$ cat tags +!_TAG_PROC_CWD /tmp/ // +main input.c /^int main (void) { return 0; }$/;" f typeref:typename:int +... +</pre> +<p class="last">From the regular tag for "main", the client tool can know the +"main" is at "input.c". However, it is a relative path. So if the +directory where ctags run and the directory +where the client tool runs are different, the client tool cannot +find "input.c" from the file system. In that case, +<tt class="docutils literal">TAG_PROC_CWD</tt> gives the tool a hint; "input.c" may be at "/tmp".</p> +</dd> +<dt><tt class="docutils literal">TAG_PROGRAM_NAME</tt></dt> +<dd>TBW</dd> +<dt><tt class="docutils literal">TAG_ROLE_DESCRIPTION</tt> (new in Universal Ctags)</dt> +<dd><p class="first">Indicates the names and descriptions of enabled roles:</p> +<pre class="literal-block"> +!_TAG_ROLE_DESCRIPTION!{language-name}!{kind-name} {role-name} /description/ +</pre> +<p class="last">If your tool relies on some roles, refer to the pseudo-tags of +this type. Note that a role owned by a disabled kind is not listed +even if the role itself is enabled.</p> +</dd> +</dl> +</div> +</div> +<div class="section" id="redundant-kinds"> +<h1>REDUNDANT-KINDS</h1> +<p>TBW</p> +</div> +<div class="section" id="multiple-languages-for-an-input-file"> +<h1>MULTIPLE-LANGUAGES FOR AN INPUT FILE</h1> +<p>Universal ctags can run multiple parsers. +That means a parser, which supports multiple parsers, may output tags for +different languages. <tt class="docutils literal">language</tt>/<tt class="docutils literal">l</tt> field can be used to show the language +for each tag.</p> +<pre class="code console literal-block"> +<span class="generic prompt">$ </span>cat /tmp/foo.html +<span class="generic output"><html> +<script>var x = 1</script> +<h1>title</h1> +</html> +</span><span class="generic prompt">$ </span>./ctags -o - --extras<span class="operator">=</span>+g /tmp/foo.html +<span class="generic output">title /tmp/foo.html /^ <h1>title<\/h1>$/;" h +x /tmp/foo.html /var x = 1/;" v +</span><span class="generic prompt">$ </span>./ctags -o - --extras<span class="operator">=</span>+g --fields<span class="operator">=</span>+l /tmp/foo.html +<span class="generic output">title /tmp/foo.html /^ <h1>title<\/h1>$/;" h language:HTML +x /tmp/foo.html /var x = 1/;" v language:JavaScript</span> +</pre> +</div> +<div class="section" id="utilizing-readtags"> +<h1>UTILIZING READTAGS</h1> +<p>See readtags(1) to know how to use readtags. This section is for discussing +some notable topics for client tools.</p> +<div class="section" id="build-filter-sorter-expressions"> +<h2>Build Filter/Sorter Expressions</h2> +<p>Certain escape sequences in expressions are recognized by readtags. For +example, when searching for a tag that matches <tt class="docutils literal"><span class="pre">a\?b</span></tt>, if using a filter +expression like <tt class="docutils literal">'(eq? $name <span class="pre">"a\?b")'</span></tt>, since <tt class="docutils literal">\?</tt> is translated into a +single <tt class="docutils literal">?</tt> by readtags, it actually searches for <tt class="docutils literal"><span class="pre">a?b</span></tt>.</p> +<p>Another problem is if a single quote appear in filter expressions (which is +also wrapped by single quotes), it terminates the expression, producing broken +expressions, and may even cause unintended shell injection. Single quotes can +be escaped using <tt class="docutils literal"><span class="pre">'"'"'</span></tt>.</p> +<p>So, client tools need to:</p> +<ul class="simple"> +<li>Replace <tt class="docutils literal">\</tt> by <tt class="docutils literal">\\</tt></li> +<li>Replace <tt class="docutils literal">'</tt> by <tt class="docutils literal"><span class="pre">'"'"'</span></tt></li> +</ul> +<p>inside the expressions. If the expression also contains strings, <tt class="docutils literal">"</tt> in the +strings needs to be replaced by <tt class="docutils literal">\"</tt>.</p> +<p>Client tools written in Lisp could build the expression using lists. <tt class="docutils literal">prin1</tt> +(in Common Lisp style Lisps) and <tt class="docutils literal">write</tt> (in Scheme style Lisps) can +translate the list into a string that can be directly used. For example, in +EmacsLisp:</p> +<div class="system-message"> +<p class="system-message-title">System Message: WARNING/2 (<tt class="docutils">ctags-client-tools.7.rst</tt>, line 308)</p> +<p>Cannot analyze code. No Pygments lexer found for "EmacsLisp".</p> +<pre class="literal-block"> +.. code-block:: EmacsLisp + + (let ((name "hi")) + (prin1 `(eq? $name ,name))) + => "(eq\\? $name "hi")" + +</pre> +</div> +<p>The "?" is escaped, and readtags can handle it. Scheme style Lisps should do +proper escaping so the expression readtags gets is just the expression passed +into <tt class="docutils literal">write</tt>. Common Lisp style Lisps may produce unrecognized escape +sequences by readtags, like <tt class="docutils literal">\#</tt>. Readtags provides some aliases for these +Lisps:</p> +<ul class="simple"> +<li>Use <tt class="docutils literal">true</tt> for <tt class="docutils literal">#t</tt>.</li> +<li>Use <tt class="docutils literal">false</tt> for <tt class="docutils literal">#f</tt>.</li> +<li>Use <tt class="docutils literal">nil</tt> or <tt class="docutils literal">()</tt> for <tt class="docutils literal">()</tt>.</li> +<li>Use <tt class="docutils literal"><span class="pre">(string->regexp</span> "PATTERN")</tt> for <tt class="docutils literal">#/PATTERN/</tt>. Use +<tt class="docutils literal"><span class="pre">(string->regexp</span> "PATTERN" <span class="pre">:case-fold</span> true)</tt> for <tt class="docutils literal">#/PATTERN/i</tt>. Notice +that <tt class="docutils literal"><span class="pre">string->regexp</span></tt> doesn't require escaping "/" in the pattern.</li> +</ul> +<p>Notice that even when the client tool uses this method, <tt class="docutils literal">'</tt> still needs to be +replaced by <tt class="docutils literal"><span class="pre">'"'"'</span></tt> to prevent broken expressions and shell injection.</p> +<p>Another thing to notice is that missing fields are represented by <tt class="docutils literal">#f</tt>, and +applying string operators to them will produce an error. You should always +check if a field is missing before applying string operators. See the +"Filtering" section in readtags(1) to know how to do this. Run "readtags -H +filter" to see which operators take string arguments.</p> +</div> +<div class="section" id="parse-readtags-output"> +<h2>Parse Readtags Output</h2> +<p>In the output of readtags, tabs can appear in all field values (e.g., the tag +name itself could contain tabs), which makes it hard to split the line into +fields. Client tools should use the <tt class="docutils literal"><span class="pre">-E</span></tt> option, which keeps the escape +sequences in the tags file, so the only field that could contain tabs is the +pattern field.</p> +<p>The pattern field could:</p> +<ul class="simple"> +<li>Use a line number. It will look like <tt class="docutils literal">number;"</tt> (e.g. <tt class="docutils literal">10;"</tt>).</li> +<li>Use a search pattern. It will look like <tt class="docutils literal"><span class="pre">/pattern/;"</span></tt> or <tt class="docutils literal"><span class="pre">?pattern?;"</span></tt>. +Notice that the search pattern could contain tabs.</li> +<li>Combine these two, like <tt class="docutils literal"><span class="pre">number;/pattern/;"</span></tt> or <tt class="docutils literal"><span class="pre">number;?pattern?;"</span></tt>.</li> +</ul> +<p>These are true for tags files using extended format, which is the default one. +The legacy format (i.e. <tt class="docutils literal"><span class="pre">--format=1</span></tt>) doesn't include the semicolons. It's +old and barely used, so we won't discuss it here.</p> +<p>Client tools could split the line using the following steps:</p> +<ul class="simple"> +<li>Find the first 2 tabs in the line, so we get the name and input field.</li> +<li>From the 2nd tab:<ul> +<li>If a <tt class="docutils literal">/</tt> follows, then the pattern delimiter is <tt class="docutils literal">/</tt>.</li> +<li>If a <tt class="docutils literal">?</tt> follows, then the pattern delimiter is <tt class="docutils literal">?</tt>.</li> +<li>If a number follows, then:<ul> +<li>If a <tt class="docutils literal">;/</tt> follows the number, then the delimiter is <tt class="docutils literal">/</tt>.</li> +<li>If a <tt class="docutils literal">;?</tt> follows the number, then the delimiter is <tt class="docutils literal">?</tt>.</li> +<li>If a <tt class="docutils literal">;"</tt> follows the number, then the field uses only line number, and +there's no pattern delimiter (since there's no regex pattern). In this +case the pattern field ends at the 3rd tab.</li> +</ul> +</li> +</ul> +</li> +<li>After the opening delimiter, find the next unescaped pattern delimiter, and +that's the closing delimiter. It will be followed by <tt class="docutils literal">;"</tt> and then a tab. +That's the end of the pattern field. By "unescaped pattern delimiter", we +mean there's an even number (including 0) of backslashes before it.</li> +<li>From here, split the rest of the line into fields by tabs.</li> +</ul> +<p>Then, the escape sequences in fields other than the pattern field should be +translated. See "Proposal" in tags(5) to know about all the escape sequences.</p> +</div> +<div class="section" id="make-use-of-the-pattern-field"> +<h2>Make Use of the Pattern Field</h2> +<p>The pattern field specifies how to find a tag in its source file. The code +generating this field seems to have a long history, so there are some pitfalls +and it's a bit hard to handle. A client tool could simply require the <tt class="docutils literal">line:</tt> +field and jump to the line it specifies, to avoid using the pattern field. But +anyway, we'll discuss how to make the best use of it here.</p> +<p>You should take the words here merely as suggestions, and not standards. A +client tool could definitely develop better (or simpler) ways to use the +pattern field.</p> +<p>From the last section, we know the pattern field could contain a line number +and a search pattern. When it only contains the line number, handling it is +easy: you simply go to that line.</p> +<p>The search pattern resembles an EX command, but as we'll see later, it's +actually not a valid one, so some manual work are required to process it.</p> +<p>The search pattern could look like <tt class="docutils literal">/pat/</tt>, called "forward search pattern", +or <tt class="docutils literal"><span class="pre">?pat?</span></tt>, called "backward search pattern". Using a search pattern means +even if the source file is updated, as long as the part containing the tag +doesn't change, we could still locate the tag correctly by searching.</p> +<p>When the pattern field only contains the search pattern, you just search for +it. The search direction (forward/backward) doesn't matter, as it's decided +solely by whether the <tt class="docutils literal"><span class="pre">-B</span></tt> option is enabled, and not the actual context. You +could always start the search from say the beginning of the file.</p> +<p>When both the search pattern and the line number are presented, you could make +good use of the line number, by going to the line first, then searching for the +nearest occurence of the pattern. A way to do this is to search both forward +and backward for the pattern, and when there is a occurence on both sides, go +to the nearer one.</p> +<p>What's good about this is when there are multiple identical lines in the source +file (e.g. the COMMON block in Fortran), this could help us find the correct +one, even after the source file is updated and the tag position is shifted by a +few lines.</p> +<p>Now let's discuss how to search for the pattern. After you trim the <tt class="docutils literal">/</tt> or +<tt class="docutils literal">?</tt> around it, the pattern resembles a regex pattern. It should be a regex +pattern, as required by being a valid EX command, but it's actually not, as +you'll see below.</p> +<p>It could begin with a <tt class="docutils literal">^</tt>, which means the pattern starts from the beginning +of a line. It could also end with an <em>unescaped</em> <tt class="docutils literal">$</tt> which means the pattern +ends at the end of a line. Let's keep this information, and trim them too.</p> +<p>Now the remaining part is the actual string containing the tag. Some characters +are escaped:</p> +<ul class="simple"> +<li><tt class="docutils literal">\</tt>.</li> +<li><tt class="docutils literal">$</tt>, but only at the end of the string.</li> +<li><tt class="docutils literal">/</tt>, but only in forward search patterns.</li> +<li><tt class="docutils literal">?</tt>, but only in backward search patterns.</li> +</ul> +<p>You need to unescape these to get the literal string. Now you could convert +this literal string to a regexp that matches it (by escaping, like +<tt class="docutils literal">re.escape</tt> in Python or <tt class="docutils literal"><span class="pre">regexp-quote</span></tt> in Elisp), and assemble it with +<tt class="docutils literal">^</tt> or <tt class="docutils literal">$</tt> if the pattern originally has it, and finally search for the tag +using this regexp.</p> +</div> +<div class="section" id="remark-about-a-previous-format-of-the-pattern-field"> +<h2>Remark: About a Previous Format of the Pattern Field</h2> +<p>In some earlier versions of Universal Ctags, the line number in the pattern +field is the actual line number minus one, for forward search patterns; or plus +one, for backward search patterns. The idea is to resemble an EX command: you +go to the line, then search forward/backward for the pattern, and you can +always find the correct one. But this denies the purpose of using a search +pattern: to tolerate file updates. For example, the tag is at line 50, +according to this scheme, the pattern field should be:</p> +<pre class="literal-block"> +49;/pat/;" +</pre> +<p>Then let's assume that some code above are removed, and the tag is now at +line 45. Now you can't find it if you search forward from line 49.</p> +<p>Due to this reason, Universal Ctags turns to use the actual line number. A +client tool could distinguish them by the <tt class="docutils literal">TAG_OUTPUT_EXCMD</tt> pseudo tag, it's +"combine" for the old scheme, and "combineV2" for the present scheme. But +probably there's no need to treat them differently, since "search for the +nearest occurence from the line" gives good result on both schemes.</p> +</div> +</div> +<div class="section" id="json-output"> +<h1>JSON OUTPUT</h1> +<p>Universal Ctags supports <a class="reference external" href="https://www.json.org/">JSON</a> (strictly +speaking <a class="reference external" href="https://jsonlines.org/">JSON Lines</a>) output format if the +ctags executable is built with <tt class="docutils literal">libjansson</tt>. JSON output goes to +standard output by default.</p> +<div class="section" id="format"> +<h2>Format</h2> +<p>Each JSON line represents a tag.</p> +<pre class="code console literal-block"> +<span class="generic prompt">$ </span>ctags --extras<span class="operator">=</span>+p --output-format<span class="operator">=</span>json --fields<span class="operator">=</span>-s input.py +<span class="generic output">{"_type": "ptag", "name": "JSON_OUTPUT_VERSION", "path": "0.0", "pattern": "in development"} +{"_type": "ptag", "name": "TAG_FILE_SORTED", "path": "1", "pattern": "0=unsorted, 1=sorted, 2=foldcase"} +... +{"_type": "tag", "name": "Klass", "path": "/tmp/input.py", "pattern": "/^class Klass:$/", "language": "Python", "kind": "class"} +{"_type": "tag", "name": "method", "path": "/tmp/input.py", "pattern": "/^ def method(self):$/", "language": "Python", "kind": "member", "scope": "Klass", "scopeKind": "class"} +...</span> +</pre> +<p>A key not starting with <tt class="docutils literal">_</tt> is mapped to a field of ctags. +"<tt class="docutils literal"><span class="pre">--output-format=json</span> <span class="pre">--list-fields</span></tt>" options list the fields.</p> +<p>A key starting with <tt class="docutils literal">_</tt> represents meta information of the JSON +line. Currently only <tt class="docutils literal">_type</tt> key is used. If the value for the key +is <tt class="docutils literal">tag</tt>, the JSON line represents a normal tag. If the value is +<tt class="docutils literal">ptag</tt>, the line represents a pseudo-tag.</p> +<p>The output format can be changed in the +future. <tt class="docutils literal">JSON_OUTPUT_VERSION</tt> pseudo-tag provides a change +client-tools to handle the changes. Current version is "0.0". A +client-tool can extract the version with <tt class="docutils literal">path</tt> key from the +pseudo-tag.</p> +<p>The JSON output format is newly designed and has no limitation found +in the default tags file format.</p> +<ul class="simple"> +<li>The values for <tt class="docutils literal">kind</tt> key are represented in long-name flags. +No one-letter is here.</li> +<li>Scope names and scope kinds have distinguished keys: <tt class="docutils literal">scope</tt> and <tt class="docutils literal">scopeKind</tt>. +They are combined in the default tags file format.</li> +</ul> +</div> +<div class="section" id="data-type-used-in-a-field"> +<h2>Data type used in a field</h2> +<p>Values for the most of all keys are represented in JSON string type. +However, some of them are represented in string, integer, and/or boolean type.</p> +<p>"<tt class="docutils literal"><span class="pre">--output-format=json</span> <span class="pre">--list-fields</span></tt>" options show What kind of data type +used in a field of JSON.</p> +<pre class="code console literal-block"> +<span class="generic prompt">$ </span>ctags --output-format<span class="operator">=</span>json --list-fields +<span class="generic prompt">#</span>LETTER NAME ENABLED LANGUAGE JSTYPE FIXED DESCRIPTION +<span class="generic output">F input yes NONE s-- no input file +... +P pattern yes NONE s-b no pattern +... +f file yes NONE --b no File-restricted scoping +... +e end no NONE -i- no end lines of various items +...</span> +</pre> +<p><tt class="docutils literal">JSTYPE</tt> column shows the data types.</p> +<dl class="docutils"> +<dt>'<tt class="docutils literal">s</tt>'</dt> +<dd>string</dd> +<dt>'<tt class="docutils literal">i</tt>'</dt> +<dd>integer</dd> +<dt>'<tt class="docutils literal">b</tt>'</dt> +<dd>boolean (true or false)</dd> +</dl> +<p>For an example, the value for <tt class="docutils literal">pattern</tt> field of ctags takes a string or a boolean value.</p> +</div> +</div> +<div class="section" id="see-also"> +<h1>SEE ALSO</h1> +<p>ctags(1), ctags-lang-python(7), ctags-incompatibilities(7), tags(5), readtags(1)</p> +</div> +</div> +</body> +</html> |