mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-21 16:05:02 +02:00
More work on shell
This commit is contained in:
@@ -53,6 +53,10 @@ type Loop struct {
|
||||
// the terminal on shutdown
|
||||
OnInitialize func() (string, error)
|
||||
|
||||
// Called just before the loop shuts down. Any returned string is written to the terminal before
|
||||
// shutdown
|
||||
OnFinalize func() string
|
||||
|
||||
// Called when a key event happens
|
||||
OnKeyEvent func(event *KeyEvent) error
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ package readline
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"kitty/tools/utils"
|
||||
@@ -259,24 +260,52 @@ func (self *Readline) erase_chars_after_cursor(amt uint, traverse_line_breaks bo
|
||||
return num
|
||||
}
|
||||
|
||||
func (self *Readline) perform_action(ac Action, repeat_count uint) bool {
|
||||
func (self *Readline) next_word_char_pos(traverse_line_breaks bool) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (self *Readline) perform_action(ac Action, repeat_count uint) error {
|
||||
switch ac {
|
||||
case ActionBackspace:
|
||||
return self.erase_chars_before_cursor(repeat_count, true) > 0
|
||||
if self.erase_chars_before_cursor(repeat_count, true) > 0 {
|
||||
return nil
|
||||
}
|
||||
case ActionDelete:
|
||||
return self.erase_chars_after_cursor(repeat_count, true) > 0
|
||||
if self.erase_chars_after_cursor(repeat_count, true) > 0 {
|
||||
return nil
|
||||
}
|
||||
case ActionMoveToStartOfLine:
|
||||
return self.move_to_start_of_line()
|
||||
if self.move_to_start_of_line() {
|
||||
return nil
|
||||
}
|
||||
case ActionMoveToEndOfLine:
|
||||
return self.move_to_end_of_line()
|
||||
if self.move_to_end_of_line() {
|
||||
return nil
|
||||
}
|
||||
case ActionMoveToStartOfDocument:
|
||||
return self.move_to_start()
|
||||
if self.move_to_start() {
|
||||
return nil
|
||||
}
|
||||
case ActionMoveToEndOfDocument:
|
||||
return self.move_to_end()
|
||||
if self.move_to_end() {
|
||||
return nil
|
||||
}
|
||||
case ActionCursorLeft:
|
||||
return self.move_cursor_left(repeat_count, true) > 0
|
||||
if self.move_cursor_left(repeat_count, true) > 0 {
|
||||
return nil
|
||||
}
|
||||
case ActionCursorRight:
|
||||
return self.move_cursor_right(repeat_count, true) > 0
|
||||
if self.move_cursor_right(repeat_count, true) > 0 {
|
||||
return nil
|
||||
}
|
||||
case ActionEndInput:
|
||||
line := self.lines[self.cursor.Y]
|
||||
if line == "" {
|
||||
return io.EOF
|
||||
}
|
||||
return self.perform_action(ActionAcceptInput, 1)
|
||||
case ActionAcceptInput:
|
||||
return ErrAcceptInput
|
||||
}
|
||||
return false
|
||||
return ErrCouldNotPerformAction
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ const (
|
||||
ActionMoveToEndOfDocument
|
||||
ActionCursorLeft
|
||||
ActionCursorRight
|
||||
ActionEndInput
|
||||
ActionAcceptInput
|
||||
)
|
||||
|
||||
type Readline struct {
|
||||
@@ -78,12 +80,32 @@ func New(loop *loop.Loop, r RlInit) *Readline {
|
||||
return ans
|
||||
}
|
||||
|
||||
func (self *Readline) ChangeLoopAndResetText(lp *loop.Loop) {
|
||||
self.loop = lp
|
||||
self.lines = []string{""}
|
||||
self.cursor = Position{}
|
||||
self.cursor_y = 0
|
||||
}
|
||||
|
||||
func (self *Readline) Start() {
|
||||
self.loop.SetCursorShape(loop.BAR_CURSOR, true)
|
||||
self.loop.StartBracketedPaste()
|
||||
self.Redraw()
|
||||
}
|
||||
|
||||
func (self *Readline) End() {
|
||||
self.loop.SetCursorShape(loop.BLOCK_CURSOR, true)
|
||||
self.loop.EndBracketedPaste()
|
||||
self.loop.QueueWriteString("\r\n")
|
||||
if self.mark_prompts {
|
||||
self.loop.QueueWriteString(PROMPT_MARK + "C" + ST)
|
||||
}
|
||||
}
|
||||
|
||||
func MarkOutputStart() string {
|
||||
return PROMPT_MARK + "C" + ST
|
||||
}
|
||||
|
||||
func (self *Readline) Redraw() {
|
||||
self.loop.StartAtomicUpdate()
|
||||
self.RedrawNonAtomic()
|
||||
@@ -94,15 +116,6 @@ func (self *Readline) RedrawNonAtomic() {
|
||||
self.redraw()
|
||||
}
|
||||
|
||||
func (self *Readline) End() {
|
||||
self.loop.EndBracketedPaste()
|
||||
self.loop.QueueWriteString("\r\n")
|
||||
self.loop.SetCursorShape(loop.BLOCK_CURSOR, true)
|
||||
if self.mark_prompts {
|
||||
self.loop.QueueWriteString(PROMPT_MARK + "C" + ST)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Readline) OnKeyEvent(event *loop.KeyEvent) error {
|
||||
err := self.handle_key_event(event)
|
||||
if err == ErrCouldNotPerformAction {
|
||||
@@ -117,6 +130,14 @@ func (self *Readline) OnText(text string, from_key_event bool, in_bracketed_past
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *Readline) PerformAction(ac Action, repeat_count uint) bool {
|
||||
return self.perform_action(ac, repeat_count)
|
||||
func (self *Readline) TextBeforeCursor() string {
|
||||
return self.text_upto_cursor_pos()
|
||||
}
|
||||
|
||||
func (self *Readline) TextAfterCursor() string {
|
||||
return self.text_after_cursor_pos()
|
||||
}
|
||||
|
||||
func (self *Readline) AllText() string {
|
||||
return self.all_text()
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@ var default_shortcuts = map[string]Action{
|
||||
"backspace": ActionBackspace,
|
||||
"ctrl+h": ActionBackspace,
|
||||
"delete": ActionDelete,
|
||||
"ctrl+d": ActionDelete,
|
||||
|
||||
"home": ActionMoveToStartOfLine,
|
||||
"ctrl+a": ActionMoveToStartOfLine,
|
||||
@@ -30,6 +29,9 @@ var default_shortcuts = map[string]Action{
|
||||
"ctrl+b": ActionCursorLeft,
|
||||
"right": ActionCursorRight,
|
||||
"ctrl+f": ActionCursorRight,
|
||||
|
||||
"ctrl+d": ActionEndInput,
|
||||
"enter": ActionAcceptInput,
|
||||
}
|
||||
|
||||
func action_for_key_event(event *loop.KeyEvent, shortcuts map[string]Action) Action {
|
||||
@@ -42,6 +44,7 @@ func action_for_key_event(event *loop.KeyEvent, shortcuts map[string]Action) Act
|
||||
}
|
||||
|
||||
var ErrCouldNotPerformAction = errors.New("Could not perform the specified action")
|
||||
var ErrAcceptInput = errors.New("Accept input")
|
||||
|
||||
func (self *Readline) handle_key_event(event *loop.KeyEvent) error {
|
||||
if event.Text != "" {
|
||||
@@ -50,9 +53,7 @@ func (self *Readline) handle_key_event(event *loop.KeyEvent) error {
|
||||
ac := action_for_key_event(event, default_shortcuts)
|
||||
if ac != ActionNil {
|
||||
event.Handled = true
|
||||
if !self.perform_action(ac, 1) {
|
||||
return ErrCouldNotPerformAction
|
||||
}
|
||||
return self.perform_action(ac, 1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user