diff --git a/event_handler.go b/event_handler.go index 466fb3c..b8ebeb0 100644 --- a/event_handler.go +++ b/event_handler.go @@ -52,6 +52,12 @@ type AnsiEventHandler interface { // Delete Line DL(int) error + // Insert Character + ICH(int) error + + // Delete Character + DCH(int) error + // Set Graphics Rendition SGR([]int) error diff --git a/parser_actions.go b/parser_actions.go index a572f6f..f4ae6ee 100644 --- a/parser_actions.go +++ b/parser_actions.go @@ -39,6 +39,8 @@ func (ap *AnsiParser) csiDispatch() error { logger.Infof("csiDispatch: %v(%v)", cmd, params) switch cmd { + case "@": + return ap.eventHandler.ICH(getInt(params, 1)) case "A": return ap.eventHandler.CUU(getInt(params, 1)) case "B": @@ -67,6 +69,8 @@ func (ap *AnsiParser) csiDispatch() error { return ap.eventHandler.IL(getInt(params, 1)) case "M": return ap.eventHandler.DL(getInt(params, 1)) + case "P": + return ap.eventHandler.DCH(getInt(params, 1)) case "S": return ap.eventHandler.SU(getInt(params, 1)) case "T": diff --git a/test_event_handler.go b/test_event_handler.go index 7b5725b..5c7ad49 100644 --- a/test_event_handler.go +++ b/test_event_handler.go @@ -107,6 +107,16 @@ func (h *TestAnsiEventHandler) DL(param int) error { return nil } +func (h *TestAnsiEventHandler) ICH(param int) error { + h.recordCall("ICH", []string{strconv.Itoa(param)}) + return nil +} + +func (h *TestAnsiEventHandler) DCH(param int) error { + h.recordCall("DCH", []string{strconv.Itoa(param)}) + return nil +} + func (h *TestAnsiEventHandler) SGR(params []int) error { strings := []string{} for _, v := range params { diff --git a/winterm/scroll_helper.go b/winterm/scroll_helper.go index e547a4c..ed19982 100644 --- a/winterm/scroll_helper.go +++ b/winterm/scroll_helper.go @@ -77,3 +77,42 @@ func (h *WindowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSO } return nil } + +func (h *WindowsAnsiEventHandler) deleteCharacters(param int) error { + info, err := GetConsoleScreenBufferInfo(h.fd) + if err != nil { + return err + } + return h.scrollLine(param, info.CursorPosition, info) +} + +func (h *WindowsAnsiEventHandler) insertCharacters(param int) error { + return h.deleteCharacters(-param) +} + +// scrollLine scrolls a line horizontally starting at the provided position by a number of columns. +func (h *WindowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error { + // Copy from and clip to the scroll region (full buffer width) + scrollRect := SMALL_RECT{ + Top: position.Y, + Bottom: position.Y, + Left: position.X, + Right: info.Size.X - 1, + } + + // Origin to which area should be copied + destOrigin := COORD{ + X: position.X - SHORT(columns), + Y: position.Y, + } + + char := CHAR_INFO{ + UnicodeChar: ' ', + Attributes: h.attributes, + } + + if err := ScrollConsoleScreenBuffer(h.fd, scrollRect, scrollRect, destOrigin, char); err != nil { + return err + } + return nil +} diff --git a/winterm/win_event_handler.go b/winterm/win_event_handler.go index c61b082..158e820 100644 --- a/winterm/win_event_handler.go +++ b/winterm/win_event_handler.go @@ -496,6 +496,24 @@ func (h *WindowsAnsiEventHandler) DL(param int) error { return h.deleteLines(param) } +func (h *WindowsAnsiEventHandler) ICH(param int) error { + if err := h.Flush(); err != nil { + return err + } + logger.Infof("ICH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.insertCharacters(param) +} + +func (h *WindowsAnsiEventHandler) DCH(param int) error { + if err := h.Flush(); err != nil { + return err + } + logger.Infof("DCH: [%v]", strconv.Itoa(param)) + h.clearWrap() + return h.deleteCharacters(param) +} + func (h *WindowsAnsiEventHandler) SGR(params []int) error { if err := h.Flush(); err != nil { return err