tex: pass three arguments to ex command functions - neatvi - [fork] simple vi-t… | |
git clone git://src.adamsgaard.dk/neatvi | |
Log | |
Files | |
Refs | |
README | |
--- | |
commit fb7b24e9ad8c6d7a9b8a3c9d3e3091a4cd8b4fd4 | |
parent 86745f7e230cc2ceb023cab75ff3105d713bb6d6 | |
Author: Ali Gholami Rudi <[email protected]> | |
Date: Sat, 25 Sep 2021 17:48:16 +0330 | |
ex: pass three arguments to ex command functions | |
Diffstat: | |
M ex.c | 274 +++++++++++------------------… | |
1 file changed, 94 insertions(+), 180 deletions(-) | |
--- | |
diff --git a/ex.c b/ex.c | |
t@@ -114,52 +114,8 @@ char *ex_filetype(void) | |
return bufs[0].ft; | |
} | |
-static char *ex_loc(char *src, char *loc); | |
-static char *ex_cmd(char *src, char *cmd); | |
-static char *ex_arg(char *src, char *arg); | |
- | |
-/* read ex command location */ | |
-static char *ex_loc(char *src, char *loc) | |
-{ | |
- while (*src == ':' || *src == ' ' || *src == '\t') | |
- src++; | |
- while (*src && !isalpha((unsigned char) *src) && *src != '=' && *src !… | |
- if (*src == '\'') | |
- *loc++ = *src++; | |
- if (*src == '/' || *src == '?') { | |
- int d = *src; | |
- *loc++ = *src++; | |
- while (*src && *src != d) { | |
- if (*src == '\\' && src[1]) | |
- *loc++ = *src++; | |
- *loc++ = *src++; | |
- } | |
- } | |
- if (*src) | |
- *loc++ = *src++; | |
- } | |
- *loc = '\0'; | |
- return src; | |
-} | |
- | |
-/* read ex command name */ | |
-static char *ex_cmd(char *src, char *cmd) | |
-{ | |
- char *cmd0 = cmd; | |
- src = ex_loc(src, cmd); | |
- while (*src == ' ' || *src == '\t') | |
- src++; | |
- while (isalpha((unsigned char) *src) && cmd < cmd0 + 16) | |
- if ((*cmd++ = *src++) == 'k' && cmd == cmd0 + 1) | |
- break; | |
- if (*src == '!' || *src == '=') | |
- *cmd++ = *src++; | |
- *cmd = '\0'; | |
- return src; | |
-} | |
- | |
-/* read ex file argument */ | |
-static char *ex_filearg(char *src, int spaceallowed) | |
+/* replace % and # in paths and commands with current and alternate path names… | |
+static char *ex_pathexpand(char *src, int spaceallowed) | |
{ | |
struct sbuf *sb = sbuf_make(); | |
while (*src && *src != '\n' && (spaceallowed || (*src != ' ' && *src !… | |
t@@ -280,7 +236,7 @@ static int ex_lineno(char **num) | |
return n; | |
} | |
-/* parse ex command location */ | |
+/* parse ex command addresses */ | |
static int ex_region(char *loc, int *beg, int *end) | |
{ | |
int naddr = 0; | |
t@@ -315,26 +271,24 @@ static int ex_region(char *loc, int *beg, int *end) | |
return 0; | |
} | |
-static int ec_write(char *ec); | |
+static int ec_write(char *loc, char *cmd, char *arg); | |
static int ex_modifiedbuffer(char *msg) | |
{ | |
if (!lbuf_modified(xb)) | |
return 0; | |
if (xaw && ex_path()[0]) | |
- return ec_write("w"); | |
+ return ec_write("", "w", ""); | |
if (msg) | |
ex_show(msg); | |
return 1; | |
} | |
-static int ec_buffer(char *ec) | |
+static int ec_buffer(char *loc, char *cmd, char *arg) | |
{ | |
- char arg[EXLEN]; | |
char ln[128]; | |
int id; | |
int i; | |
- ex_arg(ec, arg); | |
id = arg[0] ? atoi(arg) : 0; | |
for (i = 0; i < LEN(bufs) && bufs[i].lb; i++) { | |
if (id) { | |
t@@ -356,10 +310,8 @@ static int ec_buffer(char *ec) | |
return 0; | |
} | |
-static int ec_quit(char *ec) | |
+static int ec_quit(char *loc, char *cmd, char *arg) | |
{ | |
- char cmd[EXLEN]; | |
- ex_cmd(ec, cmd); | |
if (!strchr(cmd, '!')) | |
if (ex_modifiedbuffer("buffer modified\n")) | |
return 1; | |
t@@ -367,19 +319,15 @@ static int ec_quit(char *ec) | |
return 0; | |
} | |
-static int ec_edit(char *ec) | |
+static int ec_edit(char *loc, char *cmd, char *arg) | |
{ | |
char msg[128]; | |
- char cmd[EXLEN]; | |
- char arg[EXLEN]; | |
char *path; | |
int fd; | |
- ex_cmd(ec, cmd); | |
- ex_arg(ec, arg); | |
if (!strchr(cmd, '!')) | |
if (xb && ex_modifiedbuffer("buffer modified\n")) | |
return 1; | |
- if (!(path = ex_filearg(arg, 0))) | |
+ if (!(path = ex_pathexpand(arg, 0))) | |
return 1; | |
if (path[0] && bufs_find(path) >= 0) { | |
bufs_switch(bufs_find(path)); | |
t@@ -408,22 +356,19 @@ static int ec_edit(char *ec) | |
return 0; | |
} | |
-static int ec_read(char *ec) | |
+static int ec_read(char *loc, char *cmd, char *arg) | |
{ | |
- char arg[EXLEN], loc[EXLEN]; | |
char msg[128]; | |
int beg, end; | |
char *path; | |
char *obuf; | |
int n = lbuf_len(xb); | |
- ex_arg(ec, arg); | |
- ex_loc(ec, loc); | |
path = arg[0] ? arg : ex_path(); | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
if (arg[0] == '!') { | |
int pos = MIN(xrow + 1, lbuf_len(xb)); | |
- char *ecmd = ex_filearg(arg, 1); | |
+ char *ecmd = ex_pathexpand(arg, 1); | |
if (!ecmd) | |
return 1; | |
obuf = cmd_pipe(ecmd + 1, NULL, 0, 1); | |
t@@ -452,19 +397,15 @@ static int ec_read(char *ec) | |
return 0; | |
} | |
-static int ec_write(char *ec) | |
+static int ec_write(char *loc, char *cmd, char *arg) | |
{ | |
- char cmd[EXLEN], arg[EXLEN], loc[EXLEN]; | |
char msg[128]; | |
char *path; | |
char *ibuf; | |
int beg, end; | |
- ex_cmd(ec, cmd); | |
- ex_arg(ec, arg); | |
- ex_loc(ec, loc); | |
path = arg[0] ? arg : ex_path(); | |
if (cmd[0] == 'x' && !lbuf_modified(xb)) | |
- return ec_quit(cmd); | |
+ return ec_quit("", cmd, ""); | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
if (!loc[0]) { | |
t@@ -472,7 +413,7 @@ static int ec_write(char *ec) | |
end = lbuf_len(xb); | |
} | |
if (arg[0] == '!') { | |
- char *ecmd = ex_filearg(arg, 1); | |
+ char *ecmd = ex_pathexpand(arg, 1); | |
if (!ecmd) | |
return 1; | |
ibuf = lbuf_cp(xb, beg, end); | |
t@@ -516,20 +457,16 @@ static int ec_write(char *ec) | |
if (!strcmp(ex_path(), path)) | |
bufs[0].mtime = mtime(path); | |
if (cmd[0] == 'x' || (cmd[0] == 'w' && cmd[1] == 'q')) | |
- ec_quit(cmd); | |
+ ec_quit("", cmd, ""); | |
return 0; | |
} | |
-static int ec_insert(char *ec) | |
+static int ec_insert(char *loc, char *cmd, char *arg) | |
{ | |
- char arg[EXLEN], cmd[EXLEN], loc[EXLEN]; | |
struct sbuf *sb; | |
char *s; | |
int beg, end; | |
int n; | |
- ex_arg(ec, arg); | |
- ex_cmd(ec, cmd); | |
- ex_loc(ec, loc); | |
if (ex_region(loc, &beg, &end) && (beg != 0 || end != 0)) | |
return 1; | |
sb = sbuf_make(); | |
t@@ -554,13 +491,10 @@ static int ec_insert(char *ec) | |
return 0; | |
} | |
-static int ec_print(char *ec) | |
+static int ec_print(char *loc, char *cmd, char *arg) | |
{ | |
- char cmd[EXLEN], loc[EXLEN]; | |
int beg, end; | |
int i; | |
- ex_cmd(ec, cmd); | |
- ex_loc(ec, loc); | |
if (!cmd[0] && !loc[0]) | |
if (xrow >= lbuf_len(xb)) | |
return 1; | |
t@@ -573,13 +507,11 @@ static int ec_print(char *ec) | |
return 0; | |
} | |
-static int ec_null(char *ec) | |
+static int ec_null(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN]; | |
int beg, end; | |
if (!xvis) | |
- return ec_print(ec); | |
- ex_loc(ec, loc); | |
+ return ec_print(loc, cmd, arg); | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
xrow = MAX(beg, end - 1); | |
t@@ -594,13 +526,9 @@ static void ex_yank(int reg, int beg, int end) | |
free(buf); | |
} | |
-static int ec_delete(char *ec) | |
+static int ec_delete(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN]; | |
- char arg[EXLEN]; | |
int beg, end; | |
- ex_loc(ec, loc); | |
- ex_arg(ec, arg); | |
if (ex_region(loc, &beg, &end) || !lbuf_len(xb)) | |
return 1; | |
ex_yank(arg[0], beg, end); | |
t@@ -609,29 +537,21 @@ static int ec_delete(char *ec) | |
return 0; | |
} | |
-static int ec_yank(char *ec) | |
+static int ec_yank(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN]; | |
- char arg[EXLEN]; | |
int beg, end; | |
- ex_loc(ec, loc); | |
- ex_arg(ec, arg); | |
if (ex_region(loc, &beg, &end) || !lbuf_len(xb)) | |
return 1; | |
ex_yank(arg[0], beg, end); | |
return 0; | |
} | |
-static int ec_put(char *ec) | |
+static int ec_put(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN]; | |
- char arg[EXLEN]; | |
int beg, end; | |
int lnmode; | |
char *buf; | |
int n = lbuf_len(xb); | |
- ex_loc(ec, loc); | |
- ex_arg(ec, arg); | |
buf = reg_get(arg[0], &lnmode); | |
if (!buf || ex_region(loc, &beg, &end)) | |
return 1; | |
t@@ -640,12 +560,10 @@ static int ec_put(char *ec) | |
return 0; | |
} | |
-static int ec_lnum(char *ec) | |
+static int ec_lnum(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN]; | |
char msg[128]; | |
int beg, end; | |
- ex_loc(ec, loc); | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
sprintf(msg, "%d\n", end); | |
t@@ -653,22 +571,19 @@ static int ec_lnum(char *ec) | |
return 0; | |
} | |
-static int ec_undo(char *ec) | |
+static int ec_undo(char *loc, char *cmd, char *arg) | |
{ | |
return lbuf_undo(xb); | |
} | |
-static int ec_redo(char *ec) | |
+static int ec_redo(char *loc, char *cmd, char *arg) | |
{ | |
return lbuf_redo(xb); | |
} | |
-static int ec_mark(char *ec) | |
+static int ec_mark(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN], arg[EXLEN]; | |
int beg, end; | |
- ex_arg(ec, arg); | |
- ex_loc(ec, loc); | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
lbuf_mark(xb, arg[0], end - 1, 0); | |
t@@ -694,9 +609,8 @@ static void replace(struct sbuf *dst, char *rep, char *ln,… | |
} | |
} | |
-static int ec_substitute(char *ec) | |
+static int ec_substitute(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN], arg[EXLEN]; | |
struct rset *re; | |
int offs[32]; | |
int beg, end; | |
t@@ -704,8 +618,6 @@ static int ec_substitute(char *ec) | |
char *pat = NULL, *rep = NULL; | |
char *s = arg; | |
int i; | |
- ex_loc(ec, loc); | |
- ex_arg(ec, arg); | |
if (ex_region(loc, &beg, &end)) | |
return 1; | |
pat = re_read(&s); | |
t@@ -751,18 +663,14 @@ static int ec_substitute(char *ec) | |
return 0; | |
} | |
-static int ec_exec(char *ec) | |
+static int ec_exec(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN]; | |
- char arg[EXLEN]; | |
int beg, end; | |
char *text; | |
char *rep; | |
char *ecmd; | |
ex_modifiedbuffer(NULL); | |
- ex_loc(ec, loc); | |
- ex_arg(ec, arg); | |
- if (!(ecmd = ex_filearg(arg, 1))) | |
+ if (!(ecmd = ex_pathexpand(arg, 1))) | |
return 1; | |
if (!loc[0]) { | |
int ret; | |
t@@ -785,14 +693,12 @@ static int ec_exec(char *ec) | |
return 0; | |
} | |
-static int ec_make(char *ec) | |
+static int ec_make(char *log, char *cmd, char *arg) | |
{ | |
- char arg[EXLEN]; | |
char make[EXLEN]; | |
char *target; | |
ex_modifiedbuffer(NULL); | |
- ex_arg(ec, arg); | |
- if (!(target = ex_filearg(arg, 0))) | |
+ if (!(target = ex_pathexpand(arg, 0))) | |
return 1; | |
sprintf(make, "make %s", target); | |
free(target); | |
t@@ -802,10 +708,8 @@ static int ec_make(char *ec) | |
return 0; | |
} | |
-static int ec_ft(char *ec) | |
+static int ec_ft(char *loc, char *cmd, char *arg) | |
{ | |
- char arg[EXLEN]; | |
- ex_arg(ec, arg); | |
if (arg[0]) | |
snprintf(bufs[0].ft, sizeof(bufs[0].ft), "%s", arg); | |
else | |
t@@ -813,12 +717,8 @@ static int ec_ft(char *ec) | |
return 0; | |
} | |
-static int ec_cmap(char *ec) | |
+static int ec_cmap(char *loc, char *cmd, char *arg) | |
{ | |
- char cmd[EXLEN]; | |
- char arg[EXLEN]; | |
- ex_cmd(ec, cmd); | |
- ex_arg(ec, arg); | |
if (arg[0]) | |
xkmap_alt = conf_kmapfind(arg); | |
else | |
t@@ -830,9 +730,8 @@ static int ec_cmap(char *ec) | |
static int ex_exec(char *ln); | |
-static int ec_glob(char *ec) | |
+static int ec_glob(char *loc, char *cmd, char *arg) | |
{ | |
- char loc[EXLEN], cmd[EXLEN], arg[EXLEN]; | |
struct rset *re; | |
int offs[32]; | |
int beg, end, not; | |
t@@ -840,9 +739,6 @@ static int ec_glob(char *ec) | |
char *pat; | |
char *s = arg; | |
int i; | |
- ex_cmd(ec, cmd); | |
- ex_loc(ec, loc); | |
- ex_arg(ec, arg); | |
if (!loc[0] && !xgdep) | |
strcpy(loc, "%"); | |
if (ex_region(loc, &beg, &end)) | |
t@@ -905,15 +801,13 @@ static char *cutword(char *s, char *d) | |
return s; | |
} | |
-static int ec_set(char *ec) | |
+static int ec_set(char *loc, char *cmd, char *arg) | |
{ | |
- char arg[EXLEN]; | |
char tok[EXLEN]; | |
char opt[EXLEN]; | |
char *s = arg; | |
int val = 0; | |
int i; | |
- ex_arg(ec, arg); | |
if (*s) { | |
s = cutword(s, tok); | |
if (tok[0] == 'n' && tok[1] == 'o') { | |
t@@ -946,7 +840,7 @@ static int ec_set(char *ec) | |
static struct excmd { | |
char *abbr; | |
char *name; | |
- int (*ec)(char *s); | |
+ int (*ec)(char *loc, char *cmd, char *arg); | |
} excmds[] = { | |
{"b", "buffer", ec_buffer}, | |
{"p", "print", ec_print}, | |
t@@ -993,15 +887,49 @@ static int ex_idx(char *cmd) | |
return -1; | |
} | |
-/* read ex command argument */ | |
-static char *ex_arg(char *src, char *dst) | |
+/* read ex command addresses */ | |
+static char *ex_loc(char *src, char *loc) | |
+{ | |
+ while (*src == ':' || *src == ' ' || *src == '\t') | |
+ src++; | |
+ while (*src && !isalpha((unsigned char) *src) && *src != '=' && *src !… | |
+ if (*src == '\'') | |
+ *loc++ = *src++; | |
+ if (*src == '/' || *src == '?') { | |
+ int d = *src; | |
+ *loc++ = *src++; | |
+ while (*src && *src != d) { | |
+ if (*src == '\\' && src[1]) | |
+ *loc++ = *src++; | |
+ *loc++ = *src++; | |
+ } | |
+ } | |
+ if (*src) | |
+ *loc++ = *src++; | |
+ } | |
+ *loc = '\0'; | |
+ return src; | |
+} | |
+ | |
+/* read ex command name */ | |
+static char *ex_cmd(char *src, char *cmd) | |
{ | |
- char loc[EXLEN]; | |
- char cmd[EXLEN]; | |
- int c0; | |
- ex_loc(src, loc); | |
- src = ex_cmd(src, cmd); | |
- c0 = ex_idx(cmd) >= 0 ? excmds[ex_idx(cmd)].abbr[0] : -1; | |
+ char *cmd0 = cmd; | |
+ while (*src == ' ' || *src == '\t') | |
+ src++; | |
+ while (isalpha((unsigned char) *src) && cmd < cmd0 + 16) | |
+ if ((*cmd++ = *src++) == 'k' && cmd == cmd0 + 1) | |
+ break; | |
+ if (*src == '!' || *src == '=') | |
+ *cmd++ = *src++; | |
+ *cmd = '\0'; | |
+ return src; | |
+} | |
+ | |
+/* read ex command argument for excmd command */ | |
+static char *ex_arg(char *src, char *dst, char *excmd) | |
+{ | |
+ int c0 = excmd[0]; | |
while (*src == ' ' || *src == '\t') | |
src++; | |
if (c0 == '!' || c0 == 'g' || c0 == 'v' || | |
t@@ -1038,35 +966,23 @@ static char *ex_arg(char *src, char *dst) | |
return src; | |
} | |
-/* read an ex command and its arguments from src into dst */ | |
-static char *ex_line(char *src, char *dst) | |
-{ | |
- char loc[EXLEN]; | |
- char cmd[EXLEN]; | |
- char arg[EXLEN]; | |
- ex_loc(src, loc); | |
- ex_cmd(src, cmd); | |
- src = ex_arg(src, arg); | |
- sprintf(dst, "%s%s %s", loc, cmd, arg); | |
- return src; | |
-} | |
- | |
/* execute a single ex command */ | |
static int ex_exec(char *ln) | |
{ | |
- char ec[EXLEN]; | |
- char cmd[EXLEN]; | |
- int idx; | |
+ char loc[EXLEN], cmd[EXLEN], arg[EXLEN]; | |
int ret = 0; | |
+ if (strlen(ln) >= EXLEN) { | |
+ ex_show("command too long"); | |
+ return 1; | |
+ } | |
while (*ln) { | |
- ex_cmd(ln, cmd); | |
- if (strlen(ln) >= EXLEN) { | |
- ex_show("command too long"); | |
- return 1; | |
- } | |
- ln = ex_line(ln, ec); | |
- if ((idx = ex_idx(cmd)) >= 0) | |
- ret = excmds[idx].ec(ec); | |
+ int idx; | |
+ ln = ex_loc(ln, loc); | |
+ ln = ex_cmd(ln, cmd); | |
+ idx = ex_idx(cmd); | |
+ ln = ex_arg(ln, arg, idx >= 0 ? excmds[idx].abbr : "unknown"); | |
+ if (idx >= 0) | |
+ ret = excmds[idx].ec(loc, cmd, arg); | |
} | |
return ret; | |
} | |
t@@ -1092,18 +1008,16 @@ void ex(void) | |
int ex_init(char **files) | |
{ | |
- char cmd[EXLEN]; | |
- char *s = cmd; | |
+ char arg[EXLEN]; | |
+ char *s = arg; | |
char *r = files[0] ? files[0] : ""; | |
- *s++ = 'e'; | |
- *s++ = ' '; | |
- while (*r && s + 2 < cmd + sizeof(cmd)) { | |
+ while (*r && s + 2 < arg + sizeof(arg)) { | |
if (*r == ' ' || *r == '%' || *r == '#') | |
*s++ = '\\'; | |
*s++ = *r++; | |
} | |
*s = '\0'; | |
- if (ec_edit(cmd)) | |
+ if (ec_edit("", "e", arg)) | |
return 1; | |
if (getenv("EXINIT")) | |
ex_command(getenv("EXINIT")); |