diff --git a/tools/cmd/diff/main.go b/tools/cmd/diff/main.go index 02f004616..ff7c4c4e1 100644 --- a/tools/cmd/diff/main.go +++ b/tools/cmd/diff/main.go @@ -150,6 +150,7 @@ func main(_ *cli.Command, opts_ *Options, args []string) (rc int, err error) { return "" } lp.OnResize = h.on_resize + lp.OnKeyEvent = h.on_key_event err = lp.Run() if err != nil { return 1, err diff --git a/tools/cmd/diff/ui.go b/tools/cmd/diff/ui.go index 4530129e3..49b0d3189 100644 --- a/tools/cmd/diff/ui.go +++ b/tools/cmd/diff/ui.go @@ -4,8 +4,10 @@ package diff import ( "fmt" + "kitty/tools/config" "kitty/tools/tui/graphics" "kitty/tools/tui/loop" + "strconv" ) var _ = fmt.Print @@ -31,6 +33,8 @@ type AsyncResult struct { type Handler struct { async_results chan AsyncResult + shortcut_tracker config.ShortcutTracker + pending_keys []string left, right string collection *Collection diff_map map[string]*Patch @@ -54,6 +58,7 @@ var DebugPrintln func(...any) func (self *Handler) initialize() { DebugPrintln = self.lp.DebugPrintln + self.pending_keys = make([]string, 0, 4) self.current_context_count = opts.Context if self.current_context_count < 0 { self.current_context_count = int(conf.Num_context_lines) @@ -196,3 +201,30 @@ func (self *Handler) draw_screen() { } } + +func (self *Handler) on_key_event(ev *loop.KeyEvent) error { + ac := self.shortcut_tracker.Match(ev, conf.KeyboardShortcuts) + if ac != nil { + return self.dispatch_action(ac.Name, ac.Args) + } + return nil +} + +func (self *Handler) scroll_lines(amt int) { + // TODO: Implement me +} + +func (self *Handler) dispatch_action(name, args string) error { + switch name { + case `quit`: + self.lp.Quit(0) + case `scroll_by`: + amt, err := strconv.Atoi(args) + if err == nil { + self.scroll_lines(amt) + } else { + self.lp.Beep() + } + } + return nil +} diff --git a/tools/config/utils.go b/tools/config/utils.go index 5fc7d24e5..75190afd4 100644 --- a/tools/config/utils.go +++ b/tools/config/utils.go @@ -4,6 +4,7 @@ package config import ( "fmt" + "kitty/tools/tui/loop" "kitty/tools/utils" "regexp" "strconv" @@ -253,3 +254,37 @@ func ParseMap(val string) (*KeyAction, error) { action_name, action_args, _ := strings.Cut(action, " ") return &KeyAction{Name: action_name, Args: action_args, Normalized_keys: NormalizeShortcuts(spec)}, nil } + +type ShortcutTracker struct { + partial_matches []*KeyAction + partial_num_consumed int +} + +func (self *ShortcutTracker) Match(ev *loop.KeyEvent, all_actions []*KeyAction) *KeyAction { + if self.partial_num_consumed > 0 { + ev.Handled = true + self.partial_matches = utils.Filter(self.partial_matches, func(ac *KeyAction) bool { + return self.partial_num_consumed < len(ac.Normalized_keys) && ev.MatchesPressOrRepeat(ac.Normalized_keys[self.partial_num_consumed]) + }) + if len(self.partial_matches) == 0 { + self.partial_num_consumed = 0 + return nil + } + } else { + self.partial_matches = utils.Filter(all_actions, func(ac *KeyAction) bool { + return ev.MatchesPressOrRepeat(ac.Normalized_keys[0]) + }) + if len(self.partial_matches) == 0 { + return nil + } + ev.Handled = true + } + self.partial_num_consumed++ + for _, x := range self.partial_matches { + if self.partial_num_consumed >= len(x.Normalized_keys) { + self.partial_num_consumed = 0 + return x + } + } + return nil +}