Compare commits

..

No commits in common. "master" and "v2.0.0" have entirely different histories.

14 changed files with 271 additions and 834 deletions

View file

@ -1,24 +0,0 @@
# EditorConfig: http://EditorConfig.org
root = true
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
[*.md]
max_line_length = 76
indent_size = 4
trim_trailing_whitespace = true
[Vagrantfile]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[{*.sh,*.tmux}]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true

11
.gitattributes vendored
View file

@ -1,11 +0,0 @@
# The linguist directives are for https://github.com/github/linguist
*.md text eol=lf whitespace=blank-at-eol
*.sh text eol=lf whitespace=blank-at-eol diff=php
*.tmux text eol=lf whitespace=blank-at-eol diff=php
Vagrantfile text eol=lf linguist-vendored
video/* linguist-documentation
# Binary Types
*.png binary

View file

@ -1,17 +0,0 @@
sudo: required
language: bash
services:
- docker
script:
- "./citest"
notifications:
email: false
pushover:
on_success: change
on_failure: always
api_key:
secure: gWoqAqGyBbO6mcKbHkt29jJZ7ElOfct2C5WPfliBARl8ImCE0HE6CEGdK25i29mjfIxXWp3HITsRawuauZDN8nCZ9srO+0wr7OWAcZuhDW6mDmKNLX2y4eR4lK21MsMpLIHqA48hYXkHVKSHR7TDG88A/0MRXoTb5gcuPDJMqPk=
users:
secure: dIUBBbi8R7cOcwBQ8guLsq+M8vBXcSAu9vKUVEqToSHoWap4fTl4QSZpyhzxLy6uSNRwg1u20xVSlEAPee2Z+efzZQtA0I9bRTkcAMbzH65+sWKgMsEMJoHrqlCr7FvX4c+UMW9sWlRLoH52oN3ilCQNy2beI8mWqE4gAGxD4aA=

View file

@ -1,132 +1,44 @@
Change Log
==========
# Changelog
[master]
--------
### master
### Added
### v2.0.0, Dec 06, 2014
- change copy mode "put selection" key binding to `Y` so that vi mode `Ctrl-y`
is not overriden.
- Mouse support, controlled by `yank_with_mouse` and `yank_selection_mouse`
(@keidax)
### v1.0.0, Dec 06, 2014
- simplify README
- remove screencast from the master branch because it's too large for download.
The screencast is moved to the separate `screencast` branch and can be cloned
from there.
- show error message if plugin dependencies aren't insalled
- update README related plugins list
- update README to show how to update xclip selection on Linux
- add vagrant-related setup files for testing on Linux
[v2.3.0] 2018-02-01
-------------------
### v0.0.4, Jul 29, 2014
- update readme to reflect github organization change
- add screencast script file
- import screencast project
- add `video/README.md`
- put screencast in the readme
### Added
### v0.0.3, Jun 29, 2014
- Tmux 2.4 support (@docwhat, @edi9999)
- Windows Subsystem for Linux (WSL) support via `clip.exe` (@lukewang1024)
- "copy pane current directory" feature (@bruno-)
- `yank_line` and `yank_pane_pwd` fork to prevent xclip from hanging Tmux (@leoalekseyev)
* `yank_line` no longer cares if you use emacs or vi in copy-mode.
- adds wait time for 'yank line' when in the remote shell (ssh, mosh) so yank
line is more correct
- fix bug when yank-line is used in the last line in buffer. New 'solution' is
implemented for copying multiple lines.
- code cleanup
- yank-line never yanks 'newline' char for multiple-line commands in shell (this
is actually tmux/bash bug).
### Fixed
### v0.0.2, Jun 25, 2014
- Detect git builds of tmux version ≥ 2.4 (@maximbaz PR#89)
- updated readme
- for OS X, also check if 'reattach-to-user-namespace' is installed
- add a feature for copying current command line to clipboard
[v2.2.0] 2015-10-12
-------------------
### v0.0.1, Jun 24, 2014
### Added
- Support for custom copy command (if `xclip` and others aren't
accessible, and you want to have your custom copy command)
- Cygwin support via `putclip` command
[v2.1.0] 2015-06-17
-------------------
### Added
- Add support for `xsel` on Linux (@ctjhoa)
- Support for shell `vi` mode (@xnaveira)
### Updated
- Make `reattach-to-user-namespace` on OS X optional (@bosr)
- Deprecate <kbd>Alt</kbd><kbd>y</kbd>
[v2.0.0] 2014-12-06
-------------------
### Fixed
- Change copy mode "put selection" key binding to <kbd>Y</kbd> so that vi
mode <kbd>Control</kbd><kbd>y</kbd> is not overridden.
[v1.0.0] 2014-12-06
-------------------
### Added
- Show error message if plugin dependencies aren't installed.
- Vagrant setup for manually testing Linux.
### Updated
- `README`
- Related plugin list
- Instructions on updating `xclip` for Linux.
### Removed
- The screen-cast is moved into `screencast` branch.
[v0.0.4] 2014-07-29
-------------------
### Updated
- `README` documentation; including a screen-cast.
[v0.0.3] 2014-06-29
-------------------
### Added
- Wait when doing "yank line" when using a remote shell (`ssh`, `mosh`) to
ensure screen is updated.
### Fixed
- Handle `yank-line` when used on the last line of buffer: copy multiple
lines.
- `yank-line` never yanks 'newline' char for multiple-line commands in
shell (this is actually tmux/bash bug).
### Updated
- Code cleanup.
[v0.0.2] 2014-06-25
-------------------
### Updated
- `README`
### Added
- In OS X: Check if `reattach-to-user-namespace` is installed.
- "copy current command line" feature.
[v0.0.1] 2014-06-24
-------------------
- First working version.
Notes
-----
This change log is kept in <http://keepachangelog.com/> format.
[master]: https://github.com/tmux-plugins/tmux-yank/compare/v2.3.0...HEAD
[v2.3.0]: https://github.com/tmux-plugins/tmux-yank/compare/v2.2.0...v2.3.0
[v2.2.0]: https://github.com/tmux-plugins/tmux-yank/compare/v2.1.0...v2.2.0
[v2.1.0]: https://github.com/tmux-plugins/tmux-yank/compare/v2.0.0...v2.1.0
[v2.0.0]: https://github.com/tmux-plugins/tmux-yank/compare/v1.0.0...v2.0.0
[v1.0.0]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.4...v1.0.0
[v0.0.4]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.3...v0.0.4
[v0.0.3]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.2...v0.0.3
[v0.0.2]: https://github.com/tmux-plugins/tmux-yank/compare/v0.0.1...v0.0.2
[v0.0.1]: https://github.com/tmux-plugins/tmux-yank/commits/v0.0.1
- first working version

View file

@ -1,5 +1,4 @@
Copyright (C) 2014, 2017 Bruno Sutic
Copyright (C) 2017 Christian Höltje
Copyright (C) 2014 Bruno Sutic
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the "Software"),

312
README.md
View file

@ -1,289 +1,101 @@
[![Build
Status](https://travis-ci.org/tmux-plugins/tmux-yank.svg?branch=master)](https://travis-ci.org/tmux-plugins/tmux-yank)
[![GitHub
release](https://img.shields.io/github/release/tmux-plugins/tmux-yank.svg)](https://github.com/tmux-plugins/tmux-yank/releases)
[![GitHub
issues](https://img.shields.io/github/issues/tmux-plugins/tmux-yank.svg)](https://github.com/tmux-plugins/tmux-yank/issues)
# Tmux Yank
tmux-yank
=========
Enables copying to system clipboard in Tmux. Works on Linux and OS X.
Copy to the system clipboard in [`tmux`](https://tmux.github.io/).
### Screencast
Supports:
[![screencast screenshot](/video/screencast_img.png)](https://vimeo.com/102039099)
- Linux
- macOS
- Cygwin
- Windows Subsystem for Linux (WSL)
Installing
----------
### Via TPM (recommended)
The easiest way to install `tmux-yank` is via the [Tmux Plugin
Manager](https://github.com/tmux-plugins/tpm).
1. Add plugin to the list of TPM plugins in `.tmux.conf`:
``` tmux
set -g @plugin 'tmux-plugins/tmux-yank'
```
2. Use <kbd>prefix</kbd><kbd>I</kbd> install `tmux-yank`. You should now
be able to `tmux-yank` immediately.
3. When you want to update `tmux-yank` use <kbd>prefix</kbd><kbd>U</kbd>.
### Manual Installation
1. Clone the repository
``` sh
$ git clone https://github.com/tmux-plugins/tmux-yank ~/clone/path
```
2. Add this line to the bottom of `.tmux.conf`
``` tmux
run-shell ~/clone/path/yank.tmux
```
3. Reload the `tmux` environment
``` sh
# type this inside tmux
$ tmux source-file ~/.tmux.conf
```
You should now be able to use `tmux-yank` immediately.
Requirements
------------
In order for `tmux-yank` to work, there must be a program that store data in
the system clipboard.
### macOS
- [`reattach-to-user-namespace`](https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard)
**Note**: Some versions of macOS (aka OS X) have been reported to work
without `reattach-to-user-namespace`. It doesn't hurt to have it installed.
- OS X 10.8: Mountain Lion *required*
- OS X 10.9: Mavericks *required*
- OS X 10.10: Yosemite *not required*
- OS X 10.11: El Capitan *not required*
- macOS 10.12: Sierra *required*
- macOS 10.14: Mojave - *required*
- macOS 10.15: Catalina - *not required*
The easiest way to use `reattach-to-user-namespace` with `tmux` is use to
use the [`tmux-sensible`](https://github.com/tmux-plugins/tmux-sensible)
plugin.
To use it manually, use:
``` tmux
# ~/.tmux.conf
set-option -g default-command "reattach-to-user-namespace -l $SHELL"
```
If you have `tmux` 1.5 or newer and are using
[iTerm2](https://www.iterm2.com/) version 3 or newer then the <kbd>y</kbd>
in `copy-mode` and mouse selection will work without `tmux-yank`.
To enable this:
1. Go into iTerm2's preferences.
2. Go to the "General" tab.
3. Check "Applications in terminal may access clipboard"
4. In `tmux`, ensure `set-clipboard` is turned on:
``` sh
$ tmux show-options -g -s set-clipboard
set-clipboard on
```
#### [HomeBrew](https://brew.sh/) (recommended)
``` sh
$ brew install reattach-to-user-namespace
```
#### MacPorts
``` sh
$ sudo port install tmux-pasteboard
```
### Linux
- `xsel` (recommended) or `xclip` (for X).
- `wl-copy` from [wl-clipboard](https://github.com/bugaevc/wl-clipboard) (for Wayland)
If you have `tmux` 1.5 or newer and are using `xterm`, the <kbd>y</kbd> in
`copy-mode` and mouse selection will work without `tmux-yank`. See the
`tmux(1)` man page entry for the `set-clipboard` option.
#### Debian & Ubuntu
``` sh
$ sudo apt-get install xsel # or xclip
```
#### RedHat & CentOS
``` sh
$ sudo yum install xsel # or xclip
```
### Cygwin
- (*optional*) `putclip` which is part of the `cygutils-extra` package.
### Windows Subsystem for Linux (WSL)
- `clip.exe` is shipped with Windows Subsystem for Linux.
Configuration
-------------
Note: screencast shows using the "put selection" feature with `Ctrl-y` key
binding in copy mode. In `v2.0.0` this key binding was changed to `Y` (shift-y).
### Key bindings
- Normal Mode
- <kbd>prefix</kbd><kbd>y</kbd> — copies text from the command line
to the clipboard.
- `prefix + y` - copies text from the command line to clipboard.<br/>
Works with all popular shells/repls. Tested with:
- shells: `bash`, `zsh` (with `bindkey -e`), `tcsh`
- repls: `irb`, `pry`, `node`, `psql`, `python`, `php -a`, `coffee`
- remote shells: `ssh`, [mosh](http://mosh.mit.edu/)
- vim/neovim command line (requires
[vim-husk](https://github.com/bruno-/vim-husk) or
[vim-rsi](https://github.com/tpope/vim-rsi) plugin)
Works with all popular shells/repls. Tested with:
**copy mode** bindings:
- `y` - copy selection to system clipboard
- `Y` (shift-y) - "put" selection - equivalent to copying a selection, and
pasting it to the command line
- `Alt-y` - performs both of the above: copy to system clipboard and
put to command line
- shells: `bash`, `zsh` (with `bindkey -e`), `tcsh`
- repls: `irb`, `pry`, `node`, `psql`, `python`, `php -a`,
`coffee`
- remote shells: `ssh`, [mosh](http://mosh.mit.edu/)
- vim/neovim command line (requires
[vim-husk](https://github.com/bruno-/vim-husk) or
[vim-rsi](https://github.com/tpope/vim-rsi) plugin)
#### OS X requirements
- <kbd>prefix</kbd><kbd>Y</kbd> — copy the current pane's current
working directory to the clipboard.
- [reattach-to-user-namespace](https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard)<br/>
If you don't have this already, then install:
`$ brew install reattach-to-user-namespace`.
- Copy Mode
- <kbd>y</kbd> — copy selection to system clipboard.
- <kbd>Y</kbd> (shift-y) — "put" selection. Equivalent to copying a
selection, and pasting it to the command line.
#### Linux requirements
- `xclip` command<br/>
You most likely already have `xclip`, but if not:
- Debian / Ubuntu: `$ sudo apt-get install xclip`
- Red hat / CentOS: `$ yum install xclip`
### Default and Preferred Clipboard Programs
### Copy command
tmux-yank does its best to detect a reasonable choice for a clipboard
program on your OS.
**OS X**
If tmux-yank can't detect a known clipboard program then it uses the
`@custom_copy_command` tmux option as your clipboard program if set.
Copying to clipboard is done using `pbcopy`.
If you need to always override tmux-yank's choice for a clipboard program,
then you can set `@override_copy_command` to force tmux-yank to use whatever
you want.
**Linux**
Note that both programs _must_ accept `STDIN` for the text to be copied.
Copying to clipboard is done using `xclip -selection c` command by default.
An example of setting `@override_copy_command`:
If copying is different on your system, and you need the command to be i.e.
`xclip -selection normal`, here's how to customize:
``` tmux
# ~/.tmux.conf
# in .tmux.conf
set -g @yank_selection "primary"
set -g @custom_copy_command 'my-clipboard-copy --some-arg'
# or
set -g @override_copy_command 'my-clipboard-copy --some-arg'
```
### Notes
### Linux Clipboards
**Mouse Support**
Linux has several cut-and-paste clipboards: `primary`, `secondary`, and
`clipboard` (default in tmux-yank is `clipboard`).
When making a selection using tmux `mode-mouse on` or `mode-mouse copy-mode`, you cannot rely on the default 'release mouse after selection to copy' behavior. Instead, press `y` before releasing mouse.
You can change this by setting `@yank_selection`:
### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended)
``` tmux
# ~/.tmux.conf
Add plugin to the list of TPM plugins in `.tmux.conf`:
set -g @yank_selection 'primary' # or 'secondary' or 'clipboard'
```
set -g @tpm_plugins " \
tmux-plugins/tpm \
tmux-plugins/tmux-yank \
"
With mouse support turned on (see below) the default clipboard for mouse
selections is `primary`.
Hit `prefix + I` to fetch the plugin and source it. You should now be able to
use the plugin.
You can change this by setting `@yank_selection_mouse`:
### Manual Installation
``` tmux
# ~/.tmux.conf
Clone the repo:
set -g @yank_selection_mouse 'clipboard' # or 'primary' or 'secondary'
```
$ git clone https://github.com/tmux-plugins/tmux-yank ~/clone/path
### Controlling Yank Behavior
Add this line to the bottom of `.tmux.conf`:
By default, `tmux-yank` will exit copy mode after yanking text. If you wish to
remain in copy mode, you can set `@yank_action`:
run-shell ~/clone/path/yank.tmux
``` tmux
# ~/.tmux.conf
Reload TMUX environment:
set -g @yank_action 'copy-pipe' # or 'copy-pipe-and-cancel' for the default
```
# type this in terminal
$ tmux source-file ~/.tmux.conf
### Mouse Support
You should now be able to use the plugin.
`tmux-yank` has mouse support enabled by default. It will only work if `tmux`'s
built-in mouse support is also enabled (with `mouse on` since `tmux` 2.1, or
`mode-mouse on` in older versions).
### Other Tmux goodies
To yank with the mouse, click and drag with the primary button to begin
selection, and release to yank.
If you would prefer to disable this behavior, or provide your own bindings for
the `MouseDragEnd1Pane` event, you can do so with:
``` tmux
# ~/.tmux.conf
set -g @yank_with_mouse off # or 'on'
```
If you want to remain in copy mode after making a mouse selection, set
`@yank_action` as described above.
### vi mode support
If using `tmux` 2.3 or older *and* using vi keys then you'll have add the
following configuration setting:
``` tmux
# ~/.tmux.conf
set -g @shell_mode 'vi'
```
This isn't needed with `tmux` 2.4 or newer.
### Screen-cast
[![screencast
screenshot](/video/screencast_img.png)](https://vimeo.com/102039099)
**Note**: The screen-cast uses <kbd>Control</kbd><kbd>y</kbd> for
"put selection". Use <kbd>Y</kbd> in `v2.0.0` and later.
### Other tmux plugins
- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin
for regular expression searches in tmux and fast match selection
- [tmux-open](https://github.com/tmux-plugins/tmux-open) - a plugin for
quickly opening highlighted file or a URL
- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) -
automatic restoring and continuous saving of tmux environment.
Tmux yank works well with
[tmux copycat](https://github.com/tmux-plugins/tmux-copycat) and
[tmux-open](https://github.com/tmux-plugins/tmux-open) plugins.
### License

View file

@ -1 +0,0 @@
theme: jekyll-theme-slate

30
citest
View file

@ -1,30 +0,0 @@
#!/bin/bash
set -euo pipefail
cd "$(dirname "$0")"
bash_scripts=(
yank.tmux
scripts/*.sh
)
set -x
docker run \
--rm \
--volume="${PWD}:/mnt:ro" \
--workdir="/mnt" \
bash:latest \
bash -Dn "${bash_scripts[@]}"
docker run \
--rm \
--volume="${PWD}:/mnt:ro" \
--workdir="/mnt" \
koalaman/shellcheck:stable \
--shell=bash \
--external-sources \
--color=always \
"${bash_scripts[@]}"
# EOF

View file

@ -1,111 +1,91 @@
#!/usr/bin/env bash
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HELPERS_DIR="$CURRENT_DIR"
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
TMUX_COPY_MODE=""
REMOTE_SHELL_WAIT_TIME="0.4"
# shellcheck source=scripts/helpers.sh
source "${HELPERS_DIR}/helpers.sh"
source "$CURRENT_DIR/key_binding_helpers.sh"
# sets a TMUX_COPY_MODE that is used as a global variable
get_tmux_copy_mode() {
TMUX_COPY_MODE="$(tmux show-option -gwv mode-keys)"
TMUX_COPY_MODE="$(tmux show-option -gwv mode-keys)"
}
# The command when on ssh with latency. To make it work in this case too,
# sleep is added.
add_sleep_for_remote_shells() {
local pane_command
pane_command="$(tmux display-message -p '#{pane_current_command}')"
if [[ $pane_command =~ (ssh|mosh) ]]; then
sleep "$REMOTE_SHELL_WAIT_TIME"
fi
local pane_command="$(tmux display-message -p '#{pane_current_command}')"
if [[ "$pane_command" =~ (ssh|mosh) ]]; then
sleep "$REMOTE_SHELL_WAIT_TIME"
fi
}
go_to_the_beginning_of_current_line() {
if [ "$(shell_mode)" == "emacs" ]; then
tmux send-key 'C-a'
else
tmux send-key 'Escape' '0'
fi
tmux send-key 'C-a'
add_sleep_for_remote_shells
}
enter_tmux_copy_mode() {
tmux copy-mode
tmux copy-mode
}
start_tmux_selection() {
if tmux_is_at_least 2.4; then
tmux send -X begin-selection
elif [ "$TMUX_COPY_MODE" == "vi" ]; then
# vi copy mode
tmux send-key 'Space'
else
# emacs copy mode
tmux send-key 'C-Space'
fi
if [ "$TMUX_COPY_MODE" == "vi" ]; then
# vi copy mode
tmux send-key 'Space'
else
# emacs copy mode
tmux send-key 'C-Space'
fi
}
# works when command spans accross multiple lines
end_of_line_in_copy_mode() {
if tmux_is_at_least 2.4; then
tmux send -X -N 150 'cursor-down' # 'down' key. 'vi' mode is faster so we're
# jumping more lines than emacs.
tmux send -X 'end-of-line' # End of line (just in case we are already at the last line).
tmux send -X 'previous-word' # Beginning of the previous word.
tmux send -X 'next-word-end' # End of next word.
elif [ "$TMUX_COPY_MODE" == "vi" ]; then
# vi copy mode
# This sequence of keys consistently selects multiple lines
tmux send-key '150' # Go to the bottom of scrollback buffer by using
tmux send-key 'j' # 'down' key. 'vi' mode is faster so we're
# jumping more lines than emacs.
tmux send-key '$' # End of line (just in case we are already at the last line).
tmux send-key 'b' # Beginning of the previous word.
tmux send-key 'e' # End of next word.
else
# emacs copy mode
for ((c = 1; c <= '30'; c++)); do # go to the bottom of scrollback buffer
tmux send-key 'C-n'
done
tmux send-key 'C-e'
tmux send-key 'M-b'
tmux send-key 'M-f'
fi
if [ "$TMUX_COPY_MODE" == "vi" ]; then
# vi copy mode
# This sequence of keys consistently selects multiple lines
tmux send-key '150' # Go to the bottom of scrollback buffer by using
tmux send-key 'j' # 'down' key. 'vi' mode is faster so we're
# jumping more lines than emacs.
tmux send-key '$' # End of line (just in case we are already at the last line).
tmux send-key 'b' # Beginning of the previous word.
tmux send-key 'e' # End of next word.
else
# emacs copy mode
for (( c=1; c<='30'; c++ )); do # go to the bottom of scrollback buffer
tmux send-key 'C-n'
done
tmux send-key 'C-e'
tmux send-key 'M-b'
tmux send-key 'M-f'
fi
}
yank_to_clipboard() {
if tmux_is_at_least 2.4; then
# shellcheck disable=SC2119
tmux send -X copy-pipe-and-cancel "$(clipboard_copy_command)"
else
tmux send-key "$(yank_wo_newline_key)"
fi
tmux send-key "$(yank_wo_newline_key)"
}
go_to_the_end_of_current_line() {
if [ "$(shell_mode)" == "emacs" ]; then
tmux send-keys 'C-e'
else
tmux send-keys '$' 'a'
fi
tmux send-keys 'C-e'
}
display_notice() {
display_message 'Line copied to clipboard!'
}
yank_current_line() {
go_to_the_beginning_of_current_line
add_sleep_for_remote_shells
enter_tmux_copy_mode
start_tmux_selection
end_of_line_in_copy_mode
yank_to_clipboard
go_to_the_end_of_current_line
display_message 'Line copied to clipboard!'
go_to_the_beginning_of_current_line
enter_tmux_copy_mode
start_tmux_selection
end_of_line_in_copy_mode
yank_to_clipboard
go_to_the_end_of_current_line
display_notice
}
main() {
get_tmux_copy_mode
yank_current_line
get_tmux_copy_mode
yank_current_line
}
main

View file

@ -1,28 +0,0 @@
#!/usr/bin/env bash
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
HELPERS_DIR="$CURRENT_DIR"
# shellcheck source=scripts/helpers.sh
source "${HELPERS_DIR}/helpers.sh"
pane_current_path() {
tmux display -p -F "#{pane_current_path}"
}
display_notice() {
display_message 'PWD copied to clipboard!'
}
main() {
local copy_command
local payload
# shellcheck disable=SC2119
copy_command="$(clipboard_copy_command)"
payload="$(pane_current_path | tr -d '\n')"
# $copy_command below should not be quoted
echo "$payload" | $copy_command
tmux set-buffer "$payload"
display_notice
}
main

View file

@ -1,208 +0,0 @@
#!bash
# shellcheck disable=SC2239
yank_line="y"
yank_line_option="@yank_line"
yank_pane_pwd="Y"
yank_pane_pwd_option="@yank_pane_pwd"
yank_default="y"
yank_option="@copy_mode_yank"
put_default="Y"
put_option="@copy_mode_put"
yank_put_default="M-y"
yank_put_option="@copy_mode_yank_put"
yank_wo_newline_default="!"
yank_wo_newline_option="@copy_mode_yank_wo_newline"
yank_selection_default="clipboard"
yank_selection_option="@yank_selection"
yank_selection_mouse_default="primary"
yank_selection_mouse_option="@yank_selection_mouse"
yank_with_mouse_default="on"
yank_with_mouse_option="@yank_with_mouse"
yank_action_default="copy-pipe-and-cancel"
yank_action_option="@yank_action"
shell_mode_default="emacs"
shell_mode_option="@shell_mode"
custom_copy_command_default=""
custom_copy_command_option="@custom_copy_command"
override_copy_command_default=""
override_copy_command_option="@override_copy_command"
# helper functions
get_tmux_option() {
local option="$1"
local default_value="$2"
local option_value
option_value=$(tmux show-option -gqv "$option")
if [ -z "$option_value" ]; then
echo "$default_value"
else
echo "$option_value"
fi
}
yank_line_key() {
get_tmux_option "$yank_line_option" "$yank_line"
}
yank_pane_pwd_key() {
get_tmux_option "$yank_pane_pwd_option" "$yank_pane_pwd"
}
yank_key() {
get_tmux_option "$yank_option" "$yank_default"
}
put_key() {
get_tmux_option "$put_option" "$put_default"
}
yank_put_key() {
get_tmux_option "$yank_put_option" "$yank_put_default"
}
yank_wo_newline_key() {
get_tmux_option "$yank_wo_newline_option" "$yank_wo_newline_default"
}
yank_selection() {
get_tmux_option "$yank_selection_option" "$yank_selection_default"
}
yank_selection_mouse() {
get_tmux_option "$yank_selection_mouse_option" "$yank_selection_mouse_default"
}
yank_with_mouse() {
get_tmux_option "$yank_with_mouse_option" "$yank_with_mouse_default"
}
yank_action() {
get_tmux_option "$yank_action_option" "$yank_action_default"
}
shell_mode() {
get_tmux_option "$shell_mode_option" "$shell_mode_default"
}
custom_copy_command() {
get_tmux_option "$custom_copy_command_option" "$custom_copy_command_default"
}
override_copy_command() {
get_tmux_option "$override_copy_command_option" "$override_copy_command_default"
}
# Ensures a message is displayed for 5 seconds in tmux prompt.
# Does not override the 'display-time' tmux option.
display_message() {
local message="$1"
# display_duration defaults to 5 seconds, if not passed as an argument
if [ "$#" -eq 2 ]; then
local display_duration="$2"
else
local display_duration="5000"
fi
# saves user-set 'display-time' option
local saved_display_time
saved_display_time=$(get_tmux_option "display-time" "750")
# sets message display time to 5 seconds
tmux set-option -gq display-time "$display_duration"
# displays message
tmux display-message "$message"
# restores original 'display-time' value
tmux set-option -gq display-time "$saved_display_time"
}
command_exists() {
local command="$1"
type "$command" >/dev/null 2>&1
}
clipboard_copy_command() {
local mouse="${1:-false}"
# installing reattach-to-user-namespace is recommended on OS X
if [ -n "$(override_copy_command)" ]; then
override_copy_command
elif command_exists "pbcopy"; then
if command_exists "reattach-to-user-namespace"; then
echo "reattach-to-user-namespace pbcopy"
else
echo "pbcopy"
fi
elif command_exists "clip.exe"; then # WSL clipboard command
echo "cat | clip.exe"
elif command_exists "wl-copy"; then # wl-clipboard: Wayland clipboard utilities
echo "wl-copy"
elif command_exists "xsel"; then
local xsel_selection
if [[ $mouse == "true" ]]; then
xsel_selection="$(yank_selection_mouse)"
else
xsel_selection="$(yank_selection)"
fi
echo "xsel -i --$xsel_selection"
elif command_exists "xclip"; then
local xclip_selection
if [[ $mouse == "true" ]]; then
xclip_selection="$(yank_selection_mouse)"
else
xclip_selection="$(yank_selection)"
fi
echo "xclip -selection $xclip_selection"
elif command_exists "putclip"; then # cygwin clipboard command
echo "putclip"
elif [ -n "$(custom_copy_command)" ]; then
custom_copy_command
fi
}
# Cache the TMUX version for speed.
tmux_version="$(tmux -V | cut -d ' ' -f 2 | sed 's/next-//')"
tmux_is_at_least() {
if [[ $tmux_version == "$1" ]] || [[ $tmux_version == master ]]; then
return 0
fi
local i
local -a current_version wanted_version
IFS='.' read -ra current_version <<<"$tmux_version"
IFS='.' read -ra wanted_version <<<"$1"
# fill empty fields in current_version with zeros
for ((i = ${#current_version[@]}; i < ${#wanted_version[@]}; i++)); do
current_version[i]=0
done
# fill empty fields in wanted_version with zeros
for ((i = ${#wanted_version[@]}; i < ${#current_version[@]}; i++)); do
wanted_version[i]=0
done
for ((i = 0; i < ${#current_version[@]}; i++)); do
if ((10#${current_version[i]} < 10#${wanted_version[i]})); then
return 1
fi
if ((10#${current_version[i]} > 10#${wanted_version[i]})); then
return 0
fi
done
return 0
}

View file

@ -0,0 +1,78 @@
yank_line="y"
yank_line_option="@yank_line"
yank_default="y"
yank_option="@copy_mode_yank"
put_default="Y"
put_option="@copy_mode_put"
yank_put_default="M-y"
yank_put_option="@copy_mode_yank_put"
yank_wo_newline_default="!"
yank_wo_newline_option="@copy_mode_yank_wo_newline"
yank_xclip_selection_default="c"
yank_xclip_selection_option="@yank_selection"
# helper functions
get_tmux_option() {
local option="$1"
local default_value="$2"
local option_value=$(tmux show-option -gqv "$option")
if [ -z "$option_value" ]; then
echo "$default_value"
else
echo "$option_value"
fi
}
yank_line_key() {
echo "$(get_tmux_option "$yank_line_option" "$yank_line")"
}
yank_key() {
echo "$(get_tmux_option "$yank_option" "$yank_default")"
}
put_key() {
echo "$(get_tmux_option "$put_option" "$put_default")"
}
yank_put_key() {
echo "$(get_tmux_option "$yank_put_option" "$yank_put_default")"
}
yank_wo_newline_key() {
echo "$(get_tmux_option "$yank_wo_newline_option" "$yank_wo_newline_default")"
}
yank_xclip_selection() {
echo "$(get_tmux_option "$yank_xclip_selection_option" "$yank_xclip_selection_default")"
}
# Ensures a message is displayed for 5 seconds in tmux prompt.
# Does not override the 'display-time' tmux option.
display_message() {
local message="$1"
# display_duration defaults to 5 seconds, if not passed as an argument
if [ "$#" -eq 2 ]; then
local display_duration="$2"
else
local display_duration="5000"
fi
# saves user-set 'display-time' option
local saved_display_time=$(get_tmux_option "display-time" "750")
# sets message display time to 5 seconds
tmux set-option -gq display-time "$display_duration"
# displays message
tmux display-message "$message"
# restores original 'display-time' value
tmux set-option -gq display-time "$saved_display_time"
}

View file

@ -8,6 +8,3 @@
sudo add-apt-repository -y ppa:pi-rho/dev
sudo apt-get update
sudo apt-get install -y tmux=1.9a-1~ppa1~p
# configure X11 for xclip testing
echo "export DISPLAY='IP:0.0'" >>/home/vagrant/.bashrc

114
yank.tmux
View file

@ -1,92 +1,70 @@
#!/usr/bin/env bash
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SCRIPTS_DIR="${CURRENT_DIR}/scripts"
HELPERS_DIR="${CURRENT_DIR}/scripts"
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# shellcheck source=scripts/helpers.sh
source "${HELPERS_DIR}/helpers.sh"
source "$CURRENT_DIR/scripts/key_binding_helpers.sh"
command_exists() {
local command="$1"
type "$command" >/dev/null 2>&1
}
clipboard_copy_command() {
# reattach-to-user-namespace is required for OS X
if command_exists "pbcopy" && command_exists "reattach-to-user-namespace"; then
echo "reattach-to-user-namespace pbcopy"
elif command_exists "xclip"; then
local xclip_selection="$(yank_xclip_selection)"
echo "xclip -selection $xclip_selection"
fi
}
clipboard_copy_without_newline_command() {
local copy_command="$1"
printf "tr -d '\\n' | %s" "$copy_command"
local copy_command="$1"
echo "tr -d '\n' | $copy_command"
}
set_error_bindings() {
local key_bindings key
key_bindings="$(yank_key) $(put_key) $(yank_put_key)"
for key in $key_bindings; do
if tmux_is_at_least 2.4; then
tmux bind-key -T copy-mode-vi "$key" send-keys -X copy-pipe-and-cancel "tmux display-message 'Error! tmux-yank dependencies not installed!'"
tmux bind-key -T copy-mode "$key" send-keys -X copy-pipe-and-cancel "tmux display-message 'Error! tmux-yank dependencies not installed!'"
else
tmux bind-key -t vi-copy "$key" copy-pipe "tmux display-message 'Error! tmux-yank dependencies not installed!'"
tmux bind-key -t emacs-copy "$key" copy-pipe "tmux display-message 'Error! tmux-yank dependencies not installed!'"
fi
done
local key_bindings="$(yank_key) $(put_key) $(yank_put_key)"
local key
for key in $key_bindings; do
tmux bind-key -t vi-copy "$key" copy-pipe "tmux display-message 'Error! tmux-yank dependencies not installed!'"
tmux bind-key -t emacs-copy "$key" copy-pipe "tmux display-message 'Error! tmux-yank dependencies not installed!'"
done
}
error_handling_if_command_not_present() {
local copy_command="$1"
if [ -z "$copy_command" ]; then
set_error_bindings
exit 0
fi
local copy_command="$1"
if [ -z "$copy_command" ]; then
set_error_bindings
exit 0
fi
}
# `yank_without_newline` binding isn't intended to be used by the user. It is
# a helper for `copy_line` command.
set_copy_mode_bindings() {
local copy_command="$1"
local copy_wo_newline_command
copy_wo_newline_command="$(clipboard_copy_without_newline_command "$copy_command")"
local copy_command_mouse
copy_command_mouse="$(clipboard_copy_command "true")"
if tmux_is_at_least 2.4; then
tmux bind-key -T copy-mode-vi "$(yank_key)" send-keys -X "$(yank_action)" "$copy_command"
tmux bind-key -T copy-mode-vi "$(put_key)" send-keys -X copy-pipe-and-cancel "tmux paste-buffer -p"
tmux bind-key -T copy-mode-vi "$(yank_put_key)" send-keys -X copy-pipe-and-cancel "$copy_command; tmux paste-buffer -p"
tmux bind-key -T copy-mode-vi "$(yank_wo_newline_key)" send-keys -X "$(yank_action)" "$copy_wo_newline_command"
if [[ "$(yank_with_mouse)" == "on" ]]; then
tmux bind-key -T copy-mode-vi MouseDragEnd1Pane send-keys -X "$(yank_action)" "$copy_command_mouse"
fi
local copy_command="$1"
local copy_wo_newline_command="$(clipboard_copy_without_newline_command "$copy_command")"
tmux bind-key -t vi-copy "$(yank_key)" copy-pipe "$copy_command"
tmux bind-key -t vi-copy "$(put_key)" copy-pipe "tmux paste-buffer"
tmux bind-key -t vi-copy "$(yank_put_key)" copy-pipe "$copy_command; tmux paste-buffer"
tmux bind-key -t vi-copy "$(yank_wo_newline_key)" copy-pipe "$copy_wo_newline_command"
tmux bind-key -T copy-mode "$(yank_key)" send-keys -X "$(yank_action)" "$copy_command"
tmux bind-key -T copy-mode "$(put_key)" send-keys -X copy-pipe-and-cancel "tmux paste-buffer -p"
tmux bind-key -T copy-mode "$(yank_put_key)" send-keys -X copy-pipe-and-cancel "$copy_command; tmux paste-buffer -p"
tmux bind-key -T copy-mode "$(yank_wo_newline_key)" send-keys -X "$(yank_action)" "$copy_wo_newline_command"
if [[ "$(yank_with_mouse)" == "on" ]]; then
tmux bind-key -T copy-mode MouseDragEnd1Pane send-keys -X "$(yank_action)" "$copy_command_mouse"
fi
else
tmux bind-key -t vi-copy "$(yank_key)" copy-pipe "$copy_command"
tmux bind-key -t vi-copy "$(put_key)" copy-pipe "tmux paste-buffer -p"
tmux bind-key -t vi-copy "$(yank_put_key)" copy-pipe "$copy_command; tmux paste-buffer -p"
tmux bind-key -t vi-copy "$(yank_wo_newline_key)" copy-pipe "$copy_wo_newline_command"
if [[ "$(yank_with_mouse)" == "on" ]]; then
tmux bind-key -t vi-copy MouseDragEnd1Pane copy-pipe "$copy_command_mouse"
fi
tmux bind-key -t emacs-copy "$(yank_key)" copy-pipe "$copy_command"
tmux bind-key -t emacs-copy "$(put_key)" copy-pipe "tmux paste-buffer -p"
tmux bind-key -t emacs-copy "$(yank_put_key)" copy-pipe "$copy_command; tmux paste-buffer -p"
tmux bind-key -t emacs-copy "$(yank_wo_newline_key)" copy-pipe "$copy_wo_newline_command"
if [[ "$(yank_with_mouse)" == "on" ]]; then
tmux bind-key -t emacs-copy MouseDragEnd1Pane copy-pipe "$copy_command_mouse"
fi
fi
tmux bind-key -t emacs-copy "$(yank_key)" copy-pipe "$copy_command"
tmux bind-key -t emacs-copy "$(put_key)" copy-pipe "tmux paste-buffer"
tmux bind-key -t emacs-copy "$(yank_put_key)" copy-pipe "$copy_command; tmux paste-buffer"
tmux bind-key -t emacs-copy "$(yank_wo_newline_key)" copy-pipe "$copy_wo_newline_command"
}
set_normal_bindings() {
tmux bind-key "$(yank_line_key)" run-shell -b "$SCRIPTS_DIR/copy_line.sh"
tmux bind-key "$(yank_pane_pwd_key)" run-shell -b "$SCRIPTS_DIR/copy_pane_pwd.sh"
set_copy_line_bindings() {
tmux bind-key "$(yank_line_key)" run-shell "$CURRENT_DIR/scripts/copy_line.sh"
}
main() {
local copy_command
copy_command="$(clipboard_copy_command)"
error_handling_if_command_not_present "$copy_command"
set_copy_mode_bindings "$copy_command"
set_normal_bindings
local copy_command="$(clipboard_copy_command)"
error_handling_if_command_not_present "$copy_command"
set_copy_mode_bindings "$copy_command"
set_copy_line_bindings
}
main