45 Commits

Author SHA1 Message Date
631e09f428 chore: format files with shfmt and resolve most shellcheck complaints 2024-02-18 02:16:59 +00:00
6cd89beb5e chore(lib): remove use of eval 2024-02-18 01:36:28 +00:00
895dace853 fix(layout-helpers): split_h/split_v work correctly on latest tmux (#99)
The `-p` flag on `split-window` was deprecated in Tmux 3.1 in favor of
just adding a `%` suffix to the numeric value given to the `-l` flag.

This uses the new `-l <n>%` format on Tmux 3.1 and later, and uses the
old `-p <n>` format on 3.0 and older.
2024-02-18 00:42:44 +00:00
2b6239c6f0 Merge pull request #96 from gabyx/patch-1
fix: Wrong link in help command
2024-02-18 00:28:53 +00:00
de509d8a08 Merge pull request #95 from joaopedroaat/master
Bugfix: add fix to tmux next-* versions.
2024-02-18 00:28:39 +00:00
Gabriel Nützi
67ee31d783 fix: Wrong link in help command 2024-01-17 13:25:55 +01:00
João Pedro
2e4d5197ae Remove incorrect formatting. 2024-01-09 14:54:23 -03:00
João Pedro
c2cbd5d7ea Bugfix: add fix to tmux next-* versions. 2024-01-06 17:38:36 -03:00
fe1f6c4734 docs(readme): add TPM installation instructions 2023-04-11 19:24:15 +01:00
d147958750 docs(readme): format readme with prettier-js 2023-04-11 19:23:52 +01:00
957229a1e8 Merge pull request #88 from 0inp/master 2023-04-11 18:54:19 +01:00
Stephane Point
ea4a7aa57c Add TPM support 2023-04-09 14:17:14 -05:00
8987dd4492 Bump version to 0.13.0 2017-04-27 19:49:05 +01:00
9049818b25 Add optional target window argument to newly added layout helpers 2017-04-27 19:48:15 +01:00
47ef3bd857 Merge pull request #75 from leesei/sort-list
feat: sort sessions and windows list
2017-04-27 19:32:01 +01:00
a9ca566c28 Merge pull request #73 from Yuki-Inoue/synchronize-helper-methods
Add synchronize helper methods
2017-04-27 19:23:22 +01:00
87e31a03c9 Merge pull request #58 from mlavi/fish2-0-0
Accommodate fish shell 2.0.0
2017-04-27 19:21:02 +01:00
7f3ec1cd5b Merge pull request #76 from xsteve/feature/fix-has-session
Work around a problem with tmux has-session:
2017-04-27 19:18:49 +01:00
9baadfbb1e Bump version to 0.12.3 2017-04-27 18:59:38 +01:00
2adc885bb8 Fix issue with using a tmux version compiled source
Resolves #79.

When tmux is compiled from source the version string is "master" which
the tmux-version command didn't deal with correctly.
2017-04-27 18:59:38 +01:00
7cc0fa2d0e Fix typo in help text of tmux-version command 2017-04-27 18:59:38 +01:00
Stefan Reichoer
e41b15c515 Work around a problem with tmux has-session:
tmux has-session does a prefix match and not an exact match.

When a session "ABC" does exist, the session "A" is also interpreted as "ABC"
Using tmux list-sessions fixes this problem
2016-10-28 13:07:17 +02:00
leesei
690a4465b0 feat: sort sessions and windows list
On branch sort-list
Changes to be committed:
	modified:   libexec/tmuxifier-list-sessions
	modified:   libexec/tmuxifier-list-windows
2016-08-19 23:14:08 +08:00
Yuki Inoue
9bcfbd3428 Add synchronize helper methods 2016-05-09 12:34:48 +09:00
7aeeaf31d1 Merge pull request #71 from Yuki-Inoue/balance-windows-layout-helpers
Add balance_window helper methods
2016-04-28 18:35:42 +01:00
ca6dcfaaf2 Merge pull request #72 from Yuki-Inoue/fix-ci-use-github
Fix tmux sourcecode url to github
2016-04-28 18:30:26 +01:00
Yuki Inoue
fdbb1704e0 Fix tmux sourcecode url to github
The sourceforge project of tmux seems to have been removed.  So,
wgetting from github releases instead of sourceforge.
2016-04-28 22:08:30 +09:00
Yuki Inoue
499c5abd83 Add balance_window helper methods 2016-04-28 15:17:05 +09:00
3563c3d975 Bump version to 0.12.2 2016-04-02 22:28:37 +01:00
3bfbc50918 Merge pull request #70 from blueyed/fix-load-session
Fixes for load_session with file in current dir
2016-04-02 22:26:23 +01:00
Daniel Hahler
3a8a43ccdc style: load_session: move return case up, removing indent 2016-04-02 22:38:40 +02:00
Daniel Hahler
a9a87992df load_session: prefer existing session instead of file in cwd
This also adds './' to a file used from the current working dir (in case
there is no session with that name), which is required for Bash's
`source` to use it (and not look for it in `$PATH`).

Fixes https://github.com/jimeh/tmuxifier/issues/69.
2016-04-02 22:38:25 +02:00
5f4dd92d7f Merge pull request #66 from shalecraig/patch-1
Update link to iterm2
2016-01-26 23:09:54 +00:00
shale
bdaa272ca5 Update link to iterm2
iterm2 moved to gitlab from google project hosting.
2016-01-19 10:30:28 -08:00
dce4fb3ad2 Merge pull request #65 from bchretien/topic/window-rename
new_window: disable allow-rename if a window name was given
2015-12-20 23:38:43 +00:00
Benjamin Chrétien
6f8773133d new_window: disable allow-rename if a window name was given 2015-12-15 17:53:45 +01:00
92d188f9f5 Bump version to 0.12.1 2015-07-25 13:38:00 +01:00
8d1751daea Merge pull request #62 from jimeh/fix-issue-61
Fix issue #61
2015-07-25 13:35:24 +01:00
dafa938923 Add Tmux 2.0 to Travis-CI test environments 2015-07-25 13:27:12 +01:00
595269dd6a Make load-window within a session adhere to session_root setting
This should fix #61. Previously when you manually ran `tmuxifier
load-window` from within a session created by Tmuxifier, the
`session_root` path set in the session was ignored, and the new window
would be cd'd to `$HOME` unless the window configuration had
`window_root` set.
2015-07-25 13:24:02 +01:00
Mark Lavi
3c37e18987 Accommodate fish shell 2.0.0 2015-03-22 00:38:17 -07:00
b801aade99 Bump version to 0.12.0 2014-12-02 22:23:37 +00:00
a888efe6d0 Update __go_to_session layout helper test 2014-12-02 22:22:09 +00:00
4a4f62fcf2 Improve/fix help messages for a few commands 2014-12-01 21:03:26 +00:00
41da75ad39 Add support for iTerm2's Tmux integration
This should resolve #52.
2014-12-01 21:01:58 +00:00
37 changed files with 453 additions and 231 deletions

View File

@@ -4,10 +4,11 @@ env:
- TMUX_VERSION="1.7" - TMUX_VERSION="1.7"
- TMUX_VERSION="1.8" - TMUX_VERSION="1.8"
- TMUX_VERSION="1.9a" - TMUX_VERSION="1.9a"
- TMUX_VERSION="2.0"
before_install: before_install:
- sudo apt-get update - sudo apt-get update
- sudo apt-get install -y bc build-essential libevent-dev libncurses5-dev - sudo apt-get install -y bc build-essential libevent-dev libncurses5-dev
- wget http://downloads.sourceforge.net/tmux/tmux-${TMUX_VERSION}.tar.gz - wget https://github.com/tmux/tmux/releases/download/${TMUX_VERSION}/tmux-${TMUX_VERSION}.tar.gz
- tar -zxf tmux-${TMUX_VERSION}.tar.gz - tar -zxf tmux-${TMUX_VERSION}.tar.gz
- cd tmux-${TMUX_VERSION} - cd tmux-${TMUX_VERSION}
- ./configure && make && sudo make install - ./configure && make && sudo make install

150
README.md
View File

@@ -3,18 +3,18 @@
Tmuxify your Tmux. Create, edit, manage and load complex Tmux session, window Tmuxify your Tmux. Create, edit, manage and load complex Tmux session, window
and pane configurations with ease. and pane configurations with ease.
In short, Tmuxifier allows you to easily create, edit, and load "layout" In short, Tmuxifier allows you to easily create, edit, and load "layout" files,
files, which are simple shell scripts where you use the `tmux` command and which are simple shell scripts where you use the `tmux` command and helper
helper commands provided by `tmuxifier` to manage Tmux sessions and windows commands provided by `tmuxifier` to manage Tmux sessions and windows
### Window Layouts ### Window Layouts
Window layouts create a new Tmux window, optionally setting the window title Window layouts create a new Tmux window, optionally setting the window title and
and root path where all shells are cd'd to by default. It allows you to easily root path where all shells are cd'd to by default. It allows you to easily split
split a window into specifically sized panes and more as you wish. a window into specifically sized panes and more as you wish.
You can load a window layout directly into your current Tmux session, or into You can load a window layout directly into your current Tmux session, or into a
a session layout to have the window created along with the session. session layout to have the window created along with the session.
### Session Layouts ### Session Layouts
@@ -25,10 +25,11 @@ defined directly within the session layout file.
## Example ## Example
Given we have a window layout file called [example.window.sh][] which Given we have a window layout file called [example.window.sh][] which looks
looks like: like:
[example.window.sh]: https://github.com/jimeh/tmuxifier/blob/master/examples/example.window.sh [example.window.sh]:
https://github.com/jimeh/tmuxifier/blob/master/examples/example.window.sh
```bash ```bash
window_root "~/Desktop" window_root "~/Desktop"
@@ -39,8 +40,8 @@ split_h 60
select_pane 0 select_pane 0
``` ```
You can then load that window layout into a new window in the You can then load that window layout into a new window in the current tmux
current tmux session using: session using:
tmuxifier load-window example tmuxifier load-window example
@@ -50,6 +51,8 @@ Which will yield a Tmux window looking like this:
## Installation ## Installation
### Manual
Clone the repo to your machine: Clone the repo to your machine:
git clone https://github.com/jimeh/tmuxifier.git ~/.tmuxifier git clone https://github.com/jimeh/tmuxifier.git ~/.tmuxifier
@@ -57,33 +60,49 @@ Clone the repo to your machine:
Then add `$HOME/.tmuxifier/bin` to your PATH to make the `tmuxifier` executable Then add `$HOME/.tmuxifier/bin` to your PATH to make the `tmuxifier` executable
available to you: available to you:
__In bash & zsh:__ **In bash & zsh:**
```bash ```bash
export PATH="$HOME/.tmuxifier/bin:$PATH" export PATH="$HOME/.tmuxifier/bin:$PATH"
``` ```
__In tcsh:__ **In tcsh:**
```tcsh ```tcsh
set path = ( "~/.tmuxifier/bin" $path ) set path = ( "~/.tmuxifier/bin" $path )
``` ```
__In fish:__ **In fish:**
```bash ```bash
set -gx PATH "~/.tmuxifier/bin" $PATH set -gx PATH "~/.tmuxifier/bin" $PATH
``` ```
### Custom Installation Path #### Custom Installation Path
To install Tmuxifier somewhere else than the suggested `~/.tmuxifier`, simply To install Tmuxifier somewhere else than the suggested `~/.tmuxifier`, simply
clone the repository to your custom location, and ensure the `bin` folder is clone the repository to your custom location, and ensure the `bin` folder is
added to your PATH making the `tmuxifier` executable available to you. added to your PATH making the `tmuxifier` executable available to you.
### TPM
You can also install and update Tmuxifier with
[TPM](https://github.com/tmux-plugins/tpm):
```bash
set -g @plugin 'jimeh/tmuxifier'
```
Trigger TPM's install command with `prefix` + `I` to install Tmuxifier to TPM's
plugin directory (default is `$HOME/.tmux/plugins`).
To use the `tmuxifier` command, you will need to add the `bin` directory to your
PATH. If you are using the default TPM plugin directory, the `bin` directory
will be `$HOME/.tmux/plugins/tmuxifier/bin`.
## Setup ## Setup
__In bash & zsh:__ **In bash & zsh:**
And add the following to your `~/.profile`, `~/.bash_profile`, `~/.zshrc` or And add the following to your `~/.profile`, `~/.bash_profile`, `~/.zshrc` or
equivalent: equivalent:
@@ -92,7 +111,7 @@ equivalent:
eval "$(tmuxifier init -)" eval "$(tmuxifier init -)"
``` ```
__In tcsh:__ **In tcsh:**
Add the following to your `~/.cshrc`, `~/.tcshrc` or equivalent: Add the following to your `~/.cshrc`, `~/.tcshrc` or equivalent:
@@ -100,19 +119,19 @@ Add the following to your `~/.cshrc`, `~/.tcshrc` or equivalent:
eval `tmuxifier init -` eval `tmuxifier init -`
``` ```
__In fish:__ **In fish:**
And add the following to your `~/.config/fish/config.fish` or equivalent: And add the following to your `~/.config/fish/config.fish` or equivalent:
```bash ```bash
eval (tmuxifier init -) eval (tmuxifier init - fish)
``` ```
### Custom Tmux Arguments ### Custom Tmux Arguments
If you need to pass custom arguments to `tmux` itself, you can do so by If you need to pass custom arguments to `tmux` itself, you can do so by setting
setting the `TMUXIFIER_TMUX_OPTS` environment variable. For example to set the `TMUXIFIER_TMUX_OPTS` environment variable. For example to set custom
custom arguments globally: arguments globally:
```bash ```bash
export TMUXIFIER_TMUX_OPTS="-L my-awesome-socket-name" export TMUXIFIER_TMUX_OPTS="-L my-awesome-socket-name"
@@ -134,7 +153,7 @@ git pull
## Usage ## Usage
*__Note:__ This section needs expanding upon.* _**Note:** This section needs expanding upon._
For a quick reference on available commands and their aliases, please run: For a quick reference on available commands and their aliases, please run:
@@ -142,8 +161,8 @@ For a quick reference on available commands and their aliases, please run:
Tmuxifier doesn't come with any layouts, so you'll want to create your own Tmuxifier doesn't come with any layouts, so you'll want to create your own
window and session layout files. New layout files are populated with examples window and session layout files. New layout files are populated with examples
and comments explaining what things do. Also, having a look at the and comments explaining what things do. Also, having a look at the [examples][]
[examples][] directory will also give you a good idea. directory will also give you a good idea.
### Window Layouts ### Window Layouts
@@ -151,16 +170,16 @@ First off you'll want to define a window layout:
tmuxifier new-window my-awesome-window tmuxifier new-window my-awesome-window
This will create a new layout file called `my-awesome-window.window.sh` in This will create a new layout file called `my-awesome-window.window.sh` in your
your `$TMUXIFIER_LAYOUT_PATH`, and open it with the editor defined in `$TMUXIFIER_LAYOUT_PATH`, and open it with the editor defined in `$EDITOR`.
`$EDITOR`. Customize it as you wish, and save. Customize it as you wish, and save.
You can now load *my-awesome-window* with the following command: You can now load _my-awesome-window_ with the following command:
tmuxifier load-window my-awesome-window tmuxifier load-window my-awesome-window
You should now have a new Tmux window open created from your custom and You should now have a new Tmux window open created from your custom and awesome
awesome window layout. window layout.
### Session Layouts ### Session Layouts
@@ -170,8 +189,9 @@ To create your first session layout, run:
Same deal as with creating a new window, except the filename ends with Same deal as with creating a new window, except the filename ends with
`.session.sh` instead of `.window.sh`, and the file's pre-populated content `.session.sh` instead of `.window.sh`, and the file's pre-populated content
looks different. To have your awesome window loaded, add `load_window looks different. To have your awesome window loaded, add
"my-awesome-window"` to the session layout next to existing examples. `load_window "my-awesome-window"` to the session layout next to existing
examples.
To load the session layout simply run: To load the session layout simply run:
@@ -195,13 +215,28 @@ export TMUXIFIER_LAYOUT_PATH="$HOME/.tmux-layouts"
### Disable Shell-Completion ### Disable Shell-Completion
Tmuxifier comes with shell-completion for bash, zsh, tcsh, and fish. If for Tmuxifier comes with shell-completion for bash, zsh, tcsh, and fish. If for any
any reason you need to disable it, just set `$TMUXIFIER_NO_COMPLETE`. reason you need to disable it, just set `$TMUXIFIER_NO_COMPLETE`.
```bash ```bash
export TMUXIFIER_NO_COMPLETE=1 export TMUXIFIER_NO_COMPLETE=1
``` ```
## Tips
### iTerm2 Integration
Tmuxifier supports iTerm2's [Tmux integration][]. It can be used in two ways:
- Passing `-CC` as a second argument to the `load-session` command. For example:
tmuxifier load-session my-awesome-session -CC
- Setting the `TMUXIFIER_TMUX_ITERM_ATTACH` environment variable to `-CC` before
calling the `load-session` command.
[tmux integration]: https://gitlab.com/gnachman/iterm2/wikis/TmuxIntegration
## Inspiration ## Inspiration
- Tmuxifier is largely inspired by [Tmuxinator][]. - Tmuxifier is largely inspired by [Tmuxinator][].
@@ -210,16 +245,16 @@ export TMUXIFIER_NO_COMPLETE=1
## Tmuxifier vs. Tmuxinator ## Tmuxifier vs. Tmuxinator
Though Tmuxifier is largely inspired by the excellent [Tmuxinator][] project, Though Tmuxifier is largely inspired by the excellent [Tmuxinator][] project, it
it does set itself apart in a number of ways: does set itself apart in a number of ways:
- Uses shell scripts to define Tmux sessions and windows instead of YAML - Uses shell scripts to define Tmux sessions and windows instead of YAML files.
files. The benefit is total control over Tmux, but the definition files are The benefit is total control over Tmux, but the definition files are more
more complicated to work with. complicated to work with.
- Instead of using a "project" concept, Tmuxifier uses a concept of "sessions" - Instead of using a "project" concept, Tmuxifier uses a concept of "sessions"
and "windows" just like Tmux itself. This allows you to load a whole session and "windows" just like Tmux itself. This allows you to load a whole session
with multiple pre-defined window configurations, or just load a single with multiple pre-defined window configurations, or just load a single window
window configuration into your existing session. configuration into your existing session.
- Tmuxifier is a set of shell scripts, meaning it doesn't require Ruby to be - Tmuxifier is a set of shell scripts, meaning it doesn't require Ruby to be
installed on the machine. installed on the machine.
@@ -228,8 +263,8 @@ it does set itself apart in a number of ways:
## Todos ## Todos
* Improve Readme, specially Usage section. - Improve Readme, specially Usage section.
* Write up a detailed reference for all available layout helper functions. - Write up a detailed reference for all available layout helper functions.
## License ## License
@@ -237,20 +272,19 @@ it does set itself apart in a number of ways:
Copyright (c) 2014 Jim Myhrberg. Copyright (c) 2014 Jim Myhrberg.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy of
of this software and associated documentation files (the "Software"), to deal this software and associated documentation files (the "Software"), to deal in
in the Software without restriction, including without limitation the rights the Software without restriction, including without limitation the rights to
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
copies of the Software, and to permit persons to whom the Software is the Software, and to permit persons to whom the Software is furnished to do so,
furnished to do so, subject to the following conditions: subject to the following conditions:
The above copyright notice and this permission notice shall be included in all The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SOFTWARE.

View File

@@ -3,12 +3,13 @@ set -e
[ -n "$TMUXIFIER_DEBUG" ] && set -x [ -n "$TMUXIFIER_DEBUG" ] && set -x
resolve_link() { resolve_link() {
$(type -p greadlink readlink | head -1) $1 $(type -p greadlink readlink | head -1) "$1"
} }
abs_dirname() { abs_dirname() {
local cwd="$(pwd)" local cwd
local path="$1" local path="$1"
cwd="$(pwd)"
while [ -n "$path" ]; do while [ -n "$path" ]; do
cd "${path%/*}" cd "${path%/*}"
@@ -22,11 +23,12 @@ abs_dirname() {
if [ -z "${TMUXIFIER}" ]; then if [ -z "${TMUXIFIER}" ]; then
# Set TMUXIFIER relative to the "tmuxifier" executable. # Set TMUXIFIER relative to the "tmuxifier" executable.
export TMUXIFIER="$(dirname "$(abs_dirname "$0")")" TMUXIFIER="$(dirname "$(abs_dirname "$0")")"
else else
# Strip any trailing slash (/) characters from TMUXIFIER variable. # Strip any trailing slash (/) characters from TMUXIFIER variable.
export TMUXIFIER="${TMUXIFIER%/}" TMUXIFIER="${TMUXIFIER%/}"
fi fi
export TMUXIFIER
# Load tmuxifier environment variables. # Load tmuxifier environment variables.
source "$TMUXIFIER/lib/env.sh" source "$TMUXIFIER/lib/env.sh"
@@ -38,29 +40,25 @@ export PATH="$TMUXIFIER/libexec:$PATH"
export TMUXIFIER_MIN_TMUX_VERSION="1.6" export TMUXIFIER_MIN_TMUX_VERSION="1.6"
if [ "$(tmuxifier-tmux-version "$TMUXIFIER_MIN_TMUX_VERSION")" == "<" ]; then if [ "$(tmuxifier-tmux-version "$TMUXIFIER_MIN_TMUX_VERSION")" == "<" ]; then
echo -e "ERROR: Tmuxifier requires Tmux v${TMUXIFIER_MIN_TMUX_VERSION}" \ echo -e "ERROR: Tmuxifier requires Tmux v${TMUXIFIER_MIN_TMUX_VERSION}" \
"or newer. You have v$(tmuxifier-tmux-version)." >&2 "or newer. You have v$(tmuxifier-tmux-version)." >&2
exit 1 exit 1
fi fi
# Parse given command # Parse given command
command="$1" command="$1"
case "$command" in case "$command" in
"" | "-h" | "--help" ) "" | "-h" | "--help")
echo -e "tmuxifier $(tmuxifier-version)\n$(tmuxifier-help)" >&2 echo -e "tmuxifier $(tmuxifier-version)\n$(tmuxifier-help)" >&2
;; ;;
"-v" | "--version")
"-v" | "--version" )
tmuxifier-version tmuxifier-version
;; ;;
*)
* )
! command_path="$(tmuxifier-resolve-command-path "$command")" ! command_path="$(tmuxifier-resolve-command-path "$command")"
if [ -z "$command_path" ]; then if [ -z "$command_path" ]; then
echo "tmuxifier: no such command '$command'" >&2 echo "tmuxifier: no such command '$command'" >&2
exit 1 exit 1
fi fi
shift 1 shift 1
exec "$command_path" "$@" exec "$command_path" "$@"
;; ;;

View File

@@ -3,11 +3,12 @@ _tmuxifier() {
local word="${COMP_WORDS[COMP_CWORD]}" local word="${COMP_WORDS[COMP_CWORD]}"
if [ "$COMP_CWORD" -eq 1 ]; then if [ "$COMP_CWORD" -eq 1 ]; then
COMPREPLY=( $(compgen -W "$(tmuxifier commands)" -- "$word") ) COMPREPLY=($(compgen -W "$(tmuxifier commands)" -- "$word"))
else else
local command="${COMP_WORDS[1]}" local command="${COMP_WORDS[1]}"
local completions="$(tmuxifier completions "$command")" local completions
COMPREPLY=( $(compgen -W "$completions" -- "$word") ) completions="$(tmuxifier completions "$command")"
COMPREPLY=($(compgen -W "$completions" -- "$word"))
fi fi
} }

View File

@@ -11,7 +11,10 @@ end
# If `tmuxifier` is available, and `$TMUXIFIER_NO_COMPLETE` is not set, then # If `tmuxifier` is available, and `$TMUXIFIER_NO_COMPLETE` is not set, then
# load Tmuxifier shell completion. # load Tmuxifier shell completion.
if test -n (which tmuxifier); and test -z $TMUXIFIER_NO_COMPLETE if test -n (which tmuxifier); and test -z $TMUXIFIER_NO_COMPLETE
source "$TMUXIFIER/completion/tmuxifier.fish" # fish shell 2.0.0 does not have the source alias
if [ (fish --version 2>| awk -F'version ' '{print $2}') = '2.0.0' ];
. "$TMUXIFIER/completion/tmuxifier.fish"
else
source "$TMUXIFIER/completion/tmuxifier.fish"
end
end end

View File

@@ -22,6 +22,10 @@ new_window() {
if [ -n "$2" ]; then local command=("$2"); fi if [ -n "$2" ]; then local command=("$2"); fi
tmuxifier-tmux new-window -t "$session:" "${winarg[@]}" "${command[@]}" tmuxifier-tmux new-window -t "$session:" "${winarg[@]}" "${command[@]}"
# Disable renaming if a window name was given.
if [ -n "$1" ]; then tmuxifier-tmux set-option -t "$1" allow-rename off; fi
window="$(__get_current_window_index)" window="$(__get_current_window_index)"
__go_to_window_or_session_path __go_to_window_or_session_path
} }
@@ -33,7 +37,12 @@ new_window() {
# - $2: (optional) Target pane ID to split in current window. # - $2: (optional) Target pane ID to split in current window.
# #
split_v() { split_v() {
if [ -n "$1" ]; then local percentage=(-p "$1"); fi if [ "$(tmuxifier-tmux-version "3.0")" == ">" ]; then
# Tmux 3.1 and later.
if [ -n "$1" ]; then local percentage=(-l "$1"'%'); fi
else
if [ -n "$1" ]; then local percentage=(-p "$1"); fi
fi
tmuxifier-tmux split-window -t "$session:$window.$2" -v "${percentage[@]}" tmuxifier-tmux split-window -t "$session:$window.$2" -v "${percentage[@]}"
__go_to_window_or_session_path __go_to_window_or_session_path
} }
@@ -45,7 +54,12 @@ split_v() {
# - $2: (optional) Target pane ID to split in current window. # - $2: (optional) Target pane ID to split in current window.
# #
split_h() { split_h() {
if [ -n "$1" ]; then local percentage=(-p "$1"); fi if [ "$(tmuxifier-tmux-version "3.0")" == ">" ]; then
# Tmux 3.1 and later.
if [ -n "$1" ]; then local percentage=(-l "$1"'%'); fi
else
if [ -n "$1" ]; then local percentage=(-p "$1"); fi
fi
tmuxifier-tmux split-window -t "$session:$window.$2" -h "${percentage[@]}" tmuxifier-tmux split-window -t "$session:$window.$2" -h "${percentage[@]}"
__go_to_window_or_session_path __go_to_window_or_session_path
} }
@@ -101,6 +115,44 @@ select_pane() {
tmuxifier-tmux select-pane -t "$session:$window.$1" tmuxifier-tmux select-pane -t "$session:$window.$1"
} }
# Balance windows vertically with the "even-vertical" layout.
#
# Arguments:
# - $1: (optional) Window ID or name to operate on.
#
balance_windows_vertical() {
tmuxifier-tmux select-layout -t "$session:${1:-$window}" even-vertical
}
# Balance windows horizontally with the "even-horizontal" layout.
#
# Arguments:
# - $1: (optional) Window ID or name to operate on.
#
balance_windows_horizontal() {
tmuxifier-tmux select-layout -t "$session:${1:-$window}" even-horizontal
}
# Turn on synchronize-panes in a window.
#
# Arguments:
# - $1: (optional) Window ID or name to operate on.
#
synchronize_on() {
tmuxifier-tmux set-window-option -t "$session:${1:-$window}" \
synchronize-panes on
}
# Turn off synchronize-panes in a window.
#
# Arguments:
# - $1: (optional) Window ID or name to operate on.
#
synchronize_off() {
tmuxifier-tmux set-window-option -t "$session:${1:-$window}" \
synchronize-panes off
}
# Send/paste keys to the currently active pane/window. # Send/paste keys to the currently active pane/window.
# #
# Arguments: # Arguments:
@@ -128,7 +180,9 @@ run_cmd() {
# - $1: Directory path to use for session root. # - $1: Directory path to use for session root.
# #
session_root() { session_root() {
local dir="$(__expand_path $@)" local dir
dir="$(__expand_path "$@")"
if [ -d "$dir" ]; then if [ -d "$dir" ]; then
session_root="$dir" session_root="$dir"
fi fi
@@ -140,7 +194,9 @@ session_root() {
# - $1: Directory path to use for window root. # - $1: Directory path to use for window root.
# #
window_root() { window_root() {
local dir="$(__expand_path $@)" local dir
dir="$(__expand_path "$@")"
if [ -d "$dir" ]; then if [ -d "$dir" ]; then
window_root="$dir" window_root="$dir"
fi fi
@@ -162,9 +218,11 @@ load_window() {
if [ $# -gt 1 ]; then if [ $# -gt 1 ]; then
window="$2" window="$2"
else else
window="${1/%.window.sh}" window="${1/%.window.sh/}"
window="${window/%.sh}" window="${window/%.sh/}"
fi fi
# shellcheck disable=SC1090
source "$file" source "$file"
window= window=
@@ -185,31 +243,40 @@ load_window() {
# - $2: (optional) Override default window name. # - $2: (optional) Override default window name.
# #
load_session() { load_session() {
local file="$1" local file
if [ ! -f "$file" ]; then if [ "${1#*/}" = "$1" ]; then
file="$TMUXIFIER_LAYOUT_PATH/$1.session.sh" # There's no slash in the path.
fi if [ -f "$TMUXIFIER_LAYOUT_PATH/$1.session.sh" ] || [ ! -f "$1" ]; then
file="$TMUXIFIER_LAYOUT_PATH/$1.session.sh"
if [ -f "$file" ]; then
if [ $# -gt 1 ]; then
session="$2"
else else
session="${1/%.session.sh}" # bash's 'source' requires an slash in the filename to not use $PATH.
session="${session/%.sh}" file="./$1"
fi
set_default_path=true
source "$file"
session=
# Reset `$session_root`.
if [[ "$session_root" != "$HOME" ]]; then
session_root="$HOME"
fi fi
else else
file="$1"
fi
if ! [ -f "$file" ]; then
echo "\"$1\" session layout not found." >&2 echo "\"$1\" session layout not found." >&2
return 1 return 1
fi fi
if [ $# -gt 1 ]; then
session="$2"
else
session="${1/%.session.sh/}"
session="${session/%.sh/}"
fi
set_default_path=true
# shellcheck disable=SC1090
source "$file"
session=
# Reset `$session_root`.
if [[ "$session_root" != "$HOME" ]]; then
session_root="$HOME"
fi
} }
# Create a new session, returning 0 on success, 1 on failure. # Create a new session, returning 0 on success, 1 on failure.
@@ -233,7 +300,7 @@ initialize_session() {
tmuxifier-tmux start-server tmuxifier-tmux start-server
# Check if the named session already exists. # Check if the named session already exists.
if tmuxifier-tmux has-session -t "$session:" 2>/dev/null; then if tmuxifier-tmux list-sessions | grep -q "^$session:"; then
return 1 return 1
fi fi
@@ -244,11 +311,11 @@ initialize_session() {
# Set default-path for session # Set default-path for session
if [ -n "$session_root" ] && [ -d "$session_root" ]; then if [ -n "$session_root" ] && [ -d "$session_root" ]; then
cd "$session_root" cd "$session_root" || return 1
$set_default_path && tmuxifier-tmux \ $set_default_path && tmuxifier-tmux \
set-option -t "$session:" \ set-option -t "$session:" \
default-path "$session_root" 1>/dev/null default-path "$session_root" 1> /dev/null
fi fi
# Tmux 1.9 and later. # Tmux 1.9 and later.
@@ -261,10 +328,16 @@ initialize_session() {
-d -s "$session" "${session_args[@]}" -d -s "$session" "${session_args[@]}"
fi fi
if $set_default_path && [[ "$session_root" != "$HOME" ]]; then
tmuxifier-tmux setenv -t "$session:" \
TMUXIFIER_SESSION_ROOT "$session_root"
fi
# In order to ensure only specified windows are created, we move the # In order to ensure only specified windows are created, we move the
# default window to position 999, and later remove it with the # default window to position 999, and later remove it with the
# `finalize_and_go_to_session` function. # `finalize_and_go_to_session` function.
local first_window_index=$(__get_first_window_index) local first_window_index
first_window_index="$(__get_first_window_index)"
tmuxifier-tmux move-window \ tmuxifier-tmux move-window \
-s "$session:$first_window_index" -t "$session:999" -s "$session:$first_window_index" -t "$session:999"
} }
@@ -279,13 +352,12 @@ initialize_session() {
# created, but already existed, then we'll need to specifically switch to it. # created, but already existed, then we'll need to specifically switch to it.
# #
finalize_and_go_to_session() { finalize_and_go_to_session() {
! tmuxifier-tmux kill-window -t "$session:999" 2>/dev/null ! tmuxifier-tmux kill-window -t "$session:999" 2> /dev/null
if [[ "$(tmuxifier-current-session)" != "$session" ]]; then if [[ "$(tmuxifier-current-session)" != "$session" ]]; then
__go_to_session __go_to_session
fi fi
} }
# #
# Internal functions # Internal functions
# #
@@ -298,12 +370,17 @@ finalize_and_go_to_session() {
# /Users/jimeh/Projects # /Users/jimeh/Projects
# #
__expand_path() { __expand_path() {
echo $(eval echo "$@") local path="$1"
path="${path/#\~/$HOME}"
echo "$path"
} }
__get_first_window_index() { __get_first_window_index() {
local index=$(tmuxifier-tmux list-windows -t "$session:" \ local index
-F "#{window_index}" 2>/dev/null) index="$(
tmuxifier-tmux list-windows \
-t "$session:" -F "#{window_index}" 2> /dev/null
)"
if [ -n "$index" ]; then if [ -n "$index" ]; then
echo "$index" | head -1 echo "$index" | head -1
@@ -313,26 +390,41 @@ __get_first_window_index() {
} }
__get_current_window_index() { __get_current_window_index() {
local lookup=$(tmuxifier-tmux list-windows -t "$session:" \ local lookup
-F "#{window_active}:#{window_index}" 2>/dev/null | grep "^1:") lookup="$(
tmuxifier-tmux list-windows -t "$session:" \
-F "#{window_active}:#{window_index}" 2> /dev/null | grep "^1:"
)"
if [ -n "$lookup" ]; then if [ -n "$lookup" ]; then
echo "${lookup/1:}" echo "${lookup/1:/}"
fi fi
} }
__go_to_session() { __go_to_session() {
if [ -z "$TMUX" ]; then if [ -z "$TMUX" ]; then
tmuxifier-tmux -u attach-session -t "$session:" # shellcheck disable=2086
tmuxifier-tmux $TMUXIFIER_TMUX_ITERM_ATTACH -u \
attach-session -t "$session:"
else else
tmuxifier-tmux -u switch-client -t "$session:" tmuxifier-tmux -u switch-client -t "$session:"
fi fi
} }
__go_to_window_or_session_path() { __go_to_window_or_session_path() {
local window_or_session_root=${window_root-$session_root} local target_path
if [ -n "$window_or_session_root" ]; then
run_cmd "cd \"$window_or_session_root\"" if [ -n "$window_root" ]; then
target_path="$window_root"
elif [ -n "$TMUXIFIER_SESSION_ROOT" ]; then
target_path="$TMUXIFIER_SESSION_ROOT"
elif [ -n "$session_root" ]; then
target_path="$session_root"
fi
# local window_or_session_root=${window_root-$session_root}
if [ -n "$target_path" ]; then
run_cmd "cd \"$target_path\""
run_cmd "clear" run_cmd "clear"
fi fi
} }

View File

@@ -1,11 +1,11 @@
calling-help() { calling-help() {
if [[ " $@ " != *" --help "* ]] && [[ " $@ " != *" -h "* ]]; then if [[ " $* " != *" --help "* ]] && [[ " $* " != *" -h "* ]]; then
return 1 return 1
fi fi
} }
calling-complete() { calling-complete() {
if [[ " $@ " != *" --complete "* ]]; then if [[ " $* " != *" --complete "* ]]; then
return 1 return 1
fi fi
} }

View File

@@ -14,33 +14,37 @@ Resolve a command alias to it's full name."
fi fi
case "$1" in case "$1" in
"session" | "ses" | "s" ) "session" | "ses" | "s")
echo "load-session" echo "load-session"
;; ;;
"window" | "win" | "w" ) "window" | "win" | "w")
echo "load-window" echo "load-window"
;; ;;
"new-ses" | "nses" | "ns" ) "new-ses" | "nses" | "ns")
echo "new-session" echo "new-session"
;; ;;
"new-win" | "nwin" | "nw" ) "new-win" | "nwin" | "nw")
echo "new-window" echo "new-window"
;; ;;
"edit-ses" | "eses" | "es" ) "edit-ses" | "eses" | "es")
echo "edit-session" echo "edit-session"
;; ;;
"edit-win" | "ewin" | "ew" ) "edit-win" | "ewin" | "ew")
echo "edit-window" echo "edit-window"
;; ;;
"l" ) "l")
echo "list" echo "list"
;; ;;
"list-ses" | "lses" | "ls" ) "list-ses" | "lses" | "ls")
echo "list-sessions" echo "list-sessions"
;; ;;
"list-win" | "lwin" | "lw" ) "list-win" | "lwin" | "lw")
echo "list-windows" echo "list-windows"
;; ;;
* ) "completion")
echo "completions"
;;
*)
exit 1 exit 1
;;
esac esac

View File

@@ -16,7 +16,8 @@ fi
shopt -s nullglob shopt -s nullglob
{ for path in ${PATH//:/$'\n'}; do {
for path in ${PATH//:/$'\n'}; do
for command in "${path}/tmuxifier-"*; do for command in "${path}/tmuxifier-"*; do
command="${command##*tmuxifier-}" command="${command##*tmuxifier-}"
echo "$command" echo "$command"

View File

@@ -7,7 +7,9 @@ source "$TMUXIFIER/lib/util.sh"
# Provide tmuxifier help # Provide tmuxifier help
if calling-help "$@"; then if calling-help "$@"; then
echo "usage: tmuxifier completion <command> echo "usage: tmuxifier completions <command>
Aliases: completion
Print a list of available completions for specified command." Print a list of available completions for specified command."
exit exit
@@ -20,15 +22,15 @@ if calling-complete "$@"; then
fi fi
has-completions() { has-completions() {
grep -i "^# Provide tmuxifier completions" "$1" >/dev/null grep -i "^# Provide tmuxifier completions" "$1" > /dev/null
} }
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "$(tmuxifier-help completions $@)" >&2 tmuxifier-help completions "$@" >&2
exit 1 exit 1
fi fi
! command_path="$(tmuxifier-resolve-command-path "$1")" command_path="$(tmuxifier-resolve-command-path "$1")" || true
if [ -n "$command_path" ] && has-completions "$command_path"; then if [ -n "$command_path" ] && has-completions "$command_path"; then
shift shift

View File

@@ -14,8 +14,8 @@ Outputs the name of the current Tmux session."
fi fi
if [ -n "$TMUX" ]; then if [ -n "$TMUX" ]; then
for item in $(tmuxifier-tmux list-pane -F "#{session_name}");do for item in $(tmuxifier-tmux list-pane -F "#{session_name}"); do
echo $item echo "$item"
exit 0 exit 0
done done
fi fi

View File

@@ -22,7 +22,7 @@ if calling-complete "$@"; then
fi fi
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "$(tmuxifier-help edit-session $@)" >&2 tmuxifier-help edit-session "$@" >&2
exit 1 exit 1
fi fi

View File

@@ -22,7 +22,7 @@ if calling-complete "$@"; then
fi fi
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "$(tmuxifier-help edit-window $@)" >&2 tmuxifier-help edit-window "$@" >&2
exit 1 exit 1
fi fi

View File

@@ -18,7 +18,7 @@ if calling-complete "$@"; then
fi fi
has-help() { has-help() {
grep -i "^# Provide tmuxifier help" "$1" >/dev/null grep -i "^# Provide tmuxifier help" "$1" > /dev/null
} }
if [ -z "$1" ]; then if [ -z "$1" ]; then
@@ -43,7 +43,7 @@ See 'tmuxifier help <command>' for information on a specific command."
exit exit
fi fi
! command_path="$(tmuxifier-resolve-command-path "$1")" command_path="$(tmuxifier-resolve-command-path "$1")" || true
if [ -z "$command_path" ]; then if [ -z "$command_path" ]; then
echo "tmuxifier: no such command '$1'" >&2 echo "tmuxifier: no such command '$1'" >&2

View File

@@ -2,6 +2,9 @@
set -e set -e
[ -n "$TMUXIFIER_DEBUG" ] && set -x [ -n "$TMUXIFIER_DEBUG" ] && set -x
# Load internal utility functions.
source "$TMUXIFIER/lib/util.sh"
# Set shell to first argument that is not "-", "-h" or "--help". # Set shell to first argument that is not "-", "-h" or "--help".
for arg in "$@"; do for arg in "$@"; do
if [ "$arg" != "-" ] && [ "$arg" != "-h" ] && [ "$arg" != "--help" ]; then if [ "$arg" != "-" ] && [ "$arg" != "-h" ] && [ "$arg" != "--help" ]; then
@@ -14,46 +17,46 @@ if [ -z "$shell" ]; then
fi fi
case "$shell" in case "$shell" in
bash ) bash)
profile='~/.bash_profile' profile='.bash_profile'
;; ;;
zsh ) zsh)
profile='~/.zshrc' profile='.zshrc'
;; ;;
ksh ) ksh)
profile='~/.profile' profile='.profile'
;; ;;
csh ) csh)
profile='~/.cshrc' profile='.cshrc'
;; ;;
tcsh ) tcsh)
profile='~/.tcshrc' profile='.tcshrc'
;; ;;
fish ) fish)
profile='~/.config/fish/config.fish' profile='.config/fish/config.fish'
;; ;;
* ) *)
profile='shell init file' profile='shell init file'
;; ;;
esac esac
# Provide tmuxifier help # Provide tmuxifier help
if [[ " $@ " == *" --help "* ]]; then if calling-help "$@"; then
echo "usage: tmuxifier init - echo "usage: tmuxifier init -
Load Tmuxifier by adding the following to your ${profile}: Load Tmuxifier by adding the following to your ~/${profile}:
" "
case "$shell" in case "$shell" in
csh | tcsh ) csh | tcsh)
echo " eval \`tmuxifier init -\` echo " eval \`tmuxifier init -\`
" "
;; ;;
fish ) fish)
echo " eval (tmuxifier init -) echo " eval (tmuxifier init -)
" "
;; ;;
* ) *)
echo " eval \"\$(tmuxifier init -)\" echo " eval \"\$(tmuxifier init -)\"
" "
;; ;;
@@ -64,21 +67,26 @@ Load Tmuxifier by adding the following to your ${profile}:
fi fi
# Print help if "-" argument is not given # Print help if "-" argument is not given
if [[ " $@ " != *" - "* ]]; then if [[ " $* " != *" - "* ]]; then
echo "$(tmuxifier-help init $@)" >&2 tmuxifier-help init "$@" >&2
exit 1 exit 1
fi fi
case "$shell" in case "$shell" in
csh | tcsh ) csh | tcsh)
echo "setenv TMUXIFIER \"$TMUXIFIER\";" echo "setenv TMUXIFIER \"$TMUXIFIER\";"
echo "source \"\$TMUXIFIER/init.tcsh\";" echo "source \"\$TMUXIFIER/init.tcsh\";"
;; ;;
fish ) fish)
echo "set -gx TMUXIFIER \"$TMUXIFIER\";" echo "set -gx TMUXIFIER \"$TMUXIFIER\";"
echo "source \"\$TMUXIFIER/init.fish\";" # fish shell 2.0.0 does not have the source alias
if [[ $(fish --version 2>&1 | awk -F'version ' '{print $2}') = '2.0.0' ]]; then
echo ". \"\$TMUXIFIER/init.fish\";"
else
echo "source \"\$TMUXIFIER/init.fish\";"
fi
;; ;;
* ) *)
echo "export TMUXIFIER=\"$TMUXIFIER\";" echo "export TMUXIFIER=\"$TMUXIFIER\";"
echo "source \"\$TMUXIFIER/init.sh\";" echo "source \"\$TMUXIFIER/init.sh\";"
;; ;;

View File

@@ -15,7 +15,7 @@ List all session layouts."
exit exit
fi fi
list=$(find -L "$TMUXIFIER_LAYOUT_PATH" -name "*.session.sh") list=$(find -L "$TMUXIFIER_LAYOUT_PATH" -name "*.session.sh" | sort)
for file in $list; do for file in $list; do
file=${file/$TMUXIFIER_LAYOUT_PATH\//} file=${file/$TMUXIFIER_LAYOUT_PATH\//}
echo "${file/.session.sh/}" echo "${file/.session.sh/}"

View File

@@ -15,7 +15,7 @@ List all window layouts."
exit exit
fi fi
list=$(find -L "$TMUXIFIER_LAYOUT_PATH" -name "*.window.sh") list=$(find -L "$TMUXIFIER_LAYOUT_PATH" -name "*.window.sh" | sort)
for file in $list; do for file in $list; do
file=${file/$TMUXIFIER_LAYOUT_PATH\//} file=${file/$TMUXIFIER_LAYOUT_PATH\//}
echo "${file/.window.sh/}" echo "${file/.window.sh/}"

View File

@@ -7,12 +7,19 @@ source "$TMUXIFIER/lib/util.sh"
# Provide tmuxifier help # Provide tmuxifier help
if calling-help "$@"; then if calling-help "$@"; then
echo "usage: tmuxifier load-session <layout_name | file_path> echo "usage: tmuxifier load-session <layout_name | file_path> [<iterm mode>]
Aliases: session, ses, s Aliases: session, ses, s
Create a session using the session layout, unless the session already exists Create a session using the session layout, unless the session already exists
in which case, we simply attach/switch to the existing one." in which case, we simply attach/switch to the existing one.
Arguments:
<layout_name | file_path> - Name of a session layout stored in the layouts
directory, or path to a session layout file.
<iterm mode> - When given as \"-CC\" tmux will be called with
the -CC argument enabling iTerm2 integration.
More info: https://iterm2.com"
exit exit
fi fi
@@ -23,12 +30,16 @@ if calling-complete "$@"; then
fi fi
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "$(tmuxifier-help load-session $@)" >&2 tmuxifier-help load-session "$@" >&2
exit 1 exit 1
fi fi
# Load runtime functions. # Load runtime functions.
source "$TMUXIFIER/lib/runtime.sh" source "$TMUXIFIER/lib/runtime.sh"
if [ "$2" == "-CC" ]; then
export TMUXIFIER_TMUX_ITERM_ATTACH="-CC"
fi
# Load session file. # Load session file.
load_session "$1" load_session "$1"

View File

@@ -11,7 +11,11 @@ if calling-help "$@"; then
Aliases: window, win, w Aliases: window, win, w
Create a new window using the specified window layout in the current session." Create a new window using the specified window layout in the current session.
Arguments:
<layout_name | file_path> - Name of a window layout stored in the layouts
directory, or path to a window layout file."
exit exit
fi fi
@@ -22,14 +26,14 @@ if calling-complete "$@"; then
fi fi
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "$(tmuxifier-help load-window $@)" >&2 tmuxifier-help load-window "$@" >&2
exit 1 exit 1
fi fi
# Load runtime functions. # Load runtime functions.
source "$TMUXIFIER/lib/runtime.sh" source "$TMUXIFIER/lib/runtime.sh"
if [ ! -z $TMUX ]; then if [ -n "$TMUX" ]; then
session="$(tmuxifier-current-session)" session="$(tmuxifier-current-session)"
load_window "$1" load_window "$1"
else else

View File

@@ -22,7 +22,7 @@ if calling-complete "$@"; then
fi fi
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "$(tmuxifier-help new-session $@)" >&2 tmuxifier-help new-session "$@" >&2
exit 1 exit 1
fi fi

View File

@@ -22,7 +22,7 @@ if calling-complete "$@"; then
fi fi
if [ -z "$1" ]; then if [ -z "$1" ]; then
echo "$(tmuxifier-help new-window $@)" >&2 tmuxifier-help new-window "$@" >&2
exit 1 exit 1
fi fi

View File

@@ -14,11 +14,11 @@ Outputs the absolute path to the given command or command alias."
fi fi
if [ -n "$1" ]; then if [ -n "$1" ]; then
! command_path="$(command -v "tmuxifier-$1")" command_path="$(command -v "tmuxifier-$1")" || true
if [ -z "$command_path" ]; then if [ -z "$command_path" ]; then
resolved="$(tmuxifier-alias "$1")" resolved="$(tmuxifier-alias "$1")"
if [ -n "$resolved" ]; then if [ -n "$resolved" ]; then
! command_path="$(command -v "tmuxifier-$resolved")" command_path="$(command -v "tmuxifier-$resolved")" || true
fi fi
fi fi
fi fi

View File

@@ -2,4 +2,5 @@
set -e set -e
[ -n "$TMUXIFIER_DEBUG" ] && set -x [ -n "$TMUXIFIER_DEBUG" ] && set -x
# shellcheck disable=SC2086
tmux $TMUXIFIER_TMUX_OPTS "$@" tmux $TMUXIFIER_TMUX_OPTS "$@"

View File

@@ -7,11 +7,11 @@ source "$TMUXIFIER/lib/util.sh"
# Provide tmuxifier help # Provide tmuxifier help
if calling-help "$@"; then if calling-help "$@"; then
echo "usage: tmuxifier tmux-version [target-version] echo "usage: tmuxifier tmux-version [<target-version>]
Outputs current Tmux version. If given optional target-version it outputs one Outputs current Tmux version. If given optional target-version it outputs one
of three possible characters indicating if the current Tmux version number is of three possible characters indicating if the current Tmux version number is
equal to, less than, or greater than the [target-version]. equal to, less than, or greater than the <target-version>.
The three possible outputs are \"=\", \"<\", and \">\"." The three possible outputs are \"=\", \"<\", and \">\"."
exit exit
@@ -19,16 +19,17 @@ fi
# The vercomp() function is shamelessly ripped/borrowed from the following # The vercomp() function is shamelessly ripped/borrowed from the following
# StackOverflow answer: http://stackoverflow.com/a/4025065/42146 # StackOverflow answer: http://stackoverflow.com/a/4025065/42146
vercomp () { vercomp() {
if [[ $1 == $2 ]]; then return 0; fi if [[ "$1" == "$2" ]]; then return 0; fi
local IFS=. local IFS=.
# shellcheck disable=SC2206
local i ver1=($1) ver2=($2) local i ver1=($1) ver2=($2)
# fill empty fields in ver1 with zeros # fill empty fields in ver1 with zeros
for ((i=${#ver1[@]}; i<${#ver2[@]}; i++)); do ver1[i]=0; done for ((i = ${#ver1[@]}; i < ${#ver2[@]}; i++)); do ver1[i]=0; done
for ((i=0; i<${#ver1[@]}; i++)); do for ((i = 0; i < ${#ver1[@]}; i++)); do
# fill empty fields in ver2 with zeros # fill empty fields in ver2 with zeros
if [[ -z ${ver2[i]} ]]; then ver2[i]=0; fi if [[ -z ${ver2[i]} ]]; then ver2[i]=0; fi
@@ -44,17 +45,27 @@ vercomp () {
version=$(tmux -V) version=$(tmux -V)
version=${version/tmux /} version=${version/tmux /}
if [ -n "$1" ]; then # Fix for tmux next-* versions
version=${version/next-/}
if [ -z "$1" ]; then
echo "$version"
exit
fi
if [ "$version" == "master" ]; then
# When version string is "master", tmux was compiled from source, and we
# assume it's later than whatever the <target-version> is.
echo '>'
else
# Fix for "1.9a" version comparison, as vercomp() can only deal with # Fix for "1.9a" version comparison, as vercomp() can only deal with
# purely numeric version numbers. # purely numeric version numbers.
version=${version//+([a-zA-Z])/} version=${version//+([a-zA-Z])/}
vercomp "$version" "$1" vercomp "$version" "$1"
case $? in case $? in
0) echo '=';; 0) echo '=' ;;
1) echo '>';; 1) echo '>' ;;
2) echo '<';; 2) echo '<' ;;
esac esac
else
echo "$version"
fi fi

View File

@@ -13,4 +13,4 @@ Outputs Tmuxifier version."
exit exit
fi fi
echo "0.11.6" echo "0.13.0"

View File

@@ -11,21 +11,25 @@ TMUXIFER="/path/to/tmuxifier"
# When TMUXIFIER_LAYOUT_PATH is not set. # When TMUXIFIER_LAYOUT_PATH is not set.
source "${root}/lib/env.sh" source "${root}/lib/env.sh"
# shellcheck disable=SC2016
assert 'echo $TMUXIFIER_LAYOUT_PATH' "${TMUXIFIER}/layouts" assert 'echo $TMUXIFIER_LAYOUT_PATH' "${TMUXIFIER}/layouts"
# When TMUXIFIER_LAYOUT_PATH is set and has a trailing slash. # When TMUXIFIER_LAYOUT_PATH is set and has a trailing slash.
TMUXIFIER_LAYOUT_PATH="/path/to/layouts/" TMUXIFIER_LAYOUT_PATH="/path/to/layouts/"
source "${root}/lib/env.sh" source "${root}/lib/env.sh"
# shellcheck disable=SC2016
assert 'echo $TMUXIFIER_LAYOUT_PATH' "/path/to/layouts" assert 'echo $TMUXIFIER_LAYOUT_PATH' "/path/to/layouts"
unset TMUXIFIER_LAYOUT_PATH unset TMUXIFIER_LAYOUT_PATH
# When TMUXIFIER_LAYOUT_PATH is set and does not have a trailing slash. # When TMUXIFIER_LAYOUT_PATH is set and does not have a trailing slash.
TMUXIFIER_LAYOUT_PATH="/path/to/layouts" TMUXIFIER_LAYOUT_PATH="/path/to/layouts"
source "${root}/lib/env.sh" source "${root}/lib/env.sh"
# shellcheck disable=SC2016
assert 'echo $TMUXIFIER_LAYOUT_PATH' "/path/to/layouts" assert 'echo $TMUXIFIER_LAYOUT_PATH' "/path/to/layouts"
unset TMUXIFIER_LAYOUT_PATH unset TMUXIFIER_LAYOUT_PATH
# Tear down. # Tear down.
# shellcheck disable=SC2034
TMUXIFER="$realTMUXIFIER" TMUXIFER="$realTMUXIFIER"
unset realTMUXIFIER unset realTMUXIFIER

View File

@@ -19,6 +19,12 @@ assert '__expand_path "/path/to/file"' "/path/to/file"
# When given a path containing spaces, it returns path correctly. # When given a path containing spaces, it returns path correctly.
assert '__expand_path "~/Path To/File"' "${HOME}/Path To/File" assert '__expand_path "~/Path To/File"' "${HOME}/Path To/File"
# When given a relative path, it returns path as is.
assert '__expand_path "foo/bar"' "foo/bar"
# When given a relative parent path, it returns path as is.
assert '__expand_path "../foo/bar"' "../foo/bar"
# Tear down. # Tear down.
HOME="$realHOME" HOME="$realHOME"
unset realHOME unset realHOME

View File

@@ -7,25 +7,25 @@ source "${root}/lib/layout-helpers.sh"
# #
# When current window is the first and only window. # When current window is the first and only window.
create-test-session create-test-session "test"
assert "__get_current_window_index" "0" assert "__get_current_window_index" "0"
kill-test-session kill-test-session "test"
# When creating a second window. # When creating a second window.
create-test-session create-test-session "test"
test-socket-tmux new-window -t "$session:1" test-socket-tmux new-window -t "$session:1"
assert "__get_current_window_index" "1" assert "__get_current_window_index" "1"
kill-test-session kill-test-session "test"
# When creating a second window and then switching back to the first window. # When creating a second window and then switching back to the first window.
create-test-session create-test-session "test"
test-socket-tmux new-window -t "$session:1" test-socket-tmux new-window -t "$session:1"
test-socket-tmux select-window -t "$session:0" test-socket-tmux select-window -t "$session:0"
assert "__get_current_window_index" "0" assert "__get_current_window_index" "0"
kill-test-session kill-test-session "test"
# When creating multiples windows and switching between them randomly. # When creating multiples windows and switching between them randomly.
create-test-session create-test-session "test"
assert "__get_current_window_index" "0" assert "__get_current_window_index" "0"
test-socket-tmux new-window -t "$session:1" test-socket-tmux new-window -t "$session:1"
assert "__get_current_window_index" "1" assert "__get_current_window_index" "1"
@@ -41,8 +41,7 @@ test-socket-tmux select-window -t "$session:3"
assert "__get_current_window_index" "3" assert "__get_current_window_index" "3"
test-socket-tmux select-window -t "$session:2" test-socket-tmux select-window -t "$session:2"
assert "__get_current_window_index" "2" assert "__get_current_window_index" "2"
kill-test-session kill-test-session "test"
# End of tests. # End of tests.
assert_end "__get_current_window_index()" assert_end "__get_current_window_index()"

View File

@@ -7,24 +7,23 @@ source "${root}/lib/layout-helpers.sh"
# #
# When first window has a index of 0. # When first window has a index of 0.
create-test-session create-test-session "test"
assert "__get_first_window_index" "0" assert "__get_first_window_index" "0"
kill-test-session kill-test-session "test"
# When first window has a index of 1. # When first window has a index of 1.
create-test-session create-test-session "test"
test-socket-tmux new-window -t "$session:1" test-socket-tmux new-window -t "$session:1"
test-socket-tmux kill-window -t "$session:0" test-socket-tmux kill-window -t "$session:0"
assert "__get_first_window_index" "1" assert "__get_first_window_index" "1"
kill-test-session kill-test-session "test"
# When first window has a index of 2. # When first window has a index of 2.
create-test-session create-test-session "test"
test-socket-tmux new-window -t "$session:2" test-socket-tmux new-window -t "$session:2"
test-socket-tmux kill-window -t "$session:0" test-socket-tmux kill-window -t "$session:0"
assert "__get_first_window_index" "2" assert "__get_first_window_index" "2"
kill-test-session kill-test-session "test"
# End of tests. # End of tests.
assert_end "__get_first_window_index()" assert_end "__get_first_window_index()"

View File

@@ -16,6 +16,16 @@ assert_raises \
"stub_called_with tmuxifier-tmux -u attach-session -t \"${session}:\"" 0 "stub_called_with tmuxifier-tmux -u attach-session -t \"${session}:\"" 0
restore tmuxifier-tmux restore tmuxifier-tmux
# When TMUXIFIER_TMUX_ITERM_ATTACH is set, pass it in as first argument(s) to
# tmuxifier-tmux
TMUXIFIER_TMUX_ITERM_ATTACH="-CC"
stub tmuxifier-tmux
__go_to_session
assert_raises \
"stub_called_with tmuxifier-tmux -CC -u attach-session -t \"${session}:\"" 0
restore tmuxifier-tmux
unset TMUXIFIER_TMUX_ITERM_ATTACH
# When TMUX is set, switch to $session. # When TMUX is set, switch to $session.
TMUX="/tmp/tmux-501/default,1203,0" TMUX="/tmp/tmux-501/default,1203,0"
stub tmuxifier-tmux stub tmuxifier-tmux

View File

@@ -12,7 +12,6 @@ __go_to_window_or_session_path
assert "stub_called_times run_cmd" "0" assert "stub_called_times run_cmd" "0"
restore run_cmd restore run_cmd
# When only $window_root is set, runs cd to $window_root path. # When only $window_root is set, runs cd to $window_root path.
stub run_cmd stub run_cmd
window_root="/tmp" window_root="/tmp"
@@ -22,6 +21,15 @@ assert 'stub_called_with_times run_cmd clear' "1"
unset window_root unset window_root
restore run_cmd restore run_cmd
# When only $TMUXIFIER_SESSION_ROOT is set, runs cd to $TMUXIFIER_SESSION_ROOT
# path.
stub run_cmd
TMUXIFIER_SESSION_ROOT="/opt"
__go_to_window_or_session_path
assert 'stub_called_with_times run_cmd cd \"/opt\"' "1"
assert 'stub_called_with_times run_cmd clear' "1"
unset TMUXIFIER_SESSION_ROOT
restore run_cmd
# When only $session_root is set, runs cd to $session_root path. # When only $session_root is set, runs cd to $session_root path.
stub run_cmd stub run_cmd
@@ -32,7 +40,6 @@ assert 'stub_called_with_times run_cmd clear' "1"
unset session_root unset session_root
restore run_cmd restore run_cmd
# When $window_root and $session_root are set, runs cd to $window_root path. # When $window_root and $session_root are set, runs cd to $window_root path.
stub run_cmd stub run_cmd
window_root="/tmp" window_root="/tmp"
@@ -44,6 +51,31 @@ unset window_root
unset session_root unset session_root
restore run_cmd restore run_cmd
# When $TMUXIFIER_SESSION_ROOT and $session_root are set, runs cd to
# $TMUXIFIER_SESSION_ROOT path.
stub run_cmd
TMUXIFIER_SESSION_ROOT="/opt"
session_root="/usr"
__go_to_window_or_session_path
assert 'stub_called_with_times run_cmd cd \"/opt\"' "1"
assert 'stub_called_with_times run_cmd clear' "1"
unset TMUXIFIER_SESSION_ROOT
unset session_root
restore run_cmd
# When $window_root, $TMUXIFIER_SESSION_ROOT, and $session_root are set, runs
# cd to $window_root path.
stub run_cmd
window_root="/tmp"
TMUXIFIER_SESSION_ROOT="/opt"
session_root="/usr"
__go_to_window_or_session_path
assert 'stub_called_with_times run_cmd cd \"/tmp\"' "1"
assert 'stub_called_with_times run_cmd clear' "1"
unset window_root
unset TMUXIFIER_SESSION_ROOT
unset session_root
restore run_cmd
# End of tests. # End of tests.
assert_end "__go_to_window_or_session_path()" assert_end "__go_to_window_or_session_path()"

View File

@@ -7,29 +7,29 @@ source "${root}/lib/layout-helpers.sh"
# #
# When called without arguments, creates new window. # When called without arguments, creates new window.
create-test-session create-test-session "test"
stub __go_to_window_or_session_path stub __go_to_window_or_session_path
assert "test-socket-window-count" "1" assert "test-socket-window-count" "1"
new_window new_window
assert "test-socket-window-count" "2" assert "test-socket-window-count" "2"
assert "stub_called_times __go_to_window_or_session_path" "1" assert "stub_called_times __go_to_window_or_session_path" "1"
restore __go_to_window_or_session_path restore __go_to_window_or_session_path
kill-test-session kill-test-session "test"
# When called with name argument, creates new window with specified name. # When called with name argument, creates new window with specified name.
create-test-session create-test-session "test"
stub __go_to_window_or_session_path stub __go_to_window_or_session_path
assert "test-socket-window-count yippieezzz" "0" assert "test-socket-window-count yippieezzz" "0"
new_window "yippieezzz" new_window "yippieezzz"
assert "test-socket-window-count" "2" assert "test-socket-window-count" "2"
assert "test-socket-window-count yippieezzz" "1" assert "test-socket-window-count yippieezzz" "1"
restore __go_to_window_or_session_path restore __go_to_window_or_session_path
kill-test-session kill-test-session "test"
# When called with name and command argument, creates new window with # When called with name and command argument, creates new window with
# specified name and executes given command. # specified name and executes given command.
rm "/tmp/tmuxifier-new_window-test" &> /dev/null rm "/tmp/tmuxifier-new_window-test" &> /dev/null
create-test-session create-test-session "test"
stub __go_to_window_or_session_path stub __go_to_window_or_session_path
new_window "foobardoo" "touch /tmp/tmuxifier-new_window-test; bash" new_window "foobardoo" "touch /tmp/tmuxifier-new_window-test; bash"
assert "test-socket-window-count" "2" assert "test-socket-window-count" "2"
@@ -37,13 +37,13 @@ assert "test-socket-window-count foobardoo" "1"
sleep 0.1 # attempt to avoid timing issue causing flicker sleep 0.1 # attempt to avoid timing issue causing flicker
assert_raises 'test -f "/tmp/tmuxifier-new_window-test"' 0 assert_raises 'test -f "/tmp/tmuxifier-new_window-test"' 0
restore __go_to_window_or_session_path restore __go_to_window_or_session_path
kill-test-session kill-test-session "test"
rm "/tmp/tmuxifier-new_window-test" &> /dev/null rm "/tmp/tmuxifier-new_window-test" &> /dev/null
# When called ensure it sets the $window variable to the index of the newly # When called ensure it sets the $window variable to the index of the newly
# created window. # created window.
unset window unset window
create-test-session create-test-session "test"
stub __go_to_window_or_session_path stub __go_to_window_or_session_path
new_window "foo" new_window "foo"
assert "echo $window" "1" assert "echo $window" "1"
@@ -52,7 +52,7 @@ assert "echo $window" "2"
new_window "bar" new_window "bar"
assert "echo $window" "3" assert "echo $window" "3"
restore __go_to_window_or_session_path restore __go_to_window_or_session_path
kill-test-session kill-test-session "test"
unset window unset window
# End of tests. # End of tests.

View File

@@ -8,11 +8,11 @@ source "${root}/lib/layout-helpers.sh"
window_list() { window_list() {
test-socket-tmux list-windows -t "$session:" \ test-socket-tmux list-windows -t "$session:" \
-F "#{window_active}:#{window_index}" 2>/dev/null -F "#{window_active}:#{window_index}" 2> /dev/null
} }
# Selects given window when passed a window index # Selects given window when passed a window index
create-test-session create-test-session "test"
test-socket-tmux new-window -t "$session:1" test-socket-tmux new-window -t "$session:1"
test-socket-tmux new-window -t "$session:2" test-socket-tmux new-window -t "$session:2"
select_window 0 select_window 0
@@ -21,23 +21,22 @@ select_window 1
assert "window_list | grep '^1:'" "1:1" assert "window_list | grep '^1:'" "1:1"
select_window 2 select_window 2
assert "window_list | grep '^1:'" "1:2" assert "window_list | grep '^1:'" "1:2"
kill-test-session kill-test-session "test"
# Selects given window when passed a window name # Selects given window when passed a window name
create-test-session create-test-session "test"
test-socket-tmux new-window -t "$session:1" -n "foo" test-socket-tmux new-window -t "$session:1" -n "foo"
test-socket-tmux new-window -t "$session:2" -n "bar" test-socket-tmux new-window -t "$session:2" -n "bar"
select_window foo select_window foo
assert "window_list | grep '^1:'" "1:1" assert "window_list | grep '^1:'" "1:1"
select_window bar select_window bar
assert "window_list | grep '^1:'" "1:2" assert "window_list | grep '^1:'" "1:2"
kill-test-session kill-test-session "test"
# When called ensure it sets the $window variable to the index of the newly # When called ensure it sets the $window variable to the index of the newly
# created window. # created window.
unset window unset window
create-test-session create-test-session "test"
test-socket-tmux new-window -t "$session:1" -n "foo" test-socket-tmux new-window -t "$session:1" -n "foo"
test-socket-tmux new-window -t "$session:2" -n "bar" test-socket-tmux new-window -t "$session:2" -n "bar"
select_window "foo" select_window "foo"
@@ -48,7 +47,7 @@ select_window 1
assert "echo $window" "1" assert "echo $window" "1"
select_window 2 select_window 2
assert "echo $window" "2" assert "echo $window" "2"
kill-test-session kill-test-session "test"
unset window unset window
# End of tests. # End of tests.

View File

@@ -8,9 +8,11 @@ source "../test-helper.sh"
source "${root}/lib/runtime.sh" source "${root}/lib/runtime.sh"
# We assume env.sh has been sourced if $TMUXIFIER_LAYOUT_PATH has been set. # We assume env.sh has been sourced if $TMUXIFIER_LAYOUT_PATH has been set.
# shellcheck disable=SC2016
assert 'echo $TMUXIFIER_LAYOUT_PATH' "${TMUXIFIER}/layouts" assert 'echo $TMUXIFIER_LAYOUT_PATH' "${TMUXIFIER}/layouts"
# We ensure $session_root is set to $HOME by default. # We ensure $session_root is set to $HOME by default.
# shellcheck disable=SC2016
assert 'echo $session_root' "$HOME" assert 'echo $session_root' "$HOME"
# We assume layout-helpers.sh has been sourced if a few of them are available. # We assume layout-helpers.sh has been sourced if a few of them are available.
@@ -18,6 +20,5 @@ for helper in new_window split_v split_h select_window select_pane; do
assert "type $helper | head -1" "$helper is a function" assert "type $helper | head -1" "$helper is a function"
done done
# End of tests. # End of tests.
assert_end "runtime.sh" assert_end "runtime.sh"

View File

@@ -34,7 +34,6 @@ assert_raises 'calling-help welcome-home' 1
# End of tests. # End of tests.
assert_end "calling-help()" assert_end "calling-help()"
# #
# calling-complete() tests. # calling-complete() tests.
# #

View File

@@ -5,8 +5,9 @@ resolve_link() {
} }
abs_dirname() { abs_dirname() {
local cwd="$(pwd)" local cwd
local path="$1" local path="$1"
cwd="$(pwd)"
while [ -n "$path" ]; do while [ -n "$path" ]; do
cd "${path%/*}" cd "${path%/*}"
@@ -47,14 +48,13 @@ unset TMUXIFIER_NO_COMPLETE
source "${testroot}/assert.sh" source "${testroot}/assert.sh"
source "${testroot}/stub.sh" source "${testroot}/stub.sh"
# #
# Test Helpers # Test Helpers
# #
test-socket-tmux() { test-socket-tmux() {
export TMUXIFIER_TMUX_OPTS="-L tmuxifier-tests" export TMUXIFIER_TMUX_OPTS="-L tmuxifier-tests"
"$TMUX_BIN" $TMUXIFIER_TMUX_OPTS $@ "$TMUX_BIN" $TMUXIFIER_TMUX_OPTS "$@"
} }
create-test-session() { create-test-session() {
@@ -78,9 +78,10 @@ kill-test-server() {
} }
test-socket-window-count() { test-socket-window-count() {
local list="$(test-socket-tmux list-windows)" local list
list="$(test-socket-tmux list-windows)"
if [ -n "$1" ]; then if [ -n "$1" ]; then
echo "$list" | grep $1 | wc -l | awk '{print $1}' echo "$list" | grep "$1" -c | awk '{print $1}'
else else
echo "$list" | wc -l | awk '{print $1}' echo "$list" | wc -l | awk '{print $1}'
fi fi

1
tmuxifier.tmux Executable file
View File

@@ -0,0 +1 @@
#!/usr/bin/env bash