Introduction
Introduction Statistics Contact Development Disclaimer Help
add support for characters that are bigger than 1 column - sob - simple output …
git clone git://git.codemadness.org/sob
Log
Files
Refs
README
LICENSE
---
commit 953439a2efe7bf8be200be0d384377d1d96f4d48
parent 4f2bc0ed04d5afc5dfd11651fe84747eb3ec55bb
Author: Hiltjo Posthuma <[email protected]>
Date: Fri, 10 Oct 2014 18:47:55 +0000
add support for characters that are bigger than 1 column
Diffstat:
M README | 4 +++-
M sob.c | 78 +++++++++++++++++++++++++----…
2 files changed, 67 insertions(+), 15 deletions(-)
---
diff --git a/README b/README
@@ -10,6 +10,8 @@ Dependencies
Features
--------
- Small (in size and memory), not much dependencies.
+- UTF-8 input and output support.
+ - Support for characters that are bigger than 1 column.
- Custom prompt (including color support).
- Easy to write custom completion scripts or special actions.
- Custom action on SIGWINCH (window resize).
@@ -23,7 +25,7 @@ Features
Known issues
------------
-line yank doesn't work with xclip, but does work with xsel.
+- Line yank doesn't work with xclip, but does work with xsel.
Author
diff --git a/sob.c b/sob.c
@@ -12,6 +12,9 @@
#include <unistd.h>
#include <termios.h>
+#define __XOPEN_SOURCE
+#include <wchar.h>
+
#include "arg.h"
char *argv0;
@@ -27,6 +30,8 @@ struct line {
size_t utflen; /* length in characters */
size_t bytepos; /* index position (in bytes) */
size_t utfpos; /* pos in characters */
+ size_t colpos; /* cursor position (in columns) */
+ size_t collen; /* total length (in columns) */
};
static void line_clear(void);
@@ -69,10 +74,11 @@ static void setup(void);
static void sighandler(int);
static void usage(void);
+static size_t colw(const char *, size_t);
static int nonspace(int c);
static size_t utf8len(const char *);
-static size_t utfprevn(const char *, size_t , size_t);
-static size_t utfnextn(const char *, size_t , size_t);
+static size_t utfprevn(const char *, size_t, size_t);
+static size_t utfnextn(const char *, size_t, size_t);
static void utfuntilchar(size_t *, size_t *, int (*)(int), int);
static struct termios ttystate, ttysave;
@@ -92,6 +98,25 @@ nonspace(int c)
}
static size_t
+colw(const char *s, size_t max)
+{
+ size_t len = 0, i;
+ wchar_t w = 0;
+ int r;
+
+ for(i = 0; *s; s++, i++) {
+ if((*s & 0xc0) != 0x80) {
+ if((r = mbtowc(&w, s, i + 4 > max ? max - i : 4)) == -…
+ break;
+ if((r = wcwidth(w)) == -1)
+ break;
+ len += r;
+ }
+ }
+ return len;
+}
+
+static size_t
utf8len(const char *s)
{
size_t i;
@@ -133,7 +158,7 @@ utfnextn(const char *s, size_t p, size_t n)
return 0;
}
-/* b is byte start pos, u is utf pos, f is filter function,
+/* b is byte start pos, u is utf pos, c is column pos, f is filter function,
* dir is -1 or +1 for prev or next */
static void
utfuntilchar(size_t *b, size_t *u, int (*f)(int), int dir)
@@ -165,12 +190,13 @@ utfuntilchar(size_t *b, size_t *u, int (*f)(int), int dir)
static void
line_inserttext(const char *s)
{
- size_t siz, len;
+ size_t siz, ulen, clen;
siz = strlen(s);
if(line.bytepos + siz + 1 > sizeof(line.line))
return;
- len = utf8len(s);
+ clen = colw(s, siz);
+ ulen = utf8len(s);
/* append */
if(line.bytepos == line.bytesiz) {
memmove(&line.line[line.bytepos], s, siz);
@@ -184,7 +210,9 @@ line_inserttext(const char *s)
line.bytesiz += siz;
line.line[line.bytesiz + 1] = '\0';
line.utflen = utf8len(line.line);
- line.utfpos += len;
+ line.utfpos += ulen;
+ line.colpos += clen;
+ line.collen = colw(line.line, line.bytesiz);
line_draw();
}
@@ -202,6 +230,8 @@ line_set(const char *s)
line.bytepos = line.bytesiz;
line.utflen = utf8len(line.line);
line.utfpos = line.utflen;
+ line.collen = colw(line.line, line.bytesiz);
+ line.colpos = line.collen;
}
/* like mksh, toggle counting of escape codes in prompt with "\x01" */
@@ -237,7 +267,7 @@ line_draw(void)
fprintf(outfp, "\x1b[2J\x1b[H"); /* clear */
line_prompt();
fwrite(line.line, 1, line.bytesiz, outfp);
- line_cursor_move(line.utfpos);
+ line_cursor_move(line.colpos);
}
static void
@@ -268,14 +298,16 @@ static void
line_cursor_wordprev(void)
{
line_getwordposprev(line.bytepos, line.utfpos, &line.bytepos, &line.ut…
- line_cursor_move(line.utfpos);
+ line.colpos = colw(line.line, line.bytepos);
+ line_cursor_move(line.colpos);
}
static void
line_cursor_wordnext(void)
{
line_getwordposnext(line.bytepos, line.utfpos, &line.bytepos, &line.ut…
- line_cursor_move(line.utfpos);
+ line.colpos = colw(line.line, line.bytepos);
+ line_cursor_move(line.colpos);
}
static void
@@ -283,7 +315,8 @@ line_cursor_begin(void)
{
line.bytepos = 0;
line.utfpos = 0;
- line_cursor_move(line.utfpos);
+ line.colpos = 0;
+ line_cursor_move(line.colpos);
}
static void
@@ -298,7 +331,8 @@ line_cursor_prev(void)
line.bytepos -= n;
line.utfpos--;
- line_cursor_move(line.utfpos);
+ line.colpos -= colw(&line.line[line.bytepos], n);
+ line_cursor_move(line.colpos);
}
static void
@@ -311,9 +345,10 @@ line_cursor_next(void)
if((n = utfnextn(line.line, line.bytepos, 1)) == 0)
return;
+ line.colpos += colw(&line.line[line.bytepos], n);
line.bytepos += n;
line.utfpos++;
- line_cursor_move(line.utfpos);
+ line_cursor_move(line.colpos);
}
static void
@@ -321,7 +356,8 @@ line_cursor_end(void)
{
line.bytepos = line.bytesiz;
line.utfpos = line.utflen;
- line_cursor_move(line.utfpos);
+ line.colpos = line.collen;
+ line_cursor_move(line.colpos);
}
static void
@@ -342,6 +378,9 @@ line_delcharnext(void)
if((siz = utfnextn(line.line, line.bytepos, 1)) == 0)
return;
+
+ line.collen -= colw(&line.line[line.bytepos], siz);
+
memmove(&line.line[line.bytepos], &line.line[line.bytepos + siz],
line.bytesiz - line.bytepos - siz);
@@ -354,20 +393,25 @@ line_delcharnext(void)
static void
line_delcharprev(void)
{
- size_t siz;
+ size_t siz, col;
if(line.utfpos <= 0 || line.utflen <= 0)
return;
if((siz = utfprevn(line.line, line.bytepos, 1)) == 0)
return;
+ col = colw(&line.line[line.bytepos - siz], siz);
+
memmove(&line.line[line.bytepos - siz], &line.line[line.bytepos],
line.bytesiz - line.bytepos);
+
line.bytepos -= siz;
line.bytesiz -= siz;
line.line[line.bytesiz] = '\0';
line.utflen--;
line.utfpos--;
+ line.colpos -= col;
+ line.collen -= col;
line_draw();
}
@@ -379,6 +423,8 @@ line_deltoend(void)
line.bytesiz = line.bytepos;
line.utflen = utf8len(line.line);
line.utfpos = line.utflen;
+ line.collen = colw(line.line, line.bytesiz);
+ line.colpos = line.collen;
line_draw();
}
@@ -400,6 +446,8 @@ line_delwordcursor(void)
line.line[line.bytesiz] = '\0';
line.utfpos -= len;
line.utflen -= len;
+ line.collen = colw(line.line, line.bytesiz);
+ line.colpos = colw(line.line, bs);
line_draw();
}
@@ -415,6 +463,7 @@ line_delwordprev(void)
line_getwordposprev(line.bytepos, line.utfpos, &bs, &us);
siz = line.bytepos - bs;
+ line.colpos -= colw(&line.line[bs], siz);
memmove(&line.line[bs], &line.line[line.bytepos],
line.bytesiz - line.bytepos);
@@ -425,6 +474,7 @@ line_delwordprev(void)
line.line[line.bytesiz] = '\0';
line.utfpos -= len;
line.utflen -= len;
+ line.collen = colw(line.line, line.bytesiz);
line_draw();
}
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.