Compare commits

..

No commits in common. 'master' and '0.1.0' have entirely different histories.

@ -1,43 +0,0 @@
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)"

@ -1,13 +0,0 @@
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

@ -1,15 +0,0 @@
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 .

1
.gitignore vendored

@ -1 +0,0 @@
doc/tags

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

@ -1,21 +0,0 @@
The MIT License (MIT)
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
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

@ -1,40 +0,0 @@
# 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

@ -0,0 +1,103 @@
# vimux
Easily interact with tmux from vim. This project is still in development, so some features are still missing.
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 `RunVimTmuxCommand` 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 `RunVimTmuxCommand` 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 `RunLastVimTmuxCommand` that will execute the last command you called with `RunVimTmuxCommand`.
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`
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`.
## Usage
### RunVimTmuxCommand
Run a system command in a small horizontal split bellow the current pane vim is in.
```viml
" Run the current file with rspec
map <Leader>rb :call RunVimTmuxCommand("clear; rspec " . bufname("%"))<CR>
```
### PromptVimTmuxCommand
Prompt for a command and run it in a small horizontal split bellow the current pane.
```viml
" Prompt for a command to run
map <Leader>rp :PromptVimTmuxCommand<CR>
```
### RunLastVimTmuxCommand
Run the last command executed by `RunVimTmuxCommand`
```viml
" Run last command executed by RunVimTmuxCommand
map <Leader>rl :RunLastVimTmuxCommand<CR>
```
### InspectVimTmuxRunner
Move into the tmux runner pane created by `RunVimTmuxCommand` and enter copy mode (scroll mode).
```viml
" Inspect runner pane
map <Leader>ri :InspectVimTmuxRunner<CR>
```
### CloseVimTmuxPanes
Close all other tmux panes in the current window.
```viml
" Close all other tmux panes in current window
map <Leader>rx :CloseVimTmuxPanes<CR>
```
### InterruptVimTmuxRunner
Interrupt any command that is running inside the runner pane.
```viml
" Interrupt any command running in the runner pane
map <Leader>rs :InterruptVimTmuxRunner<CR>
```
### Full Keybind Example
```viml
" Run the current file with rspec
map <Leader>rb :call RunVimTmuxCommand("clear; rspec " . bufname("%"))<CR>
" Prompt for a command to run
map <Leader>rp :PromptVimTmuxCommand<CR>
" Run last command executed by RunVimTmuxCommand
map <Leader>rl :RunLastVimTmuxCommand<CR>
" Inspect runner pane
map <Leader>ri :InspectVimTmuxRunner<CR>
" Close all other tmux panes in current window
map <Leader>rx :CloseVimTmuxPanes<CR>
" Interrupt any command running in the runner pane
map <Leader>rs :InterruptVimTmuxRunner<CR>
```
## Options
### VimuxHeight
Set the percent height of the runner pane opened by `RunVimTmuxCommand`.
**Default: `"20"`**
```viml
let VimuxHeight = "50"
```
## Todo
The features I would like to add in the near future.
* Add the ability to target any tmux session, window and pane

@ -1,473 +0,0 @@
*vimux.txt* easily interact with tmux
Vimux
effortless vim and tmux interaction
==============================================================================
CONTENTS *vimux-contents*
1. About............................ |VimuxAbout|
2. Usage ........................... |VimuxUsage|
2.1 .............................. |VimuxPromptCommand|
2.2 .............................. |VimuxRunLastCommand|
2.3 .............................. |VimuxInspectRunner|
2.4 .............................. |VimuxCloseRunner|
2.5 .............................. |VimuxInterruptRunner|
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|
4. Configuration ................... |VimuxConfiguration|
==============================================================================
ABOUT (1) *VimuxAbout*
Vimux -- Easily interact with tmux from vim.
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.
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`.
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/jgdavey/tslime.vim/network
==============================================================================
USAGE (2) *VimuxUsage*
The function VimuxRunCommand(command) is the core of Vimux. It will
create a split pane in the current window and run the passed command in it.
>
:call VimuxRunCommand("ls")
<
This will run the command in a split pane without losing focus of vim. If the
command takes a long time to return you can continue to use vim while the
process finishes and will see the output in the pane when it's finished.
Furthermore there are several handy commands all starting with 'Vimux':
- |VimuxRunCommand|
- |VimuxSendText|
- |VimuxSendKeys|
- |VimuxOpenRunner|
- |VimuxRunLastCommand|
- |VimuxCloseRunner|
- |VimuxInspectRunner|
- |VimuxInterruptRunner|
- |VimuxPromptCommand|
- |VimuxClearTerminalScreen|
- |VimuxClearRunnerHistory|
- |VimuxZoomRunner|
- |VimuxRunCommandInDir|
------------------------------------------------------------------------------
*VimuxRunCommand*
VimuxRunCommand~
Run a system command in a small horizontal split bellow
the current pane vim is in. You can optionally pass a second argument to stop
vimux from automatically sending a return after the command.
>
" Run the current file with rspec
map <Leader>rb :call VimuxRunCommand("clear; rspec " . bufname("%"))<CR>
" Run command without sending a return
map <Leader>rq :call VimuxRunCommand("clear; rspec " . bufname("%"), 0)<CR>
<
------------------------------------------------------------------------------
*VimuxSendText*
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
command can be used to interact with REPLs or other interactive terminal
programs that are not shells.
------------------------------------------------------------------------------
*VimuxSendKeys*
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
can use this command to send keys such as "Enter" or "C-c" to the runner pane.
------------------------------------------------------------------------------
*VimuxOpenRunner*
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|
------------------------------------------------------------------------------
*VimuxPromptCommand*
VimuxPromptCommand~
Prompt for a command and run it in a small horizontal split bellow the current
pane. A parameter can be supplied to predefine a command or a part of the
command which can be edited in the prompt.
>
" Prompt for a command to run map
map <Leader>vp :VimuxPromptCommand<CR>
map <Leader>vm :VimuxPromptCommand("make ")<CR>
<
------------------------------------------------------------------------------
*VimuxRunLastCommand*
VimuxRunLastCommand~
Run the last command executed by `VimuxRunCommand`
>
" Run last command executed by VimuxRunCommand
map <Leader>vl :VimuxRunLastCommand<CR>
<
------------------------------------------------------------------------------
*VimuxInspectRunner*
VimuxInspectRunner~
Move into the tmux runner pane created by `VimuxRunCommand` and enter copy
pmode (scroll mode).
>
" Inspect runner pane map
map <Leader>vi :VimuxInspectRunner<CR>
<
------------------------------------------------------------------------------
*VimuxCloseRunner*
VimuxCloseRunner~
Close the tmux runner created by `VimuxRunCommand`
>
" Close vim tmux runner opened by VimuxRunCommand
map <Leader>vq :VimuxCloseRunner<CR>
<
------------------------------------------------------------------------------
*VimuxInterruptRunner*
VimuxInterruptRunner~
Interrupt any command that is running inside the
runner pane.
>
" Interrupt any command running in the runner pane map
map <Leader>vs :VimuxInterruptRunner<CR>
<
------------------------------------------------------------------------------
*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*
VimuxClearRunnerHistory~
Clear the tmux history of the runner pane for when
you enter tmux scroll mode inside the runner pane.
>
" Clear the tmux history of the runner pane
map <Leader>vc :VimuxClearRunnerHistory<CR>
<
------------------------------------------------------------------------------
*VimuxZoomRunner*
VimuxZoomRunner~
Zoom the runner pane. Once its zoomed, you will need
to use tmux "<bind-key> z" to restore the runner pane.
Zoom requires tmux version >= 1.8
>
" Zoom the tmux runner page
map <Leader>vz :VimuxZoomRunner<CR>
<
------------------------------------------------------------------------------
*VimuxRunCommandInDir*
VimuxRunCommandInDir~
Runs the specified command inside the directory of
the currently opened file. Takes two arguments. command and inFile
command: The command to run
inFile: If 1 the filename will be appended to the command
>
" Compile currently opened latex file to pdf
autocmd Filetype tex nnoremap <buffer> <Leader>rr :update<Bar>:call VimuxRunCommandInDir('latexmk -pdf', 1)<CR>
" Push the repository of the currently opened file
nnoremap <leader>gp :call VimuxRunCommandInDir("git push", 0)<CR>
<
==============================================================================
MISC (3) *VimuxMisc*
------------------------------------------------------------------------------
*VimuxExampleKeybinding*
Full Keybind Example~
>
" Run the current file with rspec
map <Leader>rb :call VimuxRunCommand("clear; rspec " . bufname("%"))<CR>
" Prompt for a command to run
map <Leader>vp :VimuxPromptCommand<CR>
" Run last command executed by VimuxRunCommand
map <Leader>vl :VimuxRunLastCommand<CR>
" Inspect runner pane
map <Leader>vi :VimuxInspectRunner<CR>
" Close vim tmux runner opened by VimuxRunCommand
map <Leader>vq :VimuxCloseRunner<CR>
" Interrupt any command running in the runner pane
map <Leader>vx :VimuxInterruptRunner<CR>
" 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>
>
------------------------------------------------------------------------------
*VimuxTslimeReplacement*
Vimux as tslime replacement~
Here is how to use vimux to send code to a REPL. This is similar to tslime.
First, add some helpful mappings.
>
function! VimuxSlime()
call VimuxRunCommand(@v, 0)
endfunction
" If text is selected, save it in the v buffer and send that buffer it to tmux
vmap <LocalLeader>vs "vy :call VimuxSlime()<CR>
" Select current paragraph and send it to tmux
nmap <LocalLeader>vs vip<LocalLeader>vs<CR>
<
Now, open a clojure file. Let's say your leader is backslash (\). Type \vp,
and then type lein repl at the prompt. This opens a tmux split running a REPL.
Then, select text or put the cursor on a function and type \vs. This will send
it to the REPL and evaluate it. The reason we pass `0` to `VimuxRunCommand`
is to stop the normal return that is sent to the runner pane and use our own
new line so the clojure REPL will evaluate the selected text without adding an
extra return. Thanks to @trptcolin for discovering this issue.
==============================================================================
CONFIGURATION (4) *VimuxConfiguration*
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*
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*
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
Default: "v"
------------------------------------------------------------------------------
*VimuxConfiguration_use_nearest*
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*
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*
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*
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*
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,321 +1,169 @@
if exists('g:loaded_vimux') || &compatible
if !has("ruby")
finish
endif
let g:loaded_vimux = 1
end
" 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)
command RunLastVimTmuxCommand :call RunLastVimTmuxCommand()
command CloseVimTmuxPanes :call CloseVimTmuxPanes()
command CloseVimTmuxWindows :call CloseVimTmuxWindows()
command InspectVimTmuxRunner :call InspectVimTmuxRunner()
command InterruptVimTmuxRunner :call InterruptVimTmuxRunner()
command PromptVimTmuxCommand :call PromptVimTmuxCommand()
function! VimuxOption(name) abort
return get(b:, a:name, get(g:, a:name))
function! RunVimTmuxCommand(command)
let g:_VimTmuxCmd = a:command
ruby CurrentTmuxSession.new.run_shell_command(Vim.evaluate("g:_VimTmuxCmd"))
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 -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 -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() abort
if exists('g:VimuxLastCommand')
call VimuxRunCommand(g:VimuxLastCommand)
function! RunLastVimTmuxCommand()
if exists("g:_VimTmuxCmd")
ruby CurrentTmuxSession.new.run_shell_command(Vim.evaluate("g:_VimTmuxCmd"))
else
echo 'No last vimux command.'
echo "No last command"
endif
endfunction
function! VimuxRunCommand(command, ...) abort
if !exists('g:VimuxRunnerIndex') || s:hasRunner(g:VimuxRunnerIndex) ==# -1
call VimuxOpenRunner()
endif
let l:autoreturn = 1
if exists('a:1')
let l:autoreturn = a:1
endif
let resetSequence = VimuxOption('VimuxResetSequence')
let g:VimuxLastCommand = a:command
call VimuxSendKeys(resetSequence)
call VimuxSendText(a:command)
if l:autoreturn ==# 1
call VimuxSendKeys('Enter')
endif
function! ClearVimTmuxWindow()
if exists("g:_VimTmuxRunnerPane")
unlet g:_VimTmuxRunnerPane
end
endfunction
function! VimuxSendText(text) abort
call VimuxSendKeys(shellescape(substitute(a:text, '\n$', ' ', '')))
function! CloseVimTmuxWindows()
ruby CurrentTmuxSession.new.close_other_panes
call ClearVimTmuxWindow()
echoerr "CloseVimTmuxWindows is deprecated, use CloseVimTmuxPanes"
endfunction
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'
endif
function! CloseVimTmuxPanes()
ruby CurrentTmuxSession.new.close_other_panes
call ClearVimTmuxWindow()
endfunction
function! VimuxOpenRunner() abort
let existingId = s:existingRunnerId()
if existingId !=# ''
let g:VimuxRunnerIndex = existingId
else
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 = s:tmuxIndex()
call s:setRunnerName()
call VimuxTmux('last-'.VimuxOption('VimuxRunnerType'))
sleep 100m
endif
function! InterruptVimTmuxRunner()
ruby CurrentTmuxSession.new.interrupt_runner
endfunction
function! VimuxCloseRunner() abort
if exists('g:VimuxRunnerIndex')
call VimuxTmux('kill-'.VimuxOption('VimuxRunnerType').' -t '.g:VimuxRunnerIndex)
unlet g:VimuxRunnerIndex
endif
function! InspectVimTmuxRunner()
ruby CurrentTmuxSession.new.inspect_runner
endfunction
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
function! PromptVimTmuxCommand()
let l:command = input("Command? ")
call RunVimTmuxCommand(l:command)
endfunction
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
ruby << EOF
class TmuxSession
def initialize(session, window, pane)
@session = session
@window = window
@pane = pane
@runner_pane = vim_cached_runner_pane
end
function! VimuxInspectRunner() abort
call VimuxTmux('select-'.VimuxOption('VimuxRunnerType').' -t '.g:VimuxRunnerIndex)
call VimuxTmux('copy-mode')
endfunction
def vim_cached_runner_pane
if Vim.evaluate('exists("g:_VimTmuxRunnerPane")') != 0
Vim.evaluate('g:_VimTmuxRunnerPane')
else
nil
end
end
function! VimuxScrollUpInspect() abort
call VimuxInspectRunner()
call VimuxTmux('last-'.VimuxOption('VimuxRunnerType'))
call VimuxSendKeys('C-u')
endfunction
def vim_cached_runner_pane=(runner_pane)
Vim.command("let g:_VimTmuxRunnerPane = '#{runner_pane}'")
end
function! VimuxScrollDownInspect() abort
call VimuxInspectRunner()
call VimuxTmux('last-'.VimuxOption('VimuxRunnerType'))
call VimuxSendKeys('C-d')
endfunction
def clear_vim_cached_runner_pane
Vim.command("unlet g:_VimTmuxRunnerPane")
end
function! VimuxInterruptRunner() abort
call VimuxSendKeys('^c')
endfunction
def height
if Vim.evaluate('exists("g:VimuxHeight")') != 0
Vim.evaluate('g:VimuxHeight')
else
20
end
end
function! VimuxClearTerminalScreen() abort
if exists('g:VimuxRunnerIndex')
call VimuxSendKeys('C-l')
endif
endfunction
def inspect_runner
run("select-pane -t #{target(:pane => runner_pane)}")
run("copy-mode")
end
function! VimuxClearRunnerHistory() abort
if exists('g:VimuxRunnerIndex')
call VimuxTmux('clear-history -t '.g:VimuxRunnerIndex)
endif
endfunction
def current_panes
run('list-panes').split("\n").map do |line|
line.split(':').first
end
end
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
def active_pane_id
run('list-panes').split("\n").map do |line|
return line.split[-2] if line =~ /\(active\)/
end
end
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
def target(args={})
"#{args.fetch(:session, @session)}:#{args.fetch(:window, @window)}.#{args.fetch(:pane, @pane)}"
end
function! s:tmuxSession() abort
return s:tmuxProperty('#S')
endfunction
def runner_pane
if @runner_pane.nil?
run("split-window -p #{height}")
@runner_pane = active_pane_id
Vim.command("let g:_VimTmuxRunnerPane = '#{@runner_pane}'")
end
function! s:tmuxIndex() abort
if VimuxOption('VimuxRunnerType') ==# 'pane'
return s:tmuxPaneId()
else
return s:tmuxWindowId()
end
endfunction
run('list-panes').split("\n").map do |line|
return line.split(':').first if line =~ /#{@runner_pane}/
end
function! s:tmuxPaneId() abort
return s:tmuxProperty('#{pane_id}')
endfunction
@runner_pane = nil
clear_vim_cached_runner_pane
runner_pane
end
function! s:tmuxWindowId() abort
return s:tmuxProperty('#{window_id}')
endfunction
def interrupt_runner
run("send-keys -t #{target(:pane => runner_pane)} ^c")
end
function! s:vimuxPaneOptions() abort
let height = VimuxOption('VimuxHeight')
let orientation = VimuxOption('VimuxOrientation')
return '-l '.height.'% -'.orientation
endfunction
def run_shell_command(command)
send_command(command, target(:pane => runner_pane))
move_up_pane
end
""
" @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
def close_other_panes
# if run("list-panes").split("\n").length > 1
run("kill-pane -a")
# end
end
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, '1:') ==# -1
return split(view, ':')[1]
endif
endfor
return ''
endfunction
def move_up_pane
run("select-pane -t #{target}")
end
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
def send_command(command, target)
run("send-keys -t #{target} '#{command.gsub("'", "\'")}'")
run("send-keys -t #{target} Enter")
end
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
def run(command)
`tmux #{command}`
end
end
function! s:tmuxProperty(property) abort
return substitute(VimuxTmux("display -p '".a:property."'"), '\n$', '', '')
endfunction
class CurrentTmuxSession < TmuxSession
def initialize
session = self.get_property(:attached, :session)
window = self.get_property(:active, :window)
pane = self.get_property(:active, :pane)
function! s:hasRunner(index) abort
let runnerType = VimuxOption('VimuxRunnerType')
return match(VimuxTmux('list-'.runnerType."s -F '#{".runnerType."_id}'"), a:index)
endfunction
super(session, window, pane)
end
function! s:autoclose() abort
if VimuxOption('VimuxCloseOnExit')
call VimuxCloseRunner()
endif
endfunction
def get_property(match, type)
run("list-#{type.to_s}").split("\n").each do |line|
return line.split(':').first if line =~ /\(#{match.to_s}\)/
end
end
end
EOF

Loading…
Cancel
Save