Move escape code parser into wcswidth package

This commit is contained in:
Kovid Goyal 2022-08-25 05:55:38 +05:30
parent 9be2247081
commit 7280c712d6
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
6 changed files with 30 additions and 27 deletions

View File

@ -20,6 +20,7 @@ import (
"kitty/tools/tty" "kitty/tools/tty"
"kitty/tools/tui" "kitty/tools/tui"
"kitty/tools/utils" "kitty/tools/utils"
"kitty/tools/wcswidth"
) )
var ProtocolVersion [3]int = [3]int{0, 20, 0} var ProtocolVersion [3]int = [3]int{0, 20, 0}
@ -127,7 +128,7 @@ func do_io(device IOAbstraction, input utils.Reader, no_response bool, response_
return nil return nil
} }
var p utils.EscapeCodeParser = utils.EscapeCodeParser{HandleDCS: handle_dcs} var p = wcswidth.EscapeCodeParser{HandleDCS: handle_dcs}
buf := make([]byte, 0, utils.DEFAULT_IO_BUFFER_SIZE) buf := make([]byte, 0, utils.DEFAULT_IO_BUFFER_SIZE)
for !response_received { for !response_received {

View File

@ -10,6 +10,7 @@ import (
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
"kitty/tools/utils" "kitty/tools/utils"
"kitty/tools/wcswidth"
) )
func read_ignoring_temporary_errors(fd int, buf []byte) (int, error) { func read_ignoring_temporary_errors(fd int, buf []byte) (int, error) {
@ -43,7 +44,7 @@ type Loop struct {
controlling_term *tty.Term controlling_term *tty.Term
terminal_options TerminalStateOptions terminal_options TerminalStateOptions
screen_size ScreenSize screen_size ScreenSize
escape_code_parser utils.EscapeCodeParser escape_code_parser wcswidth.EscapeCodeParser
keep_going bool keep_going bool
flush_write_buf bool flush_write_buf bool
death_signal Signal death_signal Signal

View File

@ -26,7 +26,7 @@ const (
UTF8_REJECT = 1 UTF8_REJECT = 1
) )
func decode_utf8(state *UTF8State, codep *UTF8State, byte_ byte) UTF8State { func DecodeUtf8(state *UTF8State, codep *UTF8State, byte_ byte) UTF8State {
typ := UTF8State(utf8_data[byte_]) typ := UTF8State(utf8_data[byte_])
b := UTF8State(byte_) b := UTF8State(byte_)
@ -41,7 +41,7 @@ func decode_utf8(state *UTF8State, codep *UTF8State, byte_ byte) UTF8State {
return *state return *state
} }
func encode_utf8(ch UTF8State, dest []byte) int { func EncodeUtf8(ch UTF8State, dest []byte) int {
if ch < 0x80 { if ch < 0x80 {
dest[0] = byte(ch) dest[0] = byte(ch)
return 1 return 1

View File

@ -1,7 +1,8 @@
package utils package wcswidth
import ( import (
"bytes" "bytes"
"kitty/tools/utils"
) )
type parser_state uint8 type parser_state uint8
@ -35,10 +36,10 @@ const (
type EscapeCodeParser struct { type EscapeCodeParser struct {
state parser_state state parser_state
utf8_state UTF8State utf8_state utils.UTF8State
csi_state csi_state csi_state csi_state
current_buffer []byte current_buffer []byte
bracketed_paste_buffer []UTF8State bracketed_paste_buffer []utils.UTF8State
current_callback func([]byte) error current_callback func([]byte) error
// Callbacks // Callbacks
@ -54,21 +55,21 @@ type EscapeCodeParser struct {
func (self *EscapeCodeParser) InBracketedPaste() bool { return self.state == bracketed_paste } func (self *EscapeCodeParser) InBracketedPaste() bool { return self.state == bracketed_paste }
func (self *EscapeCodeParser) Parse(data []byte) error { func (self *EscapeCodeParser) Parse(data []byte) error {
prev := UTF8_ACCEPT prev := utils.UTF8_ACCEPT
codep := UTF8_ACCEPT codep := utils.UTF8_ACCEPT
for i := 0; i < len(data); i++ { for i := 0; i < len(data); i++ {
switch self.state { switch self.state {
case normal, bracketed_paste: case normal, bracketed_paste:
switch decode_utf8(&self.utf8_state, &codep, data[i]) { switch utils.DecodeUtf8(&self.utf8_state, &codep, data[i]) {
case UTF8_ACCEPT: case utils.UTF8_ACCEPT:
err := self.dispatch_char(codep) err := self.dispatch_char(codep)
if err != nil { if err != nil {
self.Reset() self.Reset()
return err return err
} }
case UTF8_REJECT: case utils.UTF8_REJECT:
self.utf8_state = UTF8_ACCEPT self.utf8_state = utils.UTF8_ACCEPT
if prev != UTF8_ACCEPT && i > 0 { if prev != utils.UTF8_ACCEPT && i > 0 {
i = i - 1 i = i - 1
} }
} }
@ -109,7 +110,7 @@ func (self *EscapeCodeParser) reset_state() {
self.current_buffer = self.current_buffer[:0] self.current_buffer = self.current_buffer[:0]
self.bracketed_paste_buffer = self.bracketed_paste_buffer[:0] self.bracketed_paste_buffer = self.bracketed_paste_buffer[:0]
self.state = normal self.state = normal
self.utf8_state = UTF8_ACCEPT self.utf8_state = utils.UTF8_ACCEPT
self.current_callback = nil self.current_callback = nil
self.csi_state = parameter self.csi_state = parameter
} }
@ -132,14 +133,14 @@ func (self *EscapeCodeParser) invalid_escape_code() {
self.reset_state() self.reset_state()
} }
func (self *EscapeCodeParser) dispatch_rune(ch UTF8State) error { func (self *EscapeCodeParser) dispatch_rune(ch utils.UTF8State) error {
if self.HandleRune != nil { if self.HandleRune != nil {
return self.HandleRune(rune(ch)) return self.HandleRune(rune(ch))
} }
return nil return nil
} }
func (self *EscapeCodeParser) bp_buffer_equals(chars []UTF8State) bool { func (self *EscapeCodeParser) bp_buffer_equals(chars []utils.UTF8State) bool {
if len(self.bracketed_paste_buffer) != len(chars) { if len(self.bracketed_paste_buffer) != len(chars) {
return false return false
} }
@ -151,7 +152,7 @@ func (self *EscapeCodeParser) bp_buffer_equals(chars []UTF8State) bool {
return true return true
} }
func (self *EscapeCodeParser) dispatch_char(ch UTF8State) error { func (self *EscapeCodeParser) dispatch_char(ch utils.UTF8State) error {
if self.state == bracketed_paste { if self.state == bracketed_paste {
dispatch := func() error { dispatch := func() error {
if len(self.bracketed_paste_buffer) > 0 { if len(self.bracketed_paste_buffer) > 0 {
@ -165,7 +166,7 @@ func (self *EscapeCodeParser) dispatch_char(ch UTF8State) error {
} }
return self.dispatch_rune(ch) return self.dispatch_rune(ch)
} }
handle_ch := func(chars ...UTF8State) error { handle_ch := func(chars ...utils.UTF8State) error {
if self.bp_buffer_equals(chars) { if self.bp_buffer_equals(chars) {
self.bracketed_paste_buffer = append(self.bracketed_paste_buffer, ch) self.bracketed_paste_buffer = append(self.bracketed_paste_buffer, ch)
if self.bracketed_paste_buffer[len(self.bracketed_paste_buffer)-1] == '~' { if self.bracketed_paste_buffer[len(self.bracketed_paste_buffer)-1] == '~' {

View File

@ -1,4 +1,4 @@
package utils package wcswidth
import ( import (
"testing" "testing"

View File

@ -8,12 +8,12 @@ func IsFlagPair(a rune, b rune) bool {
return IsFlagCodepoint(a) && IsFlagCodepoint(b) return IsFlagCodepoint(a) && IsFlagCodepoint(b)
} }
type parser_state uint8 type ecparser_state uint8
type WCWidthIterator struct { type WCWidthIterator struct {
prev_ch rune prev_ch rune
prev_width int prev_width int
state parser_state state ecparser_state
} }
func (self *WCWidthIterator) Reset() { func (self *WCWidthIterator) Reset() {
@ -25,11 +25,11 @@ func (self *WCWidthIterator) Reset() {
func (self *WCWidthIterator) Step(ch rune) int { func (self *WCWidthIterator) Step(ch rune) int {
var ans int = 0 var ans int = 0
const ( const (
normal parser_state = 0 normal ecparser_state = 0
in_esc parser_state = 1 in_esc ecparser_state = 1
in_csi parser_state = 2 in_csi ecparser_state = 2
flag_pair_started parser_state = 3 flag_pair_started ecparser_state = 3
in_st_terminated parser_state = 4 in_st_terminated ecparser_state = 4
) )
switch self.state { switch self.state {
case in_csi: case in_csi: