Is there a good way to start programs from gvim without losing focus? - vim

Vim has a built-in way for executing programs, namely :!start foo for Windows and :!bar & for Unix. However, the problem I have with those is that they steal focus from Vim. I'd like to launch my build & test script, and while its working and showing output in its command window never have to manually switch back to GVim.
I have thought of 3 possible solutions:
Use Auto-It/AutoHotkey to set focus back to Gvim. Unfortunately that only works in Windows and it's brittle.
Have another process watching my sourcecode, and let that process automatically launch the script when the sourecode changes. (Another process creating a new window does not steal focus). This is a bit gimmicky, as you need to hold off on writing files until you want to start the script, and sometimes write a useless change if you want to re-test even though nothing in the source changed.
Use a client-server architecture, where Vim sends the command over a socket or something similar. This is actually my preferred solution, if there is any existing cross-platform way to do it. (I would prefer not having an extra GVim instance running for this though.)
So what would be a good way to do this? I have tried AsyncCommander but unfortunately it also steals focus.

When I'm not using a nice build system like sbt that watches source code and re-builds/re-tests for me, I tend to come up with hacks like this:
:map <F9> :!touch and-go<CR><CR>
Here hitting F9 updates a file. Pick any key binding you like.
(and of course you could do the same with imap for vim's insert mode as well.)
Then all one needs is a shell script that watches this file and executes the
command that builds/tests your project. On unix, I'd just do:
while stat -c "%Y" and-go; do sleep 1; done |
stdbuf -i0 -o0 uniq -c |
while read l; do
echo build...; # Your build/test execution commands here.
done
Running that in a separate window will be neat, because your vim/gvim window will retain it's focus throughout, while you just keep hitting F9 (or whatever) and glancing at this other window to see how your build went.
If you're up to writing a windows batch script (or powershell, I don't know) version of that as well, you should be good to go.

I think this should work:
:silent! !cmd /c start /b dir
Also, start.exe does have an option to start minimized instead of with the shared/background console.
Of course, dir is to be replaced :)

Related

tmux pin to avoid scrolling

Often when I run a command that writes to stdout, and that command fails, I have to scroll up (using uncomfortable key-bindings) looking for the place where I pressed Enter, to see what the first error was (out of hundreds others, across many screens of text). This is both annoying and time-consuming. I wish there was a feature which allowed me to pin my current terminal to the place where I am now, then start the command, see only the first lines of the output (as many as fits below my cursor) and let the rest of the output be written but not displayed. In other words I would like a feature to allow me automatically scroll up to the place where I gave the command, to see the first lines of the output (where usually the origin of the failure is displayed).
I searched for it but I didn't find it. Do you know if such feature exists? Or have an idea how to implement it with some tricks or workarounds?
If you have a unique shell prompt you could bind a key to jump between shell prompts, for example something like this will make C-b S jump to the previous shell prompt then S subsequent ones:
bind S copy-mode \; send -X search-backward 'nicholas#myhost:'
bind -Tcopy-mode S send -X search-backward 'nicholas#myhost:'
Or similarly you could search for error strings if they have a recognisable prefix. If you install the tmux 3.1 release candidate, you can search for regular expressions.
Alternatively, you could use capture-pane to load the entire history into an editor with key bindings you prefer, for example:
$ tmux capturep -S- -E- -p|vim -
Or pipe to grep or whatever. Note you will need to use a temporary file for this to work with emacs.
Or try to get into the habit of teeing commands with lots of output to a file to start with.

How to execute a terminal program and perform an action when it closes in vimscript

I'd like to write a Vim command that does the following:
Make a new split.
Launch a terminal program.
Wait for the program to stop and close the split.
Read the output produced in the second step into the original buffer.
This seems like a very common work flow, but I'm having trouble getting it to work.
The problem is in steps 3 and 4. As a test I defined:
function MyExitFunction(a,b,c)
close
read blah
endfunction
Then did:
:new | call termopen('fzf>blah',{on_exit:MyExitFunction}
which does start the terminal and close the split after the program is done. The read command, however, seems to do nothing. Perhaps it reads the input into a wrong split?
What should I do to get the actual program output into my current buffer?
Note, fzf is not the actual program I'm running, but it works a bit like it.
If you have a command that cleanly outputs to stdout, then you simply need :read !<command>.
If you want interactivity, i.e. reading from stdin first, then you should probably run it inside a terminal with :vs | te and then yank the output over. Vim doesn't have a clean and easy way to interop with interactive scripts, so this is probably as good as it's gonna get.

Prevent gVim from returning control to command line (when called from Stata)

When I call gVim from Stata with shell (or equivalently with !) Stata doesn't wait for the command to finish and continues on with the .do file. I usually specify a short sleep and everything works great (discussed on the Stata mailing list here).
But sometimes the gVim call is lengthy and the length is unknown a priori. For example. I use gVim's argdo to remove headers from a folder of text files.
!gvim -c "argdo 1,3d | update" *sheet*.txt
Is there any way that I can force gVim to not return control to Stata? Or are my best options to complete this step outside the .do file or with a pause/lengthy sleep? Thanks!
Oh, I'm on Win 8 (64 bit) with gVim 7.3.
I think you would need to make this call a Stata command or the equivalent thereof.
That is, try running this separately from a do-file editor window or as wrapped up in a separate do-file.
I realise that is not an attractive solution, but in principle it seems the only one.
(sleep solutions I dislike as fudges, but I guess no one likes them on principle.)

call vi from within vim (useful for svn commit)

I am using RedHat EL 5. I use gvim 7.1 compiled using GTK. What I want is to be able to do an svn commit (which uses vi/vim) from within gvim. Currently the only problem is that I get output which is garbled.
For example, calling :!vi produces this from within gvim:
[7;1H~
[8;1H~
[9;1H~
[10;1H~
[11;1H~
[12;1H~
[13;1H~
[14;1H~
[15;1H~
[16;1H~
[
17;1H~
[18;1H~
[19;1H~
[20;1H~
[21;1H~
[22;1H~
[23;1H~
[24;1H~
[25;1H~
[26;1H~
[27;1H~
[28;1H~
[29;1H~
[30;1H~
[31
;1H~
[32;1H~
[33;1H~
[34;1H~
[35;1H~
[36;1H~
[37;1H~
[38;1H~
[39;1H~
[15;42HVIM - Vi IMproved[17;43Hversion
7.0.237[18;39Hby Bram Moolenaar et al.[19;29HVim is open source and freely distributable[21;36HHe
lp poor children in Uganda![22;28Htype :help iccf<Enter> for information [24;28Htype :q<En
ter> to exit [25;28Htype :help<Enter> or <F1> for on-line help[26;28Htyp
e :help version7<Enter> for version info[1;1H
How do I configure vi/vim/gvim to solve this problem and thereby enable my svn commits to look proper when called from gvim.
Thank you,
Nachum
Don't use vi as the command, use gvim -f instead.
The problem is that vi (or vim in a console) requires a terminal that can do stuff like move the cursor around, etc. gvim's pty is a very basic ASCII-only terminal.
Plain old vim doesn't have this issue because it just pipes the subporcess directly to your terminal, hence all of the escape sequences still work.
You can use gvim -f instead, so that a new gvim window will pop up for your commit message. (the -f prevents backgrounding) This isn't exactly what you asked for (since you get a new window) but it's the closest you can get to what you asked for without adding full terminal support to vim.
I use VCSCommand, a nice VCS wrapper that works with SVN, GIT and others. :VCSCommit or ,cc opens a new window under the current one, lets you type your message and does the actual commit on write. Sure that's one more plugin in your setup but the conveniance may be worth it. It is for me.

Use Vim to "colourize" files or input streams

This may be an odd question, but still. I use cat to display a file in bash (KDE Konsole),
cat foobar.rb
Now, I would like to use Vim to colourize that foobar.rb file according to what you would get when you start foobar.rb in Vim. Edit: But only for display purpose, on the terminal.
I am not sure this is possible, but I thought it would be neat if I could use Vim for that.
I really just want colourized keywords, and Vim has the perfect colour definitions.
So I thought combining this would be great.
Is this possible in Vim out of the box though?
One approach would be to use a library such as Pygments, which is a general purpose syntax highlighter. You could write a wrapper called ccat or something that would apply syntax highlighting to an input file and write to stdout.
If you want to page up and down in a highlighted file, you can use less with the -R switch, which passes control characters through to the terminal directly, preserving colours. So:
ccat file.rb | less -R
But at that point, you're pretty much at the capabilities of view.
I'm not sure if I understand your question correctly, but if you are only looking for a command that will give you a read-only view of the input file (like cat) but with coloured keywords, use view. view is an alternative way to start vim in read-only mode, so you have all syntax highlighting possibilities. From the vim man page:
view Start in read-only mode. You will be protected from writing
the files. Can also be done with the "-R" argument.
gvim gview
The GUI version. Starts a new window. Can also be done with
the "-g" argument.
evim eview
The GUI version in easy mode. Starts a new window. Can also
be done with the "-y" argument.
rvim rview rgvim rgview
Like the above, but with restrictions. It will not be possi-
ble to start shell commands, or suspend Vim. Can also be
done with the "-Z" argument.
I have always seen view on systems that have vim installed.
Closest is the less script that comes with vim:
cat myfile | vim -u /usr/share/vim/vim72/macros/less.vim -
Note the - argument to vim. You may need to change the vim72 to your version (and the whole path if you have it installed elsewhere)
Now, this isn't exactly what you want, because its behaviour is less-like, in that you have to press keys to make it scroll down or complete. However, they are briefer than usual vim. For example, space to scroll down; and q to quit (not :q).
You want a cat-like version; me too. But there doesn't seem to be one.
EDIT uh, there's also a vimpager project, that includes vimcat - exactly what you want. But it doesn't come with vim, and I haven't tried it yet.
vim.org: http://www.vim.org/scripts/script.php?script_id=1723
github: https://github.com/rkitover/vimpager

Resources