ctags tag address as a line number - ctags

I am creating an IDE and I wish to implement jump to definition.
I found the perfect tool for it: ctags (https://github.com/universal-ctags/ctags)
Now the only problem is that the tags file that ctags create looks something like this:
QLineNumberArea 2point56mb.py /^class QLineNumberArea(QWidget):$/;" c
I understand the format: {tagname}Tab{tagfile}Tab{tagaddress}
So from what I understand: tagname: QLineNumberArea, tagfile: 2point56mb.py and tagaddress: /^class QLineNumberArea(QWidget):$/;" c`
The tagaddress looks like gibberish but it's a vim/ex editor command that takes you to the definition.
Now from what I read on this website: https://github.com/cztchoice/ctags/wiki/Tag-Format
Under Security it states:
Specifically, these two Ex commands are allowed:
A decimal line number:
89
A search command. It is a regular expression pattern, as used by Vi, enclosed in // or ??:
/^int c;$/
?main()?
Now here comes the problem:
I need my tags file to have a line number, instead of the search command.
I tried looking the documentation for ctags (http://docs.ctags.io/en/latest/) but I couldn't find anything that would help me.
Does anyone know how make ctags give tag addresses as a line number, rather than a search command?

That documentation is only for the changes introduced by universal ctags. What you're looking for is the documentation for exuberant ctags:
−−excmd=type
Determines the type of EX command used to locate tags in the source file. [Ignored in etags mode]
Which can also be achieved with -n.

Related

Looking for an explanation of how to use PNGlitch

I have installed the Ruby environment manager rbenv, Ruby, RubyGems, and PNGlitch (on macOS). Now how do I use PNGlitch?
The best documentation I have been able to find is on this page, and here's an example of the syntax given:
How to use this library: The Simple Way
png = PNGlitch.open '/path/to/your/image.png'
png.glitch do |data|
data.gsub /\d/, 'x'
end
png.save '/path/to/broken/image.png'
png.close
Okay, great. When I insert my file paths, save that code as an .rb file, and open it, I just get:
test.rb: command not found
If I paste it directly into Terminal I get:
png = PNGlitch.open '/Users/username/Documents/testimage.png'
-bash: png: command not found
ComputerName:~ username$ png.glitch do |data|
> data.gsub /\d/, 'x'
-bash: png.glitch: command not found
-bash: data: command not found
-bash: data.gsub: command not found
ComputerName:~ username$ end
-bash: end: command not found
ComputerName:~ username$ png.save '/Users/username/Documents/testimage_glitched.png'
-bash: png.save: command not found
ComputerName:~ username$ png.close
I also tried the syntax given on this page and entered:
pnglitch /Users/username/Documents/testimage.png –filter=Sub /Users/username/Documents/testimage_glitched.png
...this resulted in getting the following message:
tried to create Proc object without a block
Usage:
pnglitch <infile> [--filter=<n>] <outfile>
Options:
-f, --filter=<n> Fix all filter types as passed value before glitching.
A number (0..4) or a type name (none|sub|up|average|paeth).
--version Show version.
-h, --help Show this screen.
↑ I guess this is the developer's idea of documentation. 🤣
Well, trying to follow that example I also did this:
pnglitch </Users/username/Documents/testimage.png> [--filter=<2>] </Users/username/Documents/testimage_glitched.png>
...but that only resulted in:
-bash: syntax error near unexpected token 2
(I chose 2 because apparently that corresponds to the "Sub" filter.)
I tried variants of this syntax as well, including omitting characters <> and [].
There must be some assumed knowledge here that I don't have. So what I would like to know is:
How can I actually use PNGlitch to glitch a PNG image?
How can I use PNGlitch to glitch all the PNG images in a folder?
Any additional advice on using different filters would also be appreciated.
Thank you.
There's a lot going on here that needs to be cleared up.
Ruby scripts need Ruby to run
You can't just paste these into bash and expect anything useful to happen.
The usual procedure is one of two variants. Either:
Create a .rb script, like example.rb
Run ruby example.rb where that's your script name at the end.
Or use the "hash-bang" method:
Create a script with #!/usr/bin/env ruby as the very first line.
Make this script executable with chmod +x example.rb
Run this script directly, ./example.rb or whatever path it has.
Note that example.rb by itself will not work unless it is in your path, hence the ./ is necessary.
Command line example syntax
Here <name> has special meaning, where it's just a way of saying name as if it had italics or special formatting. On a text-mode terminal it's not practical to add syntax like that, it's limited to ASCII in most cases, so this tradition evolved.
Within the POSIX shell > and < have special meaning, they're used to, respectively, redirect input to or from a file. For example, ls > ls.txt dumps the output of ls into a file called ls.txt, while cat < ls.txt reads in the contents of ls.txt and displays it.
Things like [name] mean optional arguments, like [--help] means the --help argument is optional.
Within the POSIX shell [ and ] have special meaning. They can be used in an if construct, but more commonly in file wildcards, like l[abc].txt means any of la.txt, lb.txt or lc.txt.
Putting this together it's possible to understand the notation used here:
pnglitch <infile> [--filter=<n>] <outfile>
Where that means infile is your "input file" argument, and outfile is your "output file" argument, and --filter is an optional argument taking n as an input.
So you call it like this:
pnglitch input.png output.png
Or with an option, like you did:
pnglitch testimage.png --filter=sub testimage_glitched.png
Though note I've used lower-case sub as that's precisely what's in the help output and following casing conventions usually matters.

Command line options to jump to search term in .txt file searched from within Xbench (and opened in EmEditor)

I am using a glossary search program called Xbench, and it allows you to use command line parameters to automatically jump to the relevant line in the file where your search term is. The developer told me to look for tips on how to achieve this with EmEditor # https://docs.xbench.net/user-guide/xbench-settings/
There, it is explained how to achieve this with Textpad and Notepad++.
See:
For example, to configure TextPad 4 for line positioning, you must
select there the Textpad executable and specify the following in
Command-Line Parameters: $filename($line,$column). Similarly, to
configure Notepad++, you must select its executable and specify the
following in Command-Line Parameters: $filename -n$line. Other text
editors will require different values for this field. Please check
your text editor’s documentation for the suitable values.
I had a look at EmEditors command line options # http://www.emeditor.org/en/howto_file_file_commandline.html, but can't figure out how to do this. Can someone help me?
Michael Beijer (technical/patent translator)
Please try this:
$filename /l $line /cl $column
If a file name contains a space, you might need to use this:
"$filename" /l $line /cl $column

Find and replace in file with script

I want to find and replace the VALUE into a xml file :
<test name="NAME" value="VALUE"/>
I have to filter by name (because there are lot of lines like that).
Is it possible ?
Thanks for you help.
Since you tagged the question "bash", I assume that you're not trying to use an XML library (although I think an XML expert might be able to give you something like an XSLT processor command that solves this question very robustly), but that you're simply interested in doing search & replace from the commandline.
I am using perl for this:
perl -pi -e 's#VALUE#replacement#g' *.xml
See perlrun man page: Very shortly put, the -p switches perl into text processing mode, -i stands for "in-place", and -e let's you specify an expression to apply to all lines of input.
Also note (if you are not too familiar with that already) that you may use other characters than # (common ones are %, a comma, etc.) that don't clash with your search & replacement strings.
There is one small caveat: perl will read & write all files given on the commandline, even those that did not change. Thus, the files' modification times will be updated even if they did not change. (I usually work around that with some more shell magic, e.g. using grep -l or grin -l to select files for perl to work on.)
EDIT: If I understand your comments correctly, you also need help with the regular expression to apply. Let me briefly suggest something like this then:
perl -pi -e 's,(name="NAME" value=)"[^"]*",\1"NEWVALUE",g' *.xml
Related: bash XHTML parsing using xpath
You can use SED:
SED 's/\(<test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/' test.xml
where test.xml is the xml document containing the given node. This is very fragile, and you can work to make it more flexible if you need to do this substitution multiple times. For instance, the current statement is case sensitive, so it won't substitute the value on a node with the name="name", but you can add a case insensitivity flag to the end of the statement, like so:
('s/\(<test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/I').
Another option would be to use XSLT, but it would require you to download an external library. It's pretty versatile, and could be a viable option for more complex modifications to an XML document.

How to embed shell snippets in doxygen documentation

When installing my package, the user should at some point type
./wand-new "`cat wandcfg_install.spell`"
Or whatever the configuration file is called. If I put this line inside \code ... \endcode, doxygen thinks it is C++ or... Anyway, the word "new" is treated as keyword. How do I avoid this is in a semantically correct way?
I think \verbatim is disqualified because it actually is code, right?
(I guess the answer is to poke that Dimitri should add support for more languages inside a code block like LaTeX listings package, or at least add an disableparse option to code in the meantime)
Doxygen, as of July 2017, does not officially support documenting Shell/Bash scripting language, not even as an extension. There is an unofficial filter called bash-doxygen. Simple to setup: only one file download and three flags adjustments:
Edit the Doxyfile to map shell files to C parser: EXTENSION_MAPPING = sh=C
Set your shell script file names pattern as Doxygen inputs, like
e.g.: FILE_PATTERNS = *.sh
Mention doxygen-bash.sed in either the INTPUT_FILTER or the
FILTER_PATTERN directive of your Doxyfile. If doxygen-bash.sed is in
your $PATH, then you can just invoke it as is, else use sed -n -f /path/to/doxygen-bash.sed --.
Please note that since it uses C language parsing, some limitations apply, as stated in the main README page of bash-doxygen, one of them, at least in my tests, that the \code {.sh} recognises shell syntax, but all lines in the code block begin with an asterisk (*), apparently as a side-effect of requiring that all Doxygen doc sections have lines starting with double-hashes (##).

How to add comments to an Exuberant Ctags config file?

What character can I use to put comments in an Exuberant Ctags .ctags file?
I would like to add comments with explanations, and perhaps to disable some regexps.
But I can't find any comment character which ctags-exuberant accepts!
I keep getting the warning:
ctags: Warning: Ignoring non-option in /home/joey/.ctags
which is better than an error, but still a little annoying.
I have tried # // /* ... */ and ; as comments, but ctags tries to parse them all!
Here is an example file with some comments which ctags will complain about:
# Add some more rules for Javascript
--langmap=javascript:+.jpp
--regex-javascript=/^[ \t]*var ([a-zA-Z_$][0-9a-zA-Z_$]*).*$/\1/v,variable/
--regex-javascript=/^[ \t]*this\.([a-zA-Z_$][0-9a-zA-Z_$]*)[ \t]*=.*$/\1/e,export/
--regex-javascript=/^[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*):.*$/\1/p,property/
--regex-javascript=/^\<function\>[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*)/\1/f,function/
# Define tags for the Coffeescript language
--langdef=coffee
--langmap=coffee:.coffee
--regex-coffee=/^class #?([a-zA-Z_$][0-9a-zA-Z_$]*)( extends [a-zA-Z_$][0-9a-zA-Z_$]*)?$/\1/c,class/
--regex-coffee=/^[ \t]*(#|this\.)([a-zA-Z_$][0-9a-zA-Z_$]*).*$/\2/e,export/
--regex-coffee=/^[ \t]*#?([a-zA-Z_$][0-9a-zA-Z_$]*):.*[-=]>.*$/\1/f,function/
--regex-coffee=/^[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*)[ \t]+=.*[-=]>.*$/\1/f,function/
--regex-coffee=/^[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*)[ \t]+=[^->\n]*$/\1/v,variable/
--regex-coffee=/^[ \t]*#?([a-zA-Z_$][0-9a-zA-Z_$]*):.*$/\1/p,property/
You can't! I looked through the source code (thanks to apt-get source). There are no checks for lines to ignore. The relevant code is in parseFileOptions() in options.c
But sometimes comments are a neccessity, so as a workaround I put a comment in as a regexp, in such as way that it is unlikely to ever match anything.
--regex-coffee=/^(COMMENT: Disable next line when using prop tag)/\1/X,XXX/
The ^ helps the match to fail quickly, whilst the ( ) wrapper is purely for visual effect.
Your comment should be a valid regexp, to avoid warnings on stderr. (That means unescaped /s must be avoided, and if you use any [ ] ( or )s they should be paired up.) See Tom's solution to avoid these restrictions.
As #joeytwiddle points out, comments are not supported by the parser, but there is a work-around.
Example .ctags file:
--regex-C=/$x/x/x/e/ The ctags parser currently doesn't support comments
--regex-C=/$x/x/x/e/ This is a work-around which works with '/' characters
--regex-C=/$x/x/x/e/ http://stackoverflow.com/questions/10973224/how-to-add-comments-to-an-exuberant-ctags-config-file
--regex-C=/$x/x/x/e/
--regex-C=/$x/x/x/e/ You can add whatever comment text you want here.
You can use '#' as the start of comment if you are using Universal-ctag(https://ctags.io).
Given that comments don't work, what about a .ctags.readme file...
For most things you don't actually need a comment, e.g. you don't really need the comment below.
# Define tags for the Coffeescript language
--langdef=coffee
--langmap=coffee:.coffee
I can see however that you might want to add comments explaining some mind bending regex, so for each line that absolutely needs it you can copy paste it into the .ctags.readme file as a markdown file:
Forgive me father for I have regexed
It was purely because I wanted some lovely coffee properties
```
--regex-coffee=/^[ \t]*#?([a-zA-Z_$][0-9a-zA-Z_$]*):.*$/\1/p,property/
```
Keeping .ctags.readme and .ctags in sync
You could have a block at the bottom of the ctags file separated with a line break, then delete this final block.
If you only have the one line break in your .ctags file this sed will delete all the lines after the line break.
Then do some grepping for the --regex lines to append the lines from .ctags.readme into .ctags.
sed -i '/^\s*$/,$d' .ctags
grep "^--regex" .ctags.readme >> .ctags

Resources