From: Tom Tromey <tromey@redhat.com>
To: Elena Zannoni <ezannoni@cygnus.com>
Cc: gdb-patches@sources.redhat.com
Subject: Re: PATCH: operate-and-get-next
Date: Sat, 13 Oct 2001 10:24:00 -0000 [thread overview]
Message-ID: <87g08nzbho.fsf@creche.redhat.com> (raw)
In-Reply-To: <15300.61266.27769.906320@krustylu.cygnus.com>
>>>>> "Elena" == Elena Zannoni <ezannoni@cygnus.com> writes:
Elena> It looks to me that prompt_just_set is always 1, after it is
Elena> set the very first time. So it doesn't really help.
Quite right, sorry.
Elena> Instead of having this global variable, could it be possible to
Elena> play with installing and un-installing the hook itself? And
Elena> then have rl_callback_read_char_wrapper do a check
Ok, I implemented this. And it does make things cleaner. Thanks.
I don't really like the hook name I chose but I was unable to think of
a better one. I can rename it to whatever you like.
The new patch is appended.
It has one very ugly thing, namely the call to
after_char_processing_hook in start_event_loop. Without this call,
if the user entered a command that caused an error, then the
C-o binding wouldn't work.
For instance I tested it like this:
output 1\n <- gives an error
p 1
C-p C-p <- move up history
C-o <- re-accept the error line
This would fail to put `p 1' into the editing buffer.
The reason is that the error causes us to unwind past the call to
after_char_processing_hook.
I tried calling the hook from a cleanup in rl_callback_read_char_wrapper,
but that didn't work. The problem is that the error unwinding leaves
the readline in a state that we can't anticipate -- the where_history()
value is wrong, so the operate-and-get-next completion code doesn't
work.
What I'd really like is a hook which is called at the right point
after the prompt is printed. It doesn't need to be called for every
character (that is the conceptual problem, I think, with the appended).
Unfortunately calling the hook in display_gdb_prompt won't work, for
reasons mentioned in my first patch.
I guess I could try to put an `after_prompt_hook' into start_event_loop.
This might work ok. What would you think of that? Or is there
another approach you'd like me to try?
Thanks,
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* event-loop.c (start_event_loop): Call
after_char_processing_hook.
* event-top.h (after_char_processing_hook): Declare.
* event-top.c (rl_callback_read_char_wrapper): Call
after_char_processing_hook.
(after_char_processing_hook): New global.
* top.c (operate_saved_history): New global.
(gdb_rl_operate_and_get_next): New function.
(init_main): Add the operate-and-get-next defun.
(gdb_rl_operate_and_get_next_completion): New function.
Index: event-loop.c
===================================================================
RCS file: /cvs/src/src/gdb/event-loop.c,v
retrieving revision 1.16
diff -u -r1.16 event-loop.c
--- event-loop.c 2001/03/27 20:36:23 1.16
+++ event-loop.c 2001/10/13 17:11:13
@@ -402,6 +402,14 @@
interface specific, because interfaces can display the
prompt in their own way. */
display_gdb_prompt (0);
+ /* This call looks bizarre, but it is required. If the user
+ entered a command that caused an error,
+ after_char_processing_hook won't be called from
+ rl_callback_read_char_wrapper. Using a cleanup there
+ won't work, since we want this function to be called
+ after a new prompt is printed. */
+ if (after_char_processing_hook)
+ (*after_char_processing_hook) ();
/* Maybe better to set a flag to be checked somewhere as to
whether display the prompt or not. */
}
Index: event-top.c
===================================================================
RCS file: /cvs/src/src/gdb/event-top.c,v
retrieving revision 1.16
diff -u -r1.16 event-top.c
--- event-top.c 2001/08/27 22:39:55 1.16
+++ event-top.c 2001/10/13 17:11:15
@@ -153,6 +153,10 @@
char *linebuffer_ptr;
}
readline_input_state;
+
+/* This hook is called by rl_callback_read_char_wrapper after each
+ character is processed. */
+void (*after_char_processing_hook) ();
\f
/* Wrapper function for calling into the readline library. The event
@@ -162,6 +166,8 @@
rl_callback_read_char_wrapper (gdb_client_data client_data)
{
rl_callback_read_char ();
+ if (after_char_processing_hook)
+ (*after_char_processing_hook) ();
}
/* Initialize all the necessary variables, start the event loop,
Index: event-top.h
===================================================================
RCS file: /cvs/src/src/gdb/event-top.h,v
retrieving revision 1.3
diff -u -r1.3 event-top.h
--- event-top.h 2001/04/20 14:25:59 1.3
+++ event-top.h 2001/10/13 17:11:15
@@ -108,3 +108,4 @@
extern void (*call_readline) (void *);
extern void (*input_handler) (char *);
extern int input_fd;
+extern void (*after_char_processing_hook) (void);
Index: top.c
===================================================================
RCS file: /cvs/src/src/gdb/top.c,v
retrieving revision 1.45
diff -u -r1.45 top.c
--- top.c 2001/09/07 21:33:08 1.45
+++ top.c 2001/10/13 17:11:17
@@ -1032,6 +1032,55 @@
#endif
}
\f
+/* The current saved history number from operate-and-get-next.
+ This is -1 if not valid. */
+static int operate_saved_history = -1;
+
+/* This is put on the appropriate hook and helps operate-and-get-next
+ do its work. */
+ void
+gdb_rl_operate_and_get_next_completion ()
+{
+ if (operate_saved_history != -1)
+ {
+ int delta = where_history () - operate_saved_history;
+ /* The `key' argument to rl_get_previous_history is ignored. */
+ rl_get_previous_history (delta, 0);
+ operate_saved_history = -1;
+
+ /* readline doesn't automatically update the display for us. */
+ rl_redisplay ();
+
+ after_char_processing_hook = NULL;
+ rl_pre_input_hook = NULL;
+ }
+}
+
+/* This is a gdb-local readline command handler. It accepts the
+ current command line (like RET does) and, if this command was taken
+ from the history, arranges for the next command in the history to
+ appear on the command line when the prompt returns.
+ We ignore the arguments. */
+static int
+gdb_rl_operate_and_get_next (int count, int key)
+{
+ if (event_loop_p)
+ {
+ /* Use the async hook. */
+ after_char_processing_hook = gdb_rl_operate_and_get_next_completion;
+ }
+ else
+ {
+ /* This hook only works correctly when we are using the
+ synchronous readline. */
+ rl_pre_input_hook = (Function *) gdb_rl_operate_and_get_next_completion;
+ }
+
+ /* Add 1 because we eventually want the next line. */
+ operate_saved_history = where_history () + 1;
+ return rl_newline (1, key);
+}
+\f
/* Read one line from the command input stream `instream'
into the local static buffer `linebuffer' (whose current length
is `linelength').
@@ -1881,6 +1930,10 @@
get_gdb_completer_word_break_characters ();
rl_completer_quote_characters = get_gdb_completer_quote_characters ();
rl_readline_name = "gdb";
+
+ /* The name for this defun comes from Bash, where it originated.
+ 15 is Control-o, the same binding this function has in Bash. */
+ rl_add_defun ("operate-and-get-next", gdb_rl_operate_and_get_next, 15);
/* The set prompt command is different depending whether or not the
async version is run. NOTE: this difference is going to
Index: doc/ChangeLog
from Tom Tromey <tromey@redhat.com>
* gdb.texinfo (Command Syntax): Document C-o binding.
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.51
diff -u -r1.51 gdb.texinfo
--- doc/gdb.texinfo 2001/09/12 19:49:52 1.51
+++ doc/gdb.texinfo 2001/10/13 17:11:34
@@ -1190,6 +1190,13 @@
nothing. This is useful mainly in command files (@pxref{Command
Files,,Command files}).
+@cindex repeating command sequences
+@kindex C-o @r{(operate-and-get-next)}
+The @kbd{C-o} binding is useful for repeating a complex sequence of
+commands. This command accepts the current line, like @kbd{RET}, and
+then fetches the next line relative to the current line from the history
+for editing.
+
@node Completion
@section Command completion
next prev parent reply other threads:[~2001-10-13 10:24 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-10-03 16:05 Tom Tromey
2001-10-04 0:00 ` Eli Zaretskii
2001-10-04 18:16 ` Tom Tromey
2001-10-09 12:06 ` Eli Zaretskii
2001-10-09 12:48 ` Tom Tromey
2001-10-10 17:53 ` Elena Zannoni
2001-10-13 10:24 ` Tom Tromey [this message]
2001-10-15 9:13 ` Elena Zannoni
[not found] ` <878zdibdxb.fsf@creche.redhat.com>
2001-11-08 16:01 ` Elena Zannoni
2001-11-08 18:22 ` Tom Tromey
2001-11-09 13:16 ` Eli Zaretskii
[not found] <15362.64511.39505.586347@krustylu.cygnus.com>
2001-11-13 9:48 ` Elena Zannoni
2001-11-13 10:55 ` Tom Tromey
2001-11-26 19:26 ` Tom Tromey
2001-11-26 23:43 ` Eli Zaretskii
2001-11-14 11:56 ` Eli Zaretskii
2001-11-26 18:36 ` Elena Zannoni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87g08nzbho.fsf@creche.redhat.com \
--to=tromey@redhat.com \
--cc=ezannoni@cygnus.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox