Get previous command in Fish shell

67 Views Asked by At

Is there a way to get the previous command (with its parameters) in Fish shell? I.e. not its exit code/status but the actual command given.

My use case is that I'd like to know the previous command in a later command when combining them with a logical AND operator, like e.g.

first_cmd params; and my_func

That is, I'd like to use the string "first_cmd params" in my Fish function my_func.

The long story:

My actual use case is that I currently have a Fish function sr (for "say ready") like this (running on macOS):

function sr
    if test $status -eq 0
        say -v Samantha 'Operation finished';
    else
        say -v Samantha 'Operation failed';
    end
end

I use that to get an audible notification about some long-running operation finishing or failing so that I can leave some commands running in a terminal, do other stuff while waiting them to finish, and then jump back to the terminal once they're ready. For example:

docker-compose build; sr; docker-compose up

This works, but I started thinking it would be even better if the notification mentioned the command that had finished. I.e. instead of saying "Operation finished" it would say "docker-compose build finished" in the above example.

I tried this with

say -v Samantha $history[1] 'succeeded';

and

say -v Samantha (history --max 1) 'succeeded';

(which I believe are equivalent) but that of course doesn't do what I want, as history uses lines of commands and does not separate commands on the same line etc.

I guess one option could be to change my custom function to take the command as a parameter, like

sr "docker-compose build"

which would run the command and then say out the result. But if there's a way to get the previous command (as a string), that'd be a simpler change.

Other approaches to achieve what I want are of course welcome also.

1

There are 1 best solutions below

0
MJV On

As I haven't been able to find a way to do what I wished, I changed my sr function to take the command part of its message as an optional parameter.

function sr -a 'custom_message'
    set success $status

    if test -n "$custom_message"
        set cmd_name $custom_message
    else
        set cmd_name "Operation"
    end

    if test $success -eq 0
        set result "succeeded"
    else
        set result "failed"
    end

    say -v Samantha $cmd_name $result

    return $success
end

I also modified the code a bit otherwise so that it's now possible to chain the following command with an and (since I'm passing on the exit status of the first command):

docker-compose build; sr "docker compose build"; and docker-compose up
                                                 ^^^

This isn't optimal as I have to manually write the message for the function, but this might not be a big issue as I usually repeat the same kind of command chains quite often and use Fish's brilliant auto complete from history for these, so after writing this once I'll most likely get it quickly from the command history.