From 72f7a9f5048c862839add16d27755e8b9b32c8d1 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Sun, 16 Oct 2016 19:14:55 -0400 Subject: [PATCH] Fixed cursor movement and column keeping between lines --- buf.c | 27 +++++++++++++++++++++++---- edit.h | 1 + screen.c | 8 -------- utf8.c | 7 +++++++ xedit.c | 1 - 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/buf.c b/buf.c index 8e1d217..b9b573c 100644 --- a/buf.c +++ b/buf.c @@ -1,6 +1,7 @@ #define _GNU_SOURCE #include #include +#include #include "edit.h" @@ -161,11 +162,29 @@ unsigned buf_byline(Buf* buf, unsigned pos, int count) { } unsigned buf_getcol(Buf* buf, unsigned pos) { - return (pos - buf_bol(buf, pos)); + unsigned curr = buf_bol(buf, pos); + unsigned col = 0; + for (; curr < pos; curr = buf_byrune(buf, curr, 1)) + col += runewidth(col, buf_get(buf, curr)); + return col; } unsigned buf_setcol(Buf* buf, unsigned pos, unsigned col) { - unsigned bol = buf_bol(buf, pos); - unsigned len = buf_eol(buf, pos) - bol; - return buf_byrune(buf, bol, (len > col ? col : len)); + unsigned bol = buf_bol(buf, pos); + unsigned curr = bol; + unsigned len = 0; + unsigned i = 0; + /* determine the length of the line in columns */ + for (; buf_get(buf, curr) != '\n'; curr = buf_byrune(buf, curr, 1)) + len += runewidth(len, buf_get(buf, curr)); + /* iterate over the runes until we reach the target column */ + curr = bol, i = 0; + while (i < col && i < len) { + int width = runewidth(i, buf_get(buf, curr)); + curr = buf_byrune(buf, curr, 1); + if (col >= i && col < (i+width)) + break; + i += width; + } + return curr; } diff --git a/edit.h b/edit.h index 2d34cc1..50c7d4d 100644 --- a/edit.h +++ b/edit.h @@ -34,6 +34,7 @@ size_t utf8encode(char str[UTF_MAX], Rune rune); bool utf8decode(Rune* rune, size_t* length, int byte); Rune fgetrune(FILE* f); void fputrune(Rune rune, FILE* f); +int runewidth(unsigned col, Rune r); /* Buffer management functions *****************************************************************************/ diff --git a/screen.c b/screen.c index b9952e2..9d5b90d 100644 --- a/screen.c +++ b/screen.c @@ -1,5 +1,4 @@ #include "edit.h" -#include static unsigned NumRows = 0; static unsigned NumCols = 0; @@ -73,13 +72,6 @@ void screen_clearrow(unsigned row) { scrrow->len = 0; } -static int runewidth(unsigned col, Rune r) { - if (r == '\t') return (TabWidth - (col % TabWidth)); - int width = wcwidth(r); - if (width < 0) width = 1; - return width; -} - unsigned screen_setcell(unsigned row, unsigned col, Rune r) { if (row >= NumRows || col >= NumCols) return 0; Row* scrrow = screen_getrow(row); diff --git a/utf8.c b/utf8.c index dac7d2f..99ae9d2 100644 --- a/utf8.c +++ b/utf8.c @@ -102,3 +102,10 @@ void utf8save(Buf* buf, FILE* file) { fputrune(buf_get(buf, i), file); } +int runewidth(unsigned col, Rune r) { + if (r == '\t') return (TabWidth - (col % TabWidth)); + int width = wcwidth(r); + if (width < 0) width = 1; + return width; +} + diff --git a/xedit.c b/xedit.c index d83c28c..e17c92b 100644 --- a/xedit.c +++ b/xedit.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include -- 2.49.0