tlbuf: preserve marks during change and delete commands - neatvi - [fork] simpl… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit 70f7eb3e153a4b749d07c242945d4a693085c6fc | |
parent 86c9ce2ce6d2ca663846199b322fcb341e23d527 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Thu, 3 Sep 2015 18:22:28 +0430 | |
lbuf: preserve marks during change and delete commands | |
Also, the undo command restores the marks inside the changing region. | |
Diffstat: | |
M ex.c | 29 +++++++++++++---------------- | |
M lbuf.c | 171 ++++++++++++++---------------… | |
M vi.c | 41 ++++++++++++-----------------… | |
M vi.h | 5 ++--- | |
4 files changed, 110 insertions(+), 136 deletions(-) | |
--- | |
diff --git a/ex.c b/ex.c | |
t@@ -336,8 +336,7 @@ static int ec_edit(char *ec) | |
bufs_switch(bufs_open(path)); | |
fd = open(ex_path(), O_RDONLY); | |
if (fd >= 0) { | |
- lbuf_rm(xb, 0, lbuf_len(xb)); | |
- lbuf_rd(xb, fd, 0); | |
+ lbuf_rd(xb, fd, 0, lbuf_len(xb)); | |
close(fd); | |
snprintf(msg, sizeof(msg), "\"%s\" %d lines [r]\n", | |
ex_path(), lbuf_len(xb)); | |
t@@ -362,19 +361,21 @@ static int ec_read(char *ec) | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
if (arg[0] == '!') { | |
+ int pos = MIN(xrow + 1, lbuf_len(xb)); | |
if (ex_expand(arg, ex_argeol(ec))) | |
return 1; | |
obuf = cmd_pipe(arg + 1, NULL, 0, 1); | |
if (obuf) | |
- lbuf_put(xb, MIN(xrow + 1, lbuf_len(xb)), obuf); | |
+ lbuf_edit(xb, obuf, pos, pos); | |
free(obuf); | |
} else { | |
int fd = open(path, O_RDONLY); | |
+ int pos = lbuf_len(xb) ? end : 0; | |
if (fd < 0) { | |
ex_show("read failed\n"); | |
return 1; | |
} | |
- lbuf_rd(xb, fd, lbuf_len(xb) ? end : 0); | |
+ lbuf_rd(xb, fd, pos, pos); | |
close(fd); | |
} | |
xrow = end + lbuf_len(xb) - n - 1; | |
t@@ -445,11 +446,6 @@ static int ec_insert(char *ec) | |
ex_loc(ec, loc); | |
if (ex_region(loc, &beg, &end) && (beg != 0 || end != 0)) | |
return 1; | |
- if (cmd[0] == 'c') { | |
- if (lbuf_len(xb)) | |
- lbuf_rm(xb, beg, end); | |
- end = beg + 1; | |
- } | |
sb = sbuf_make(); | |
while ((s = ex_read(""))) { | |
if (!strcmp(".", s)) { | |
t@@ -461,10 +457,12 @@ static int ec_insert(char *ec) | |
free(s); | |
} | |
if (cmd[0] == 'a') | |
- if (end > lbuf_len(xb)) | |
- end = lbuf_len(xb); | |
+ if (beg + 1 <= lbuf_len(xb)) | |
+ beg++; | |
+ if (cmd[0] != 'c') | |
+ end = beg; | |
n = lbuf_len(xb); | |
- lbuf_put(xb, end, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), beg, end); | |
xrow = MIN(lbuf_len(xb) - 1, end + lbuf_len(xb) - n - 1); | |
sbuf_free(sb); | |
return 0; | |
t@@ -522,7 +520,7 @@ static int ec_delete(char *ec) | |
if (ex_region(loc, &beg, &end) || !lbuf_len(xb)) | |
return 1; | |
ex_yank(arg[0], beg, end); | |
- lbuf_rm(xb, beg, end); | |
+ lbuf_edit(xb, NULL, beg, end); | |
xrow = beg; | |
return 0; | |
} | |
t@@ -553,7 +551,7 @@ static int ec_put(char *ec) | |
buf = reg_get(arg[0], &lnmode); | |
if (!buf || ex_region(loc, &beg, &end)) | |
return 1; | |
- lbuf_put(xb, end, buf); | |
+ lbuf_edit(xb, buf, end, end); | |
xrow = MIN(lbuf_len(xb) - 1, end + lbuf_len(xb) - n - 1); | |
return 0; | |
} | |
t@@ -647,8 +645,7 @@ static int ec_substitute(char *ec) | |
break; | |
} | |
sbuf_str(r, ln); | |
- lbuf_rm(xb, i, i + 1); | |
- lbuf_put(xb, i, sbuf_buf(r)); | |
+ lbuf_edit(xb, sbuf_buf(r), i, i + 1); | |
sbuf_free(r); | |
} | |
rset_free(re); | |
diff --git a/lbuf.c b/lbuf.c | |
t@@ -1,3 +1,4 @@ | |
+#include <ctype.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
t@@ -8,9 +9,9 @@ | |
/* line operations */ | |
struct lopt { | |
- char *buf; /* text inserted or deleted */ | |
- int ins; /* insertion operation if non-zero */ | |
- int beg, end; | |
+ char *ins; /* inserted text */ | |
+ char *del; /* deleted text */ | |
+ int pos, n_ins, n_del; /* modification location */ | |
int seq; /* operation number */ | |
int *mark, *mark_off; /* saved marks */ | |
}; | |
t@@ -27,7 +28,6 @@ struct lbuf { | |
int hist_sz; /* size of hist[] */ | |
int hist_n; /* current history head in hist[] */ | |
int hist_u; /* current undo head in hist[] */ | |
- int mod_new; /* clear modification marks */ | |
int useq_zero; /* useq for lbuf_saved() */ | |
int useq_last; /* useq before hist[] */ | |
}; | |
t@@ -45,11 +45,33 @@ struct lbuf *lbuf_make(void) | |
static void lopt_done(struct lopt *lo) | |
{ | |
- free(lo->buf); | |
+ free(lo->ins); | |
+ free(lo->del); | |
free(lo->mark); | |
free(lo->mark_off); | |
} | |
+static void lbuf_savemark(struct lbuf *lb, struct lopt *lo, int m) | |
+{ | |
+ if (lb->mark[m] >= 0) { | |
+ if (!lo->mark) { | |
+ lo->mark = malloc(sizeof(lb->mark)); | |
+ lo->mark_off = malloc(sizeof(lb->mark_off)); | |
+ memset(lo->mark, 0xff, sizeof(lb->mark)); | |
+ } | |
+ lo->mark[m] = lb->mark[m]; | |
+ lo->mark_off[m] = lb->mark_off[m]; | |
+ } | |
+} | |
+ | |
+static void lbuf_loadmark(struct lbuf *lb, struct lopt *lo, int m) | |
+{ | |
+ if (lo->mark && lo->mark[m] >= 0) { | |
+ lb->mark[m] = lo->mark[m]; | |
+ lb->mark_off[m] = lo->mark_off[m]; | |
+ } | |
+} | |
+ | |
void lbuf_free(struct lbuf *lb) | |
{ | |
int i; | |
t@@ -79,51 +101,46 @@ static void lbuf_insertline(struct lbuf *lb, int pos, cha… | |
lb->ln[pos] = s; | |
} | |
-/* low-level insertion */ | |
-static void lbuf_insert(struct lbuf *lb, int pos, char *s) | |
+/* low-level replacement */ | |
+static void lbuf_replace(struct lbuf *lb, char *s, int pos, int n_del) | |
{ | |
- int lb_len = lbuf_len(lb); | |
- int beg = pos, end; | |
char *r; | |
+ int n_ins = 0; | |
int i; | |
- while ((r = strchr(s, '\n'))) { | |
+ for (i = 0; i < n_del; i++) | |
+ free(lb->ln[pos + i]); | |
+ memmove(lb->ln + pos, lb->ln + pos + n_del, | |
+ (lb->ln_n - pos - n_del) * sizeof(lb->ln[0])); | |
+ lb->ln_n -= n_del; | |
+ while (s && (r = strchr(s, '\n'))) { | |
char *n = malloc(r - s + 2); | |
memcpy(n, s, r - s + 1); | |
n[r - s + 1] = '\0'; | |
- lbuf_insertline(lb, pos++, n); | |
+ lbuf_insertline(lb, pos + n_ins++, n); | |
s = r + 1; | |
} | |
- for (i = 0; i < LEN(lb->mark); i++) /* updating marks */ | |
- if (lb->mark[i] >= pos) | |
- lb->mark[i] += lbuf_len(lb) - lb_len; | |
- end = beg + lbuf_len(lb) - lb_len; | |
- if (lb->mod_new || lb->mark['['] < 0 || lb->mark['['] > beg) | |
- lbuf_mark(lb, '[', beg, 0); | |
- if (lb->mod_new || lb->mark[']'] < 0 || lb->mark[']'] < end - 1) | |
- lbuf_mark(lb, ']', end - 1, 0); | |
- lb->mod_new = 0; | |
+ for (i = 0; i < LEN(lb->mark); i++) { /* updating marks */ | |
+ if (!s && lb->mark[i] >= pos && lb->mark[i] < pos + n_del) | |
+ lb->mark[i] = -1; | |
+ else if (lb->mark[i] >= pos + n_del) | |
+ lb->mark[i] += n_ins - n_del; | |
+ else if (lb->mark[i] >= pos + n_ins) | |
+ lb->mark[i] = pos + n_ins - 1; | |
+ } | |
+ lbuf_mark(lb, '[', pos, 0); | |
+ lbuf_mark(lb, ']', pos + n_ins - n_del, 0); | |
} | |
-/* low-level deletion */ | |
-static void lbuf_delete(struct lbuf *lb, int beg, int end) | |
+static int uc_newlines(char *s) | |
{ | |
- int i; | |
- for (i = beg; i < end; i++) | |
- free(lb->ln[i]); | |
- memmove(lb->ln + beg, lb->ln + end, (lb->ln_n - end) * sizeof(lb->ln[0… | |
- lb->ln_n -= end - beg; | |
- for (i = 0; i < LEN(lb->mark); i++) /* updating marks */ | |
- if (lb->mark[i] > beg) | |
- lb->mark[i] = MAX(beg, lb->mark[i] + beg - end); | |
- if (lb->mod_new || lb->mark['['] < 0 || lb->mark['['] > beg) | |
- lbuf_mark(lb, '[', beg, 0); | |
- if (lb->mod_new || lb->mark[']'] < 0 || lb->mark[']'] < beg) | |
- lbuf_mark(lb, ']', beg, 0); | |
- lb->mod_new = 0; | |
+ int n; | |
+ for (n = 0; (s = strchr(s, '\n')); n++) | |
+ s++; | |
+ return n; | |
} | |
/* append undo/redo history */ | |
-static void lbuf_opt(struct lbuf *lb, int ins, int beg, int end) | |
+static void lbuf_opt(struct lbuf *lb, char *buf, int pos, int n_del) | |
{ | |
struct lopt *lo; | |
int i; | |
t@@ -142,14 +159,19 @@ static void lbuf_opt(struct lbuf *lb, int ins, int beg, … | |
lb->hist_n++; | |
lb->hist_u = lb->hist_n; | |
memset(lo, 0, sizeof(*lo)); | |
- lo->ins = ins; | |
- lo->beg = beg; | |
- lo->end = end; | |
- lo->buf = lbuf_cp(lb, beg, end); | |
+ lo->pos = pos; | |
+ lo->n_del = n_del; | |
+ lo->del = n_del ? lbuf_cp(lb, pos, pos + n_del) : NULL; | |
+ lo->n_ins = buf ? uc_newlines(buf) : 0; | |
+ lo->ins = buf ? uc_dup(buf) : NULL; | |
lo->seq = lb->useq; | |
+ for (i = 0; i < LEN(lb->mark); i++) | |
+ if (lb->mark[i] >= pos && lb->mark[i] < pos + n_del) | |
+ if (isalpha(i)) | |
+ lbuf_savemark(lb, lo, i); | |
} | |
-void lbuf_rd(struct lbuf *lbuf, int fd, int pos) | |
+void lbuf_rd(struct lbuf *lbuf, int fd, int beg, int end) | |
{ | |
char buf[1 << 10]; | |
struct sbuf *sb; | |
t@@ -157,7 +179,7 @@ void lbuf_rd(struct lbuf *lbuf, int fd, int pos) | |
sb = sbuf_make(); | |
while ((nr = read(fd, buf, sizeof(buf))) > 0) | |
sbuf_mem(sb, buf, nr); | |
- lbuf_put(lbuf, pos, sbuf_buf(sb)); | |
+ lbuf_edit(lbuf, sbuf_buf(sb), beg, end); | |
sbuf_free(sb); | |
} | |
t@@ -168,23 +190,17 @@ void lbuf_wr(struct lbuf *lbuf, int fd, int beg, int end) | |
write(fd, lbuf->ln[i], strlen(lbuf->ln[i])); | |
} | |
-void lbuf_rm(struct lbuf *lb, int beg, int end) | |
+/* replace lines beg through end with buf */ | |
+void lbuf_edit(struct lbuf *lb, char *buf, int beg, int end) | |
{ | |
+ if (beg > lb->ln_n) | |
+ beg = lb->ln_n; | |
if (end > lb->ln_n) | |
end = lb->ln_n; | |
- if (beg == end) | |
- return; | |
- lbuf_opt(lb, 0, beg, end); | |
- lbuf_delete(lb, beg, end); | |
-} | |
- | |
-void lbuf_put(struct lbuf *lb, int pos, char *s) | |
-{ | |
- int lb_len = lbuf_len(lb); | |
- if (!*s) | |
+ if (beg == end && !buf) | |
return; | |
- lbuf_insert(lb, pos, s); | |
- lbuf_opt(lb, 1, pos, pos + lbuf_len(lb) - lb_len); | |
+ lbuf_opt(lb, buf, beg, end - beg); | |
+ lbuf_replace(lb, buf, beg, end - beg); | |
} | |
char *lbuf_cp(struct lbuf *lb, int beg, int end) | |
t@@ -226,42 +242,18 @@ int lbuf_jump(struct lbuf *lbuf, int mark, int *pos, int… | |
return 0; | |
} | |
-static void lbuf_savemarks(struct lbuf *lb, struct lopt *lo) | |
-{ | |
- int i; | |
- lo->mark = malloc(sizeof(lb->mark)); | |
- lo->mark_off = malloc(sizeof(lb->mark_off)); | |
- for (i = 0; i < LEN(lb->mark); i++) | |
- lo->mark[i] = -1; | |
- lo->mark['*'] = lb->mark['*']; | |
- lo->mark_off['*'] = lb->mark_off['*']; | |
-} | |
- | |
-static void lbuf_loadmarks(struct lbuf *lb, struct lopt *lo) | |
-{ | |
- int i; | |
- for (i = 0; lo->mark && i < LEN(lb->mark); i++) { | |
- if (lo->mark[i] >= 0) { | |
- lb->mark[i] = lo->mark[i]; | |
- lb->mark_off[i] = lo->mark_off[i]; | |
- } | |
- } | |
-} | |
- | |
int lbuf_undo(struct lbuf *lb) | |
{ | |
- int useq; | |
+ int useq, i; | |
if (!lb->hist_u) | |
return 1; | |
useq = lb->hist[lb->hist_u - 1].seq; | |
- lb->mod_new = 1; | |
while (lb->hist_u && lb->hist[lb->hist_u - 1].seq == useq) { | |
struct lopt *lo = &lb->hist[--(lb->hist_u)]; | |
- if (lo->ins) | |
- lbuf_delete(lb, lo->beg, lo->end); | |
- else | |
- lbuf_insert(lb, lo->beg, lo->buf); | |
- lbuf_loadmarks(lb, lo); | |
+ lbuf_replace(lb, lo->del, lo->pos, lo->n_ins); | |
+ lbuf_loadmark(lb, lo, '*'); | |
+ for (i = 0; i < LEN(lb->mark); i++) | |
+ lbuf_loadmark(lb, lo, i); | |
} | |
return 0; | |
} | |
t@@ -272,14 +264,10 @@ int lbuf_redo(struct lbuf *lb) | |
if (lb->hist_u == lb->hist_n) | |
return 1; | |
useq = lb->hist[lb->hist_u].seq; | |
- lb->mod_new = 1; | |
while (lb->hist_u < lb->hist_n && lb->hist[lb->hist_u].seq == useq) { | |
struct lopt *lo = &lb->hist[lb->hist_u++]; | |
- if (lo->ins) | |
- lbuf_insert(lb, lo->beg, lo->buf); | |
- else | |
- lbuf_delete(lb, lo->beg, lo->end); | |
- lbuf_loadmarks(lb, lo); | |
+ lbuf_replace(lb, lo->ins, lo->pos, lo->n_del); | |
+ lbuf_loadmark(lb, lo, '*'); | |
} | |
return 0; | |
} | |
t@@ -309,8 +297,7 @@ int lbuf_modified(struct lbuf *lb) | |
{ | |
struct lopt *lo = lb->hist_n ? &lb->hist[lb->hist_n - 1] : NULL; | |
if (lb->hist_u == lb->hist_n && lo && !lo->mark) | |
- lbuf_savemarks(lb, lo); | |
- lb->mod_new = 1; | |
+ lbuf_savemark(lb, lo, '*'); | |
lb->useq++; | |
return lbuf_seq(lb) != lb->useq_zero; | |
} | |
diff --git a/vi.c b/vi.c | |
t@@ -572,13 +572,14 @@ static void vi_delete(int r1, int o1, int r2, int o2, in… | |
free(region); | |
pref = lnmode ? uc_dup("") : uc_sub(lbuf_get(xb, r1), 0, o1); | |
post = lnmode ? uc_dup("\n") : uc_sub(lbuf_get(xb, r2), o2, -1); | |
- lbuf_rm(xb, r1, r2 + 1); | |
if (!lnmode) { | |
struct sbuf *sb = sbuf_make(); | |
sbuf_str(sb, pref); | |
sbuf_str(sb, post); | |
- lbuf_put(xb, r1, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), r1, r2 + 1); | |
sbuf_free(sb); | |
+ } else { | |
+ lbuf_edit(xb, NULL, r1, r2 + 1); | |
} | |
xrow = r1; | |
xoff = lnmode ? lbuf_indents(xb, xrow) : o1; | |
t@@ -653,8 +654,7 @@ static void vi_change(int r1, int o1, int r2, int o2, int … | |
vi_drawrm(r1, r2, 0); | |
rep = vi_input(pref, post, &row, &off); | |
if (rep) { | |
- lbuf_rm(xb, r1, r2 + 1); | |
- lbuf_put(xb, r1, rep); | |
+ lbuf_edit(xb, rep, r1, r2 + 1); | |
xrow = r1 + row - 1; | |
xoff = off; | |
free(rep); | |
t@@ -683,16 +683,15 @@ static void vi_case(int r1, int o1, int r2, int o2, int … | |
} | |
pref = lnmode ? uc_dup("") : uc_sub(lbuf_get(xb, r1), 0, o1); | |
post = lnmode ? uc_dup("\n") : uc_sub(lbuf_get(xb, r2), o2, -1); | |
- lbuf_rm(xb, r1, r2 + 1); | |
if (!lnmode) { | |
struct sbuf *sb = sbuf_make(); | |
sbuf_str(sb, pref); | |
sbuf_str(sb, region); | |
sbuf_str(sb, post); | |
- lbuf_put(xb, r1, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), r1, r2 + 1); | |
sbuf_free(sb); | |
} else { | |
- lbuf_put(xb, r1, region); | |
+ lbuf_edit(xb, region, r1, r2 + 1); | |
} | |
xrow = r2; | |
xoff = lnmode ? lbuf_indents(xb, r2) : o2; | |
t@@ -711,10 +710,8 @@ static void vi_pipe(int r1, int r2) | |
return; | |
text = lbuf_cp(xb, r1, r2 + 1); | |
rep = cmd_pipe(cmd, text, 1, 1); | |
- if (rep) { | |
- lbuf_rm(xb, r1, r2 + 1); | |
- lbuf_put(xb, r1, rep); | |
- } | |
+ if (rep) | |
+ lbuf_edit(xb, rep, r1, r2 + 1); | |
free(cmd); | |
free(text); | |
free(rep); | |
t@@ -734,8 +731,7 @@ static void vi_shift(int r1, int r2, int dir) | |
else | |
ln = ln[0] == ' ' || ln[0] == '\t' ? ln + 1 : ln; | |
sbuf_str(sb, ln); | |
- lbuf_rm(xb, i, i + 1); | |
- lbuf_put(xb, i, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), i, i + 1); | |
sbuf_free(sb); | |
} | |
xrow = r1; | |
t@@ -813,11 +809,9 @@ static int vc_insert(int cmd) | |
vi_drawrm(xrow, xrow, cmd == 'o' || cmd == 'O'); | |
rep = vi_input(pref, post, &row, &off); | |
if ((cmd == 'o' || cmd == 'O') && !lbuf_len(xb)) | |
- lbuf_put(xb, 0, "\n"); | |
+ lbuf_edit(xb, "\n", 0, 0); | |
if (rep) { | |
- if (cmd != 'o' && cmd != 'O') | |
- lbuf_rm(xb, xrow, xrow + 1); | |
- lbuf_put(xb, xrow, rep); | |
+ lbuf_edit(xb, rep, xrow, xrow + (cmd != 'o' && cmd != 'O')); | |
xrow += row - 1; | |
xoff = off; | |
free(rep); | |
t@@ -842,10 +836,10 @@ static int vc_put(int cmd) | |
for (i = 0; i < cnt; i++) | |
sbuf_str(sb, buf); | |
if (!lbuf_len(xb)) | |
- lbuf_put(xb, 0, "\n"); | |
+ lbuf_edit(xb, "\n", 0, 0); | |
if (cmd == 'p') | |
xrow++; | |
- lbuf_put(xb, xrow, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), xrow, xrow); | |
xoff = lbuf_indents(xb, xrow); | |
sbuf_free(sb); | |
} else { | |
t@@ -860,8 +854,7 @@ static int vc_put(int cmd) | |
s = uc_sub(ln, off, -1); | |
sbuf_str(sb, s); | |
free(s); | |
- lbuf_rm(xb, xrow, xrow + 1); | |
- lbuf_put(xb, xrow, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), xrow, xrow + 1); | |
xoff = off + uc_slen(buf) * cnt - 1; | |
sbuf_free(sb); | |
} | |
t@@ -903,8 +896,7 @@ static int vc_join(void) | |
sbuf_mem(sb, ln, lnend - ln); | |
} | |
sbuf_chr(sb, '\n'); | |
- lbuf_rm(xb, beg, end); | |
- lbuf_put(xb, beg, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), beg, end); | |
xoff = off; | |
sbuf_free(sb); | |
return 0; | |
t@@ -963,8 +955,7 @@ static int vc_replace(void) | |
for (i = 0; i < cnt; i++) | |
sbuf_str(sb, cs); | |
sbuf_str(sb, post); | |
- lbuf_rm(xb, xrow, xrow + 1); | |
- lbuf_put(xb, xrow, sbuf_buf(sb)); | |
+ lbuf_edit(xb, sbuf_buf(sb), xrow, xrow + 1); | |
off += cnt - 1; | |
xoff = off; | |
sbuf_free(sb); | |
diff --git a/vi.h b/vi.h | |
t@@ -8,11 +8,10 @@ | |
/* line buffer, managing a number of lines */ | |
struct lbuf *lbuf_make(void); | |
void lbuf_free(struct lbuf *lbuf); | |
-void lbuf_rd(struct lbuf *lbuf, int fd, int pos); | |
+void lbuf_rd(struct lbuf *lbuf, int fd, int beg, int end); | |
void lbuf_wr(struct lbuf *lbuf, int fd, int beg, int end); | |
-void lbuf_rm(struct lbuf *lbuf, int beg, int end); | |
+void lbuf_edit(struct lbuf *lbuf, char *s, int beg, int end); | |
char *lbuf_cp(struct lbuf *lbuf, int beg, int end); | |
-void lbuf_put(struct lbuf *lbuf, int pos, char *s); | |
char *lbuf_get(struct lbuf *lbuf, int pos); | |
int lbuf_len(struct lbuf *lbuf); | |
void lbuf_mark(struct lbuf *lbuf, int mark, int pos, int off); |