cscope and ctag cannot find a function definition which is located in class declaration - function

I use vim + ctag + cscope when I browse C++ source code.
When I want to look up a definition of any function cscope and/or ctag produce a list of cadidates which seem to be the one.
But when I try this for a function which is defined in a class declaration in a header file, none of those two produce the list of cadidates.
When ctag and/or cscope fail like this I now know that the function definition should be in a header file. So I open the header file and find the function definition in it.
But I wonder if this is inevitable behavior of ctag and cscope.
Aren't there any way to make them(ctag and cscope) clever for this kind of cases so that I can find the definition of every function even though they are defined in a header file?
Thank you very much.
Journeyer J. Joh

I generated tag file like the one below.
ctags --langmap=C++:.inc --c++-kinds=+p --fields=+iaS --extra=+fq --sort=foldcase -R .
But it has to be corrected the way below.
ctags --langmap=C++:+.inc --c++-kinds=+p --fields=+iaS --extra=+fq --sort=foldcase -R .
from
--langmap=C++:.inc
to
--langmap=C++:+.inc
man ctags has instruction for this:
[...] to specify that only files with extensions of .c and .x are to be treated as C language files, use "--langmap=c:.c.x"; to also add files with extensions of .j as Java language files, specify "--langmap=c:.c.x,java:+.j".

Related

Sublime Text - find all instances of an html class name project-wide

I want to find all instances of a class named "validation" in all of my html files project wide. It's a very large project and a search for the word "validation" gives me hundreds of irrelevant results (js functions, css, js/css minified, other classes, functions and html page content containing the word validation, etc). It can sometimes be the second, third, or fourth class declared so searching for "class='validation" doesn't work.
Is there a way to specify that I only want results where validation is a class declared on an html block?
Yes. In the sublime menu go to Find --> Find in Files...
Then match what is in the following image.
The first thing you will want to do is consider other possibilities with how you can solve this problem. Currently, it sounds like you are only using sublime text. Have you considered trying to use a command-line tool like grep?
Here is an example of how it could be used.
I have a project called enfold-child with a bunch of frontend assets for a wordpress project. Let's say, I want to find all of my scss files with the class "home" listed in them somewhere, but I do NOT want to pull in built css files, or anything in my node_modules folder. The way i would do that is as follows:
Folder structure:
..
|build
|scss_files
|node_modules
|css_files
|style.css
grep -rnw build --exclude=*{.css} --exclude-dir=node_modules -e home
grep = handy search utility.
-r = recursive search.
-n = provide line numbers for each match
-w = Select only those lines containing matches that form whole words.
-e = match against a regular expression.
home = the expression I want to search for.
In general, the command line has most anything one could want/need to do most of the nifty operations offered by most text-editors -- such as Sublime. Becoming familiar with the command line will save you a bunch of time and headaches in the future.
In SublimeText, right-click on the folder you want to start the search from and click on Find in Folder. Make sure regex search is enabled (the .* button in the search panel) and use this regex as the search string:
class="([^"]+ )?validation[ "]
That regex will handle cases where "validation" is the only classname as well as cases where its one of several classnames (in which case it can be anywhere in the list).
If you didn't stick to double quotes, this version will work with single or double quotes:
class=['"]([^'"]+ )?validation[ '"]
If you want to use these regexes from the command line with grep, you'll need to include a -E argument for "extended regular expressions".

How to add html attributes and values for all lines quickly with vim and plugins?

My os:debian8.
uname -a
Linux debian 3.16.0-4-amd64 #1 SMP Debian 3.16.39-1+deb8u2 (2017-03-07) x86_64 GNU/Linux
Here is my base file.
home
help
variables
compatibility
modelines
searching
selection
markers
indenting
reformatting
folding
tags
makefiles
mapping
registers
spelling
plugins
etc
I want to create a html file as bellow.
home
help
variables
compatibility
modelines
searching
selection
markers
indenting
reformatting
folding
tags
makefiles
mapping
registers
spelling
plugins
etc
Every line was added href and id attributes,whose values are line content pasted .html and line content itself correspondingly.
How to add html attributes and values for all lines quickly with vim and plugins?
sed,awk,sublime text 3 are all welcomed to solve the problem.
$ sed 's:.*:&:' file
home
help
variables
compatibility
modelines
searching
selection
markers
indenting
reformatting
folding
tags
makefiles
mapping
registers
spelling
plugins
etc
if you want to do this in vi itself, no plug-in neccessary
Open the file, type : and insert this line as the command
%s:.*:&
it will make all the substitutions in the file.
sed is the best solution (simple and pretty fast here) if your are sure of the content, if not it need a bit of complexity that is better treated by awk:
awk '
{
# change special char for HTML constraint
Org = URL = HTML = $0
# sample of modification
gsub( / /, "%20", URL)
gsub( /</, "%3C", HTML)
printf( "%s\n", URL, Org, HTML)
}
' YourFile
To complete this easily in Sublime Text, without any plugins added:
Open the base file in Sublime Text
Type Ctrl+Shift+P and in the fuzzy search input type syn html to set the file syntax to HTML.
In the View menu, make sure Word Wrap is toggled off.
Ctrl+A to select all.
Ctrl+Shift+L to break selection into multi-line edit.
Ctrl+C to copy selection into clipboard as multiple lines.
Alt+Shift+W to wrap each line with a tag-- then tap a to convert the default <p> tag into an <a> tag (hit esc to quit out of any context menus that might pop up)
Type a space then href=" -- you should see this being added to every line as they all have cursors. Also you should note that Sublime has automatically closed your quotes for you, so you have href="" with the cursor between the quotes.
ctrl+v -- this is where the magic happens-- your clipboard contains every lines worth of contents, so it will paste each appropriate value into the quotes where the cursor is lying. Then you simply type .html to add the extension.
Use the right arrow to move the cursors outside of the quotes for the href attribute and follow the two previous steps to similarly add an id attribute with the intended ids pasted in.
Voila! You're done.
Multi-line editing is very powerful as you learn how to combine it with other keyboard shortcuts. It has been a huge improvement in my workflow. If you have any questions please feel free to comment and I'll adjust as needed.
With bash one-liner:
while read v; do printf '%s\n' "$v" "$v" "$v"; done < file
(OR)
while read v; do echo "$v"; done < file
Try this -
awk '{print a$1b$1c$1d}' a='' d='' file
home
help
variables
compatibility
modelines
searching
selection
markers
indenting
reformatting
folding
tags
makefiles
mapping
registers
spelling
plugins
etc
Here I have created 4 variable a,b,c & d which you can edit as per your choice.
OR
while read -r i;do echo ""$i";done < f
home
help
variables
compatibility
To execute it directly in vim:
!sed 's:.*:&:' %
In awk, no regex, no nothing, just print strings around $1s, escaping "s:
$ awk '{print "" $1 ""}' file
home
help
If you happen to have empty lines in there just add /./ before the {:
/./{print ...
list=$(cat basefile.txt)
for val in $list
do
echo ""$val"" >> newfile.html
done
Using bash, you can always make a script or type this into the command line.
This vim replacement pattern handles your base file:
s#^\s*\(.\{-}\)\s*$#\1#
^\s* matches any leading spaces, then
.\{-} captures everything after that, non-greedily — allowing
\s$ to match any trailing spaces.
This avoids giving you stuff like home .
You can also process several base files with vim at once:
vim -c 'bufdo %s#^\s*\(.\{-}\)\s*$#\1# | saveas! %:p:r.html' some.txt more.txt`
bufdo %s#^\s*\(.\{-}\)\s*$#\1# runs the replacement on each buffer loaded into vim,
saveas! %:p:r.html saves each buffer with an html extension, overwriting if necessary,
vim will open and show you the saved more.html, which you can correct as needed, and
you can use :n and :prev to visit some.html.
Something like sed’s probably best for big jobs, but this lets you tweak the conversions in vim right after it’s made them, use :u to undo, etc. Enjoy!

PanDoc: How to assign level-one Atx-style header (markdown) to the contents of html title tag

I am using PanDoc to convert a large number of markdown (.md) files to html. I'm using the following Windows command-line:
for %%i in (*.md) do pandoc -f markdown -s %%~ni.md > html/%%~ni.html
On a test run, the html looks OK, except for the title tag - it's empty. Here is an example of the beginning of the .md file:
#Topic Title
- [Anchor 1](#anchor1)
- [Anchor 2](#anchor2)
<a name="anchor1"></a>
## Anchor 1
Is there a way I can tell PanDoc to parse the
#Topic Title
so that, in the html output files, I will get:
<title>Topic Title</title>
?
There are other .md tags I'd like to parse, and I think solving this will help me solve the rest of it.
I don't believe Pandoc supports this out-of-the-box. The relevant part of the Pandoc documentation states:
Templates may contain variables. Variable names are sequences of alphanumerics, -, and _, starting with a letter. A variable name surrounded by $ signs will be replaced by its value. For example, the string $title$ in
<title>$title$</title>
will be replaced by the document title.
It then continues:
Some variables are set automatically by pandoc. These vary somewhat depending on the output format, but include metadata fields (such as title, author, and date) as well as the following:
And proceeds to list a bunch of variables (none of which are relevant to your question). However, the above quote indicates that the title variable is a metadata field. The metadata field can be defined in a pandoc_title_block, a yaml_metadata_block, or passed in as a command line option.
The docs note that:
... you may also keep the metadata in a separate YAML file and pass it to pandoc as an argument, along with your markdown files ...
So you have a couple options:
Edit each document to add metadata defining the title for each document (this could possibly be scripted).
Write your script to extract the title (perhaps a regex which looks for #header in the first line) and passes that in to Pandoc as a command line option.
If you intend to start including the metadata in new documents you create going forward, then the first option is probably the way to go. Run a script once to batch edit your documents and then your done. However, if you have no intention of adding metadata to any documents, I would consider the second option. You are already running a loop, so just get the title before calling Pandoc within your loop (although I'm not sure how to do that in a windows script).

Using mxmlc to compile as files with more than one src paths

I am using mxmlc.exe to compile my Flash project but I have two separated source files.
I noticed that I can specify more than one -compiler.library-path but it seems not OK to specify more than one -compiler.source-path parameters.
For some reasons I have to keep the src files in different folders. Is there any way I can still compile?
Thanks!
The desired command-line parameters:
mxmlc.exe src/Editor.as
-output=Editor.swf
-compiler.source-path=src1 -compiler.source-path=../src2
-compiler.library-path=libs -compiler.library-path=../libs
The += operator will append the second path to compiler.library-path, whereas the = operator will replace the value with a new one.
try this instead:
mxmlc.exe src/Editor.as
-output=Editor.swf
-compiler.source-path=src1 -compiler.source-path=../src2
-compiler.library-path+=libs -compiler.library-path=../libs
You might have to play a bit with the spacing before and after the += to get it working exactly right.

How do I make a Makefile target depend on a file that only possibly exists?

I have a set of files of the form [name].c, some of which #include an associated [name].h file. I want a makefile target that re-builds [name].o if [name].c or [name].h are modified. I tried:
$(OBJDIR)/%.o : $(SRCDIR)/%.c $(SRCDIR)/%.h
#Implementation of target omitted
However, for the .c files that don't have associated .h files, make complains on the above rule. I tried:
$(OBJDIR)/%.o : $(SRCDIR)/%.c $(wildcard $(SRCDIR)/%.h)
#Implementation of target omitted
This builds, but modifying the .h files does not trigger a rebuild. Is there some reason I can't use % in this way?
Note: I'm trying to avoid a solution that uses makedeps.pl or makefile generation (because I am not actually working with .c or .h files).
Your attempt won't work because variables and functions that appear as part of target or prerequisite lists are expanded immediately, when the makefile is read in. At that point, obviously, there's no way to know what % might expand to later, when make is trying to figure out how to build targets, so it's actually expanding the literal string <srcdir>/%.h of which presumably there is none.
One answer is to move the prerequisites to a separate rule:
$(OBJDIR)/foo.o : $(wildcard $(SRCDIR)/foo.h)
$(OBJDIR)/bar.o : $(wildcard $(SRCDIR)/bar.h)
$(OBJDIR)/baz.o : $(wildcard $(SRCDIR)/baz.h)
If you don't want to have to write this out, you can use eval to do it for you: suppose you have a variable listing the object files:
OBJECTS = foo.o bar.o baz.o
$(foreach O,$(OBJECTS),$(eval $(OBJDIR)/$O : $(wildcard $(SRCDIR)/$(O:.o=.h))))
(that might not be exactly right).
Alternatively, you can enable .SECONDEXPANSION and write:
.SECONDEXPANSION:
$(OBJDIR)/%.o : $(SRCDIR)/%.c $$(wildcard $(SRCDIR)/%.h)
#Implementation of target omitted
(note the extra $ escaping the wildcard function).