Преглед изворни кода

Implement chorded keybinds

Johan Rong пре 1 месец
родитељ
комит
bb545eeb3d
4 измењених фајлова са 100 додато и 12 уклоњено
  1. 28 1
      internal/editor/action.go
  2. 66 10
      internal/editor/keyinput.go
  3. 2 1
      internal/editor/model.go
  4. 4 0
      internal/editor/render.go

+ 28 - 1
internal/editor/action.go

@@ -15,6 +15,7 @@ type ActionManager = struct {
 	Normal  []Action
 	Insert  []Action
 	Palette []Action
+	CM		ChordManager
 }
 
 type Action = struct {
@@ -36,8 +37,21 @@ const (
 	BindingChord
 )
 
+type ChordManager = struct {
+	Recording   bool
+	Recorded    []string
+}
+
+func NewChordManager() ChordManager {
+	return ChordManager{
+		Recording: false,
+		Recorded:  []string{},
+	}
+}
+
 func DefaultActionManager() ActionManager {
 	return ActionManager{
+		CM:	     NewChordManager(),
 		Common:  []Action{
 			Action{
 				Bindings: []Binding{
@@ -234,6 +248,19 @@ func DefaultActionManager() ActionManager {
 			},
 		},
 		Normal:  []Action{
+			Action{
+				Bindings: []Binding{
+					Binding{
+						Type:  BindingChord,
+						Chord: []string{"d", "d"},
+					},
+				},
+				Callback: func(m *Model, args []string) {
+					m.BM.PaletteBuffer.Clear()
+					m.BM.PaletteBuffer.Insert("moose.error:TODO: line delete not implemented yet")
+					return
+				},
+			},
 			Action{
 				Bindings: []Binding{
 					Binding{
@@ -434,7 +461,7 @@ func DefaultActionManager() ActionManager {
 						for _, action := range append(m.AM.Common, append(m.AM.Normal, m.AM.Insert...)...) {
 							if action.Callback == nil { continue }
 
-							if len(action.Command) > 0 &&  slices.Contains(util.StandardizeBindingsArray(action.Command), util.StandardizeBinding(cmd)) {
+							if len(action.Commands) > 0 &&  slices.Contains(util.StandardizeBindingsArray(action.Commands), util.StandardizeBinding(cmd)) {
 								m.Mode = ModeNormal
 								action.Callback(m, args[1:])
 								return

+ 66 - 10
internal/editor/keyinput.go

@@ -1,26 +1,82 @@
 package editor
 
 import (
-	"slices"
 	"github.com/gdamore/tcell/v3"
 	"moose/internal/util"
 )
 
 func (m *Model) HandleKeyInput(ev *tcell.EventKey) {
+	hasValidContinuingChordPath := false
+
 	for _, action := range append(m.CurrentActionSet(), m.AM.Common...) {
-		if len(action.Binding) > 0 && slices.Contains(util.StandardizeBindingsArray(action.Binding), util.StandardizeBinding(ev.Name())) {
-			if action.AskArgs == true {
-				m.Mode = ModePalette
-				m.BM.PaletteBuffer.Clear()
-				m.BM.PaletteBuffer.Insert("/" + action.Command[0] + " ")
-				return
-			}
+		for _, binding := range action.Bindings {
+			switch binding.Type {
+			case BindingSingle: 
+				if util.StandardizeBinding(binding.Single) == util.StandardizeBinding(ev.Name()) {
+					if len(action.Commands) > 0 && action.AskArgs == true {
+						m.Mode = ModePalette
+						m.BM.PaletteBuffer.Clear()
+						m.BM.PaletteBuffer.Insert("/" + action.Commands[0] + " ")
+						return
+					}
+
+					action.Callback(m, []string{})
+					return
+				}
+			case BindingChord:
+				if m.AM.CM.Recording {
+					if len(binding.Chord) > len(m.AM.CM.Recorded) {
+						matching := false
+						for i := range m.AM.CM.Recorded {
+							if m.AM.CM.Recorded[i] == binding.Chord[i] {
+								matching = true
+							} else {
+								matching = false
+								break
+							}
+						}
+
+						if matching {
+							hasValidContinuingChordPath = true
+							if binding.Chord[len(m.AM.CM.Recorded)] == util.StandardizeBinding(ev.Name()) {
+								m.AM.CM.Recorded = append(m.AM.CM.Recorded, util.StandardizeBinding(ev.Name()))
 
-			action.Callback(m, []string{})
-			return
+								if len(m.AM.CM.Recorded) == len(binding.Chord) {
+									action.Callback(m, []string{})
+									m.AM.CM = NewChordManager()
+									return
+								}
+							} else {
+								continue
+							}
+						} else {
+							continue
+						}
+					} else {
+						continue
+					}
+				} else {
+					if binding.Chord[0] == util.StandardizeBinding(ev.Name()) {
+						hasValidContinuingChordPath = true
+						m.AM.CM.Recorded = append(m.AM.CM.Recorded, util.StandardizeBinding(ev.Name()))
+
+						if len(m.AM.CM.Recorded) == len(binding.Chord) {
+							action.Callback(m, []string{})
+							m.AM.CM = NewChordManager()
+							return
+						} else {
+							m.AM.CM.Recording = true
+						}
+					}
+				}
+			}
 		}
 	}
 
+	if !hasValidContinuingChordPath {
+		m.AM.CM = NewChordManager()
+	}
+
 	if m.Mode == ModeWrite {
 		if ev.Key() == tcell.KeyRune {
 			m.BM.Current().Insert(ev.Str())

+ 2 - 1
internal/editor/model.go

@@ -12,6 +12,7 @@ type Model struct {
 	BM		   buffer.BufferManager
 	AM         ActionManager
 	ShouldQuit bool
+	DebugLog   string
 }
 
 func NewModel(screen tcell.Screen, style tcell.Style) Model {
@@ -24,7 +25,7 @@ func NewModel(screen tcell.Screen, style tcell.Style) Model {
 			CurrentIdx:    0,
 			PaletteBuffer: buffer.NewBuffer(),
 		},
-		AM:       DefaultActionManager(),
+		AM:            DefaultActionManager(),
 		ShouldQuit:    false,
 	}
 

+ 4 - 0
internal/editor/render.go

@@ -2,6 +2,7 @@ package editor
 
 import (
 	"strings"
+	"strconv"
 	"fmt"
 	"moose/internal/buffer"
 	"github.com/gdamore/tcell/v3/color"
@@ -113,6 +114,9 @@ func (m Model) Render() {
 	}
 
 	m.Screen.PutStrStyled(sWidth - (len(modeStr) + 1), maxHeight, strings.ToUpper(modeStr), m.Style.Background(color.Black))
+	
+	logStr := m.DebugLog + ", " + strings.Join(m.AM.CM.Recorded, "+") + ", " + strconv.FormatBool(m.AM.CM.Recording)
+	m.Screen.PutStrStyled(1, maxHeight, logStr, m.Style.Background(color.Black))
 
 	if m.Mode == ModePalette {
 		m.Screen.PutStrStyled(0, maxHeight + 1, m.BM.PaletteBuffer.String(), m.Style)