EMACS find-grep command switching windows - function

I have the following in my .emacs
(defun find-in-workspace(term)
(interactive "sSearchInWorkspace: \n")
(grep-find (concat "grep -rnH --include=\*.{c,cpp,h} --include=-e '" term "' /home/workspaces/*")))
which is just a wrapper around grep-find so that it can search all the files in my workspace.
My problem is with the grep buffer. I would like to keep my cursor in the grep buffer's window when I select items from it so that I can quickly browse through the code, but selecting a line will automatically moves my cursor to the other window, which adds up in keystrokes when I have a list of over 5 items. Is there anyway I can build this functionality into this function, or change a setting for grep-find? I've been searching but haven't found a solution.

See the functions next-error and previous-error. They leave the grep buffer, but they work from anywhere, so, for example, if you bind next-error to a convenient a key then you can keep pressing it and it will iterate over the grep buffer.

There might be some options of grep behavior, that you might find if you dig in the lisp/progmodes/grep.el from the source, but I really think it might be better and easier to have a look of GrepPlus library which bring many enhancement of emacs grep.
Otherwise you could also use occur and see how you could customize it. In occur, when you are in the match buffer, you can it C-o instead of Ret, which will show in the other buffer the match you selected, keeping your cursor in the match buffer. Difference with grep, is that it only works with opened buffer. I'm rather sure grep+ might have the equivalent. You should have a look

There are two functions for doing exactly what you want: previous-error-no-select and next-error-no-select.
Also, you may find useful next-error-follow-minor-mode.

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".

Function to open a file and navigate to a specified line number

I have the output of recursive grep (actually ag) in a buffer, which is of the form filename:linenumber: ... [match] ..., and I want to be able to go to the occurrence (file and line number) currently under the cursor. This told me that I could execute normal-mode movements, so after extracting the file:line portion, I wrote this function:
function OpenFileNewTab(name)
let l:pair=split(a:name, ":")
execute "tabnew" get(l:pair, 0)
execute "normal!" get(l:pair, 1) . "G"
endfunction
It is supposed to open the specified file in a tab and then do <lineno>G, like I am able to do manually, to go to the specified line number. However, the cursor just stays on line 1. What am I doing wrong?
This question, by title alone, would be an exact duplicate, but it talks locating symbols in other files, while I already have the locations at hand.
Edit: My mappings for grep / ag are as follows:
nnoremap <Leader>ag :execute "new \| read !ag --literal -w" "<C-r><C-w>" g:repo \| :set filetype=c<CR>
nnoremap <Leader>gf ^v2t:"zy :execute OpenFileNewTab("<C-r>z")<CR>
To get my grep / ag results, I put the cursor on the word I want to search and enter <leader>ag, then, in the new buffer, I put the cursor on a line and enter <leader>gf - it selects from the start up to the second colon and calls OpenFileNewTab.
Edit 2: I'm on Cygwin, if it is of any importance - I doubt it.
Why don't you set &grepprg to call ag ?
" according to man ag
set grepprg=ag\ --vimgrep\ $*
set grepformat=%f:%l:%c:%m
" And then (not tested)
nnoremap <Leader>ag :grep -w <c-r><c-w><cr>
As others have said in the comments, you are just trying to emulate what the quickfix windows already provides. And, we are lucky vim can call grep, and it has a variation point to let us specify which grep program we wish to use: 'grepprg'.
Use file-line plugin. Pressing Enter on a line in the quicklist will normally open that file; file-line will make any filename of the form file:line:column (and several other formats) to open file and position to line and column.
I only found this (old) thread after I posted the exact same question on vi.stackexchange: https://vi.stackexchange.com/q/39557/44764. To help anyone who comes looking, I post the best answer to my question below as an alternative to the answers already given.
The gF command, like gf, opens the file in a new tab but additionally it also positions the cursor on the line after the colon. (I note the OP defines <leader>gf so maybe vim/neovim didn't auto-define gf or gF at the time this thread was originally created.)

Trying to redirect output of a command to a variable

>> set signal_name [get_fanout abc_signal]
{xyz_blah_blah}
>> echo $signal_name
#142
>> set signal_name [get_fanout abc_signal]
{xyz_blah_blah}
>> echo $signal_name
#144
>>
I tried other stuff like catch etc, and every where, it returns #number. My goal is to be able to print the actual value instead of the number - xyz_blah_blah.
I am new to tcl. Want to understand, if this is an array or a pointer to an array or something like that. When I try the exact same thing with a different command, which returns just a value, then it works. This is a new command which returns value in parenthesis.
Please help. Thanks.
Every Tcl command produces a result value, which you capture and use by putting the call of the command in [square brackets] and putting the whole lot as part of an argument to another command. Thus, in:
set signal_name [get_fanout abc_signal]
the result of the call to get_fanout is used as the second argument to set. I suggest that you might also like to try doing this:
puts "-->[get_fanout abc_signal]<--"
It's just the same, except this time we're concatenating it with some other small string bits and printing the whole lot out. (In case you're wondering, the result of puts itself is always the empty string if there isn't an error, and set returns the contents of the variable.)
If that is still printing the wrong value (as well as the right one beforehand, without arrow marks around it) the real issue may well be that get_fanout is not doing what you expect. While it is possible to capture the standard output of a command, doing so is a considerably more advanced technique; it is probably better to consider whether there is an alternate mechanism to achieve what you want. (The get_fanout command is not a standard part of the Tcl language library or any very common add-on library like Tk or the Tcllib collection, so we can only guess at its behavior.)

Vim execute in function behaving differently

I am playing around with a small Vim function that will highlight whitespace.
But the execute command is behaving differently than when its called directly.
So the function looks like this:
function! ShowWhitespace()
execute "/\\s\\+$"
endfunction
And it is mapped as:
command! SW call ShowWhitespace()
When :SW is executed it simply searches and gets the cursor to where whitespace exists.
However, when I do this in the command line:
:exe "/\\s\\+$"
It highlights correctly the whitespace. I am also making sure that highlightsearch is always on, so this is not an issue of having it on or off.
As a side note, I need to have this in a function because I want to have other things that have not yet been added to it for flexibility (like toggling for example).
Why would this behave differently in a function than executing it directly? I've written a wealth of functions in Vim and never seen this work different.
EDIT & Solution:
So it seems Vim doesn't like having functions altering searches. As soon as a function exits the search patterns are cleared (as pointed out by :help function-search-undo.
This might look ugly but does what I was looking to do in the first place:
command! -bang Ws let orig_line = line('.') | exe ((<bang>0)?":set hls!":":set hls") | exe '/\s\+$' | exe orig_line
Explained bit by bit:
Maps the (bang-accepting) Ws command to the following actions:
saves the original line where cursor is located
depending on bang or no bang (e.g. :Ws! or :Ws) it sets highlightsearch
Executes the search to find whitespace
Goes back to the original line if it changed
If you don't wish to move the cursor (and never do it), just set #/ to the correct search pattern, i.e.:
let #/ = '\s\+$'
NB: the function should have moved the cursor.

MySQL the command line and pagers

I cant find anything about this from searching here.
I use mysql on the command line at work and I work with fairly large tables so I set the mysql pager allowing a more readable result if I run a query, that returns 1000's of results. I use the command below to set the pager.
\P less -Sin
This suits my needs but has left me wondering if there are any more pager styles that mysql uses on the command line.
The MySQL client just passes its output to whatever command you specify with \P (for "Pager").
-Sin are commandline switches to the program less. From man less:
-i Causes searches to ignore case
-n Suppresses line numbers
-S Causes lines longer than the screen width to be chopped rather than folded.
For more options of the MySQL client, see reference.
mysql> pager less
PAGER set to 'less'
You might want to try pspg:
Unix pager designed for work with tables. Designed for PostgreSQL, but MySQL is supported too.
Main target
possibility to freeze first few rows, first few columns
possibility to use fancy colors - like mcview or FoxPro
In action:
This post is old, but still very helpful.
You can set the pager to whatever you want, including a script that parses all output before feeding it back to you. The examples there include using an add-on tool that makes EXPLAIN output more readable.
Also note that to turn off this functionality and return to normal stdout the command is nopager.
If you don't like less you can use more :)
\P more