Skip to content

Commit 3adcb42

Browse files
committed
feat: Add scroll position handling for cursor movement in copy-mode
1 parent e064edc commit 3adcb42

File tree

1 file changed

+38
-4
lines changed

1 file changed

+38
-4
lines changed

easymotion.py

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,18 @@ def cleanup_window():
4646
pyshell('tmux kill-window')
4747

4848
def tmux_capture_pane(pane_id):
49-
return pyshell('tmux capture-pane -p -t {}'.format(pane_id))[:-1]
49+
scroll_pos = get_scroll_position(pane_id)
50+
51+
if scroll_pos > 0:
52+
# When scrolled up, use negative numbers to capture from history
53+
# -scroll_pos is where we are in history
54+
# -(scroll_pos - curses.LINES + 1) captures one screen worth from there
55+
cmd = f'tmux capture-pane -p -S -{scroll_pos} -E -{scroll_pos - curses.LINES + 1} -t {pane_id}'
56+
else:
57+
# If not scrolled, just capture current view (default behavior)
58+
cmd = f'tmux capture-pane -p -t {pane_id}'
59+
60+
return pyshell(cmd)[:-1]
5061

5162
def fill_pane_content_with_space(pane_content, width):
5263
lines = pane_content.splitlines()
@@ -57,9 +68,25 @@ def fill_pane_content_with_space(pane_content, width):
5768
result.append(line + ' ' * padding)
5869
return '\n'.join(result)
5970

71+
def get_scroll_position(pane_id):
72+
# First check if we're in copy-mode
73+
copy_mode = pyshell(f'tmux display-message -p -t {pane_id} "#{{pane_in_mode}}"').strip()
74+
if copy_mode != "1":
75+
return 0
76+
77+
# Get scroll position only if in copy-mode
78+
scroll_pos = pyshell(f'tmux display-message -p -t {pane_id} "#{{scroll_position}}"').strip()
79+
try:
80+
return int(scroll_pos)
81+
except ValueError:
82+
return 0
83+
6084
def tmux_move_cursor(pane_id, position):
61-
pyshell('tmux copy-mode -t {id}; tmux send-keys -X -t {id} top-line; tmux send-keys -X -t {id} -N {pos} cursor-right'
62-
.format(id=pane_id, pos=position))
85+
# First ensure we're in copy mode
86+
pyshell(f'tmux copy-mode -t {pane_id}')
87+
# Move to top and then navigate to position
88+
pyshell(f'tmux send-keys -X -t {pane_id} top-line')
89+
pyshell(f'tmux send-keys -X -t {pane_id} -N {position} cursor-right')
6390

6491
def generate_hints(keys):
6592
def _generate_hints(keys):
@@ -74,6 +101,7 @@ def _generate_hints(keys):
74101

75102
def main(stdscr):
76103
pane_id = tmux_pane_id()
104+
scroll_position = get_scroll_position(pane_id)
77105
captured_pane = tmux_capture_pane(pane_id)
78106

79107
# invisible cursor
@@ -149,7 +177,13 @@ def main(stdscr):
149177
target_pos = positions[hints_dict[ch1+ch2]]
150178
line_offset = sum(len(line) + 1 for line in lines[:target_pos[0]])
151179
final_pos = line_offset + target_pos[1]
152-
tmux_move_cursor(pane_id, final_pos)
180+
181+
# Adjust for scroll position
182+
if scroll_position > 0:
183+
tmux_move_cursor(pane_id, final_pos)
184+
else:
185+
# If not scrolled, move to absolute position
186+
tmux_move_cursor(pane_id, final_pos)
153187
cleanup_window()
154188

155189
curses.wrapper(main)

0 commit comments

Comments
 (0)