diff --git a/dot_config/tmux/plugins/tmux-sensible/CHANGELOG.md b/dot_config/tmux/plugins/tmux-sensible/CHANGELOG.md new file mode 100644 index 0000000..579c0db --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/CHANGELOG.md @@ -0,0 +1,43 @@ +# Changelog + +### master +- remove `detach-on-destroy` +- do not set `aggressive-resize` on iTerm terminal +- disable `detach-on-destroy` + +### v3.0.0, 2015-06-24 +- remove 'almost sensible' feature + +### v2.3.0, 2015-06-24 +- update to support \*THE\* latest tmux version +- bugfix for `prefix + R` key binding +- fix for tmux 2.0 `default-terminal` option (thanks @kwbr) + +### v2.2.0, 2015-02-10 +- bugfix in `key_binding_not_set`: the regex is now properly detecting key + bindings with `-r` flag. +- enable `aggressive-resize` + +### v2.1.0, 2014-12-12 +- check before binding `prefix + prefix` (@m1foley) +- enable `focus-events` +- deprecate 'almost sensible' feature. The reason for this is to focus the + plugin on doing just one thing. + +### v2.0.0, 2014-10-03 +- bugfix: prevent exiting tmux if 'reattach-to-user-namespace' is not installed +- remove all mouse-related options +- introduce 'almost sensible' setting and options + +### v1.1.0, 2014-08-30 +- bugfix: determine the default shell from the $SHELL env var on OS X +- set `mode-mouse on` by default +- do not make any decision about the prefix, just enhance it +- update `README.md`. List options set in the plugin. +- do *not* set `mode-mouse on` by default because some users don't like it +- if a user changes default prefix but binds `C-b` to something else, do not + unbind `C-b` + +### v1.0.0, 2014-07-30 +- initial work on the plugin +- add readme diff --git a/dot_config/tmux/plugins/tmux-sensible/LICENSE.md b/dot_config/tmux/plugins/tmux-sensible/LICENSE.md new file mode 100644 index 0000000..40f6ddd --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) 2014 Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dot_config/tmux/plugins/tmux-sensible/README.md b/dot_config/tmux/plugins/tmux-sensible/README.md new file mode 100644 index 0000000..fff34fa --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/README.md @@ -0,0 +1,122 @@ +# Tmux sensible + +A set of tmux options that should be acceptable to everyone. + +Inspired by [vim-sensible](https://github.com/tpope/vim-sensible). + +Tested and working on Linux, OSX and Cygwin. + +### Principles + +- `tmux-sensible` options should be acceptable to **every** tmux user!
+ If any of the options bothers you, please open an issue and it will probably + be updated (or removed). +- if you think a new option should be added, feel free to open a pull request. +- **no overriding** of user defined settings.
+ Your existing `.tmux.conf` settings are respected and they won't be changed. + That way you can use `tmux-sensible` if you have a few specific options. + +### Goals + +- group standard tmux community options in one place +- remove clutter from your `.tmux.conf` +- educate new tmux users about basic options + +### Options + +```tmux +# Address vim mode switching delay (http://superuser.com/a/252717/65504) +set -s escape-time 0 + +# Increase scrollback buffer size from 2000 to 50000 lines +set -g history-limit 50000 + +# Increase tmux messages display duration from 750ms to 4s +set -g display-time 4000 + +# Refresh 'status-left' and 'status-right' more often, from every 15s to 5s +set -g status-interval 5 + +# (OS X) Fix pbcopy/pbpaste for old tmux versions (pre 2.6) +set -g default-command "reattach-to-user-namespace -l $SHELL" + +# Upgrade $TERM +set -g default-terminal "screen-256color" + +# Emacs key bindings in tmux command prompt (prefix + :) are better than +# vi keys, even for vim users +set -g status-keys emacs + +# Focus events enabled for terminals that support them +set -g focus-events on + +# Super useful when using "grouped sessions" and multi-monitor setup +setw -g aggressive-resize on +``` + +### Key bindings + +```tmux +# Easier and faster switching between next/prev window +bind C-p previous-window +bind C-n next-window +``` + +Above bindings enhance the default `prefix + p` and `prefix + n` bindings by +allowing you to hold `Ctrl` and repeat `a + p`/`a + n` (if your prefix is +`C-a`), which is a lot quicker. + +```tmux +# Source .tmux.conf as suggested in `man tmux` +bind R source-file '~/.tmux.conf' +``` + +"Adaptable" key bindings that build upon your `prefix` value: + +```tmux +# If prefix is 'C-a' +bind C-a send-prefix +bind a last-window +``` + +If prefix is `C-b`, above keys will be `C-b` and `b`.
+If prefix is `C-z`, above keys will be `C-z` and `z`... you get the idea. + +### Installation with [Tmux Plugin Manager](https://github.com/tmux-plugins/tpm) (recommended) + +Add plugin to the list of TPM plugins in `.tmux.conf`: + +```tmux +set -g @plugin 'tmux-plugins/tmux-sensible' +``` + +Hit `prefix + I` to fetch the plugin and source it. That's it! + +### Manual Installation + +Clone the repo: + + $ git clone https://github.com/tmux-plugins/tmux-sensible ~/clone/path + +Add this line to the bottom of `.tmux.conf`: + +```tmux +run-shell ~/clone/path/sensible.tmux +``` + +Reload TMUX environment with `$ tmux source-file ~/.tmux.conf`, and that's it. + +### Other goodies + +You might also find these useful: + +- [copycat](https://github.com/tmux-plugins/tmux-copycat) + improve tmux search and reduce mouse usage +- [pain control](https://github.com/tmux-plugins/tmux-pain-control) + useful standard bindings for controlling panes +- [resurrect](https://github.com/tmux-plugins/tmux-resurrect) + persists tmux environment across system restarts + +### License + +[MIT](LICENSE.md) diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/branches/.keep b/dot_config/tmux/plugins/tmux-sensible/dot_git/branches/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/config b/dot_config/tmux/plugins/tmux-sensible/dot_git/config new file mode 100644 index 0000000..d3eb0d4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/tmux-plugins/tmux-sensible + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/description b/dot_config/tmux/plugins/tmux-sensible/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/index b/dot_config/tmux/plugins/tmux-sensible/dot_git/index new file mode 100644 index 0000000..241f06d Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/index differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/info/exclude b/dot_config/tmux/plugins/tmux-sensible/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/HEAD new file mode 100644 index 0000000..717b4c1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 25cb91f42d020f675bb0a2ce3fbd3a5d96119efa Hydroxycarbamide 1693244975 +0200 clone: from https://github.com/tmux-plugins/tmux-sensible diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/heads/master b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/heads/master new file mode 100644 index 0000000..717b4c1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 25cb91f42d020f675bb0a2ce3fbd3a5d96119efa Hydroxycarbamide 1693244975 +0200 clone: from https://github.com/tmux-plugins/tmux-sensible diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..717b4c1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 25cb91f42d020f675bb0a2ce3fbd3a5d96119efa Hydroxycarbamide 1693244975 +0200 clone: from https://github.com/tmux-plugins/tmux-sensible diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/info/.keep b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/info/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.idx b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.idx new file mode 100644 index 0000000..2cdcae9 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.idx differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.pack b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.pack new file mode 100644 index 0000000..adb25e1 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.pack differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.rev b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.rev new file mode 100644 index 0000000..a2745c4 Binary files /dev/null and b/dot_config/tmux/plugins/tmux-sensible/dot_git/objects/pack/readonly_pack-6b9a01cfec744033b4a7c1d9f764911107dadf93.rev differ diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/packed-refs b/dot_config/tmux/plugins/tmux-sensible/dot_git/packed-refs new file mode 100644 index 0000000..aa00119 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +25cb91f42d020f675bb0a2ce3fbd3a5d96119efa refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/heads/master b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/heads/master new file mode 100644 index 0000000..61072b5 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/heads/master @@ -0,0 +1 @@ +25cb91f42d020f675bb0a2ce3fbd3a5d96119efa diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.0.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.0.0 new file mode 100644 index 0000000..f9c2582 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.0.0 @@ -0,0 +1 @@ +bb7593b2c5c6c76a2872981f837d16e6ddbeff53 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.1.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.1.0 new file mode 100644 index 0000000..9a414ff --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v1.1.0 @@ -0,0 +1 @@ +dfea8c551c6c6b5e03873476360a732cc798f3a5 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.0.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.0.0 new file mode 100644 index 0000000..58a2b6e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.0.0 @@ -0,0 +1 @@ +8478e668197b78c46e2fe934ea2b582587731be9 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.1.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.1.0 new file mode 100644 index 0000000..9e5cf7a --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.1.0 @@ -0,0 +1 @@ +992141db12089e0a1cc9fac1e425788fdc34173c diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.2.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.2.0 new file mode 100644 index 0000000..ddb030e --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.2.0 @@ -0,0 +1 @@ +f896d2af916d3185616d498287515b3d43449aa1 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.3.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.3.0 new file mode 100644 index 0000000..39a28a4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v2.3.0 @@ -0,0 +1 @@ +a4f9a791e09178abcb7a9625cfea9e210f14210e diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v3.0.0 b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v3.0.0 new file mode 100644 index 0000000..631584b --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_git/refs/tags/v3.0.0 @@ -0,0 +1 @@ +ccb68a6b1cf9b75818b93240240d6d266f2f12c4 diff --git a/dot_config/tmux/plugins/tmux-sensible/dot_gitattributes b/dot_config/tmux/plugins/tmux-sensible/dot_gitattributes new file mode 100644 index 0000000..4cde323 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/dot_gitattributes @@ -0,0 +1,2 @@ +# Force text files to have unix eols, so Windows/Cygwin does not break them +*.* eol=lf diff --git a/dot_config/tmux/plugins/tmux-sensible/executable_sensible.tmux b/dot_config/tmux/plugins/tmux-sensible/executable_sensible.tmux new file mode 100644 index 0000000..66db3c1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux-sensible/executable_sensible.tmux @@ -0,0 +1,168 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# used to match output from `tmux list-keys` +KEY_BINDING_REGEX="bind-key[[:space:]]\+\(-r[[:space:]]\+\)\?\(-T prefix[[:space:]]\+\)\?" + +is_osx() { + local platform=$(uname) + [ "$platform" == "Darwin" ] +} + +iterm_terminal() { + [[ "${TERM_PROGRAM}" =~ ^iTerm || "${LC_TERMINAL}" =~ ^iTerm ]] +} + +command_exists() { + local command="$1" + type "$command" >/dev/null 2>&1 +} + +# returns prefix key, e.g. 'C-a' +prefix() { + tmux show-option -gv prefix +} + +# if prefix is 'C-a', this function returns 'a' +prefix_without_ctrl() { + local prefix="$(prefix)" + echo "$prefix" | cut -d '-' -f2 +} + +option_value_not_changed() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -gv "$option") + [ "$option_value" == "$default_value" ] +} + +server_option_value_not_changed() { + local option="$1" + local default_value="$2" + local option_value=$(tmux show-option -sv "$option") + [ "$option_value" == "$default_value" ] +} + +key_binding_not_set() { + local key="${1//\\/\\\\}" + if $(tmux list-keys | grep -q "${KEY_BINDING_REGEX}${key}[[:space:]]"); then + return 1 + else + return 0 + fi +} + +key_binding_not_changed() { + local key="$1" + local default_value="$2" + if $(tmux list-keys | grep -q "${KEY_BINDING_REGEX}${key}[[:space:]]\+${default_value}"); then + # key still has the default binding + return 0 + else + return 1 + fi +} + +get_tmux_config() { + local tmux_config_xdg="${XDG_CONFIG_HOME:-$HOME/.config}/tmux/tmux.conf" + local tmux_config="$HOME/.tmux.conf" + + if [ -f "${tmux_config_xdg}" ]; then + echo "${tmux_config_xdg}" + else + echo ${tmux_config} + fi +} + +main() { + # OPTIONS + + # address vim mode switching delay (http://superuser.com/a/252717/65504) + if server_option_value_not_changed "escape-time" "500"; then + tmux set-option -s escape-time 0 + fi + + # increase scrollback buffer size + if option_value_not_changed "history-limit" "2000"; then + tmux set-option -g history-limit 50000 + fi + + # tmux messages are displayed for 4 seconds + if option_value_not_changed "display-time" "750"; then + tmux set-option -g display-time 4000 + fi + + # refresh 'status-left' and 'status-right' more often + if option_value_not_changed "status-interval" "15"; then + tmux set-option -g status-interval 5 + fi + + # required (only) on OS X + if is_osx && command_exists "reattach-to-user-namespace" && option_value_not_changed "default-command" ""; then + tmux set-option -g default-command "reattach-to-user-namespace -l $SHELL" + fi + + # upgrade $TERM, tmux 1.9 + if option_value_not_changed "default-terminal" "screen"; then + tmux set-option -g default-terminal "screen-256color" + fi + # upgrade $TERM, tmux 2.0+ + if server_option_value_not_changed "default-terminal" "screen"; then + tmux set-option -s default-terminal "screen-256color" + fi + + # emacs key bindings in tmux command prompt (prefix + :) are better than + # vi keys, even for vim users + tmux set-option -g status-keys emacs + + # focus events enabled for terminals that support them + tmux set-option -g focus-events on + + # super useful when using "grouped sessions" and multi-monitor setup + if ! iterm_terminal; then + tmux set-window-option -g aggressive-resize on + fi + + # DEFAULT KEY BINDINGS + + local prefix="$(prefix)" + local prefix_without_ctrl="$(prefix_without_ctrl)" + + # if C-b is not prefix + if [ $prefix != "C-b" ]; then + # unbind obsolete default binding + if key_binding_not_changed "C-b" "send-prefix"; then + tmux unbind-key C-b + fi + + # pressing `prefix + prefix` sends to the shell + if key_binding_not_set "$prefix"; then + tmux bind-key "$prefix" send-prefix + fi + fi + + # If Ctrl-a is prefix then `Ctrl-a + a` switches between alternate windows. + # Works for any prefix character. + if key_binding_not_set "$prefix_without_ctrl"; then + tmux bind-key "$prefix_without_ctrl" last-window + fi + + # easier switching between next/prev window + if key_binding_not_set "C-p"; then + tmux bind-key C-p previous-window + fi + if key_binding_not_set "C-n"; then + tmux bind-key C-n next-window + fi + + # source `.tmux.conf` file - as suggested in `man tmux` + if key_binding_not_set "R"; then + local tmux_config=$(get_tmux_config) + + tmux bind-key R run-shell " \ + tmux source-file ${tmux_config} > /dev/null; \ + tmux display-message 'Sourced ${tmux_config}!'" + fi +} +main diff --git a/dot_config/tmux/plugins/tmux/LICENSE b/dot_config/tmux/plugins/tmux/LICENSE new file mode 100644 index 0000000..006383b --- /dev/null +++ b/dot_config/tmux/plugins/tmux/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Catppuccin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/dot_config/tmux/plugins/tmux/README.md b/dot_config/tmux/plugins/tmux/README.md new file mode 100644 index 0000000..916399a --- /dev/null +++ b/dot_config/tmux/plugins/tmux/README.md @@ -0,0 +1,376 @@ +

+ Logo
+ + Catppuccin for Tmux + +

+ +

+ + + +

+ +

+ +

+ +## Content + +1. [Themes](#themes) +2. [Installation](#installation) +3. [Overview](#overview) +4. [Configuration options](#configuration-options) + 1. [Window](#window) + 2. [Window default](#window-default) + 3. [Window current](#window-current) + 4. [Status](#status) + 5. [Customizing modules](#customizing-modules) + 6. [Battery module](#battery-module) +5. [Create a custom module](#create-a-custom-module) +6. [Configuration Examples](#configuration-examples) + 1. [Config 1](#config-1) + 2. [Config 2](#config-2) + 3. [Config 3](#config-3) + +## Themes + +- 🌻 [Latte](./catppuccin-latte.tmuxtheme) +- 🪴 [Frappé](./catppuccin-frappe.tmuxtheme) +- 🌺 [Macchiato](./catppuccin-macchiato.tmuxtheme) +- 🌿 [Mocha](./catppuccin-mocha.tmuxtheme) + +## Installation + +In order to have the icons displayed correctly please use / update your favorite [patched font](https://www.nerdfonts.com/font-downloads). +If you do not have a patched font installed, you can override or remove any icon. Check the documentation bellow on the options available. + +### TPM + +1. Install [TPM](https://github.com/tmux-plugins/tpm) +2. Add the Catppuccin plugin: + +```bash +set -g @plugin 'catppuccin/tmux' +# ...alongside +set -g @plugin 'tmux-plugins/tpm' +``` + +3. (Optional) Set your preferred flavour, it defaults to `"mocha"`: + +```bash +set -g @catppuccin_flavour 'latte' # or frappe, macchiato, mocha +``` + +### Manual + +1. Copy your desired theme's configuration contents into your Tmux config (usually stored at `~/.tmux.conf`) +2. Reload Tmux by either restarting the session or reloading it with `tmux source-file ~/.tmux.conf` + +## Overview + +![Default](./assets/overview.png) +This is a diagram on how the theme is split between it's components. + +## Configuration options + +All flavours support certain levels of customization that match our [Catppuccin +Style Guide][style-guide]. To add these customizations, add any of the following +options to your Tmux configuration. + +### Window + +#### Set the window left separator: +```sh +set -g @catppuccin_window_left_separator "█" +``` + +#### Set the window middle separator: +```sh +set -g @catppuccin_window_middle_separator "█" +``` + +#### Set the window right separator: +```sh +set -g @catppuccin_window_right_separator "█" +``` + +#### Position the number: +```sh +set -g @catppuccin_window_number_position "left" +``` +Values: +- left - the number will be on the left part of the window +- right - the number will be on the right part of the window + +#### Enable window status: +```sh +set -g @catppuccin_window_status_enable "yes" +``` +Values: +- yes - this will enable the window status part +- no - this will disable the window status part + +#### Enable window status icons instead of text: +```sh +set -g @catppuccin_window_status_icon_enable "yes" +``` +Values: +- yes - this will replace the windows status text with icons +- no - this will keep the windows status in text format + +#### Override windows status icons +```sh +set -g @catppuccin_icon_window_last "󰖰" +set -g @catppuccin_icon_window_current "󰖯" +set -g @catppuccin_icon_window_zoom "󰁌" +set -g @catppuccin_icon_window_mark "󰃀" +set -g @catppuccin_icon_window_silent "󰂛" +set -g @catppuccin_icon_window_activity "󰖲" +set -g @catppuccin_icon_window_bell "󰂞" +``` + +### Window default + +#### Set the window default color fill: +```sh +set -g @catppuccin_window_default_fill "number" +``` +Values: +- number - only the number of the window part will have color +- all - the entire window part will have the same color +- none - the entire window part will have no color + +#### Override the window default text: +```sh +set -g @catppuccin_window_default_text "#{b:pane_current_path}" # use "#W" for application instead of directory +``` + +### Window current + +#### Set the window current color fill: +```sh +set -g @catppuccin_window_current_fill "number" +``` +Values: +- number - only the number of the window part will have color +- all - the entire window part will have the same color +- none - the entire window part will have no color + +#### Override the window current text: +```sh +set -g @catppuccin_window_current_text "#{b:pane_current_path}" # use "#W" for application instead of directory +``` + +#### Set the current directory format +```sh +set -g @catppuccin_window_current_format_directory_text "#{b:pane_current_path}" +``` +Use this to overide the way the current directory is displayed. + +#### Set the directory format +```sh +set -g @catppuccin_window_format_directory_text "#{b:pane_current_path}" +``` +Use this to overide the way the directory is displayed. + +### Status + +#### Set the status module left separator: +```sh +set -g @catppuccin_status_left_separator "" +``` + +#### Set the status module right separator: +```sh +set -g @catppuccin_status_right_separator "█" +``` + +#### Set the status module right separator inverse: +```sh +set -g @catppuccin_status_right_separator_inverse "no" +``` +Values: +- yes - the colors will be inverted for the right separator +- no - the colors will not be inverted for the right separator + +#### Set the status connect separator: +```sh +set -g @catppuccin_status_connect_separator "yes" +``` +Values: +- yes - the background color of the separator will not blend in with the brackground color of tmux +- no - the background color of the separator will blend in with the brackground color of tmux + + +#### Set the status module color fill: +```sh +set -g @catppuccin_status_fill "icon" +``` +Values: +- icon - only the icon of the module will have color +- all - the entire module will have the same color + +#### Set the module list +```sh +set -g @catppuccin_status_modules "application session" +``` +Provide a list of modules and the order in which you want them to appear in the status. + +Available modules: +- application - display the current window running application +- directory - display the basename of the current window path +- session - display the number of tmux sessions running +- user - display the username +- host - display the hostname +- date_time - display the date and time +- [battery](#battery-module) - display the battery + +### Customizing modules + +Every module (except the module "session") supports the following overrides: + +#### Override the specific module icon +```sh +set -g @catppuccin_[module_name]_icon "icon" +``` + +#### Override the specific module color +```sh +set -g @catppuccin_[module_name]_color "color" +``` + +#### Override the specific module text +```sh +set -g @catppuccin_[module_name]_text "text" +``` + +#### Removing a specific module option +```sh +set -g @catppuccin_[module_name]_[option] "null" +``` +This is for the situation where you want to remove the icon from a module. +Ex: +```sh +set -g @catppuccin_date_time_icon "null" +``` + +### Battery module + +#### Requirements +This module depends on [tmux-battery](https://github.com/tmux-plugins/tmux-battery/tree/master). + +#### Install +The prefered way to install tmux-battery is using [TPM](https://github.com/tmux-plugins/tpm). + +#### Configure +Load tmux-battery after you load catppuccin. +```sh +set -g @plugin 'catppuccin/tmux' +... +set -g @plugin 'tmux-plugins/tmux-battery' +``` + +Add the battery module to the status modules list. +```sh +set -g @catppuccin_status_modules "... battery ..." +``` + +## Create a custom module + +It is possible to add a new custom module or overrite any of the existing modules. + +Look into custom/README.md for more details. + +Any file added to the custom folder will be preserved when updating catppuccin. + +## Configuration Examples +Below are provided a few configurations as examples or starting points. + +Note: +When switching bettwen configurations run: +```sh +tmux kill-server +``` +In order to kill the tmux server and clear all global variables. + + +### Config 1 +![Default](./assets/config1.png) + +```sh +set -g @catppuccin_window_right_separator "█ " +set -g @catppuccin_window_number_position "right" +set -g @catppuccin_window_middle_separator " | " + +set -g @catppuccin_window_default_fill "none" + +set -g @catppuccin_window_current_fill "all" + +set -g @catppuccin_status_modules "application session user host date_time" +set -g @catppuccin_status_left_separator "█" +set -g @catppuccin_status_right_separator "█" + +set -g @catppuccin_date_time_text "%Y-%m-%d %H:%M:%S" +``` + +### Config 2 +![Default](./assets/config2.png) + +```sh +set -g @catppuccin_window_left_separator "█" +set -g @catppuccin_window_right_separator "█ " +set -g @catppuccin_window_number_position "right" +set -g @catppuccin_window_middle_separator " █" + +set -g @catppuccin_window_default_fill "number" + +set -g @catppuccin_window_current_fill "number" +set -g @catppuccin_window_current_text "#{pane_current_path}" + +set -g @catppuccin_status_modules "application session date_time" +set -g @catppuccin_status_left_separator "" +set -g @catppuccin_status_right_separator " " +set -g @catppuccin_status_right_separator_inverse "yes" +set -g @catppuccin_status_fill "all" +set -g @catppuccin_status_connect_separator "no" +``` + +### Config 3 +![Default](./assets/config3.png) + +```sh +set -g @catppuccin_window_left_separator "" +set -g @catppuccin_window_right_separator " " +set -g @catppuccin_window_middle_separator " █" +set -g @catppuccin_window_number_position "right" + +set -g @catppuccin_window_default_fill "number" +set -g @catppuccin_window_default_text "#W" + +set -g @catppuccin_window_current_fill "number" +set -g @catppuccin_window_current_text "#W" + +set -g @catppuccin_status_modules "directory user host session" +set -g @catppuccin_status_left_separator " " +set -g @catppuccin_status_right_separator "" +set -g @catppuccin_status_right_separator_inverse "no" +set -g @catppuccin_status_fill "icon" +set -g @catppuccin_status_connect_separator "no" + +set -g @catppuccin_directory_text "#{pane_current_path}" +``` + +[style-guide]: https://github.com/catppuccin/catppuccin/blob/main/docs/style-guide.md + +## 💝 Thanks to + +- [Pocco81](https://github.com/catppuccin) +- [vinnyA3](https://github.com/vinnyA3) +- [rogeruiz](https://github.com/rogeruiz) + +  + +

+

Copyright © 2021-present Catppuccin Org +

diff --git a/dot_config/tmux/plugins/tmux/assets/config1.png b/dot_config/tmux/plugins/tmux/assets/config1.png new file mode 100644 index 0000000..79bc1af --- /dev/null +++ b/dot_config/tmux/plugins/tmux/assets/config1.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:19b8b4ff6c75075ab7593f1d20fcbee897dcc1bb8babe472bc8ce697aa7a8c83 +size 93462 diff --git a/dot_config/tmux/plugins/tmux/assets/config2.png b/dot_config/tmux/plugins/tmux/assets/config2.png new file mode 100644 index 0000000..0a8a13e --- /dev/null +++ b/dot_config/tmux/plugins/tmux/assets/config2.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df84b94a68f3e94a9b89ca08c17df4411e6c6f260d8cf199b206fd00191a8c59 +size 79236 diff --git a/dot_config/tmux/plugins/tmux/assets/config3.png b/dot_config/tmux/plugins/tmux/assets/config3.png new file mode 100644 index 0000000..40eb5a0 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/assets/config3.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0a96df00a128915de05e409aada417b9d57085c1df1af8c2bfe7eb53d441a1c5 +size 84927 diff --git a/dot_config/tmux/plugins/tmux/assets/frappe.webp b/dot_config/tmux/plugins/tmux/assets/frappe.webp new file mode 100644 index 0000000..64c14f8 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/assets/frappe.webp differ diff --git a/dot_config/tmux/plugins/tmux/assets/latte.webp b/dot_config/tmux/plugins/tmux/assets/latte.webp new file mode 100644 index 0000000..6e48ac9 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/assets/latte.webp differ diff --git a/dot_config/tmux/plugins/tmux/assets/macchiato.webp b/dot_config/tmux/plugins/tmux/assets/macchiato.webp new file mode 100644 index 0000000..df3aa04 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/assets/macchiato.webp differ diff --git a/dot_config/tmux/plugins/tmux/assets/mocha.webp b/dot_config/tmux/plugins/tmux/assets/mocha.webp new file mode 100644 index 0000000..d9ee469 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/assets/mocha.webp differ diff --git a/dot_config/tmux/plugins/tmux/assets/overview.png b/dot_config/tmux/plugins/tmux/assets/overview.png new file mode 100644 index 0000000..02bc754 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/assets/overview.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf7b173dfc74e285ff94e9ad649d736aedcdae6a2cd56d1488c75722594cf04e +size 227645 diff --git a/dot_config/tmux/plugins/tmux/assets/preview.webp b/dot_config/tmux/plugins/tmux/assets/preview.webp new file mode 100644 index 0000000..3224dc1 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/assets/preview.webp differ diff --git a/dot_config/tmux/plugins/tmux/catppuccin-frappe.tmuxtheme b/dot_config/tmux/plugins/tmux/catppuccin-frappe.tmuxtheme new file mode 100644 index 0000000..a38a73f --- /dev/null +++ b/dot_config/tmux/plugins/tmux/catppuccin-frappe.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Frappe) +thm_bg="#303446" +thm_fg="#c6d0f5" +thm_cyan="#99d1db" +thm_black="#292c3c" +thm_gray="#414559" +thm_magenta="#ca9ee6" +thm_pink="#f4b8e4" +thm_red="#e78284" +thm_green="#a6d189" +thm_yellow="#e5c890" +thm_blue="#8caaee" +thm_orange="#ef9f76" +thm_black4="#626880" diff --git a/dot_config/tmux/plugins/tmux/catppuccin-latte.tmuxtheme b/dot_config/tmux/plugins/tmux/catppuccin-latte.tmuxtheme new file mode 100644 index 0000000..16f078f --- /dev/null +++ b/dot_config/tmux/plugins/tmux/catppuccin-latte.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Latte) +thm_bg="#dce0e8" +thm_fg="#4c4f69" +thm_cyan="#179299" +thm_black="#e6e9ef" +thm_gray="#bcc0cc" +thm_magenta="#ea76cb" +thm_pink="#8839ef" +thm_red="#d20f39" +thm_green="#40a02b" +thm_yellow="#df8e1d" +thm_blue="#1e66f5" +thm_orange="#fe640b" +thm_black4="#acb0be" diff --git a/dot_config/tmux/plugins/tmux/catppuccin-macchiato.tmuxtheme b/dot_config/tmux/plugins/tmux/catppuccin-macchiato.tmuxtheme new file mode 100644 index 0000000..c90bf76 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/catppuccin-macchiato.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Macchiato) +thm_bg="#24273a" +thm_fg="#cad3f5" +thm_cyan="#91d7e3" +thm_black="#1e2030" +thm_gray="#363a4f" +thm_magenta="#c6a0f6" +thm_pink="#f5bde6" +thm_red="#ed8796" +thm_green="#a6da95" +thm_yellow="#eed49f" +thm_blue="#8aadf4" +thm_orange="#f5a97f" +thm_black4="#5b6078" diff --git a/dot_config/tmux/plugins/tmux/catppuccin-mocha.tmuxtheme b/dot_config/tmux/plugins/tmux/catppuccin-mocha.tmuxtheme new file mode 100644 index 0000000..41e6369 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/catppuccin-mocha.tmuxtheme @@ -0,0 +1,17 @@ +# NOTE: you can use vars with $ and ${} as long as the str is double quoted: "" +# WARNING: hex colors can't contain capital letters + +# --> Catppuccin (Mocha) +thm_bg="#1e1e2e" +thm_fg="#cdd6f4" +thm_cyan="#89dceb" +thm_black="#181825" +thm_gray="#313244" +thm_magenta="#cba6f7" +thm_pink="#f5c2e7" +thm_red="#f38ba8" +thm_green="#a6e3a1" +thm_yellow="#f9e2af" +thm_blue="#89b4fa" +thm_orange="#fab387" +thm_black4="#585b70" diff --git a/dot_config/tmux/plugins/tmux/custom/README.md b/dot_config/tmux/plugins/tmux/custom/README.md new file mode 100644 index 0000000..232df4a --- /dev/null +++ b/dot_config/tmux/plugins/tmux/custom/README.md @@ -0,0 +1,32 @@ +# User defined modules + +## Description + +This folder is used to store user defined modules. +You can use this folder to add a new module or override any existing module. +To override an existing module, make sure you use the same name for your module as the module you want to override. +You can also override the window module for current and default window. + +## Create a new module + +Use the [Module template](#module-template) (or example.sh) as a starting point when creating a new module. +Save the new module under this folder using the module name as the file name and .sh as the extension. +Update the status module list with your module. +```sh +set -g @catppuccin_status_modules "... ..." + +``` + +## Module template +```sh +show_() { # save this module in a file with the name .sh + local index=$1 # this variable is used by the module loader in order to know the position of this module + local icon="$(get_tmux_option "@catppuccin__icon" "")" + local color="$(get_tmux_option "@catppuccin__color" "")" + local text="$(get_tmux_option "@catppuccin__text" "")" + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} +``` diff --git a/dot_config/tmux/plugins/tmux/custom/example.sh b/dot_config/tmux/plugins/tmux/custom/example.sh new file mode 100644 index 0000000..613caa7 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/custom/example.sh @@ -0,0 +1,10 @@ +show_example() { + local index=$1 + local icon="$(get_tmux_option "@catppuccin_test_icon" "󰙨")" + local color="$(get_tmux_option "@catppuccin_test_color" "$thm_blue")" + local text="$(get_tmux_option "@catppuccin_test_text" "It works!")" + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} diff --git a/dot_config/tmux/plugins/tmux/dot_editorconfig b/dot_config/tmux/plugins/tmux/dot_editorconfig new file mode 100644 index 0000000..d86ac02 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_editorconfig @@ -0,0 +1,34 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# EditorConfig is awesome: https://EditorConfig.org + +root = true + +[*] +charset = utf-8 +indent_size = 2 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +# go +[*.go] +indent_style = tab +indent_size = 4 + +# python +[*.{ini,py,py.tpl,rst}] +indent_size = 4 + +# rust +[*.rs] +indent_size = 4 + +# documentation, utils +[*.{md,mdx,diff}] +trim_trailing_whitespace = false + +# windows shell scripts +[*.{cmd,bat,ps1}] +end_of_line = crlf diff --git a/dot_config/tmux/plugins/tmux/dot_git/HEAD b/dot_config/tmux/plugins/tmux/dot_git/HEAD new file mode 100644 index 0000000..b870d82 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/dot_config/tmux/plugins/tmux/dot_git/branches/.keep b/dot_config/tmux/plugins/tmux/dot_git/branches/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tmux/dot_git/config b/dot_config/tmux/plugins/tmux/dot_git/config new file mode 100644 index 0000000..d0c161f --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/config @@ -0,0 +1,13 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/catppuccin/tmux + fetch = +refs/heads/main:refs/remotes/origin/main +[branch "main"] + remote = origin + merge = refs/heads/main diff --git a/dot_config/tmux/plugins/tmux/dot_git/description b/dot_config/tmux/plugins/tmux/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tmux/dot_git/index b/dot_config/tmux/plugins/tmux/dot_git/index new file mode 100644 index 0000000..54d2633 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/dot_git/index differ diff --git a/dot_config/tmux/plugins/tmux/dot_git/info/exclude b/dot_config/tmux/plugins/tmux/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tmux/dot_git/logs/HEAD b/dot_config/tmux/plugins/tmux/dot_git/logs/HEAD new file mode 100644 index 0000000..0e066ab --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 7a284c98e5df4cc84a1a45ad633916f0b2b916b2 Hydroxycarbamide 1693244972 +0200 clone: from https://github.com/catppuccin/tmux diff --git a/dot_config/tmux/plugins/tmux/dot_git/logs/refs/heads/main b/dot_config/tmux/plugins/tmux/dot_git/logs/refs/heads/main new file mode 100644 index 0000000..0e066ab --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/logs/refs/heads/main @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 7a284c98e5df4cc84a1a45ad633916f0b2b916b2 Hydroxycarbamide 1693244972 +0200 clone: from https://github.com/catppuccin/tmux diff --git a/dot_config/tmux/plugins/tmux/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..0e066ab --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 7a284c98e5df4cc84a1a45ad633916f0b2b916b2 Hydroxycarbamide 1693244972 +0200 clone: from https://github.com/catppuccin/tmux diff --git a/dot_config/tmux/plugins/tmux/dot_git/objects/info/.keep b/dot_config/tmux/plugins/tmux/dot_git/objects/info/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.idx b/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.idx new file mode 100644 index 0000000..58e95d7 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.idx differ diff --git a/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.pack b/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.pack new file mode 100644 index 0000000..b3c4dbc Binary files /dev/null and b/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.pack differ diff --git a/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.rev b/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.rev new file mode 100644 index 0000000..4c55226 Binary files /dev/null and b/dot_config/tmux/plugins/tmux/dot_git/objects/pack/readonly_pack-7668bd690c801816a92c0e196d45dd12a8948655.rev differ diff --git a/dot_config/tmux/plugins/tmux/dot_git/packed-refs b/dot_config/tmux/plugins/tmux/dot_git/packed-refs new file mode 100644 index 0000000..af553f4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +7a284c98e5df4cc84a1a45ad633916f0b2b916b2 refs/remotes/origin/main diff --git a/dot_config/tmux/plugins/tmux/dot_git/refs/heads/main b/dot_config/tmux/plugins/tmux/dot_git/refs/heads/main new file mode 100644 index 0000000..7dbf0b9 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/refs/heads/main @@ -0,0 +1 @@ +7a284c98e5df4cc84a1a45ad633916f0b2b916b2 diff --git a/dot_config/tmux/plugins/tmux/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tmux/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..4b0a875 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/main diff --git a/dot_config/tmux/plugins/tmux/dot_git/refs/tags/.keep b/dot_config/tmux/plugins/tmux/dot_git/refs/tags/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tmux/dot_gitignore b/dot_config/tmux/plugins/tmux/dot_gitignore new file mode 100644 index 0000000..0d82d79 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/dot_gitignore @@ -0,0 +1 @@ +custom diff --git a/dot_config/tmux/plugins/tmux/executable_catppuccin.tmux b/dot_config/tmux/plugins/tmux/executable_catppuccin.tmux new file mode 100644 index 0000000..81b38a4 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/executable_catppuccin.tmux @@ -0,0 +1,329 @@ +#!/usr/bin/env bash +PLUGIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +get_tmux_option() { + local option value default + option="$1" + default="$2" + value=$(tmux show-option -gqv "$option") + + if [ -n "$value" ] + then + if [ "$value" = "null" ] + then + echo "" + + else + echo "$value" + fi + + else + echo "$default" + + fi +} + +set() { + local option=$1 + local value=$2 + tmux_commands+=(set-option -gq "$option" "$value" ";") +} + +setw() { + local option=$1 + local value=$2 + tmux_commands+=(set-window-option -gq "$option" "$value" ";") +} + +build_window_icon() { + local window_status_icon_enable=$(get_tmux_option "@catppuccin_window_status_icon_enable" "yes") + + local custom_icon_window_last=$(get_tmux_option "@catppuccin_icon_window_last" "󰖰") + local custom_icon_window_current=$(get_tmux_option "@catppuccin_icon_window_current" "󰖯") + local custom_icon_window_zoom=$(get_tmux_option "@catppuccin_icon_window_zoom" "󰁌") + local custom_icon_window_mark=$(get_tmux_option "@catppuccin_icon_window_mark" "󰃀") + local custom_icon_window_silent=$(get_tmux_option "@catppuccin_icon_window_silent" "󰂛") + local custom_icon_window_activity=$(get_tmux_option "@catppuccin_icon_window_activity" "󰖲") + local custom_icon_window_bell=$(get_tmux_option "@catppuccin_icon_window_bell" "󰂞") + + if [ "$window_status_icon_enable" = "yes" ] + then + # #!~[*-]MZ + local show_window_status="#{?window_activity_flag,${custom_icon_window_activity},}#{?window_bell_flag,${custom_icon_window_bell},}#{?window_silence_flag,${custom_icon_window_silent},}#{?window_active,${custom_icon_window_current},}#{?window_last_flag,${custom_icon_window_last},}#{?window_marked_flag,${custom_icon_window_mark},}#{?window_zoomed_flag,${custom_icon_window_zoom},}" + fi + + if [ "$window_status_icon_enable" = "no" ] + then + local show_window_status="#F" + fi + + echo "$show_window_status" +} + +build_window_format() { + local number=$1 + local color=$2 + local background=$3 + local text=$4 + local fill=$5 + + if [ "$window_status_enable" = "yes" ] + then + local icon="$( build_window_icon )" + text="$text $icon" + fi + + if [ "$fill" = "none" ] + then + local show_left_separator="#[fg=$thm_gray,bg=$thm_bg,nobold,nounderscore,noitalics]$window_left_separator" + local show_number="#[fg=$thm_fg,bg=$thm_gray]$number" + local show_middle_separator="#[fg=$thm_fg,bg=$thm_gray,nobold,nounderscore,noitalics]$window_middle_separator" + local show_text="#[fg=$thm_fg,bg=$thm_gray]$text" + local show_right_separator="#[fg=$thm_gray,bg=$thm_bg]$window_right_separator" + + fi + + if [ "$fill" = "all" ] + then + local show_left_separator="#[fg=$color,bg=$thm_bg,nobold,nounderscore,noitalics]$window_left_separator" + local show_number="#[fg=$background,bg=$color]$number" + local show_middle_separator="#[fg=$background,bg=$color,nobold,nounderscore,noitalics]$window_middle_separator" + local show_text="#[fg=$background,bg=$color]$text" + local show_right_separator="#[fg=$color,bg=$thm_bg]$window_right_separator" + + fi + + if [ "$fill" = "number" ] + then + local show_number="#[fg=$background,bg=$color]$number" + local show_middle_separator="#[fg=$color,bg=$background,nobold,nounderscore,noitalics]$window_middle_separator" + local show_text="#[fg=$thm_fg,bg=$background]$text" + + if [ "$window_number_position" = "right" ] + then + local show_left_separator="#[fg=$background,bg=$thm_bg,nobold,nounderscore,noitalics]$window_left_separator" + local show_right_separator="#[fg=$color,bg=$thm_bg]$window_right_separator" + fi + + if [ "$window_number_position" = "left" ] + then + local show_right_separator="#[fg=$background,bg=$thm_bg,nobold,nounderscore,noitalics]$window_right_separator" + local show_left_separator="#[fg=$color,bg=$thm_bg]$window_left_separator" + fi + + fi + + local final_window_format + + if [ "$window_number_position" = "right" ] + then + final_window_format="$show_left_separator$show_text$show_middle_separator$show_number$show_right_separator" + fi + + if [ "$window_number_position" = "left" ] + then + final_window_format="$show_left_separator$show_number$show_middle_separator$show_text$show_right_separator" + fi + + echo "$final_window_format" +} + +build_status_module() { + local index=$1 + local icon=$2 + local color=$3 + local text=$4 + + if [ "$status_fill" = "icon" ] + then + local show_left_separator="#[fg=$color,bg=$thm_gray,nobold,nounderscore,noitalics]$status_left_separator" + + local show_icon="#[fg=$thm_bg,bg=$color,nobold,nounderscore,noitalics]$icon " + local show_text="#[fg=$thm_fg,bg=$thm_gray] $text" + + local show_right_separator="#[fg=$thm_gray,bg=$thm_bg,nobold,nounderscore,noitalics]$status_right_separator" + + if [ "$status_connect_separator" = "yes" ] + then + local show_left_separator="#[fg=$color,bg=$thm_gray,nobold,nounderscore,noitalics]$status_left_separator" + local show_right_separator="#[fg=$thm_gray,bg=$thm_gray,nobold,nounderscore,noitalics]$status_right_separator" + + else + local show_left_separator="#[fg=$color,bg=$thm_bg,nobold,nounderscore,noitalics]$status_left_separator" + local show_right_separator="#[fg=$thm_gray,bg=$thm_bg,nobold,nounderscore,noitalics]$status_right_separator" + fi + + fi + + if [ "$status_fill" = "all" ] + then + local show_left_separator="#[fg=$color,bg=$thm_gray,nobold,nounderscore,noitalics]$status_left_separator" + + local show_icon="#[fg=$thm_bg,bg=$color,nobold,nounderscore,noitalics]$icon " + local show_text="#[fg=$thm_bg,bg=$color]$text" + + local show_right_separator="#[fg=$color,bg=$thm_gray,nobold,nounderscore,noitalics]$status_right_separator" + + if [ "$status_connect_separator" = "yes" ] + then + local show_left_separator="#[fg=$color,nobold,nounderscore,noitalics]$status_left_separator" + local show_right_separator="#[fg=$color,bg=$color,nobold,nounderscore,noitalics]$status_right_separator" + + else + local show_left_separator="#[fg=$color,bg=$thm_bg,nobold,nounderscore,noitalics]$status_left_separator" + local show_right_separator="#[fg=$color,bg=$thm_bg,nobold,nounderscore,noitalics]$status_right_separator" + fi + + fi + + if [ "$status_right_separator_inverse" = "yes" ] + then + if [ "$status_connect_separator" = "yes" ] + then + local show_right_separator="#[fg=$thm_gray,bg=$color,nobold,nounderscore,noitalics]$status_right_separator" + else + local show_right_separator="#[fg=$thm_bg,bg=$color,nobold,nounderscore,noitalics]$status_right_separator" + fi + fi + + if [ $(($index)) -eq 0 ] + then + local show_left_separator="#[fg=$color,bg=$thm_bg,nobold,nounderscore,noitalics]$status_left_separator" + fi + + echo "$show_left_separator$show_icon$show_text$show_right_separator" +} + +load_modules() { + local modules_list=$1 + + local modules_custom_path=$PLUGIN_DIR/custom + local modules_status_path=$PLUGIN_DIR/status + local modules_window_path=$PLUGIN_DIR/window + + local module_index=0; + local module_name + local loaded_modules + local IN=$modules_list + + # https://stackoverflow.com/questions/918886/how-do-i-split-a-string-on-a-delimiter-in-bash#15988793 + while [ "$IN" != "$iter" ] ;do + # extract the substring from start of string up to delimiter. + iter=${IN%% *} + # delete this first "element" AND next separator, from $IN. + IN="${IN#$iter }" + # Print (or doing anything with) the first "element". + + module_name=$iter + + local module_path=$modules_custom_path/$module_name.sh + source $module_path + + if [ 0 -eq $? ] + then + loaded_modules="$loaded_modules$( show_$module_name $module_index )" + module_index=$module_index+1 + continue + fi + + local module_path=$modules_status_path/$module_name.sh + source $module_path + + if [ 0 -eq $? ] + then + loaded_modules="$loaded_modules$( show_$module_name $module_index )" + module_index=$module_index+1 + continue + fi + + local module_path=$modules_window_path/$module_name.sh + source $module_path + + if [ 0 -eq $? ] + then + loaded_modules="$loaded_modules$( show_$module_name $module_index )" + module_index=$module_index+1 + continue + fi + + done + + echo "$loaded_modules" +} + +main() { + local theme + theme="$(get_tmux_option "@catppuccin_flavour" "mocha")" + + # Aggregate all commands in one array + local tmux_commands=() + + # NOTE: Pulling in the selected theme by the theme that's being set as local + # variables. + # shellcheck source=catppuccin-frappe.tmuxtheme + # https://github.com/dylanaraps/pure-sh-bible#parsing-a-keyval-file + while IFS='=' read -r key val; do + # Skip over lines containing comments. + # (Lines starting with '#'). + [ "${key##\#*}" ] || continue + + # '$key' stores the key. + # '$val' stores the value. + eval "local $key"="$val" + done < "${PLUGIN_DIR}/catppuccin-${theme}.tmuxtheme" + + # status + set status "on" + set status-bg "${thm_bg}" + set status-justify "left" + set status-left-length "100" + set status-right-length "100" + + # messages + set message-style "fg=${thm_cyan},bg=${thm_gray},align=centre" + set message-command-style "fg=${thm_cyan},bg=${thm_gray},align=centre" + + # panes + set pane-border-style "fg=${thm_gray}" + set pane-active-border-style "fg=${thm_blue}" + + # windows + setw window-status-activity-style "fg=${thm_fg},bg=${thm_bg},none" + setw window-status-separator "" + setw window-status-style "fg=${thm_fg},bg=${thm_bg},none" + + # --------=== Statusline + + local window_left_separator=$(get_tmux_option "@catppuccin_window_left_separator" "█") + local window_right_separator=$(get_tmux_option "@catppuccin_window_right_separator" "█") + local window_middle_separator=$(get_tmux_option "@catppuccin_window_middle_separator" "█ ") + local window_number_position=$(get_tmux_option "@catppuccin_window_number_position" "left") # right, left + local window_status_enable=$(get_tmux_option "@catppuccin_window_status_enable" "no") # right, left + + local window_format=$( load_modules "window_default_format") + local window_current_format=$( load_modules "window_current_format") + + setw window-status-format "$window_format" + setw window-status-current-format "$window_current_format" + + local status_left_separator=$(get_tmux_option "@catppuccin_status_left_separator" "") + local status_right_separator=$(get_tmux_option "@catppuccin_status_right_separator" "█") + local status_right_separator_inverse=$(get_tmux_option "@catppuccin_status_right_separator_inverse" "no") + local status_connect_separator=$(get_tmux_option "@catppuccin_status_connect_separator" "yes") + local status_fill=$(get_tmux_option "@catppuccin_status_fill" "icon") + + local status_modules=$(get_tmux_option "@catppuccin_status_modules" "application session") + local loaded_modules=$( load_modules "$status_modules") + + set status-left "" + set status-right "$loaded_modules" + + # --------=== Modes + # + setw clock-mode-colour "${thm_blue}" + setw mode-style "fg=${thm_pink} bg=${thm_black4} bold" + + tmux "${tmux_commands[@]}" +} + +main "$@" diff --git a/dot_config/tmux/plugins/tmux/status/application.sh b/dot_config/tmux/plugins/tmux/status/application.sh new file mode 100644 index 0000000..56f2e76 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/status/application.sh @@ -0,0 +1,10 @@ +show_application() { + local index=$1 + local icon=$(get_tmux_option "@catppuccin_application_icon" "") + local color=$(get_tmux_option "@catppuccin_application_color" "$thm_pink") + local text=$(get_tmux_option "@catppuccin_application_text" "#W") + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} diff --git a/dot_config/tmux/plugins/tmux/status/battery.sh b/dot_config/tmux/plugins/tmux/status/battery.sh new file mode 100644 index 0000000..7ad978f --- /dev/null +++ b/dot_config/tmux/plugins/tmux/status/battery.sh @@ -0,0 +1,23 @@ +show_battery() { + tmux set-option -g @batt_icon_charge_tier8 '󰁹' + tmux set-option -g @batt_icon_charge_tier7 '󰂁' + tmux set-option -g @batt_icon_charge_tier6 '󰁿' + tmux set-option -g @batt_icon_charge_tier5 '󰁾' + tmux set-option -g @batt_icon_charge_tier4 '󰁽' + tmux set-option -g @batt_icon_charge_tier3 '󰁼' + tmux set-option -g @batt_icon_charge_tier2 '󰁻' + tmux set-option -g @batt_icon_charge_tier1 '󰁺' + tmux set-option -g @batt_icon_status_charged '󰚥' + tmux set-option -g @batt_icon_status_charging '󰂄' + tmux set-option -g @batt_icon_status_discharging '󰂃' + tmux set-option -g @batt_icon_status_unknown '󰂑' + + local index=$1 + local icon=$(get_tmux_option "@catppuccin_battery_icon" "#{battery_icon}") + local color=$(get_tmux_option "@catppuccin_battery_color" "$thm_yellow") + local text=$(get_tmux_option "@catppuccin_battery_text" "#{battery_percentage}") + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} diff --git a/dot_config/tmux/plugins/tmux/status/date_time.sh b/dot_config/tmux/plugins/tmux/status/date_time.sh new file mode 100644 index 0000000..9f7030e --- /dev/null +++ b/dot_config/tmux/plugins/tmux/status/date_time.sh @@ -0,0 +1,11 @@ +show_date_time() { + local index=$1 + local icon="$(get_tmux_option "@catppuccin_date_time_icon" "󰃰")" + local color="$(get_tmux_option "@catppuccin_date_time_color" "$thm_blue")" + local text="$(get_tmux_option "@catppuccin_date_time_text" "%Y-%m-%d %H:%M")" + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} + diff --git a/dot_config/tmux/plugins/tmux/status/directory.sh b/dot_config/tmux/plugins/tmux/status/directory.sh new file mode 100644 index 0000000..1ff293d --- /dev/null +++ b/dot_config/tmux/plugins/tmux/status/directory.sh @@ -0,0 +1,10 @@ +show_directory() { + local index=$1 + local icon=$(get_tmux_option "@catppuccin_directory_icon" "") + local color=$(get_tmux_option "@catppuccin_directory_color" "$thm_pink") + local text=$(get_tmux_option "@catppuccin_directory_text" "#{b:pane_current_path}") + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} diff --git a/dot_config/tmux/plugins/tmux/status/host.sh b/dot_config/tmux/plugins/tmux/status/host.sh new file mode 100644 index 0000000..5abd71e --- /dev/null +++ b/dot_config/tmux/plugins/tmux/status/host.sh @@ -0,0 +1,10 @@ +show_host() { + local index=$1 + local icon=$(get_tmux_option "@catppuccin_host_icon" "󰒋") + local color=$(get_tmux_option "@catppuccin_host_color" "$thm_magenta") + local text=$(get_tmux_option "@catppuccin_host_text" "#H") + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} diff --git a/dot_config/tmux/plugins/tmux/status/session.sh b/dot_config/tmux/plugins/tmux/status/session.sh new file mode 100644 index 0000000..58d6c90 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/status/session.sh @@ -0,0 +1,10 @@ +show_session() { + local index=$1 + local icon=$(get_tmux_option "@catppuccin_session_icon" "") + local color=$(get_tmux_option "@catppuccin_session_color" "#{?client_prefix,$thm_red,$thm_green}") + local text=$(get_tmux_option "@catppuccin_session_text" "#S") + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} diff --git a/dot_config/tmux/plugins/tmux/status/user.sh b/dot_config/tmux/plugins/tmux/status/user.sh new file mode 100644 index 0000000..1d4d03e --- /dev/null +++ b/dot_config/tmux/plugins/tmux/status/user.sh @@ -0,0 +1,10 @@ +show_user() { + local index=$1 + local icon=$(get_tmux_option "@catppuccin_user_icon" "") + local color=$(get_tmux_option "@catppuccin_user_color" "$thm_cyan") + local text=$(get_tmux_option "@catppuccin_user_text" "#(whoami)") + + local module=$( build_status_module "$index" "$icon" "$color" "$text" ) + + echo "$module" +} diff --git a/dot_config/tmux/plugins/tmux/window/window_current_format.sh b/dot_config/tmux/plugins/tmux/window/window_current_format.sh new file mode 100644 index 0000000..88e9053 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/window/window_current_format.sh @@ -0,0 +1,11 @@ +show_window_current_format() { + local number="#I" + local color="$thm_orange" + local background="$thm_bg" + local text="$(get_tmux_option "@catppuccin_window_current_text" "#{b:pane_current_path}")" # use #W for application instead of directory + local fill="$(get_tmux_option "@catppuccin_window_current_fill" "number")" # number, all, none + + local current_window_format=$( build_window_format "$number" "$color" "$background" "$text" "$fill" ) + + echo "$current_window_format" +} diff --git a/dot_config/tmux/plugins/tmux/window/window_default_format.sh b/dot_config/tmux/plugins/tmux/window/window_default_format.sh new file mode 100644 index 0000000..1f5f016 --- /dev/null +++ b/dot_config/tmux/plugins/tmux/window/window_default_format.sh @@ -0,0 +1,11 @@ +show_window_default_format() { + local number="#I" + local color="$thm_blue" + local background="$thm_gray" + local text="$(get_tmux_option "@catppuccin_window_default_text" "#{b:pane_current_path}")" # use #W for application instead of directory + local fill="$(get_tmux_option "@catppuccin_window_default_fill" "number")" # number, all, none + + local default_window_format=$( build_window_format "$number" "$color" "$background" "$text" "$fill" ) + + echo "$default_window_format" +} diff --git a/dot_config/tmux/plugins/tpm/CHANGELOG.md b/dot_config/tmux/plugins/tpm/CHANGELOG.md new file mode 100644 index 0000000..a9ce81e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/CHANGELOG.md @@ -0,0 +1,86 @@ +# Changelog + +### master + +### v3.1.0, 2023-01-03 +- 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` +- More stuff, check `git log`. + +### v3.0.0, 2015-08-03 +- refactor `shared_set_tpm_path_constant` function +- move all instructions to `docs/` dir +- add `bin/install_plugins` cli executable script +- improved test runner function +- switch to using [tmux-test](https://github.com/tmux-plugins/tmux-test) + framework +- add `bin/update_plugins` cli executable script +- refactor test `expect` scripts, make them simpler and ensure they properly + assert expectations +- refactor code that sets 'TMUX_PLUGIN_MANAGER_PATH' global env var +- stop using global variable for 'tpm path' +- support defining plugins via `set -g @plugin` in sourced files as well + +### v2.0.0, 2015-07-07 +- 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 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 +- ensure old/deprecated plugin syntax `set -g @tpm_plugins` works alongside new + `set -g @plugin` syntax + +### v1.2.2, 2015-02-08 +- set GIT_TERMINAL_PROMPT=0 when doing `git clone`, `pull` or `submodule update` + to ensure git does not prompt for username/password in any case + +### v1.2.1, 2014-11-21 +- change the way plugin name is expanded. It now uses the http username + and password by default, like this: `https://git::@github.com/`. This prevents + username and password prompt (and subsequently tmux install hanging) with old + git versions. Fixes #7. + +### v1.2.0, 2014-11-20 +- refactor tests so they can be used on travis +- add travis.yml, add travis badge to the readme + +### v1.1.0, 2014-11-19 +- if the plugin is not downloaded do not source it +- remove `PLUGINS.md`, an obsolete list of plugins +- update readme with instructions about uninstalling plugins +- tilde char and `$HOME` in `TMUX_SHARED_MANAGER_PATH` couldn't be used because + they are just plain strings. Fixing the problem by manually expanding them. +- bugfix: fragile `*.tmux` file globbing (@majutsushi) + +### v1.0.0, 2014-08-05 +- update readme because of github organization change to + [tmux-plugins](https://github.com/tmux-plugins) +- update tests to pass +- update README to suggest different first plugin +- update list of plugins in the README +- remove README 'about' section +- move key binding to the main file. Delete `key_binding.sh`. +- rename `display_message` -> `echo_message` +- installing plugins installs just new plugins. Already installed plugins aren't + updated. +- add 'update plugin' binding and functionality +- add test for updating a plugin + +### v0.0.2, 2014-07-17 +- run all *.tmux plugin files as executables +- fix all redirects to /dev/null +- fix bug: TPM shared path is created before sync (cloning plugins from github + is done) +- add test suite running in Vagrant +- add Tmux version check. `TPM` won't run if Tmux version is less than 1.9. + +### v0.0.1, 2014-05-21 +- get TPM up and running diff --git a/dot_config/tmux/plugins/tpm/HOW_TO_PLUGIN.md b/dot_config/tmux/plugins/tpm/HOW_TO_PLUGIN.md new file mode 100644 index 0000000..9901619 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/HOW_TO_PLUGIN.md @@ -0,0 +1,2 @@ +Instructions moved to +[docs/how_to_create_plugin.md](docs/how_to_create_plugin.md). diff --git a/dot_config/tmux/plugins/tpm/LICENSE.md b/dot_config/tmux/plugins/tpm/LICENSE.md new file mode 100644 index 0000000..1222865 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/LICENSE.md @@ -0,0 +1,20 @@ +MIT license +Copyright (C) 2014 Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dot_config/tmux/plugins/tpm/README.md b/dot_config/tmux/plugins/tpm/README.md new file mode 100644 index 0000000..2371863 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/README.md @@ -0,0 +1,101 @@ +# Tmux Plugin Manager + +[![Build Status](https://travis-ci.org/tmux-plugins/tpm.svg?branch=master)](https://travis-ci.org/tmux-plugins/tpm) + +Installs and loads `tmux` plugins. + +Tested and working on Linux, OSX, and Cygwin. + +See list of plugins [here](https://github.com/tmux-plugins/list). + +### Installation + +Requirements: `tmux` version 1.9 (or higher), `git`, `bash`. + +Clone TPM: + +```bash +git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm +``` + +Put this at the bottom of `~/.tmux.conf` (`$XDG_CONFIG_HOME/tmux/tmux.conf` +works too): + +```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 'github_username/plugin_name#branch' +# 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' +``` + +Reload TMUX environment so TPM is sourced: + +```bash +# type this in terminal if tmux is already running +tmux source ~/.tmux.conf +``` + +That's it! + +### Installing plugins + +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. 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 repository +- Refreshes TMUX environment + +`prefix` + U +- updates plugin(s) + +`prefix` + alt + u +- remove/uninstall plugins not on the plugin list + +### Docs + +- [Help, tpm not working](docs/tpm_not_working.md) - problem solutions + +More advanced features and instructions, regular users probably do not need +this: + +- [How to create a plugin](docs/how_to_create_plugin.md). It's easy. +- [Managing plugins via the command line](docs/managing_plugins_via_cmd_line.md) +- [Changing plugins install dir](docs/changing_plugins_install_dir.md) +- [Automatic TPM installation on a new machine](docs/automatic_tpm_installation.md) + +### Tests + +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: + +```bash +# within project directory +./run_tests +``` + +### License + +[MIT](LICENSE.md) diff --git a/dot_config/tmux/plugins/tpm/bin/executable_clean_plugins b/dot_config/tmux/plugins/tpm/bin/executable_clean_plugins new file mode 100644 index 0000000..12f8730 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bin/executable_clean_plugins @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" + +main() { + "$SCRIPTS_DIR/clean_plugins.sh" # has correct exit code +} +main diff --git a/dot_config/tmux/plugins/tpm/bin/executable_install_plugins b/dot_config/tmux/plugins/tpm/bin/executable_install_plugins new file mode 100644 index 0000000..c66b15b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bin/executable_install_plugins @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" + +main() { + "$SCRIPTS_DIR/install_plugins.sh" # has correct exit code +} +main diff --git a/dot_config/tmux/plugins/tpm/bin/executable_update_plugins b/dot_config/tmux/plugins/tpm/bin/executable_update_plugins new file mode 100644 index 0000000..30a5646 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bin/executable_update_plugins @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +# Script intended for use via the command line. +# +# `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, +# but does not need to be started in order to run this script. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +PROGRAM_NAME="$0" + +if [ $# -eq 0 ]; then + echo "usage:" + echo " $PROGRAM_NAME all update all plugins" + echo " $PROGRAM_NAME tmux-foo update plugin 'tmux-foo'" + echo " $PROGRAM_NAME tmux-bar tmux-baz update multiple plugins" + exit 1 +fi + +main() { + "$SCRIPTS_DIR/update_plugin.sh" --shell-echo "$*" # has correct exit code +} +main "$*" + diff --git a/dot_config/tmux/plugins/tpm/bindings/executable_clean_plugins b/dot_config/tmux/plugins/tpm/bindings/executable_clean_plugins new file mode 100644 index 0000000..9a0d5d7 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bindings/executable_clean_plugins @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + reload_tmux_environment + "$SCRIPTS_DIR/clean_plugins.sh" --tmux-echo >/dev/null 2>&1 + reload_tmux_environment + end_message +} +main diff --git a/dot_config/tmux/plugins/tpm/bindings/executable_install_plugins b/dot_config/tmux/plugins/tpm/bindings/executable_install_plugins new file mode 100644 index 0000000..3ade3c4 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bindings/executable_install_plugins @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + reload_tmux_environment + "$SCRIPTS_DIR/install_plugins.sh" --tmux-echo >/dev/null 2>&1 + reload_tmux_environment + end_message +} +main diff --git a/dot_config/tmux/plugins/tpm/bindings/executable_update_plugins b/dot_config/tmux/plugins/tpm/bindings/executable_update_plugins new file mode 100644 index 0000000..28cc281 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/bindings/executable_update_plugins @@ -0,0 +1,49 @@ +#!/usr/bin/env bash + +# Tmux key-binding script. +# Scripts intended to be used via the command line are in `bin/` directory. + +# This script: +# - shows a list of installed plugins +# - starts a prompt to enter the name of the plugin that will be updated + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +SCRIPTS_DIR="$CURRENT_DIR/../scripts" +HELPERS_DIR="$SCRIPTS_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +display_plugin_update_list() { + local plugins="$(tpm_plugins_list_helper)" + tmux_echo "Installed plugins:" + tmux_echo "" + + for plugin in $plugins; do + # displaying only installed plugins + if plugin_already_installed "$plugin"; then + local plugin_name="$(plugin_name_helper "$plugin")" + tmux_echo " $plugin_name" + fi + done + + tmux_echo "" + tmux_echo "Type plugin name to update it." + tmux_echo "" + tmux_echo "- \"all\" - updates all plugins" + tmux_echo "- ENTER - cancels" +} + +update_plugin_prompt() { + tmux command-prompt -p 'plugin update:' " \ + send-keys C-c; \ + run-shell '$SCRIPTS_DIR/update_plugin_prompt_handler.sh %1'" +} + +main() { + reload_tmux_environment + display_plugin_update_list + update_plugin_prompt +} +main diff --git a/dot_config/tmux/plugins/tpm/docs/automatic_tpm_installation.md b/dot_config/tmux/plugins/tpm/docs/automatic_tpm_installation.md new file mode 100644 index 0000000..630573f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/automatic_tpm_installation.md @@ -0,0 +1,12 @@ +# Automatic tpm installation + +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 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 && ~/.tmux/plugins/tpm/bin/install_plugins'" +``` + +This useful tip was submitted by @acr4 and narfman0. diff --git a/dot_config/tmux/plugins/tpm/docs/changing_plugins_install_dir.md b/dot_config/tmux/plugins/tpm/docs/changing_plugins_install_dir.md new file mode 100644 index 0000000..27de96d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/changing_plugins_install_dir.md @@ -0,0 +1,16 @@ +# Changing plugins install dir + +By default, TPM installs plugins in a subfolder named `plugins/` inside +`$XDG_CONFIG_HOME/tmux/` if a `tmux.conf` file was found at that location, or +inside `~/.tmux/` otherwise. + +You can change the install path by putting this in `.tmux.conf`: + + set-environment -g TMUX_PLUGIN_MANAGER_PATH '/some/other/path/' + +Tmux plugin manager initialization in `.tmux.conf` should also be updated: + + # initializes TMUX plugin manager in a new path + run /some/other/path/tpm/tpm + +Please make sure that the `run` line is at the very bottom of `.tmux.conf`. diff --git a/dot_config/tmux/plugins/tpm/docs/how_to_create_plugin.md b/dot_config/tmux/plugins/tpm/docs/how_to_create_plugin.md new file mode 100644 index 0000000..f7d9c13 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/how_to_create_plugin.md @@ -0,0 +1,108 @@ +# How to create Tmux plugins + +Creating a new plugin is easy. + +For demonstration purposes we'll create a simple plugin that lists all +installed TPM plugins. Yes, a plugin that lists plugins :) We'll bind that to +`prefix + T`. + +The source code for this example plugin can be found +[here](https://github.com/tmux-plugins/tmux-example-plugin). + +### 1. create a new git project + +TPM depends on git for downloading and updating plugins. + +To create a new git project: + + $ mkdir tmux_my_plugin + $ cd tmux_my_plugin + $ git init + +### 2. create a `*.tmux` plugin run file + +When it sources a plugin, TPM executes all `*.tmux` files in your plugins' +directory. That's how plugins are run. + +Create a plugin run file in plugin directory: + + $ touch 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. + +### 3. create a plugin key binding + +We want the behavior of the plugin to trigger when a user hits `prefix + T`. + +Key `T` is chosen because: + - it's "kind of" a mnemonic for `TPM` + - the key is not used by Tmux natively. Tmux man page, KEY BINDINGS section + contains a list of all the bindings Tmux uses. There's plenty of unused keys + and we don't want to override any of Tmux default key bindings. + +Open the plugin run file in your favorite text editor: + + $ vim my_plugin.tmux + # or + $ subl my_plugin.tmux + +Put the following content in the file: + + #!/usr/bin/env bash + + CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + tmux bind-key T run-shell "$CURRENT_DIR/scripts/tmux_list_plugins.sh" + +As you can see, plugin run file is a simple bash script that sets up the binding. + +When pressed, `prefix + T` will execute another shell script: +`tmux_list_plugins.sh`. That script should be in `scripts/` directory - +relative to the plugin run file. + + +### 4. listing plugins + +Now that we have the binding, let's create a script that's invoked with +`prefix + T`. + + $ mkdir scripts + $ touch scripts/tmux_list_plugins.sh + $ chmod u+x scripts/tmux_list_plugins.sh + +And here's the script content: + + #!/usr/bin/env bash + + # fetching the directory where plugins are installed + plugin_path="$(tmux show-env -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" + + # listing installed plugins + ls -1 "$plugin_path" + +### 5. try it out + +To see if this works, execute the plugin run file: + + $ ./my_plugin.tmux + +That should set up the key binding. Now hit `prefix + T` and see if it works. + +### 6. publish the plugin + +When everything is ready, push the plugin to an online git repository, +preferably GitHub. + +Other users can install your plugin by just adding plugin git URL to the +`@plugin` list in their `.tmux.conf`. + +If the plugin is on GitHub, your users will be able to use the shorthand of +`github_username/repository`. + +### Conclusion + +Hopefully, that was easy. As you can see, it's mostly shell scripting. + +You can use other scripting languages (ruby, python etc) but plain old shell +is preferred because of portability. diff --git a/dot_config/tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md b/dot_config/tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md new file mode 100644 index 0000000..7aefd7d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md @@ -0,0 +1,36 @@ +# Managing plugins via the command line + +Aside from tmux key bindings, TPM provides shell interface for managing plugins +via scripts located in [bin/](../bin/) directory. + +Tmux does not need to be started in order to run scripts (but it's okay if it +is). If you [changed tpm install dir](../docs/changing_plugins_install_dir.md) +in `.tmux.conf` that should work fine too. + +Prerequisites: + +- tmux installed on the system (doh) +- `.tmux.conf` set up for TPM + +### Installing plugins + +As usual, plugins need to be specified in `.tmux.conf`. Run the following +command to install plugins: + + ~/.tmux/plugins/tpm/bin/install_plugins + +### Updating plugins + +To update all installed plugins: + + ~/.tmux/plugins/tpm/bin/update_plugins all + +or update a single plugin: + + ~/.tmux/plugins/tpm/bin/update_plugins tmux-sensible + +### Removing plugins + +To remove plugins not on the plugin list: + + ~/.tmux/plugins/tpm/bin/clean_plugins diff --git a/dot_config/tmux/plugins/tpm/docs/tpm_not_working.md b/dot_config/tmux/plugins/tpm/docs/tpm_not_working.md new file mode 100644 index 0000000..6680291 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/docs/tpm_not_working.md @@ -0,0 +1,102 @@ +# 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 a brew prefix (e.g. `/usr/local/bin`) will not be found. + +The solution is to find your brew prefix + +```sh +> echo "$(brew --prefix)/bin" +/opt/homebrew/bin +``` + +And prepend it to the `PATH` environment variable +``` +set-environment -g PATH "/opt/homebrew/bin:/bin:/usr/bin" +``` + +before any `run-shell`/`run` commands in `~/.tmux.conf`. diff --git a/dot_config/tmux/plugins/tpm/dot_git/HEAD b/dot_config/tmux/plugins/tpm/dot_git/HEAD new file mode 100644 index 0000000..cb089cd --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/branches/.keep b/dot_config/tmux/plugins/tpm/dot_git/branches/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tpm/dot_git/config b/dot_config/tmux/plugins/tpm/dot_git/config new file mode 100644 index 0000000..ea5d8f7 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/config @@ -0,0 +1,15 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true +[submodule] + active = . +[remote "origin"] + url = https://git::@github.com/tmux-plugins/tpm + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master +[submodule "lib/tmux-test"] + url = https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_git/description b/dot_config/tmux/plugins/tpm/dot_git/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_update.sample b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/index b/dot_config/tmux/plugins/tpm/dot_git/index new file mode 100644 index 0000000..c6154b0 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/index differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/info/exclude b/dot_config/tmux/plugins/tpm/dot_git/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tpm/dot_git/logs/HEAD b/dot_config/tmux/plugins/tpm/dot_git/logs/HEAD new file mode 100644 index 0000000..ad45a16 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/logs/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 99469c4a9b1ccf77fade25842dc7bafbc8ce9946 Hydroxycarbamide 1693244974 +0200 clone: from https://github.com/tmux-plugins/tpm diff --git a/dot_config/tmux/plugins/tpm/dot_git/logs/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/heads/master new file mode 100644 index 0000000..ad45a16 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 99469c4a9b1ccf77fade25842dc7bafbc8ce9946 Hydroxycarbamide 1693244974 +0200 clone: from https://github.com/tmux-plugins/tpm diff --git a/dot_config/tmux/plugins/tpm/dot_git/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..ad45a16 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 99469c4a9b1ccf77fade25842dc7bafbc8ce9946 Hydroxycarbamide 1693244974 +0200 clone: from https://github.com/tmux-plugins/tpm diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/HEAD new file mode 100644 index 0000000..b36919d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/HEAD @@ -0,0 +1 @@ +33fa65fbfb72ba6dd106c21bf5ee6cc353ecdbb6 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/branches/.keep b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/branches/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/config b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/config new file mode 100644 index 0000000..a228840 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/config @@ -0,0 +1,12 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = false + logallrefupdates = true + worktree = ../../../../lib/tmux-test +[remote "origin"] + url = https://github.com/tmux-plugins/tmux-test.git + fetch = +refs/heads/master:refs/remotes/origin/master +[branch "master"] + remote = origin + merge = refs/heads/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/description b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_applypatch-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_applypatch-msg.sample new file mode 100644 index 0000000..a5d7b84 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_commit-msg.sample new file mode 100644 index 0000000..b58d118 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_fsmonitor-watchman.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_fsmonitor-watchman.sample new file mode 100644 index 0000000..23e856f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_post-update.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_post-update.sample new file mode 100644 index 0000000..ec17ec1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-applypatch.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-applypatch.sample new file mode 100644 index 0000000..4142082 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-commit.sample new file mode 100644 index 0000000..e144712 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-merge-commit.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-merge-commit.sample new file mode 100644 index 0000000..399eab1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-push.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-push.sample new file mode 100644 index 0000000..4ce688d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-rebase.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-rebase.sample new file mode 100644 index 0000000..6cbef5c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-receive.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-receive.sample new file mode 100644 index 0000000..a1fd29e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_prepare-commit-msg.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_prepare-commit-msg.sample new file mode 100644 index 0000000..10fa14c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_push-to-checkout.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_push-to-checkout.sample new file mode 100644 index 0000000..af5a0c0 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_update.sample b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_update.sample new file mode 100644 index 0000000..c4d426b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/hooks/executable_update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/index b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/index new file mode 100644 index 0000000..e9df080 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/index differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/info/exclude b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/HEAD new file mode 100644 index 0000000..aaf3a75 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/HEAD @@ -0,0 +1,2 @@ +0000000000000000000000000000000000000000 cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 Hydroxycarbamide 1693244975 +0200 clone: from https://github.com/tmux-plugins/tmux-test.git +cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 33fa65fbfb72ba6dd106c21bf5ee6cc353ecdbb6 Hydroxycarbamide 1693244975 +0200 checkout: moving from master to 33fa65fbfb72ba6dd106c21bf5ee6cc353ecdbb6 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/heads/master new file mode 100644 index 0000000..3a47960 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/heads/master @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 Hydroxycarbamide 1693244975 +0200 clone: from https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/remotes/origin/HEAD new file mode 100644 index 0000000..3a47960 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/logs/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +0000000000000000000000000000000000000000 cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 Hydroxycarbamide 1693244975 +0200 clone: from https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/info/.keep b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/info/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.idx b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.idx new file mode 100644 index 0000000..dc77dab Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.idx differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.pack b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.pack new file mode 100644 index 0000000..3d0f6c1 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.pack differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.rev b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.rev new file mode 100644 index 0000000..3b016b7 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/objects/pack/readonly_pack-682baae89da52dce28f4e38633aaa4c7d2ae0037.rev differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/packed-refs b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/packed-refs new file mode 100644 index 0000000..c115c69 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/heads/master new file mode 100644 index 0000000..4a94ccf --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/heads/master @@ -0,0 +1 @@ +cdcc3222ad1faf3370d47c04bc3ee07842f9e7e6 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.0.1 b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.0.1 new file mode 100644 index 0000000..6e54b81 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.0.1 @@ -0,0 +1 @@ +53f50f99968c5d111dd8b1c9c2d220d818bc5b75 diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.1.0 b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.1.0 new file mode 100644 index 0000000..bb34893 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.1.0 @@ -0,0 +1 @@ +0ea93e8287d81626e21a7c5d7a04bc60fb83034e diff --git a/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.2.0 b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.2.0 new file mode 100644 index 0000000..b8cf1e2 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/modules/lib/tmux-test/refs/tags/v0.2.0 @@ -0,0 +1 @@ +f9e3edd4d3855b76f676c885349e598c1b71d471 diff --git a/dot_config/tmux/plugins/tpm/dot_git/objects/info/.keep b/dot_config/tmux/plugins/tpm/dot_git/objects/info/.keep new file mode 100644 index 0000000..e69de29 diff --git a/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.idx b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.idx new file mode 100644 index 0000000..5791428 Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.idx differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.pack b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.pack new file mode 100644 index 0000000..40beeff Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.pack differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.rev b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.rev new file mode 100644 index 0000000..ec09ecf Binary files /dev/null and b/dot_config/tmux/plugins/tpm/dot_git/objects/pack/readonly_pack-15f2d7356a9c0b6c51bcf035d011eef973a8126a.rev differ diff --git a/dot_config/tmux/plugins/tpm/dot_git/packed-refs b/dot_config/tmux/plugins/tpm/dot_git/packed-refs new file mode 100644 index 0000000..51e3419 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/packed-refs @@ -0,0 +1,2 @@ +# pack-refs with: peeled fully-peeled sorted +99469c4a9b1ccf77fade25842dc7bafbc8ce9946 refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/heads/master b/dot_config/tmux/plugins/tpm/dot_git/refs/heads/master new file mode 100644 index 0000000..e69d6dc --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/heads/master @@ -0,0 +1 @@ +99469c4a9b1ccf77fade25842dc7bafbc8ce9946 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/remotes/origin/HEAD b/dot_config/tmux/plugins/tpm/dot_git/refs/remotes/origin/HEAD new file mode 100644 index 0000000..6efe28f --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/remotes/origin/HEAD @@ -0,0 +1 @@ +ref: refs/remotes/origin/master diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.1 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.1 new file mode 100644 index 0000000..3c28b9e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.1 @@ -0,0 +1 @@ +aee1fbc949e1f68db3d8da7ac1b9bee5b4ac1595 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.2 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.2 new file mode 100644 index 0000000..2a3fd81 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v0.0.2 @@ -0,0 +1 @@ +e29045e1db9ad6e1e9cf72ab59b78f0ec72cafb8 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.0.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.0.0 new file mode 100644 index 0000000..761fd8d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.0.0 @@ -0,0 +1 @@ +d520c6a47a40dc1ab0e7799d95514c5aab000a8f diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.1.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.1.0 new file mode 100644 index 0000000..3c31de9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.1.0 @@ -0,0 +1 @@ +0794614b55ea7c9b7c07306e64a09b8ac1207a2e diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.0 new file mode 100644 index 0000000..f811427 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.0 @@ -0,0 +1 @@ +1e65a591ab5972ff9072f2c07608ee1dd0b88eb7 diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.1 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.1 new file mode 100644 index 0000000..737c3e9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.1 @@ -0,0 +1 @@ +92ba10978b6e9a7a767ed2ddb9c7190f9956789a diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.2 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.2 new file mode 100644 index 0000000..c48d270 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v1.2.2 @@ -0,0 +1 @@ +5957fe6b4644e75ba0740a94faf97307eb31046d diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v2.0.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v2.0.0 new file mode 100644 index 0000000..c9292df --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v2.0.0 @@ -0,0 +1 @@ +79c45e42bf525de25a12689f3770ff1f1d30a1aa diff --git a/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v3.0.0 b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v3.0.0 new file mode 100644 index 0000000..2c56969 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_git/refs/tags/v3.0.0 @@ -0,0 +1 @@ +234002ad1c58e04b4e74853c7f1698874f69da60 diff --git a/dot_config/tmux/plugins/tpm/dot_gitattributes b/dot_config/tmux/plugins/tpm/dot_gitattributes new file mode 100644 index 0000000..80772e4 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_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/dot_config/tmux/plugins/tpm/dot_gitignore b/dot_config/tmux/plugins/tpm/dot_gitignore new file mode 100644 index 0000000..8a94156 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_gitignore @@ -0,0 +1,4 @@ +**/.vagrant/ +run_tests +tests/run_tests_in_isolation +tests/helpers/helpers.sh diff --git a/dot_config/tmux/plugins/tpm/dot_gitmodules b/dot_config/tmux/plugins/tpm/dot_gitmodules new file mode 100644 index 0000000..5e44e3c --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_gitmodules @@ -0,0 +1,3 @@ +[submodule "lib/tmux-test"] + path = lib/tmux-test + url = https://github.com/tmux-plugins/tmux-test.git diff --git a/dot_config/tmux/plugins/tpm/dot_travis.yml b/dot_config/tmux/plugins/tpm/dot_travis.yml new file mode 100644 index 0000000..ac45d8b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/dot_travis.yml @@ -0,0 +1,19 @@ +# generic packages and tmux +before_install: + - sudo apt-get update + - sudo apt-get install -y git-core expect + - sudo apt-get install -y python-software-properties software-properties-common + - sudo apt-get install -y libevent-dev libncurses-dev + - git clone https://github.com/tmux/tmux.git + - cd tmux + - git checkout 2.0 + - sh autogen.sh + - ./configure && make && sudo make install + +install: + - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules + # manual `git clone` required for testing `tmux-test` plugin itself + - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true + - lib/tmux-test/setup + +script: ./tests/run_tests_in_isolation diff --git a/dot_config/tmux/plugins/tpm/executable_tpm b/dot_config/tmux/plugins/tpm/executable_tpm new file mode 100644 index 0000000..7ad4b99 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/executable_tpm @@ -0,0 +1,81 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +BINDINGS_DIR="$CURRENT_DIR/bindings" +SCRIPTS_DIR="$CURRENT_DIR/scripts" + +source "$SCRIPTS_DIR/variables.sh" + +get_tmux_option() { + local option="$1" + local default_value="$2" + local option_value="$(tmux show-option -gqv "$option")" + if [ -z "$option_value" ]; then + echo "$default_value" + else + echo "$option_value" + fi +} + +tpm_path_set() { + tmux show-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" >/dev/null 2>&1 +} + +# Check if configuration file exists at an XDG-compatible location, if so use +# that directory for TMUX_PLUGIN_MANAGER_PATH. Otherwise use $DEFAULT_TPM_PATH. +set_default_tpm_path() { + local xdg_tmux_path="${XDG_CONFIG_HOME:-$HOME/.config}/tmux" + local tpm_path="$DEFAULT_TPM_PATH" + + if [ -f "$xdg_tmux_path/tmux.conf" ]; then + tpm_path="$xdg_tmux_path/plugins/" + fi + + tmux set-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" "$tpm_path" +} + +# Ensures TMUX_PLUGIN_MANAGER_PATH global env variable is set. +# +# Put this in `.tmux.conf` to override the default: +# `set-environment -g TMUX_PLUGIN_MANAGER_PATH "/some/other/path/"` +set_tpm_path() { + if ! tpm_path_set; then + set_default_tpm_path + fi +} + +# 1. Fetches plugin names from `@plugin` variables +# 2. Creates full plugin path +# 3. Sources all *.tmux files from each of the plugin directories +# - no errors raised if directory does not exist +# Files are sourced as tmux config files, not as shell scripts! +source_plugins() { + "$SCRIPTS_DIR/source_plugins.sh" >/dev/null 2>&1 +} + +# prefix + I - downloads TPM plugins and reloads TMUX environment +# prefix + U - updates a plugin (or all of them) and reloads TMUX environment +# prefix + alt + u - remove unused TPM plugins and reloads TMUX environment +set_tpm_key_bindings() { + local install_key="$(get_tmux_option "$install_key_option" "$default_install_key")" + tmux bind-key "$install_key" run-shell "$BINDINGS_DIR/install_plugins" + + local update_key="$(get_tmux_option "$update_key_option" "$default_update_key")" + tmux bind-key "$update_key" run-shell "$BINDINGS_DIR/update_plugins" + + local clean_key="$(get_tmux_option "$clean_key_option" "$default_clean_key")" + tmux bind-key "$clean_key" run-shell "$BINDINGS_DIR/clean_plugins" +} + +supported_tmux_version_ok() { + "$SCRIPTS_DIR/check_tmux_version.sh" "$SUPPORTED_TMUX_VERSION" +} + +main() { + if supported_tmux_version_ok; then + set_tpm_path + set_tpm_key_bindings + source_plugins + fi +} +main diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/CHANGELOG.md b/dot_config/tmux/plugins/tpm/lib/tmux-test/CHANGELOG.md new file mode 100644 index 0000000..e6b9c79 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/CHANGELOG.md @@ -0,0 +1,45 @@ +# Changelog + +### master +- move `setup` task to `.travis.yml` for travis tests +- "merge" travis.yml and travis_for_plugins.yml files (no need to keep em + separate) +- add more useful helper functions +- remove tmux-test repo as a submodule from self, this causes issues with + `$ git submodule update --recursive --init` command that some users use for + managing other plugins +- add new helper `teardown_helper` +- add `run_tests` helper +- change CLI syntax for choosing vagrant machine to run the tests on +- enable running just a single test via `run_tests` cli interface +- add `--keep-running` cli option to continue running vagrant after the tests + are done executing +- start using tmux 2.0 for tests + +### v0.2.0, 2015-02-22 +- `setup` script gitignores `tests/helpers.sh` +- move `tests/helpers.sh` to `tests/helpers/helpers.sh` +- `setup` undo removes added lines from gitignore file + +### v0.1.0, 2015-02-22 +- changes so that 'tmux-test' can be included with tmux plugins +- do not gitignore submodules directory +- add installation and usage instructions +- copy `.travis.yml` to the project root when running `setup` script +- add a brief mention of travis CI to the readme +- add test helpers +- `setup` script symlinks helpers file to `tests/` directory +- `setup` script can undo most of its actions +- add a tmux scripting test +- `tmux-test` uses `tmux-test` to test itself +- update `tmux-test` submodule +- a different `travis.yml` for `tmux-test` and for plugins + +### v0.0.1, 2015-02-21 +- git init +- add vagrant provisioning scripts for ubuntu and debian +- add a ".travis.yml" file +- generic "run_tests" script +- "run_tests_in_isolation" script +- add "Vagrantfile" +- enable passing VM names as arguments to "run_tests" script diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/LICENSE.md b/dot_config/tmux/plugins/tpm/lib/tmux-test/LICENSE.md new file mode 100644 index 0000000..e6e7350 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/LICENSE.md @@ -0,0 +1,19 @@ +Copyright (C) Bruno Sutic + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/README.md b/dot_config/tmux/plugins/tpm/lib/tmux-test/README.md new file mode 100644 index 0000000..27dccc9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/README.md @@ -0,0 +1,134 @@ +# tmux-test + +[![Build Status](https://travis-ci.org/tmux-plugins/tmux-test.png?branch=master)](https://travis-ci.org/tmux-plugins/tmux-test) + +A small framework for isolated testing of tmux plugins. Isolation is achieved by +running the tests in `Vagrant`. Works on [travis](travis-ci.org) too. + +Extracted from [tmux plugin manager](https://github.com/tmux-plugins/tpm) and +[tmux-copycat](https://github.com/tmux-plugins/tmux-copycat). + +Dependencies: `Vagrant` (no required when running on travis). + +### Setup + +Let's say you made tmux plugin with the following file hierarchy: + +```text +/tmux-plugin +|-- plugin.tmux +`-- scripts + `-- plugin_script.sh +``` + +From your project root directory (tmux-plugin/) execute the following shell +command to fetch `tmux-test` and add it as a submodule: + + $ git submodule add https://github.com/tmux-plugins/tmux-test.git lib/tmux-test + +Run the `setup` script: + + $ lib/tmux-test/setup + +The project directory will now look like this (additions have comments): + +```text +/tmux-plugin +|-- plugin.tmux +|-- run_tests # symlink, gitignored +|-- .gitignore # 2 lines appended to gitignore +|-- .travis.yml # added +|-- lib/tmux-test/ # git submodule +|-- scripts +| `-- plugin_script.sh +`-- tests # dir to put the tests in + `-- run_tests_in_isolation.sh # symlink, gitignored + `-- helpers + `-- helpers.sh # symlinked bash helpers, gitignored +``` + +`tmux-test` is now set up. You are ok to commit the additions to the repo. + +### Writing and running tests + +A test is any executable with a name starting with `test_` in `tests/` +directory. + +Now that you installed `tmux-test` let's create an example test. + +- create a `tests/test_example.sh` file with the following content (it's a + `bash` script but it can be any executable): + + #/usr/bin/env bash + + CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + + # bash helpers provided by 'tmux-test' + source $CURRENT_DIR/helpers/helpers.sh + + # installs plugin from current repo in Vagrant (or on Travis) + install_tmux_plugin_under_test_helper + + # start tmux in background (plugin under test is sourced) + tmux new -d + + # get first session name + session_name="$(tmux list-sessions -F "#{session_name}")" + + # fail the test if first session name is not "0" + if [ "$session_name" == "0" ]; then + # fail_helper is also provided by 'tmux-test' + fail_helper "First session name is not '0' by default" + fi + + # sets the right script exit code ('tmux-test' helper) + exit_helper + +- make the test file executable with `$ chmod +x tests/test_example.sh` +- run the test by executing `./run_tests` from the project root directory +- the first invocation might take some time because Vagrant's ubuntu virtual + machine is downloading. You should see `Success, tests pass!` message when it's + done. + +Check out more example test scripts in this project's [tests/ directory](tests/). + +### Continuous integration + +The setup script (`lib/tmux-test/setup`) added a `.travis.yml` file to the +project root. To setup continuous integration, just add/enable the project on +[travis](travis-ci.org). + +### Notes + +- The `tests/` directory for tests and `lib/tmux-test/` for cloning `tmux-test` + into cannot be changed currently +- Don't run `tests/run_tests_in_isolation` script on your local development + environment. That's an internal test runner meant to be executed in an + isolated environment like `vagrant` or `travis`.
+ Use `./run_tests` script. +- You can use `KEEP_RUNNING=true ./run_tests` for faster test running cycle. + If this case `Vagrant` will keep running even after the tests are done. +- You can use `VAGRANT_CWD=lib/tmux-text/ vagrant ssh ubuntu` for ssh login to + `Vagrant`. + +### Running `tmux-test` framework tests + +`tmux-test` uses itself to test itself. To run framework tests: + +- clone this project `$ git clone git@github.com:tmux-plugins/tmux-test.git` +- `$ cd tmux-test` +- run `$ ./run_framework_tests` + +### Other goodies + +- [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for + regex searches in tmux and fast match selection +- [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) - automatic + restoring and continuous saving of tmux env + +You might want to follow [@brunosutic](https://twitter.com/brunosutic) on +twitter if you want to hear about new tmux plugins or feature updates. + +### License + +[MIT](LICENSE.md) diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/Vagrantfile b/dot_config/tmux/plugins/tpm/lib/tmux-test/Vagrantfile new file mode 100644 index 0000000..04b3eba --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/Vagrantfile @@ -0,0 +1,17 @@ +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + + config.vm.synced_folder "../../", "/vagrant" + + config.vm.define :ubuntu do |ubuntu| + ubuntu.vm.box = "hashicorp/precise64" + ubuntu.vm.provision "shell", path: "vagrant_ubuntu_provisioning.sh" + end + + config.vm.define :centos do |centos| + centos.vm.box = "chef/centos-6.5" + centos.vm.provision "shell", path: "vagrant_centos_provisioning.sh" + end + +end diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_git b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_git new file mode 100644 index 0000000..71808e5 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_git @@ -0,0 +1 @@ +gitdir: ../../.git/modules/lib/tmux-test diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_gitignore b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_gitignore new file mode 100644 index 0000000..27281b5 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_gitignore @@ -0,0 +1,2 @@ +.vagrant/ +lib/ diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_travis.yml b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_travis.yml new file mode 100644 index 0000000..ac45d8b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/dot_travis.yml @@ -0,0 +1,19 @@ +# generic packages and tmux +before_install: + - sudo apt-get update + - sudo apt-get install -y git-core expect + - sudo apt-get install -y python-software-properties software-properties-common + - sudo apt-get install -y libevent-dev libncurses-dev + - git clone https://github.com/tmux/tmux.git + - cd tmux + - git checkout 2.0 + - sh autogen.sh + - ./configure && make && sudo make install + +install: + - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules + # manual `git clone` required for testing `tmux-test` plugin itself + - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true + - lib/tmux-test/setup + +script: ./tests/run_tests_in_isolation diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_framework_tests b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_framework_tests new file mode 100644 index 0000000..ed7f634 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_framework_tests @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# This file is used to run "tmux-test" framework tests. + +# "setup" script is needed to run the tests, but it overrides some working dir +# files. To address that, "setup" is run before the tests and it's actions are +# undone after. + +main() { + git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test + lib/tmux-test/setup + ./run_tests + local exit_value=$? + lib/tmux-test/setup "undo" + exit "$exit_value" +} +main diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_tests b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_tests new file mode 100644 index 0000000..eeeef28 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_literal_run_tests @@ -0,0 +1,145 @@ +#!/usr/bin/env bash + +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + +# Run this script when running a test suite. + +# For each virtual machine where tests run, this script performs the following: +# - starts VM +# - starts the test suite witin a VM +# - stops the VM after the test suite is done + +export BOXES="" +export FILES="" +export KEEP_RUNNING="" + +# global variable for script exit value +export EXIT_VALUE=0 + +display_help() { + echo "Usage:" + echo " ./run_tests # runs tests on default VM ubuntu" + echo " ./run_tests -m ubuntu # runs tests on ubuntu VM" + echo " ./run_tests -m ubuntu -m centos # runs tests on ubuntu and cents VMs" + echo " ./run_tests tests/some_test # run a single test file" + echo " ./run_tests --keep-running # don't stop vagrant after the tests are done" +} + +parse_arguments() { + while : + do + case "$1" in + -m | --machine) + local machine="$2" + if [ "$machine" == "ubuntu" ] || [ "$machine" == "centos" ]; then + BOXES="$BOXES $machine" + else + echo "Unknown machine '$machine'" + echo "" + display_help + exit 1 + fi + shift 2 + ;; + + -k | --keep-running) + KEEP_RUNNING="true" + shift + ;; + + -h | --help) + display_help + exit 0 + ;; + + --) # End of all options + shift + FILES="$*" + break + ;; + + -* ) + echo "Error: Unknown option: $1" >&2 + echo "" + display_help + exit 1 + ;; + + *) # No more options + FILES="$*" + break + ;; + esac + done + + # default options + if [ -z "$BOXES" ]; then + BOXES="ubuntu" + fi +} + +register_failing_tests() { + EXIT_VALUE=1 +} + +run_vagrant() { + local box="$1" + VAGRANT_CWD=lib/tmux-test/ vagrant up "$box" +} + +# Halt vagrant after tests are done running, unless `--keep-running` +# option is given +stop_vagrant() { + local box="$1" + if [ -z "$KEEP_RUNNING" ]; then + VAGRANT_CWD=lib/tmux-test/ vagrant halt "$box" + else + echo + echo "--keep-running option set, Vagrant not halted" + fi +} + +run_tests() { + local box="$1" + local test_file="/vagrant/tests/run_tests_in_isolation" + echo "Running test suite on $box from: $test_file" + echo + VAGRANT_CWD=lib/tmux-test/ vagrant ssh "$box" -c "cd /vagrant; $test_file $FILES" +} + +exit_message() { + local exit_val="$1" + echo + if [ "$exit_val" == 0 ]; then + echo "Success, tests pass!" + else + echo "Tests failed!" 1>&2 + fi +} + +run_tests_on_vm() { + local vm="$1" + run_vagrant "$vm" + run_tests "$vm" + local tests_exit_value="$?" + stop_vagrant "$vm" + if [ "$tests_exit_value" -gt 0 ]; then + register_failing_tests + fi +} + +run_tests_on_virtual_machines() { + local box + for box in $BOXES; do + run_tests_on_vm "$box" + done +} + +main() { + parse_arguments "$@" + run_tests_on_virtual_machines + exit_message "$EXIT_VALUE" + exit "$EXIT_VALUE" +} +main "$@" diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_setup b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_setup new file mode 100644 index 0000000..575a8a3 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/executable_setup @@ -0,0 +1,93 @@ +#!/usr/bin/env bash + +# invoke this script from your projects root directory + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# pass "undo" as a script arg to undo most of the setup actions +UNDO_SETUP="$1" +undo() { + [ "$UNDO_SETUP" == "undo" ] +} + +restore() { + local file="$1" + rm -f "$file" + git checkout -- "$file" 2>/dev/null +} + +gitignore() { + local file="$1" + grep -q "^${file}$" .gitignore 2>/dev/null || echo "$file" >> .gitignore +} + +remove_from_gitignore() { + local file="$1" + local escaped_filename="$(echo "$file" | sed "s,/,\\\/,g")" + sed -i"" "/^${escaped_filename}$/d" .gitignore +} + +add_files_to_gitignore() { + if ! undo; then + gitignore "run_tests" + gitignore "tests/run_tests_in_isolation" + gitignore "tests/helpers/helpers.sh" + else + remove_from_gitignore "run_tests" + remove_from_gitignore "tests/run_tests_in_isolation" + remove_from_gitignore "tests/helpers/helpers.sh" + fi +} + +symlink_user_test_runner() { + local file="run_tests" + if ! undo; then + ln -sf "lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +create_directory_for_tests() { + if ! undo; then + mkdir -p tests/helpers/ + fi +} + +symlink_internal_test_runner() { + local file="tests/run_tests_in_isolation" + if ! undo; then + ln -sf "../lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +symlink_test_helpers() { + local file="tests/helpers/helpers.sh" + if ! undo; then + ln -sf "../../lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +copy_travis_yml() { + local file=".travis.yml" + if ! undo; then + cp "lib/tmux-test/${file}" "$file" + else + restore "$file" + fi +} + +main() { + add_files_to_gitignore + symlink_user_test_runner + create_directory_for_tests + symlink_internal_test_runner + symlink_test_helpers + copy_travis_yml +} +main + diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_literal_run_tests_in_isolation b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_literal_run_tests_in_isolation new file mode 100644 index 0000000..fa39ebe --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_literal_run_tests_in_isolation @@ -0,0 +1,47 @@ +#!/usr/bin/env bash + +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + +# This script should be run within an isolated enviroment (Vagrant, travis). +# Depending on what the tests do, it might NOT be safe to run this script +# directly on the development machine. + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +EXIT_VALUE=0 # running a test suite is successful by default + +all_test_files() { + ls -1 "$CURRENT_DIR" | # test files are in the current dir + \grep -i "^test" | # test file names start with "test" + xargs # file names in a single line +} + +set_exit_val_to_false() { + EXIT_VALUE=1 +} + +run_tests() { + local test_file tests_files + if [ "$#" -gt 0 ]; then + test_files="${@//tests\//}" # remove 'tests/' directory prefix + else + test_files="$(all_test_files)" + fi + for test_file in $test_files; do + echo "Running test: $test_file" + "${CURRENT_DIR}/${test_file}" + + # handling exit value + local test_exit_value="$?" + if [ "$test_exit_value" -ne 0 ]; then + set_exit_val_to_false + fi + done +} + +main() { + run_tests "$@" + exit "$EXIT_VALUE" +} +main "$@" diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_basic_script_execution.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_basic_script_execution.sh new file mode 100644 index 0000000..0fdcf09 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_basic_script_execution.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +exit 0 diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_default_session_name.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_default_session_name.sh new file mode 100644 index 0000000..c761b93 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_default_session_name.sh @@ -0,0 +1,24 @@ +#/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# bash helpers provided by 'tmux-test' +source $CURRENT_DIR/helpers/helpers.sh + +# installs plugin from current repo in Vagrant (or on Travis) +install_tmux_plugin_under_test_helper + +# start tmux in background (plugin under test is sourced) +tmux new -d + +# get first session name +session_name="$(tmux list-sessions -F "#{session_name}")" + +# fail the test if first session name is not "0" +if ! [ "$session_name" == "0" ]; then + # fail_helper is also provided by 'tmux-test' + fail_helper "First session name is not '0' by default" +fi + +# sets the right script exit code ('tmux-test' helper) +exit_helper diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_tmux_scripting.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_tmux_scripting.sh new file mode 100644 index 0000000..3b4bece --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/executable_test_tmux_scripting.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +source $CURRENT_DIR/helpers/helpers.sh + +number_of_windows() { + tmux list-windows | + wc -l | + sed "s/ //g" +} + +main() { + # start tmux in the background + tmux new -d + tmux new-window + + local number_of_windows="$(number_of_windows)" + if ! [ "$number_of_windows" -eq 2 ]; then + fail_helper "Incorrect number of windows. Expected 2, got $number_of_windows" + fi + exit_helper +} +main diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/helpers/helpers.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/helpers/helpers.sh new file mode 100644 index 0000000..32b1ee4 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/tests/helpers/helpers.sh @@ -0,0 +1,68 @@ +# This file is a symlink from 'tmux-test' plugin. +# You probably don't want to edit it. + + +# Global variable that keeps the value of test status (success/fail). +# Suggested usage is via `fail_helper` and `exit_helper` functions. +TEST_STATUS="success" + +# PRIVATE FUNCTIONS + +_clone_the_plugin() { + local plugin_path="${HOME}/.tmux/plugins/tmux-plugin-under-test/" + rm -rf "$plugin_path" + git clone --recursive "${CURRENT_DIR}/../" "$plugin_path" >/dev/null 2>&1 +} + +_add_plugin_to_tmux_conf() { + set_tmux_conf_helper<<-HERE + run-shell '~/.tmux/plugins/tmux-plugin-under-test/*.tmux' + HERE +} + +# PUBLIC HELPER FUNCTIONS + +teardown_helper() { + rm -f ~/.tmux.conf + rm -rf ~/.tmux/ + tmux kill-server >/dev/null 2>&1 +} + +set_tmux_conf_helper() { + > ~/.tmux.conf # empty tmux.conf file + while read line; do + echo "$line" >> ~/.tmux.conf + done +} + +fail_helper() { + local message="$1" + echo "$message" >&2 + TEST_STATUS="fail" +} + +exit_helper() { + teardown_helper + if [ "$TEST_STATUS" == "fail" ]; then + echo "FAIL!" + echo + exit 1 + else + echo "SUCCESS" + echo + exit 0 + fi +} + +install_tmux_plugin_under_test_helper() { + _clone_the_plugin + _add_plugin_to_tmux_conf +} + +run_tests() { + # get all the functions starting with 'test_' and invoke them + for test in $(compgen -A function | grep "^test_"); do + "$test" + done + exit_helper +} diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_centos_provisioning.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_centos_provisioning.sh new file mode 100644 index 0000000..20a282b --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_centos_provisioning.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# libevent2 installation instructions from here +# https://gist.github.com/rschuman/6168833 + +sudo su - + +yum -y install gcc kernel-devel make automake autoconf ncurses-devel +yum -y install git-core expect vim ruby ruby-devel ruby-irb + +# install libevent2 from source +curl http://sourceforge.net/projects/levent/files/latest/download?source=files -L -o libevent2.tar.gz -w 'Last URL was: %{url_effective}' +cd ~/downloads +tar zxvf libevent2.tar.gz +cd ./libevent-* +./configure --prefix=/usr/local +make +make install + +# compile tmux +git clone https://github.com/tmux/tmux.git ~/tmux_source +cd ~/tmux_source +git checkout 2.0 +sh autogen.sh +LDFLAGS="-L/usr/local/lib -Wl,-rpath=/usr/local/lib" ./configure --prefix=/usr/local +make && sudo make install diff --git a/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_ubuntu_provisioning.sh b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_ubuntu_provisioning.sh new file mode 100644 index 0000000..63a60ea --- /dev/null +++ b/dot_config/tmux/plugins/tpm/lib/tmux-test/vagrant_ubuntu_provisioning.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash + +sudo apt-get update +sudo apt-get install -y git-core expect vim +sudo apt-get install -y python-software-properties software-properties-common +sudo apt-get install -y build-essential libtool autotools-dev autoconf +sudo apt-get install -y pkg-config libevent-dev libncurses-dev + +# install tmux 2.0 +git clone https://github.com/tmux/tmux.git ~/tmux_source +cd ~/tmux_source +git checkout 2.0 +sh autogen.sh +./configure && make && sudo make install diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_check_tmux_version.sh b/dot_config/tmux/plugins/tpm/scripts/executable_check_tmux_version.sh new file mode 100644 index 0000000..b0aedec --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_check_tmux_version.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +VERSION="$1" +UNSUPPORTED_MSG="$2" + +get_tmux_option() { + local option=$1 + local default_value=$2 + local option_value=$(tmux show-option -gqv "$option") + if [ -z "$option_value" ]; then + echo "$default_value" + else + echo "$option_value" + fi +} + +# Ensures a message is displayed for 5 seconds in tmux prompt. +# Does not override the 'display-time' tmux option. +display_message() { + local message="$1" + + # display_duration defaults to 5 seconds, if not passed as an argument + if [ "$#" -eq 2 ]; then + local display_duration="$2" + else + local display_duration="5000" + fi + + # saves user-set 'display-time' option + local saved_display_time=$(get_tmux_option "display-time" "750") + + # sets message display time to 5 seconds + tmux set-option -gq display-time "$display_duration" + + # displays message + tmux display-message "$message" + + # restores original 'display-time' value + tmux set-option -gq display-time "$saved_display_time" +} + +# this is used to get "clean" integer version number. Examples: +# `tmux 1.9` => `19` +# `1.9a` => `19` +get_digits_from_string() { + local string="$1" + local only_digits="$(echo "$string" | tr -dC '[:digit:]')" + echo "$only_digits" +} + +tmux_version_int() { + local tmux_version_string=$(tmux -V) + echo "$(get_digits_from_string "$tmux_version_string")" +} + +unsupported_version_message() { + if [ -n "$UNSUPPORTED_MSG" ]; then + echo "$UNSUPPORTED_MSG" + else + echo "Error, Tmux version unsupported! Please install Tmux version $VERSION or greater!" + fi +} + +exit_if_unsupported_version() { + local current_version="$1" + local supported_version="$2" + if [ "$current_version" -lt "$supported_version" ]; then + display_message "$(unsupported_version_message)" + exit 1 + fi +} + +main() { + local supported_version_int="$(get_digits_from_string "$VERSION")" + local current_version_int="$(tmux_version_int)" + exit_if_unsupported_version "$current_version_int" "$supported_version_int" +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_clean_plugins.sh b/dot_config/tmux/plugins/tpm/scripts/executable_clean_plugins.sh new file mode 100644 index 0000000..a025524 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_clean_plugins.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +clean_plugins() { + local plugins plugin plugin_directory + plugins="$(tpm_plugins_list_helper)" + + for plugin_directory in "$(tpm_path)"/*; do + [ -d "${plugin_directory}" ] || continue + plugin="$(plugin_name_helper "${plugin_directory}")" + case "${plugins}" in + *"${plugin}"*) : ;; + *) + [ "${plugin}" = "tpm" ] && continue + echo_ok "Removing \"$plugin\"" + rm -rf "${plugin_directory}" >/dev/null 2>&1 + [ -d "${plugin_directory}" ] && + echo_err " \"$plugin\" clean fail" || + echo_ok " \"$plugin\" clean success" + ;; + esac + done +} + +main() { + ensure_tpm_path_exists + clean_plugins + exit_value_helper +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_install_plugins.sh b/dot_config/tmux/plugins/tpm/scripts/executable_install_plugins.sh new file mode 100644 index 0000000..e2450ac --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_install_plugins.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +clone() { + local plugin="$1" + local branch="$2" + if [ -n "$branch" ]; then + cd "$(tpm_path)" && + GIT_TERMINAL_PROMPT=0 git clone -b "$branch" --single-branch --recursive "$plugin" >/dev/null 2>&1 + else + cd "$(tpm_path)" && + GIT_TERMINAL_PROMPT=0 git clone --single-branch --recursive "$plugin" >/dev/null 2>&1 + fi +} + +# tries cloning: +# 1. plugin name directly - works if it's a valid git url +# 2. expands the plugin name to point to a GitHub repo and tries cloning again +clone_plugin() { + local plugin="$1" + local branch="$2" + clone "$plugin" "$branch" || + clone "https://git::@github.com/$plugin" "$branch" +} + +# clone plugin and produce output +install_plugin() { + local plugin="$1" + local branch="$2" + local plugin_name="$(plugin_name_helper "$plugin")" + + if plugin_already_installed "$plugin"; then + echo_ok "Already installed \"$plugin_name\"" + else + echo_ok "Installing \"$plugin_name\"" + clone_plugin "$plugin" "$branch" && + echo_ok " \"$plugin_name\" download success" || + echo_err " \"$plugin_name\" download fail" + fi +} + +install_plugins() { + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + install_plugin "${plugin[0]}" "${plugin[1]}" + done +} + +verify_tpm_path_permissions() { + local path="$(tpm_path)" + # check the write permission flag for all users to ensure + # that we have proper access + [ -w "$path" ] || + echo_err "$path is not writable!" +} + +main() { + ensure_tpm_path_exists + verify_tpm_path_permissions + install_plugins + exit_value_helper +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_source_plugins.sh b/dot_config/tmux/plugins/tpm/scripts/executable_source_plugins.sh new file mode 100644 index 0000000..6381d54 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_source_plugins.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" + +plugin_dir_exists() { + [ -d "$1" ] +} + +# Runs all *.tmux files from the plugin directory. +# Files are ran as executables. +# No errors if the plugin dir does not exist. +silently_source_all_tmux_files() { + local plugin_path="$1" + local plugin_tmux_files="$plugin_path*.tmux" + if plugin_dir_exists "$plugin_path"; then + for tmux_file in $plugin_tmux_files; do + # if the glob didn't find any files this will be the + # unexpanded glob which obviously doesn't exist + [ -f "$tmux_file" ] || continue + # runs *.tmux file as an executable + $tmux_file >/dev/null 2>&1 + done + fi +} + +source_plugins() { + local plugin plugin_path + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + plugin_path="$(plugin_path_helper "${plugin[0]}")" + silently_source_all_tmux_files "$plugin_path" + done +} + +main() { + source_plugins +} +main diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin.sh b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin.sh new file mode 100644 index 0000000..e533664 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +# this script handles core logic of updating plugins + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +source "$HELPERS_DIR/plugin_functions.sh" +source "$HELPERS_DIR/utility.sh" + +if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions + source "$HELPERS_DIR/tmux_echo_functions.sh" +else # shell output functions + source "$HELPERS_DIR/shell_echo_functions.sh" +fi + +# from now on ignore first script argument +shift + +pull_changes() { + local plugin="$1" + local plugin_path="$(plugin_path_helper "$plugin")" + cd "$plugin_path" && + GIT_TERMINAL_PROMPT=0 git pull && + GIT_TERMINAL_PROMPT=0 git submodule update --init --recursive +} + +update() { + local plugin="$1" output + output=$(pull_changes "$plugin" 2>&1) + if (( $? == 0 )); then + echo_ok " \"$plugin\" update success" + echo_ok "$(echo "$output" | sed -e 's/^/ | /')" + else + echo_err " \"$plugin\" update fail" + echo_err "$(echo "$output" | sed -e 's/^/ | /')" + fi +} + +update_all() { + echo_ok "Updating all plugins!" + echo_ok "" + local plugins="$(tpm_plugins_list_helper)" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + local plugin_name="$(plugin_name_helper "${plugin[0]}")" + # updating only installed plugins + if plugin_already_installed "$plugin_name"; then + update "$plugin_name" & + fi + done + wait +} + +update_plugins() { + local plugins="$*" + for plugin in $plugins; do + IFS='#' read -ra plugin <<< "$plugin" + local plugin_name="$(plugin_name_helper "${plugin[0]}")" + if plugin_already_installed "$plugin_name"; then + update "$plugin_name" & + else + echo_err "$plugin_name not installed!" & + fi + done + wait +} + +main() { + ensure_tpm_path_exists + if [ "$1" == "all" ]; then + update_all + else + update_plugins "$*" + fi + exit_value_helper +} +main "$*" diff --git a/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin_prompt_handler.sh b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin_prompt_handler.sh new file mode 100644 index 0000000..5e1f7d9 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/executable_update_plugin_prompt_handler.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +HELPERS_DIR="$CURRENT_DIR/helpers" + +if [ $# -eq 0 ]; then + exit 0 +fi + +source "$HELPERS_DIR/tmux_echo_functions.sh" +source "$HELPERS_DIR/tmux_utils.sh" + +main() { + "$CURRENT_DIR/update_plugin.sh" --tmux-echo "$*" + reload_tmux_environment + end_message +} +main "$*" diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/plugin_functions.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/plugin_functions.sh new file mode 100644 index 0000000..f33d215 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/plugin_functions.sh @@ -0,0 +1,104 @@ +# using @tpm_plugins is now deprecated in favor of using @plugin syntax +tpm_plugins_variable_name="@tpm_plugins" + +# manually expanding tilde char or `$HOME` variable. +_manual_expansion() { + local path="$1" + local expanded_tilde="${path/#\~/$HOME}" + echo "${expanded_tilde/#\$HOME/$HOME}" +} + +_tpm_path() { + local string_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)/" + _manual_expansion "$string_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:-$HOME/.config}/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() { + 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 + cat $(_manual_expansion "$file") 2>/dev/null + done + fi +} + +# return files sourced from tmux config files +_sourced_files() { + _tmux_conf_contents | + sed -E -n -e "s/^[[:space:]]*source(-file)?[[:space:]]+(-q+[[:space:]]+)?['\"]?([^'\"]+)['\"]?/\3/p" +} + +# 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() { + # 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 '/^[ \t]*set(-option)? +-g +@plugin/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $4 }' +} + +# Allowed plugin name formats: +# 1. "git://github.com/user/plugin_name.git" +# 2. "user/plugin_name" +plugin_name_helper() { + local plugin="$1" + # get only the part after the last slash, e.g. "plugin_name.git" + local plugin_basename="$(basename "$plugin")" + # remove ".git" extension (if it exists) to get only "plugin_name" + local plugin_name="${plugin_basename%.git}" + echo "$plugin_name" +} + +plugin_path_helper() { + local plugin="$1" + local plugin_name="$(plugin_name_helper "$plugin")" + echo "$(tpm_path)${plugin_name}/" +} + +plugin_already_installed() { + local plugin="$1" + local plugin_path="$(plugin_path_helper "$plugin")" + [ -d "$plugin_path" ] && + cd "$plugin_path" && + git remote >/dev/null 2>&1 +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh new file mode 100644 index 0000000..ecaa37e --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh @@ -0,0 +1,7 @@ +echo_ok() { + echo "$*" +} + +echo_err() { + fail_helper "$*" +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh new file mode 100644 index 0000000..7a6ef0a --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh @@ -0,0 +1,28 @@ +_has_emacs_mode_keys() { + $(tmux show -gw mode-keys | grep -q emacs) +} + +tmux_echo() { + local message="$1" + tmux run-shell "echo '$message'" +} + +echo_ok() { + tmux_echo "$*" +} + +echo_err() { + tmux_echo "$*" +} + +end_message() { + if _has_emacs_mode_keys; then + local continue_key="ESCAPE" + else + local continue_key="ENTER" + fi + tmux_echo "" + tmux_echo "TMUX environment reloaded." + tmux_echo "" + tmux_echo "Done, press $continue_key to continue." +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_utils.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_utils.sh new file mode 100644 index 0000000..238952d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/tmux_utils.sh @@ -0,0 +1,6 @@ +HELPERS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +source "$HELPERS_DIR/plugin_functions.sh" + +reload_tmux_environment() { + tmux source-file $(_get_user_tmux_conf) >/dev/null 2>&1 +} diff --git a/dot_config/tmux/plugins/tpm/scripts/helpers/utility.sh b/dot_config/tmux/plugins/tpm/scripts/helpers/utility.sh new file mode 100644 index 0000000..de6eb35 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/helpers/utility.sh @@ -0,0 +1,17 @@ +ensure_tpm_path_exists() { + mkdir -p "$(tpm_path)" +} + +fail_helper() { + local message="$1" + echo "$message" >&2 + FAIL="true" +} + +exit_value_helper() { + if [ "$FAIL" == "true" ]; then + exit 1 + else + exit 0 + fi +} diff --git a/dot_config/tmux/plugins/tpm/scripts/variables.sh b/dot_config/tmux/plugins/tpm/scripts/variables.sh new file mode 100644 index 0000000..5601a86 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/scripts/variables.sh @@ -0,0 +1,13 @@ +install_key_option="@tpm-install" +default_install_key="I" + +update_key_option="@tpm-update" +default_update_key="U" + +clean_key_option="@tpm-clean" +default_clean_key="M-u" + +SUPPORTED_TMUX_VERSION="1.9" + +DEFAULT_TPM_ENV_VAR_NAME="TMUX_PLUGIN_MANAGER_PATH" +DEFAULT_TPM_PATH="$HOME/.tmux/plugins/" diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_failed_plugin_download b/dot_config/tmux/plugins/tpm/tests/executable_expect_failed_plugin_download new file mode 100644 index 0000000..b970477 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_failed_plugin_download @@ -0,0 +1,36 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 20 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"non-existing-plugin\"" +} + +expect { + "\"non-existing-plugin\" download fail" +} + +expect { + "Done, press ENTER to continue" { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_clean_plugins b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_clean_plugins new file mode 100644 index 0000000..987c49d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_clean_plugins @@ -0,0 +1,35 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + alt + u +send "u" + +set timeout 5 + +expect_after { + timeout { exit 1 } +} + +expect { + "Removing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" clean success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_multiple_plugins_download b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_multiple_plugins_download new file mode 100644 index 0000000..cc87a26 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_multiple_plugins_download @@ -0,0 +1,44 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" download success" +} + +expect { + "Installing \"tmux-copycat\"" +} + +expect { + "\"tmux-copycat\" download success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_plugin_download b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_plugin_download new file mode 100644 index 0000000..388f05d --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_plugin_download @@ -0,0 +1,50 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + I +send "I" + +# cloning might take a while +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installing \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" download success" +} + +expect { + "Done, press ENTER to continue" { + send " " + } +} + +sleep 1 +# this is tmux prefix + I +send "I" + +expect { + "Already installed \"tmux-example-plugin\"" +} + +expect { + "Done, press ENTER to continue" { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_a_single_plugin b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_a_single_plugin new file mode 100644 index 0000000..bcd64fe --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_a_single_plugin @@ -0,0 +1,55 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + U +send "U" + +set timeout 15 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installed plugins" +} + +expect { + "tmux-example-plugin" +} + +expect { + "\"all\" - updates all plugins" +} + +expect { + "ENTER - cancels" +} + +# wait for tmux to display prompt before sending characters +sleep 1 +send "tmux-example-plugin\r" + +expect { + "Updating \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" update success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_all_plugins b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_all_plugins new file mode 100644 index 0000000..4f3a4a3 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_expect_successful_update_of_all_plugins @@ -0,0 +1,59 @@ +#!/usr/bin/env expect + +# disables script output +log_user 0 + +spawn tmux + +# Waiting for tmux to attach. If this is not done, next command, `send` will +# not work properly. +sleep 1 + +# this is tmux prefix + U +send "U" + +set timeout 5 + +expect_after { + timeout { exit 1 } +} + +expect { + "Installed plugins" +} + +expect { + "tmux-example-plugin" +} + +expect { + "\"all\" - updates all plugins" +} + +expect { + "ENTER - cancels" +} + +# wait for tmux to display prompt before sending characters +sleep 1 +send "all\r" + +expect { + "Updating all plugins!" +} + +expect { + "Updating \"tmux-example-plugin\"" +} + +expect { + "\"tmux-example-plugin\" update success" +} + +expect { + "Done, press ENTER to continue." { + exit 0 + } +} + +exit 1 diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_clean.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_clean.sh new file mode 100644 index 0000000..d36c468 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_clean.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +manually_install_the_plugin() { + rm -rf "$PLUGINS_DIR" + mkdir -p "$PLUGINS_DIR" + cd "$PLUGINS_DIR" + git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin +} + +# TMUX KEY-BINDING TESTS + +test_plugin_uninstallation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + "$CURRENT_DIR/expect_successful_clean_plugins" || + fail_helper "[key-binding] clean fails" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_uninstallation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean success' || + fail_helper "[script] plugin cleaning fails" + + teardown_helper +} + +test_unsuccessful_plugin_uninstallation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + chmod 000 "$PLUGINS_DIR/tmux-example-plugin" # disable directory deletion + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean fail' "$expected_exit_code" || + fail_helper "[script] unsuccessful plugin cleaning doesn't fail" + + chmod 755 "$PLUGINS_DIR/tmux-example-plugin" # enable directory deletion + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation.sh new file mode 100644 index 0000000..94fb674 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation.sh @@ -0,0 +1,284 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PLUGINS_DIR="$HOME/.tmux/plugins" +TPM_DIR="$PWD" + +CUSTOM_PLUGINS_DIR="$HOME/foo/plugins" +ADDITIONAL_CONFIG_FILE_1="$HOME/.tmux/additional_config_file_1" +ADDITIONAL_CONFIG_FILE_2="$HOME/.tmux/additional_config_file_2" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +# TMUX KEY-BINDING TESTS + +test_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails" + + 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 + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_plugin_download" || + fail_helper "[key-binding][custom dir] plugin installation fails" + + check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][custom dir] plugin download fails" + + teardown_helper + rm -rf "$CUSTOM_PLUGINS_DIR" +} + +test_non_existing_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/non-existing-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_failed_plugin_download" || + fail_helper "[key-binding] non existing plugin installation doesn't fail" + + teardown_helper +} + +test_multiple_plugins_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + \ \ set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding] multiple plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding] plugin download fails (tmux-copycat)" + + teardown_helper +} + +test_plugins_installation_from_sourced_file_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + source '$ADDITIONAL_CONFIG_FILE_1' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding][sourced file] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][sourced file] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding][sourced file] plugin download fails (tmux-copycat)" + + teardown_helper +} + +test_plugins_installation_from_multiple_sourced_files_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + \ \ source '$ADDITIONAL_CONFIG_FILE_1' + source-file '$ADDITIONAL_CONFIG_FILE_2' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-example-plugin'" > "$ADDITIONAL_CONFIG_FILE_1" + echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_2" + + "$CURRENT_DIR/expect_successful_multiple_plugins_download" || + fail_helper "[key-binding][multiple sourced files] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding][multiple sourced files] plugin download fails (tmux-copycat)" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script] plugin already installed message fail" + + teardown_helper +} + +test_plugin_installation_custom_dir_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script][custom dir] plugin installation fails" + + check_dir_exists_helper "$CUSTOM_PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][custom dir] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script][custom dir] plugin already installed message fail" + + teardown_helper + rm -rf "$CUSTOM_PLUGINS_DIR" +} + +test_non_existing_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/non-existing-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/install_plugins" '"non-existing-plugin" download fail' "$expected_exit_code" || + fail_helper "[script] non existing plugin installation doesn't fail" + + teardown_helper +} + +test_multiple_plugins_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + \ \ set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] multiple plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script] multiple plugins already installed message fail" + + teardown_helper +} + +test_plugins_installation_from_sourced_file_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + source '$ADDITIONAL_CONFIG_FILE_1' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo "set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-copycat" download success' || + fail_helper "[script][sourced file] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][sourced file] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script][sourced file] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script][sourced file] plugins already installed message fail" + + teardown_helper +} + +test_plugins_installation_from_multiple_sourced_files_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + \ \ source '$ADDITIONAL_CONFIG_FILE_1' + source-file '$ADDITIONAL_CONFIG_FILE_2' + set -g @plugin 'tmux-plugins/tmux-example-plugin' + run-shell "$TPM_DIR/tpm" + HERE + + mkdir ~/.tmux + echo " set -g @plugin 'tmux-plugins/tmux-copycat'" > "$ADDITIONAL_CONFIG_FILE_1" + echo "set -g @plugin 'tmux-plugins/tmux-sensible'" > "$ADDITIONAL_CONFIG_FILE_2" + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-sensible" download success' || + fail_helper "[script][multiple sourced files] plugins installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-copycat)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-sensible/" || + fail_helper "[script][multiple sourced files] plugin download fails (tmux-sensible)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-sensible"' || + fail_helper "[script][multiple sourced files] plugins already installed message fail" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation_legacy.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation_legacy.sh new file mode 100644 index 0000000..b1d0cf6 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_installation_legacy.sh @@ -0,0 +1,100 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +PLUGINS_DIR="$HOME/.tmux/plugins" +TPM_DIR="$PWD" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +# TMUX KEY-BINDING TESTS + +test_plugin_installation_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + # opens tmux and test it with `expect` + $CURRENT_DIR/expect_successful_plugin_download || + fail_helper "[key-binding] plugin installation fails" + + # check plugin dir exists after download + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails" + + teardown_helper +} + +test_legacy_and_new_syntax_for_plugin_installation_work_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins " \ + tmux-plugins/tmux-example-plugin \ + " + set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + # opens tmux and test it with `expect` + "$CURRENT_DIR"/expect_successful_multiple_plugins_download || + fail_helper "[key-binding] multiple plugins installation fails" + + # check plugin dir exists after download + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[key-binding] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[key-binding] plugin download fails (tmux-copycat)" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_installation_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || + fail_helper "[script] plugin already installed message fail" + + teardown_helper +} + +test_legacy_and_new_syntax_for_plugin_installation_work_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @tpm_plugins " \ + tmux-plugins/tmux-example-plugin \ + " + set -g @plugin 'tmux-plugins/tmux-copycat' + run-shell "$TPM_DIR/tpm" + HERE + + script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || + fail_helper "[script] multiple plugin installation fails" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || + fail_helper "[script] plugin download fails (tmux-example-plugin)" + + check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || + fail_helper "[script] plugin download fails (tmux-copycat)" + + script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || + fail_helper "[script] multiple plugins already installed message fail" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_sourcing.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_sourcing.sh new file mode 100644 index 0000000..c06f1fe --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_sourcing.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +CUSTOM_PLUGINS_DIR="$HOME/foo/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +check_binding_defined() { + local binding="$1" + tmux list-keys | grep -q "$binding" +} + +create_test_plugin_helper() { + local plugin_path="$PLUGINS_DIR/tmux_test_plugin/" + rm -rf "$plugin_path" + mkdir -p "$plugin_path" + + while read line; do + echo "$line" >> "$plugin_path/test_plugin.tmux" + done + chmod +x "$plugin_path/test_plugin.tmux" +} + +check_tpm_path() { + local correct_tpm_path="$1" + local tpm_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" + [ "$correct_tpm_path" == "$tpm_path" ] +} + +test_plugin_sourcing() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "doesnt_matter/tmux_test_plugin" + run-shell "$TPM_DIR/tpm" + HERE + + # manually creates a local tmux plugin + create_test_plugin_helper <<- HERE + tmux bind-key R run-shell foo_command + HERE + + tmux new-session -d # tmux starts detached + check_binding_defined "R run-shell foo_command" || + fail_helper "Plugin sourcing fails" + + teardown_helper +} + +test_default_tpm_path() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + run-shell "$TPM_DIR/tpm" + HERE + + check_tpm_path "${PLUGINS_DIR}/" || + fail_helper "Default TPM path not correct" + + teardown_helper +} + +test_custom_tpm_path() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' + run-shell "$TPM_DIR/tpm" + HERE + + check_tpm_path "$CUSTOM_PLUGINS_DIR" || + fail_helper "Custom TPM path not correct" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_update.sh b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_update.sh new file mode 100644 index 0000000..4924d16 --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/executable_test_plugin_update.sh @@ -0,0 +1,60 @@ +#!/usr/bin/env bash + +CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +TPM_DIR="$PWD" +PLUGINS_DIR="$HOME/.tmux/plugins" + +source "$CURRENT_DIR/helpers/helpers.sh" +source "$CURRENT_DIR/helpers/tpm.sh" + +manually_install_the_plugin() { + mkdir -p "$PLUGINS_DIR" + cd "$PLUGINS_DIR" + git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin +} + +# TMUX KEY-BINDING TESTS + +test_plugin_update_via_tmux_key_binding() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + "$CURRENT_DIR/expect_successful_update_of_all_plugins" || + fail_helper "[key-binding] 'update all plugins' fails" + + "$CURRENT_DIR/expect_successful_update_of_a_single_plugin" || + fail_helper "[key-binding] 'update single plugin' fails" + + teardown_helper +} + +# SCRIPT TESTS + +test_plugin_update_via_script() { + set_tmux_conf_helper <<- HERE + set -g mode-keys vi + set -g @plugin "tmux-plugins/tmux-example-plugin" + run-shell "$TPM_DIR/tpm" + HERE + + manually_install_the_plugin + + local expected_exit_code=1 + script_run_helper "$TPM_DIR/bin/update_plugins" 'usage' "$expected_exit_code" || + fail_helper "[script] running update plugins without args should fail" + + script_run_helper "$TPM_DIR/bin/update_plugins tmux-example-plugin" '"tmux-example-plugin" update success' || + fail_helper "[script] plugin update fails" + + script_run_helper "$TPM_DIR/bin/update_plugins all" '"tmux-example-plugin" update success' || + fail_helper "[script] update all plugins fails" + + teardown_helper +} + +run_tests diff --git a/dot_config/tmux/plugins/tpm/tests/helpers/tpm.sh b/dot_config/tmux/plugins/tpm/tests/helpers/tpm.sh new file mode 100644 index 0000000..1594afb --- /dev/null +++ b/dot_config/tmux/plugins/tpm/tests/helpers/tpm.sh @@ -0,0 +1,13 @@ +check_dir_exists_helper() { + [ -d "$1" ] +} + +# runs the scripts and asserts it has the correct output and exit code +script_run_helper() { + local script="$1" + local expected_output="$2" + local expected_exit_code="${3:-0}" + $script 2>&1 | + grep "$expected_output" >/dev/null 2>&1 && # grep -q flag quits the script early + [ "${PIPESTATUS[0]}" -eq "$expected_exit_code" ] +} diff --git a/dot_config/tmux/tmux.conf b/dot_config/tmux/tmux.conf new file mode 100644 index 0000000..534efa6 --- /dev/null +++ b/dot_config/tmux/tmux.conf @@ -0,0 +1,14 @@ +set-environment -g TMUX_PLUGIN_MANAGER_PATH '~/.local/share/tmux/plugins' + +set -g base-index 1 +setw -g pane-base-index 1 +set -g default-terminal "xterm-256color" +set-option -ga terminal-overrides ",xterm-256color:Tc" + +set -g @plugin 'catppuccin/tmux' +set -g @plugin 'tmux-plugins/tpm' +set -g @plugin 'tmux-plugins/tmux-sensible' + +set -g @catppuccin_flavor 'macchiato' + +run '~/.local/share/tmux/plugins/tpm/tpm'