From: Chris Allegretta Date: Thu, 16 Jan 2003 23:44:46 +0000 (+0000) Subject: - Added search/replace history log. Flag -H, --historylog. Flags HISTORY_CHANGED... X-Git-Tag: v1.1.99pre1~10 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=f3de8b552ec1993f9b8055c5065e9bdb967decbb;p=nano.git - 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 --- diff --git a/ChangeLog b/ChangeLog index 59d7c95b..dfa0cf28 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/files.c b/files.c index e2d3cf49..af376d32 100644 --- a/files.c +++ b/files.c @@ -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 diff --git a/nano.c b/nano.c index c6dc793c..7996f740 100644 --- a/nano.c +++ b/nano.c @@ -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")); diff --git a/nano.h b/nano.h index 25fe0a3a..92b462cd 100644 --- a/nano.h +++ b/nano.h @@ -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 */ diff --git a/nanorc.sample b/nanorc.sample index f5b4de1f..31cbedd4 100644 --- a/nanorc.sample +++ b/nanorc.sample @@ -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\>.*" diff --git a/proto.h b/proto.h index 5b428605..05043a1f 100644 --- a/proto.h +++ b/proto.h @@ -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 */ diff --git a/rcfile.c b/rcfile.c index f8974a4c..714f1df0 100644 --- a/rcfile.c +++ b/rcfile.c @@ -84,6 +84,7 @@ const static rcoption rcopts[] = { {"tabsize", 0}, {"tempfile", TEMP_OPT}, {"view", VIEW_MODE}, + {"historylog", HISTORYLOG}, {NULL, 0} }; diff --git a/search.c b/search.c index 1ab222e4..cd1ed793 100644 --- a/search.c +++ b/search.c @@ -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; }