| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 |
- package editor
- import(
- "strings"
- "strconv"
- "slices"
- "os"
- "github.com/zyedidia/rope"
- "golang.design/x/clipboard"
- "moose/internal/buffer"
- "moose/internal/util"
- "moose/internal/about"
- )
- type ActionManager = struct {
- Common []Action
- Normal []Action
- Insert []Action
- Palette []Action
- CM ChordManager
- }
- type Action = struct {
- Bindings []Binding
- Commands []string
- AskArgs bool
- Callback func(*Model, []string)
- }
- type Binding = struct {
- Type BindingType
- Single string
- Chord []string
- }
- type BindingType int
- const (
- BindingSingle BindingType = iota
- 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{
- Commands: []string{"version"},
- Callback: func(m *Model, args []string) {
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.info:Moose version '" + about.Version + "'")
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "f12",
- },
- },
- Callback: func(m *Model, args []string) {
- m.Mode = ModeNormal
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "ctrl+q",
- },
- },
- Commands: []string{"q", "quit"},
- AskArgs: true,
- Callback: func(m *Model, args []string) {
- m.Quit()
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "ctrl+s",
- },
- },
- Commands: []string{"s", "save"},
- AskArgs: false,
- Callback: func(m *Model, args []string) {
- path := ""
- if len(args) < 1 || args[0] == "" {
- if m.BM.Current().Path == "" {
- m.Mode = ModeNormal
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.error:Missing filename argument for save")
- return
- }
- }
- if len(args) > 0 && args[0] != "" {
- m.BM.Current().Path = args[0]
- }
- path = m.BM.Current().Path
- data := []byte(m.BM.Current().String())
- err := os.WriteFile(path, data, 0644)
- if err != nil {
- m.Mode = ModeNormal
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.error:Could not save to file \"" + path + "\": " + err.Error())
- return
- }
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.info:Wrote " + strconv.Itoa(len(data)) + " bytes to \"" + path + "\"")
- return
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "ctrl+shift+s",
- },
- },
- Commands: []string{"s", "save"},
- AskArgs: true,
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "ctrl+e",
- },
- },
- Commands: []string{"e", "edit"},
- AskArgs: true,
- Callback: func(m *Model, args []string) {
- if len(args) < 1 {
- m.Mode = ModeNormal
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.error:Did not specify path for edit")
- return
- }
- content, err := os.ReadFile(args[0])
- if err != nil {
- m.Mode = ModeNormal
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.error:Could not edit file \"" + args[0] + "\": " + err.Error())
- return
- }
- m.BM.Current().Clear()
- m.BM.Current().Rope = rope.New(content)
- m.BM.Current().LI.Rebuild(m.BM.Current().Rope)
- m.BM.Current().Path = args[0]
- m.BM.Current().History = buffer.UndoStack{}
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "left",
- },
- },
- Callback: func(m *Model, args []string) {
- if m.Mode == ModePalette {
- m.BM.PaletteBuffer.MoveHoriz(-1)
- } else {
- m.BM.Current().MoveHoriz(-1)
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "right",
- },
- },
- Callback: func(m *Model, args []string) {
- if m.Mode == ModePalette {
- m.BM.PaletteBuffer.MoveHoriz(1)
- } else {
- m.BM.Current().MoveHoriz(1)
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "up",
- },
- },
- Callback: func(m *Model, args []string) {
- if m.Mode != ModePalette {
- m.BM.Current().MoveVert(-1)
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "down",
- },
- },
- Callback: func(m *Model, args []string) {
- if m.Mode != ModePalette {
- m.BM.Current().MoveVert(1)
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "shift+left",
- },
- },
- AskArgs: false,
- Callback: func(m *Model, args []string) {
- if m.Mode == ModePalette {
- m.BM.PaletteBuffer.MoveWordHoriz(-1)
- } else {
- m.BM.Current().MoveWordHoriz(-1)
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "shift+right",
- },
- },
- AskArgs: false,
- Callback: func(m *Model, args []string) {
- if m.Mode == ModePalette {
- m.BM.PaletteBuffer.MoveWordHoriz(1)
- } else {
- m.BM.Current().MoveWordHoriz(1)
- }
- },
- },
- },
- Normal: []Action{
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "z",
- },
- },
- Commands: []string{"u", "undo"},
- AskArgs: false,
- Callback: func(m *Model, args []string) {
- if m.Mode == ModePalette {
- m.BM.PaletteBuffer.Undo()
- } else {
- m.BM.Current().Undo()
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "y",
- },
- },
- Commands: []string{"r", "redo"},
- AskArgs: false,
- Callback: func(m *Model, args []string) {
- if m.Mode == ModePalette {
- m.BM.PaletteBuffer.Redo()
- } else {
- m.BM.Current().Redo()
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingChord,
- Chord: []string{"d", "d"},
- },
- },
- Callback: func(m *Model, args []string) {
- m.BM.Current().DeleteLine()
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "w",
- },
- },
- Callback: func(m *Model, args []string) {
- m.Mode = ModeWrite
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "q",
- },
- },
- Callback: func(m *Model, args []string) {
- m.Mode = ModePalette
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("/")
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "f",
- },
- },
- AskArgs: true,
- Callback: func(m *Model, args []string) {
- m.Mode = ModePalette
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("?")
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "v",
- },
- },
- Commands: []string{"p", "paste"},
- AskArgs: false,
- Callback: func(m *Model, args []string) {
- text := clipboard.Read(clipboard.FmtText)
- if string(text) != "" {
- if m.Mode == ModePalette {
- m.BM.PaletteBuffer.Insert(string(text))
- } else {
- m.BM.Current().Insert(string(text))
- }
- }
- },
- },
- },
- Insert: []Action{
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "shift+up",
- },
- },
- Commands: []string{"curup"},
- Callback: func(m *Model, args []string) {
- m.BM.Current().AddCursorVert(-1)
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "shift+down",
- },
- },
- Commands: []string{"curdown"},
- Callback: func(m *Model, args []string) {
- m.BM.Current().AddCursorVert(1)
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "esc",
- },
- },
- Commands: []string{"clrc", "clearcursors"},
- Callback: func(m *Model, args []string) {
- m.BM.Current().ClearCursors()
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "tab",
- },
- },
- Callback: func(m *Model, args []string) {
- for _ = range 4 {
- m.BM.Current().Insert(" ")
- }
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "shift+tab",
- },
- },
- Callback: func(m *Model, args []string) {
- // TODO: implement m.BM.Current().remove...
-
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "backspace",
- },
- },
- Callback: func(m *Model, args []string) {
- m.BM.Current().Delete()
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "enter",
- },
- },
- Callback: func(m *Model, args []string) {
- m.BM.Current().Insert("\n")
- },
- },
- },
- Palette: []Action{
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "backspace",
- },
- },
- Callback: func(m *Model, args []string) {
- m.BM.PaletteBuffer.Delete()
- },
- },
- Action{
- Bindings: []Binding{
- Binding{
- Type: BindingSingle,
- Single: "enter",
- },
- },
- Callback: func(m *Model, _ []string) {
- input := m.BM.PaletteBuffer.String()
- args := strings.Split(input, " ")
- if args[0] == "" {
- m.Mode = ModeNormal
- return
- }
- cmd := string([]rune(args[0])[1:])
- if strings.HasPrefix(args[0], "/") {
- for _, action := range append(m.AM.Common, append(m.AM.Normal, m.AM.Insert...)...) {
- if action.Callback == nil { continue }
- if len(action.Commands) > 0 && slices.Contains(util.StandardizeBindingsArray(action.Commands), util.StandardizeBinding(cmd)) {
- m.Mode = ModeNormal
- action.Callback(m, args[1:])
- return
- }
- }
- m.Mode = ModeNormal
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.error:Unknown command \"" + cmd + "\"")
- } else if strings.HasPrefix(args[0], "?") {
- m.Mode = ModeFind
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.error:Find mode unimplemented \"" + cmd + "\"")
- } else {
- m.Mode = ModeNormal
- m.BM.PaletteBuffer.Clear()
- m.BM.PaletteBuffer.Insert("moose.error:Unknown palette input \"" + args[0] + "\"")
- }
- },
- },
- },
- }
- }
|