Add option to remove duplicate command history entries
This patch implements the new option "history remove-duplicates", which controls the removal of duplicate history entries ("off" by default). The motivation for this option is to be able to reduce the prevalence of basic commands such as "up" and "down" in the history file. These common commands crowd out more unique commands in the history file (when the history file has a fixed size), and they make navigation of the history file via ^P, ^N and ^R more inconvenient. The option takes an integer denoting the number of history entries to look back at for a history entry that is a duplicate of the latest one. "history remove-duplicates 1" is equivalent to bash's ignoredups option, and "history remove-duplicates unlimited" is equivalent to bash's erasedups option. [ I decided to go with this integer approach instead of a tri-state enum because it's slightly more flexible and seemingly more intuitive than leave/erase/ignore. ] gdb/ChangeLog: * NEWS: Mention the new option "history remove-duplicates". * top.c (history_remove_duplicates): New static variable. (show_history_remove_duplicates): New static function. (gdb_add_history): Conditionally remove duplicate history entries. (init_main): Add "history remove-duplicates" option. gdb/doc/ChangeLog: * gdb.texinfo (Command History): Document the new option "history remove-duplicates". gdb/testsuite/ChangeLog: * gdb.base/history-duplicates.exp: New test.
This commit is contained in:
parent
2e52ae68e7
commit
fc637f04c7
|
@ -1,3 +1,12 @@
|
|||
2015-06-26 Patrick Palka <patrick@parcs.ath.cx>
|
||||
|
||||
* NEWS: Mention the new option "history remove-duplicates".
|
||||
* top.c (history_remove_duplicates): New static variable.
|
||||
(show_history_remove_duplicates): New static function.
|
||||
(gdb_add_history): Conditionally remove duplicate history
|
||||
entries.
|
||||
(init_main): Add "history remove-duplicates" option.
|
||||
|
||||
2015-06-26 Patrick Palka <patrick@parcs.ath.cx>
|
||||
|
||||
* tui/tui-win.c (focus_completer): New static function.
|
||||
|
|
4
gdb/NEWS
4
gdb/NEWS
|
@ -145,6 +145,10 @@ show max-completions
|
|||
to avoid generating large completion lists, the computation of
|
||||
which can cause the debugger to become temporarily unresponsive.
|
||||
|
||||
set history remove-duplicates
|
||||
show history remove-duplicates
|
||||
Control the removal of duplicate history entries.
|
||||
|
||||
maint set symbol-cache-size
|
||||
maint show symbol-cache-size
|
||||
Control the size of the symbol cache.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2015-06-26 Patrick Palka <patrick@parcs.ath.cx>
|
||||
|
||||
* gdb.texinfo (Command History): Document the new option
|
||||
"history remove-duplicates".
|
||||
|
||||
2015-06-19 Doug Evans <dje@google.com>
|
||||
|
||||
* stabs.texinfo (ELF Linker Relocation): Mention Sun stabs is no
|
||||
|
|
|
@ -22644,6 +22644,21 @@ to 256 if this variable is not set. Non-numeric values of @env{GDBHISTSIZE}
|
|||
are ignored. If @var{size} is @code{unlimited} or if @env{GDBHISTSIZE} is
|
||||
either a negative number or the empty string, then the number of commands
|
||||
@value{GDBN} keeps in the history list is unlimited.
|
||||
|
||||
@cindex remove duplicate history
|
||||
@kindex set history remove-duplicates
|
||||
@item set history remove-duplicates @var{count}
|
||||
@itemx set history remove-duplicates unlimited
|
||||
Control the removal of duplicate history entries in the command history list.
|
||||
If @var{count} is non-zero, @value{GDBN} will look back at the last @var{count}
|
||||
history entries and remove the first entry that is a duplicate of the current
|
||||
entry being added to the command history list. If @var{count} is
|
||||
@code{unlimited} then this lookbehind is unbounded. If @var{count} is 0, then
|
||||
removal of duplicate history entries is disabled.
|
||||
|
||||
Only history entries added during the current session are considered for
|
||||
removal. This option is set to 0 by default.
|
||||
|
||||
@end table
|
||||
|
||||
History expansion assigns special meaning to the character @kbd{!}.
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2015-06-26 Patrick Palka <patrick@parcs.ath.cx>
|
||||
|
||||
* gdb.base/history-duplicates.exp: New test.
|
||||
|
||||
2015-06-26 Patrick Palka <patrick@parcs.ath.cx>
|
||||
|
||||
* gdb.base/completion.exp: Test the completion of the "focus"
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
# Copyright 2015 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This file is part of the gdb testsuite.
|
||||
|
||||
# Test the operation of the "history remove-duplicates" option.
|
||||
|
||||
|
||||
# Check that the previous history entry is ENTRY.
|
||||
|
||||
proc check_prev_history_entry { entry { test_suffix "" } } {
|
||||
set test_name "history entry is $entry"
|
||||
if { $test_suffix != "" } {
|
||||
append test_name " $test_suffix"
|
||||
}
|
||||
|
||||
# Send ^P followed by ^L.
|
||||
send_gdb "\x10\x0c"
|
||||
|
||||
gdb_expect {
|
||||
-re $entry {
|
||||
pass $test_name
|
||||
}
|
||||
timeout {
|
||||
fail $test_name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Foreach element ELT in THINGS, run the command "print $ELT", making sure that
|
||||
# each invocation of "print" has a unique test name.
|
||||
|
||||
proc run_print_on_each_thing { things } {
|
||||
set index 0
|
||||
|
||||
foreach thing $things {
|
||||
gdb_test "print $thing" "" "printing $thing (item #$index)"
|
||||
incr index
|
||||
}
|
||||
}
|
||||
|
||||
# By default the option is set to 0.
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_test "show history remove-duplicates" "is 0\\."
|
||||
|
||||
# Test the "unlimited" setting.
|
||||
with_test_prefix "remove-duplicates=unlimited" {
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_test "set history remove-duplicates unlimited"
|
||||
|
||||
run_print_on_each_thing { 0 1 2 1 1 2 3 3 4 1 2 3 4 }
|
||||
|
||||
check_prev_history_entry "print 4"
|
||||
check_prev_history_entry "print 3"
|
||||
check_prev_history_entry "print 2"
|
||||
check_prev_history_entry "print 1"
|
||||
check_prev_history_entry "print 0"
|
||||
}
|
||||
|
||||
|
||||
# Test the "1" setting.
|
||||
with_test_prefix "remove-duplicates=1" {
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_test "set history remove-duplicates 1"
|
||||
|
||||
run_print_on_each_thing { 0 1 0 2 2 1 }
|
||||
|
||||
check_prev_history_entry "print 1"
|
||||
check_prev_history_entry "print 2"
|
||||
check_prev_history_entry "print 0"
|
||||
check_prev_history_entry "print 1" "(again)"
|
||||
check_prev_history_entry "print 0" "(again)"
|
||||
}
|
||||
|
||||
|
||||
# Test the "0" setting.
|
||||
with_test_prefix "remove-duplicates=0" {
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_test "set history remove-duplicates 0"
|
||||
|
||||
run_print_on_each_thing { 0 0 1 1 }
|
||||
|
||||
check_prev_history_entry "print 1"
|
||||
check_prev_history_entry "print 1" "(again)"
|
||||
check_prev_history_entry "print 0"
|
||||
check_prev_history_entry "print 0" "(again)"
|
||||
}
|
||||
|
||||
|
||||
# Test the "2" setting.
|
||||
with_test_prefix "remove-duplicates=2" {
|
||||
gdb_exit
|
||||
gdb_start
|
||||
gdb_test "set history remove-duplicates 2"
|
||||
|
||||
run_print_on_each_thing { 1 2 0 2 0 }
|
||||
|
||||
check_prev_history_entry "print 0"
|
||||
check_prev_history_entry "print 2"
|
||||
check_prev_history_entry "print 1"
|
||||
}
|
66
gdb/top.c
66
gdb/top.c
|
@ -698,6 +698,20 @@ show_history_size (struct ui_file *file, int from_tty,
|
|||
value);
|
||||
}
|
||||
|
||||
/* Variable associated with the "history remove-duplicates" option.
|
||||
The value -1 means unlimited. */
|
||||
static int history_remove_duplicates = 0;
|
||||
|
||||
static void
|
||||
show_history_remove_duplicates (struct ui_file *file, int from_tty,
|
||||
struct cmd_list_element *c, const char *value)
|
||||
{
|
||||
fprintf_filtered (file,
|
||||
_("The number of history entries to look back at for "
|
||||
"duplicates is %s.\n"),
|
||||
value);
|
||||
}
|
||||
|
||||
static char *history_filename;
|
||||
static void
|
||||
show_history_filename (struct ui_file *file, int from_tty,
|
||||
|
@ -897,8 +911,43 @@ static int command_count = 0;
|
|||
void
|
||||
gdb_add_history (const char *command)
|
||||
{
|
||||
add_history (command);
|
||||
command_count++;
|
||||
|
||||
if (history_remove_duplicates != 0)
|
||||
{
|
||||
int lookbehind;
|
||||
int lookbehind_threshold;
|
||||
|
||||
/* The lookbehind threshold for finding a duplicate history entry is
|
||||
bounded by command_count because we can't meaningfully delete
|
||||
history entries that are already stored in the history file since
|
||||
the history file is appended to. */
|
||||
if (history_remove_duplicates == -1
|
||||
|| history_remove_duplicates > command_count)
|
||||
lookbehind_threshold = command_count;
|
||||
else
|
||||
lookbehind_threshold = history_remove_duplicates;
|
||||
|
||||
using_history ();
|
||||
for (lookbehind = 0; lookbehind < lookbehind_threshold; lookbehind++)
|
||||
{
|
||||
HIST_ENTRY *temp = previous_history ();
|
||||
|
||||
if (temp == NULL)
|
||||
break;
|
||||
|
||||
if (strcmp (temp->line, command) == 0)
|
||||
{
|
||||
HIST_ENTRY *prev = remove_history (where_history ());
|
||||
command_count--;
|
||||
free_history_entry (prev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
using_history ();
|
||||
}
|
||||
|
||||
add_history (command);
|
||||
}
|
||||
|
||||
/* Safely append new history entries to the history file in a corruption-free
|
||||
|
@ -1880,6 +1929,21 @@ variable \"GDBHISTSIZE\", or to 256 if this variable is not set."),
|
|||
show_history_size,
|
||||
&sethistlist, &showhistlist);
|
||||
|
||||
add_setshow_zuinteger_unlimited_cmd ("remove-duplicates", no_class,
|
||||
&history_remove_duplicates, _("\
|
||||
Set how far back in history to look for and remove duplicate entries."), _("\
|
||||
Show how far back in history to look for and remove duplicate entries."), _("\
|
||||
If set to a nonzero value N, GDB will look back at the last N history entries\n\
|
||||
and remove the first history entry that is a duplicate of the most recent\n\
|
||||
entry, each time a new history entry is added.\n\
|
||||
If set to \"unlimited\", this lookbehind is unbounded.\n\
|
||||
Only history entries added during this session are considered for removal.\n\
|
||||
If set to 0, removal of duplicate history entries is disabled.\n\
|
||||
By default this option is set to 0."),
|
||||
NULL,
|
||||
show_history_remove_duplicates,
|
||||
&sethistlist, &showhistlist);
|
||||
|
||||
add_setshow_filename_cmd ("filename", no_class, &history_filename, _("\
|
||||
Set the filename in which to record the command history"), _("\
|
||||
Show the filename in which to record the command history"), _("\
|
||||
|
|
Loading…
Reference in New Issue