Keymap stacks work as expected with proper fallthrough emulating normal/insert

This commit is contained in:
Joseph Ferano 2023-11-09 11:06:12 +07:00
parent 7228bf3201
commit e8ea80ff66
3 changed files with 34 additions and 45 deletions

View File

@ -7,7 +7,10 @@ kb('insert', 'up' , cursor_go_up)
kb('insert', 'down' , cursor_go_down)
kb('insert', 'C-e' , cursor_go_line_end)
kb('insert', 'C-a' , cursor_go_line_beginning)
kb('insert', 'escape', lambda: push(keymappings['normal']))
kb('insert', 'escape', lambda: keymap_push(keymappings['normal']))
kb('insert', 'backspace', buffer_delete_character_under_cursor)
kb('insert', 'delete', buffer_delete_next_character)
kb('insert', 'return', buffer_newline_at_pos)
kb('normal', 'i', keymap_pop)
kb('normal', 'H', cursor_go_buffer_beginning)
kb('normal', 'L', cursor_go_buffer_end)

65
fide.py
View File

@ -117,50 +117,35 @@ def main():
curr_line = buffer_line_current(current_buffer)
kb_to_test = Keybinding(pg.key.name(event.key), event.mod)
# print(kb_to_test, event.key, pg.key.name(event.key))
passthrough = True
for i in range(len(keymap_stack) - 1, -1, -1):
keymap = keymap_stack[i]
# check if a modifier is pressed
if kb_to_test in keymap.mapping:
keymap.mapping[kb_to_test]()
# if mod_key and event.unicode:
# print(mod_key + pg.key.name(event.key))
# print(pg.key.name(event.key))
# if event.mod == 64: # Right Ctrl
# # this is inefficient, might as well just pass the mod number
# # and make the mapping mod_num -> config_key
# mod_key = translate_keyname('left ctrl')
# if event.unicode:
# # print(mod_key, event.key, event.unicode)
# key = mod_key + pg.key.name(event.key)
# if key in keymappings[current_buffer.mode]:
# keymappings[current_buffer.mode][key]()
# # if event.key == pg.K_e:
# # cursor_go_line_end()
# # if event.key == pg.K_a:
# # cursor_go_line_beginning()
# if event.key == pg.K_RETURN:
# src = buffer_line_current(current_buffer).piece.get_text()
# # try:
# # eval(src[3:])
# # except:
# # print('error evaluating line: ' + src[3:])
# console.runsource(src[3:])
# elif pg.key.name(event.key) == 'escape':
# pass
# elif event.key == pg.K_RETURN:
# buffer_newline_at_pos()
# elif event.key == pg.K_BACKSPACE:
# buffer_delete_character_under_cursor()
# elif event.key == pg.K_DELETE:
# buffer_delete_next_character()
# elif pg.key.name(event.key) in keymappings[current_buffer.mode]:
# keymappings[current_buffer.mode][pg.key.name(event.key)]()
# pass
# elif event.mod < 2:
# elif event.unicode:
# buffer_insert_char(event.unicode)
if not keymap.pinned:
keymap_stack.pop()
break
passthrough = False
else:
if keymap.pop_not_found:
keymap_stack.pop()
else:
print(f"{kb_to_test} not found")
if not keymap.fallthrough:
passthrough = False
break
# No keybinding found so send the directly to the buffer
# I think emacs instead binds every key to a function that sends the
# letter, we can evaluate if that's better later on
if passthrough and event.mod < 2 and event.unicode:
buffer_insert_char(event.unicode)
# if event.key == pg.K_RETURN:
# src = buffer_line_current(current_buffer).piece.get_text()
# try:
# eval(src[3:])
# except:
# print('error evaluating line: ' + src[3:])
# console.runsource(src[3:])
for i,curr_line in enumerate(current_buffer.lines):
render = text_renderer.render(curr_line.piece.get_text(), True, 'black')

View File

@ -11,7 +11,7 @@ class Keybinding:
class Keymap:
name: str
pinned: bool
passthrough: bool
fallthrough: bool
pop_not_found: bool
mapping: Dict[[int,str],Callable] = field(default_factory=dict)
@ -74,14 +74,15 @@ def parse_keybinding(keybinding: str) -> str:
modifiers |= 1
key = key.lower()
if not key.isalnum():
modifiers |= 1
key = symbol_to_num(key)
return Keybinding(key, modifiers)
keymap_stack = [
Keymap('insert', pinned=True, passthrough=False, pop_not_found=False),
Keymap('normal', pinned=True, passthrough=False, pop_not_found=False),
Keymap('insert', pinned=True, fallthrough=True, pop_not_found=False),
Keymap('normal', pinned=True, fallthrough=False, pop_not_found=False),
]
keymappings = {
@ -94,7 +95,7 @@ def kb(mode: str, binding: str, f: Callable):
keymappings[mode].mapping[b] = f
def keymap_push(keymap: Keymap):
keymap_stack.append(keymap_push)
keymap_stack.append(keymap)
def keymap_pop():
keymap_stack.pop()