I know zsh has a preexec hook that fires before the command is executed, but is there one that fires after the command has been initiated but before the output is displayed to the screen? I ask because I want to display something based on if there was/will be actual output.
For example:
cd dir
does not output anything
ls dir
outputs stuff
In that example, I want to display: Output:\n
before the ls directory display but not when cd
is run since it doesn't have a display. I want it to look like:
~ $: cd dir
~/dir $: ls .
Output:
total 464
drwxr-xr-x+ 55 eddie staff 1.8K May 2 11:07 .
drwxr-xr-x 6 root admin 204B Apr 22 13:48 ..
~/dir $
I don't just want to wrap cd and ls. Those were examples. I want it to be for every command.
Best Answer
There can't be any predisplay hook as the shell is not involved at all when commands output something to the terminal or any other file.
The hook would have to be in the commands run at the first writing system call made by any process or thread started by the command line to a file descriptor open to the tty device. Or you'd have to redirect the stdout and stderr of the command with some IPC mechanism (would probably have to be a pseudo-tty pair so as to minimise the impact on the command behaviour), and insert the
Output:
when something is received¹. In any case, that would be quite involved and quite intrusive.Now, not something I would do, but you could try something like:
That is, just before running a command output
Output:
and move the cursor to the right edge of the screen (so the next thing written if any would be at the start of the next line) and record the current cursor position in$pos_before
.And just before the next prompt, query the cursor position again, and if it hasn't moved, move the cursor back to the beginning of the line so the next prompt overrides that
Output:
. We disablepromptsp
as it interferes with that.¹Such a pty-based approach could be implemented with
expect
for instance: