Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[keys] use prettykeys internally for input bindings and other getkeystroke uses #2594

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 40 additions & 44 deletions visidata/_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,50 +227,50 @@ def handle_key(self, ch:str, scr) -> bool:
v = self.value

if ch == '': return False
elif ch == 'KEY_IC': self.insert_mode = not self.insert_mode
elif ch == '^A' or ch == 'KEY_HOME': i = 0
elif ch == '^B' or ch == 'KEY_LEFT': i -= 1
elif ch in ('^C', '^Q', '^['): raise EscapeException(ch)
elif ch == '^D' or ch == 'KEY_DC': v = delchar(v, i)
elif ch == '^E' or ch == 'KEY_END': i = len(v)
elif ch == '^F' or ch == 'KEY_RIGHT': i += 1
elif ch == '^G':
elif ch == 'Ins': self.insert_mode = not self.insert_mode
elif ch == 'Ctrl+A' or ch == 'Home': i = 0
elif ch == 'Ctrl+B' or ch == 'Left': i -= 1
elif ch in ('Ctrl+C', 'Ctrl+Q', 'Ctrl+['): raise EscapeException(ch)
elif ch == 'Ctrl+D' or ch == 'Del': v = delchar(v, i)
elif ch == 'Ctrl+E' or ch == 'End': i = len(v)
elif ch == 'Ctrl+F' or ch == 'Right': i += 1
elif ch == 'Ctrl+G':
vd.cycleSidebar()
return False # not considered a first keypress
elif ch in ('^H', 'KEY_BACKSPACE', '^?'): i -= 1; v = delchar(v, i)
elif ch == '^I': v, i = self.completion(v, i, +1)
elif ch == 'KEY_BTAB': v, i = self.completion(v, i, -1)
elif ch in ['^J', '^M']: return True # ENTER to accept value
elif ch == '^K': v = v[:i] # ^Kill to end-of-line
elif ch == '^N':
elif ch in ('Ctrl+H', 'Bksp', 'Ctrl+?'): i -= 1; v = delchar(v, i)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got "no command for Ctrl+?" when I typed Backspace

elif ch == 'Tab': v, i = self.completion(v, i, +1)
elif ch == 'Shift+Tab': v, i = self.completion(v, i, -1)
elif ch == 'Enter': return True # ENTER to accept value
elif ch == 'Ctrl+K': v = v[:i] # Ctrl+Kill to end-of-line
elif ch == 'Ctrl+N':
c = ''
while not c:
c = vd.getkeystroke(scr)
c = vd.prettykeys(c)
i += len(c)
v += c
elif ch == '^O':
elif ch == 'Ctrl+O':
edit_v = vd.launchExternalEditor(v)
if self.value == '' and edit_v == '':
# if a cell has a value of None, keep it when the editor exits with no change
raise EscapeException(ch)
else:
self.value = edit_v
return True
elif ch == '^R': v = self.orig_value # ^Reload initial value
elif ch == '^T': v = delchar(splice(v, i-2, v[i-1:i]), i) # swap chars
elif ch == '^U': v = v[i:]; i = 0 # clear to beginning
elif ch == '^V': v = splice(v, i, until_get_wch(scr)); i += 1 # literal character
elif ch == '^W': j = find_nonword(v, 0, i-1, -1); v = v[:j+1] + v[i:]; i = j+1 # erase word
elif ch == '^Y': v = splice(v, i, str(vd.memory.clipval))
elif ch == '^Z': vd.suspend()
elif ch == 'Ctrl+R': v = self.orig_value # Ctrl+Reload initial value
elif ch == 'Ctrl+T': v = delchar(splice(v, i-2, v[i-1:i]), i) # swap chars
elif ch == 'Ctrl+U': v = v[i:]; i = 0 # clear to beginning
elif ch == 'Ctrl+V': v = splice(v, i, until_get_wch(scr)); i += 1 # literal character
elif ch == 'Ctrl+W': j = find_nonword(v, 0, i-1, -1); v = v[:j+1] + v[i:]; i = j+1 # erase word
elif ch == 'Ctrl+Y': v = splice(v, i, str(vd.memory.clipval))
elif ch == 'Ctrl+Z': vd.suspend()
# CTRL+arrow
elif ch == 'kLFT5': i = find_nonword(v, 0, i-1, -1)+1; # word left
elif ch == 'kRIT5': i = find_nonword(v, i+1, len(v)-1, +1)+1; # word right
elif ch == 'kUP5': pass
elif ch == 'kDN5': pass
elif self.history and ch == 'KEY_UP': v, i = self.prev_history(v, i)
elif self.history and ch == 'KEY_DOWN': v, i = self.next_history(v, i)
elif ch == 'Ctrl+Left': i = find_nonword(v, 0, i-1, -1)+1; # word left
elif ch == 'Ctrl+Right': i = find_nonword(v, i+1, len(v)-1, +1)+1; # word right
elif ch == 'Ctrl+Up': pass
elif ch == 'Ctrl+Down': pass
elif self.history and ch == 'Up': v, i = self.prev_history(v, i)
elif self.history and ch == 'Down': v, i = self.next_history(v, i)
elif len(ch) > 1: pass
else:
if self.first_action:
Expand Down Expand Up @@ -481,12 +481,10 @@ def _drawPrompt(val):
updater=_drawPrompt,
record=False,
bindings={
'KEY_BTAB': change_input(-1),
'^I': change_input(+1),
'KEY_SR': change_input(-1),
'KEY_SF': change_input(+1),
'kUP': change_input(-1),
'kDN': change_input(+1),
'Shift+Tab': change_input(-1),
'Tab': change_input(+1),
'Shift+Up': change_input(-1),
'Shift+Down': change_input(+1),
})
break
except ChangeInput as e:
Expand Down Expand Up @@ -623,21 +621,19 @@ def editCell(self, vcolidx=None, rowidx=None, value=None, **kwargs):
value = value or col.getDisplayValue(self.rows[self.cursorRowIndex])

bindings={
'kUP': acceptThenFunc('go-up', 'rename-col' if rowidx < 0 else 'edit-cell'),
'KEY_SR': acceptThenFunc('go-up', 'rename-col' if rowidx < 0 else 'edit-cell'),
'kDN': acceptThenFunc('go-down', 'rename-col' if rowidx < 0 else 'edit-cell'),
'KEY_SF': acceptThenFunc('go-down', 'rename-col' if rowidx < 0 else 'edit-cell'),
'KEY_SRIGHT': acceptThenFunc('go-right', 'rename-col' if rowidx < 0 else 'edit-cell'),
'KEY_SLEFT': acceptThenFunc('go-left', 'rename-col' if rowidx < 0 else 'edit-cell'),
'^I': acceptThenFunc('go-right', 'rename-col' if rowidx < 0 else 'edit-cell'),
'KEY_BTAB': acceptThenFunc('go-left', 'rename-col' if rowidx < 0 else 'edit-cell'),
'Shift+Up': acceptThenFunc('go-up', 'rename-col' if rowidx < 0 else 'edit-cell'),
'Shift+Down': acceptThenFunc('go-down', 'rename-col' if rowidx < 0 else 'edit-cell'),
'Shift+Right': acceptThenFunc('go-right', 'rename-col' if rowidx < 0 else 'edit-cell'),
'Shift+Left': acceptThenFunc('go-left', 'rename-col' if rowidx < 0 else 'edit-cell'),
'Tab': acceptThenFunc('go-right', 'rename-col' if rowidx < 0 else 'edit-cell'),
'Shift+Tab': acceptThenFunc('go-left', 'rename-col' if rowidx < 0 else 'edit-cell'),
}

if vcolidx >= self.nVisibleCols-1:
bindings['^I'] = acceptThenFunc('go-down', 'go-leftmost', 'edit-cell')
bindings['Tab'] = acceptThenFunc('go-down', 'go-leftmost', 'edit-cell')

if vcolidx <= 0:
bindings['KEY_BTAB'] = acceptThenFunc('go-up', 'go-rightmost', 'edit-cell')
bindings['Shift+Tab'] = acceptThenFunc('go-up', 'go-rightmost', 'edit-cell')

# update local bindings with kwargs.bindings instead of the inverse, to preserve kwargs.bindings for caller
bindings.update(kwargs.get('bindings', {}))
Expand Down
24 changes: 12 additions & 12 deletions visidata/canvas_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,18 +129,18 @@ def slide(self, rows, dx, dy):
TextCanvas.addCommand('', 'go-up', 'cursorBox.y1 -= 1')
TextCanvas.addCommand('', 'go-left', 'cursorBox.x1 -= 1')
TextCanvas.addCommand('', 'go-right', 'cursorBox.x1 += 1')
TextCanvas.addCommand('kRIT5', 'resize-cursor-wider', 'cursorBox.w += 1', 'increase cursor width by one character')
TextCanvas.addCommand('kLFT5', 'resize-cursor-thinner', 'cursorBox.w -= 1', 'decrease cursor width by one character')
TextCanvas.addCommand('kUP5', 'resize-cursor-shorter', 'cursorBox.h -= 1', 'decrease cursor height by one character')
TextCanvas.addCommand('kDN5', 'resize-cursor-taller', 'cursorBox.h += 1', 'increase cursor height by one character')
TextCanvas.addCommand('gzKEY_LEFT', 'resize-cursor-min-width', 'cursorBox.w = 1')
TextCanvas.addCommand('gzKEY_UP', 'resize-cursor-min-height', 'cursorBox.h = 1')
TextCanvas.addCommand('Ctrl+Right', 'resize-cursor-wider', 'cursorBox.w += 1', 'increase cursor width by one character')
TextCanvas.addCommand('Ctrl+Left', 'resize-cursor-thinner', 'cursorBox.w -= 1', 'decrease cursor width by one character')
TextCanvas.addCommand('Ctrl+Up', 'resize-cursor-shorter', 'cursorBox.h -= 1', 'decrease cursor height by one character')
TextCanvas.addCommand('Ctrl+Down', 'resize-cursor-taller', 'cursorBox.h += 1', 'increase cursor height by one character')
TextCanvas.addCommand('gzLeft', 'resize-cursor-min-width', 'cursorBox.w = 1')
TextCanvas.addCommand('gzUp', 'resize-cursor-min-height', 'cursorBox.h = 1')
TextCanvas.addCommand('z_', 'resize-cursor-min', 'cursorBox.h = cursorBox.w = 1')
TextCanvas.addCommand('g_', 'resize-cursor-max', 'cursorBox.x1=cursorBox.y1=0; cursorBox.h=maxY+1; cursorBox.w=maxX+1')
TextCanvas.bindkey('zKEY_RIGHT', 'resize-cursor-wider')
TextCanvas.bindkey('zKEY_LEFT', 'resize-cursor-thinner')
TextCanvas.bindkey('zKEY_UP', 'resize-cursor-shorter')
TextCanvas.bindkey('zKEY_DOWN', 'resize-cursor-taller')
TextCanvas.bindkey('zRight', 'resize-cursor-wider')
TextCanvas.bindkey('zLeft', 'resize-cursor-thinner')
TextCanvas.bindkey('zUp', 'resize-cursor-shorter')
TextCanvas.bindkey('zDown', 'resize-cursor-taller')
TextCanvas.addCommand('BUTTON1_PRESSED', 'move-cursor', 'sheet.cursorBox = CharBox(None, mouseX, mouseY, 1, 1)', 'start cursor box with left mouse button press')
TextCanvas.addCommand('BUTTON1_RELEASED', 'end-cursor', 'cursorBox.x2=mouseX+2; cursorBox.y2=mouseY+2; cursorBox.normalize()', 'end cursor box with left mouse button release')

Expand All @@ -155,8 +155,8 @@ def slide(self, rows, dx, dy):
TextCanvas.addCommand('zu', 'unselect-top-cursor', 'source.unselect(list(itercursor(n=1)))')
TextCanvas.addCommand('d', 'delete-cursor', 'source.deleteBy(lambda r,rows=cursorRows: r in rows)', 'delete first item under cursor')
TextCanvas.addCommand('gd', 'delete-selected', 'source.deleteSelected()', 'delete selected rows on source sheet')
TextCanvas.addCommand(ENTER, 'dive-cursor', 'vs=copy(source); vs.rows=cursorRows; vs.source=sheet; vd.push(vs)', 'dive into source rows under cursor')
TextCanvas.addCommand('g'+ENTER, 'dive-selected', 'vd.push(type(source)(source=sheet, rows=source.selectedRows))', 'dive into selected source rows')
TextCanvas.addCommand('Enter', 'dive-cursor', 'vs=copy(source); vs.rows=cursorRows; vs.source=sheet; vd.push(vs)', 'dive into source rows under cursor')
TextCanvas.addCommand('gEnter', 'dive-selected', 'vd.push(type(source)(source=sheet, rows=source.selectedRows))', 'dive into selected source rows')

TextCanvas.addCommand('H', 'slide-left-obj', 'slide(source.selectedRows, -1, 0)', 'slide selected objects left one character')
TextCanvas.addCommand('J', 'slide-down-obj', 'slide(source.selectedRows, 0, +1)', 'slide selected objects down one character')
Expand Down
4 changes: 2 additions & 2 deletions visidata/clipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ def paste_after(sheet, rowidx):
Sheet.addCommand('gzx', 'cut-cells', 'copyCells(cursorCol, onlySelectedRows); cursorCol.setValues(onlySelectedRows, None)', 'delete (cut) contents of current column for selected rows and move them to clipboard')


Sheet.bindkey('KEY_DC', 'delete-cell'),
Sheet.bindkey('gKEY_DC', 'delete-cells'),
Sheet.bindkey('Del', 'delete-cell'),
Sheet.bindkey('gDel', 'delete-cells'),

vd.addMenuItems('''
Edit > Delete > current row > delete-row
Expand Down
12 changes: 6 additions & 6 deletions visidata/features/cmdpalette.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ def _draw_palette(value):

navailitems = min(len(palrows), nitems)

bindings['^I'] = lambda *args: tab(1, navailitems) or args
bindings['KEY_BTAB'] = lambda *args: tab(-1, navailitems) or args
bindings['Ctrl+I'] = lambda *args: tab(1, navailitems) or args
bindings['Shift+Tab'] = lambda *args: tab(-1, navailitems) or args

for i in range(nitems-len(palrows)):
palrows.append((None, None))
Expand All @@ -132,16 +132,16 @@ def _draw_palette(value):
if not topitem: return
if multiple:
bindings[' '] = partial(add_to_input, value=topitem[value_key])
bindings['^J'] = partial(accept_input_if_subset, value=topitem[value_key])
bindings['Enter'] = partial(accept_input_if_subset, value=topitem[value_key])
else:
bindings['^J'] = partial(accept_input, value=topitem[value_key])
bindings['Enter'] = partial(accept_input, value=topitem[value_key])
elif item and i == tabitem:
if not item: return
if multiple:
bindings['^J'] = partial(accept_input_if_subset, value=item[value_key])
bindings['Enter'] = partial(accept_input_if_subset, value=item[value_key])
bindings[' '] = partial(add_to_input, value=item[value_key])
else:
bindings['^J'] = partial(accept_input, value=item[value_key])
bindings['Enter'] = partial(accept_input, value=item[value_key])
attr = colors.color_menu_spec

match_summary = formatter(m, item, trigger_key) if item else ' '
Expand Down
2 changes: 1 addition & 1 deletion visidata/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ def run(self, scr):

while True:
k = vd.getkeystroke(self.scrForm, self)
if k in ['^C', '^Q', '^[', 'q']:
if k in ['Ctrl+C', 'Ctrl+Q', 'Ctrl+[', 'q']:
return {}
if curinput and k in curinput.keystrokes:
return {curinput.input: k}
Expand Down
8 changes: 4 additions & 4 deletions visidata/help.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,10 +168,10 @@ def openManPage(vd):
BaseSheet.addCommand('z^H', 'help-commands', 'vd.push(HelpSheet(name + "_commands", source=sheet, revbinds={}))', 'list commands and keybindings available on current sheet')
BaseSheet.addCommand('gz^H', 'help-commands-all', 'vd.push(HelpSheet("all_commands", source=None, revbinds={}))', 'list commands and keybindings for all sheet types')

BaseSheet.bindkey('KEY_F(1)', 'sysopen-help')
BaseSheet.bindkey('zKEY_F(1)', 'help-commands')
BaseSheet.bindkey('zKEY_BACKSPACE', 'help-commands')
BaseSheet.bindkey('gKEY_BACKSPACE', 'sysopen-help')
BaseSheet.bindkey('F1', 'sysopen-help')
BaseSheet.bindkey('zF1', 'help-commands')
BaseSheet.bindkey('zBksp', 'help-commands')
BaseSheet.bindkey('gBksp', 'sysopen-help')

HelpSheet.addCommand(None, 'exec-command', 'quit(sheet); draw_all(); activeStack[0].execCommand(cursorRow.longname)', 'execute command on undersheet')
BaseSheet.addCommand(None, 'open-tutorial-visidata', 'launchBrowser("https://jsvine.github.io/intro-to-visidata/")', 'open https://jsvine.github.io/intro-to-visidata/')
Expand Down
1 change: 0 additions & 1 deletion visidata/mainloop.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,6 @@ def mainloop(vd, scr):
vd.warning('duplicate prefix: ' + keystroke)
vd.keystrokes = ''
else:
keystroke = vd.prettykeys(keystroke)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the removal of this line that broke spacebar (' ') and the shift keys!

vd.keystrokes += keystroke

vd.drawRightStatus(sheet._scr, sheet) # visible for commands that wait for input
Expand Down
16 changes: 8 additions & 8 deletions visidata/menu.py
Original file line number Diff line number Diff line change
Expand Up @@ -442,15 +442,15 @@ def _clickedDuringMenu():

currentItem = sheet.getMenuItem()

if k == '^[': # ESC
if k == 'Ctrl+[': # ESC
nEscapes += 1 #1470
if nEscapes > 1:
return
continue
else:
nEscapes = 0

if k in ['^C', '^Q', 'q', '^H', 'KEY_BACKSPACE']:
if k in ['Ctrl+C', 'Ctrl+Q', 'q', 'Ctrl+H', 'Bksp']:
return

elif k in ['KEY_MOUSE']:
Expand All @@ -460,25 +460,25 @@ def _clickedDuringMenu():
elif r == 'doit':
break

elif k in ['KEY_RIGHT', 'l']:
elif k in ['Right', 'l']:
if currentItem.menus and sheet.activeMenuItems[1] != 0: # not first item
sheet.activeMenuItems.append(0)
else:
sheet.activeMenuItems = [sheet.activeMenuItems[0]+1, 0]

elif k in ['KEY_LEFT', 'h']:
elif k in ['Left', 'h']:
if len(sheet.activeMenuItems) > 2:
sheet.activeMenuItems.pop(-1)
else:
sheet.activeMenuItems = [sheet.activeMenuItems[0]-1, 0]

elif k in ['KEY_DOWN', 'j']:
elif k in ['Down', 'j']:
sheet.activeMenuItems[-1] += 1

elif k in ['KEY_UP', 'k']:
elif k in ['Up', 'k']:
sheet.activeMenuItems[-1] -= 1

elif k in [ENTER, ' ', '^J', '^M']:
elif k in ['Enter', ' ']:
if currentItem.menus:
sheet.activeMenuItems.append(0)
else:
Expand Down Expand Up @@ -512,6 +512,6 @@ def _clickedDuringMenu():
BaseSheet.addCommand('Alt+s', 'menu-system', 'pressMenu("System")', '')
BaseSheet.addCommand('Alt+h', 'menu-help', 'pressMenu("Help")', 'open the Help menu')
BaseSheet.bindkey('Ctrl+H', 'menu-help')
BaseSheet.bindkey('KEY_BACKSPACE', 'menu-help')
BaseSheet.bindkey('Bksp', 'menu-help')

vd.addGlobals({'Menu': Menu})
Loading
Loading