Compare commits

...

78 Commits

Author SHA1 Message Date
spike a62c16c8c3 add a mini sleep for slow to start shells (fish omf) 2 years ago
spike 3c0a1708dc fix pane height parameters 2 years ago
Michael van der Kamp 616fcb4799
Merge pull request #215 from mvanderkamp/issue-210-hotfix
Hotfix for issue from PR #210
2 years ago
Michael van der Kamp 2344b96fed Add a guard against queries matching current pane 2 years ago
Michael van der Kamp 076e13b77c Directly return empty string when not using existing runner
- This should have been happening anyway due to a later conditional,
      but may not if tmux changed its behaviour.
2 years ago
Michael van der Kamp 740320b798
Address #212 (#213) 2 years ago
Michael van der Kamp 3daa0e91f0
Support tmux's target-pane and target-window syntax for finding an existing runner (#210) 2 years ago
Matthias Bilger 89604a4464
Merge pull request #198 from mvanderkamp/responsive_autoclose
Allow resetting the VimuxCloseOnExit option
3 years ago
Michael van der Kamp 028897b6fb Allow resetting the VimuxCloseOnExit option
Instead of paying attention to the value when starting up, check the
option's value at close.
3 years ago
Matthias Bilger 031cc6208e
Merge pull request #202 from mvanderkamp/issue_201
Use same height and orientation arguments for opening and toggling panes
3 years ago
Samuel Walladge 853646aef3
Abort with an error if run outside tmux session (#204)
Otherwise, the command sent will run in a different and likely unexpected tmux session.
3 years ago
Michael van der Kamp 55a470dc0d Use same height and orientation arguments for opening and toggling panes 3 years ago
Michael van der Kamp a1650d5f9b
Use abort for all function declarations (#196)
See:
`:help func-abort`
`:help except-compat`
3 years ago
John Bredall ee0dfae330
Fix VimuxTogglePane (#195) 3 years ago
Caleb Maclennan ee3075ad30
ci: Test on unreleased NeoVIM development builds (#193) 3 years ago
Caleb Maclennan 96a47f7895
ci: Test on older Ubuntu flavor (has tmux 2.x) 3 years ago
Caleb Maclennan 708ce200d5
Merge pull request #190 from jaspertandy/master 3 years ago
jaspertandy a70218b30c Update documentation for g:VimuxCommandShell 3 years ago
jaspertandy 59b1d28f80 Needs no argument rather than a blank argument 3 years ago
jaspertandy 784b2834c7 Preference to allow up-arrow 3 years ago
Caleb Maclennan 29d46f6bc1
Merge pull request #189 from mvanderkamp/autoclose_option 3 years ago
Michael van der Kamp 7d977a2954 Documentation touchups 3 years ago
Michael van der Kamp c4adf57f6e Add documentation for g:VimuxCloseOnExit 3 years ago
Michael van der Kamp 54d24d1694 Add an option to autoclose the runner 3 years ago
Gerhard Hellmann 5b1791673c
Add option to expand VimuxPromptCommand arguments (#166)
Co-authored-by: Gerhard Siegesmund <gerhard.siegesmund@btd.de>
3 years ago
Caleb Maclennan 3bfe0ea285
Fix CI test step name 3 years ago
Caleb Maclennan 9dd1b68b59
Merge pull request #187 from preservim/test
Add CI workflow to actually test-drive Vimux

This is fairly primitive, but it's a start. At least we will know if a PR makes some egregious error that makes basic functionality die. In the future we should probably write some small test scripts and verify the contents of panes with some sort of content capture for true unit regression testing, but a pass/fail grade that we don't explode is better than no testing.
3 years ago
Caleb Maclennan f02fa9c161
Add CI badge for tmux + vim/nvim + vimux check 3 years ago
Caleb Maclennan fb43fcbc16
Add CI workflow to actually test-drive Vimux 3 years ago
Caleb Maclennan 1b38911c40 Disallow chaining VimuxRunCommand and VimuxPromptCommand
Fixes #185

Vim does not allow escaping some characters in commands that can be
chained. In particular bars are disallowed and double quotes begin code
comments. Both of these things are regular features in shell command
strings.

I'm disallowing chaining for the two commands that take shell commands
as arguments so they can be used sensibly again. One solution to allow
this might be to have a ...Bar version of each. It might also be
possible to work around this with `:call` and functions instead of
commands.
3 years ago
Caleb Maclennan 9214bf9578
Split PR review from branch check workflows 3 years ago
Caleb Maclennan f293536dd5
docus: Copy edit help docs with fresh link and to remove 1st person 3 years ago
Caleb Maclennan f1c27deeaa
docs: Promote usage links in readme and remove help doc specific copy 3 years ago
Caleb Maclennan cac9d11158
docs: Update dead link and copy edit readme to avoid 1st person 3 years ago
Caleb Maclennan 8cc4fe9678
Merge pull request #183 from mvanderkamp/initialize_settings 3 years ago
Caleb Maclennan f4df4c9b5b
docs: Note settings may be buffer-local 3 years ago
Caleb Maclennan 29c5b39545
Merge branch 'master' into initialize_settings 3 years ago
Caleb Maclennan 576b24c7a0
Cleanup public/private API‌ split & coding style (#184)
* feat: Make s:VimuxOption (was _VimuxOption) public VimuxOption
* refactor: Simplify script-local private function names
* style: Format each function as a paragraph with no blanks
* feat: Make s:tmuxExec (was _VimuxTmux) public VimuxTmux
3 years ago
Caleb Maclennan 992d525ef9
feat: Make s:tmuxExec (was _VimuxTmux) public VimuxTmux 3 years ago
Caleb Maclennan 566833e291
style: Format each function as a paragraph with no blanks 3 years ago
Caleb Maclennan 43681e9f91
refactor: Simplify script-local private function names 3 years ago
Caleb Maclennan 601749152e
feat: Make s:VimuxOption (was _VimuxOption) public VimuxOption 3 years ago
Michael van der Kamp b13568ea1b
Support buffer-local variants of options 3 years ago
Michael van der Kamp 748b54b885
Define options once at startup
This also removes a couple of "getter" functions that were being used to
look up options and fall back to their defaults
3 years ago
Caleb Maclennan 5f999f4dc4
Fix variable mismatch looking for previous command 3 years ago
Caleb Maclennan 3a1aad8752
style: Normalize indentation and other whitespace 3 years ago
Caleb Maclennan a2ab8880a1
Allow all commands to be used in chains (#182)
Allow all commands to be used in chains
3 years ago
Caleb Maclennan ed12df373a
Update canonical URL in readme to new org namespace 3 years ago
Caleb Maclennan efe04f05dc
Use more standard suffix for Markdown file 3 years ago
Caleb Maclennan 486ac1bd6e
Add lint badge to README 3 years ago
Caleb Maclennan 0e3ebca98b
Add CI job to run vint linter 3 years ago
Caleb Maclennan bde8b4cb37
Fix vimscript lint errors and add CI linter (#181)
* Add Vint config file for vimscript linting
* Replace underscore convention with proper script-local scopes
* Prefer single quoted strings
* Use the full option name
* Use robust operators
3 years ago
Caleb Maclennan c212352f93
Use robust operators 3 years ago
Caleb Maclennan f589e21472
Use the full option name 3 years ago
Caleb Maclennan a5a17b8e32
Prefer single quoted strings 3 years ago
Caleb Maclennan e6fb662bf1
Replace underscore convention with proper script-local scopes 3 years ago
Caleb Maclennan 925ae23b42
Add Vint config file for vimscript linting 3 years ago
Matthias Bilger 3693ec6f12
Merge pull request #180 from m42e/preserve-choosesession
Allow setting of VimuxRunner name to reuse session
3 years ago
Matthias Bilger af602e362d Allow setting of VimuxRunner name to reuse session 3 years ago
Caleb Maclennan 0f5fd2ce49
Fix typo and bump license date range, closes #154 3 years ago
Thales Mello 57bbdc4478
Enable tab autocompletion on VimuxPromptOption (#142) 3 years ago
Caleb Maclennan cce8466613
Move the cheese, because it has to move to run
As anybody following this might have divined, my testing  was flawed and
I was running different code than I was viewing.
3 years ago
Caleb Maclennan 71f28c8296
Merge pull request #174 from mvanderkamp/split-extra-args 3 years ago
Caleb Maclennan 48b541b1a4
Avoid useless space in default empty argument string 3 years ago
Philipp Moers ef5622f225
Add VimuxClearTerminalScreen (#178) 3 years ago
Caleb Maclennan 7f15726b07
Merge pull request #155 from lyuts/check_tmux_binary 3 years ago
Caleb Maclennan 9c05307141
Refactor PR code order to not move cheese
With tons of outstanding PRs I don't want to introduce conflicts for no
reason. We can refactor to make the source order more sensible later.
3 years ago
Giuseppe Rota 46377b8ab9
Escape the text sent to tmux
Closes #76
3 years ago
Thomas Mayfield 8fa6ca92c0
Update VimuxSlime example to use VimuxRunCommand (#165)
I was a little confused by the example in the VimuxTslimeReplacement 
section until I figured out that it was supposed to be calling
VimuxRunCommand, rather than VimuxSendText -> VimuxSendKeys. 
The intended call is referenced in the follow paragraph, where it 
describes passing `0` as a second arg to that call to avoid an 
unwanted extra newline.
3 years ago
Eugene Yunak 1dec7164ca
Use IDs instead of indexes to identify windows and panes (#110)
...because indexes can change while IDs are constant and unique.
3 years ago
saubhik fff2f1a686
Fix Markdown formatting in readme (#170) 3 years ago
Eugene Yunak f48360cea6
Fix docs, config variables should be global (#111) 3 years ago
Jonathan Barratt 02315b02c4
Fix typos in readme (#164) 3 years ago
Michael vanderKamp 67bd945586 Add detail about VimuxOpenExtraArgs option to docs 4 years ago
Michael vanderKamp 556a2d692b Add a VimuxOpenRunner command 4 years ago
Michael vanderKamp 3fdafcfd60 Add VimuxOpenExtraArgs option 4 years ago
lyuts 9f81329f60 Wrap tmux executable detection in a helper function.
Function encapsulates executable detection which is needed at vim
startup for checking tmux availability and during actual command
running.
7 years ago
lyuts 0a560ba419 Check tmux binary availability at startup.
Updated the plugin to:
- let override the location of tmux executable.
- check tmux executable availability.
7 years ago

@ -0,0 +1,43 @@
name: Check
on: [push, pull_request]
jobs:
check:
strategy:
fail-fast: false
matrix:
osFlavor: [ubuntu-20.04, ubuntu-18.04]
vimFlavor: [neovim, vim]
vimVersion: [stable, unstable]
exclude:
- vimFlavor: vim
vimVersion: unstable
runs-on: ${{ matrix.osFlavor }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Enable Universe package repository
run: |
sudo add-apt-repository ${{ matrix.vimVersion == 'stable' && 'universe' || 'ppa:neovim-ppa/unstable' }}
sudo apt-get update
- name: Install tmux and ${{ matrix.vimFlavor }}
run: |
sudo apt-get install tmux ${{ matrix.vimFlavor }}
- name: Review versions
run: |
tmux -V
${{ matrix.vimFlavor == 'neovim' && 'nvim' || 'vim' }} --version
# This tests looks for two thigs:
# * That VIM doesn't hang. If it succedes it will quit quickly. If 5
# seconds later the tmux session is still running either the runner pane
# didn't get closed or (more likely) we threw some error and VIM is
# sitting there expecting us to acknowledge the message(s).
# * That VIM exited normally. This check isn't very useful since :qa
# never bubbles up an error, but if someday we use :cq for a test being
# ready to check the exit code seems like a good thing.
- name: "Try Vimux"
run: |
ec="$(mktemp)"
tmux new -s ci -d "${{ matrix.vimFlavor == 'neovim' && 'nvim -u /dev/null --headless' || 'vim' }} -i NONE \"+so plugin/vimux.vim\" \"+VimuxRunCommand('date')\" \"+VimuxCloseRunner | qa\"; echo \$? > '$ec'"
sleep 5
tmux kill-session -t ci && exit 1
exit "$(cat $ec)"

@ -0,0 +1,13 @@
name: Reviewdog
on: [pull_request]
jobs:
vint:
name: vint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: vint
uses: reviewdog/action-vint@v1
with:
github_token: ${{ secrets.github_token }}
reporter: github-pr-review

@ -0,0 +1,15 @@
name: Vint
on: [push]
jobs:
vint:
name: vint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
- name: Setup dependencies
run: pip install vim-vint
- name: Lint Vimscript
run: vint .

@ -0,0 +1,5 @@
cmdargs:
severity: style_problem
color: true
env:
neovim: false

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2103 Benjamin Mills
Copyright (c) 2012-2021 Benjamin Mills
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -0,0 +1,40 @@
# Vimux: easily interact with tmux from vim
[![Vint](https://github.com/preservim/vimux/workflows/Vint/badge.svg)](https://github.com/preservim/vimux/actions?workflow=Vint)
[![Check](https://github.com/preservim/vimux/workflows/Check/badge.svg)](https://github.com/preservim/vimux/actions?workflow=Check)
![vimux](https://www.braintreepayments.com/blog/content/images/blog/vimux3.png)
Vimux was originally inspired by [tslime.vim](https://github.com/jgdavey/tslime.vim/network), a plugin that lets you send input to tmux. While tslime.vim works well, it wasn't optimized for the use case of having a smaller tmux pane used to run tests or play with a REPL. The goal of Vimux is to make interacting with tmux from vim effortless.
By default, when you call `VimuxRunCommand` vimux will create a 20% tall horizontal pane under your current tmux pane and execute a command in it without losing the focus on vim. Once that pane exists, whenever you call `VimuxRunCommand` again the command will be executed in that pane. A frequent use case is wanting to rerun commands over and over. An example of this is running the current file through rspec. Rather than typing that over and over `VimuxRunLastCommand` will execute the last command called with `VimuxRunCommand`.
## Installation
With **[vim-bundle](https://github.com/preservim/vim-bundle)**: `vim-bundle install preservim/vimux`
With **[Vundle](https://github.com/gmarik/Vundle.vim)**: `Plugin 'preservim/vimux'` in your .vimrc
Otherwise download the latest [tarball](https://github.com/preservim/vimux/tarball/master), extract it and move `plugin/vimux.vim` inside `~/.vim/plugin`. If you're using [pathogen](https://github.com/tpope/vim-pathogen), then move the entire folder extracted from the tarball into `~/.vim/bundle`.
_Notes:_
* Vimux assumes a reasonably new version of tmux. Some older versions might work but it is recommended to use the latest stable release.
## Usage
The full documentation is available [online](https://raw.github.com/preservim/vimux/master/doc/vimux.txt) and accessible inside vim via `:help vimux`
## Platform-specific Plugins
* [vim-vroom](https://github.com/skalnik/vim-vroom) runner for rspec, cucumber and test/unit; vimux support via `g:vroom_use_vimux`
* [vimux-ruby-test](https://github.com/pgr0ss/vimux-ruby-test) a set of commands to easily run ruby tests
* [vimux-cucumber](https://github.com/cloud8421/vimux-cucumber) run Cucumber Features through Vimux
* [vim-turbux](https://github.com/jgdavey/vim-turbux) Turbo Ruby testing with tmux
* [vimux-pyutils](https://github.com/julienr/vimux-pyutils) A set of functions for vimux that allow to run code blocks in ipython
* [vimux-nose-test](https://github.com/pitluga/vimux-nose-test) Run nose tests in vimux
* [vimux-golang](https://github.com/benmills/vimux-golang) Run go tests in vimux
* [vimux-zeus](https://github.com/jingweno/vimux-zeus) Run zeus commands in vimux
* [vimix](https://github.com/spiegela/vimix) Run Elixir mix commands in vimux
* [vimux-cargo](https://github.com/jtdowney/vimux-cargo) run rust tests and projects using cargo and vimux
* [vimux-bazel-test](https://github.com/pgr0ss/vimux-bazel-test) Run bazel tests in vimux
* [vimux-jest-test](https://github.com/tyewang/vimux-jest-test) Run jest tests in vimux

@ -1,41 +0,0 @@
# vimux
Easily interact with tmux from vim.
![vimux](https://www.braintreepayments.com/blog/content/images/blog/vimux3.png)
What inspired me to write vimux was [tslime.vim](https://github.com/kikijump/tslime.vim), a plugin that lets you send input to tmux. While tslime.vim works well, I felt it wasn't optimized for my primary use case which was having a smaller tmux pane that I would use to run tests or play with a REPL.
My goal with vimux is to make interacting with tmux from vim effortless. By default when you call `VimuxRunCommand` vimux will create a 20% tall horizontal pane under your current tmux pane and execute a command in it without losing focus of vim. Once that pane exists whenever you call `VimuxRunCommand` again the command will be executed in that pane. As I was using vimux myself I wanted to rerun commands over and over. An example of this was running the current file through rspec. Rather than typing that over and over I wrote `VimuxRunLastCommand` that will execute the last command you called with `VimuxRunCommand`.
Other auxiliary functions and the ones I talked about above can be found bellow with a full description and example key binds for your vimrc.
## Installation
With **[vim-bundle](https://github.com/benmills/vim-bundle)**: `vim-bundle install benmills/vimux`
With **[Vundle](https://github.com/gmarik/Vundle.vim)**: 'Plugin benmills/vimux' in your .vimrc
Otherwise download the latest [tarball](https://github.com/benmills/vimux/tarball/master), extract it and move `plugin/vimux.vim` inside `~/.vim/plugin`. If you're using [pathogen](https://github.com/tpope/vim-pathogen), then move the entire folder extracted from the tarball into `~/.vim/bundle`.
_Notes:_
* Vimux assumes a tmux version >= 1.5. Some older versions might work but it is recommeded to use at least version 1.5.
## Platform-specific Plugins
* [vim-vroom](https://github.com/skalnik/vim-vroom) runner for rspec, cucumber and test/unit; vimux support via `g:vroom_use_vimux`
* [vimux-ruby-test](https://github.com/pgr0ss/vimux-ruby-test) a set of commands to easily run ruby tests
* [vimux-cucumber](https://github.com/cloud8421/vimux-cucumber) run Cucumber Features through Vimux
* [vim-turbux](https://github.com/jgdavey/vim-turbux) Turbo Ruby testing with tmux
* [vimux-pyutils](https://github.com/julienr/vimux-pyutils) A set of functions for vimux that allow to run code blocks in ipython
* [vimux-nose-test](https://github.com/pitluga/vimux-nose-test) Run nose tests in vimux
* [vimux-golang](https://github.com/benmills/vimux-golang) Run go tests in vimux
* [vimux-zeus](https://github.com/jingweno/vimux-zeus) Run zeus commands in vimux
* [vimix](https://github.com/spiegela/vimix) Run Elixir mix commands in vimux
* [vimux-cargo](https://github.com/jtdowney/vimux-cargo) run rust tests and projects using cargo and vimux
* [vimux-bazel-test](https://github.com/pgr0ss/vimux-bazel-test) Run bazel tests in vimux
* [vimux-jest-test](https://github.com/tyewang/vimux-jest-test) Run jest tests in vimux
## Usage
The full documentation is available [online](https://raw.github.com/benmills/vimux/master/doc/vimux.txt) and accessible inside vim `:help vimux`

@ -13,9 +13,10 @@ CONTENTS *vimux-contents*
2.3 .............................. |VimuxInspectRunner|
2.4 .............................. |VimuxCloseRunner|
2.5 .............................. |VimuxInterruptRunner|
2.6 .............................. |VimuxClearRunnerHistory|
2.7 .............................. |VimuxZoomRunner|
2.8 .............................. |VimuxRunCommandInDir|
2.6 .............................. |VimuxClearTerminalScreen|
2.7 .............................. |VimuxClearRunnerHistory|
2.8 .............................. |VimuxZoomRunner|
2.9 .............................. |VimuxRunCommandInDir|
3. Misc ............................ |VimuxMisc|
3.1 Example Keybinding............ |VimuxExampleKeybinding|
3.2 Tslime Replacement............ |VimuxTslimeReplacement|
@ -27,25 +28,24 @@ ABOUT (1) *VimuxAbout*
Vimux -- Easily interact with tmux from vim.
What inspired me to write vimux was tslime.vim [1], a plugin that lets you
send input to tmux. While tslime.vim works well, I felt it wasn't optimized
for my primary use case which was having a smaller tmux pane that I would use
to run tests or play with a REPL.
Vimux was originally inspired by tslime.vim [1], a plugin that lets you send
input to tmux. While tslime.vim works well, it wasn't optimized for the use
case of having a smaller tmux pane used to run tests or play with a REPL. The
goal of Vimux is to make interacting with tmux from vim effortless.
My goal with vimux is to make interacting with tmux from vim effortless. By
default when you call `VimuxRunCommand` vimux will create a 20% tall
By default, when you call `VimuxRunCommand` vimux will create a 20% tall
horizontal pane under your current tmux pane and execute a command in it
without losing focus of vim. Once that pane exists whenever you call
`VimuxRunCommand` again the command will be executed in that pane. As I was
using vimux myself I wanted to rerun commands over and over. An example of
this was running the current file through rspec. Rather than typing that over
and over I wrote `VimuxRunLastCommand` that will execute the last command
you called with `VimuxRunCommand`.
without losing the focus on vim. Once that pane exists, whenever you call
`VimuxRunCommand` again the command will be executed in that pane. A frequent
use case is wanting to rerun commands over and over. An example of this is
running the current file through rspec. Rather than typing that over and over
`VimuxRunLastCommand` will execute the last command called with
`VimuxRunCommand`.
Other auxiliary functions and the ones I talked about above can be found
bellow with a full description and example key binds for your vimrc.
Other auxiliary functions and the ones talked about above can be found bellow
with full descriptions and example key bindings for your vimrc.
[1] https://github.com/kikijump/tslime.vim
[1] https://github.com/jgdavey/tslime.vim/network
==============================================================================
@ -70,6 +70,7 @@ Furthermore there are several handy commands all starting with 'Vimux':
- |VimuxInspectRunner|
- |VimuxInterruptRunner|
- |VimuxPromptCommand|
- |VimuxClearTerminalScreen|
- |VimuxClearRunnerHistory|
- |VimuxZoomRunner|
- |VimuxRunCommandInDir|
@ -93,7 +94,7 @@ vimux from automatically sending a return after the command.
VimuxSendText~
Send raw text to the runner pane. This command will not open a new pane if one
does not already exist. You will need to use VimuxOpenRunner to do this. This
does not already exist. You will need to use |VimuxOpenRunner| to do this. This
command can be used to interact with REPLs or other interactive terminal
programs that are not shells.
@ -103,7 +104,7 @@ programs that are not shells.
VimuxSendKeys~
Send keys to the runner pane. This command will not open a new pane if one
does not already exist. You will need to use VimuxOpenRunner to do this. You
does not already exist. You will need to use |VimuxOpenRunner| to do this. You
can use this command to send keys such as "Enter" or "C-c" to the runner pane.
------------------------------------------------------------------------------
@ -112,7 +113,7 @@ VimuxOpenRunner~
This will either open a new pane or use the nearest pane and set it as the
vimux runner pane for the other vimux commands. You can control if this command
uses the nearest pane or always creates a new one with g:VimuxUseNearest
uses the nearest pane or always creates a new one with g:|VimuxUseNearest|
------------------------------------------------------------------------------
*VimuxPromptCommand*
@ -170,6 +171,15 @@ runner pane.
<
------------------------------------------------------------------------------
*VimuxClearTerminalScreen*
VimuxClearTerminalScreen~
Clear the terminal screen of the runner pane.
>
" Clear the terminal screen of the runner pane.
map <Leader>v<C-l> :VimuxClearTerminalScreen<CR>
<
------------------------------------------------------------------------------
*VimuxClearRunnerHistory*
@ -240,6 +250,9 @@ Full Keybind Example~
" Zoom the runner pane (use <bind-key> z to restore runner pane)
map <Leader>vz :call VimuxZoomRunner()<CR>
" Clear the terminal screen of the runner pane.
map <Leader>v<C-l> :VimuxClearTerminalScreen<CR>
>
------------------------------------------------------------------------------
@ -251,8 +264,7 @@ First, add some helpful mappings.
>
function! VimuxSlime()
call VimuxSendText(@v)
call VimuxSendKeys("Enter")
call VimuxRunCommand(@v, 0)
endfunction
" If text is selected, save it in the v buffer and send that buffer it to tmux
@ -274,28 +286,30 @@ extra return. Thanks to @trptcolin for discovering this issue.
==============================================================================
CONFIGURATION (4) *VimuxConfiguration*
You can configure Vimux like this:
You can configure Vimux as follows. Note that all occurances of global
variables `g:Vimux...` may also be set using buffer variables `b:Vimux...` to
change the behavior of Vimux in just the current buffer.
------------------------------------------------------------------------------
*VimuxConfiguration_height*
2.1 g:VimuxHeight~
4.1 g:VimuxHeight~
The percent of the screen the split pane Vimux will spawn should take up.
>
let g:VimuxHeight = "40"
<
Default: "20"
------------------------------------------------------------------------------
*VimuxConfiguration_orientation*
2.2 g:VimuxOrientation~
4.2 g:VimuxOrientation~
The default orientation of the split tmux pane. This tells tmux to make the
pane either vertically or horizontally, which is backward from how Vim handles
creating splits.
>
let g:VimuxOrientation = "h"
<
Options:
"v": vertical
"h": horizontal
@ -304,63 +318,156 @@ Default: "v"
------------------------------------------------------------------------------
*VimuxConfiguration_use_nearest*
2.3 g:VimuxUseNearest
4.3 g:VimuxUseNearest~
Use existing pane or window (not used by vim) if found instead of running
split-window.
>
let g:VimuxUseNearest = 1
<
Default: 1
------------------------------------------------------------------------------
*VimuxConfiguration_reset_sequence*
2.4 g:VimuxResetSequence~
4.4 g:VimuxResetSequence~
The keys sent to the runner pane before running a command. By default it sends
`q` to make sure the pane is not in scroll-mode and `C-u` to clear the line.
>
let g:VimuxResetSequence = ""
<
Default: "q C-u"
------------------------------------------------------------------------------
*VimuxPromptString*
2.5 g:VimuxPromptString~
4.5 g:VimuxPromptString~
The string presented in the vim command line when Vimux is invoked. Be sure
to put a space at the end of the string to allow for distinction between
the prompt and your input.
>
let g:VimuxPromptString = ""
<
Default: "Command? "
------------------------------------------------------------------------------
*VimuxRunnerType*
2.6 g:VimuxRunnerType~
4.6 g:VimuxRunnerType~
The type of view object Vimux should use for the runner. For reference, a
tmux session is a group of windows, and a window is a layout of panes.
>
let g:VimuxRunnerType = "window"
<
Options:
"pane": for panes
"window": for windows
Default: "pane"
------------------------------------------------------------------------------
*VimuxRunnerName*
4.7 g:VimuxRunnerName~
Setting the name for the runner. Works for panes and windows. This makes the
VimuxRunner reusable between sessions. Caveat is, all your instances (in the
same session/window) use the same window.
Caution: It is probably best not to mix this with |VimuxCloseOnExit|.
>
let g:VimuxRunnerName = "vimuxout"
<
Default: ""
------------------------------------------------------------------------------
*VimuxTmuxCommand*
2.7 g:VimuxTmuxCommand~
4.8 g:VimuxTmuxCommand~
The command that Vimux runs when it calls out to tmux. It may be useful to
redefine this if you're using something like tmate.
>
let g:VimuxTmuxCommand = "tmate"
<
Default: "tmux"
------------------------------------------------------------------------------
*VimuxOpenExtraArgs*
4.9 g:VimuxOpenExtraArgs~
Allows addtional arguments to be passed to the tmux command that opens the
runner. Make sure that the arguments specified are valid depending on whether
you're using panes or windows, and your version of tmux.
>
let g:VimuxOpenExtraArgs = "-c #{pane_current_path}"
<
Default: ""
------------------------------------------------------------------------------
*VimuxExpandCommand*
4.10 g:VimuxExpandCommand~
Should the command given at the prompt via VimuxPromptCommand be expanded
using expand(). 1 to expand the string.
Unfortunately expand() only expands % (etc.) if the string starts with that
character. So the command is split at spaces and then rejoined after
expansion. With this simple approach things like "%:h/test.xml" are not
possible.
>
let g:VimuxExpandCommand = 1
<
Default: 0
------------------------------------------------------------------------------
*VimuxCloseOnExit*
4.11 g:VimuxCloseOnExit~
Set this option to `1` or `v:true` to tell vimux to close the runner when you quit
vim.
Caution: It is probably best not to mix this with |VimuxRunnerName|.
>
let g:VimuxCloseOnExit = 1
<
Default: 0
------------------------------------------------------------------------------
*VimuxCommandShell*
4.12 g:VimuxCommandShell~
Set this option to `1` or `v:true` to enable shell completion in
VimuxPromptCommand
Set this option to `0` or `v:false` to enable vim command editing in
VimuxPromptCommand
Enabling shell completion blocks the ability to use up-arrow to cycle through
previously-run commands in VimuxPromptCommand.
>
let g:VimuxCommandShell = 0
<
Default: 1
------------------------------------------------------------------------------
*VimuxRunnerQuery*
4.13 g:VimuxRunnerQuery~
Set this option to define a query to use for looking up an existing runner
pane or window when initiating Vimux. Uses the tmux syntax for the target-pane
and target-window command arguments. (See the man page for tmux). It must be a
dictionary containing up to two keys, "pane" and "window", defining the query
to use for the respective runner types.
If no key exists for the current runner type, the search for an existing
runner falls back to the `VimuxUseNearest` option (and the related
`VimuxRunnerName`). If that option is false or either command fails, a new
runner is created instead, positioned according to `VimuxOrientation`.
>
let g:VimuxRunnerQuery = {
\ 'pane': '{down-of}',
\ 'window': 'vimux',
\}
<
Default: {}
==============================================================================
vim:tw=78:ts=2:sw=2:expandtab:ft=help:norl:

@ -1,203 +1,321 @@
if exists("g:loaded_vimux") || &cp
if exists('g:loaded_vimux') || &compatible
finish
endif
let g:loaded_vimux = 1
" Set up all global options with defaults right away, in one place
let g:VimuxDebug = get(g:, 'VimuxDebug', v:false)
let g:VimuxHeight = get(g:, 'VimuxHeight', 20)
let g:VimuxOpenExtraArgs = get(g:, 'VimuxOpenExtraArgs', '')
let g:VimuxOrientation = get(g:, 'VimuxOrientation', 'v')
let g:VimuxPromptString = get(g:, 'VimuxPromptString', 'Command? ')
let g:VimuxResetSequence = get(g:, 'VimuxResetSequence', 'q C-u')
let g:VimuxRunnerName = get(g:, 'VimuxRunnerName', '')
let g:VimuxRunnerType = get(g:, 'VimuxRunnerType', 'pane')
let g:VimuxRunnerQuery = get(g:, 'VimuxRunnerQuery', {})
let g:VimuxTmuxCommand = get(g:, 'VimuxTmuxCommand', 'tmux')
let g:VimuxUseNearest = get(g:, 'VimuxUseNearest', v:true)
let g:VimuxExpandCommand = get(g:, 'VimuxExpandCommand', v:false)
let g:VimuxCloseOnExit = get(g:, 'VimuxCloseOnExit', v:false)
let g:VimuxCommandShell = get(g:, 'VimuxCommandShell', v:true)
function! VimuxOption(name) abort
return get(b:, a:name, get(g:, a:name))
endfunction
if !executable(VimuxOption('VimuxTmuxCommand'))
echohl ErrorMsg | echomsg 'Failed to find executable '.VimuxOption('VimuxTmuxCommand') | echohl None
finish
endif
command -nargs=* VimuxRunCommand :call VimuxRunCommand(<args>)
command VimuxRunLastCommand :call VimuxRunLastCommand()
command VimuxCloseRunner :call VimuxCloseRunner()
command VimuxZoomRunner :call VimuxZoomRunner()
command VimuxInspectRunner :call VimuxInspectRunner()
command VimuxScrollUpInspect :call VimuxScrollUpInspect()
command VimuxScrollDownInspect :call VimuxScrollDownInspect()
command VimuxInterruptRunner :call VimuxInterruptRunner()
command -bar VimuxRunLastCommand :call VimuxRunLastCommand()
command -bar VimuxOpenRunner :call VimuxOpenRunner()
command -bar VimuxCloseRunner :call VimuxCloseRunner()
command -bar VimuxZoomRunner :call VimuxZoomRunner()
command -bar VimuxInspectRunner :call VimuxInspectRunner()
command -bar VimuxScrollUpInspect :call VimuxScrollUpInspect()
command -bar VimuxScrollDownInspect :call VimuxScrollDownInspect()
command -bar VimuxInterruptRunner :call VimuxInterruptRunner()
command -nargs=? VimuxPromptCommand :call VimuxPromptCommand(<args>)
command VimuxClearRunnerHistory :call VimuxClearRunnerHistory()
command VimuxTogglePane :call VimuxTogglePane()
function! VimuxRunCommandInDir(command, useFile)
let l:file = ""
if a:useFile ==# 1
let l:file = shellescape(expand('%:t'), 1)
endif
call VimuxRunCommand("(cd ".shellescape(expand('%:p:h'), 1)." && ".a:command." ".l:file.")")
command -bar VimuxClearTerminalScreen :call VimuxClearTerminalScreen()
command -bar VimuxClearRunnerHistory :call VimuxClearRunnerHistory()
command -bar VimuxTogglePane :call VimuxTogglePane()
augroup VimuxAutocmds
au!
autocmd VimLeave * call s:autoclose()
augroup END
function! VimuxRunCommandInDir(command, useFile) abort
let l:file = ''
if a:useFile ==# 1
let l:file = shellescape(expand('%:t'), 1)
endif
call VimuxRunCommand('(cd '.shellescape(expand('%:p:h'), 1).' && '.a:command.' '.l:file.')')
endfunction
function! VimuxRunLastCommand()
if exists("g:VimuxRunnerIndex")
function! VimuxRunLastCommand() abort
if exists('g:VimuxLastCommand')
call VimuxRunCommand(g:VimuxLastCommand)
else
echo "No last vimux command."
echo 'No last vimux command.'
endif
endfunction
function! VimuxRunCommand(command, ...)
if !exists("g:VimuxRunnerIndex") || _VimuxHasRunner(g:VimuxRunnerIndex) == -1
function! VimuxRunCommand(command, ...) abort
if !exists('g:VimuxRunnerIndex') || s:hasRunner(g:VimuxRunnerIndex) ==# -1
call VimuxOpenRunner()
endif
let l:autoreturn = 1
if exists("a:1")
if exists('a:1')
let l:autoreturn = a:1
endif
let resetSequence = _VimuxOption("g:VimuxResetSequence", "q C-u")
let resetSequence = VimuxOption('VimuxResetSequence')
let g:VimuxLastCommand = a:command
call VimuxSendKeys(resetSequence)
call VimuxSendText(a:command)
if l:autoreturn == 1
call VimuxSendKeys("Enter")
if l:autoreturn ==# 1
call VimuxSendKeys('Enter')
endif
endfunction
function! VimuxSendText(text)
call VimuxSendKeys('"'.escape(a:text, '\"$`').'"')
function! VimuxSendText(text) abort
call VimuxSendKeys(shellescape(substitute(a:text, '\n$', ' ', '')))
endfunction
function! VimuxSendKeys(keys)
if exists("g:VimuxRunnerIndex")
call _VimuxTmux("send-keys -t ".g:VimuxRunnerIndex." ".a:keys)
function! VimuxSendKeys(keys) abort
if exists('g:VimuxRunnerIndex')
call VimuxTmux('send-keys -t '.g:VimuxRunnerIndex.' '.a:keys)
else
echo "No vimux runner pane/window. Create one with VimuxOpenRunner"
echo 'No vimux runner pane/window. Create one with VimuxOpenRunner'
endif
endfunction
function! VimuxOpenRunner()
let nearestIndex = _VimuxNearestIndex()
if _VimuxOption("g:VimuxUseNearest", 1) == 1 && nearestIndex != -1
let g:VimuxRunnerIndex = nearestIndex
function! VimuxOpenRunner() abort
let existingId = s:existingRunnerId()
if existingId !=# ''
let g:VimuxRunnerIndex = existingId
else
if _VimuxRunnerType() == "pane"
let height = _VimuxOption("g:VimuxHeight", 20)
let orientation = _VimuxOption("g:VimuxOrientation", "v")
call _VimuxTmux("split-window -p ".height." -".orientation)
elseif _VimuxRunnerType() == "window"
call _VimuxTmux("new-window")
let extraArguments = VimuxOption('VimuxOpenExtraArgs')
if VimuxOption('VimuxRunnerType') ==# 'pane'
call VimuxTmux('split-window '.s:vimuxPaneOptions().' '.extraArguments)
elseif VimuxOption('VimuxRunnerType') ==# 'window'
call VimuxTmux('new-window '.extraArguments)
endif
let g:VimuxRunnerIndex = _VimuxTmuxIndex()
call _VimuxTmux("last-"._VimuxRunnerType())
let g:VimuxRunnerIndex = s:tmuxIndex()
call s:setRunnerName()
call VimuxTmux('last-'.VimuxOption('VimuxRunnerType'))
sleep 100m
endif
endfunction
function! VimuxCloseRunner()
if exists("g:VimuxRunnerIndex")
call _VimuxTmux("kill-"._VimuxRunnerType()." -t ".g:VimuxRunnerIndex)
function! VimuxCloseRunner() abort
if exists('g:VimuxRunnerIndex')
call VimuxTmux('kill-'.VimuxOption('VimuxRunnerType').' -t '.g:VimuxRunnerIndex)
unlet g:VimuxRunnerIndex
endif
endfunction
function! VimuxTogglePane()
if exists("g:VimuxRunnerIndex")
if _VimuxRunnerType() == "window"
call _VimuxTmux("join-pane -d -s ".g:VimuxRunnerIndex." -p "._VimuxOption("g:VimuxHeight", 20))
let g:VimuxRunnerType = "pane"
elseif _VimuxRunnerType() == "pane"
let g:VimuxRunnerIndex=substitute(_VimuxTmux("break-pane -d -t ".g:VimuxRunnerIndex." -P -F '#{window_index}'"), "\n", "", "")
let g:VimuxRunnerType = "window"
function! VimuxTogglePane() abort
if exists('g:VimuxRunnerIndex')
if VimuxOption('VimuxRunnerType') ==# 'window'
call VimuxTmux('join-pane -s '.g:VimuxRunnerIndex.' '.s:vimuxPaneOptions())
let g:VimuxRunnerType = 'pane'
let g:VimuxRunnerIndex = s:tmuxIndex()
call VimuxTmux('last-'.VimuxOption('VimuxRunnerType'))
elseif VimuxOption('VimuxRunnerType') ==# 'pane'
let g:VimuxRunnerIndex=substitute(
\ VimuxTmux('break-pane -d -s '.g:VimuxRunnerIndex." -P -F '#{window_id}'"),
\ '\n',
\ '',
\ ''
\)
let g:VimuxRunnerType = 'window'
endif
endif
endfunction
function! VimuxZoomRunner()
if exists("g:VimuxRunnerIndex")
if _VimuxRunnerType() == "pane"
call _VimuxTmux("resize-pane -Z -t ".g:VimuxRunnerIndex)
elseif _VimuxRunnerType() == "window"
call _VimuxTmux("select-window -t ".g:VimuxRunnerIndex)
function! VimuxZoomRunner() abort
if exists('g:VimuxRunnerIndex')
if VimuxOption('VimuxRunnerType') ==# 'pane'
call VimuxTmux('resize-pane -Z -t '.g:VimuxRunnerIndex)
elseif VimuxOption('VimuxRunnerType') ==# 'window'
call VimuxTmux('select-window -t '.g:VimuxRunnerIndex)
endif
endif
endfunction
function! VimuxInspectRunner()
call _VimuxTmux("select-"._VimuxRunnerType()." -t ".g:VimuxRunnerIndex)
call _VimuxTmux("copy-mode")
function! VimuxInspectRunner() abort
call VimuxTmux('select-'.VimuxOption('VimuxRunnerType').' -t '.g:VimuxRunnerIndex)
call VimuxTmux('copy-mode')
endfunction
function! VimuxScrollUpInspect()
function! VimuxScrollUpInspect() abort
call VimuxInspectRunner()
call _VimuxTmux("last-"._VimuxRunnerType())
call VimuxSendKeys("C-u")
call VimuxTmux('last-'.VimuxOption('VimuxRunnerType'))
call VimuxSendKeys('C-u')
endfunction
function! VimuxScrollDownInspect()
function! VimuxScrollDownInspect() abort
call VimuxInspectRunner()
call _VimuxTmux("last-"._VimuxRunnerType())
call VimuxSendKeys("C-d")
call VimuxTmux('last-'.VimuxOption('VimuxRunnerType'))
call VimuxSendKeys('C-d')
endfunction
function! VimuxInterruptRunner()
call VimuxSendKeys("^c")
function! VimuxInterruptRunner() abort
call VimuxSendKeys('^c')
endfunction
function! VimuxClearRunnerHistory()
if exists("g:VimuxRunnerIndex")
call _VimuxTmux("clear-history -t ".g:VimuxRunnerIndex)
function! VimuxClearTerminalScreen() abort
if exists('g:VimuxRunnerIndex')
call VimuxSendKeys('C-l')
endif
endfunction
function! VimuxPromptCommand(...)
let command = a:0 == 1 ? a:1 : ""
let l:command = input(_VimuxOption("g:VimuxPromptString", "Command? "), command)
function! VimuxClearRunnerHistory() abort
if exists('g:VimuxRunnerIndex')
call VimuxTmux('clear-history -t '.g:VimuxRunnerIndex)
endif
endfunction
function! VimuxPromptCommand(...) abort
let command = a:0 ==# 1 ? a:1 : ''
if VimuxOption('VimuxCommandShell')
let l:command = input(VimuxOption('VimuxPromptString'), command, 'shellcmd')
else
let l:command = input(VimuxOption('VimuxPromptString'), command)
endif
if VimuxOption('VimuxExpandCommand')
let l:command = join(map(split(l:command, ' '), 'expand(v:val)'), ' ')
endif
call VimuxRunCommand(l:command)
endfunction
function! _VimuxTmux(arguments)
let l:command = _VimuxOption("g:VimuxTmuxCommand", "tmux")
return system(l:command." ".a:arguments)
function! VimuxTmux(arguments) abort
if VimuxOption('VimuxDebug')
echom VimuxOption('VimuxTmuxCommand').' '.a:arguments
endif
if has_key(environ(), 'TMUX')
return system(VimuxOption('VimuxTmuxCommand').' '.a:arguments)
else
throw 'Aborting, because not inside tmux session.'
endif
endfunction
function! _VimuxTmuxSession()
return _VimuxTmuxProperty("#S")
function! s:tmuxSession() abort
return s:tmuxProperty('#S')
endfunction
function! _VimuxTmuxIndex()
if _VimuxRunnerType() == "pane"
return _VimuxTmuxPaneIndex()
function! s:tmuxIndex() abort
if VimuxOption('VimuxRunnerType') ==# 'pane'
return s:tmuxPaneId()
else
return _VimuxTmuxWindowIndex()
return s:tmuxWindowId()
end
endfunction
function! _VimuxTmuxPaneIndex()
return _VimuxTmuxProperty("#I.#P")
function! s:tmuxPaneId() abort
return s:tmuxProperty('#{pane_id}')
endfunction
function! _VimuxTmuxWindowIndex()
return _VimuxTmuxProperty("#I")
function! s:tmuxWindowId() abort
return s:tmuxProperty('#{window_id}')
endfunction
function! _VimuxNearestIndex()
let views = split(_VimuxTmux("list-"._VimuxRunnerType()."s"), "\n")
function! s:vimuxPaneOptions() abort
let height = VimuxOption('VimuxHeight')
let orientation = VimuxOption('VimuxOrientation')
return '-l '.height.'% -'.orientation
endfunction
""
" @return a string of the form '%4', the ID of the pane or window to use,
" or '' if no nearest pane or window is found.
function! s:existingRunnerId() abort
let runnerType = VimuxOption('VimuxRunnerType')
let query = get(VimuxOption('VimuxRunnerQuery'), runnerType, '')
if empty(query)
if empty(VimuxOption('VimuxUseNearest'))
return ''
else
return s:nearestRunnerId()
endif
endif
" Try finding the runner using the provided query
let currentId = s:tmuxIndex()
let message = VimuxTmux('select-'.runnerType.' -t '.query.'')
if message ==# ''
" A match was found. Make sure it isn't the current vim pane/window
" though!
let runnerId = s:tmuxIndex()
if runnerId !=# currentId
" Success!
call VimuxTmux('last-'.runnerType)
return runnerId
endif
endif
return ''
endfunction
function! s:nearestRunnerId() abort
" Try finding the runner in the current window/session, optionally using a
" name/title filter
let runnerType = VimuxOption('VimuxRunnerType')
let filter = s:getTargetFilter()
let views = split(
\ VimuxTmux(
\ 'list-'.runnerType.'s'
\ ." -F '#{".runnerType.'_active}:#{'.runnerType."_id}'"
\ .filter),
\ '\n')
" '1:' is the current active pane (the one with vim).
" Find the first non-active pane.
for view in views
if match(view, "(active)") == -1
return split(view, ":")[0]
if match(view, '1:') ==# -1
return split(view, ':')[1]
endif
endfor
return -1
return ''
endfunction
function! _VimuxRunnerType()
return _VimuxOption("g:VimuxRunnerType", "pane")
function! s:getTargetFilter() abort
let targetName = VimuxOption('VimuxRunnerName')
if targetName ==# ''
return ''
endif
let runnerType = VimuxOption('VimuxRunnerType')
if runnerType ==# 'window'
return " -f '#{==:#{window_name},".targetName."}'"
elseif runnerType ==# 'pane'
return " -f '#{==:#{pane_title},".targetName."}'"
endif
endfunction
function! _VimuxOption(option, default)
if exists(a:option)
return eval(a:option)
else
return a:default
function! s:setRunnerName() abort
let targetName = VimuxOption('VimuxRunnerName')
if targetName ==# ''
return
endif
let runnerType = VimuxOption('VimuxRunnerType')
if runnerType ==# 'window'
call VimuxTmux('rename-window '.targetName)
elseif runnerType ==# 'pane'
call VimuxTmux('select-pane -T '.targetName)
endif
endfunction
function! s:tmuxProperty(property) abort
return substitute(VimuxTmux("display -p '".a:property."'"), '\n$', '', '')
endfunction
function! _VimuxTmuxProperty(property)
return substitute(_VimuxTmux("display -p '".a:property."'"), '\n$', '', '')
function! s:hasRunner(index) abort
let runnerType = VimuxOption('VimuxRunnerType')
return match(VimuxTmux('list-'.runnerType."s -F '#{".runnerType."_id}'"), a:index)
endfunction
function! _VimuxHasRunner(index)
return match(_VimuxTmux("list-"._VimuxRunnerType()."s -a"), a:index.":")
function! s:autoclose() abort
if VimuxOption('VimuxCloseOnExit')
call VimuxCloseRunner()
endif
endfunction

Loading…
Cancel
Save