From 535d0c1489e482d4788f861ce1d2a32e6bd8b14a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 21 Aug 2013 15:24:41 +1000 Subject: [PATCH] Browser: add 'v' to open file in an editor. 'v' as in 'visual', just like 'less'. Signed-off-by: NeilBrown --- vpatch.c | 152 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 92 insertions(+), 60 deletions(-) diff --git a/vpatch.c b/vpatch.c index 076f4ce..5a24eea 100644 --- a/vpatch.c +++ b/vpatch.c @@ -44,6 +44,7 @@ #include #include #include +#include static void term_init(int raw); @@ -1235,6 +1236,8 @@ static char *merge_window_help[] = { " c toggle accepting of result of conflict", " X toggle ignored of all Change, Conflict", " and Unmatched items in current line", + " v Save the current merge and run the", + " default editor on the file.", NULL }; static char *save_query[] = { @@ -1257,6 +1260,25 @@ static char *toggle_ignore[] = { NULL }; +static void do_edit(char *file) +{ + char *ed = getenv("VISUAL"); + if (!ed) + ed = getenv("EDITOR"); + if (!ed) + ed = "/usr/bin/edit"; + switch(fork()) { + case 0: + execlp(ed, ed, file, NULL); + exit(2); + case -1: + break; + default: + wait(NULL); + } +} + + static int merge_window(struct plist *p, FILE *f, int reverse, int replace, int selftest, int ignore_blanks) { @@ -1334,6 +1356,46 @@ static int merge_window(struct plist *p, FILE *f, int reverse, int replace, unsigned int searchlen; } *anchor = NULL; + void free_stuff(void) + { + free(fm.list); + free(fb.list); + free(fa.list); + free(csl1); + free(csl2); + free(ci.merger); + } + void find_line(int ln) + { + pos.p.m = 0; /* merge node */ + pos.p.s = 0; /* stream number */ + pos.p.o = -1; /* offset */ + pos.p.lineno = 1; + pos.state = 0; + memset(&curs, 0, sizeof(curs)); + do + next_mline(&pos, fm, fb, fa, ci.merger, mode); + while (pos.p.lineno < ln && ci.merger[pos.p.m].type != End); + vpos = pos; + } + void prepare_merge(int ch) + { + /* FIXME check for errors in the stream */ + fm = split_stream(sm, ByWord | ignore_blanks); + fb = split_stream(sb, ByWord | ignore_blanks); + fa = split_stream(sa, ByWord | ignore_blanks); + + if (ch) + csl1 = pdiff(fm, fb, ch); + else + csl1 = diff(fm, fb); + csl2 = diff_patch(fb, fa); + + ci = make_merger(fm, fb, fa, csl1, csl2, 0, 1, 0); + for (i = 0; ci.merger[i].type != End; i++) + ci.merger[i].oldtype = ci.merger[i].type; + } + if (selftest) { intr_kills = 1; selftest = 1; @@ -1385,32 +1447,12 @@ static int merge_window(struct plist *p, FILE *f, int reverse, int replace, endwin(); return 0; } - /* FIXME check for errors in the stream */ - fm = split_stream(sm, ByWord | ignore_blanks); - fb = split_stream(sb, ByWord | ignore_blanks); - fa = split_stream(sa, ByWord | ignore_blanks); - - if (ch) - csl1 = pdiff(fm, fb, ch); - else - csl1 = diff(fm, fb); - csl2 = diff_patch(fb, fa); - - ci = make_merger(fm, fb, fa, csl1, csl2, 0, 1, 0); - for (i = 0; ci.merger[i].type != End; i++) - ci.merger[i].oldtype = ci.merger[i].type; - + prepare_merge(ch); term_init(!selftest); row = 1; - pos.p.m = 0; /* merge node */ - pos.p.s = 0; /* stream number */ - pos.p.o = -1; /* offset */ - pos.p.lineno = 1; - pos.state = 0; - next_mline(&pos, fm, fb, fa, ci.merger, mode); - memset(&curs, 0, sizeof(curs)); - vpos = pos; + find_line(1); + while (1) { unsigned int next; if (refresh >= 2) { @@ -1762,12 +1804,7 @@ static int merge_window(struct plist *p, FILE *f, int reverse, int replace, free(sm.body); free(sb.body); free(sa.body); - free(fm.list); - free(fb.list); - free(fa.list); - free(csl1); - free(csl2); - free(ci.merger); + free_stuff(); endwin(); return answer; @@ -1779,41 +1816,36 @@ static int merge_window(struct plist *p, FILE *f, int reverse, int replace, break; changes = 0; } - free(fm.list); - free(fb.list); - free(fa.list); - free(csl1); - free(csl2); - free(ci.merger); + free_stuff(); ignore_blanks = ignore_blanks ? 0 : IgnoreBlanks; - fm = split_stream(sm, ByWord | ignore_blanks); - fb = split_stream(sb, ByWord | ignore_blanks); - fa = split_stream(sa, ByWord | ignore_blanks); - - if (ch) - csl1 = pdiff(fm, fb, ch); - else - csl1 = diff(fm, fb); - csl2 = diff_patch(fb, fa); + prepare_merge(ch); + find_line(pos.p.lineno); - ci = make_merger(fm, fb, fa, csl1, csl2, 0, 1, 0); - for (i = 0; ci.merger[i].type != End; i++) - ci.merger[i].oldtype = ci.merger[i].type; + refresh = 2; + break; - { - int ln = pos.p.lineno; - pos.p.m = 0; /* merge node */ - pos.p.s = 0; /* stream number */ - pos.p.o = -1; /* offset */ - pos.p.lineno = 1; - pos.state = 0; - next_mline(&pos, fm, fb, fa, ci.merger, mode); - memset(&curs, 0, sizeof(curs)); - while (pos.p.lineno < ln && ci.merger[pos.p.m].type != End) - next_mline(&pos, fm, fb, fa, ci.merger, mode); - vpos = pos; - } + case 'v': + save_merge(fm, fb, fa, ci.merger, + p->file, !p->is_merge); + p->is_merge = 1; + endwin(); + free_stuff(); + do_edit(p->file); + sp = load_file(p->file); + split_merge(sp, &sm, &sb, &sa); + free(sp.body); + prepare_merge(0); + p->wiggles = 0; + p->conflicts = isolate_conflicts( + fm, fb, fa, csl1, csl2, 0, + ci.merger, 0, &p->wiggles); + p->chunks = p->conflicts; refresh = 2; + changes = 0; + + find_line(pos.p.lineno); + + doupdate(); break; case '/': -- 2.39.5