RFR: Best way to cache and rerun by default

Often when I am working I want to run some nearly one off command repeatedly, like a specific test (rather than all tests), etc. What I would love is a way to bind like ,r to prompt for the command the first time when run, and thereafter use the cached one by default. Possibly with ,R to change it.

Can you give me an example of command you want to run?

Example: go test foo -run TestBar

I will just run that one test dozens of times when doing dev on that specific bit of code, generally I would actually be running it with like tmux sendkeys (with a C-c to kill the old version if running).

From Kakoune, you want to press r to run a shell command, and see its output, in a side terminal?

What I am thinking is like ,R to use prompt to store it, then I run it with ,r

Prior to this, I was source a .kakrc.local in my project root, but now my run commands are changing more often, currently I have something like the following in my .kakrc.local

map global user r %{<esc>:w<ret>:nop %sh{tmux send-key -t +1 C-c C-c "clear && tmux clear && source env.sh && source ~/.envlocal.sh && go test yada-yada" Enter}<ret>}

Works great, kills the current running process and starts my new one. A bit ugly, but very reliable. I am just going to swap out what is in the quotes (clear && tmux clear && source env.sh && source ~/.envlocal.sh && go test yada-yada)

How about using a FIFO to communicate with the terminal. That way, it would work even without tmux.

shell-pipe-read

#!/bin/sh

pipe=shell-pipe.fifo

mkfifo $pipe
trap "rm -f $pipe" EXIT

while true; do
  sh $pipe
done

kakrc

define-command shell-pipe-send -params .. -shell-completion %{
  echo -to-file shell-pipe.fifo %arg(@)
}

define-command shell-pipe-prompt %{
  prompt -shell-completion 'shell-pipe:' 'shell-pipe-send %val(text)'
}

map global user R ': shell-pipe-prompt<ret>'
map global user r ': shell-pipe-prompt<ret><up><ret>'
1 Like

I literally facepalmed, such an obvious way to do this at a prompt, but the fifo solution is awesome, I will play with it.

If you are working with projects you can store the shell-pipe in the Git directory.

git rev-parse --absolute-git-dir

It’s a common technique to store Ctags files.

This is some dark magic right there

1 Like

@robertmeta I added an issue for you.

Usage would be:

  1. Launch a REPL with the repl command.
  2. Press R to run a command.
  3. Press r to run the last command.

Configuration:

define-command send-text-prompt %{
  prompt -shell-completion 'Send text:' 'send-text %val(text)'
}

map global user R ': send-text-prompt<ret>'
map global user r ': send-text-prompt<ret><up><ret>'
1 Like

Way more reliable than my sort of adhoc attempts.

I feel like this is not quite right, but this is really neat to think about. Hrmm…

So… after a lot of sort of – not liking my way, I hit on the way that REALLY works for my workflow, and I thought I would share.

My dev-cycle generally takes place in a tmux session, with a few panes open. Generally I am cycling on code and running it over and over and over. Right now, at my main gig, I am doing typescript (god I hate two space indents), and I generally am running little test yarn commands that change often. I run these in the bottom right pain of my active window. With that in mind, it occurred to me that really what I want to do most of the time is just “do whatever I just did again”, so I simplified a lot.

map global user r %{: nop %sh{tmux send-keys -t {bottom-right} Up Enter }<ret>} -docstring "Rerun in bottom-right"
map global user R %{: nop %sh{tmux send-keys -t {bottom-right} C-c Up Enter }<ret>} -docstring "Cancel and rerun in bottom-right"

Stupidly simple, generalized, and works great for me.

1 Like