* added Tab Stops support

* added support for Screen Mode (DECSCNM) -- reverse colors

* bug fix: cursor rendition in Origin Mode

* bug fix: SGR parameters handling

* Save/Restore Cursor updates. Partial charset implementation.
This commit is contained in:
rrrooommmaaa 2019-02-01 20:03:41 +03:00 committed by Liam Galvin
parent aad680440d
commit 0c7499bf7e
6 changed files with 105 additions and 6 deletions

View File

@ -14,11 +14,14 @@ type Buffer struct {
displayChangeHandlers []chan bool
savedX uint16
savedY uint16
savedCursorAttr *CellAttributes
dirty bool
selectionStart *Position
selectionEnd *Position
selectionComplete bool // whether the selected text can update or whether it is final
terminalState *TerminalState
savedCharsets []*map[rune]rune
savedCurrentCharset int
}
type Position struct {
@ -355,13 +358,27 @@ func (buffer *Buffer) ScrollToEnd() {
}
func (buffer *Buffer) SaveCursor() {
copiedAttr := buffer.terminalState.CursorAttr
buffer.savedCursorAttr = &copiedAttr
buffer.savedX = buffer.terminalState.cursorX
buffer.savedY = buffer.terminalState.cursorY
buffer.savedCharsets = make([]*map[rune]rune, len(buffer.terminalState.Charsets))
copy(buffer.savedCharsets, buffer.terminalState.Charsets)
buffer.savedCurrentCharset = buffer.terminalState.CurrentCharset
}
func (buffer *Buffer) RestoreCursor() {
if buffer.savedCursorAttr != nil {
copiedAttr := *buffer.savedCursorAttr
buffer.terminalState.CursorAttr = copiedAttr // @todo ignore colors?
}
buffer.terminalState.cursorX = buffer.savedX
buffer.terminalState.cursorY = buffer.savedY
if buffer.savedCharsets != nil {
buffer.terminalState.Charsets = make([]*map[rune]rune, len(buffer.savedCharsets))
copy(buffer.terminalState.Charsets, buffer.savedCharsets)
buffer.terminalState.CurrentCharset = buffer.savedCurrentCharset
}
}
func (buffer *Buffer) CursorAttr() *CellAttributes {

View File

@ -16,6 +16,8 @@ type TerminalState struct {
AutoWrap bool
maxLines uint64
tabStops map[uint16]struct{}
Charsets []*map[rune]rune // array of 2 charsets, nil means ASCII (no conversion)
CurrentCharset int // active charset index in Charsets array, valid values are 0 or 1
}
// NewTerminalMode creates a new terminal state
@ -30,6 +32,7 @@ func NewTerminalState(viewCols uint16, viewLines uint16, attr CellAttributes, ma
viewHeight: viewLines,
topMargin: 0,
bottomMargin: uint(viewLines - 1),
Charsets: []*map[rune]rune{nil, nil},
LineFeedMode: true,
}
b.TabReset()

View File

@ -17,8 +17,8 @@ var ansiSequenceMap = map[rune]escapeSequenceHandler{
'P': sixelHandler,
'c': risHandler, //RIS
'#': screenStateHandler,
'(': swallowHandler(1), // character set bullshit
')': swallowHandler(1), // character set bullshit
'(': scs0Handler, // select character set into G0
')': scs1Handler, // select character set into G1
'*': swallowHandler(1), // character set bullshit
'+': swallowHandler(1), // character set bullshit
'>': swallowHandler(0), // numeric char selection //@todo

65
terminal/charset.go Normal file
View File

@ -0,0 +1,65 @@
package terminal
import "fmt"
var charSets = map[rune]*map[rune]rune{
'0': &decSpecGraphics,
'B': nil, // ASCII
// @todo 1,2,A
}
var decSpecGraphics = map[rune]rune{
0x5f: 0x00A0, // NO-BREAK SPACE
0x60: 0x25C6, // BLACK DIAMOND
0x61: 0x2592, // MEDIUM SHADE
0x62: 0x2409, // SYMBOL FOR HORIZONTAL TABULATION
0x63: 0x240C, // SYMBOL FOR FORM FEED
0x64: 0x240D, // SYMBOL FOR CARRIAGE RETURN
0x65: 0x240A, // SYMBOL FOR LINE FEED
0x66: 0x00B0, // DEGREE SIGN
0x67: 0x00B1, // PLUS-MINUS SIGN
0x68: 0x2424, // SYMBOL FOR NEWLINE
0x69: 0x240B, // SYMBOL FOR VERTICAL TABULATION
0x6a: 0x2518, // BOX DRAWINGS LIGHT UP AND LEFT
0x6b: 0x2510, // BOX DRAWINGS LIGHT DOWN AND LEFT
0x6c: 0x250C, // BOX DRAWINGS LIGHT DOWN AND RIGHT
0x6d: 0x2514, // BOX DRAWINGS LIGHT UP AND RIGHT
0x6e: 0x253C, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x6f: 0x23BA, // HORIZONTAL SCAN LINE-1
0x70: 0x23BB, // HORIZONTAL SCAN LINE-3
0x71: 0x2500, // BOX DRAWINGS LIGHT HORIZONTAL
0x72: 0x23BC, // HORIZONTAL SCAN LINE-7
0x73: 0x23BD, // HORIZONTAL SCAN LINE-9
0x74: 0x251C, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x75: 0x2524, // BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x76: 0x2534, // BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x77: 0x252C, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x78: 0x2502, // BOX DRAWINGS LIGHT VERTICAL
0x79: 0x2264, // LESS-THAN OR EQUAL TO
0x7a: 0x2265, // GREATER-THAN OR EQUAL TO
0x7b: 0x03C0, // GREEK SMALL LETTER PI
0x7c: 0x2260, // NOT EQUAL TO
0x7d: 0x00A3, // POUND SIGN
0x7e: 0x00B7, // MIDDLE DOT
}
func scs0Handler(pty chan rune, terminal *Terminal) error {
return scsHandler(pty, terminal, 0)
}
func scs1Handler(pty chan rune, terminal *Terminal) error {
return scsHandler(pty, terminal, 1)
}
func scsHandler(pty chan rune, terminal *Terminal, which int) error {
b := <-pty
cs, ok := charSets[b]
if ok {
terminal.logger.Debugf("Selected charset %v into G%v", string(b), which)
terminal.terminalState.Charsets[which] = cs
return nil
}
terminal.terminalState.Charsets[which] = nil
return fmt.Errorf("Unknown SCS charset code: 0x%02X [%v]", b, string(b))
}

View File

@ -61,12 +61,14 @@ func enqHandler(terminal *Terminal) error {
}
func shiftOutHandler(terminal *Terminal) error {
terminal.logger.Errorf("Received shift out")
terminal.logger.Debugf("Received shift out")
terminal.terminalState.CurrentCharset = 1
return nil
}
func shiftInHandler(terminal *Terminal) error {
terminal.logger.Errorf("Received shift in")
terminal.logger.Debugf("Received shift in")
terminal.terminalState.CurrentCharset = 0
return nil
}
@ -79,10 +81,22 @@ func (terminal *Terminal) processRune(b rune) {
return
}
//terminal.logger.Debugf("Received character 0x%X: %q", b, string(b))
terminal.ActiveBuffer().Write(b)
terminal.ActiveBuffer().Write(terminal.translateRune(b))
terminal.isDirty = true
}
func (terminal *Terminal) translateRune(b rune) rune {
table := terminal.terminalState.Charsets[terminal.terminalState.CurrentCharset]
if table == nil {
return b
}
chr, ok := (*table)[b]
if ok {
return chr
}
return b
}
func (terminal *Terminal) processInput(pty chan rune) {
// https://en.wikipedia.org/wiki/ANSI_escape_code

View File

@ -20,7 +20,7 @@ func sgrSequenceHandler(params []string, terminal *Terminal) error {
p := strings.Replace(strings.Replace(params[i], "[", "", -1), "]", "", -1)
switch p {
case "00", "0":
case "00", "0", "":
attr := terminal.ActiveBuffer().CursorAttr()
*attr = buffer.CellAttributes{
FgColour: terminal.config.ColourScheme.Foreground,