- Added search/replace history log. Flag -H, --historylog. Flags HISTORY_CHANGED and HISTORYLOG, added entries in nanorc.sample, new functions log_history and save_history (Ken Tyler)

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1366 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
master
Chris Allegretta 2003-01-16 23:44:46 +00:00
parent 09fc4300ec
commit f3de8b552e
8 changed files with 140 additions and 3 deletions

View File

@ -22,6 +22,10 @@ Changes
the "Up" shortcut is displayed properly in the help menu,
remove a few bits of unneeded and/or warning-generating code,
and fix some missing statusq() prompts with --enable-tiny.
- Added search/replace history log. Flag -H, --historylog.
Flags HISTORY_CHANGED and HISTORYLOG (only room for one more
flag!), added entries in nanorc.sample, new functions
log_history and save_history (Ken Tyler).
- Translation updates (see po/ChangeLog for details).
- Forward-ported Chris' --disable-wrapping-as-root option from
1.0.9. Per Jordi's suggestions, have it override

104
files.c
View File

@ -2851,3 +2851,107 @@ char *do_browse_from(const char *inpath)
return bob;
}
#endif /* !DISABLE_BROWSER */
#ifndef NANO_SMALL
#ifdef ENABLE_NANORC
void load_history(void)
{
FILE *hist;
const struct passwd *userage;
uid_t euid = geteuid();
static char *nanohist;
char *buf, *ptr;
historyheadtype *history = &search_history;
do {
userage = getpwent();
} while (userage != NULL && userage->pw_uid != euid);
endpwent();
/* assume do_rcfile has reported missing home dir */
if (userage != NULL) {
nanohist = nrealloc(nanohist, strlen(userage->pw_dir) + 15);
sprintf(nanohist, "%s/.nano_history", userage->pw_dir);
hist = fopen(nanohist, "r");
if (!hist) {
if (errno != ENOENT)
rcfile_error(_("Unable to open ~/.nano_history file, %s"), strerror(errno));
free(nanohist);
} else {
buf = charalloc(1024);
while (fgets(buf, 1023, hist) != 0) {
ptr = buf;
while (*ptr != '\n')
ptr++;
*ptr = '\0';
if (strlen(buf))
update_history(history, buf);
else
history = &replace_history;
}
fclose(hist);
free(buf);
free(nanohist);
UNSET(HISTORY_CHANGED);
}
}
}
/* save histories to ~/.nano_history */
void save_history(void)
{
FILE *hist;
const struct passwd *userage;
uid_t euid = geteuid();
char *nanohist = NULL;
historytype *h;
/* don't save unchanged or empty histories */
if (!((search_history.count || replace_history.count) &&
ISSET(HISTORY_CHANGED) && !ISSET(VIEW_MODE)))
return;
do {
userage = getpwent();
} while (userage != NULL && userage->pw_uid != euid);
endpwent();
if (userage != NULL) {
nanohist = nrealloc(nanohist, strlen(userage->pw_dir) + 15);
sprintf(nanohist, "%s/.nano_history", userage->pw_dir);
hist = fopen(nanohist, "wb");
if (!hist) {
rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
} else {
/* set rw only by owner for security ?? */
chmod(nanohist, S_IRUSR | S_IWUSR);
/* write oldest first */
for (h = search_history.tail ; h->prev ; h = h->prev) {
nrealloc(h->data, strlen(h->data) + 1);
strcat(h->data, "\n");
if (fputs(h->data, hist) == EOF) {
rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
goto come_from;
}
}
if (fputs("\n", hist) == EOF) {
rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
goto come_from;
}
for (h = replace_history.tail ; h->prev ; h = h->prev) {
nrealloc(h->data, strlen(h->data) + 1);
strcat(h->data, "\n");
if (fputs(h->data, hist) == EOF) {
rcfile_msg(_("Unable to write ~/.nano_history file, %s"), strerror(errno));
goto come_from;
}
}
come_from:
fclose(hist);
}
free(nanohist);
}
}
#endif /* ENABLE_NANORC */
#endif NANO_SMALL

22
nano.c
View File

@ -68,6 +68,12 @@ RETSIGTYPE finish(int sigage)
{
#ifndef NANO_SMALL
#ifdef ENABLE_NANORC
/* do here so errors about ./nano_history
don't confuse user */
if (!ISSET(NO_RCFILE) && ISSET(HISTORYLOG))
save_history();
#endif
free_history(&search_history);
free_history(&replace_history);
#endif
@ -625,6 +631,7 @@ void usage(void)
print1opt("-F", "--multibuffer", _("Enable multiple file buffers"));
#endif
#ifdef ENABLE_NANORC
print1opt("-H", "--historylog", _("Log and read search/replace string history"));
print1opt("-I", "--ignorercfiles", _("Don't look at nanorc files"));
#endif
print1opt("-K", "--keypad", _("Use alternate keypad routines"));
@ -3012,6 +3019,7 @@ int main(int argc, char *argv[])
{"multibuffer", 0, 0, 'F'},
#endif
#ifdef ENABLE_NANORC
{"historylog", 0, 0, 'H'},
{"ignorercfiles", 0, 0, 'I'},
#endif
{"keypad", 0, 0, 'K'},
@ -3089,11 +3097,11 @@ int main(int argc, char *argv[])
#endif
#ifdef HAVE_GETOPT_LONG
while ((optchr = getopt_long(argc, argv, "h?BDFIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz",
while ((optchr = getopt_long(argc, argv, "h?BDFHIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz",
long_options, &option_index)) != -1) {
#else
while ((optchr =
getopt(argc, argv, "h?BDFIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz")) != -1) {
getopt(argc, argv, "h?BDFHIKMNQ:RST:VY:abcefgijklmo:pr:s:tvwxz")) != -1) {
#endif
switch (optchr) {
@ -3120,6 +3128,9 @@ int main(int argc, char *argv[])
break;
#endif
#ifdef ENABLE_NANORC
case 'H':
SET(HISTORYLOG);
break;
case 'I':
SET(NO_RCFILE);
break;
@ -3390,7 +3401,14 @@ int main(int argc, char *argv[])
#ifndef NANO_SMALL
history_init();
#ifdef ENABLE_NANORC
if (!ISSET(NO_RCFILE) && ISSET(HISTORYLOG))
load_history();
#endif
#endif
#ifdef DEBUG
fprintf(stderr, _("Main: bottom win\n"));

2
nano.h
View File

@ -247,6 +247,8 @@ typedef struct historyheadtype {
#define NO_RCFILE (1<<26)
#define COLOR_SYNTAX (1<<27)
#define PRESERVE (1<<28)
#define HISTORY_CHANGED (1<<29)
#define HISTORYLOG (1<<30)
/* Control key sequences, changing these would be very very bad */

View File

@ -73,6 +73,9 @@
## Save automatically on exit, don't prompt
# set tempfile
## Enable ~/.nano_history for saving and reading search/replace strings.
# set historylog
## Disallow file modification, why would you want this in an rc file? ;)
# set view
@ -165,7 +168,7 @@
#syntax "nanorc" "[\.]*nanorc$"
#color white "^ *(set|unset).*$"
#color cyan "^ *(set|unset) (autoindent|backup|const|cut|fill|keypad|multibuffer|noconvert|nofollow|nohelp|nowrap|operatingdir|preserve|quotestr|regexp|smooth|speller|suspend|tabsize|tempfile|view)"
#color cyan "^ *(set|unset) (autoindent|backup|const|cut|fill|keypad|multibuffer|noconvert|nofollow|nohelp|nowrap|operatingdir|preserve|quotestr|regexp|smooth|speller|suspend|tabsize|tempfile|historylog|view)"
#color brightwhite "^ *syntax [^ ]*"
#color brightblue "^ *set\>" "^ *unset\>" "^ *syntax\>"
#color white "^ *color\>.*"

View File

@ -370,6 +370,10 @@ char *get_history_older(historyheadtype *h);
char *get_history_newer(historyheadtype *h);
char *get_history_completion(historyheadtype *h, char *s);
void free_history(historyheadtype *h);
#ifdef ENABLE_NANORC
void load_history(void);
void save_history(void);
#endif
#endif
/* Public functions in utils.c */

View File

@ -84,6 +84,7 @@ const static rcoption rcopts[] = {
{"tabsize", 0},
{"tempfile", TEMP_OPT},
{"view", VIEW_MODE},
{"historylog", HISTORYLOG},
{NULL, 0}
};

View File

@ -957,6 +957,7 @@ void update_history(historyheadtype *h, char *s)
}
insert_node((historytype *)h, s);
h->count++;
SET(HISTORY_CHANGED);
up_hs:
h->current = h->next;
}