Changeset View
Changeset View
Standalone View
Standalone View
bin/sh/histedit.c
Show All 33 Lines | |||||
#if 0 | #if 0 | ||||
static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95"; | static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95"; | ||||
#endif | #endif | ||||
#endif /* not lint */ | #endif /* not lint */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/mman.h> | |||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <dirent.h> | #include <dirent.h> | ||||
#include <errno.h> | #include <errno.h> | ||||
#include <fcntl.h> | #include <fcntl.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include <paths.h> | #include <paths.h> | ||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
Show All 25 Lines | |||||
static FILE *el_in, *el_out; | static FILE *el_in, *el_out; | ||||
static char *fc_replace(const char *, char *, char *); | static char *fc_replace(const char *, char *, char *); | ||||
static int not_fcnumber(const char *); | static int not_fcnumber(const char *); | ||||
static int str_to_event(const char *, int); | static int str_to_event(const char *, int); | ||||
static int comparator(const void *, const void *, void *); | static int comparator(const void *, const void *, void *); | ||||
static char **sh_matches(const char *, int, int); | static char **sh_matches(const char *, int, int); | ||||
static unsigned char sh_complete(EditLine *, int); | static unsigned char sh_complete(EditLine *, int); | ||||
static unsigned char fcempty(EditLine *, int); | |||||
static const char * | static const char * | ||||
get_histfile(void) | get_histfile(void) | ||||
{ | { | ||||
const char *histfile; | const char *histfile; | ||||
/* don't try to save if the history size is 0 */ | /* don't try to save if the history size is 0 */ | ||||
if (hist == NULL || histsizeval() == 0) | if (hist == NULL || histsizeval() == 0) | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ | ||||
el = el_init(arg0, el_in, el_out, el_out); | el = el_init(arg0, el_in, el_out, el_out); | ||||
if (el != NULL) { | if (el != NULL) { | ||||
if (hist) | if (hist) | ||||
el_set(el, EL_HIST, history, hist); | el_set(el, EL_HIST, history, hist); | ||||
el_set(el, EL_PROMPT, getprompt); | el_set(el, EL_PROMPT, getprompt); | ||||
el_set(el, EL_ADDFN, "sh-complete", | el_set(el, EL_ADDFN, "sh-complete", | ||||
"Filename completion", | "Filename completion", | ||||
sh_complete); | sh_complete); | ||||
el_set(el, EL_ADDFN, | |||||
"edit-and-execute-command", | |||||
"Use $EDITOR to provide a command", | |||||
fcempty); | |||||
} else { | } else { | ||||
bad: | bad: | ||||
out2fmt_flush("sh: can't initialize editing\n"); | out2fmt_flush("sh: can't initialize editing\n"); | ||||
} | } | ||||
INTON; | INTON; | ||||
} else if (!editing && el) { | } else if (!editing && el) { | ||||
INTOFF; | INTOFF; | ||||
el_end(el); | el_end(el); | ||||
el = NULL; | el = NULL; | ||||
INTON; | INTON; | ||||
} | } | ||||
if (el) { | if (el) { | ||||
if (Vflag) | if (Vflag) | ||||
el_set(el, EL_EDITOR, "vi"); | el_set(el, EL_EDITOR, "vi"); | ||||
else if (Eflag) { | else if (Eflag) { | ||||
el_set(el, EL_EDITOR, "emacs"); | el_set(el, EL_EDITOR, "emacs"); | ||||
el_set(el, EL_BIND, "^R", "em-inc-search-prev", NULL); | el_set(el, EL_BIND, "^R", "em-inc-search-prev", NULL); | ||||
el_set(el, EL_BIND, "^X^E", | |||||
"edit-and-execute-command", NULL); | |||||
} | } | ||||
el_set(el, EL_BIND, "^I", "sh-complete", NULL); | el_set(el, EL_BIND, "^I", "sh-complete", NULL); | ||||
el_source(el, NULL); | el_source(el, NULL); | ||||
} | } | ||||
} else { | } else { | ||||
INTOFF; | INTOFF; | ||||
if (el) { /* no editing if not interactive */ | if (el) { /* no editing if not interactive */ | ||||
el_end(el); | el_end(el); | ||||
Show All 27 Lines | |||||
void | void | ||||
setterm(const char *term) | setterm(const char *term) | ||||
{ | { | ||||
if (rootshell && el != NULL && term != NULL) | if (rootshell && el != NULL && term != NULL) | ||||
el_set(el, EL_TERMINAL, term); | el_set(el, EL_TERMINAL, term); | ||||
} | } | ||||
int | int | ||||
histcmd(int argc, char **argv __unused) | histcmd(int argc __unused, char **argv __unused) | ||||
{ | { | ||||
int ch; | int ch; | ||||
const char *editor = NULL; | const char *editor = NULL; | ||||
HistEvent he; | HistEvent he; | ||||
int lflg = 0, nflg = 0, rflg = 0, sflg = 0; | int lflg = 0, nflg = 0, rflg = 0, sflg = 0; | ||||
int i, retval; | int i, retval; | ||||
const char *firststr, *laststr; | |||||
int first, last, direction; | int first, last, direction; | ||||
char *pat = NULL, *repl = NULL; | char *pat = NULL, *repl = NULL; | ||||
static int active = 0; | static int active = 0; | ||||
struct jmploc jmploc; | struct jmploc jmploc; | ||||
struct jmploc *savehandler; | struct jmploc *savehandler; | ||||
char editfilestr[PATH_MAX]; | char editfilestr[PATH_MAX]; | ||||
char *volatile editfile; | char *volatile editfile; | ||||
FILE *efp = NULL; | FILE *efp = NULL; | ||||
int oldhistnum; | int oldhistnum; | ||||
if (hist == NULL) | |||||
error("history not active"); | |||||
if (argc == 1) | |||||
error("missing history argument"); | |||||
while (not_fcnumber(*argptr) && (ch = nextopt("e:lnrs")) != '\0') | while (not_fcnumber(*argptr) && (ch = nextopt("e:lnrs")) != '\0') | ||||
switch ((char)ch) { | switch ((char)ch) { | ||||
case 'e': | case 'e': | ||||
editor = shoptarg; | editor = shoptarg; | ||||
break; | break; | ||||
case 'l': | case 'l': | ||||
lflg = 1; | lflg = 1; | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | if (lflg == 0 && *argptr != NULL && | ||||
pat = *argptr; | pat = *argptr; | ||||
*repl++ = '\0'; | *repl++ = '\0'; | ||||
argptr++; | argptr++; | ||||
} | } | ||||
/* | /* | ||||
* determine [first] and [last] | * determine [first] and [last] | ||||
*/ | */ | ||||
if (*argptr == NULL) { | if (*argptr == NULL) { | ||||
firststr = lflg ? "-16" : "-1"; | /* not used */ | ||||
laststr = "-1"; | |||||
} else if (argptr[1] == NULL) { | } else if (argptr[1] == NULL) { | ||||
firststr = argptr[0]; | first = str_to_event(argptr[0], 0); | ||||
laststr = lflg ? "-1" : argptr[0]; | last = str_to_event(lflg ? "-1" : argptr[0], 1); | ||||
} else if (argptr[2] == NULL) { | } else if (argptr[2] == NULL) { | ||||
firststr = argptr[0]; | first = str_to_event(argptr[0], 0); | ||||
laststr = argptr[1]; | last = str_to_event(argptr[1], 1); | ||||
} else | } else | ||||
error("too many arguments"); | error("too many arguments"); | ||||
/* | |||||
* Turn into event numbers. | |||||
*/ | |||||
first = str_to_event(firststr, 0); | |||||
last = str_to_event(laststr, 1); | |||||
if (rflg) { | if (rflg) { | ||||
i = last; | i = last; | ||||
last = first; | last = first; | ||||
first = i; | first = i; | ||||
} | } | ||||
/* | /* | ||||
* XXX - this should not depend on the event numbers | * XXX - this should not depend on the event numbers | ||||
Show All 13 Lines | if ((fd = mkstemp(editfilestr)) < 0) | ||||
error("can't create temporary file %s", editfile); | error("can't create temporary file %s", editfile); | ||||
editfile = editfilestr; | editfile = editfilestr; | ||||
if ((efp = fdopen(fd, "w")) == NULL) { | if ((efp = fdopen(fd, "w")) == NULL) { | ||||
close(fd); | close(fd); | ||||
error("Out of space"); | error("Out of space"); | ||||
} | } | ||||
} | } | ||||
if (*argptr == NULL || hist == NULL) | |||||
goto empty; | |||||
/* | /* | ||||
* Loop through selected history events. If listing or executing, | * Loop through selected history events. If listing or executing, | ||||
* do it now. Otherwise, put into temp file and call the editor | * do it now. Otherwise, put into temp file and call the editor | ||||
* after. | * after. | ||||
* | * | ||||
* The history interface needs rethinking, as the following | * The history interface needs rethinking, as the following | ||||
* convolutions will demonstrate. | * convolutions will demonstrate. | ||||
*/ | */ | ||||
Show All 34 Lines | for (;retval != -1; retval = history(hist, &he, direction)) { | ||||
} | } | ||||
/* | /* | ||||
* At end? (if we were to lose last, we'd sure be | * At end? (if we were to lose last, we'd sure be | ||||
* messed up). | * messed up). | ||||
*/ | */ | ||||
if (he.num == last) | if (he.num == last) | ||||
break; | break; | ||||
} | } | ||||
empty: | |||||
if (editor) { | if (editor) { | ||||
char *editcmd; | char *editcmd; | ||||
void *m = mmap(NULL, 1024, PROT_READ, MAP_SHARED, fileno(efp), 0); | |||||
fclose(efp); | fclose(efp); | ||||
INTON; | |||||
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2); | editcmd = stalloc(strlen(editor) + strlen(editfile) + 2); | ||||
sprintf(editcmd, "%s %s", editor, editfile); | sprintf(editcmd, "%s %s", editor, editfile); | ||||
evalstring(editcmd, 0); /* XXX - should use no JC command */ | evalstring(editcmd, 0); /* XXX - should use no JC command */ | ||||
readcmdfile(editfile); /* XXX - should read back - quick tst */ | out2str(m); | ||||
flushout(out2); | |||||
evalstring(m, EV_INTER); | |||||
if (hist) | |||||
history(hist, &he, H_ENTER, m); | |||||
munmap(m, 1024); | |||||
fclose(efp); | |||||
INTON; | |||||
unlink(editfile); | unlink(editfile); | ||||
} | } | ||||
if (lflg == 0 && active > 0) | if (lflg == 0 && active > 0) | ||||
--active; | --active; | ||||
if (displayhist) | if (displayhist) | ||||
displayhist = 0; | displayhist = 0; | ||||
handler = savehandler; | handler = savehandler; | ||||
▲ Show 20 Lines • Show All 242 Lines • ▼ Show 20 Lines | |||||
* bind a key (tab by default) to execute the function. | * bind a key (tab by default) to execute the function. | ||||
*/ | */ | ||||
unsigned char | unsigned char | ||||
sh_complete(EditLine *sel, int ch __unused) | sh_complete(EditLine *sel, int ch __unused) | ||||
{ | { | ||||
return (unsigned char)fn_complete2(sel, NULL, sh_matches, | return (unsigned char)fn_complete2(sel, NULL, sh_matches, | ||||
L" \t\n\"\\'`@$><=;|&{(", NULL, NULL, (size_t)100, | L" \t\n\"\\'`@$><=;|&{(", NULL, NULL, (size_t)100, | ||||
NULL, &((int) {0}), NULL, NULL, FN_QUOTE_MATCH); | NULL, &((int) {0}), NULL, NULL, FN_QUOTE_MATCH); | ||||
} | |||||
unsigned char | |||||
fcempty(EditLine *sel __unused, int ch __unused) | |||||
{ | |||||
char *args[] = {(char[]){"fc"}, NULL}; | |||||
argptr = args + 1; | |||||
out2c('\n'); | |||||
histcmd(1, args); | |||||
out2str(getprompt(NULL)); | |||||
flushout(out2); | |||||
return (0); | |||||
} | } | ||||
#else | #else | ||||
#include "error.h" | #include "error.h" | ||||
int | int | ||||
histcmd(int argc __unused, char **argv __unused) | histcmd(int argc __unused, char **argv __unused) | ||||
{ | { | ||||
Show All 14 Lines |