├── .gitattributes
├── .gitignore
├── .gitmodules
├── .travis.yml
├── CHANGELOG.md
├── HOW_TO_PLUGIN.md
├── LICENSE.md
├── README.md
├── bin
├── clean_plugins
├── install_plugins
└── update_plugins
├── bindings
├── clean_plugins
├── install_plugins
└── update_plugins
├── docs
├── automatic_tpm_installation.md
├── changing_plugins_install_dir.md
├── how_to_create_plugin.md
├── managing_plugins_via_cmd_line.md
└── tpm_not_working.md
├── scripts
├── check_tmux_version.sh
├── clean_plugins.sh
├── helpers
│ ├── plugin_functions.sh
│ ├── shell_echo_functions.sh
│ ├── tmux_echo_functions.sh
│ ├── tmux_utils.sh
│ └── utility.sh
├── install_plugins.sh
├── source_plugins.sh
├── update_plugin.sh
├── update_plugin_prompt_handler.sh
└── variables.sh
├── tests
├── expect_failed_plugin_download
├── expect_successful_clean_plugins
├── expect_successful_multiple_plugins_download
├── expect_successful_plugin_download
├── expect_successful_update_of_a_single_plugin
├── expect_successful_update_of_all_plugins
├── helpers
│ └── tpm.sh
├── test_plugin_clean.sh
├── test_plugin_installation.sh
├── test_plugin_installation_legacy.sh
├── test_plugin_sourcing.sh
└── test_plugin_update.sh
└── tpm
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Force text files to have unix eols, so Windows/Cygwin does not break them
2 | *.* eol=lf
3 |
4 | # These files are unfortunately not recognized as text files so
5 | # explicitly listing them here
6 | tpm eol=lf
7 | bin/* eol=lf
8 | bindings/* eol=lf
9 | tests/* eol=lf
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | **/.vagrant/
2 | run_tests
3 | tests/run_tests_in_isolation
4 | tests/helpers/helpers.sh
5 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "lib/tmux-test"]
2 | path = lib/tmux-test
3 | url = https://github.com/tmux-plugins/tmux-test.git
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # generic packages and tmux
2 | before_install:
3 | - sudo apt-get update
4 | - sudo apt-get install -y git-core expect
5 | - sudo apt-get install -y python-software-properties software-properties-common
6 | - sudo apt-get install -y libevent-dev libncurses-dev
7 | - git clone https://github.com/tmux/tmux.git
8 | - cd tmux
9 | - git checkout 2.0
10 | - sh autogen.sh
11 | - ./configure && make && sudo make install
12 |
13 | install:
14 | - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules
15 | # manual `git clone` required for testing `tmux-test` plugin itself
16 | - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true
17 | - lib/tmux-test/setup
18 |
19 | script: ./tests/run_tests_in_isolation
20 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ### master
4 |
5 | ### v3.1.0, 2023-01-03
6 | - upgrade to new version of `tmux-test`
7 | - bug: when using `emacs` copy mode, Enter does not quit screen after tpm
8 | installation/update. Fix by making `Escape` the key for emacs mode.
9 | - add a doc with troubleshooting instructions
10 | - add `.gitattributes` file that forces linefeed characters (classic `\n`) as
11 | line endings - helps with misconfigured git on windows/cygwin
12 | - readme update: announce Cygwin support
13 | - un-deprecate old plugin definition syntax: `set -g @tpm_plugins`
14 | - More stuff, check `git log`.
15 |
16 | ### v3.0.0, 2015-08-03
17 | - refactor `shared_set_tpm_path_constant` function
18 | - move all instructions to `docs/` dir
19 | - add `bin/install_plugins` cli executable script
20 | - improved test runner function
21 | - switch to using [tmux-test](https://github.com/tmux-plugins/tmux-test)
22 | framework
23 | - add `bin/update_plugins` cli executable script
24 | - refactor test `expect` scripts, make them simpler and ensure they properly
25 | assert expectations
26 | - refactor code that sets 'TMUX_PLUGIN_MANAGER_PATH' global env var
27 | - stop using global variable for 'tpm path'
28 | - support defining plugins via `set -g @plugin` in sourced files as well
29 |
30 | ### v2.0.0, 2015-07-07
31 | - enable overriding default key bindings
32 | - start using `C-c` to clear screen
33 | - add uninstall/clean procedure and keybinding (prefix+alt+u) (@chilicuil)
34 | - add new `set @plugin 'repo'` plugin definition syntax (@chilicuil)
35 | - revert back to using `-g` flag in new plugin definition syntax
36 | - permit leading whitespace with new plugin definition syntax (thanks @chilicuil)
37 | - make sure `TMUX_PLUGIN_MANAGER_PATH` always has trailng slash
38 | - ensure old/deprecated plugin syntax `set -g @tpm_plugins` works alongside new
39 | `set -g @plugin` syntax
40 |
41 | ### v1.2.2, 2015-02-08
42 | - set GIT_TERMINAL_PROMPT=0 when doing `git clone`, `pull` or `submodule update`
43 | to ensure git does not prompt for username/password in any case
44 |
45 | ### v1.2.1, 2014-11-21
46 | - change the way plugin name is expanded. It now uses the http username
47 | and password by default, like this: `https://git::@github.com/`. This prevents
48 | username and password prompt (and subsequently tmux install hanging) with old
49 | git versions. Fixes #7.
50 |
51 | ### v1.2.0, 2014-11-20
52 | - refactor tests so they can be used on travis
53 | - add travis.yml, add travis badge to the readme
54 |
55 | ### v1.1.0, 2014-11-19
56 | - if the plugin is not downloaded do not source it
57 | - remove `PLUGINS.md`, an obsolete list of plugins
58 | - update readme with instructions about uninstalling plugins
59 | - tilde char and `$HOME` in `TMUX_SHARED_MANAGER_PATH` couldn't be used because
60 | they are just plain strings. Fixing the problem by manually expanding them.
61 | - bugfix: fragile `*.tmux` file globbing (@majutsushi)
62 |
63 | ### v1.0.0, 2014-08-05
64 | - update readme because of github organization change to
65 | [tmux-plugins](https://github.com/tmux-plugins)
66 | - update tests to pass
67 | - update README to suggest different first plugin
68 | - update list of plugins in the README
69 | - remove README 'about' section
70 | - move key binding to the main file. Delete `key_binding.sh`.
71 | - rename `display_message` -> `echo_message`
72 | - installing plugins installs just new plugins. Already installed plugins aren't
73 | updated.
74 | - add 'update plugin' binding and functionality
75 | - add test for updating a plugin
76 |
77 | ### v0.0.2, 2014-07-17
78 | - run all *.tmux plugin files as executables
79 | - fix all redirects to /dev/null
80 | - fix bug: TPM shared path is created before sync (cloning plugins from github
81 | is done)
82 | - add test suite running in Vagrant
83 | - add Tmux version check. `TPM` won't run if Tmux version is less than 1.9.
84 |
85 | ### v0.0.1, 2014-05-21
86 | - get TPM up and running
87 |
--------------------------------------------------------------------------------
/HOW_TO_PLUGIN.md:
--------------------------------------------------------------------------------
1 | Instructions moved to
2 | [docs/how_to_create_plugin.md](docs/how_to_create_plugin.md).
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | MIT license
2 | Copyright (C) 2014 Bruno Sutic
3 |
4 | Permission is hereby granted, free of charge, to any person obtaining
5 | a copy of this software and associated documentation files (the "Software"),
6 | to deal in the Software without restriction, including without limitation
7 | the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 | and/or sell copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be included
12 | in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tmux Plugin Manager
2 |
3 | [](https://travis-ci.org/tmux-plugins/tpm)
4 |
5 | Installs and loads `tmux` plugins.
6 |
7 | Tested and working on Linux, OSX, and Cygwin.
8 |
9 | See list of plugins [here](https://github.com/tmux-plugins/list).
10 |
11 | ### Installation
12 |
13 | Requirements: `tmux` version 1.9 (or higher), `git`, `bash`.
14 |
15 | Clone TPM:
16 |
17 | ```bash
18 | git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm
19 | ```
20 |
21 | Put this at the bottom of `~/.tmux.conf` (`$XDG_CONFIG_HOME/tmux/tmux.conf`
22 | works too):
23 |
24 | ```bash
25 | # List of plugins
26 | set -g @plugin 'tmux-plugins/tpm'
27 | set -g @plugin 'tmux-plugins/tmux-sensible'
28 |
29 | # Other examples:
30 | # set -g @plugin 'github_username/plugin_name'
31 | # set -g @plugin 'github_username/plugin_name#branch'
32 | # set -g @plugin 'git@github.com:user/plugin'
33 | # set -g @plugin 'git@bitbucket.com:user/plugin'
34 |
35 | # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
36 | run '~/.tmux/plugins/tpm/tpm'
37 | ```
38 |
39 | Reload TMUX environment so TPM is sourced:
40 |
41 | ```bash
42 | # type this in terminal if tmux is already running
43 | tmux source ~/.tmux.conf
44 | ```
45 |
46 | That's it!
47 |
48 | ### Installing plugins
49 |
50 | 1. Add new plugin to `~/.tmux.conf` with `set -g @plugin '...'`
51 | 2. Press `prefix` + I (capital i, as in **I**nstall) to fetch the plugin.
52 |
53 | You're good to go! The plugin was cloned to `~/.tmux/plugins/` dir and sourced.
54 |
55 | ### Uninstalling plugins
56 |
57 | 1. Remove (or comment out) plugin from the list.
58 | 2. Press `prefix` + alt + u (lowercase u as in **u**ninstall) to remove the plugin.
59 |
60 | All the plugins are installed to `~/.tmux/plugins/` so alternatively you can
61 | find plugin directory there and remove it.
62 |
63 | ### Key bindings
64 |
65 | `prefix` + I
66 | - Installs new plugins from GitHub or any other git repository
67 | - Refreshes TMUX environment
68 |
69 | `prefix` + U
70 | - updates plugin(s)
71 |
72 | `prefix` + alt + u
73 | - remove/uninstall plugins not on the plugin list
74 |
75 | ### Docs
76 |
77 | - [Help, tpm not working](docs/tpm_not_working.md) - problem solutions
78 |
79 | More advanced features and instructions, regular users probably do not need
80 | this:
81 |
82 | - [How to create a plugin](docs/how_to_create_plugin.md). It's easy.
83 | - [Managing plugins via the command line](docs/managing_plugins_via_cmd_line.md)
84 | - [Changing plugins install dir](docs/changing_plugins_install_dir.md)
85 | - [Automatic TPM installation on a new machine](docs/automatic_tpm_installation.md)
86 |
87 | ### Tests
88 |
89 | Tests for this project run on [Travis CI](https://travis-ci.org/tmux-plugins/tpm).
90 |
91 | When run locally, [vagrant](https://www.vagrantup.com/) is required.
92 | Run tests with:
93 |
94 | ```bash
95 | # within project directory
96 | ./run_tests
97 | ```
98 |
99 | ### License
100 |
101 | [MIT](LICENSE.md)
102 |
--------------------------------------------------------------------------------
/bin/clean_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Script intended for use via the command line.
4 | #
5 | # `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system,
6 | # but does not need to be started in order to run this script.
7 |
8 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9 | SCRIPTS_DIR="$CURRENT_DIR/../scripts"
10 |
11 | main() {
12 | "$SCRIPTS_DIR/clean_plugins.sh" # has correct exit code
13 | }
14 | main
15 |
--------------------------------------------------------------------------------
/bin/install_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Script intended for use via the command line.
4 | #
5 | # `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system,
6 | # but does not need to be started in order to run this script.
7 |
8 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9 | SCRIPTS_DIR="$CURRENT_DIR/../scripts"
10 |
11 | main() {
12 | "$SCRIPTS_DIR/install_plugins.sh" # has correct exit code
13 | }
14 | main
15 |
--------------------------------------------------------------------------------
/bin/update_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Script intended for use via the command line.
4 | #
5 | # `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system,
6 | # but does not need to be started in order to run this script.
7 |
8 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9 | SCRIPTS_DIR="$CURRENT_DIR/../scripts"
10 | PROGRAM_NAME="$0"
11 |
12 | if [ $# -eq 0 ]; then
13 | echo "usage:"
14 | echo " $PROGRAM_NAME all update all plugins"
15 | echo " $PROGRAM_NAME tmux-foo update plugin 'tmux-foo'"
16 | echo " $PROGRAM_NAME tmux-bar tmux-baz update multiple plugins"
17 | exit 1
18 | fi
19 |
20 | main() {
21 | "$SCRIPTS_DIR/update_plugin.sh" --shell-echo "$*" # has correct exit code
22 | }
23 | main "$*"
24 |
25 |
--------------------------------------------------------------------------------
/bindings/clean_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Tmux key-binding script.
4 | # Scripts intended to be used via the command line are in `bin/` directory.
5 |
6 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
7 | SCRIPTS_DIR="$CURRENT_DIR/../scripts"
8 | HELPERS_DIR="$SCRIPTS_DIR/helpers"
9 |
10 | source "$HELPERS_DIR/tmux_echo_functions.sh"
11 | source "$HELPERS_DIR/tmux_utils.sh"
12 |
13 | main() {
14 | reload_tmux_environment
15 | "$SCRIPTS_DIR/clean_plugins.sh" --tmux-echo >/dev/null 2>&1
16 | reload_tmux_environment
17 | end_message
18 | }
19 | main
20 |
--------------------------------------------------------------------------------
/bindings/install_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Tmux key-binding script.
4 | # Scripts intended to be used via the command line are in `bin/` directory.
5 |
6 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
7 | SCRIPTS_DIR="$CURRENT_DIR/../scripts"
8 | HELPERS_DIR="$SCRIPTS_DIR/helpers"
9 |
10 | source "$HELPERS_DIR/tmux_echo_functions.sh"
11 | source "$HELPERS_DIR/tmux_utils.sh"
12 |
13 | main() {
14 | reload_tmux_environment
15 | "$SCRIPTS_DIR/install_plugins.sh" --tmux-echo >/dev/null 2>&1
16 | reload_tmux_environment
17 | end_message
18 | }
19 | main
20 |
--------------------------------------------------------------------------------
/bindings/update_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Tmux key-binding script.
4 | # Scripts intended to be used via the command line are in `bin/` directory.
5 |
6 | # This script:
7 | # - shows a list of installed plugins
8 | # - starts a prompt to enter the name of the plugin that will be updated
9 |
10 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
11 | SCRIPTS_DIR="$CURRENT_DIR/../scripts"
12 | HELPERS_DIR="$SCRIPTS_DIR/helpers"
13 |
14 | source "$HELPERS_DIR/plugin_functions.sh"
15 | source "$HELPERS_DIR/tmux_echo_functions.sh"
16 | source "$HELPERS_DIR/tmux_utils.sh"
17 |
18 | display_plugin_update_list() {
19 | local plugins="$(tpm_plugins_list_helper)"
20 | tmux_echo "Installed plugins:"
21 | tmux_echo ""
22 |
23 | for plugin in $plugins; do
24 | # displaying only installed plugins
25 | if plugin_already_installed "$plugin"; then
26 | local plugin_name="$(plugin_name_helper "$plugin")"
27 | tmux_echo " $plugin_name"
28 | fi
29 | done
30 |
31 | tmux_echo ""
32 | tmux_echo "Type plugin name to update it."
33 | tmux_echo ""
34 | tmux_echo "- \"all\" - updates all plugins"
35 | tmux_echo "- ENTER - cancels"
36 | }
37 |
38 | update_plugin_prompt() {
39 | tmux command-prompt -p 'plugin update:' " \
40 | send-keys C-c; \
41 | run-shell '$SCRIPTS_DIR/update_plugin_prompt_handler.sh %1'"
42 | }
43 |
44 | main() {
45 | reload_tmux_environment
46 | display_plugin_update_list
47 | update_plugin_prompt
48 | }
49 | main
50 |
--------------------------------------------------------------------------------
/docs/automatic_tpm_installation.md:
--------------------------------------------------------------------------------
1 | # Automatic tpm installation
2 |
3 | One of the first things we do on a new machine is cloning our dotfiles. Not everything comes with them though, so for example `tpm` most likely won't be installed.
4 |
5 | If you want to install `tpm` and plugins automatically when tmux is started, put the following snippet in `.tmux.conf` before the final `run '~/.tmux/plugins/tpm/tpm'`:
6 |
7 | ```
8 | if "test ! -d ~/.tmux/plugins/tpm" \
9 | "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'"
10 | ```
11 |
12 | This useful tip was submitted by @acr4 and narfman0.
13 |
--------------------------------------------------------------------------------
/docs/changing_plugins_install_dir.md:
--------------------------------------------------------------------------------
1 | # Changing plugins install dir
2 |
3 | By default, TPM installs plugins in a subfolder named `plugins/` inside
4 | `$XDG_CONFIG_HOME/tmux/` if a `tmux.conf` file was found at that location, or
5 | inside `~/.tmux/` otherwise.
6 |
7 | You can change the install path by putting this in `.tmux.conf`:
8 |
9 | set-environment -g TMUX_PLUGIN_MANAGER_PATH '/some/other/path/'
10 |
11 | Tmux plugin manager initialization in `.tmux.conf` should also be updated:
12 |
13 | # initializes TMUX plugin manager in a new path
14 | run /some/other/path/tpm/tpm
15 |
16 | Please make sure that the `run` line is at the very bottom of `.tmux.conf`.
17 |
--------------------------------------------------------------------------------
/docs/how_to_create_plugin.md:
--------------------------------------------------------------------------------
1 | # How to create Tmux plugins
2 |
3 | Creating a new plugin is easy.
4 |
5 | For demonstration purposes we'll create a simple plugin that lists all
6 | installed TPM plugins. Yes, a plugin that lists plugins :) We'll bind that to
7 | `prefix + T`.
8 |
9 | The source code for this example plugin can be found
10 | [here](https://github.com/tmux-plugins/tmux-example-plugin).
11 |
12 | ### 1. create a new git project
13 |
14 | TPM depends on git for downloading and updating plugins.
15 |
16 | To create a new git project:
17 |
18 | $ mkdir tmux_my_plugin
19 | $ cd tmux_my_plugin
20 | $ git init
21 |
22 | ### 2. create a `*.tmux` plugin run file
23 |
24 | When it sources a plugin, TPM executes all `*.tmux` files in your plugins'
25 | directory. That's how plugins are run.
26 |
27 | Create a plugin run file in plugin directory:
28 |
29 | $ touch my_plugin.tmux
30 | $ chmod u+x my_plugin.tmux
31 |
32 | You can have more than one `*.tmux` file, and all will get executed. However, usually
33 | you'll need just one.
34 |
35 | ### 3. create a plugin key binding
36 |
37 | We want the behavior of the plugin to trigger when a user hits `prefix + T`.
38 |
39 | Key `T` is chosen because:
40 | - it's "kind of" a mnemonic for `TPM`
41 | - the key is not used by Tmux natively. Tmux man page, KEY BINDINGS section
42 | contains a list of all the bindings Tmux uses. There's plenty of unused keys
43 | and we don't want to override any of Tmux default key bindings.
44 |
45 | Open the plugin run file in your favorite text editor:
46 |
47 | $ vim my_plugin.tmux
48 | # or
49 | $ subl my_plugin.tmux
50 |
51 | Put the following content in the file:
52 |
53 | #!/usr/bin/env bash
54 |
55 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
56 | tmux bind-key T run-shell "$CURRENT_DIR/scripts/tmux_list_plugins.sh"
57 |
58 | As you can see, plugin run file is a simple bash script that sets up the binding.
59 |
60 | When pressed, `prefix + T` will execute another shell script:
61 | `tmux_list_plugins.sh`. That script should be in `scripts/` directory -
62 | relative to the plugin run file.
63 |
64 |
65 | ### 4. listing plugins
66 |
67 | Now that we have the binding, let's create a script that's invoked with
68 | `prefix + T`.
69 |
70 | $ mkdir scripts
71 | $ touch scripts/tmux_list_plugins.sh
72 | $ chmod u+x scripts/tmux_list_plugins.sh
73 |
74 | And here's the script content:
75 |
76 | #!/usr/bin/env bash
77 |
78 | # fetching the directory where plugins are installed
79 | plugin_path="$(tmux show-env -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)"
80 |
81 | # listing installed plugins
82 | ls -1 "$plugin_path"
83 |
84 | ### 5. try it out
85 |
86 | To see if this works, execute the plugin run file:
87 |
88 | $ ./my_plugin.tmux
89 |
90 | That should set up the key binding. Now hit `prefix + T` and see if it works.
91 |
92 | ### 6. publish the plugin
93 |
94 | When everything is ready, push the plugin to an online git repository,
95 | preferably GitHub.
96 |
97 | Other users can install your plugin by just adding plugin git URL to the
98 | `@plugin` list in their `.tmux.conf`.
99 |
100 | If the plugin is on GitHub, your users will be able to use the shorthand of
101 | `github_username/repository`.
102 |
103 | ### Conclusion
104 |
105 | Hopefully, that was easy. As you can see, it's mostly shell scripting.
106 |
107 | You can use other scripting languages (ruby, python etc) but plain old shell
108 | is preferred because of portability.
109 |
--------------------------------------------------------------------------------
/docs/managing_plugins_via_cmd_line.md:
--------------------------------------------------------------------------------
1 | # Managing plugins via the command line
2 |
3 | Aside from tmux key bindings, TPM provides shell interface for managing plugins
4 | via scripts located in [bin/](../bin/) directory.
5 |
6 | Tmux does not need to be started in order to run scripts (but it's okay if it
7 | is). If you [changed tpm install dir](../docs/changing_plugins_install_dir.md)
8 | in `.tmux.conf` that should work fine too.
9 |
10 | Prerequisites:
11 |
12 | - tmux installed on the system (doh)
13 | - `.tmux.conf` set up for TPM
14 |
15 | ### Installing plugins
16 |
17 | As usual, plugins need to be specified in `.tmux.conf`. Run the following
18 | command to install plugins:
19 |
20 | ~/.tmux/plugins/tpm/bin/install_plugins
21 |
22 | ### Updating plugins
23 |
24 | To update all installed plugins:
25 |
26 | ~/.tmux/plugins/tpm/bin/update_plugins all
27 |
28 | or update a single plugin:
29 |
30 | ~/.tmux/plugins/tpm/bin/update_plugins tmux-sensible
31 |
32 | ### Removing plugins
33 |
34 | To remove plugins not on the plugin list:
35 |
36 | ~/.tmux/plugins/tpm/bin/clean_plugins
37 |
--------------------------------------------------------------------------------
/docs/tpm_not_working.md:
--------------------------------------------------------------------------------
1 | # Help, tpm not working!
2 |
3 | Here's the list of issues users had with `tpm`:
4 |
5 |
6 |
7 | > Nothing works. `tpm` key bindings `prefix + I`, `prefix + U` not even
8 | defined.
9 |
10 | Related [issue #22](https://github.com/tmux-plugins/tpm/issues/22)
11 |
12 | - Do you have required `tmux` version to run `tpm`?
13 | Check `tmux` version with `$ tmux -V` command and make sure it's higher or
14 | equal to the required version for `tpm` as stated in the readme.
15 |
16 | - ZSH tmux plugin might be causing issues.
17 | If you have it installed, try disabling it and see if `tpm` works then.
18 |
19 |
20 |
21 | > Help, I'm using custom config file with `tmux -f /path/to/my_tmux.conf`
22 | to start Tmux and for some reason plugins aren't loaded!?
23 |
24 | Related [issue #57](https://github.com/tmux-plugins/tpm/issues/57)
25 |
26 | `tpm` has a known issue when using custom config file with `-f` option.
27 | The solution is to use alternative plugin definition syntax. Here are the steps
28 | to make it work:
29 |
30 | 1. remove all `set -g @plugin` lines from tmux config file
31 | 2. in the config file define the plugins in the following way:
32 |
33 | # List of plugins
34 | set -g @tpm_plugins ' \
35 | tmux-plugins/tpm \
36 | tmux-plugins/tmux-sensible \
37 | tmux-plugins/tmux-resurrect \
38 | '
39 |
40 | # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
41 | run '~/.tmux/plugins/tpm/tpm'
42 |
43 | 3. Reload TMUX environment so TPM is sourced: `$ tmux source /path/to/my_tmux.conf`
44 |
45 | The plugins should now be working.
46 |
47 |
48 |
49 | > Weird sequence of characters show up when installing or updating plugins
50 |
51 | Related: [issue #25](https://github.com/tmux-plugins/tpm/issues/25)
52 |
53 | - This could be caused by [tmuxline.vim](https://github.com/edkolev/tmuxline.vim)
54 | plugin. Uninstall it and see if things work.
55 |
56 |
57 |
58 | > "failed to connect to server" error when sourcing .tmux.conf
59 |
60 | Related: [issue #48](https://github.com/tmux-plugins/tpm/issues/48)
61 |
62 | - Make sure `tmux source ~/.tmux.conf` command is ran from inside `tmux`.
63 |
64 |
65 |
66 | > tpm not working: '~/.tmux/plugins/tpm/tpm' returned 2 (Windows / Cygwin)
67 |
68 | Related: [issue #81](https://github.com/tmux-plugins/tpm/issues/81)
69 |
70 | This issue is most likely caused by Windows line endings. For example, if you
71 | have git's `core.autocrlf` option set to `true`, git will automatically convert
72 | all the files to Windows line endings which might cause a problem.
73 |
74 | The solution is to convert all line ending to Unix newline characters. This
75 | command handles that for all files under `.tmux/` dir (skips `.git`
76 | subdirectories):
77 |
78 | ```bash
79 | find ~/.tmux -type d -name '.git*' -prune -o -type f -print0 | xargs -0 dos2unix
80 | ```
81 |
82 |
83 |
84 | > '~/.tmux/plugins/tpm/tpm' returned 127 (on macOS, w/ tmux installed using brew)
85 |
86 | Related: [issue #67](https://github.com/tmux-plugins/tpm/issues/67)
87 |
88 | This problem is because tmux's `run-shell` command runs a shell which doesn't read from user configs, thus tmux installed in a brew prefix (e.g. `/usr/local/bin`) will not be found.
89 |
90 | The solution is to find your brew prefix
91 |
92 | ```sh
93 | > echo "$(brew --prefix)/bin"
94 | /opt/homebrew/bin
95 | ```
96 |
97 | And prepend it to the `PATH` environment variable
98 | ```
99 | set-environment -g PATH "/opt/homebrew/bin:/bin:/usr/bin"
100 | ```
101 |
102 | before any `run-shell`/`run` commands in `~/.tmux.conf`.
103 |
--------------------------------------------------------------------------------
/scripts/check_tmux_version.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | VERSION="$1"
4 | UNSUPPORTED_MSG="$2"
5 |
6 | get_tmux_option() {
7 | local option=$1
8 | local default_value=$2
9 | local option_value=$(tmux show-option -gqv "$option")
10 | if [ -z "$option_value" ]; then
11 | echo "$default_value"
12 | else
13 | echo "$option_value"
14 | fi
15 | }
16 |
17 | # Ensures a message is displayed for 5 seconds in tmux prompt.
18 | # Does not override the 'display-time' tmux option.
19 | display_message() {
20 | local message="$1"
21 |
22 | # display_duration defaults to 5 seconds, if not passed as an argument
23 | if [ "$#" -eq 2 ]; then
24 | local display_duration="$2"
25 | else
26 | local display_duration="5000"
27 | fi
28 |
29 | # saves user-set 'display-time' option
30 | local saved_display_time=$(get_tmux_option "display-time" "750")
31 |
32 | # sets message display time to 5 seconds
33 | tmux set-option -gq display-time "$display_duration"
34 |
35 | # displays message
36 | tmux display-message "$message"
37 |
38 | # restores original 'display-time' value
39 | tmux set-option -gq display-time "$saved_display_time"
40 | }
41 |
42 | # this is used to get "clean" integer version number. Examples:
43 | # `tmux 1.9` => `19`
44 | # `1.9a` => `19`
45 | get_digits_from_string() {
46 | local string="$1"
47 | local only_digits="$(echo "$string" | tr -dC '[:digit:]')"
48 | echo "$only_digits"
49 | }
50 |
51 | tmux_version_int() {
52 | local tmux_version_string=$(tmux -V)
53 | echo "$(get_digits_from_string "$tmux_version_string")"
54 | }
55 |
56 | unsupported_version_message() {
57 | if [ -n "$UNSUPPORTED_MSG" ]; then
58 | echo "$UNSUPPORTED_MSG"
59 | else
60 | echo "Error, Tmux version unsupported! Please install Tmux version $VERSION or greater!"
61 | fi
62 | }
63 |
64 | exit_if_unsupported_version() {
65 | local current_version="$1"
66 | local supported_version="$2"
67 | if [ "$current_version" -lt "$supported_version" ]; then
68 | display_message "$(unsupported_version_message)"
69 | exit 1
70 | fi
71 | }
72 |
73 | main() {
74 | local supported_version_int="$(get_digits_from_string "$VERSION")"
75 | local current_version_int="$(tmux_version_int)"
76 | exit_if_unsupported_version "$current_version_int" "$supported_version_int"
77 | }
78 | main
79 |
--------------------------------------------------------------------------------
/scripts/clean_plugins.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | HELPERS_DIR="$CURRENT_DIR/helpers"
5 |
6 | source "$HELPERS_DIR/plugin_functions.sh"
7 | source "$HELPERS_DIR/utility.sh"
8 |
9 | if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions
10 | source "$HELPERS_DIR/tmux_echo_functions.sh"
11 | else # shell output functions
12 | source "$HELPERS_DIR/shell_echo_functions.sh"
13 | fi
14 |
15 | clean_plugins() {
16 | local plugins plugin plugin_directory
17 | plugins="$(tpm_plugins_list_helper)"
18 |
19 | for plugin_directory in "$(tpm_path)"/*; do
20 | [ -d "${plugin_directory}" ] || continue
21 | plugin="$(plugin_name_helper "${plugin_directory}")"
22 | case "${plugins}" in
23 | *"${plugin}"*) : ;;
24 | *)
25 | [ "${plugin}" = "tpm" ] && continue
26 | echo_ok "Removing \"$plugin\""
27 | rm -rf "${plugin_directory}" >/dev/null 2>&1
28 | [ -d "${plugin_directory}" ] &&
29 | echo_err " \"$plugin\" clean fail" ||
30 | echo_ok " \"$plugin\" clean success"
31 | ;;
32 | esac
33 | done
34 | }
35 |
36 | main() {
37 | ensure_tpm_path_exists
38 | clean_plugins
39 | exit_value_helper
40 | }
41 | main
42 |
--------------------------------------------------------------------------------
/scripts/helpers/plugin_functions.sh:
--------------------------------------------------------------------------------
1 | # using @tpm_plugins is now deprecated in favor of using @plugin syntax
2 | tpm_plugins_variable_name="@tpm_plugins"
3 |
4 | # manually expanding tilde char or `$HOME` variable.
5 | _manual_expansion() {
6 | local path="$1"
7 | local expanded_tilde="${path/#\~/$HOME}"
8 | echo "${expanded_tilde/#\$HOME/$HOME}"
9 | }
10 |
11 | _tpm_path() {
12 | local string_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)/"
13 | _manual_expansion "$string_path"
14 | }
15 |
16 | _CACHED_TPM_PATH="$(_tpm_path)"
17 |
18 | # Get the absolute path to the users configuration file of TMux.
19 | # This includes a prioritized search on different locations.
20 | #
21 | _get_user_tmux_conf() {
22 | # Define the different possible locations.
23 | xdg_location="${XDG_CONFIG_HOME:-$HOME/.config}/tmux/tmux.conf"
24 | default_location="$HOME/.tmux.conf"
25 |
26 | # Search for the correct configuration file by priority.
27 | if [ -f "$xdg_location" ]; then
28 | echo "$xdg_location"
29 |
30 | else
31 | echo "$default_location"
32 | fi
33 | }
34 |
35 | _tmux_conf_contents() {
36 | user_config=$(_get_user_tmux_conf)
37 | cat /etc/tmux.conf "$user_config" 2>/dev/null
38 | if [ "$1" == "full" ]; then # also output content from sourced files
39 | local file
40 | for file in $(_sourced_files); do
41 | cat $(_manual_expansion "$file") 2>/dev/null
42 | done
43 | fi
44 | }
45 |
46 | # return files sourced from tmux config files
47 | _sourced_files() {
48 | _tmux_conf_contents |
49 | sed -E -n -e "s/^[[:space:]]*source(-file)?[[:space:]]+(-q+[[:space:]]+)?['\"]?([^'\"]+)['\"]?/\3/p"
50 | }
51 |
52 | # Want to be able to abort in certain cases
53 | trap "exit 1" TERM
54 | export TOP_PID=$$
55 |
56 | _fatal_error_abort() {
57 | echo >&2 "Aborting."
58 | kill -s TERM $TOP_PID
59 | }
60 |
61 | # PUBLIC FUNCTIONS BELOW
62 |
63 | tpm_path() {
64 | if [ "$_CACHED_TPM_PATH" == "/" ]; then
65 | echo >&2 "FATAL: Tmux Plugin Manager not configured in tmux.conf"
66 | _fatal_error_abort
67 | fi
68 | echo "$_CACHED_TPM_PATH"
69 | }
70 |
71 | tpm_plugins_list_helper() {
72 | # lists plugins from @tpm_plugins option
73 | echo "$(tmux start-server\; show-option -gqv "$tpm_plugins_variable_name")"
74 |
75 | # read set -g @plugin "tmux-plugins/tmux-example-plugin" entries
76 | _tmux_conf_contents "full" |
77 | awk '/^[ \t]*set(-option)? +-g +@plugin/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $4 }'
78 | }
79 |
80 | # Allowed plugin name formats:
81 | # 1. "git://github.com/user/plugin_name.git"
82 | # 2. "user/plugin_name"
83 | plugin_name_helper() {
84 | local plugin="$1"
85 | # get only the part after the last slash, e.g. "plugin_name.git"
86 | local plugin_basename="$(basename "$plugin")"
87 | # remove ".git" extension (if it exists) to get only "plugin_name"
88 | local plugin_name="${plugin_basename%.git}"
89 | echo "$plugin_name"
90 | }
91 |
92 | plugin_path_helper() {
93 | local plugin="$1"
94 | local plugin_name="$(plugin_name_helper "$plugin")"
95 | echo "$(tpm_path)${plugin_name}/"
96 | }
97 |
98 | plugin_already_installed() {
99 | local plugin="$1"
100 | local plugin_path="$(plugin_path_helper "$plugin")"
101 | [ -d "$plugin_path" ] &&
102 | cd "$plugin_path" &&
103 | git remote >/dev/null 2>&1
104 | }
105 |
--------------------------------------------------------------------------------
/scripts/helpers/shell_echo_functions.sh:
--------------------------------------------------------------------------------
1 | echo_ok() {
2 | echo "$*"
3 | }
4 |
5 | echo_err() {
6 | fail_helper "$*"
7 | }
8 |
--------------------------------------------------------------------------------
/scripts/helpers/tmux_echo_functions.sh:
--------------------------------------------------------------------------------
1 | _has_emacs_mode_keys() {
2 | $(tmux show -gw mode-keys | grep -q emacs)
3 | }
4 |
5 | tmux_echo() {
6 | local message="$1"
7 | tmux run-shell "echo '$message'"
8 | }
9 |
10 | echo_ok() {
11 | tmux_echo "$*"
12 | }
13 |
14 | echo_err() {
15 | tmux_echo "$*"
16 | }
17 |
18 | end_message() {
19 | if _has_emacs_mode_keys; then
20 | local continue_key="ESCAPE"
21 | else
22 | local continue_key="ENTER"
23 | fi
24 | tmux_echo ""
25 | tmux_echo "TMUX environment reloaded."
26 | tmux_echo ""
27 | tmux_echo "Done, press $continue_key to continue."
28 | }
29 |
--------------------------------------------------------------------------------
/scripts/helpers/tmux_utils.sh:
--------------------------------------------------------------------------------
1 | HELPERS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
2 | source "$HELPERS_DIR/plugin_functions.sh"
3 |
4 | reload_tmux_environment() {
5 | tmux source-file $(_get_user_tmux_conf) >/dev/null 2>&1
6 | }
7 |
--------------------------------------------------------------------------------
/scripts/helpers/utility.sh:
--------------------------------------------------------------------------------
1 | ensure_tpm_path_exists() {
2 | mkdir -p "$(tpm_path)"
3 | }
4 |
5 | fail_helper() {
6 | local message="$1"
7 | echo "$message" >&2
8 | FAIL="true"
9 | }
10 |
11 | exit_value_helper() {
12 | if [ "$FAIL" == "true" ]; then
13 | exit 1
14 | else
15 | exit 0
16 | fi
17 | }
18 |
--------------------------------------------------------------------------------
/scripts/install_plugins.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | HELPERS_DIR="$CURRENT_DIR/helpers"
5 |
6 | source "$HELPERS_DIR/plugin_functions.sh"
7 | source "$HELPERS_DIR/utility.sh"
8 |
9 | if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions
10 | source "$HELPERS_DIR/tmux_echo_functions.sh"
11 | else # shell output functions
12 | source "$HELPERS_DIR/shell_echo_functions.sh"
13 | fi
14 |
15 | clone() {
16 | local plugin="$1"
17 | local branch="$2"
18 | if [ -n "$branch" ]; then
19 | cd "$(tpm_path)" &&
20 | GIT_TERMINAL_PROMPT=0 git clone -b "$branch" --single-branch --recursive "$plugin" >/dev/null 2>&1
21 | else
22 | cd "$(tpm_path)" &&
23 | GIT_TERMINAL_PROMPT=0 git clone --single-branch --recursive "$plugin" >/dev/null 2>&1
24 | fi
25 | }
26 |
27 | # tries cloning:
28 | # 1. plugin name directly - works if it's a valid git url
29 | # 2. expands the plugin name to point to a GitHub repo and tries cloning again
30 | clone_plugin() {
31 | local plugin="$1"
32 | local branch="$2"
33 | clone "$plugin" "$branch" ||
34 | clone "https://git::@github.com/$plugin" "$branch"
35 | }
36 |
37 | # clone plugin and produce output
38 | install_plugin() {
39 | local plugin="$1"
40 | local branch="$2"
41 | local plugin_name="$(plugin_name_helper "$plugin")"
42 |
43 | if plugin_already_installed "$plugin"; then
44 | echo_ok "Already installed \"$plugin_name\""
45 | else
46 | echo_ok "Installing \"$plugin_name\""
47 | clone_plugin "$plugin" "$branch" &&
48 | echo_ok " \"$plugin_name\" download success" ||
49 | echo_err " \"$plugin_name\" download fail"
50 | fi
51 | }
52 |
53 | install_plugins() {
54 | local plugins="$(tpm_plugins_list_helper)"
55 | for plugin in $plugins; do
56 | IFS='#' read -ra plugin <<< "$plugin"
57 | install_plugin "${plugin[0]}" "${plugin[1]}"
58 | done
59 | }
60 |
61 | verify_tpm_path_permissions() {
62 | local path="$(tpm_path)"
63 | # check the write permission flag for all users to ensure
64 | # that we have proper access
65 | [ -w "$path" ] ||
66 | echo_err "$path is not writable!"
67 | }
68 |
69 | main() {
70 | ensure_tpm_path_exists
71 | verify_tpm_path_permissions
72 | install_plugins
73 | exit_value_helper
74 | }
75 | main
76 |
--------------------------------------------------------------------------------
/scripts/source_plugins.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | HELPERS_DIR="$CURRENT_DIR/helpers"
5 |
6 | source "$HELPERS_DIR/plugin_functions.sh"
7 |
8 | plugin_dir_exists() {
9 | [ -d "$1" ]
10 | }
11 |
12 | # Runs all *.tmux files from the plugin directory.
13 | # Files are ran as executables.
14 | # No errors if the plugin dir does not exist.
15 | silently_source_all_tmux_files() {
16 | local plugin_path="$1"
17 | local plugin_tmux_files="$plugin_path*.tmux"
18 | if plugin_dir_exists "$plugin_path"; then
19 | for tmux_file in $plugin_tmux_files; do
20 | # if the glob didn't find any files this will be the
21 | # unexpanded glob which obviously doesn't exist
22 | [ -f "$tmux_file" ] || continue
23 | # runs *.tmux file as an executable
24 | $tmux_file >/dev/null 2>&1
25 | done
26 | fi
27 | }
28 |
29 | source_plugins() {
30 | local plugin plugin_path
31 | local plugins="$(tpm_plugins_list_helper)"
32 | for plugin in $plugins; do
33 | IFS='#' read -ra plugin <<< "$plugin"
34 | plugin_path="$(plugin_path_helper "${plugin[0]}")"
35 | silently_source_all_tmux_files "$plugin_path"
36 | done
37 | }
38 |
39 | main() {
40 | source_plugins
41 | }
42 | main
43 |
--------------------------------------------------------------------------------
/scripts/update_plugin.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # this script handles core logic of updating plugins
4 |
5 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6 | HELPERS_DIR="$CURRENT_DIR/helpers"
7 |
8 | source "$HELPERS_DIR/plugin_functions.sh"
9 | source "$HELPERS_DIR/utility.sh"
10 |
11 | if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions
12 | source "$HELPERS_DIR/tmux_echo_functions.sh"
13 | else # shell output functions
14 | source "$HELPERS_DIR/shell_echo_functions.sh"
15 | fi
16 |
17 | # from now on ignore first script argument
18 | shift
19 |
20 | pull_changes() {
21 | local plugin="$1"
22 | local plugin_path="$(plugin_path_helper "$plugin")"
23 | cd "$plugin_path" &&
24 | GIT_TERMINAL_PROMPT=0 git pull &&
25 | GIT_TERMINAL_PROMPT=0 git submodule update --init --recursive
26 | }
27 |
28 | update() {
29 | local plugin="$1" output
30 | output=$(pull_changes "$plugin" 2>&1)
31 | if (( $? == 0 )); then
32 | echo_ok " \"$plugin\" update success"
33 | echo_ok "$(echo "$output" | sed -e 's/^/ | /')"
34 | else
35 | echo_err " \"$plugin\" update fail"
36 | echo_err "$(echo "$output" | sed -e 's/^/ | /')"
37 | fi
38 | }
39 |
40 | update_all() {
41 | echo_ok "Updating all plugins!"
42 | echo_ok ""
43 | local plugins="$(tpm_plugins_list_helper)"
44 | for plugin in $plugins; do
45 | IFS='#' read -ra plugin <<< "$plugin"
46 | local plugin_name="$(plugin_name_helper "${plugin[0]}")"
47 | # updating only installed plugins
48 | if plugin_already_installed "$plugin_name"; then
49 | update "$plugin_name" &
50 | fi
51 | done
52 | wait
53 | }
54 |
55 | update_plugins() {
56 | local plugins="$*"
57 | for plugin in $plugins; do
58 | IFS='#' read -ra plugin <<< "$plugin"
59 | local plugin_name="$(plugin_name_helper "${plugin[0]}")"
60 | if plugin_already_installed "$plugin_name"; then
61 | update "$plugin_name" &
62 | else
63 | echo_err "$plugin_name not installed!" &
64 | fi
65 | done
66 | wait
67 | }
68 |
69 | main() {
70 | ensure_tpm_path_exists
71 | if [ "$1" == "all" ]; then
72 | update_all
73 | else
74 | update_plugins "$*"
75 | fi
76 | exit_value_helper
77 | }
78 | main "$*"
79 |
--------------------------------------------------------------------------------
/scripts/update_plugin_prompt_handler.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | HELPERS_DIR="$CURRENT_DIR/helpers"
5 |
6 | if [ $# -eq 0 ]; then
7 | exit 0
8 | fi
9 |
10 | source "$HELPERS_DIR/tmux_echo_functions.sh"
11 | source "$HELPERS_DIR/tmux_utils.sh"
12 |
13 | main() {
14 | "$CURRENT_DIR/update_plugin.sh" --tmux-echo "$*"
15 | reload_tmux_environment
16 | end_message
17 | }
18 | main "$*"
19 |
--------------------------------------------------------------------------------
/scripts/variables.sh:
--------------------------------------------------------------------------------
1 | install_key_option="@tpm-install"
2 | default_install_key="I"
3 |
4 | update_key_option="@tpm-update"
5 | default_update_key="U"
6 |
7 | clean_key_option="@tpm-clean"
8 | default_clean_key="M-u"
9 |
10 | SUPPORTED_TMUX_VERSION="1.9"
11 |
12 | DEFAULT_TPM_ENV_VAR_NAME="TMUX_PLUGIN_MANAGER_PATH"
13 | DEFAULT_TPM_PATH="$HOME/.tmux/plugins/"
14 |
--------------------------------------------------------------------------------
/tests/expect_failed_plugin_download:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env expect
2 |
3 | # disables script output
4 | log_user 0
5 |
6 | spawn tmux
7 |
8 | # Waiting for tmux to attach. If this is not done, next command, `send` will
9 | # not work properly.
10 | sleep 1
11 |
12 | # this is tmux prefix + I
13 | send "I"
14 |
15 | # cloning might take a while
16 | set timeout 20
17 |
18 | expect_after {
19 | timeout { exit 1 }
20 | }
21 |
22 | expect {
23 | "Installing \"non-existing-plugin\""
24 | }
25 |
26 | expect {
27 | "\"non-existing-plugin\" download fail"
28 | }
29 |
30 | expect {
31 | "Done, press ENTER to continue" {
32 | exit 0
33 | }
34 | }
35 |
36 | exit 1
37 |
--------------------------------------------------------------------------------
/tests/expect_successful_clean_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env expect
2 |
3 | # disables script output
4 | log_user 0
5 |
6 | spawn tmux
7 |
8 | # Waiting for tmux to attach. If this is not done, next command, `send` will
9 | # not work properly.
10 | sleep 1
11 |
12 | # this is tmux prefix + alt + u
13 | send "u"
14 |
15 | set timeout 5
16 |
17 | expect_after {
18 | timeout { exit 1 }
19 | }
20 |
21 | expect {
22 | "Removing \"tmux-example-plugin\""
23 | }
24 |
25 | expect {
26 | "\"tmux-example-plugin\" clean success"
27 | }
28 |
29 | expect {
30 | "Done, press ENTER to continue." {
31 | exit 0
32 | }
33 | }
34 |
35 | exit 1
36 |
--------------------------------------------------------------------------------
/tests/expect_successful_multiple_plugins_download:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env expect
2 |
3 | # disables script output
4 | log_user 0
5 |
6 | spawn tmux
7 |
8 | # Waiting for tmux to attach. If this is not done, next command, `send` will
9 | # not work properly.
10 | sleep 1
11 |
12 | # this is tmux prefix + I
13 | send "I"
14 |
15 | # cloning might take a while
16 | set timeout 15
17 |
18 | expect_after {
19 | timeout { exit 1 }
20 | }
21 |
22 | expect {
23 | "Installing \"tmux-example-plugin\""
24 | }
25 |
26 | expect {
27 | "\"tmux-example-plugin\" download success"
28 | }
29 |
30 | expect {
31 | "Installing \"tmux-copycat\""
32 | }
33 |
34 | expect {
35 | "\"tmux-copycat\" download success"
36 | }
37 |
38 | expect {
39 | "Done, press ENTER to continue." {
40 | exit 0
41 | }
42 | }
43 |
44 | exit 1
45 |
--------------------------------------------------------------------------------
/tests/expect_successful_plugin_download:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env expect
2 |
3 | # disables script output
4 | log_user 0
5 |
6 | spawn tmux
7 |
8 | # Waiting for tmux to attach. If this is not done, next command, `send` will
9 | # not work properly.
10 | sleep 1
11 |
12 | # this is tmux prefix + I
13 | send "I"
14 |
15 | # cloning might take a while
16 | set timeout 15
17 |
18 | expect_after {
19 | timeout { exit 1 }
20 | }
21 |
22 | expect {
23 | "Installing \"tmux-example-plugin\""
24 | }
25 |
26 | expect {
27 | "\"tmux-example-plugin\" download success"
28 | }
29 |
30 | expect {
31 | "Done, press ENTER to continue" {
32 | send "
"
33 | }
34 | }
35 |
36 | sleep 1
37 | # this is tmux prefix + I
38 | send "I"
39 |
40 | expect {
41 | "Already installed \"tmux-example-plugin\""
42 | }
43 |
44 | expect {
45 | "Done, press ENTER to continue" {
46 | exit 0
47 | }
48 | }
49 |
50 | exit 1
51 |
--------------------------------------------------------------------------------
/tests/expect_successful_update_of_a_single_plugin:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env expect
2 |
3 | # disables script output
4 | log_user 0
5 |
6 | spawn tmux
7 |
8 | # Waiting for tmux to attach. If this is not done, next command, `send` will
9 | # not work properly.
10 | sleep 1
11 |
12 | # this is tmux prefix + U
13 | send "U"
14 |
15 | set timeout 15
16 |
17 | expect_after {
18 | timeout { exit 1 }
19 | }
20 |
21 | expect {
22 | "Installed plugins"
23 | }
24 |
25 | expect {
26 | "tmux-example-plugin"
27 | }
28 |
29 | expect {
30 | "\"all\" - updates all plugins"
31 | }
32 |
33 | expect {
34 | "ENTER - cancels"
35 | }
36 |
37 | # wait for tmux to display prompt before sending characters
38 | sleep 1
39 | send "tmux-example-plugin\r"
40 |
41 | expect {
42 | "Updating \"tmux-example-plugin\""
43 | }
44 |
45 | expect {
46 | "\"tmux-example-plugin\" update success"
47 | }
48 |
49 | expect {
50 | "Done, press ENTER to continue." {
51 | exit 0
52 | }
53 | }
54 |
55 | exit 1
56 |
--------------------------------------------------------------------------------
/tests/expect_successful_update_of_all_plugins:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env expect
2 |
3 | # disables script output
4 | log_user 0
5 |
6 | spawn tmux
7 |
8 | # Waiting for tmux to attach. If this is not done, next command, `send` will
9 | # not work properly.
10 | sleep 1
11 |
12 | # this is tmux prefix + U
13 | send "U"
14 |
15 | set timeout 5
16 |
17 | expect_after {
18 | timeout { exit 1 }
19 | }
20 |
21 | expect {
22 | "Installed plugins"
23 | }
24 |
25 | expect {
26 | "tmux-example-plugin"
27 | }
28 |
29 | expect {
30 | "\"all\" - updates all plugins"
31 | }
32 |
33 | expect {
34 | "ENTER - cancels"
35 | }
36 |
37 | # wait for tmux to display prompt before sending characters
38 | sleep 1
39 | send "all\r"
40 |
41 | expect {
42 | "Updating all plugins!"
43 | }
44 |
45 | expect {
46 | "Updating \"tmux-example-plugin\""
47 | }
48 |
49 | expect {
50 | "\"tmux-example-plugin\" update success"
51 | }
52 |
53 | expect {
54 | "Done, press ENTER to continue." {
55 | exit 0
56 | }
57 | }
58 |
59 | exit 1
60 |
--------------------------------------------------------------------------------
/tests/helpers/tpm.sh:
--------------------------------------------------------------------------------
1 | check_dir_exists_helper() {
2 | [ -d "$1" ]
3 | }
4 |
5 | # runs the scripts and asserts it has the correct output and exit code
6 | script_run_helper() {
7 | local script="$1"
8 | local expected_output="$2"
9 | local expected_exit_code="${3:-0}"
10 | $script 2>&1 |
11 | grep "$expected_output" >/dev/null 2>&1 && # grep -q flag quits the script early
12 | [ "${PIPESTATUS[0]}" -eq "$expected_exit_code" ]
13 | }
14 |
--------------------------------------------------------------------------------
/tests/test_plugin_clean.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | TPM_DIR="$PWD"
5 | PLUGINS_DIR="$HOME/.tmux/plugins"
6 |
7 | source "$CURRENT_DIR/helpers/helpers.sh"
8 | source "$CURRENT_DIR/helpers/tpm.sh"
9 |
10 | manually_install_the_plugin() {
11 | rm -rf "$PLUGINS_DIR"
12 | mkdir -p "$PLUGINS_DIR"
13 | cd "$PLUGINS_DIR"
14 | git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin
15 | }
16 |
17 | # TMUX KEY-BINDING TESTS
18 |
19 | test_plugin_uninstallation_via_tmux_key_binding() {
20 | set_tmux_conf_helper <<- HERE
21 | set -g mode-keys vi
22 | run-shell "$TPM_DIR/tpm"
23 | HERE
24 |
25 | manually_install_the_plugin
26 |
27 | "$CURRENT_DIR/expect_successful_clean_plugins" ||
28 | fail_helper "[key-binding] clean fails"
29 |
30 | teardown_helper
31 | }
32 |
33 | # SCRIPT TESTS
34 |
35 | test_plugin_uninstallation_via_script() {
36 | set_tmux_conf_helper <<- HERE
37 | set -g mode-keys vi
38 | run-shell "$TPM_DIR/tpm"
39 | HERE
40 |
41 | manually_install_the_plugin
42 |
43 | script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean success' ||
44 | fail_helper "[script] plugin cleaning fails"
45 |
46 | teardown_helper
47 | }
48 |
49 | test_unsuccessful_plugin_uninstallation_via_script() {
50 | set_tmux_conf_helper <<- HERE
51 | set -g mode-keys vi
52 | run-shell "$TPM_DIR/tpm"
53 | HERE
54 |
55 | manually_install_the_plugin
56 | chmod 000 "$PLUGINS_DIR/tmux-example-plugin" # disable directory deletion
57 |
58 | local expected_exit_code=1
59 | script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean fail' "$expected_exit_code" ||
60 | fail_helper "[script] unsuccessful plugin cleaning doesn't fail"
61 |
62 | chmod 755 "$PLUGINS_DIR/tmux-example-plugin" # enable directory deletion
63 |
64 | teardown_helper
65 | }
66 |
67 | run_tests
68 |
--------------------------------------------------------------------------------
/tests/test_plugin_installation.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | PLUGINS_DIR="$HOME/.tmux/plugins"
5 | TPM_DIR="$PWD"
6 |
7 | CUSTOM_PLUGINS_DIR="$HOME/foo/plugins"
8 | ADDITIONAL_CONFIG_FILE_1="$HOME/.tmux/additional_config_file_1"
9 | ADDITIONAL_CONFIG_FILE_2="$HOME/.tmux/additional_config_file_2"
10 |
11 | source "$CURRENT_DIR/helpers/helpers.sh"
12 | source "$CURRENT_DIR/helpers/tpm.sh"
13 |
14 | # TMUX KEY-BINDING TESTS
15 |
16 | test_plugin_installation_via_tmux_key_binding() {
17 | set_tmux_conf_helper <<- HERE
18 | set -g mode-keys vi
19 | set -g @plugin "tmux-plugins/tmux-example-plugin"
20 | run-shell "$TPM_DIR/tpm"
21 | HERE
22 |
23 | "$CURRENT_DIR/expect_successful_plugin_download" ||
24 | fail_helper "[key-binding] plugin installation fails"
25 |
26 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
27 | fail_helper "[key-binding] plugin download fails"
28 |
29 | teardown_helper
30 | }
31 |
32 | test_plugin_installation_via_tmux_key_binding_set_option() {
33 | set_tmux_conf_helper <<- HERE
34 | set -g mode-keys vi
35 | set-option -g @plugin "tmux-plugins/tmux-example-plugin"
36 | run-shell "$TPM_DIR/tpm"
37 | HERE
38 |
39 | "$CURRENT_DIR/expect_successful_plugin_download" ||
40 | fail_helper "[key-binding][set-option] plugin installation fails"
41 |
42 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
43 | fail_helper "[key-binding][set-option] plugin download fails"
44 |
45 | teardown_helper
46 | }
47 |
48 | test_plugin_installation_custom_dir_via_tmux_key_binding() {
49 | set_tmux_conf_helper <<- HERE
50 | set -g mode-keys vi
51 | set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR'
52 |
53 | set -g @plugin "tmux-plugins/tmux-example-plugin"
54 | run-shell "$TPM_DIR/tpm"
55 | HERE
56 |
57 | "$CURRENT_DIR/expect_successful_plugin_download" ||
58 | fail_helper "[key-binding][custom dir] plugin installation fails"
59 |
60 | check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" ||
61 | fail_helper "[key-binding][custom dir] plugin download fails"
62 |
63 | teardown_helper
64 | rm -rf "$CUSTOM_PLUGINS_DIR"
65 | }
66 |
67 | test_non_existing_plugin_installation_via_tmux_key_binding() {
68 | set_tmux_conf_helper <<- HERE
69 | set -g mode-keys vi
70 | set -g @plugin "tmux-plugins/non-existing-plugin"
71 | run-shell "$TPM_DIR/tpm"
72 | HERE
73 |
74 | "$CURRENT_DIR/expect_failed_plugin_download" ||
75 | fail_helper "[key-binding] non existing plugin installation doesn't fail"
76 |
77 | teardown_helper
78 | }
79 |
80 | test_multiple_plugins_installation_via_tmux_key_binding() {
81 | set_tmux_conf_helper <<- HERE
82 | set -g mode-keys vi
83 | set -g @plugin "tmux-plugins/tmux-example-plugin"
84 | \ \ set -g @plugin 'tmux-plugins/tmux-copycat'
85 | run-shell "$TPM_DIR/tpm"
86 | HERE
87 |
88 | "$CURRENT_DIR/expect_successful_multiple_plugins_download" ||
89 | fail_helper "[key-binding] multiple plugins installation fails"
90 |
91 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
92 | fail_helper "[key-binding] plugin download fails (tmux-example-plugin)"
93 |
94 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
95 | fail_helper "[key-binding] plugin download fails (tmux-copycat)"
96 |
97 | teardown_helper
98 | }
99 |
100 | test_plugins_installation_from_sourced_file_via_tmux_key_binding() {
101 | set_tmux_conf_helper <<- HERE
102 | set -g mode-keys vi
103 | source '$ADDITIONAL_CONFIG_FILE_1'
104 | set -g @plugin 'tmux-plugins/tmux-example-plugin'
105 | run-shell "$TPM_DIR/tpm"
106 | HERE
107 |
108 | mkdir ~/.tmux
109 | echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1"
110 |
111 | "$CURRENT_DIR/expect_successful_multiple_plugins_download" ||
112 | fail_helper "[key-binding][sourced file] plugins installation fails"
113 |
114 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
115 | fail_helper "[key-binding][sourced file] plugin download fails (tmux-example-plugin)"
116 |
117 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
118 | fail_helper "[key-binding][sourced file] plugin download fails (tmux-copycat)"
119 |
120 | teardown_helper
121 | }
122 |
123 | test_plugins_installation_from_multiple_sourced_files_via_tmux_key_binding() {
124 | set_tmux_conf_helper <<- HERE
125 | set -g mode-keys vi
126 | \ \ source '$ADDITIONAL_CONFIG_FILE_1'
127 | source-file '$ADDITIONAL_CONFIG_FILE_2'
128 | run-shell "$TPM_DIR/tpm"
129 | HERE
130 |
131 | mkdir ~/.tmux
132 | echo "set -g @plugin 'tmux-plugins/tmux-example-plugin'" > "$ADDITIONAL_CONFIG_FILE_1"
133 | echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_2"
134 |
135 | "$CURRENT_DIR/expect_successful_multiple_plugins_download" ||
136 | fail_helper "[key-binding][multiple sourced files] plugins installation fails"
137 |
138 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
139 | fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-example-plugin)"
140 |
141 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
142 | fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-copycat)"
143 |
144 | teardown_helper
145 | }
146 |
147 | # SCRIPT TESTS
148 |
149 | test_plugin_installation_via_script() {
150 | set_tmux_conf_helper <<- HERE
151 | set -g mode-keys vi
152 | set -g @plugin "tmux-plugins/tmux-example-plugin"
153 | run-shell "$TPM_DIR/tpm"
154 | HERE
155 |
156 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' ||
157 | fail_helper "[script] plugin installation fails"
158 |
159 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
160 | fail_helper "[script] plugin download fails"
161 |
162 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' ||
163 | fail_helper "[script] plugin already installed message fail"
164 |
165 | teardown_helper
166 | }
167 |
168 | test_plugin_installation_custom_dir_via_script() {
169 | set_tmux_conf_helper <<- HERE
170 | set -g mode-keys vi
171 | set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR'
172 |
173 | set -g @plugin "tmux-plugins/tmux-example-plugin"
174 | run-shell "$TPM_DIR/tpm"
175 | HERE
176 |
177 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' ||
178 | fail_helper "[script][custom dir] plugin installation fails"
179 |
180 | check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" ||
181 | fail_helper "[script][custom dir] plugin download fails"
182 |
183 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' ||
184 | fail_helper "[script][custom dir] plugin already installed message fail"
185 |
186 | teardown_helper
187 | rm -rf "$CUSTOM_PLUGINS_DIR"
188 | }
189 |
190 | test_non_existing_plugin_installation_via_script() {
191 | set_tmux_conf_helper <<- HERE
192 | set -g mode-keys vi
193 | set -g @plugin "tmux-plugins/non-existing-plugin"
194 | run-shell "$TPM_DIR/tpm"
195 | HERE
196 |
197 | local expected_exit_code=1
198 | script_run_helper "$TPM_DIR/bin/install_plugins" '"non-existing-plugin" download fail' "$expected_exit_code" ||
199 | fail_helper "[script] non existing plugin installation doesn't fail"
200 |
201 | teardown_helper
202 | }
203 |
204 | test_multiple_plugins_installation_via_script() {
205 | set_tmux_conf_helper <<- HERE
206 | set -g mode-keys vi
207 | set -g @plugin "tmux-plugins/tmux-example-plugin"
208 | \ \ set -g @plugin 'tmux-plugins/tmux-copycat'
209 | run-shell "$TPM_DIR/tpm"
210 | HERE
211 |
212 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' ||
213 | fail_helper "[script] multiple plugins installation fails"
214 |
215 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
216 | fail_helper "[script] plugin download fails (tmux-example-plugin)"
217 |
218 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
219 | fail_helper "[script] plugin download fails (tmux-copycat)"
220 |
221 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' ||
222 | fail_helper "[script] multiple plugins already installed message fail"
223 |
224 | teardown_helper
225 | }
226 |
227 | test_plugins_installation_from_sourced_file_via_script() {
228 | set_tmux_conf_helper <<- HERE
229 | set -g mode-keys vi
230 | source '$ADDITIONAL_CONFIG_FILE_1'
231 | set -g @plugin 'tmux-plugins/tmux-example-plugin'
232 | run-shell "$TPM_DIR/tpm"
233 | HERE
234 |
235 | mkdir ~/.tmux
236 | echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1"
237 |
238 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-copycat" download success' ||
239 | fail_helper "[script][sourced file] plugins installation fails"
240 |
241 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
242 | fail_helper "[script][sourced file] plugin download fails (tmux-example-plugin)"
243 |
244 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
245 | fail_helper "[script][sourced file] plugin download fails (tmux-copycat)"
246 |
247 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' ||
248 | fail_helper "[script][sourced file] plugins already installed message fail"
249 |
250 | teardown_helper
251 | }
252 |
253 | test_plugins_installation_from_multiple_sourced_files_via_script() {
254 | set_tmux_conf_helper <<- HERE
255 | set -g mode-keys vi
256 | \ \ source '$ADDITIONAL_CONFIG_FILE_1'
257 | source-file '$ADDITIONAL_CONFIG_FILE_2'
258 | set -g @plugin 'tmux-plugins/tmux-example-plugin'
259 | run-shell "$TPM_DIR/tpm"
260 | HERE
261 |
262 | mkdir ~/.tmux
263 | echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1"
264 | echo "set -g @plugin 'tmux-plugins/tmux-sensible'" > "$ADDITIONAL_CONFIG_FILE_2"
265 |
266 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-sensible" download success' ||
267 | fail_helper "[script][multiple sourced files] plugins installation fails"
268 |
269 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
270 | fail_helper "[script][multiple sourced files] plugin download fails (tmux-example-plugin)"
271 |
272 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
273 | fail_helper "[script][multiple sourced files] plugin download fails (tmux-copycat)"
274 |
275 | check_dir_exists_helper "$PLUGINS_DIR/tmux-sensible/" ||
276 | fail_helper "[script][multiple sourced files] plugin download fails (tmux-sensible)"
277 |
278 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-sensible"' ||
279 | fail_helper "[script][multiple sourced files] plugins already installed message fail"
280 |
281 | teardown_helper
282 | }
283 |
284 | run_tests
285 |
--------------------------------------------------------------------------------
/tests/test_plugin_installation_legacy.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | PLUGINS_DIR="$HOME/.tmux/plugins"
5 | TPM_DIR="$PWD"
6 |
7 | source "$CURRENT_DIR/helpers/helpers.sh"
8 | source "$CURRENT_DIR/helpers/tpm.sh"
9 |
10 | # TMUX KEY-BINDING TESTS
11 |
12 | test_plugin_installation_via_tmux_key_binding() {
13 | set_tmux_conf_helper <<- HERE
14 | set -g mode-keys vi
15 | set -g @tpm_plugins "tmux-plugins/tmux-example-plugin"
16 | run-shell "$TPM_DIR/tpm"
17 | HERE
18 |
19 | # opens tmux and test it with `expect`
20 | $CURRENT_DIR/expect_successful_plugin_download ||
21 | fail_helper "[key-binding] plugin installation fails"
22 |
23 | # check plugin dir exists after download
24 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
25 | fail_helper "[key-binding] plugin download fails"
26 |
27 | teardown_helper
28 | }
29 |
30 | test_legacy_and_new_syntax_for_plugin_installation_work_via_tmux_key_binding() {
31 | set_tmux_conf_helper <<- HERE
32 | set -g mode-keys vi
33 | set -g @tpm_plugins " \
34 | tmux-plugins/tmux-example-plugin \
35 | "
36 | set -g @plugin 'tmux-plugins/tmux-copycat'
37 | run-shell "$TPM_DIR/tpm"
38 | HERE
39 |
40 | # opens tmux and test it with `expect`
41 | "$CURRENT_DIR"/expect_successful_multiple_plugins_download ||
42 | fail_helper "[key-binding] multiple plugins installation fails"
43 |
44 | # check plugin dir exists after download
45 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
46 | fail_helper "[key-binding] plugin download fails (tmux-example-plugin)"
47 |
48 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
49 | fail_helper "[key-binding] plugin download fails (tmux-copycat)"
50 |
51 | teardown_helper
52 | }
53 |
54 | # SCRIPT TESTS
55 |
56 | test_plugin_installation_via_script() {
57 | set_tmux_conf_helper <<- HERE
58 | set -g mode-keys vi
59 | set -g @tpm_plugins "tmux-plugins/tmux-example-plugin"
60 | run-shell "$TPM_DIR/tpm"
61 | HERE
62 |
63 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' ||
64 | fail_helper "[script] plugin installation fails"
65 |
66 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
67 | fail_helper "[script] plugin download fails"
68 |
69 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' ||
70 | fail_helper "[script] plugin already installed message fail"
71 |
72 | teardown_helper
73 | }
74 |
75 | test_legacy_and_new_syntax_for_plugin_installation_work_via_script() {
76 | set_tmux_conf_helper <<- HERE
77 | set -g mode-keys vi
78 | set -g @tpm_plugins " \
79 | tmux-plugins/tmux-example-plugin \
80 | "
81 | set -g @plugin 'tmux-plugins/tmux-copycat'
82 | run-shell "$TPM_DIR/tpm"
83 | HERE
84 |
85 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' ||
86 | fail_helper "[script] multiple plugin installation fails"
87 |
88 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" ||
89 | fail_helper "[script] plugin download fails (tmux-example-plugin)"
90 |
91 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" ||
92 | fail_helper "[script] plugin download fails (tmux-copycat)"
93 |
94 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' ||
95 | fail_helper "[script] multiple plugins already installed message fail"
96 |
97 | teardown_helper
98 | }
99 |
100 | run_tests
101 |
--------------------------------------------------------------------------------
/tests/test_plugin_sourcing.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | TPM_DIR="$PWD"
5 | PLUGINS_DIR="$HOME/.tmux/plugins"
6 |
7 | CUSTOM_PLUGINS_DIR="$HOME/foo/plugins"
8 |
9 | source "$CURRENT_DIR/helpers/helpers.sh"
10 | source "$CURRENT_DIR/helpers/tpm.sh"
11 |
12 | check_binding_defined() {
13 | local binding="$1"
14 | tmux list-keys | grep -q "$binding"
15 | }
16 |
17 | create_test_plugin_helper() {
18 | local plugin_path="$PLUGINS_DIR/tmux_test_plugin/"
19 | rm -rf "$plugin_path"
20 | mkdir -p "$plugin_path"
21 |
22 | while read line; do
23 | echo "$line" >> "$plugin_path/test_plugin.tmux"
24 | done
25 | chmod +x "$plugin_path/test_plugin.tmux"
26 | }
27 |
28 | check_tpm_path() {
29 | local correct_tpm_path="$1"
30 | local tpm_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)"
31 | [ "$correct_tpm_path" == "$tpm_path" ]
32 | }
33 |
34 | test_plugin_sourcing() {
35 | set_tmux_conf_helper <<- HERE
36 | set -g mode-keys vi
37 | set -g @plugin "doesnt_matter/tmux_test_plugin"
38 | run-shell "$TPM_DIR/tpm"
39 | HERE
40 |
41 | # manually creates a local tmux plugin
42 | create_test_plugin_helper <<- HERE
43 | tmux bind-key R run-shell foo_command
44 | HERE
45 |
46 | tmux new-session -d # tmux starts detached
47 | check_binding_defined "R run-shell foo_command" ||
48 | fail_helper "Plugin sourcing fails"
49 |
50 | teardown_helper
51 | }
52 |
53 | test_default_tpm_path() {
54 | set_tmux_conf_helper <<- HERE
55 | set -g mode-keys vi
56 | run-shell "$TPM_DIR/tpm"
57 | HERE
58 |
59 | check_tpm_path "${PLUGINS_DIR}/" ||
60 | fail_helper "Default TPM path not correct"
61 |
62 | teardown_helper
63 | }
64 |
65 | test_custom_tpm_path() {
66 | set_tmux_conf_helper <<- HERE
67 | set -g mode-keys vi
68 | set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR'
69 | run-shell "$TPM_DIR/tpm"
70 | HERE
71 |
72 | check_tpm_path "$CUSTOM_PLUGINS_DIR" ||
73 | fail_helper "Custom TPM path not correct"
74 |
75 | teardown_helper
76 | }
77 |
78 | run_tests
79 |
--------------------------------------------------------------------------------
/tests/test_plugin_update.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | TPM_DIR="$PWD"
5 | PLUGINS_DIR="$HOME/.tmux/plugins"
6 |
7 | source "$CURRENT_DIR/helpers/helpers.sh"
8 | source "$CURRENT_DIR/helpers/tpm.sh"
9 |
10 | manually_install_the_plugin() {
11 | mkdir -p "$PLUGINS_DIR"
12 | cd "$PLUGINS_DIR"
13 | git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin
14 | }
15 |
16 | # TMUX KEY-BINDING TESTS
17 |
18 | test_plugin_update_via_tmux_key_binding() {
19 | set_tmux_conf_helper <<- HERE
20 | set -g mode-keys vi
21 | set -g @plugin "tmux-plugins/tmux-example-plugin"
22 | run-shell "$TPM_DIR/tpm"
23 | HERE
24 |
25 | manually_install_the_plugin
26 |
27 | "$CURRENT_DIR/expect_successful_update_of_all_plugins" ||
28 | fail_helper "[key-binding] 'update all plugins' fails"
29 |
30 | "$CURRENT_DIR/expect_successful_update_of_a_single_plugin" ||
31 | fail_helper "[key-binding] 'update single plugin' fails"
32 |
33 | teardown_helper
34 | }
35 |
36 | # SCRIPT TESTS
37 |
38 | test_plugin_update_via_script() {
39 | set_tmux_conf_helper <<- HERE
40 | set -g mode-keys vi
41 | set -g @plugin "tmux-plugins/tmux-example-plugin"
42 | run-shell "$TPM_DIR/tpm"
43 | HERE
44 |
45 | manually_install_the_plugin
46 |
47 | local expected_exit_code=1
48 | script_run_helper "$TPM_DIR/bin/update_plugins" 'usage' "$expected_exit_code" ||
49 | fail_helper "[script] running update plugins without args should fail"
50 |
51 | script_run_helper "$TPM_DIR/bin/update_plugins tmux-example-plugin" '"tmux-example-plugin" update success' ||
52 | fail_helper "[script] plugin update fails"
53 |
54 | script_run_helper "$TPM_DIR/bin/update_plugins all" '"tmux-example-plugin" update success' ||
55 | fail_helper "[script] update all plugins fails"
56 |
57 | teardown_helper
58 | }
59 |
60 | run_tests
61 |
--------------------------------------------------------------------------------
/tpm:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
4 | BINDINGS_DIR="$CURRENT_DIR/bindings"
5 | SCRIPTS_DIR="$CURRENT_DIR/scripts"
6 |
7 | source "$SCRIPTS_DIR/variables.sh"
8 |
9 | get_tmux_option() {
10 | local option="$1"
11 | local default_value="$2"
12 | local option_value="$(tmux show-option -gqv "$option")"
13 | if [ -z "$option_value" ]; then
14 | echo "$default_value"
15 | else
16 | echo "$option_value"
17 | fi
18 | }
19 |
20 | tpm_path_set() {
21 | tmux show-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" >/dev/null 2>&1
22 | }
23 |
24 | # Check if configuration file exists at an XDG-compatible location, if so use
25 | # that directory for TMUX_PLUGIN_MANAGER_PATH. Otherwise use $DEFAULT_TPM_PATH.
26 | set_default_tpm_path() {
27 | local xdg_tmux_path="${XDG_CONFIG_HOME:-$HOME/.config}/tmux"
28 | local tpm_path="$DEFAULT_TPM_PATH"
29 |
30 | if [ -f "$xdg_tmux_path/tmux.conf" ]; then
31 | tpm_path="$xdg_tmux_path/plugins/"
32 | fi
33 |
34 | tmux set-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" "$tpm_path"
35 | }
36 |
37 | # Ensures TMUX_PLUGIN_MANAGER_PATH global env variable is set.
38 | #
39 | # Put this in `.tmux.conf` to override the default:
40 | # `set-environment -g TMUX_PLUGIN_MANAGER_PATH "/some/other/path/"`
41 | set_tpm_path() {
42 | if ! tpm_path_set; then
43 | set_default_tpm_path
44 | fi
45 | }
46 |
47 | # 1. Fetches plugin names from `@plugin` variables
48 | # 2. Creates full plugin path
49 | # 3. Sources all *.tmux files from each of the plugin directories
50 | # - no errors raised if directory does not exist
51 | # Files are sourced as tmux config files, not as shell scripts!
52 | source_plugins() {
53 | "$SCRIPTS_DIR/source_plugins.sh" >/dev/null 2>&1
54 | }
55 |
56 | # prefix + I - downloads TPM plugins and reloads TMUX environment
57 | # prefix + U - updates a plugin (or all of them) and reloads TMUX environment
58 | # prefix + alt + u - remove unused TPM plugins and reloads TMUX environment
59 | set_tpm_key_bindings() {
60 | local install_key="$(get_tmux_option "$install_key_option" "$default_install_key")"
61 | tmux bind-key "$install_key" run-shell "$BINDINGS_DIR/install_plugins"
62 |
63 | local update_key="$(get_tmux_option "$update_key_option" "$default_update_key")"
64 | tmux bind-key "$update_key" run-shell "$BINDINGS_DIR/update_plugins"
65 |
66 | local clean_key="$(get_tmux_option "$clean_key_option" "$default_clean_key")"
67 | tmux bind-key "$clean_key" run-shell "$BINDINGS_DIR/clean_plugins"
68 | }
69 |
70 | supported_tmux_version_ok() {
71 | "$SCRIPTS_DIR/check_tmux_version.sh" "$SUPPORTED_TMUX_VERSION"
72 | }
73 |
74 | main() {
75 | if supported_tmux_version_ok; then
76 | set_tpm_path
77 | set_tpm_key_bindings
78 | source_plugins
79 | fi
80 | }
81 | main
82 |
--------------------------------------------------------------------------------