diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..80772e4 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,9 @@ +# Force text files to have unix eols, so Windows/Cygwin does not break them +*.* eol=lf + +# These files are unfortunately not recognized as text files so +# explicitly listing them here +tpm eol=lf +bin/* eol=lf +bindings/* eol=lf +tests/* eol=lf diff --git a/CHANGELOG.md b/CHANGELOG.md index d141843..394758d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ - upgrade to new version of `tmux-test` - bug: when using `emacs` copy mode, Enter does not quit screen after tpm installation/update. Fix by making `Escape` the key for emacs mode. +- add a doc with troubleshooting instructions +- add `.gitattributes` file that forces linefeed characters (classic `\n`) as + line endings - helps with misconfigured git on windows/cygwin +- readme update: announce Cygwin support +- un-deprecate old plugin definition syntax: `set -g @tpm_plugins` ### v3.0.0, 2015-08-03 - refactor `shared_set_tpm_path_constant` function @@ -23,7 +28,7 @@ - enable overriding default key bindings - start using `C-c` to clear screen - add uninstall/clean procedure and keybinding (prefix+alt+u) (@chilicuil) -- add new `set @plugin 'repo'` plugin defintion syntax (@chilicuil) +- add new `set @plugin 'repo'` plugin definition syntax (@chilicuil) - revert back to using `-g` flag in new plugin definition syntax - permit leading whitespace with new plugin definition syntax (thanks @chilicuil) - make sure `TMUX_PLUGIN_MANAGER_PATH` always has trailng slash diff --git a/README.md b/README.md index 9559d83..db640bf 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # Tmux Plugin Manager -[![Build Status](https://travis-ci.org/tmux-plugins/tpm.png?branch=master)](https://travis-ci.org/tmux-plugins/tpm) +[![Build Status](https://travis-ci.org/tmux-plugins/tpm.svg?branch=master)](https://travis-ci.org/tmux-plugins/tpm) -Installs and loads TMUX plugins. +Installs and loads `tmux` plugins. + +Tested and working on Linux, OSX, and Cygwin. ### Installation @@ -10,57 +12,61 @@ Requirements: `tmux` version 1.9 (or higher), `git`, `bash`. Clone TPM: - $ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm +```bash +$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm +``` -Put this at the bottom of `.tmux.conf`: +Put this at the bottom of `~/.tmux.conf` (`$XDG_CONFIG_HOME/tmux/tmux.conf` +works too): - # List of plugins - set -g @plugin 'tmux-plugins/tpm' - set -g @plugin 'tmux-plugins/tmux-sensible' +```bash +# List of plugins +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' - # Other examples: - # set -g @plugin 'github_username/plugin_name' - # set -g @plugin 'git@github.com/user/plugin' - # set -g @plugin 'git@bitbucket.com/user/plugin' +# Other examples: +# set -g @plugin 'github_username/plugin_name' +# set -g @plugin 'git@github.com/user/plugin' +# set -g @plugin 'git@bitbucket.com/user/plugin' - # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) - run '~/.tmux/plugins/tpm/tpm' +# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) +run -b '~/.tmux/plugins/tpm/tpm' +``` Reload TMUX environment so TPM is sourced: - # type this in terminal - $ tmux source ~/.tmux.conf +```bash +# type this in terminal if tmux is already running +$ tmux source ~/.tmux.conf +``` That's it! -(**Note:** using `set -g @tpm_plugins` is deprecated, but still works alongside -new syntax) - ### Installing plugins -1. add new plugin to `.tmux.conf` with `set -g @plugin '...'` -2. hit `prefix + I` (I as in **I**nstall) to fetch the plugin +1. Add new plugin to `~/.tmux.conf` with `set -g @plugin '...'` +2. Press `prefix` + I (capital i, as in **I**nstall) to fetch the plugin. You're good to go! The plugin was cloned to `~/.tmux/plugins/` dir and sourced. ### Uninstalling plugins -1. remove (or comment out) plugin from the list -2. hit `prefix + alt + u` (u as in **u**install) to remove the plugin +1. Remove (or comment out) plugin from the list. +2. Press `prefix` + alt + u (lowercase u as in **u**ninstall) to remove the plugin. All the plugins are installed to `~/.tmux/plugins/` so alternatively you can find plugin directory there and remove it. ### Key bindings -`prefix + I` -- installs new plugins from github or any other git repo -- refreshes TMUX environment +`prefix` + I +- Installs new plugins from GitHub or any other git repository +- Refreshes TMUX environment -`prefix + U` +`prefix` + U - updates plugin(s) -`prefix + alt + u` +`prefix` + alt + u - remove/uninstall plugins not on the plugin list ### More plugins @@ -69,6 +75,8 @@ For more plugins, check [here](https://github.com/tmux-plugins). ### Docs +- [Help, tpm not working](docs/tpm_not_working.md) - problem solutions + More advanced features and instructions, regular users probably do not need this: @@ -79,13 +87,15 @@ this: ### Tests -Tests for this project run on [travis](https://travis-ci.org/tmux-plugins/tpm). +Tests for this project run on [Travis CI](https://travis-ci.org/tmux-plugins/tpm). When run locally, [vagrant](https://www.vagrantup.com/) is required. Run tests with: - # within project directory - $ ./run_tests +```bash +# within project directory +$ ./run_tests +``` ### Other goodies diff --git a/docs/automatic_tpm_installation.md b/docs/automatic_tpm_installation.md index 22ded34..630573f 100644 --- a/docs/automatic_tpm_installation.md +++ b/docs/automatic_tpm_installation.md @@ -2,11 +2,11 @@ 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. -If you wanna install `tpm` automatically when tmux is started, put the following snippet in `.tmux.conf` before the final `run '~/.tmux/plugins/tpm/tpm'`: +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'`: ``` if "test ! -d ~/.tmux/plugins/tpm" \ - "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm'" + "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'" ``` -This useful tip was submitted by @acr4. +This useful tip was submitted by @acr4 and narfman0. diff --git a/docs/how_to_create_plugin.md b/docs/how_to_create_plugin.md index a7c6961..b1a68f9 100644 --- a/docs/how_to_create_plugin.md +++ b/docs/how_to_create_plugin.md @@ -27,7 +27,7 @@ directory. That's how plugins are run. Create a plugin run file in plugin directory: $ touch my_plugin.tmux - $ chmod +x my_plugin.tmux + $ chmod u+x my_plugin.tmux You can have more than one `*.tmux` file, and all will get executed. However, usually you'll need just one. @@ -69,7 +69,7 @@ Now that we have the binding, let's create a script that's invoked with $ mkdir scripts $ touch scripts/tmux_list_plugins.sh - $ chmod +x scripts/tmux_list_plugins.sh + $ chmod u+x scripts/tmux_list_plugins.sh And here's the script content: @@ -104,5 +104,5 @@ If the plugin is on Github, your users will be able to use the shorthand of Hopefully, that was easy. As you can see, it's mostly shell scripting. -You can use other scripting languages (ruby, phyton etc) but plain old shell +You can use other scripting languages (ruby, python etc) but plain old shell is preferred because of portability. diff --git a/docs/tpm_not_working.md b/docs/tpm_not_working.md new file mode 100644 index 0000000..bfa14ac --- /dev/null +++ b/docs/tpm_not_working.md @@ -0,0 +1,96 @@ +# Help, tpm not working! + +Here's the list of issues users had with `tpm`: + +
+ +> Nothing works. `tpm` key bindings `prefix + I`, `prefix + U` not even + defined. + +Related [issue #22](https://github.com/tmux-plugins/tpm/issues/22) + +- Do you have required `tmux` version to run `tpm`?
+ Check `tmux` version with `$ tmux -V` command and make sure it's higher or + equal to the required version for `tpm` as stated in the readme. + +- ZSH tmux plugin might be causing issues.
+ If you have it installed, try disabling it and see if `tpm` works then. + +
+ +> Help, I'm using custom config file with `tmux -f /path/to/my_tmux.conf` +to start Tmux and for some reason plugins aren't loaded!? + +Related [issue #57](https://github.com/tmux-plugins/tpm/issues/57) + +`tpm` has a known issue when using custom config file with `-f` option. +The solution is to use alternative plugin definition syntax. Here are the steps +to make it work: + +1. remove all `set -g @plugin` lines from tmux config file +2. in the config file define the plugins in the following way: + + # List of plugins + set -g @tpm_plugins ' \ + tmux-plugins/tpm \ + tmux-plugins/tmux-sensible \ + tmux-plugins/tmux-resurrect \ + ' + + # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) + run '~/.tmux/plugins/tpm/tpm' + +3. Reload TMUX environment so TPM is sourced: `$ tmux source /path/to/my_tmux.conf` + +The plugins should now be working. + +
+ +> Weird sequence of characters show up when installing or updating plugins + +Related: [issue #25](https://github.com/tmux-plugins/tpm/issues/25) + +- This could be caused by [tmuxline.vim](https://github.com/edkolev/tmuxline.vim) + plugin. Uninstall it and see if things work. + +
+ +> "failed to connect to server" error when sourcing .tmux.conf + +Related: [issue #48](https://github.com/tmux-plugins/tpm/issues/48) + +- Make sure `tmux source ~/.tmux.conf` command is ran from inside `tmux`. + +
+ +> tpm not working: '~/.tmux/plugins/tpm/tpm' returned 2 (Windows / Cygwin) + +Related: [issue #81](https://github.com/tmux-plugins/tpm/issues/81) + +This issue is most likely caused by Windows line endings. For example, if you +have git's `core.autocrlf` option set to `true`, git will automatically convert +all the files to Windows line endings which might cause a problem. + +The solution is to convert all line ending to Unix newline characters. This +command handles that for all files under `.tmux/` dir (skips `.git` +subdirectories): + +```bash +find ~/.tmux -type d -name '.git*' -prune -o -type f -print0 | xargs -0 dos2unix +``` + +
+ +> '~/.tmux/plugins/tpm/tpm' returned 127 (on macOS, w/ tmux installed using brew) + +Related: [issue #67](https://github.com/tmux-plugins/tpm/issues/67) + +This problem is because tmux's `run-shell` command runs a shell which doesn't read from user configs, thus tmux installed in `/usr/local/bin` will not be found. + +The solution is to insert the following line: + +``` +set-environment -g PATH "/usr/local/bin:/bin:/usr/bin" +``` + +before any `run-shell`/`run` commands in `~/.tmux.conf`. diff --git a/scripts/helpers/plugin_functions.sh b/scripts/helpers/plugin_functions.sh index e1da249..cbd1b55 100644 --- a/scripts/helpers/plugin_functions.sh +++ b/scripts/helpers/plugin_functions.sh @@ -15,8 +15,26 @@ _tpm_path() { _CACHED_TPM_PATH="$(_tpm_path)" +# Get the absolute path to the users configuration file of TMux. +# This includes a prioritized search on different locations. +# +_get_user_tmux_conf() { + # Define the different possible locations. + xdg_location="$XDG_CONFIG_HOME/tmux/tmux.conf" + default_location="$HOME/.tmux.conf" + + # Search for the correct configuration file by priority. + if [ -f "$xdg_location" ]; then + echo "$xdg_location" + + else + echo "$default_location" + fi +} + _tmux_conf_contents() { - cat /etc/tmux.conf ~/.tmux.conf 2>/dev/null + user_config=$(_get_user_tmux_conf) + cat /etc/tmux.conf "$user_config" 2>/dev/null if [ "$1" == "full" ]; then # also output content from sourced files local file for file in $(_sourced_files); do @@ -28,22 +46,35 @@ _tmux_conf_contents() { # return files sourced from tmux config files _sourced_files() { _tmux_conf_contents | - awk '/^ *source(-file)? +/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $2 }' + awk '/^[ \t]*source(-file)? +/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $2 }' +} + +# Want to be able to abort in certain cases +trap "exit 1" TERM +export TOP_PID=$$ + +_fatal_error_abort() { + echo >&2 "Aborting." + kill -s TERM $TOP_PID } # PUBLIC FUNCTIONS BELOW tpm_path() { + if [ "$_CACHED_TPM_PATH" == "/" ]; then + echo >&2 "FATAL: Tmux Plugin Manager not configured in tmux.conf" + _fatal_error_abort + fi echo "$_CACHED_TPM_PATH" } tpm_plugins_list_helper() { - # DEPRECATED: lists plugins from @tpm_plugins option + # lists plugins from @tpm_plugins option echo "$(tmux start-server\; show-option -gqv "$tpm_plugins_variable_name")" # read set -g @plugin "tmux-plugins/tmux-example-plugin" entries _tmux_conf_contents "full" | - awk '/^ *set +-g +@plugin/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $4 }' + awk '/^[ \t]*set(-option)? +-g +@plugin/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $4 }' } # Allowed plugin name formats: diff --git a/scripts/update_plugin.sh b/scripts/update_plugin.sh index d923d83..7d856ee 100755 --- a/scripts/update_plugin.sh +++ b/scripts/update_plugin.sh @@ -27,7 +27,6 @@ pull_changes() { update() { local plugin="$1" - echo_ok "Updating \"$plugin\"" $(pull_changes "$plugin" > /dev/null 2>&1) && echo_ok " \"$plugin\" update success" || echo_err " \"$plugin\" update fail" @@ -41,9 +40,10 @@ update_all() { local plugin_name="$(plugin_name_helper "$plugin")" # updating only installed plugins if plugin_already_installed "$plugin_name"; then - update "$plugin_name" + update "$plugin_name" & fi done + wait } update_plugins() { @@ -51,14 +51,16 @@ update_plugins() { for plugin in $plugins; do local plugin_name="$(plugin_name_helper "$plugin")" if plugin_already_installed "$plugin_name"; then - update "$plugin_name" + update "$plugin_name" & else - echo_err "$plugin_name not installed!" + echo_err "$plugin_name not installed!" & fi done + wait } main() { + ensure_tpm_path_exists if [ "$1" == "all" ]; then update_all else diff --git a/tests/test_plugin_installation.sh b/tests/test_plugin_installation.sh index 65b1899..94fb674 100755 --- a/tests/test_plugin_installation.sh +++ b/tests/test_plugin_installation.sh @@ -29,6 +29,22 @@ test_plugin_installation_via_tmux_key_binding() { teardown_helper } +test_plugin_installation_via_tmux_key_binding_set_option() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-option -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding][set-option] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][set-option] plugin download fails" + + teardown_helper +} + test_plugin_installation_custom_dir_via_tmux_key_binding() { set_tmux_conf_helper <<- HERE set -g mode-keys vi