mirror of https://github.com/liamg/aminal.git
Vttest 2 (#190)
* 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:
parent
aad680440d
commit
0c7499bf7e
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue