├── README.md
├── bin
└── t
└── t-smart-tmux-session-manager.tmux
/README.md:
--------------------------------------------------------------------------------
1 | # Introducing Sesh 🎉
2 |
3 | I've rewritten this project in Go and called it "sesh". It's more flexible and faster than the original script. I'm no longer maintaining this project. I'll leave it up for historical purposes, but I recommend you check out the new project.
4 |
5 | [Check out sesh](https://github.com/joshmedeski/sesh)
6 |
7 | # t - the smart tmux session manager
8 |
9 | tmux is a powerful tool, but dealing with sessions can be painful. This script makes it easy to create and switch tmux sessions:
10 |
11 |
12 | Documentation
13 |
14 | ## Prerequisites
15 |
16 | - [tmux](https://github.com/tmux/tmux) (>= 3.2)
17 | - [tpm](https://github.com/tmux-plugins/tpm)
18 | - [zoxide](https://github.com/ajeetdsouza/zoxide)
19 | - [fzf](https://github.com/junegunn/fzf) (>=0.35.0)
20 |
21 | _Note: some users have had issues with fzf integration on tmux 3.2a where upon
22 | spawning fzf it would lock the tmux pane. Upgrading to 3.3a seems to be a viable
23 | workaround_ Check [#104](https://github.com/joshmedeski/t-smart-tmux-session-manager/issues/104)
24 |
25 | ```sh
26 | brew install tmux zoxide fzf
27 | ```
28 |
29 | Use the package manager of your OS if you are not on macOS.
30 |
31 | ## How to install
32 |
33 | ### 1. Install tpm plugin
34 |
35 | Add the following line to your `tmux.conf` file:
36 |
37 | ```sh
38 | set -g @plugin 'joshmedeski/t-smart-tmux-session-manager'
39 | ```
40 |
41 | **Note:** tpm recommends you list your plugins and then run tpm at the very bottom of your `tmux.conf`.
42 |
43 | Then, run `I` to install the plugin.
44 |
45 | ### 2. Add to path
46 |
47 | To use the `t` script from anywhere, select your shell environment and follow the instructions.
48 |
49 | **Note:** you'll need to check the path of your tpm plugins. It may be `~/.tmux/plugins` or `~/.config/tmux/plugins` depending on where your `tmux.conf` is located.
50 |
51 |
52 | bash
53 |
54 | Add the following line to `~/.bashrc`
55 |
56 | ```sh
57 | # ~/.tmux/plugins
58 | export PATH=$HOME/.tmux/plugins/t-smart-tmux-session-manager/bin:$PATH
59 | # ~/.config/tmux/plugins
60 | export PATH=$HOME/.config/tmux/plugins/t-smart-tmux-session-manager/bin:$PATH
61 | ```
62 |
63 |
64 |
65 |
66 | zsh
67 |
68 | Add the following line to `~/.zprofile`
69 |
70 | ```sh
71 | # ~/.tmux/plugins
72 | export PATH=$HOME/.tmux/plugins/t-smart-tmux-session-manager/bin:$PATH
73 | # ~/.config/tmux/plugins
74 | export PATH=$HOME/.config/tmux/plugins/t-smart-tmux-session-manager/bin:$PATH
75 | ```
76 |
77 |
78 |
79 |
80 | fish
81 |
82 | Add the following line to `~/.config/fish/config.fish`
83 |
84 | ```fish
85 | # ~/.tmux/plugins
86 | fish_add_path $HOME/.tmux/plugins/t-smart-tmux-session-manager/bin
87 | # ~/.config/tmux/plugins
88 | fish_add_path $HOME/.config/tmux/plugins/t-smart-tmux-session-manager/bin
89 | ```
90 |
91 |
92 |
93 | ### 3. Recommended tmux settings
94 |
95 | I recommend you add these settings to your `tmux.conf` to have a better experience with this plugin.
96 |
97 | ```sh
98 | bind-key x kill-pane # skip "kill-pane 1? (y/n)" prompt
99 | set -g detach-on-destroy off # don't exit from tmux when closing a session
100 | ```
101 |
102 | ### 4. Customize Prompt (optional)
103 |
104 | If your terminal supports [Nerd Font symbols](https://www.nerdfonts.com/), you can customize your prompt.
105 |
106 | ```sh
107 | set -g @t-fzf-prompt ' '
108 | ```
109 |
110 | Or you can replace the prompt with anything you'd like.
111 |
112 | ## How to use
113 |
114 | ```sh
115 | Run interactive mode
116 | t
117 | ctrl-s list only tmux sessions
118 | ctrl-x list only zoxide results
119 | ctrl-f list results from the find command
120 |
121 | Go to session (matches tmux session, zoxide result, or directory)
122 | t {name}
123 |
124 | Open popup (while in tmux)
125 | +T
126 | ctrl-s list only tmux sessions
127 | ctrl-x list only zoxide results
128 | ctrl-f list results from the find command
129 |
130 | Show help
131 | t -h
132 | t --help
133 | ```
134 |
135 | By default, this plugin is bound to `+T` which triggers a fzf-tmux popup that display zoxide results. Type the result you want and when you hit enter it will create a tmux session and connect to it or, if the sessions already exists, switch to it.
136 |
137 | If you are not in tmux, you can simply run `t` to start the interactive script, or call `t {name}` to jump directly to a session of your choosing.
138 |
139 | ### Key Bindings
140 |
141 | - `ctrl-s` list only tmux sessions
142 | - `ctrl-x` list only zoxide results
143 | - `ctrl-f` find by directory
144 |
145 | ## Extra features
146 |
147 | ### Cloning repositories
148 |
149 | You can quickly clone a repository to your preferred directory by using the `t` command combined with the `-r` flag (or `--repo`).
150 |
151 | First, you have to set the `T_REPOS_DIR` variable in your shell environment. Make sure to set it where you want your repositories cloned.
152 |
153 |
154 | bash
155 |
156 | Add the following line to `~/.bashrc`
157 |
158 | ```sh
159 | export T_REPOS_DIR="~/repos"
160 | ```
161 |
162 |
163 |
164 |
165 | zsh
166 |
167 | Add the following line to `~/.zshrc`
168 |
169 | ```sh
170 | export T_REPOS_DIR="~/repos"
171 | ```
172 |
173 |
174 |
175 |
176 | fish
177 |
178 | Add the following line to `~/.config/fish/conf.d/t.fish`
179 |
180 | ```fish
181 | set -Ux T_REPOS_DIR ~/repos
182 | ```
183 |
184 |
185 |
186 | In order to use the feature, simply run:
187 |
188 | ```sh
189 | t -r https://github.com/joshmedeski/t-smart-tmux-session-manager.git
190 | ```
191 |
192 | **Note:** it has to be a valid git remote url (ending in `.git`) or order to work.
193 |
194 | I prefer to copy the repository URL to my clipboard and run the following command on macOS.
195 |
196 |
197 | bash/zsh
198 |
199 | ```sh
200 | t -r $(pbpaste)
201 | ```
202 |
203 |
204 |
205 |
206 | fish
207 |
208 | ```sh
209 | t -r (pbpaste)
210 | ```
211 |
212 |
213 |
214 | If you want to overwrite the directory to clone to, you can overwrite the `T_REPOS_DIR` variable before running the command:
215 |
216 | ```sh
217 | T_REPOS_DIR=~/code t --repo https://github.com/joshmedeski/tmux-list.git
218 | ```
219 |
220 | ## How to customize
221 |
222 | ### Use Git Root for session name
223 |
224 | You may prefer your session names starting from the root of the git repository. This can help with naming conflicts if you have multiple directories with the same name on your machine and make it clear when you have multiple sessions open in the same git repository.
225 |
226 |
227 | bash
228 |
229 | Add the following line to `~/.bashrc`
230 |
231 | ```sh
232 | export T_SESSION_USE_GIT_ROOT="true"
233 | ```
234 |
235 |
236 |
237 |
238 | zsh
239 |
240 | Add the following line to `~/.zshrc`
241 |
242 | ```sh
243 | export T_SESSION_USE_GIT_ROOT="true"
244 | ```
245 |
246 |
247 |
248 |
249 | fish
250 |
251 | Add the following line to `~/.config/fish/conf.d/t.fish`
252 |
253 | ```fish
254 | set -Ux T_SESSION_USE_GIT_ROOT true
255 | ```
256 |
257 |
258 |
259 | ### Include parent dir in session name
260 |
261 | You may prefer your session names having a prefix of the parent directory. This can help with naming conflicts if you have multiple directories with the same name on your machine.
262 |
263 |
264 | bash
265 |
266 | Add the following line to `~/.bashrc`
267 |
268 | ```sh
269 | export T_SESSION_NAME_INCLUDE_PARENT="true"
270 | ```
271 |
272 |
273 |
274 |
275 | zsh
276 |
277 | Add the following line to `~/.zshrc`
278 |
279 | ```sh
280 | export T_SESSION_NAME_INCLUDE_PARENT="true"
281 | ```
282 |
283 |
284 |
285 |
286 | fish
287 |
288 | Add the following line to `~/.config/fish/conf.d/t.fish`
289 |
290 | ```fish
291 | set -Ux T_SESSION_NAME_INCLUDE_PARENT true
292 | ```
293 |
294 |
295 |
296 | ### Custom fzf-tmux keybinding
297 |
298 | By default, the `t` popup is bound to `T`. In order to overwrite your own custom key binding, add setting the `@t-bind` varaible to your `tmux.conf`:
299 |
300 | ```sh
301 | set -g @t-bind "K"
302 | ```
303 |
304 | You can unbind the default by using `none`.
305 |
306 | ```sh
307 | set -g @t-bind "none" # unbind default
308 | ```
309 |
310 | ### Change default fzf results
311 |
312 | By default, t will display tmux sessions and zoxide results by default. You can change this by setting `@t-fzf-default-results` variable to your `tmux.conf`:
313 |
314 | ```sh
315 | set -g @t-fzf-default-results 'sessions' # show tmux sessions by default
316 | ```
317 |
318 | ```sh
319 | set -g @t-fzf-default-results 'zoxide' # show zoxide results by default
320 | ```
321 |
322 | ### Custom find command
323 |
324 | By default, the find key binding (`^f`) will run a simple `find` command to search for directories in and around your home directory.
325 |
326 | ```sh
327 | find ~ -maxdepth 3 -type d
328 | ```
329 |
330 | You can customize this command by setting `@t-find-binding` variable to your `tmux.conf`:
331 |
332 | In this example, I'm setting the prompt with a custom [Nerd Font icon](https://www.nerdfonts.com/) and using [fd](https://github.com/sharkdp/fd) to search directories (including hidden ones) up to two levels deep from my home directory.
333 |
334 | ```sh
335 | set -g @t-fzf-find-binding 'ctrl-f:change-prompt( )+reload(fd -H -d 2 -t d . ~)'
336 | ```
337 |
338 | Run `man fzf` to learn more about how to customize key bindings with fzf.
339 |
340 | ### FZF_TMUX_OPTS
341 |
342 | If you want to overwrite the fzf-tmux options, you can set the `FZF_TMUX_OPTS` variable in your shell environment.
343 |
344 | ```bash
345 | # ~/.bashrc or ~/.zshrc
346 | export FZF_TMUX_OPTS="-p 55%,60%"
347 | ```
348 |
349 | ```fish
350 | # ~/.config/fish/config.fish
351 | set -Ux FZF_TMUX_OPTS "-p 55%,60%"
352 | ```
353 |
354 | Run `man fzf-tmux` to learn more about the available options.
355 |
356 | ### Custom Border Label
357 |
358 | If you want to customize the fzf popup border label, you can add `T_FZF_BORDER_LABEL` to your shell variable
359 |
360 | ```bash
361 | # ~/.bashrc or ~/.zshrc
362 | export T_FZF_BORDER_LABEL=' Your Custom Label '
363 | ```
364 |
365 | or if you use fish:
366 |
367 | ```fish
368 | # ~/.config/fish/config.fish
369 | set -Ux T_FZF_BORDER_LABEL " Your Custom Label "
370 | ```
371 |
372 | ## Background
373 |
374 | Interested in learning more about how this script came to be? Check out [Smart tmux sessions with zoxide and fzf](https://www.joshmedeski.com/posts/smart-tmux-sessions-with-zoxide-and-fzf/).
375 | ]
376 |
377 | ## Startup script
378 |
379 | You can run a startup script when you create a new session. This is useful for running a command when you create a new session, like starting a dev server or automatically opening neovim to begin editing a file.
380 |
381 | This works by adding a `.t` file to your desired directory. Here is a quick script for bootstrapping that file:
382 |
383 | ```sh
384 | touch .t && chmod +x .t && echo -e '#!/usr/bin/env bash\n' > .t && nvim .t
385 | ```
386 |
387 | I like opening Neovim and the find file Telescope prompt to quickly find a file to edit. Here is an example of what I put in many of my projects:
388 |
389 | ```sh
390 | #!/usr/bin/env bash
391 | nvim -c 'Telescope find_files'
392 | ```
393 |
394 | So, when you open any project that detects a `.t` it will automatically run that script when a session is created.
395 |
396 | This feature is in early development so please feel free to give feedback if you have ideas for how to improve on it.
397 |
398 | ## Bonus: macOS keyboard shortcut
399 |
400 | My personal workflow uses [macOS Keyboard Shortcuts for tmux](https://www.joshmedeski.com/posts/macos-keyboard-shortcuts-for-tmux/). I have bound the `t` popup to `cmd+j` with the following code:
401 |
402 |
403 | Alacritty
404 |
405 | Add the following line to your `alacritty.yml`
406 |
407 | ```yml
408 | key_bindings:
409 | - { key: K, mods: Command, chars: "\x02\x54" } # open t - tmux smart session manager
410 | ```
411 |
412 |
413 |
414 |
415 | Kitty
416 |
417 | Add the following line to your `kitty.conf`
418 |
419 | ```sh
420 | map cmd+k send_text all \x02\x54
421 | ```
422 |
423 |
424 |
425 |
426 | WezTerm
427 |
428 | Add the following line to your `wezterm.lua` inside the **keys** options
429 |
430 | ```sh
431 | { key = 'j', mods = 'CMD', action = wezterm.action.SendString '\x02\x54' }, -- open t - tmux smart session manager
432 |
433 | ```
434 |
435 |
436 |
437 | **Note:** These bindings are based off the default prefix, `ctrl+b` (which converts to `\x02`). If you changed your prefix, I recommend [watching my video](https://www.joshmedeski.com/posts/macos-keyboard-shortcuts-for-tmux/) which goes into depth how to customize your own keybindings in Alacritty.
438 |
439 |
440 |
--------------------------------------------------------------------------------
/bin/t:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # determine if the tmux server is running
4 | if tmux list-sessions &>/dev/null; then
5 | TMUX_RUNNING=0
6 | else
7 | TMUX_RUNNING=1
8 | fi
9 |
10 | # determine the user's current position relative tmux:
11 | # serverless - there is no running tmux server
12 | # attached - the user is currently attached to the running tmux server
13 | # detached - the user is currently not attached to the running tmux server
14 | T_RUNTYPE="serverless"
15 | if [ "$TMUX_RUNNING" -eq 0 ]; then
16 | if [ "$TMUX" ]; then # inside tmux
17 | T_RUNTYPE="attached"
18 | else # outside tmux
19 | T_RUNTYPE="detached"
20 | fi
21 | fi
22 |
23 | # display help text with an argument
24 | if [ "$1" = "-h" ] || [ "$1" == "--help" ]; then
25 | printf "\n"
26 | printf "\033[1m t - the smart tmux session manager\033[0m\n"
27 | printf "\033[37m https://github.com/joshmedeski/t-smart-tmux-session-manager\n"
28 | printf "\n"
29 | printf "\033[32m Run interactive mode\n"
30 | printf "\033[34m t\n"
31 | printf "\033[34m ctrl-s list only tmux sessions\n"
32 | printf "\033[34m ctrl-x list only zoxide results\n"
33 | printf "\033[34m ctrl-f list results from the find command\n"
34 | printf "\n"
35 | printf "\033[32m Go to session (matches tmux session, zoxide result, or directory)\n"
36 | printf "\033[34m t {name}\n"
37 | printf "\n"
38 | printf "\033[32m Open popup (while in tmux)\n"
39 |
40 | if [ "$TMUX_RUNNING" -eq 0 ]; then
41 | T_BIND=$(tmux show-option -gvq "@t-bind")
42 | if [ "$T_BIND" = "" ]; then
43 | T_BIND="T"
44 | fi
45 | printf "\033[34m +%s\n" "$T_BIND"
46 | printf "\033[34m ctrl-s list only tmux sessions\n"
47 | printf "\033[34m ctrl-x list only zoxide results\n"
48 | printf "\033[34m ctrl-f list results from the find command\n"
49 | else
50 | printf "\033[34m start tmux server to see bindings\n" "$T_BIND"
51 | fi
52 |
53 | printf "\n"
54 | printf "\033[32m Show help\n"
55 | printf "\033[34m t -h\n"
56 | printf "\033[34m t --help\n"
57 | printf "\n"
58 | exit 0
59 | fi
60 |
61 | HOME_REPLACER="" # default to a noop
62 | echo "$HOME" | grep -E "^[a-zA-Z0-9\-_/.@]+$" &>/dev/null # chars safe to use in sed
63 | HOME_SED_SAFE=$?
64 | if [ $HOME_SED_SAFE -eq 0 ]; then # $HOME should be safe to use in sed
65 | HOME_REPLACER="s|^$HOME/|~/|"
66 | fi
67 |
68 | get_fzf_prompt() {
69 | local fzf_prompt
70 | local fzf_default_prompt='> '
71 | if [ "$TMUX_RUNNING" -eq 0 ]; then
72 | fzf_prompt="$(tmux show -gqv '@t-fzf-prompt')"
73 | fi
74 | [ -n "$fzf_prompt" ] && echo "$fzf_prompt" || echo "$fzf_default_prompt"
75 | }
76 | PROMPT=$(get_fzf_prompt)
77 |
78 | get_fzf_find_binding() {
79 | local fzf_find_binding
80 | local fzf_find_binding_default='ctrl-f:change-prompt(find> )+reload(find ~ -maxdepth 3 -type d)'
81 | if [ "$TMUX_RUNNING" -eq 0 ]; then
82 | fzf_find_binding="$(tmux show -gqv '@t-fzf-find-binding')"
83 | fi
84 | [ -n "$fzf_find_binding" ] && echo "$fzf_find_binding" || echo "$fzf_find_binding_default"
85 | }
86 |
87 | FIND_BIND=$(get_fzf_find_binding)
88 |
89 | get_sessions_by_mru() {
90 | if [ "$T_RUNTYPE" == "attached" ]; then
91 | CURRENT_SID=$(tmux display-message -p "#{session_id}")
92 | else
93 | CURRENT_SID=""
94 | fi
95 | tmux list-sessions \
96 | -f "#{!=:#{session_id},$CURRENT_SID}" \
97 | -F '#{session_last_attached} #{session_name}' \
98 | | sort --numeric-sort --reverse | awk '{print $2}; END {print "———"}'
99 | }
100 |
101 | get_zoxide_results() {
102 | zoxide query -l | sed -e "$HOME_REPLACER"
103 | }
104 |
105 | get_fzf_results() {
106 | if [ "$TMUX_RUNNING" -eq 0 ]; then
107 | fzf_default_results="$(tmux show -gqv '@t-fzf-default-results')"
108 | case $fzf_default_results in
109 | sessions)
110 | get_sessions_by_mru
111 | ;;
112 | zoxide)
113 | get_zoxide_results
114 | ;;
115 | *)
116 | get_sessions_by_mru && get_zoxide_results # default shows both
117 | ;;
118 | esac
119 | else
120 | get_zoxide_results # only show zoxide results when outside tmux
121 | fi
122 | }
123 |
124 | fzf_border_label_default=' t - smart tmux session manager '
125 | BORDER_LABEL=${T_FZF_BORDER_LABEL:-$fzf_border_label_default}
126 |
127 | HEADER=" ^s sessions ^x zoxide ^f find"
128 | SESSION_BIND="ctrl-s:change-prompt(sessions> )+reload(tmux list-sessions -F '#S')"
129 | ZOXIDE_BIND="ctrl-x:change-prompt(zoxide> )+reload(zoxide query -l | sed -e \"$HOME_REPLACER\")"
130 | TAB_BIND="tab:down,btab:up"
131 |
132 | if [ $# -ge 1 ]; then # argument provided
133 | if [ "$1" = "-r" ] || [ "$1" == "--repo" ]; then
134 | if [[ -z $T_REPOS_DIR ]]; then
135 | echo "T_REPOS_DIR has not been set"
136 | exit 1
137 | fi
138 |
139 | if [ -z "$2" ]; then
140 | echo "No repository url provided -r {url}"
141 | exit 1
142 | fi
143 |
144 | REPO_URL=$2
145 | cd $T_REPOS_DIR
146 |
147 | if git clone --recursive $REPO_URL; then
148 | RESULT="$T_REPOS_DIR/$(basename "$_" .git)"
149 | else
150 | exit $? # exit code from last command
151 | fi
152 |
153 | else # not -r or --repo
154 | zoxide query "$1" &>/dev/null
155 | ZOXIDE_RESULT_EXIT_CODE=$?
156 | if [ $ZOXIDE_RESULT_EXIT_CODE -eq 0 ]; then # zoxide result found
157 | RESULT=$(zoxide query "$1")
158 | else # no zoxide result found
159 | ls "$1" &>/dev/null
160 | LS_EXIT_CODE=$?
161 | if [ $LS_EXIT_CODE -eq 0 ]; then # directory found
162 | RESULT=$1
163 | else # no directory found
164 | echo "No directory found."
165 | exit 1
166 | fi
167 | fi
168 | fi
169 | else # argument not provided
170 | case $T_RUNTYPE in
171 | attached)
172 | if [[ -z $FZF_TMUX_OPTS ]]; then
173 | FZF_TMUX_OPTS="-p 53%,58%"
174 | fi
175 |
176 | RESULT=$(
177 | (get_fzf_results) | fzf-tmux \
178 | --bind "$FIND_BIND" \
179 | --bind "$SESSION_BIND" \
180 | --bind "$TAB_BIND" \
181 | --bind "$ZOXIDE_BIND" \
182 | --border-label "$BORDER_LABEL" \
183 | --header "$HEADER" \
184 | --no-sort \
185 | --prompt "$PROMPT" \
186 | $FZF_TMUX_OPTS
187 | )
188 | ;;
189 | detached)
190 | RESULT=$(
191 | (get_fzf_results) | fzf \
192 | --bind "$FIND_BIND" \
193 | --bind "$SESSION_BIND" \
194 | --bind "$TAB_BIND" \
195 | --bind "$ZOXIDE_BIND" \
196 | --border \
197 | --border-label "$BORDER_LABEL" \
198 | --header "$HEADER" \
199 | --no-sort \
200 | --prompt "$PROMPT"
201 | )
202 | ;;
203 | serverless)
204 | RESULT=$(
205 | (get_fzf_results) | fzf \
206 | --bind "$FIND_BIND" \
207 | --bind "$TAB_BIND" \
208 | --bind "$ZOXIDE_BIND" \
209 | --border \
210 | --border-label "$BORDER_LABEL" \
211 | --header " ^x zoxide ^f find" \
212 | --no-sort \
213 | --prompt "$PROMPT"
214 | )
215 | ;;
216 | esac
217 | fi
218 |
219 | if [ "$RESULT" = "" ]; then # no result
220 | exit 0 # exit silently
221 | fi
222 |
223 | if [ $HOME_SED_SAFE -eq 0 ]; then
224 | RESULT=$(echo "$RESULT" | sed -e "s|^~/|$HOME/|") # get real home path back
225 | fi
226 |
227 | zoxide add "$RESULT" &>/dev/null # add to zoxide database
228 |
229 | if [[ $RESULT != /* ]]; then # not folder path from zoxide result
230 | SESSION_NAME=$RESULT
231 | elif [[ $T_SESSION_USE_GIT_ROOT == 'true' ]]; then
232 | GIT_ROOT=$(git -C $RESULT rev-parse --show-toplevel 2>/dev/null) && echo $GIT_ROOT >/dev/null
233 | if [[ $? -ne 0 ]]; then # not inside git repository
234 | SESSION_NAME=$(basename "$RESULT" | tr ' .:' '_')
235 | else # is in git repository
236 | BASENAME=$(basename $GIT_ROOT)
237 | RELATIVE_PATH=${RESULT#$GIT_ROOT}
238 |
239 | # git worktree
240 | GIT_WORKTREE_ROOT=$(git -C $RESULT rev-parse --git-common-dir 2>/dev/null) && echo $GIT_WORKTREE_ROOT >/dev/null
241 | if [[ $? -eq 0 ]] && [[ ! $GIT_WORKTREE_ROOT =~ ^(\.\./)*\.git$ ]]; then # is inside git worktree
242 | GIT_WORKTREE_ROOT=$(echo $GIT_WORKTREE_ROOT | sed -E 's/(\/.git|\/.bare)$//') # remove .git or .bare suffix
243 | BASENAME=$(basename $GIT_WORKTREE_ROOT)
244 | RELATIVE_PATH=${RESULT#$GIT_WORKTREE_ROOT}
245 | fi
246 |
247 | SEPARATOR="/"
248 | FORMATTED_PATH="${RELATIVE_PATH//\//$SEPARATOR}"
249 | SESSION_NAME=$(echo $BASENAME$FORMATTED_PATH | tr ' .:' '_')
250 | fi
251 | elif [[ $T_SESSION_NAME_INCLUDE_PARENT == 'true' ]]; then
252 | SESSION_NAME=$(echo "$RESULT" | tr ' .:' '_' | awk -F "/" '{print $(NF-1)"/"$NF}')
253 | else
254 | SESSION_NAME=$(basename "$RESULT" | tr ' .:' '_')
255 | fi
256 |
257 | if [ "$T_RUNTYPE" != "serverless" ]; then
258 | SESSION=$(tmux list-sessions -F '#S' | grep "^$SESSION_NAME$") # find existing session
259 | fi
260 |
261 | if [ "$SESSION" = "" ]; then # session is missing
262 | SESSION="$SESSION_NAME"
263 | if [ -e $RESULT/.t ]; then
264 | tmux new-session -d -s "$SESSION" -c "$RESULT" $RESULT/.t # create session and run .t startup script
265 | else
266 | tmux new-session -d -s "$SESSION" -c "$RESULT" # create session
267 | fi
268 | fi
269 |
270 | case $T_RUNTYPE in # attach to session
271 | attached)
272 | tmux switch-client -t "$SESSION"
273 | ;;
274 | detached | serverless)
275 | tmux attach -t "$SESSION"
276 | ;;
277 | esac
278 |
--------------------------------------------------------------------------------
/t-smart-tmux-session-manager.tmux:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
4 |
5 | tmux_option_or_fallback() {
6 | local option_value
7 | option_value="$(tmux show-option -gqv "$1")"
8 | if [ -z "$option_value" ]; then
9 | option_value="$2"
10 | fi
11 | echo "$option_value"
12 | }
13 |
14 | tmux bind-key "$(tmux_option_or_fallback "@t-bind" "T")" run-shell "$CURRENT_DIR/bin/t"
15 |
--------------------------------------------------------------------------------