]> git.mdlowis.com Git - projs/tide.git/commitdiff
Fixed cursor movement and column keeping between lines
authorMichael D. Lowis <mike@mdlowis.com>
Sun, 16 Oct 2016 23:14:55 +0000 (19:14 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sun, 16 Oct 2016 23:14:55 +0000 (19:14 -0400)
buf.c
edit.h
screen.c
utf8.c
xedit.c

diff --git a/buf.c b/buf.c
index 8e1d2175636ebb9e02d419d3af0a61a141e5a2de..b9b573cc6f101e62b4d6971ebb10b24a836dc4f2 100644 (file)
--- a/buf.c
+++ b/buf.c
@@ -1,6 +1,7 @@
 #define _GNU_SOURCE
 #include <string.h>
 #include <assert.h>
+#include <wchar.h>
 
 #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 2d34cc1130d7b5d362d5673f8ac71458ff98fa81..50c7d4d9a1b872e289e35e33010e9d20782dedf4 100644 (file)
--- 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
  *****************************************************************************/
index b9952e29a6d3235a3ee84e79ee9d4542a1877d5e..9d5b90ddcc3de182f03f7a714e171e7052e58123 100644 (file)
--- a/screen.c
+++ b/screen.c
@@ -1,5 +1,4 @@
 #include "edit.h"
-#include <wchar.h>
 
 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 dac7d2f2d735d86bb375994eb40597cf820fe4f3..99ae9d213d3fa786338edb91d279b36ab18b50d6 100644 (file)
--- 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 d83c28c6a6bfbe1a099e162669e34e5043de4b49..e17c92be6bb6ca73c7282a064b04add656ef7eb6 100644 (file)
--- a/xedit.c
+++ b/xedit.c
@@ -2,7 +2,6 @@
 #include <time.h>
 #include <signal.h>
 #include <locale.h>
-#include <wchar.h>
 #include <X11/Xlib.h>
 #include <X11/Xft/Xft.h>