Can ack/ag/grep print function name? - linux

Is it possible to print the function or class name in which a keyword occurs when using ack or ag? This is something I have highly desired for quite some time.
I think it would be quite tricky, as different programming languages have different ways of enclosing functions/classes.
Note that my goal right is for searching through C source code, however I would prefer a generic solution which covers more languages/syntax.

Author of ack here. No, I don't know of any greplike tool that understands anything about the text files that it's searching. It's something that people ask for all the time, but I've never even thought about implementing it.
You said "I think it would be quite tricky, as different programming languages have different ways of enclosing functions/classes." You're exactly right. Also, consider things like comments
/* void foo() */
and literal strings
printf( "void foo()" );
that would cause problems for any search tool. Neither of those instances of the string void foo() is actually a function declaration.
Check out the More Tools page on beyondgrep.com. Something like cscope might help you.

As commented by #Inian, it would be difficult to get a robust solution using ack, ag and grep as they are not aware of the grammar of the languages.
However, for my case of looking inside C source code files, I used ack with an OR condition to include lines which are starting with the function definitions. In my case, all my functions were either returning int or nothing. Hence, the following code printed out function definition lines alongwith the lines containing the KEYWORD:
ack 'KEYWORD|^void|^int'

Although none of the programs you listed currently have this functionality, Git uses language-based regexps to implement git grep -L (search within a function name). This blog post describes how it works. The current list of regexps are in the git source tree here, and can be extended as described in the blog above.
Also, ctags provides a universal way to enumerate tags from files of multiple languages, but I haven't (yet) found a way to integrate this output with git grep -L yet.

Related

Vim-Sexp - How do I move each inner form to a new line?

I have the awesome vim-sexp and vim-sexp-mappings-for-regular-people plugins installed, and I've come across a situation I'm not sure how to solve.
Suppose I have the following form:
(alimony barbara (code determinant) eclair final-countdown)
How can I transform that to:
(alimony
barbara
(code determinant)
eclair
final-countdown)
I can go ahead and insert a newline before every inner-form/element, but that is a bit tedious. There should be a way with or without the sexp plugin
This is an old question, but maybe an updated answer will help someone who comes here in the future.
You don't have to write the program mentioned by Kaz. Others have already done it. I have not tried them, but here are a few:
fipp,
cljfmt,
cljstyle,
zprint,
joker. (The last one does more than code formatting.)
As Kaz suggests, once installed, you can pipe code to a formatter using !. You can even bind this operation to a key combination. Some of the formatters offer suggestions about how to do this sort of thing.
In addition, some vim IDE plugins, such as vim-iced provide support for using an external formatter.
A productive way to get this behavior would be, rather than fighting with Vim modules and extensions, to write a Lisp program which reads S-expressions and outputs them reformatted in the desired way. To use that program out of Vim, just pipe a range of lines into it using the ! command.

Built-in help text (not html) documentation for Racket xrepl

I’m running racket as a repl (with xrepl), and I’m able to use ,doc to see some relevant documentation (almost awesome), but it fires up a web browser to see the documentation. I’d like to be able to see the docs right in the repl, similarly to how it’s presented in other repls (R, Clojure, ipython, pry, etc). Is this possible?
E.g., in Clojure’s lein repl, one can do:
user=> (doc map)
-------------------------
clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
Returns a lazy sequence consisting of the result of applying ...
It would also be great to be able to see source ((source map) in clojure), but I haven’t seen any hints of this being available.
I happen to be using Vim (with slime/tmux), so any Vim-based solution would also work, probably tied to its K built-in help.
I'm not sure this is practical given the nature of Racket documentation.
The help deliverable is HTML.
Unlike Clojure (or Emacs Lisp), Racket doesn't have doc strings in the function definition source.
Racket docs don't have a convention like the one that the first line of a doc string should be a summary (a short-version to use in situations like a list of commands or in a REPL).
You can try xrepl's ,desc <id> command. Starting in Racket 6.1.1, if the function has installed documentation, it will print a rendering of the "blue box" -- the function signature with contracts and/or types. In many cases that's all you need, say to jog your memory. However there is no text describing the item. And if there is no installed help for a function, it won't attempt to show you anything based on the function's definition source.
So for example in racket-mode for Emacs, there is a racket-describe command and it does not fire up a browser -- but it shows the full HTML help (if any) using shr in a separate Emacs buffer. If there is no help, it does try to find the source and extract a contract/type and signature to show you. But again, there is no doc string in that source, to find, much less a one-line summary to show neatly in a REPL.
There are vim fans using Racket; the ones I know are use evil-mode in Emacs and feel it's the best of both worlds. However I appreciate that's not your current workflow using multiple languages, so I'm not proposing that as the solution for you.
I put together VROD, a solution that parses the reference documentation into something that Vim can work with. This provides essentially what you can get from clojure's doc built-in help, but through Vim’s K-help. And it also does some highlighting and shows examples.
(It also happens to do auto-completion of functions.)

creating tags for a script language for easy browsing in vim

I use ctags+Vim for a lot of my projects and I really like the ability to easily browse through large chunks of code quickly.
I am also using Stata, a statistical package, which has a script language. Even though you can have routines in the code, its code tends to be series of commands that perform data and statistics operations. And the code files can be very long. So I always find myself in need of a way to browse it efficiently.
Since I use Vim, I can use marks. But I was wondering if I could use ctags to do this. That is, I want to create a tag marker which (1) won't cause a problem when I run the script (2) easy to introduce to ctags.
Because it is supposed to not break the script, it needs to be a comment. In Stata, comment lines start with * and flow comments can be made by /* ..... */.
It would be great, for example, have sections in the code, marked by comments:
* Section: Data
And ctags picks up "Data Manipulation" as the tag. So I can see a list of sections and jump to them easily without the needs for creating marks.
Is there anyway to do this? I'd appreciate any comments.
You need a way to generate a tags database for your Stata files. The format is simple, see :help tags-file-format. The default tags program, Exuberant Ctags can be extended with regular expressions (--langmap, --regex); that probably only yields an approximate parsing for complex languages, but it should suffice for custom section marks; maybe you could even directly extract interesting language keywords.

Using Emacs for big big projects

Maybe is a often repeated question here, but i can't find anything similar with the search.
The point is that i like to use Emacs for my personal projects, usually very small applications using C or python, but i was wondering how to use it also for my work, in which we have project with about 10k files of source code, so is veeeery big (actually i am using source insight, that is very nice tool, but only for windows), questions are:
Searching: Which is the most convenient way to search a string within the whole project?
Navigating throught the function: I mean something like putting the cursor over a function, define, var, and going to the definition
Refactoring
Also if you have any experience with this and want to share your thoughts i will consider it highly interesting.
Br
The "traditional" way of navigating C source files is to use "etags" to make a file called TAGS, then use ALT-. to go to functions across files.
For searching for strings in files, I usually use "grep". You could make a shell script with all the directories you want to search or something if you get tired of typing them in each time.
My projects typically live in git, so I put this together to quickly search them:
;; There's something similar (but fancier) in vc-git.el: vc-git-grep
;; -I means don't search through binary files
(defcustom git-grep-switches "--extended-regexp -I -n --ignore-case"
"Switches to pass to `git grep'."
:type 'string)
(defun git-grep (command-args)
(interactive
(list (read-shell-command "Run git-grep (like this): "
(format "git grep %s -e "
git-grep-switches)
'git-grep-history)))
(let ((grep-use-null-device nil))
(grep command-args)))
There is also the Emacs Code Browser. It makes exploring projects a lot simpler. See here and here for more information.
Regarding searches in the whole project, I find extremely useful the rgrep command.
Also, imenu is quite handy to jump to a function definition in the same file.
These are my 2p.
look to EDE from CEDET - it provide base support for projects...
ECB is too heavyweight for my taste. I have had good results with xcscope. Needless to say it doesn't help too much with Python.
http://www.emacswiki.org/emacs/CScopeAndEmacs
In addition to using TAGS as others have mentioned, I find igrep and igrep-find very useful. There is also Emacs' built in grep and grep-find, but I find their interface more clumsy.
My standard search is:
M-x igrep-find some_regexp RET ~/work_area/*.cxx
Which will look for all *.cxx files under ~/work/area, and show results matching some_regexp. Like all the search utilities, it populates a compilation-like buffer you can navigate using C-x ` (aka M-x next-error).
There are many ways that Icicles can help with projects. Likewise, Bookmark+ and even Dired+.
These libraries can help you create, organize, and manage projects, wherever their files and directories might reside. And they can help you navigate and search in various ways.
Some of the features are unique -- quite different from other approaches. I could list some of the project support here, but this is the best place to start.

How do I put strings into stringtables in MFC?

I'm trying to localize a large MFC project where all the strings are hard-coded into the source code. (It was the easiest thing to do at the time, back before we had any idea we'd expand into other markets.) I've looked at localization tools, and invariably they say to put all the strings into the .rc file first, or just assume it has been done. Of the ones I've checked, appTranslator is the only one that even hints it may be a problem, and provides a couple of convenience functions to cut down on the wordiness of the resulting source code.
Does anybody have a better idea than going through hundreds of files manually, and making the occasional mistake along the way?
Is there some sort of product out there to help?
Does anybody have experience with doing this?
It is a tedious process to be sure. I participated in an effort like this many years ago. We did it manually. You can probably write some common code that makes the loading, checking, etc all pretty clean with minimal bloat.
I don't know of any products that will do it for you.
CStrings might be your friend - using the LoadString() member.
I would either derive from CString or write some other code that encapsulates default values (their current hard-coded values probably) and other error conditions and then use that in place of the hard-coded strings.
If you prefer not to use CString, then deriving from std::string and using the global LoadString() works fine too.
as for tools:
not sure they will work for your case:
http://www.modelmakertools.com/articles/hard-coded-strings.html
apparently this tool can find all the strings in your exe files:
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx
Then you can search for them and replace.
I think writing a tool would be fairly straightforward - look for " character and then create an entry in an rc file that corresponds to the .cpp or .h file it came from. You will have a lot of culling to do, but it is a start. You can do a replace of the text, or insert comments, etc. You can use the line number and file name for the resource id/name in a #include.
I know it's too late but just for the search engine.
There is a feature of CString to initialize it from a resource ID.
CString((LPCTSTR)IDS_RESOURCE_ID)

Resources