Introduction
Introduction Statistics Contact Development Disclaimer Help
tvi: yank and put - neatvi - [fork] simple vi-type editor with UTF-8 support
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
commit 01c3c8a62f1daee16d343488699f804c72dbca91
parent f80a244199b5d2735fcdd0abd4664346ba51dd32
Author: Ali Gholami Rudi <[email protected]>
Date: Tue, 5 May 2015 12:17:59 +0430
vi: yank and put
Diffstat:
M Makefile | 2 +-
A reg.c | 26 ++++++++++++++++++++++++++
M uc.c | 28 ++++++++++++++++++++++++++++
M vi.c | 134 ++++++++++++++++++++---------…
M vi.h | 8 ++++++++
5 files changed, 148 insertions(+), 50 deletions(-)
---
diff --git a/Makefile b/Makefile
t@@ -2,7 +2,7 @@ CC = cc
CFLAGS = -Wall -O2
LDFLAGS =
-OBJS = vi.o ex.o lbuf.o sbuf.o ren.o led.o uc.o term.o
+OBJS = vi.o ex.o lbuf.o sbuf.o ren.o reg.o led.o uc.o term.o
all: vi
%.o: %.c
diff --git a/reg.c b/reg.c
t@@ -0,0 +1,26 @@
+#include <stdlib.h>
+#include <string.h>
+#include "vi.h"
+
+static char *reg;
+static int lnmode;
+
+char *reg_get(int c, int *ln)
+{
+ *ln = lnmode;
+ return reg;
+}
+
+void reg_put(int c, char *s, int ln)
+{
+ char *nreg = malloc(strlen(s) + 1);
+ strcpy(nreg, s);
+ free(reg);
+ reg = nreg;
+ lnmode = ln;
+}
+
+void reg_done(void)
+{
+ free(reg);
+}
diff --git a/uc.c b/uc.c
t@@ -94,6 +94,34 @@ char **uc_chop(char *s, int *n)
return chrs;
}
+char *uc_chr(char *s, int off)
+{
+ int i = 0;
+ while (s && *s) {
+ if (i++ == off)
+ return s;
+ s = uc_next(s);
+ }
+ return s && (off < 0 || i == off) ? s : "";
+}
+
+char *uc_sub(char *s, int beg, int end)
+{
+ char *sbeg = uc_chr(s, beg);
+ char *send = uc_chr(s, end);
+ int len = sbeg && send && sbeg <= send ? send - sbeg : 0;
+ char *r = malloc(len + 1);
+ memcpy(r, sbeg, len);
+ r[len] = '\0';
+ return r;
+}
+
+char *uc_dup(char *s)
+{
+ char *r = malloc(strlen(s) + 1);
+ return r ? strcpy(r, s) : NULL;
+}
+
int uc_isspace(char *s)
{
int c = s ? (unsigned char) *s : 0;
diff --git a/vi.c b/vi.c
t@@ -98,17 +98,14 @@ static char *lbuf_chr(struct lbuf *lb, int r, int c)
{
static char chr[8];
char *ln = lbuf_get(lb, r);
- int n;
if (ln) {
- char **chrs = uc_chop(ln, &n);
int off = ren_off(ln, c);
- if (off >= 0 && off < n) {
- memcpy(chr, chrs[off], uc_len(chrs[off]));
- chr[uc_len(chr)] = '\0';
- free(chrs);
+ char *s = uc_chr(ln, off);
+ if (s) {
+ memcpy(chr, s, uc_len(s));
+ chr[uc_len(s)] = '\0';
return chr;
}
- free(chrs);
}
return "";
}
t@@ -364,30 +361,6 @@ static int vi_motion(int *row, int *col, int pre1, int pr…
return c;
}
-static char *vi_strprefix(char *s, int off)
-{
- struct sbuf *sb = sbuf_make();
- int n;
- char **chrs = uc_chop(s ? s : "", &n);
- if (n > 0)
- sbuf_mem(sb, s, chrs[MIN(n - 1, off)] - s);
- free(chrs);
- return sbuf_done(sb);
-}
-
-static char *vi_strpostfix(char *s, int off)
-{
- struct sbuf *sb = sbuf_make();
- int n;
- char **chrs = uc_chop(s ? s : "", &n);
- if (n >= 0 && off < n)
- sbuf_str(sb, chrs[off]);
- free(chrs);
- if (!sbuf_len(sb))
- sbuf_chr(sb, '\n');
- return sbuf_done(sb);
-}
-
static void swap(int *a, int *b)
{
int t = *a;
t@@ -395,10 +368,23 @@ static void swap(int *a, int *b)
*b = t;
}
-static char *sdup(char *s) /* strdup() */
+static char *lbuf_region(struct lbuf *lb, int r1, int l1, int r2, int l2)
{
- char *r = malloc(strlen(s) + 1);
- return r ? strcpy(r, s) : NULL;
+ struct sbuf *sb;
+ char *s1, *s2, *s3;
+ if (r1 == r2)
+ return uc_sub(lbuf_get(lb, r1), l1, l2);
+ sb = sbuf_make();
+ s1 = uc_sub(lbuf_get(lb, r1), l1, -1);
+ s3 = uc_sub(lbuf_get(lb, r2), 0, l2);
+ s2 = lbuf_cp(lb, r1 + 1, r2);
+ sbuf_str(sb, s1);
+ sbuf_str(sb, s2);
+ sbuf_str(sb, s3);
+ free(s1);
+ free(s2);
+ free(s3);
+ return sbuf_done(sb);
}
static void vc_motion(int c, int pre1)
t@@ -429,14 +415,34 @@ static void vc_motion(int c, int pre1)
swap(&r1, &r2);
swap(&c1, &c2);
}
+ if (c == 'y') { /* adjusting cursor pos…
+ xrow = r1;
+ xcol = ln ? xcol : c1;
+ }
for (i = 0; i < 2; i++) {
l1 = ren_insertionoffset(lbuf_get(xb, r1), c1, 1);
l2 = ren_insertionoffset(lbuf_get(xb, r2), c2, !closed);
if (r1 == r2 && l2 < l1) /* offsets out of order */
swap(&l1, &l2);
}
- pref = ln ? sdup("") : vi_strprefix(lbuf_get(xb, r1), l1);
- post = ln ? sdup("\n") : vi_strpostfix(lbuf_get(xb, r2), l2);
+ pref = ln ? uc_dup("") : uc_sub(lbuf_get(xb, r1), 0, l1);
+ post = ln ? uc_dup("\n") : uc_sub(lbuf_get(xb, r2), l2, -1);
+ if (c == 'c' || c == 'd' || c == 'y') {
+ char *region = lbuf_region(xb, r1, ln ? 0 : l1, r2, ln ? -1 : …
+ reg_put(0, region, ln);
+ free(region);
+ }
+ if (c == 'c') {
+ int row, col;
+ char *rep = led_input(pref, post, &row, &col);
+ if (rep) {
+ lbuf_rm(xb, r1, r2 + 1);
+ lbuf_put(xb, r1, rep);
+ xrow = r1 + row;
+ xcol = col;
+ free(rep);
+ }
+ }
if (c == 'd') {
lbuf_rm(xb, r1, r2 + 1);
if (!ln) {
t@@ -451,17 +457,6 @@ static void vc_motion(int c, int pre1)
if (ln)
lbuf_postindents(xb, &xrow, &xcol);
}
- if (c == 'c') {
- int row, col;
- char *rep = led_input(pref, post, &row, &col);
- if (rep) {
- lbuf_rm(xb, r1, r2 + 1);
- lbuf_put(xb, r1, rep);
- xrow = r1 + row;
- xcol = col;
- free(rep);
- }
- }
free(pref);
free(post);
}
t@@ -486,8 +481,8 @@ static void vc_insert(int cmd)
off = ln ? ren_insertionoffset(ln, xcol, 1) : 0;
if (cmd == 'a' || cmd == 'A')
off = ln ? ren_insertionoffset(ln, xcol, 0) : 0;
- pref = ln ? vi_strprefix(ln, off) : sdup("");
- post = ln ? vi_strpostfix(ln, off) : sdup("\n");
+ pref = ln ? uc_sub(ln, 0, off) : uc_dup("");
+ post = ln ? uc_sub(ln, off, -1) : uc_dup("\n");
rep = led_input(pref, post, &row, &col);
if (rep) {
if (cmd != 'o' && cmd != 'O')
t@@ -501,6 +496,40 @@ static void vc_insert(int cmd)
free(post);
}
+static void vc_put(int cmd, int cnt)
+{
+ int lnmode;
+ char *ln;
+ char *buf = reg_get(0, &lnmode);
+ struct sbuf *sb;
+ int off;
+ int i;
+ if (!buf)
+ return;
+ ln = lnmode ? NULL : lbuf_get(xb, xrow);
+ off = ln ? ren_insertionoffset(ln, xcol, cmd == 'P') : 0;
+ if (cmd == 'p' && !ln)
+ xrow++;
+ sb = sbuf_make();
+ if (ln) {
+ char *s = uc_sub(ln, 0, off);
+ sbuf_str(sb, s);
+ free(s);
+ }
+ for (i = 0; i < MAX(cnt, 1); i++)
+ sbuf_str(sb, buf);
+ if (ln) {
+ char *s = uc_sub(ln, off, -1);
+ sbuf_str(sb, s);
+ free(s);
+ }
+ if (ln)
+ lbuf_rm(xb, xrow, xrow + 1);
+ lbuf_put(xb, xrow, sbuf_buf(sb));
+ sbuf_free(sb);
+
+}
+
static void vi(void)
{
int mark;
t@@ -559,6 +588,7 @@ static void vi(void)
break;
case 'c':
case 'd':
+ case 'y':
vc_motion(c, pre1);
redraw = 1;
break;
t@@ -575,6 +605,11 @@ static void vi(void)
if ((mark = vi_read()) > 0 && isalpha(mark))
lbuf_mark(xb, mark, xrow);
break;
+ case 'p':
+ case 'P':
+ vc_put(c, pre1);
+ redraw = 1;
+ break;
default:
continue;
}
t@@ -618,5 +653,6 @@ int main(int argc, char *argv[])
else
ex();
lbuf_free(xb);
+ reg_done();
return 0;
}
diff --git a/vi.h b/vi.h
t@@ -48,12 +48,20 @@ int ren_last(char *s);
int ren_cmp(char *s, int pos1, int pos2);
int ren_insertionoffset(char *s, int pos, int pre);
+/* string registers */
+char *reg_get(int c, int *lnmode);
+void reg_put(int c, char *s, int lnmode);
+void reg_done(void);
+
/* utf-8 helper functions */
int uc_len(char *s);
int uc_dir(char *s);
int uc_wid(char *s);
int uc_slen(char *s);
int uc_code(char *s);
+char *uc_chr(char *s, int off);
+char *uc_sub(char *s, int beg, int end);
+char *uc_dup(char *s);
int uc_isspace(char *s);
int uc_isprint(char *s);
int uc_isdigit(char *s);
You are viewing proxied material from mx1.adamsgaard.dk. 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.