]> git.lizzy.rs Git - micro.git/blobdiff - cmd/micro/messenger.go
Code optimisation (#1117)
[micro.git] / cmd / micro / messenger.go
index 05c0bef3bc97a6f07bddd6a29ea96f53fec31ba5..b55557af290832cbea0a799e47f2d8fd8ada3ce2 100644 (file)
@@ -223,6 +223,7 @@ func (m *Messenger) LetterPrompt(prompt string, responses ...rune) (rune, bool)
        }
 }
 
+// Completion represents a type of completion
 type Completion int
 
 const (
@@ -260,6 +261,11 @@ func (m *Messenger) Prompt(prompt, placeholder, historyType string, completionTy
                event := <-events
 
                switch e := event.(type) {
+               case *tcell.EventResize:
+                       for _, t := range tabs {
+                               t.Resize()
+                       }
+                       RedrawAll()
                case *tcell.EventKey:
                        switch e.Key() {
                        case tcell.KeyCtrlQ, tcell.KeyCtrlC, tcell.KeyEscape:
@@ -322,7 +328,7 @@ func (m *Messenger) Prompt(prompt, placeholder, historyType string, completionTy
                                        chosen = chosen + CommonSubstring(suggestions...)
                                }
 
-                               if chosen != "" {
+                               if len(suggestions) != 0 && chosen != "" {
                                        m.response = shellwords.Join(append(args[:len(args)-1], chosen)...)
                                        m.cursorx = Count(m.response)
                                }
@@ -332,7 +338,7 @@ func (m *Messenger) Prompt(prompt, placeholder, historyType string, completionTy
                m.HandleEvent(event, m.history[historyType])
 
                m.Clear()
-               for _, v := range tabs[curTab].views {
+               for _, v := range tabs[curTab].Views {
                        v.Display()
                }
                DisplayTabs()
@@ -348,62 +354,160 @@ func (m *Messenger) Prompt(prompt, placeholder, historyType string, completionTy
        return response, canceled
 }
 
+// UpHistory fetches the previous item in the history
+func (m *Messenger) UpHistory(history []string) {
+       if m.historyNum > 0 {
+               m.historyNum--
+               m.response = history[m.historyNum]
+               m.cursorx = Count(m.response)
+       }
+}
+
+// DownHistory fetches the next item in the history
+func (m *Messenger) DownHistory(history []string) {
+       if m.historyNum < len(history)-1 {
+               m.historyNum++
+               m.response = history[m.historyNum]
+               m.cursorx = Count(m.response)
+       }
+}
+
+// CursorLeft moves the cursor one character left
+func (m *Messenger) CursorLeft() {
+       if m.cursorx > 0 {
+               m.cursorx--
+       }
+}
+
+// CursorRight moves the cursor one character right
+func (m *Messenger) CursorRight() {
+       if m.cursorx < Count(m.response) {
+               m.cursorx++
+       }
+}
+
+// Start moves the cursor to the start of the line
+func (m *Messenger) Start() {
+       m.cursorx = 0
+}
+
+// End moves the cursor to the end of the line
+func (m *Messenger) End() {
+       m.cursorx = Count(m.response)
+}
+
+// Backspace deletes one character
+func (m *Messenger) Backspace() {
+       if m.cursorx > 0 {
+               m.response = string([]rune(m.response)[:m.cursorx-1]) + string([]rune(m.response)[m.cursorx:])
+               m.cursorx--
+       }
+}
+
+// Paste pastes the clipboard
+func (m *Messenger) Paste() {
+       clip, _ := clipboard.ReadAll("clipboard")
+       m.response = Insert(m.response, m.cursorx, clip)
+       m.cursorx += Count(clip)
+}
+
+// WordLeft moves the cursor one word to the left
+func (m *Messenger) WordLeft() {
+       response := []rune(m.response)
+       m.CursorLeft()
+       if m.cursorx <= 0 {
+               return
+       }
+       for IsWhitespace(response[m.cursorx]) {
+               if m.cursorx <= 0 {
+                       return
+               }
+               m.CursorLeft()
+       }
+       m.CursorLeft()
+       for IsWordChar(string(response[m.cursorx])) {
+               if m.cursorx <= 0 {
+                       return
+               }
+               m.CursorLeft()
+       }
+       m.CursorRight()
+}
+
+// WordRight moves the cursor one word to the right
+func (m *Messenger) WordRight() {
+       response := []rune(m.response)
+       if m.cursorx >= len(response) {
+               return
+       }
+       for IsWhitespace(response[m.cursorx]) {
+               m.CursorRight()
+               if m.cursorx >= len(response) {
+                       m.CursorRight()
+                       return
+               }
+       }
+       m.CursorRight()
+       if m.cursorx >= len(response) {
+               return
+       }
+       for IsWordChar(string(response[m.cursorx])) {
+               m.CursorRight()
+               if m.cursorx >= len(response) {
+                       return
+               }
+       }
+}
+
+// DeleteWordLeft deletes one word to the left
+func (m *Messenger) DeleteWordLeft() {
+       m.WordLeft()
+       m.response = string([]rune(m.response)[:m.cursorx])
+}
+
 // HandleEvent handles an event for the prompter
 func (m *Messenger) HandleEvent(event tcell.Event, history []string) {
        switch e := event.(type) {
        case *tcell.EventKey:
-               if e.Key() != tcell.KeyRune || e.Modifiers() != 0 {
-                       for key, actions := range bindings {
-                               if e.Key() == key.keyCode {
-                                       if e.Key() == tcell.KeyRune {
-                                               if e.Rune() != key.r {
-                                                       continue
-                                               }
-                                       }
-                                       if e.Modifiers() == key.modifiers {
-                                               for _, action := range actions {
-                                                       funcName := FuncName(action)
-                                                       switch funcName {
-                                                       case "main.(*View).CursorUp":
-                                                               if m.historyNum > 0 {
-                                                                       m.historyNum--
-                                                                       m.response = history[m.historyNum]
-                                                                       m.cursorx = Count(m.response)
-                                                               }
-                                                       case "main.(*View).CursorDown":
-                                                               if m.historyNum < len(history)-1 {
-                                                                       m.historyNum++
-                                                                       m.response = history[m.historyNum]
-                                                                       m.cursorx = Count(m.response)
-                                                               }
-                                                       case "main.(*View).CursorLeft":
-                                                               if m.cursorx > 0 {
-                                                                       m.cursorx--
-                                                               }
-                                                       case "main.(*View).CursorRight":
-                                                               if m.cursorx < Count(m.response) {
-                                                                       m.cursorx++
-                                                               }
-                                                       case "main.(*View).CursorStart", "main.(*View).StartOfLine":
-                                                               m.cursorx = 0
-                                                       case "main.(*View).CursorEnd", "main.(*View).EndOfLine":
-                                                               m.cursorx = Count(m.response)
-                                                       case "main.(*View).Backspace":
-                                                               if m.cursorx > 0 {
-                                                                       m.response = string([]rune(m.response)[:m.cursorx-1]) + string([]rune(m.response)[m.cursorx:])
-                                                                       m.cursorx--
-                                                               }
-                                                       case "main.(*View).Paste":
-                                                               clip, _ := clipboard.ReadAll("clipboard")
-                                                               m.response = Insert(m.response, m.cursorx, clip)
-                                                               m.cursorx += Count(clip)
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
                switch e.Key() {
+               case tcell.KeyCtrlA:
+                       m.Start()
+               case tcell.KeyCtrlE:
+                       m.End()
+               case tcell.KeyUp:
+                       m.UpHistory(history)
+               case tcell.KeyDown:
+                       m.DownHistory(history)
+               case tcell.KeyLeft:
+                       if e.Modifiers() == tcell.ModCtrl {
+                               m.Start()
+                       } else if e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {
+                               m.WordLeft()
+                       } else {
+                               m.CursorLeft()
+                       }
+               case tcell.KeyRight:
+                       if e.Modifiers() == tcell.ModCtrl {
+                               m.End()
+                       } else if e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {
+                               m.WordRight()
+                       } else {
+                               m.CursorRight()
+                       }
+               case tcell.KeyBackspace2, tcell.KeyBackspace:
+                       if e.Modifiers() == tcell.ModCtrl || e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {
+                               m.DeleteWordLeft()
+                       } else {
+                               m.Backspace()
+                       }
+               case tcell.KeyCtrlW:
+                       m.DeleteWordLeft()
+               case tcell.KeyCtrlV:
+                       m.Paste()
+               case tcell.KeyCtrlF:
+                       m.WordRight()
+               case tcell.KeyCtrlB:
+                       m.WordLeft()
                case tcell.KeyRune:
                        m.response = Insert(m.response, m.cursorx, string(e.Rune()))
                        m.cursorx++
@@ -500,11 +604,11 @@ func (m *Messenger) Display() {
 func (m *Messenger) LoadHistory() {
        if GetGlobalOption("savehistory").(bool) {
                file, err := os.Open(configDir + "/buffers/history")
+               defer file.Close()
                var decodedMap map[string][]string
                if err == nil {
                        decoder := gob.NewDecoder(file)
                        err = decoder.Decode(&decodedMap)
-                       file.Close()
 
                        if err != nil {
                                m.Error("Error loading history:", err)
@@ -529,11 +633,12 @@ func (m *Messenger) SaveHistory() {
                // Don't save history past 100
                for k, v := range m.history {
                        if len(v) > 100 {
-                               m.history[k] = v[0:100]
+                               m.history[k] = v[len(m.history[k])-100:]
                        }
                }
 
                file, err := os.Create(configDir + "/buffers/history")
+               defer file.Close()
                if err == nil {
                        encoder := gob.NewEncoder(file)
 
@@ -542,7 +647,6 @@ func (m *Messenger) SaveHistory() {
                                m.Error("Error saving history:", err)
                                return
                        }
-                       file.Close()
                }
        }
 }