External output to vim buffer AFTER command completes - shell

I'm currently using gVim on Windows 7
Running a command like:
:r! racket %
I am able to successfully read in the desired output about half of the time. The rest of the time, nothing is read. It seems to be an issue with vim reading in the output before the shell execution has terminated and actually generated some output.
Any ideas?

From :help :r!
:[range]r[ead] !{cmd} Execute {cmd} and insert its standard output below
the cursor or the specified line. A temporary file is
used to store the output of the command which is then
read into the buffer. 'shellredir' is used to save
the output of the command, which can be set to include
stderr or not. {cmd} is executed like with ":!{cmd}",
any '!' is replaced with the previous command |:!|.
It could be that you need to set :help shellredir to include stderr.

Related

ITerm: Is there a way to reprint output of previous command without running it?

Of course, we can feed the output of any command to a file. Using command > /tmp/filename
Or even better use command | tee /tmp/filename to have the standard output be fed onto the terminal as well as the file name.
However, If I just executed command is there a way for ITerm to reprint the output that command already fed to console without re-running the command (example use case: command is not idempotent and I want to grep something without having to touch the mouse)
You could use the script command, which records your input + the output your commands generate.
To use it, just run script at the beginning, before you start any execution, and this will throw you in a new shell. which gets recorded in a file called typescript in your HOME folder.
Once you are done, you can exit, and then have all of the input + output in that typescript log file.

Piping not seem to work with cd | explorer in cmd

I've been learning batch scripting so I came across pipes and I/O redirection.
If this works:
tasklist | find "winword"
Why does this not:
cd | explorer
I expect this command to open explorer at current working directory as cd without any parameters outputs current directory and:
explorer %directory%
opens explorer at %directory%.
Is there something I am doing wrong here?
Open a Command Prompt window, type find "blah" and press Enter; you'll see it awaits user/keyboard/console input, which STDIN points to (press Ctrl+Z and Enter to end the prompt). Then type echo blah and press Enter; you'll notice the text blah is printed, so there is display/console output; this is pointed to by STDOUT. A pipe | takes the data at STDOUT from the left-side command and redirects it into STDIN for the right-side command.
Now type explorer into the Command Prompt window; of course an Explorer Window pops up, but what happens in the Command Prompt? right, nothing, it does not await any input at STDIN. So you can pipe to it but it will not care as it does not read at STDIN. In fact, GUI applications do generally not use STDIN and STDOUT, because these things are intended for command line applications.
Yet another example: in a Command Prompt window, type echo C:\Windows; quite obvious what will happen; then type echo C:\Windows| dir; what happens? dir returns the contents of the current directory but not of C:\Windows. Why? well, let's type dir first and see what happens: yes, dir shows the contents of the current directory, and it does not await console input; so at the right side of the pipe it receives data at STDIN but it simply doesn't care. You can try using dir "C:\some\other\folder", without and with the pipe, the output is just the same, STDIN is ignored here.
The echo/dir example also demonstrates the difference between console input (STDIN) and command line arguments or parameters: the path in the command line dir "C:\some\other\folder" is such an argument, and you cannot replace it by data from STDIN. To understand why, you need to distinguish between parse time (when the command is read and parsed by the interpreter) and run time (when the command is actually executed): arguments already have to be present at parse time, whilst STDIN is only relevant during run time, which is later. So we can say they just never meet.
This also reflects the situation with your attempt cd | explorer: the latter accepts command line arguments (which anyway need to be available before execution, so at parse time), but it doesn't care about STDIN. Also the STDOUT data from cd isn't available before execution (but only during run time), so it would arrive too late anyway...

Redirect Input and Output to and from buffer

Is it possible to redirect the input and output of a shell command to and from vim buffer?
Intended behavior is similar to the Emacs shell-command-on-region for input and redirecting the output to a buffer as emacs does. The input and output buffers are not the same.
Based on this description of shell-command-on-region:
M-| cmd <RET>
Run the shell command cmd with region contents as input; optionally replace the region with the output (shell-command-on-region).
the built-in way to run a command with the selected lines as input is :help :w_c:
:[range]w[rite] [++opt] !{cmd}
Execute {cmd} with [range] lines as standard input
(note the space in front of the '!'). [...]
and the built-in way to replace the selection with the input of a command is :help !:
:{range}![!]{filter} [!][arg] *:range!*
Filter {range} lines through the external program
{filter}. [...]
Both methods have slight alternatives, don't be afraid to scroll around when reading an help section.

Capture output of last executed command into a variable without affecting Vim and line returns

From this question: bash - automatically capture output of last executed command into a variable I used this command:
PROMPT_COMMAND='LAST="`cat /tmp/x`"; exec >/dev/tty; exec > >(tee /tmp/x)'
It works, but when I use Vim I get this:
# vim
Vim: Warning: Output is not to a terminal
Then Vim opens. But it takes a while. Is there a way to get rid of this message and the slowdown?
Also when I list dir and I echo $LAST it removes the return lines (\n). Is there a way to keep the return lines (\n)?
I think what you ask for is hard do achieve. Vim tests if the output is a terminal. The command you've provided redirects the output to the tee command. tee saves its input (which also menans: command's output) to the file and outputs it to the terminal. But vim knows nothing about it. It only knows its output is not a terminal. So it outputs warning. And from the vim's source code:
[...]
if (scriptin[0] == NULL)
ui_delay(2000L, TRUE);
TIME_MSG("Warning delay");
which means this redirection will always get you 2 seconds delay.
Also, for example, man vim command will not work with such redirections, because terminal output has some attributest (e.g. width and height) which generic file hasn't. So... it won't work.

fastest command, which accepts pipe, but generates no text on StdOut & StdErr

Which command in Windows command script (.cmd) accepts pipe (so, no error "The Process tried to write to a nonexistent pipe." generated), but generates no output itself, including output to StdErr? I need to not touch normal StdErr output (keep in mind, pipe transports only StdOut). I can't use null device, due to it's not installed in the system.
For example, command|rem generates mentioned error. But I want no error output, except generated by command, so rem is not suitable command for needed purpose.
Main aim is the script speed. So, don't offer extensive constructions, please.
should be break(or set/p= ?) as it is internal command prompt command (i.e. no external process started ) and generally do nothing.Though I suppose if you are searching for executable packed with the windows answer will be different.
The cd . command is what you are looking for. I used it to create empty files. This way, command | cd . works and echo Hello >&2 | cd . show "Hello" in the screen! This works as a filter that just blocks Stdout (interesting).

Resources