Skip to content

Commit c17bdc6

Browse files
author
Rob
committed
More range parsing ([+-][0-9]+), partial [range]!cmd support
1 parent bef1b97 commit c17bdc6

File tree

8 files changed

+138
-35
lines changed

8 files changed

+138
-35
lines changed

README.md

-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
11
Micro Vi
22

33
Similar commands to vi.
4-
5-
6-
Bugs
7-
----
8-
9-
Display code is still being changed, currently the only way to quit is Ctrl-C.
10-
"Lolz".

command.c

+58-18
Original file line numberDiff line numberDiff line change
@@ -230,44 +230,70 @@ void cmd_q(int argc, char **argv, int force, struct range *rng)
230230

231231
void cmd_bang(int argc, char **argv, int force, struct range *rng)
232232
{
233-
if(rng->start != -1 || rng->end != -1){
233+
if(rng->start != -1){
234234
/* rw!cmd command */
235-
struct list *l;
235+
struct list *l, *to_pipe;
236+
char *free_me = argv_to_str(argc, argv);
237+
char *cmd = strchr(free_me, '!') + 1;
236238

237-
if(argc < 2){
238-
gui_status(GUI_ERR, "usage: [range]!cmd");
239+
if(argc <= 1){
240+
gui_status(GUI_ERR, "usage: range!cmd");
239241
return;
240242
}
241243

242-
/* FIXME: more than one arg.. herpaderp */
243-
l = pipe_readwrite(argv[1], buffer_gethead(global_buffer));
244+
if(--rng->start < 0)
245+
rng->start = 0;
246+
if(rng->end == -1)
247+
rng->end = rng->start;
248+
249+
to_pipe = buffer_extract_range(global_buffer, rng);
250+
251+
l = pipe_readwrite(cmd, to_pipe ? to_pipe : buffer_gethead(global_buffer));
244252

245253
if(l){
246254
if(l->data){
247-
buffer_replace(global_buffer, l);
255+
if(to_pipe){
256+
struct list *inshere;
257+
258+
inshere = buffer_getindex(global_buffer, rng->start);
259+
260+
if(!inshere)
261+
inshere = buffer_gettail(global_buffer);
262+
263+
buffer_insertlistafter(global_buffer, inshere, l);
264+
265+
list_free_nodata(to_pipe);
266+
to_pipe = NULL;
267+
}else{
268+
buffer_replace(global_buffer, l);
269+
}
270+
248271
buffer_modified(global_buffer) = 1;
249272
}else{
250273
list_free(l, free);
251-
gui_status(GUI_ERR, "%s: no output", argv[1]);
274+
gui_status(GUI_ERR, "%s: no output", cmd);
252275
}
253276
}else{
254277
gui_status(GUI_ERR, "pipe_readwrite() error: %s", strerror(errno));
255278
}
256-
return;
257-
}
258279

259-
if(argc == 1){
260-
shellout("sh", NULL);
280+
free(free_me);
281+
if(to_pipe)
282+
list_free(to_pipe, free);
261283
}else{
262-
char *cmd = argv_to_str(argc - 1, argv + 1);
263-
shellout(cmd, NULL);
264-
free(cmd);
284+
if(argc == 1){
285+
shellout("sh", NULL);
286+
}else{
287+
char *cmd = argv_to_str(argc - 1, argv + 1);
288+
shellout(cmd, NULL);
289+
free(cmd);
290+
}
265291
}
266292
}
267293

268294
void cmd_e(int argc, char **argv, int force, struct range *rng)
269295
{
270-
if(argc != 2){
296+
if(argc != 2 || rng->start != -1 || rng->end != -1){
271297
gui_status(GUI_ERR, "usage: e[!] fname");
272298
return;
273299
}
@@ -283,7 +309,7 @@ void cmd_e(int argc, char **argv, int force, struct range *rng)
283309

284310
void cmd_new(int argc, char **argv, int force, struct range *rng)
285311
{
286-
if(argc != 1){
312+
if(argc != 1 || rng->start != -1 || rng->end != -1){
287313
gui_status(GUI_ERR, "usage: new[!]");
288314
return;
289315
}
@@ -565,14 +591,28 @@ void command_run(char *in)
565591
s = parserange(in, &rng, &lim);
566592

567593
if(!s){
568-
gui_status(GUI_ERR, "couldn't parse range");
594+
if(errno == ERANGE){
595+
if(gui_confirm("range backwards, flip? ")){
596+
int i = rng.start;
597+
rng.start = rng.end;
598+
rng.end = i;
599+
600+
i = strspn(in, "^$.%,-+0123456789");
601+
s = in + i;
602+
goto cont;
603+
}
604+
}else{
605+
gui_status(GUI_ERR, "range out of limits");
606+
}
607+
569608
return;
570609
}else if(HAVE_RANGE && *s == '\0'){
571610
/* just a number, move to that line */
572611
gui_move(rng.start - 1, gui_x());
573612
return;
574613
}
575614

615+
cont:
576616
if(!HAVE_RANGE)
577617
rng.start = rng.end = -1;
578618

gui/gui.c

+19-2
Original file line numberDiff line numberDiff line change
@@ -391,12 +391,17 @@ int gui_getstr(char **ps, const struct gui_read_opts *opts)
391391
}
392392
}
393393

394-
int gui_prompt(const char *p, char **pbuf, intellisensef f)
394+
void gui_printprompt(const char *p)
395395
{
396-
struct gui_read_opts opts;
397396
move(LINES - 1, 0);
398397
gui_clrtoeol();
399398
addstr(p);
399+
}
400+
401+
int gui_prompt(const char *p, char **pbuf, intellisensef f)
402+
{
403+
struct gui_read_opts opts;
404+
gui_printprompt(p);
400405

401406
memset(&opts, 0, sizeof opts);
402407
opts.bspc_cancel = 1;
@@ -405,6 +410,18 @@ int gui_prompt(const char *p, char **pbuf, intellisensef f)
405410
return gui_getstr(pbuf, &opts);
406411
}
407412

413+
int gui_confirm(const char *p)
414+
{
415+
int c;
416+
417+
gui_printprompt(p);
418+
c = gui_getch();
419+
420+
if(c == 'y' || c == 'Y')
421+
return 1;
422+
return 0;
423+
}
424+
408425
void gui_redraw()
409426
{
410427
redrawwin(stdscr);

gui/gui.h

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ struct gui_read_opts
3030

3131
int gui_getstr(char **ps, const struct gui_read_opts *);
3232
int gui_prompt(const char *p, char **, intellisensef);
33+
int gui_confirm(const char *p);
3334
#endif
3435
int gui_getch(void);
3536
int gui_peekch(void);

range.c

+36-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
#include <stdlib.h>
22
#include <ctype.h>
3+
#include <errno.h>
34

45
#include "range.h"
56

7+
extern void *stderr;
8+
69
static int number(char **, int, int);
710
static char *getrange(char *, struct range *, int, int);
811

@@ -38,6 +41,32 @@ static int number(char **sp, int cur, int lim)
3841
++*sp;
3942
curv = cur+1;
4043
return 1;
44+
45+
case '+':
46+
case '-':
47+
{
48+
int chr = *s;
49+
int i;
50+
51+
++*sp;
52+
53+
if(isdigit(**sp)){
54+
number(sp, cur, lim);
55+
i = curv;
56+
}else{
57+
i = cur;
58+
}
59+
60+
if(chr == '+')
61+
i += 2;
62+
else
63+
i -= 1;
64+
curv = i;
65+
66+
fprintf(stderr, "parsed, curv=%d (i=%d, chr=%c), *sp=\"%s\"\n",curv,i,chr,*sp);
67+
68+
return 1;
69+
}
4170
}
4271

4372
return 0;
@@ -75,10 +104,16 @@ char *parserange(char *in, struct range *rng, struct range *lim)
75104

76105
if(s > in){
77106
/* validate range */
107+
fprintf(stderr, "rng = { %d, %d }, cur=%d, max=%d\n",
108+
rng->start, rng->end,
109+
lim->start, lim->end);
110+
78111
if(rng->start < 1 || rng->start > lim->end ||
79-
rng->end < 1 || rng->end > lim->end){
112+
rng->end < 1 || rng->end > lim->end){
113+
errno = EINVAL;
80114
return NULL;
81115
}else if(rng->start > rng->end){
116+
errno = ERANGE;
82117
return NULL;
83118
}
84119
}

util/list.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@ struct list *list_getindex(struct list *l, int i)
269269
return l;
270270
}
271271

272+
void list_free_nodata(struct list *l)
273+
{
274+
struct list *del;
275+
l = list_gethead(l);
276+
while(l){
277+
del = l;
278+
l = l->next;
279+
free(del);
280+
}
281+
}
282+
272283
void list_free(struct list *l, void (*f)(void *))
273284
{
274285
struct list *del;
@@ -385,7 +396,8 @@ struct list *list_from_fd(int fd, int *haseol)
385396
i = list_gettail(i);
386397
}
387398

388-
*haseol = eol;
399+
if(haseol)
400+
*haseol = eol;
389401

390402
if(ferror(f)){
391403
list_free(l, free);

util/list.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ struct list *list_getindex(struct list *, int);
3535
struct list *list_copy_range(struct list *l, void *(*f_dup)(void *), struct range *r);
3636
struct list *list_copy( struct list *l, void *(*f_dup)(void *));
3737

38-
void list_free(struct list *l, void (*f)(void *));
38+
void list_free( struct list *l, void (*f)(void *));
39+
void list_free_nodata(struct list *l);
3940

4041
struct list *list_from_fd( int fd, int *haseol);
4142
struct list *list_from_file( FILE *f, int *haseol);

util/pipe.c

+9-5
Original file line numberDiff line numberDiff line change
@@ -113,13 +113,17 @@ struct list *pipe_readwrite(const char *cmd, struct list *l)
113113
close(parent_to_child[WRITE_FD]);
114114
close(child_to_parent[READ_FD]);
115115

116-
if(dup2(parent_to_child[READ_FD], STDIN_FILENO ) == -1 ||
117-
dup2(child_to_parent[WRITE_FD], STDOUT_FILENO) == -1 ||
118-
dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
119-
116+
if(
117+
dup2(parent_to_child[READ_FD], STDIN_FILENO ) == -1 ||
118+
dup2(child_to_parent[WRITE_FD], STDOUT_FILENO) == -1 ||
119+
dup2(STDOUT_FILENO, STDERR_FILENO) == -1
120+
){
120121
exit(-1);
122+
}
121123

122-
exit(system(cmd));
124+
execlp("sh", "sh", "-c", cmd, NULL);
125+
perror("exec()");
126+
exit(-1);
123127

124128
default:
125129
{

0 commit comments

Comments
 (0)