sergeant 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +1 -1
- data/lib/sergeant/modals/help.rb +114 -86
- data/lib/sergeant/rendering.rb +5 -2
- data/lib/sergeant/version.rb +1 -1
- data/lib/sergeant.rb +7 -2
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 37a2b99f4864cf2d4d4b4cffc4eb62a3c89a28216833084ad587bafd8b49c773
|
|
4
|
+
data.tar.gz: 2ddb28f7922812df52333b8bd49eef9dbec5c1e91c6d2523a72b3857fd7f9c4c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b659a1fc589acc4ee89eadbae2c3095643e494ce8e5402fd4a7f118ba79fe132d17a44002187428ea5951dd5c9b2e5355868ae86947d38416b0e3d40e29d634e
|
|
7
|
+
data.tar.gz: 1145c08b4d59cb1a47da1e8e6b42d1802a74b9ade0c6918b2fd0e43754300a4dee4db43e19e866fa939a8bf59166d44a32b641263cf6adcb6dd0aba6a1638dc2
|
data/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
8
|
|
|
9
|
+
## [1.0.11] - 2026-08-24
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- **Resizable side preview panel** - `[` / `]` shrink/grow the preview panel in 5% steps (clamped 15%-60% of terminal width), instead of a fixed 35% ratio
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
- **Help modal (`m`) now scrolls** - if the key mapping list doesn't fit the terminal height, it scrolls with `j`/`k`/arrows and shows a scrollbar, instead of silently cutting off the bottom of the list
|
|
16
|
+
- Removed the `v` key - it was bound to the exact same "preview file" action as `Enter`/`→`/`l` on a file, so it was a pure duplicate with no functionality behind it
|
|
17
|
+
|
|
18
|
+
## [1.0.10] - 2026-08-24
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
- **Help modal silently truncating its own key list** - `show_help_modal` capped its height at a hardcoded value that no longer fit all the key mappings, cutting off everything from the ownership toggle (`o`) onward - including `b`, `H`, `R`, and even `q`/`ESC` to quit - on any normal-sized terminal. The modal now sizes itself from the actual number of key mappings, so it never happens again.
|
|
22
|
+
|
|
9
23
|
## [1.0.9] - 2026-08-19
|
|
10
24
|
|
|
11
25
|
### Added
|
data/README.md
CHANGED
|
@@ -231,7 +231,6 @@ cd $(sgt --pwd /usr/local)
|
|
|
231
231
|
| `u` | Unmark all items |
|
|
232
232
|
| `n` | Create new file or directory |
|
|
233
233
|
| `e` | Edit file with $EDITOR (or nano/nvim/vim) |
|
|
234
|
-
| `v` | Preview file or archive contents |
|
|
235
234
|
|
|
236
235
|
### Other Commands
|
|
237
236
|
|
|
@@ -246,6 +245,7 @@ cd $(sgt --pwd /usr/local)
|
|
|
246
245
|
| `:` | Execute terminal command in current directory |
|
|
247
246
|
| `o` | Toggle ownership/permissions display |
|
|
248
247
|
| `P` | Toggle side preview panel |
|
|
248
|
+
| `[` / `]` | Shrink / grow side preview panel |
|
|
249
249
|
| `b` | Go to bookmark |
|
|
250
250
|
| `H` | Show recent directories history |
|
|
251
251
|
| `R` | Force refresh and clear cache |
|
data/lib/sergeant/modals/help.rb
CHANGED
|
@@ -5,110 +5,138 @@
|
|
|
5
5
|
module Sergeant
|
|
6
6
|
module Modals
|
|
7
7
|
module Help
|
|
8
|
+
HELP_LINES = [
|
|
9
|
+
'Navigation:',
|
|
10
|
+
' ↑/k - Move up',
|
|
11
|
+
' ↓/j - Move down',
|
|
12
|
+
' Enter / →/l - Open directory or preview file',
|
|
13
|
+
' ←/h - Go back to parent directory',
|
|
14
|
+
'',
|
|
15
|
+
'File Operations:',
|
|
16
|
+
' Space - Mark/unmark item',
|
|
17
|
+
' c - Copy marked items',
|
|
18
|
+
' x - Cut marked items',
|
|
19
|
+
' p - Paste copied/cut items',
|
|
20
|
+
' d - Delete marked items',
|
|
21
|
+
' r - Rename current item',
|
|
22
|
+
' u - Unmark all items',
|
|
23
|
+
' n - Create new file or directory',
|
|
24
|
+
'',
|
|
25
|
+
'View & Search:',
|
|
26
|
+
' e - Edit file ($EDITOR, nano, nvim, vim)',
|
|
27
|
+
' f - Filter current directory view',
|
|
28
|
+
' / - Search files (with fzf if available)',
|
|
29
|
+
'',
|
|
30
|
+
'Other:',
|
|
31
|
+
' : - Execute terminal command',
|
|
32
|
+
' o - Toggle ownership display',
|
|
33
|
+
' P - Toggle side preview panel',
|
|
34
|
+
' [ / ] - Shrink/grow side preview panel',
|
|
35
|
+
' b - Go to bookmark',
|
|
36
|
+
' H - Show recent directories history',
|
|
37
|
+
' R - Force refresh and clear cache',
|
|
38
|
+
' q / ESC - Quit and cd to current directory'
|
|
39
|
+
].freeze
|
|
40
|
+
|
|
41
|
+
HELP_SECTION_HEADERS = ['Navigation:', 'File Operations:', 'View & Search:', 'Other:'].freeze
|
|
42
|
+
|
|
8
43
|
def show_help_modal
|
|
9
44
|
max_y = lines
|
|
10
45
|
max_x = cols
|
|
11
46
|
|
|
12
|
-
modal_height = [
|
|
13
|
-
modal_width = [70, max_x - 4].min
|
|
14
|
-
|
|
15
|
-
|
|
47
|
+
modal_height = [HELP_LINES.length + 4, max_y - 4].min
|
|
48
|
+
modal_width = [70, max_x - 4].min
|
|
49
|
+
geometry = {
|
|
50
|
+
y: (max_y - modal_height) / 2,
|
|
51
|
+
x: (max_x - modal_width) / 2,
|
|
52
|
+
width: modal_width,
|
|
53
|
+
height: modal_height
|
|
54
|
+
}
|
|
55
|
+
visible_rows = modal_height - 4
|
|
56
|
+
max_scroll = [HELP_LINES.length - visible_rows, 0].max
|
|
57
|
+
scroll_offset = 0
|
|
58
|
+
|
|
59
|
+
loop do
|
|
60
|
+
draw_help_frame(geometry)
|
|
61
|
+
draw_help_lines(geometry, visible_rows, scroll_offset)
|
|
62
|
+
draw_help_scrollbar(geometry, visible_rows, scroll_offset, max_scroll)
|
|
16
63
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
64
|
+
refresh
|
|
65
|
+
|
|
66
|
+
case getch
|
|
67
|
+
when Curses::Key::DOWN, 'j'
|
|
68
|
+
scroll_offset = [scroll_offset + 1, max_scroll].min
|
|
69
|
+
when Curses::Key::UP, 'k'
|
|
70
|
+
scroll_offset = [scroll_offset - 1, 0].max
|
|
71
|
+
else
|
|
72
|
+
break
|
|
21
73
|
end
|
|
22
74
|
end
|
|
75
|
+
end
|
|
23
76
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
77
|
+
def draw_help_frame(geometry)
|
|
78
|
+
y = geometry[:y]
|
|
79
|
+
x = geometry[:x]
|
|
80
|
+
width = geometry[:width]
|
|
81
|
+
height = geometry[:height]
|
|
28
82
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
addstr('
|
|
32
|
-
end
|
|
33
|
-
attron(color_pair(5) | Curses::A_BOLD) do
|
|
34
|
-
addstr(' Key Mappings '.center(modal_width - 2))
|
|
83
|
+
(y..(y + height)).each do |row|
|
|
84
|
+
setpos(row, x)
|
|
85
|
+
attron(color_pair(3)) { addstr(' ' * width) }
|
|
35
86
|
end
|
|
36
|
-
|
|
37
|
-
|
|
87
|
+
|
|
88
|
+
setpos(y, x)
|
|
89
|
+
attron(color_pair(4) | Curses::A_BOLD) { addstr("┌#{'─' * (width - 2)}┐") }
|
|
90
|
+
|
|
91
|
+
setpos(y + 1, x)
|
|
92
|
+
attron(color_pair(4) | Curses::A_BOLD) { addstr('│') }
|
|
93
|
+
attron(color_pair(5) | Curses::A_BOLD) { addstr(' Key Mappings '.center(width - 2)) }
|
|
94
|
+
attron(color_pair(4) | Curses::A_BOLD) { addstr('│') }
|
|
95
|
+
|
|
96
|
+
setpos(y + 2, x)
|
|
97
|
+
attron(color_pair(4)) { addstr("├#{'─' * (width - 2)}┤") }
|
|
98
|
+
|
|
99
|
+
setpos(y + height - 1, x)
|
|
100
|
+
attron(color_pair(4) | Curses::A_BOLD) { addstr("└#{'─' * (width - 2)}┘") }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def draw_help_lines(geometry, visible_rows, scroll_offset)
|
|
104
|
+
visible_rows.times do |row|
|
|
105
|
+
line = HELP_LINES[scroll_offset + row]
|
|
106
|
+
|
|
107
|
+
setpos(geometry[:y] + 3 + row, geometry[:x])
|
|
108
|
+
attron(color_pair(4)) { addstr('│ ') }
|
|
109
|
+
draw_help_line_text(line, geometry[:width])
|
|
110
|
+
attron(color_pair(4)) { addstr(' │') }
|
|
38
111
|
end
|
|
112
|
+
end
|
|
39
113
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
addstr(
|
|
114
|
+
def draw_help_line_text(line, width)
|
|
115
|
+
unless line
|
|
116
|
+
addstr(''.ljust(width - 4))
|
|
117
|
+
return
|
|
43
118
|
end
|
|
44
119
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
' ←/h - Go back to parent directory',
|
|
51
|
-
'',
|
|
52
|
-
'File Operations:',
|
|
53
|
-
' Space - Mark/unmark item',
|
|
54
|
-
' c - Copy marked items',
|
|
55
|
-
' x - Cut marked items',
|
|
56
|
-
' p - Paste copied/cut items',
|
|
57
|
-
' d - Delete marked items',
|
|
58
|
-
' r - Rename current item',
|
|
59
|
-
' u - Unmark all items',
|
|
60
|
-
' n - Create new file or directory',
|
|
61
|
-
'',
|
|
62
|
-
'View & Search:',
|
|
63
|
-
' e - Edit file ($EDITOR, nano, nvim, vim)',
|
|
64
|
-
' v - Preview file or archive contents',
|
|
65
|
-
' f - Filter current directory view',
|
|
66
|
-
' / - Search files (with fzf if available)',
|
|
67
|
-
'',
|
|
68
|
-
'Other:',
|
|
69
|
-
' : - Execute terminal command',
|
|
70
|
-
' o - Toggle ownership display',
|
|
71
|
-
' P - Toggle side preview panel',
|
|
72
|
-
' b - Go to bookmark',
|
|
73
|
-
' H - Show recent directories history',
|
|
74
|
-
' R - Force refresh and clear cache',
|
|
75
|
-
' q / ESC - Quit and cd to current directory'
|
|
76
|
-
]
|
|
77
|
-
|
|
78
|
-
help_lines.each_with_index do |line, idx|
|
|
79
|
-
break if idx >= modal_height - 4 # Stop if we run out of vertical space
|
|
80
|
-
|
|
81
|
-
setpos(modal_y + 3 + idx, modal_x)
|
|
82
|
-
attron(color_pair(4)) do
|
|
83
|
-
addstr('│ ')
|
|
84
|
-
end
|
|
120
|
+
display_line = if line.length > width - 4
|
|
121
|
+
"#{line[0...(width - 7)]}..."
|
|
122
|
+
else
|
|
123
|
+
line.ljust(width - 4)
|
|
124
|
+
end
|
|
85
125
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
line.ljust(modal_width - 4)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
if line.start_with?('Navigation:', 'File Operations:', 'Other:')
|
|
94
|
-
attron(color_pair(1) | Curses::A_BOLD) do
|
|
95
|
-
addstr(display_line)
|
|
96
|
-
end
|
|
97
|
-
else
|
|
98
|
-
addstr(display_line)
|
|
99
|
-
end
|
|
100
|
-
attron(color_pair(4)) do
|
|
101
|
-
addstr(' │')
|
|
102
|
-
end
|
|
126
|
+
if HELP_SECTION_HEADERS.include?(line)
|
|
127
|
+
attron(color_pair(1) | Curses::A_BOLD) { addstr(display_line) }
|
|
128
|
+
else
|
|
129
|
+
addstr(display_line)
|
|
103
130
|
end
|
|
131
|
+
end
|
|
104
132
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
133
|
+
def draw_help_scrollbar(geometry, visible_rows, scroll_offset, max_scroll)
|
|
134
|
+
return unless max_scroll.positive?
|
|
135
|
+
|
|
136
|
+
scroll_pos = ((scroll_offset.to_f / max_scroll) * (visible_rows - 1)).round.clamp(0, visible_rows - 1)
|
|
109
137
|
|
|
110
|
-
|
|
111
|
-
|
|
138
|
+
setpos(geometry[:y] + 3 + scroll_pos, geometry[:x] + geometry[:width] - 2)
|
|
139
|
+
attron(color_pair(4) | Curses::A_BOLD) { addstr('█') }
|
|
112
140
|
end
|
|
113
141
|
end
|
|
114
142
|
end
|
data/lib/sergeant/rendering.rb
CHANGED
|
@@ -15,7 +15,10 @@ module Sergeant
|
|
|
15
15
|
# both panes stay readable; below that it just doesn't fit.
|
|
16
16
|
MIN_PREVIEW_TOTAL_WIDTH = 100
|
|
17
17
|
MIN_PREVIEW_WIDTH = 24
|
|
18
|
-
|
|
18
|
+
PREVIEW_WIDTH_RATIO_DEFAULT = 0.35
|
|
19
|
+
PREVIEW_WIDTH_RATIO_MIN = 0.15
|
|
20
|
+
PREVIEW_WIDTH_RATIO_MAX = 0.6
|
|
21
|
+
PREVIEW_WIDTH_RATIO_STEP = 0.05
|
|
19
22
|
|
|
20
23
|
# Maps file_category (Sergeant::Utils) to the color pair set up in
|
|
21
24
|
# Sergeant#apply_color_theme (pairs 7-10).
|
|
@@ -50,7 +53,7 @@ module Sergeant
|
|
|
50
53
|
|
|
51
54
|
preview_enabled = @show_preview && max_x >= MIN_PREVIEW_TOTAL_WIDTH
|
|
52
55
|
if preview_enabled
|
|
53
|
-
preview_width = [(max_x *
|
|
56
|
+
preview_width = [(max_x * @preview_width_ratio).to_i, MIN_PREVIEW_WIDTH].max
|
|
54
57
|
list_width = max_x - preview_width - 1
|
|
55
58
|
else
|
|
56
59
|
preview_width = 0
|
data/lib/sergeant/version.rb
CHANGED
data/lib/sergeant.rb
CHANGED
|
@@ -46,6 +46,7 @@ class SergeantApp
|
|
|
46
46
|
|
|
47
47
|
# Side preview panel
|
|
48
48
|
@show_preview = true
|
|
49
|
+
@preview_width_ratio = Sergeant::Rendering::PREVIEW_WIDTH_RATIO_DEFAULT
|
|
49
50
|
@last_preview_path = :unset
|
|
50
51
|
@preview_kind = :empty
|
|
51
52
|
@preview_item = nil
|
|
@@ -111,10 +112,14 @@ class SergeantApp
|
|
|
111
112
|
when 'P'
|
|
112
113
|
@show_preview = !@show_preview
|
|
113
114
|
@last_preview_path = :unset
|
|
115
|
+
when '['
|
|
116
|
+
step = Sergeant::Rendering::PREVIEW_WIDTH_RATIO_STEP
|
|
117
|
+
@preview_width_ratio = [@preview_width_ratio - step, Sergeant::Rendering::PREVIEW_WIDTH_RATIO_MIN].max
|
|
118
|
+
when ']'
|
|
119
|
+
step = Sergeant::Rendering::PREVIEW_WIDTH_RATIO_STEP
|
|
120
|
+
@preview_width_ratio = [@preview_width_ratio + step, Sergeant::Rendering::PREVIEW_WIDTH_RATIO_MAX].min
|
|
114
121
|
when 'e'
|
|
115
122
|
edit_file
|
|
116
|
-
when 'v'
|
|
117
|
-
preview_file
|
|
118
123
|
when 32, ' '
|
|
119
124
|
toggle_mark
|
|
120
125
|
when 'c'
|