Vim execute in function behaving differently - function

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.

Related

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

printing the output of shell command from python subprocess

I am running a shell script which emits lots of line while executing...they are just status output rather than the actual output....
I want them to be displayed on a JTextArea. I am working on jython. The piece of my code looks like:
self.console=JTextArea(20,80)
cmd = "/Users/name/galaxy-dist/run.sh"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE,stderr=subprocess.PIPE, shell=True)
self.console.append(p.stdout.read())
This will wait until the command finishes and prints the output. But I want to show the realtime out put to mimic the console. Anybody have the idea ?
You're making things more complicated than they need to be. The Popen docs state the following about the stream arguments:
With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent. [my emphasis]
Therefore, if you want the subprocess' output to go to your stdout, simply leave those arguments blank:
subprocess.Popen(cmd, shell=True)
In fact, you aren't using any of the more advanced features of the Popen constructor, and this particular example doesn't need any parsing by the shell, so you can simplify it further with the subprocess.call() function:
subprocess.call(cmd)
If you still want the return code, simply set a variable equal to this call:
return_code = subprocess.call(cmd)

EMACS find-grep command switching windows

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.

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

Seeking a vim function to insert the text behind a hyperlink

I'm writing a book. I have a large notes file, with hyperlinks of interest. I'd like to be able to move the cursor over a hyperlink, execute a command, and have the text of the webpage inserted for reading, cutting, and modifying. Ideally, it would only be the readable text rather than the full HTML, but I'll take what I can get (or what I can wget, if that's the right shell function).
Surely such a thing has already been put together, but searches for "vim insert text hyperlink" and such are not very helpful. Have you seen this function?
With your mouse cursor on a hyperlink, execute
:rC-rC-aEnter
This will insert the raw contents on the following line.
To preprocess:
:r !links -dumpC-rC-aEnter
Of course, you can map this to a key:
:nnoremap <F6> :r !links -dump <C-r><C-a><CR>
Various notes:
If you have quoted urls, you might not be happy about C-rC-a because the quotes will get included. Consider doing
:se iskeyword+=/,:,.
And use C-rC-w instead. Alternatively,
:se isfname-="
allows you to use C-rC-f instead.
If you don't want to tinker with any of your settings, consider creating a function that saves and restores the value of &iskeyword or &isfname. To bring out the big gun, write a regex for URLs and use that:
func! ReadFromUrl()
let url = substitute(getline('.'), '\c\v^.*((https?|ftp|file)://[a-z0-9.:/%+()]+).*$', '\1', '')
exec 'r! links -dump "' . url . '"'
endf
command! ReadFromUrl call ReadFromUrl()
nnoremap! <F6> ReadFromUrl<CR>
Move the cursor to the hype-link, and type this command:
:exec 'r!wget -q -O- ' getline('.') ' | html2text'
It'll append the content of the hype-link after the hype-link.
To make this command work, you need install html2text.
Good luck!