Skip to content

Commit 1e9fd0b

Browse files
author
Bruno Sutic
committed
Columnize session_list when its too long
Fixes #9
1 parent 5b78604 commit 1e9fd0b

File tree

3 files changed

+96
-20
lines changed

3 files changed

+96
-20
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
has dimensions 80x25. This is the default `new-session -d` win size. Fixing
66
this by first switching to a new session (so the window is resized), then
77
pulling target pane over.
8+
- 'goto-session' feature - when session list does not fit on the screen, show it
9+
in columns
10+
- 'goto-session' - when all the sessions don't fit on the screen, the last
11+
displayed element is '...' indicating there's more sessions
812

913
### v2.1.0, 2015-01-11
1014
- add a `@` key binding for "promoting" current pane into a new session

scripts/tmux_goto_session.sh

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,8 @@ CURRENT_SCRIPT="$CURRENT_DIR/$FILE_NAME"
99
LOOP="$1"
1010
SESSION_NAME="$2"
1111

12-
# Programming Tmux is great!
13-
#
14-
# For example, take a look at the below line. It's by far the biggest hack of
15-
# my life. Essentially this should be just:
16-
# `tmux list-sessions -F "#{session_name}"`
17-
#
18-
# But that only shows the session list in the current shell, and we want a nice
19-
# display across the whole screen.
20-
# To achieve this, we wrap the above command in `tmux run-shell` like this:
21-
# `tmux run-shell 'tmux list-sessions -F "#{session_name}"'`
22-
#
23-
# This does produce the "whole screen display" effect, but it also introduces a
24-
# bug: `#{session_name}` is only expanded to the current session name, so you
25-
# get a session list where only the name of the current session is displayed.
26-
#
27-
# So we hack what is already hacked. `#{session_name}` interpolation is split
28-
# with the help of of `interpolation` variable.
29-
# Wrapper command (`tmux run-shell`) won't perform interpolation and the inner
30-
# `tmux list-sessions` command will.
3112
display_session_list() {
32-
tmux run-shell 'interpolation={session_name}; tmux list-sessions -F "#$interpolation"'
13+
tmux run-shell $CURRENT_DIR/tmux_list_sessions.sh
3314
}
3415

3516
# Starts a loop: the command is invoked until correct session name is typed,

scripts/tmux_list_sessions.sh

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#!/usr/bin/env bash
2+
3+
session_list() {
4+
tmux list-sessions -F "#{session_name}"
5+
}
6+
7+
output_height() {
8+
local list="$1"
9+
echo "$list" |
10+
wc -l |
11+
tr -d ' '
12+
}
13+
14+
# calculates required number of columns for the multi-column output
15+
get_column_number() {
16+
local output_height="$1"
17+
local pane_height="$2"
18+
local columns="$(expr $output_height / $pane_height )"
19+
if [ $(expr $output_height % $pane_height ) -gt 0 ]; then
20+
columns=$(expr $columns + 1)
21+
fi
22+
echo "$columns"
23+
}
24+
25+
get_column_width() {
26+
declare -a array=("${!1}")
27+
local width=0
28+
# searching for the longest session name
29+
for session_name in "${array[@]}"; do
30+
if [ ${#session_name} -gt $width ]; then
31+
width="${#session_name}"
32+
fi
33+
done
34+
# add some padding to the right
35+
echo $((width + 2))
36+
}
37+
38+
print_multi_column_output() {
39+
local output_height="$1"
40+
local pane_height="$2"
41+
local pane_width="$3"
42+
local columns="$(get_column_number "$output_height" "$pane_height")"
43+
eval session_array=( $(tmux list-sessions -F "'#{session_name}'") )
44+
local width="$(get_column_width session_array[@])"
45+
46+
# limit number of displayed columns
47+
local max_columns=$(( $((pane_width + 2)) / $width))
48+
if [ $columns -gt $max_columns ]; then
49+
# there's more columns than it fits on the display
50+
columns="$max_columns"
51+
# last displayed element indicates there's more
52+
session_array[$((pane_height * columns - 1))]="..."
53+
fi
54+
55+
# Composing a string that prints variable number of columns.
56+
# Example print_string for 2 columns:
57+
# printf "%-17s %s\n" "${session_array[$index]}" "${session_array[$((index + 54 ))]}"
58+
local first_arg=''
59+
local arg_list=''
60+
local i=1
61+
while [ $i -lt $columns ]; do
62+
first_arg+="%-${width}s"
63+
arg_list+=" \"\${session_array[\$((index + $((i * $pane_height)) ))]}\""
64+
i=$((i + 1))
65+
done
66+
67+
local print_string=''
68+
print_string+='printf "'
69+
print_string+=$first_arg
70+
print_string+='%s\n" "${session_array[$index]}"'
71+
print_string+=$arg_list
72+
73+
local index=0
74+
while [ $index -lt $pane_height ]; do
75+
eval "$print_string"
76+
index=$((index + 1))
77+
done
78+
}
79+
80+
main() {
81+
local pane_height=$(tmux display-message -p -F "#{pane_height}")
82+
local pane_width=$(tmux display-message -p -F "#{pane_width}")
83+
local session_list="$(session_list)"
84+
local output_height=$(output_height "$session_list")
85+
if [ $output_height -gt $pane_height ]; then
86+
print_multi_column_output "$output_height" "$pane_height" "$pane_width"
87+
else
88+
echo "$session_list"
89+
fi
90+
}
91+
main

0 commit comments

Comments
 (0)