| Ilya Zakharevich on Thu, 17 Oct 2002 12:08:40 -0700 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| [PATCH CVS] Readline improvements |
[Some time ago F1/M-h did not work before parentheses of
function()
Apparently, it was recently fixed. However, in between somebody
noticed this lack of functionallity, and switched off an important
feature of TAB - to make TAB work as F1 in this situation. Thus
currently F1 and TAB do the same between parentheses (as above).]
This patch:
a) Restores the historic behaviour of TAB (insert the template for
function arguments), if one wants help, press F1 or M-h;
b) make default(readline,4) and default(readline,2) etc. switch the
electric TAB (as above) and electric-parens settings;
c) Better formatting of the message when one switches the two
setting above (by giving non-positive arguments to TAB or "(");
d) Colors now work with default(readline,0) too;
e) Beginning of support for Mouse-Editing in xterm (see
http://groups.google.com/groups?selm=ani7hg%24bmf%241%40agate.berkeley.edu&output=gplain).
Currently we support the 2004 setting by interpreting F200/F201
as signals to switch off/back electric parens. In particular,
one can have default(readline,2) *and* cut-and-paste in new xterm
without bad interactions (if one enables 2004 before entering gp).
This probably is not 100%-proof in vi-mode. However, I cannot
fix it, since I'm vi-ignorant.
Enjoy,
Ilya
--- ./src/gp/gp_rl.c-pre3 Tue Oct 15 20:26:50 2002
+++ ./src/gp/gp_rl.c Thu Oct 17 03:08:46 2002
@@ -61,8 +61,6 @@ static entree *current_ep = NULL;
static int pari_rl_back;
extern RLCI rl_last_func;
-static int do_args_complete = 1;
-static int do_matched_insert = 0;
static int did_init_matched = 0;
#ifdef HAS_RL_SAVE_PROMPT
@@ -88,22 +86,32 @@ static int did_init_matched = 0;
# define USER_COMPLETION ((GF)username_completion_function)
#endif
-#define ELECTRIC_PAREN 1
-#define ARGS_COMPLETE 2
static int
-change_state(char *msg, int *opt, int count)
+change_state(char *msg, ulong flag, int count)
{
- int c;
+ int c = (readline_state & flag) != 0;
+ ulong o_readline_state = readline_state;
switch(count)
{
default: c = 0; break; /* off */
case -1: c = 1; break; /* on */
- case -2: c = 1 - *opt; /* toggle */
+ case -2: c = 1 - c; /* toggle */
+ }
+ if (c)
+ readline_state |= flag;
+ else {
+ readline_state &= ~flag;
+ if (!readline_state && o_readline_state)
+ readline_state = 1;
}
- *opt = c;
SAVE_PROMPT();
- rl_message("%s: %s.", msg, c? "on": "off");
+#if 0 /* Does not work well... */
+ rl_message("%s[%s: %s] %s", term_get_color(c_PROMPT),
+ msg, c? "on": "off", term_get_color(c_INPUT));
+#else
+ rl_message("[%s: %s] ", msg, c? "on": "off");
+#endif
c = rl_read_key();
RESTORE_PROMPT();
rl_clear_message();
@@ -118,7 +126,7 @@ pari_rl_complete(int count, int key)
pari_rl_back = 0;
if (count <= 0)
- return change_state("complete args", &do_args_complete, count);
+ return change_state("complete args", DO_ARGS_COMPLETE, count);
rl_begin_undo_group();
if (rl_last_func == pari_rl_complete)
@@ -129,6 +137,28 @@ pari_rl_complete(int count, int key)
rl_end_undo_group(); return ret;
}
+static int did_matched_insert;
+
+static int
+pari_rl_matched_insert_suspend(int count, int key)
+{
+ ulong o_readline_state = readline_state;
+
+ did_matched_insert = (readline_state & DO_MATCHED_INSERT);
+ readline_state &= ~DO_MATCHED_INSERT;
+ if (!readline_state && o_readline_state)
+ readline_state = 1;
+ return 1;
+}
+
+static int
+pari_rl_matched_insert_restore(int count, int key)
+{
+ if (did_matched_insert)
+ readline_state |= DO_MATCHED_INSERT;
+ return 1;
+}
+
static const char paropen[] = "([{";
static const char parclose[] = ")]}";
@@ -139,9 +169,9 @@ pari_rl_matched_insert(int count, int ke
int i = 0, ret;
if (count <= 0)
- return change_state("electric parens", &do_matched_insert, count);
+ return change_state("electric parens", DO_MATCHED_INSERT, count);
while (paropen[i] && paropen[i] != key) i++;
- if (!paropen[i] || !do_matched_insert || GP_DATA->flags & EMACS)
+ if (!paropen[i] || !(readline_state & DO_MATCHED_INSERT) || GP_DATA->flags & EMACS)
return ((RLCI)rl_insert)(count,key);
rl_begin_undo_group();
((RLCI)rl_insert)(count,key);
@@ -155,7 +185,7 @@ pari_rl_default_matched_insert(int count
{
if (!did_init_matched) {
did_init_matched = 1;
- do_matched_insert = 1;
+ readline_state |= DO_MATCHED_INSERT;
}
return pari_rl_matched_insert(count, key);
}
@@ -537,17 +567,37 @@ pari_completion(char *text, int START, i
while (j <= END && isspace((int)rl_line_buffer[j])) j++;
k = END;
while (k > j && isspace((int)rl_line_buffer[k])) k--;
- /* If we are in empty parens, output function help */
- if (do_args_complete && k == j
+ /* If we are in empty parens, insert the default arguments */
+ if ((readline_state & DO_ARGS_COMPLETE) && k == j
&& (rl_line_buffer[j] == ')' || !rl_line_buffer[j])
&& (iend - i < MAX_KEYWORD)
&& ( strncpy(buf, rl_line_buffer + i, iend - i),
buf[iend - i] = 0, 1)
&& (ep = is_entry(buf)) && ep->help)
{
+#if 1
+ char *s = ep->help;
+
+ while (is_keyword_char(*s)) s++;
+ if (*s++ == '(')
+ { /* Function, print arguments! */
+ char *endh = s;
+ while (*endh && *endh != ')' && *endh != '(') endh++;
+ if (*endh == ')')
+ { /* Well-formed help. */
+ char *str = strncpy((char*) gpmalloc(endh-s + 1), s, endh-s);
+ char **ret = (char**)gpmalloc(sizeof(char*)*2);
+ str[endh-s] = 0;
+ ret[0] = str; ret[1] = NULL;
+ if (GP_DATA->flags & EMACS) ret = matches_for_emacs("",ret);
+ return ret;
+ }
+ }
+#else /* Why duplicate F1 (and emit a bell)?! */
rl_print_aide(buf,h_RL);
rl_attempted_completion_over = 1;
return NULL;
+#endif
}
}
for(i=END-1;i>=start;i--)
@@ -631,6 +681,8 @@ init_readline(void)
Defun("long-help", rl_long_help, -1);
Defun("pari-complete", pari_rl_complete, '\t');
Defun("pari-matched-insert", pari_rl_default_matched_insert, -1);
+ Defun("pari-matched-insert-suspend", pari_rl_matched_insert_suspend, -1);
+ Defun("pari-matched-insert-restore", pari_rl_matched_insert_restore, -1);
Defun("pari-forward-sexp", pari_rl_forward_sexp, -1);
Defun("pari-backward-sexp", pari_rl_backward_sexp, -1);
@@ -645,6 +697,13 @@ init_readline(void)
KSbind("[11~", rl_short_help, emacs_meta_keymap); /* f1, xterm */
KSbind("OP", rl_short_help, vi_movement_keymap); /* f1, vt100 */
KSbind("[11~", rl_short_help, vi_movement_keymap); /* f1, xterm */
+ /* XTerm may signal start/end of paste by eming F200/F201 */
+ /* XXXX For vi mode something more intelligent is needed - to switch to the
+ insert mode - and back when restoring. */
+ KSbind("[200~", pari_rl_matched_insert_suspend, emacs_meta_keymap); /* pre-paste xterm */
+ KSbind("[200~", pari_rl_matched_insert_suspend, vi_movement_keymap); /* pre-paste xterm */
+ KSbind("[201~", pari_rl_matched_insert_restore, emacs_meta_keymap); /* post-paste xterm */
+ KSbind("[201~", pari_rl_matched_insert_restore, vi_movement_keymap); /* post-paste xterm */
# endif
Bind('(', pari_rl_matched_insert, emacs_standard_keymap);
Bind('[', pari_rl_matched_insert, emacs_standard_keymap);
--- ./src/gp/gp.c-pre3 Tue Oct 15 20:26:00 2002
+++ ./src/gp/gp.c Thu Oct 17 02:51:42 2002
@@ -637,16 +637,31 @@ static GEN
sd_debug(char *v, int flag)
{ return sd_ulong(v,flag,"debug",&DEBUGLEVEL, 0,20,NULL); }
+#ifdef READLINE
+ulong readline_state = DO_ARGS_COMPLETE;
+#endif
+
static GEN
sd_rl(char *v, int flag)
{
#ifdef READLINE
+ static const char * const msg[] = {NULL,
+ "(bits 0x2/0x4 control matched-insert/arg-complete)"};
+ ulong o_readline_state;
+ GEN res;
+
if (!readline_init && *v && *v != '0') {
init_readline();
readline_init = 1;
}
+ o_readline_state = readline_state;
+ res = sd_ulong(v,flag,"readline", &readline_state, 0, 3, (char**)msg);
+ if (o_readline_state != readline_state)
+ sd_gptoggle(readline_state ? "1" : "0", d_SILENT, "readline", USE_READLINE);
+ return res;
+#else
+ sd_gptoggle(v, flag, "readline", USE_READLINE);
#endif
- return sd_gptoggle(v,flag,"readline", USE_READLINE);
}
static GEN
@@ -2209,10 +2224,13 @@ brace_color(char *s, int c, int force)
{
if (disable_color || (gp_colors[c] == c_NONE && !force)) return;
#ifdef RL_PROMPT_START_IGNORE
- *s++ = RL_PROMPT_START_IGNORE;
+ if (GP_DATA->flags & USE_READLINE)
+ *s++ = RL_PROMPT_START_IGNORE;
#endif
strcpy(s, term_get_color(c));
#ifdef RL_PROMPT_START_IGNORE
+ if (!(GP_DATA->flags & USE_READLINE))
+ return;
s+=strlen(s);
*s++ = RL_PROMPT_END_IGNORE; *s = 0;
#endif
--- ./src/gp/gp.h-pre3 Tue Jun 11 17:24:10 2002
+++ ./src/gp/gp.h Thu Oct 17 02:38:18 2002
@@ -30,6 +30,10 @@ extern ulong init_opts;
extern char *current_logfile;
extern jmp_buf environnement;
+extern ulong readline_state;
+#define DO_MATCHED_INSERT 2
+#define DO_ARGS_COMPLETE 4
+
/* for do_time() */
enum { ti_NOPRINT, ti_REGULAR, ti_LAST, ti_INTERRUPT };