From 59005c5800683f1096ac02148df842f0ed8c841c Mon Sep 17 00:00:00 2001 From: sloum Date: Thu, 1 Apr 2021 22:57:36 -0700 Subject: [PATCH] Fixes some off by one issues as well as printing invisible characters --- main.go | 48 +++++++++++++++++++++++++++++++++++++++--------- qline.swim | 1 + 2 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 qline.swim diff --git a/main.go b/main.go index 7a8bdcf..4ac1c31 100644 --- a/main.go +++ b/main.go @@ -35,6 +35,7 @@ type Buffer struct { cursor int maxWidth int offset int + cursorStart int } func (lb Buffer) String() string { @@ -53,7 +54,13 @@ func (lb *Buffer) deleteChar() { } } +// TODO rework this so that the changes are made but all drawing to the screen comes +// from one source and always draws the whole input area. This will make dealing with +// offsets much easier. func (lb *Buffer) addChar(c rune, echo bool) { + if c < 9 || (c > 10 && c < 13) || (c > 13 && c < 32) { + return + } if lb.cursor == len(lb.buf) { lb.buf = append(lb.buf, c) lb.cursor++ @@ -76,9 +83,11 @@ func (lb *Buffer) controlInput(c rune) { case Delete: lb.deleteChar() case BackSpace: - lb.cursor-- - fmt.Print("\033[1D") - lb.deleteChar() + if lb.cursor > 0 { + lb.cursor-- + fmt.Print("\033[1D") + lb.deleteChar() + } case LeftArrow: if lb.cursor > 0 { lb.cursor-- @@ -90,11 +99,15 @@ func (lb *Buffer) controlInput(c rune) { fmt.Print("\033[1C") } case Home: - fmt.Printf("\033[%dD", lb.cursor) - lb.cursor = 0 + if lb.cursor > 0 { + fmt.Printf("\033[%dD", lb.cursor) + lb.cursor = 0 + } case End: - fmt.Printf("\033[%dC", len(lb.buf)-lb.cursor) - lb.cursor = len(lb.buf) + if lb.cursor < len(lb.buf) { + fmt.Printf("\033[%dC", len(lb.buf)-lb.cursor) + lb.cursor = len(lb.buf) + } } } @@ -104,12 +117,20 @@ func (lb *Buffer) seedContent(s string) { } } +func parseCursorPosition(esc string) (int, int, error) { + var row, col int + r := strings.NewReader(esc) + _, err := fmt.Fscanf(r, "\033[%d;%dR", &row, &col) + return row, col, err +} + func GetText(prompt string, content string) string { cols, _ := termios.GetWindowSize() - b := Buffer{make([]rune, 0, (len(content)+1)*2), 0, cols-len(prompt), 0} + b := Buffer{make([]rune, 0, (len(content)+1)*2), 0, cols-len(prompt), 0, 0} b.seedContent(content) fmt.Print(prompt) + fmt.Print("\033[6n") fmt.Print(b.String()) var ch rune @@ -118,7 +139,10 @@ func GetText(prompt string, content string) string { for { ch, err = readKey(reader) - if err != nil { + if err != nil && err.Error() == "response" { + b.cursorStart = int(ch) + b.maxWidth = cols - b.cursorStart + } else if err != nil { continue } if ch == CarriageReturn || ch == NewLine { @@ -172,6 +196,12 @@ func readKey(reader *bufio.Reader) (rune, error) { char = End case isDeleteKey(escSeq): char = Delete + case escSeq[len(escSeq)-1] == 'R': + _, cols, err := parseCursorPosition(escSeq) + if err == nil { + err = fmt.Errorf("response") + } + return rune(cols), err default: fmt.Printf("Odd sequence: %s\n", escSeq[1:]) } diff --git a/qline.swim b/qline.swim new file mode 100644 index 0000000..fb362f8 --- /dev/null +++ b/qline.swim @@ -0,0 +1 @@ +{"BoardTitle":"","Lanes":[{"LaneTitle":"Backlog","Stories":[{"StoryTitle":"Figure out a way to solve the linewidth issue","StoryBody":"Right now, line editing is working, but without knowing where the cursor starts out we cant know where the end of the line is.","StoryUsers":["sloum"],"StoryTag":-1,"StoryTasks":[{"TaskBody":"Try the escape code method.","TaskComplete":false}],"StoryComments":[],"StoryCreated":"2021-04-01T21:57:43.386761058-07:00","StoryUpdated":"2021-04-01T21:59:21.689817136-07:00","StoryPoints":3},{"StoryTitle":"Build out line offsetting for display","StoryBody":"Once widths are figured out there needs to be horizontal scrolling of input for display soas to not jump down a line.","StoryUsers":["sloum"],"StoryTag":-1,"StoryTasks":[],"StoryComments":[],"StoryCreated":"2021-04-01T21:59:09.929902095-07:00","StoryUpdated":"2021-04-01T22:00:00.004446556-07:00","StoryPoints":2}],"CurrentStory":1},{"LaneTitle":"Active","Stories":[],"CurrentStory":-1},{"LaneTitle":"Complete","Stories":[],"CurrentStory":-1}],"CurrentLane":0,"Zoom":3,"StoryOpen":true} \ No newline at end of file