From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 105397 invoked by alias); 26 Jun 2015 13:35:20 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 105380 invoked by uid 89); 26 Jun 2015 13:35:19 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.3 required=5.0 tests=AWL,BAYES_50,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 X-HELO: mail-ob0-f174.google.com Received: from mail-ob0-f174.google.com (HELO mail-ob0-f174.google.com) (209.85.214.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Fri, 26 Jun 2015 13:35:18 +0000 Received: by obbop1 with SMTP id op1so66840608obb.2 for ; Fri, 26 Jun 2015 06:35:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=PreoWVdjqVLTx8hRswGpVMSwgw1VvneAXaTUWD5x1Sc=; b=VBf8ycy519nBdTh0e8lyzsAHT0DrS/eXwpICf4up+g0VM6TFsV5BnfXSO+NHdb/YsY rp7HgDCCTBkRftR9GZI153tWp1v9TrOFwzq9s4yr9ss4018frvDc/zeumSopWMc05vO7 GgkO0u0UPvdnqyG/7UZXBxzxZ9s0VndiqNsbXF1AXhKjejFT4qeVbWpOnrBhBWPwZ0AQ 7wiEsjtFl6Z0b1LaUezicVAOimzyD7jOCZbhBSQrajsWx16fptnmtXGhmSVyZa3innhg O1tVmxAT2Qmm3nChML9aP/vNOWJSh0CQHO+tRt01k8AS6qurbTRZKpMEdecNTivrCFoH NHQg== X-Gm-Message-State: ALoCoQmwRdIQMtDPUfeduKDylIepGKmI3PWkFUj8QdA1njU3ebP66V8daM6Toa5Lkbk8eBb2W3+4 X-Received: by 10.202.54.3 with SMTP id d3mr1421655oia.103.1435325716061; Fri, 26 Jun 2015 06:35:16 -0700 (PDT) MIME-Version: 1.0 Received: by 10.182.96.167 with HTTP; Fri, 26 Jun 2015 06:34:56 -0700 (PDT) In-Reply-To: <1434756821-7423-1-git-send-email-patrick@parcs.ath.cx> References: <5578539E.1020806@redhat.com> <1434756821-7423-1-git-send-email-patrick@parcs.ath.cx> From: Patrick Palka Date: Fri, 26 Jun 2015 13:35:00 -0000 Message-ID: Subject: Re: [PATCH] Add option to remove duplicate command history entries To: "gdb-patches@sourceware.org" Cc: Patrick Palka Content-Type: text/plain; charset=UTF-8 X-SW-Source: 2015-06/txt/msg00567.txt.bz2 On Fri, Jun 19, 2015 at 7:33 PM, Patrick Palka wrote: > 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. > --- > gdb/NEWS | 4 + > gdb/doc/gdb.texinfo | 15 +++ > gdb/testsuite/gdb.base/history-duplicates.exp | 129 ++++++++++++++++++++++++++ > gdb/top.c | 66 ++++++++++++- > 4 files changed, 213 insertions(+), 1 deletion(-) > create mode 100644 gdb/testsuite/gdb.base/history-duplicates.exp > > diff --git a/gdb/NEWS b/gdb/NEWS > index 3ec5851..6d29004 100644 > --- a/gdb/NEWS > +++ b/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. > diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo > index c9a532a..c5885eb 100644 > --- a/gdb/doc/gdb.texinfo > +++ b/gdb/doc/gdb.texinfo > @@ -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{size} > +@itemx set history remove-duplicates unlimited > +Control the removal of duplicate history entries in the command history list. > +If @var{size} is non-zero, @value{GDBN} will look back at the last @var{size} > +history entries and remove the first entry that is a duplicate of the current > +entry being added to the command history list. If @var{size} is > +@code{unlimited} then this lookbehind is unbounded. If @var{size} 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{!}. > diff --git a/gdb/testsuite/gdb.base/history-duplicates.exp b/gdb/testsuite/gdb.base/history-duplicates.exp > new file mode 100644 > index 0000000..f88607f > --- /dev/null > +++ b/gdb/testsuite/gdb.base/history-duplicates.exp > @@ -0,0 +1,129 @@ > +# 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 . > + > +# 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 "history entry is $entry" > + if { $test_suffix != "" } { > + append test " $test_suffix" > + } > + > + # Send ^P followed by ^L. > + send_gdb "\x10\x0c" > + > + gdb_expect { > + -re $entry { > + pass $test > + } > + timeout { > + fail $test > + } > + } > +} > + > +# 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" > + > + gdb_test "print 0" > + gdb_test "print 1" > + gdb_test "print 2" > + gdb_test "print 1" > + gdb_test "print 1" > + gdb_test "print 2" > + gdb_test "print 3" > + gdb_test "print 3" > + gdb_test "print 4" > + gdb_test "print 1" > + gdb_test "print 2" > + gdb_test "print 3" > + gdb_test "print 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" > + > + gdb_test "print 0" > + gdb_test "print 1" > + gdb_test "print 0" > + gdb_test "print 2" > + gdb_test "print 2" > + gdb_test "print 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" > + > + gdb_test "print 0" > + gdb_test "print 0" > + gdb_test "print 1" > + gdb_test "print 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" > + > + gdb_test "print 1" > + gdb_test "print 2" > + gdb_test "print 0" > + gdb_test "print 2" > + gdb_test "print 0" > + > + check_prev_history_entry "print 0" > + check_prev_history_entry "print 2" > + check_prev_history_entry "print 1" > +} > diff --git a/gdb/top.c b/gdb/top.c > index 6ae84ab..5114c2e 100644 > --- a/gdb/top.c > +++ b/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 > @@ -1872,6 +1921,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 non-zero 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"), _("\ > -- > 2.4.4.410.g43ed522.dirty > Ping.