1package gui
2
3import (
4	"unicode"
5
6	"github.com/jesseduffield/gocui"
7)
8
9func (gui *Gui) handleEditorKeypress(textArea *gocui.TextArea, key gocui.Key, ch rune, mod gocui.Modifier, allowMultiline bool) bool {
10	newlineKey, ok := gui.getKey(gui.Config.GetUserConfig().Keybinding.Universal.AppendNewline).(gocui.Key)
11	if !ok {
12		newlineKey = gocui.KeyAltEnter
13	}
14
15	switch {
16	case key == gocui.KeyBackspace || key == gocui.KeyBackspace2:
17		textArea.BackSpaceChar()
18	case key == gocui.KeyCtrlD || key == gocui.KeyDelete:
19		textArea.DeleteChar()
20	case key == gocui.KeyArrowDown:
21		textArea.MoveCursorDown()
22	case key == gocui.KeyArrowUp:
23		textArea.MoveCursorUp()
24	case key == gocui.KeyArrowLeft:
25		textArea.MoveCursorLeft()
26	case key == gocui.KeyArrowRight:
27		textArea.MoveCursorRight()
28	case key == newlineKey:
29		if allowMultiline {
30			textArea.TypeRune('\n')
31		} else {
32			return false
33		}
34	case key == gocui.KeySpace:
35		textArea.TypeRune(' ')
36	case key == gocui.KeyInsert:
37		textArea.ToggleOverwrite()
38	case key == gocui.KeyCtrlU:
39		textArea.DeleteToStartOfLine()
40	case key == gocui.KeyCtrlA || key == gocui.KeyHome:
41		textArea.GoToStartOfLine()
42	case key == gocui.KeyCtrlE || key == gocui.KeyEnd:
43		textArea.GoToEndOfLine()
44
45		// TODO: see if we need all three of these conditions: maybe the final one is sufficient
46	case ch != 0 && mod == 0 && unicode.IsPrint(ch):
47		textArea.TypeRune(ch)
48	default:
49		return false
50	}
51
52	return true
53}
54
55// we've just copy+pasted the editor from gocui to here so that we can also re-
56// render the commit message length on each keypress
57func (gui *Gui) commitMessageEditor(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) bool {
58	matched := gui.handleEditorKeypress(v.TextArea, key, ch, mod, true)
59
60	// This function is called again on refresh as part of the general resize popup call,
61	// but we need to call it here so that when we go to render the text area it's not
62	// considered out of bounds to add a newline, meaning we can avoid unnecessary scrolling.
63	err := gui.resizePopupPanel(v, v.TextArea.GetContent())
64	if err != nil {
65		gui.Log.Error(err)
66	}
67	v.RenderTextArea()
68	gui.RenderCommitLength()
69
70	return matched
71}
72
73func (gui *Gui) defaultEditor(v *gocui.View, key gocui.Key, ch rune, mod gocui.Modifier) bool {
74	matched := gui.handleEditorKeypress(v.TextArea, key, ch, mod, false)
75
76	v.RenderTextArea()
77
78	if gui.findSuggestions != nil {
79		input := v.TextArea.GetContent()
80		gui.suggestionsAsyncHandler.Do(func() func() {
81			suggestions := gui.findSuggestions(input)
82			return func() { gui.setSuggestions(suggestions) }
83		})
84	}
85
86	return matched
87}
88