From 48fbbc7ac8dd4b8c00bbfe3ecd394e840ae0d40a Mon Sep 17 00:00:00 2001 From: Byron Rakitzis Date: Sat, 24 Aug 2024 15:03:33 -0700 Subject: [PATCH] Fix treatment of slashes (path separator) by history command This change fixes the history pruning treatment of a slash character in the history followed by the name of the history command. The purpose of pruning is to avoid recursion in the history rewind, so history lines with a history command in them are pruned away in the search. With the history command named as "-", previously a history line like: find / --option would have been pruned (too aggressively). The change trims whitespace after first considering the case of whitespace separating a slash and the name of the history command. A few basic unit tests for the history command are also added with this commit. --- Makefile | 5 ++- history.c | 3 +- test-history/Makefile | 40 ++++++++++++++++++ test-history/append_char | 5 +++ test-history/delete_char | 5 +++ test-history/delete_char_stepwise | 8 ++++ test-history/ignore_me | 57 ++++++++++++++++++++++++++ test-history/insert_char | 5 +++ test-history/insert_char_skip_tabs | 5 +++ test-history/match_me_no_syntax | 2 + test-history/match_me_slash_whitespace | 2 + test-history/replace_space | 5 +++ test-history/skip_match | 9 ++++ test-history/truncate_and_append | 5 +++ 14 files changed, 154 insertions(+), 2 deletions(-) create mode 100644 test-history/Makefile create mode 100644 test-history/append_char create mode 100644 test-history/delete_char create mode 100644 test-history/delete_char_stepwise create mode 100644 test-history/ignore_me create mode 100644 test-history/insert_char create mode 100644 test-history/insert_char_skip_tabs create mode 100644 test-history/match_me_no_syntax create mode 100644 test-history/match_me_slash_whitespace create mode 100644 test-history/replace_space create mode 100644 test-history/skip_match create mode 100644 test-history/truncate_and_append diff --git a/Makefile b/Makefile index 39966e64..5ce3ce5b 100644 --- a/Makefile +++ b/Makefile @@ -82,11 +82,14 @@ version.h: Makefile .git/index @echo "CC $@" $(CC) $(_CPPFLAGS) $(_CFLAGS) -o $@ $< -check: trip +check: trip testhist trip: rc tripping ./rc -p <"$(srcdir)/trip.rc" +testhist: history + cd "$(srcdir)/test-history" && make + acutest.h:; wget --compression=gzip https://raw.githubusercontent.com/mity/acutest/master/include/acutest.h test-bestline.o: test-bestline.c edit-bestline.c acutest.h diff --git a/history.c b/history.c index 032c01f3..68d7bf7b 100644 --- a/history.c +++ b/history.c @@ -248,6 +248,8 @@ again: s = last; for (t = s; *t != '\0'; ++t) if (*t == me) { char *u = t - 1; + if (u < s || *u == '/') + goto again; while (u >= s && (*u == ' ' || *u == '\t')) --u; if (u < s) @@ -256,7 +258,6 @@ again: s = last; case '`': case '@': case '(': case ')': case '{': case '|': - case '/': goto again; default: break; diff --git a/test-history/Makefile b/test-history/Makefile new file mode 100644 index 00000000..23fc2a82 --- /dev/null +++ b/test-history/Makefile @@ -0,0 +1,40 @@ +all: -p --p \ + ignore_me.test \ + match_me_no_syntax.test \ + match_me_slash_whitespace.test \ + delete_char.test \ + delete_char_stepwise.test \ + insert_char.test \ + insert_char_skip_tabs.test \ + replace_space.test \ + append_char.test \ + truncate_and_append.test \ + skip_match.test + +ignore_me.test: force + @cp $(@:.test=) $@ + history=$@ ./-p | cmp -n `sed 1q $@ | wc -c` - $@ + @rm $@ + +match_me_no_syntax.test \ +match_me_slash_whitespace.test: force + @cp $(@:.test=) $@ + history=$@ ./-p > $(@:.test=.out) && sed -n 2p $@ | cmp - $(@:.test=.out) + @rm $@ $(@:.test=.out) + +delete_char.test \ +delete_char_stepwise.test \ +insert_char.test \ +insert_char_skip_tabs.test \ +replace_space.test \ +append_char.test \ +truncate_and_append.test \ +skip_match.test: force + @cp $(@:.test=) $@ + sed -n -e /EOF/q -e 1d -e p $@ | history=$@ ./--p >$(@:.test=.out) 2>/dev/null && sed 1q $@ | cmp - $(@:.test=.out) + @rm $@ $(@:.test=.out) + +-p --p: ../history + cp ../history ./$@ + +force: diff --git a/test-history/append_char b/test-history/append_char new file mode 100644 index 00000000..f6b45fe8 --- /dev/null +++ b/test-history/append_char @@ -0,0 +1,5 @@ +append the second the + + the + +EOF +append the second diff --git a/test-history/delete_char b/test-history/delete_char new file mode 100644 index 00000000..f823d66c --- /dev/null +++ b/test-history/delete_char @@ -0,0 +1,5 @@ +delete the second the + #### + +EOF +delete the the second the diff --git a/test-history/delete_char_stepwise b/test-history/delete_char_stepwise new file mode 100644 index 00000000..3e4a13db --- /dev/null +++ b/test-history/delete_char_stepwise @@ -0,0 +1,8 @@ +delete the second the + # + # + # + # + +EOF +delete the the second the diff --git a/test-history/ignore_me b/test-history/ignore_me new file mode 100644 index 00000000..4ac23322 --- /dev/null +++ b/test-history/ignore_me @@ -0,0 +1,57 @@ +the cases below should all be ignored +- +-- +-p +--p +./- +./-- +./-p +./--p + - + -- + -p + --p + ./- + ./-- + ./-p + ./--p +{-} +{--} +{-p} +{--p} +{ -} +{ --} +{ -p} +{ --p} +(-) +(--) +(-p) +(--p) +( -) +( --) +( -p) +( --p) +()- +()-- +()-p +()--p +@- +@-- +@-p +@--p +@ - +@ -- +@ -p +@ --p +|- +|-- +|-p +|--p +`- +`-- +`-p +`--p +` - +` -- +` -p +` --p diff --git a/test-history/insert_char b/test-history/insert_char new file mode 100644 index 00000000..8fac8f02 --- /dev/null +++ b/test-history/insert_char @@ -0,0 +1,5 @@ +insert the first the + ^the + +EOF +insert first the diff --git a/test-history/insert_char_skip_tabs b/test-history/insert_char_skip_tabs new file mode 100644 index 00000000..47f9f1d3 --- /dev/null +++ b/test-history/insert_char_skip_tabs @@ -0,0 +1,5 @@ +insert after a combination of spaces and tabs near the last position + ^near the last + +EOF +insert after a combination of spaces and tabs position diff --git a/test-history/match_me_no_syntax b/test-history/match_me_no_syntax new file mode 100644 index 00000000..ab827f9c --- /dev/null +++ b/test-history/match_me_no_syntax @@ -0,0 +1,2 @@ +this should match +echo -- -n diff --git a/test-history/match_me_slash_whitespace b/test-history/match_me_slash_whitespace new file mode 100644 index 00000000..f722aafb --- /dev/null +++ b/test-history/match_me_slash_whitespace @@ -0,0 +1,2 @@ +this should match +find / -- -ls diff --git a/test-history/replace_space b/test-history/replace_space new file mode 100644 index 00000000..7210c53a --- /dev/null +++ b/test-history/replace_space @@ -0,0 +1,5 @@ +replace spaces + %%% + +EOF +replace the spaces diff --git a/test-history/skip_match b/test-history/skip_match new file mode 100644 index 00000000..300d0f3b --- /dev/null +++ b/test-history/skip_match @@ -0,0 +1,9 @@ +append the second the +- +- + + the + +EOF +append the second +skip this line +skip this line, too diff --git a/test-history/truncate_and_append b/test-history/truncate_and_append new file mode 100644 index 00000000..e8e9a822 --- /dev/null +++ b/test-history/truncate_and_append @@ -0,0 +1,5 @@ +truncate and append + $ and append + +EOF +truncate this old stuff