commit - b60507ee6753bf11be13aee78316315edf433587
commit + 6d24bfb3ca185665e8a7fa4e5f88434690f4272d
blob - 196f62dfe357c6603e7b34b29c6bfae0aa17fb56
blob + a5e03b8df279c4a7c853b64d6beaee58b93b6300
--- cmd.c
+++ cmd.c
#include <string.h>
#include <unistd.h>
+#include <grapheme.h>
+
#include "certs.h"
#include "cmd.h"
#include "compl.h"
void
cmd_backward_char(struct buffer *buffer)
{
- if (buffer->cpoff != 0)
- buffer->cpoff--;
+ struct vline *vl;
+ char *text;
+ size_t left, off, point = 0;
+
+ if ((vl = buffer->current_line) == NULL)
+ return;
+
+ text = vl->parent->line + vl->from;
+ left = vl->len;
+
+ for (;;) {
+ off = grapheme_next_character_break_utf8(text, left);
+ if (point + off >= buffer->point_offset)
+ break;
+ point += off;
+ text += off;
+ left -= off;
+ }
+
+ buffer->point_offset = point;
}
void
cmd_forward_char(struct buffer *buffer)
{
- if (buffer->current_line == NULL)
+ struct vline *vl;
+ char *text;
+ size_t left, off;
+
+ if ((vl = buffer->current_line) == NULL)
return;
- if (buffer->current_line->cplen > buffer->cpoff)
- buffer->cpoff++;
+
+ text = vl->parent->line + vl->from;
+ left = vl->len;
+
+ text += buffer->point_offset;
+ left -= buffer->point_offset;
+
+ off = grapheme_next_character_break_utf8(text, left);
+ buffer->point_offset += off;
}
void
void
cmd_move_beginning_of_line(struct buffer *buffer)
{
- buffer->cpoff = 0;
+ buffer->point_offset = 0;
}
void
vl = buffer->current_line;
if (vl == NULL)
return;
- buffer->cpoff = vl->cplen;
+ buffer->point_offset = vl->len;
}
void
cmd_beginning_of_buffer(struct buffer *buffer)
{
buffer->current_line = TAILQ_FIRST(&buffer->vhead);
- buffer->cpoff = 0;
+ buffer->point_offset = 0;
buffer->top_line = buffer->current_line;
buffer->line_off = 0;
}
void
cmd_mini_delete_char(struct buffer *buffer)
{
- char *line, *c, *n;
+ struct vline *vl;
+ char *text;
+ size_t old_point, gap, rest;
GUARD_READ_ONLY();
- minibuffer_taint_hist();
-
- line = buffer->current_line->parent->line + buffer->current_line->from;
- c = utf8_nth(line, buffer->cpoff);
- if (*c == '\0')
+ vl = buffer->current_line;
+ old_point = buffer->point_offset;
+ cmd_forward_char(buffer);
+ gap = buffer->point_offset - old_point;
+ if (gap == 0)
return;
- n = utf8_next_cp(c);
- memmove(c, n, strlen(n)+1);
+ minibuffer_taint_hist();
+ text = vl->parent->line + vl->from + old_point;
+ rest = vl->len - buffer->point_offset;
+ memmove(text, text + gap, rest);
+ buffer->point_offset = old_point;
+
recompute_completions(0);
}
void
cmd_mini_delete_backward_char(struct buffer *buffer)
{
- char *line, *c, *p;
+ struct vline *vl;
+ char *text;
+ size_t old_point, gap, rest;
GUARD_READ_ONLY();
- minibuffer_taint_hist();
-
- line = buffer->current_line->parent->line + buffer->current_line->from;
- c = utf8_nth(line, buffer->cpoff);
- if (c == line)
+ vl = buffer->current_line;
+ old_point = buffer->point_offset;
+ cmd_backward_char(buffer);
+ gap = old_point - buffer->point_offset;
+ if (gap == 0)
return;
- p = utf8_prev_cp(c-1, line);
+
+ minibuffer_taint_hist();
- memmove(p, c, strlen(c)+1);
- buffer->cpoff--;
+ text = vl->parent->line + vl->from + buffer->point_offset;
+ rest = vl->len - old_point;
+ memmove(text, text + gap, rest);
recompute_completions(0);
}
minibuffer_taint_hist();
line = buffer->current_line->parent->line + buffer->current_line->from;
- c = utf8_nth(line, buffer->cpoff);
+ c = line + buffer->point_offset;
*c = '\0';
recompute_completions(0);
minibuffer_taint_hist();
*buffer->current_line->parent->line = '\0';
- buffer->cpoff = 0;
+ buffer->point_offset = 0;
recompute_completions(0);
}
blob - 84fb3401f3806491824997f7dbf3e61fa9e7b6bd
blob + 39a65d822fa0094de2c922da93c1c315408ff2b9
--- minibuffer.c
+++ minibuffer.c
#include <stdlib.h>
#include <string.h>
+#include <grapheme.h>
+
#include "certs.h"
#include "cmd.h"
#include "defaults.h"
minibuffer_taint_hist();
strlcpy(ministate.buf, vl->parent->line, sizeof(ministate.buf));
- ministate.buffer.cpoff = ministate.vline.cplen = utf8_cplen(ministate.buf);
+ ministate.buffer.point_offset = strlen(ministate.buf);
+ ministate.vline.len = strlen(ministate.buf);
return 0;
}
ministate.editing = 1;
strlcpy(ministate.buf, hist_cur(ministate.hist),
sizeof(ministate.buf));
- ministate.buffer.cpoff = 0;
- ministate.vline.cplen = utf8_cplen(ministate.buf);
+ ministate.buffer.point_offset = 0;
ministate.buffer.current_line->parent->line = ministate.buf;
}
if (thiskey.cp == 0)
return;
- len = utf8_encode(thiskey.cp, tmp);
- c = utf8_nth(ministate.buffer.current_line->parent->line,
- ministate.buffer.cpoff);
+ len = grapheme_encode_utf8(thiskey.cp, tmp, sizeof(tmp));
+
+ c = ministate.buffer.current_line->parent->line
+ + ministate.buffer.current_line->from
+ + ministate.buffer.point_offset;
if (c + len > ministate.buf + sizeof(ministate.buf) - 1)
return;
memmove(c + len, c, strlen(c)+1);
memcpy(c, tmp, len);
- ministate.buffer.cpoff++;
+ ministate.buffer.point_offset += len;
recompute_completions(1);
}
if (ministate.abortfn == NULL)
ministate.abortfn = exit_minibuffer;
- ministate.buffer.cpoff = 0;
if (minibuffer->input) {
strlcpy(ministate.buf, minibuffer->input,
sizeof(ministate.buf));
- ministate.vline.cplen = utf8_cplen(ministate.buf);
- ministate.buffer.cpoff = ministate.vline.cplen;
+ ministate.buffer.point_offset = strlen(ministate.buf);
+ ministate.vline.len = strlen(ministate.buf);
} else {
ministate.buf[0] = '\0';
- ministate.vline.cplen = ministate.buffer.cpoff = 0;
+ ministate.buffer.point_offset = 0;
+ ministate.vline.len = 0;
}
ministate.buffer.current_line = &ministate.vline;
blob - 3520b8ccfe4a9e44bc7f12180e6c0e5c85bddfdc
blob + 3f7a73e3c48f1a88a5ba2c6846e2c4930cd0f8bc
--- telescope.h
+++ telescope.h
struct line *parent;
size_t from;
size_t len;
- size_t cplen;
#define L_CONTINUATION 0x2
int flags;
size_t line_max;
struct vline *top_line;
struct vline *current_line;
- size_t cpoff;
+ size_t point_offset;
TAILQ_HEAD(, line) head;
TAILQ_HEAD(vhead, vline) vhead;
blob - f4317da5b1180f1a70852db4ec5e016213c36217
blob + 81a4a7734f9793f8d8ad1985024d95075580c30e
--- ui.c
+++ ui.c
place->line_off = buffer->line_off;
place->top_line = buffer->top_line;
place->current_line = buffer->current_line;
- place->cpoff = buffer->cpoff;
+ place->point_offset = buffer->point_offset;
}
void
buffer->line_off = place->line_off;
buffer->top_line = place->top_line;
buffer->current_line = place->current_line;
- buffer->cpoff = place->cpoff;
+ buffer->point_offset = place->point_offset;
}
static void
vl = buffer->current_line;
if (vl == NULL || vl->len == 0 || vl->parent == NULL)
- buffer->curs_x = buffer->cpoff = 0;
+ buffer->curs_x = buffer->point_offset = 0;
else if (vl->parent->data != NULL) {
text = vl->parent->data;
- buffer->curs_x = utf8_snwidth(text + 1, buffer->cpoff) + 1;
+ buffer->curs_x = utf8_snwidth(text, buffer->point_offset);
} else {
text = vl->parent->line + vl->from;
- buffer->curs_x = utf8_snwidth(text, buffer->cpoff);
+ buffer->curs_x = utf8_snwidth(text, buffer->point_offset);
}
/* small hack: don't olivetti-mode the download pane */
if (!ministate.editing)
start = hist_cur(ministate.hist);
line = buffer->current_line->parent->line + buffer->current_line->from;
- c = utf8_nth(line, buffer->cpoff);
+ c = line + buffer->point_offset;
while (utf8_swidth_between(start, c) > (size_t)COLS/2) {
start = utf8_next_cp(start);
}
blob - 045a2712523fc2f2729b7404174da25a8da3616b
blob + d7061ea4db14f8fe650c8b087523e180da9efec8
--- ui.h
+++ ui.h
size_t line_off;
struct vline *current_line;
struct vline *top_line;
- size_t cpoff;
+ size_t point_offset;
};
enum pairs {
blob - 1433aacce3f0e55b5875538c3ce4bd8fcea4e490
blob + e0e97f5607bfff0056604783be9887e989c3a1bc
--- utf8.c
+++ utf8.c
return wcwidth((wchar_t)cp);
}
-/* NOTE: n is the number of codepoints, NOT the byte length. In
- * other words, s MUST be NUL-terminated. */
size_t
-utf8_snwidth(const char *s, size_t n)
+utf8_snwidth(const char *s, size_t off)
{
size_t i, tot;
uint32_t cp = 0, state = 0;
tot = 0;
- for (i = 0; *s && i < n; ++s)
- if (!decode(&state, &cp, *s)) {
- i++;
+ for (i = 0; i < off; ++i)
+ if (!decode(&state, &cp, s[i]))
tot += utf8_chwidth(cp);
- }
return tot;
}
blob - 3054f79000e3cbe7f8e905d1994cc436fccd7cf4
blob + b60ff4d9cc3db8f1cb3223f1a45a3768914373de
--- wrap.c
+++ wrap.c
if (len != 0) {
vl->from = buf - l->line;
vl->len = len;
- vl->cplen = utf8_ncplen(buf, vl->len);
}
vl->flags = flags;