sendkey to active tmux window - tmux

I have a tmux session called test with several windows, one for each test file. I have another tmux session with vim and the tmuxify plugin. When I tap <f8>, my .vimrc file is programmed to send the <f7> key to the the left pane in window #0 like so:
nmap <buffer> <F8> :execute "silent !tmux send-keys -t test:0.left 'F7'" <bar>:redraw!<CR>
<f7> triggers the test to be run. Works well.
However, notice the test:0.left bit. I have window #0 hardcoded in there. If I want to run the tests in window #7, for example, I first have to swap it with window #0 and then run the test.
What I'd rather do is just send the <f7> key to whatever window in the test session is currently open.
Is there a way to do this?

I consulted ye olde manual. Solution:
test:.left
Leaving the window blank defaults to the current window.

Related

In tmux, how can I move the current window in the next/previous session without specifying its name or index?

I'm currently using tmux 3.1c; I'd like to bind two keys in order to move the current window in the next/previous session. I want that the window is moved regardless the current session's name/index. The basic idea is that:
if I press e.g. C-b + some <key1>, the current window is moved in the session following the current one, without giving any further input; the window should be moved in the last position of this next session;
if I press e.g. C-b + some <key2> the current window is moved in the session before the current one, without giving any further input; the window should be moved in the last position of this previous session;
On the man pages I found some tokens which act as aliases in order to refer to windows/panes, but no tokens for sessions. I found some interesting examples also here, but no one pointed me to the result I wanted to achieve.
My guess is that in my .tmux.conf I need to set something like
bind-key <key1> move-window -t <target_for_next_session>
bind-key <key2> move-window -t <target_for_previous_session>
(and maybe target the current window somehow too for -s option). I tried to play around with those targets but with no luck. My main guess is that I need to combine the session_id variable in the FORMATS section with the -t option from bind-key, with some +1/-1 increment.
Unfortunately answers for this question always refer to session names/indexes, which are something I don't want to specify.
Thanks in advance!

tmux determine if a pane is marked

I want to create a tmux keybind which sends a set of keystrokes to the marked pane. This is convenient for implementing a hotkey that runs something so I don't have to manually focus another pane and then come back.
But I'd like for this key to not do anything if there's no marked pane present. I've looked in the manpage and found nothing obvious that I can use to check this state.
To target the marked pane you can use -t '~' or -t '{marked}'.
In this case it is simply a matter of send -t '~' <keys here>.
A more generic way to get the marked pane in your shell would be tmux display -p -t '~' '#D'.

In zsh, how to save interrupted (^C) commands to history automatically?

When a command is executed, the command is saved to history. Is there an option in zsh which automatically save the commands interrupted by Ctrl-C to history?
If you mainly want to put a command back and run another first, I would suggest using the push-line widget, which is made just for that. It puts the current command on hold and clears the command line. After running another command, the original command is automatically restored. If you want to run multiple commands, you can repeat the process. As it works on a stack, you can even put multiple commands on hold. They will be restored in reverse order.
From the zshzle(1) manpage:
push-line (^Q ESC-Q ESC-q) (unbound) (unbound)
Push the current buffer onto the buffer stack and clear the buffer. Next time the editor starts up, the buffer will be popped off the top of the buffer stack and loaded into the editing buffer.
As you can see, by default it is bound in emacs mode (bindkey -e) to ^[q, ^[Q and ^Q. That is Alt+q (or Esc, q), Alt+Shift+q (or Esc, Shift+q) and Ctrl+q. The last of which only works if the option FLOW_CONTROL is disabled (setopt noflowcontrol).
There is also the push-line-or-edit widget. It behaves the same on a primary (PS1) prompt. But on a secondary (PS2) prompt it makes the whole multi-line construct (not just the current line) editable. Just like when you pull a multi-line construct from history.

zsh: Unable to bind ^q or \M-q in vi mode

My .zshrc file contains the line
bindkey -v
I'm attempting to bind ^q or \M-q to push-line, e.g.
bindkey "^q" push-line
but for some reason it isn't working.
Running `bind key -v' confirms
"^Q" push-line
But it doesn't actually do anything. Other control- mappings, such as ^r, work fine.
I can successfully map "push-line" to "\eq", but I don't like this behavior. First of all, I never use esc- type bindings, and secondly doing so binds it to control, meta, and escape, which is overkill. (Incidentally, shouldn't it only bind all of them like that with `bindkey -m'? I never set that in my .zshrc?)
So, anybody have any idea what's going on here?
These shortcuts are used by Software flow control (wikipedia)
Ctrl+S and Ctrl+Q are used to stop and resume the output of a program.
To try it:
Run while (true) ; do echo $RANDOM ; sleep 1 ; done
Press Ctrl+S, the output stop.
Press Ctrl+Q, the output resume.
(I'm not sure the program is stopped like with Ctrl+Z, i think it is stuck by lack of outputting. Ctrl+C to kill the program.)
These shortcuts take over your shortcuts, but if you disable this flow control feature, it could work.
You can learn how to disable it in How to unfreeze after accidentally pressing Ctrl-S in a terminal? - Unix and Linux.
Try it and tell us.

How to open a new file in vim in a new window

Is there a way to open vim in a new shell window or tab? I'm used to doing $ mate file, which opens the file in a new window.
I prefer having one 'central shell' where I issue commands and edit files in other windows or tabs, as necessary. How do people normally open vim files locally?
from inside vim, use one of the following
open a new window below the current one:
:new filename.ext
open a new window beside the current one:
:vert new filename.ext
You can do so from within vim, using its own windows or tabs.
One way to go is to utilize the built-in file explorer; activate it via :Explore, or :Texplore for a tabbed interface (which I find most comfortable).
:Texplore (and :Sexplore) will also guard you from accidentally exiting the current buffer (editor) on :q once you're inside the explorer.
To toggle between open tabs, use gt or gT (next tab and previous tab, respectively).
See also Using tab pages on the vim wiki.
I use this subtle alias:
alias vim='gnome-terminal -- vim'
-x is deprecated now. We need to use -- instead
If you don't mind using gVim, you can launch a single instance, so that when a new file is opened with it it's automatically opened in a new tab in the currently running instance.
to do this you can write: gVim --remote-tab-silent file
You could always make an alias to this command so that you don't have to type so many words.
For example I use linux and bash and in my ~/.bashrc file I have:
alias g='gvim --remote-tab-silent'
so instead of doing $ mate file I do: $ g file
I'm using the following, though it's hardcoded for gnome-terminal. It also changes the CWD and buffer for vim to be the same as your current buffer and it's directory.
:silent execute '!gnome-terminal -- zsh -i -c "cd ' shellescape(expand("%:h")) '; vim' shellescape(expand("%:p")) '; zsh -i"' <cr>
Check out gVim. You can launch that in its own window.
gVim makes it really easy to manage multiple open buffers graphically.
You can also do the usual :e to open a new file, CTRL+^ to toggle between buffers, etc...
Another cool feature lets you open a popup window that lists all the buffers you've worked on.
This allows you to switch between open buffers with a single click.
To do this, click on the Buffers menu at the top and click the dotted line with the scissors.
Otherwise you can just open a new tab from your terminal session and launch vi from there.
You can usually open a new tab from terminal with CTRL+T or CTRL+ALT+T
Once vi is launched, it's easy to open new files and switch between them.

Resources