Path: utzoo!telly!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!genbank!apple!gem.mps.ohio-state.edu!tut.cis.ohio-state.edu!PAWL.RPI.EDU!night From: night@PAWL.RPI.EDU (Trip Martin KA2LIV night@pawl.rpi.edu) Newsgroups: gnu.bash.bug Subject: Re: Question about vi-mode Message-ID: <8911131417.AA23466@pawl.rpi.edu> Date: 13 Nov 89 14:15:51 GMT References: <8911130830.AA22741@hub.ucsb.edu> Sender: daemon@tut.cis.ohio-state.edu Distribution: gnu Organization: GNUs Not Usenet Lines: 268 Here are the patches. There are a couple of other patches I forgot to mention. Both affect reading stty settings for erase and kill to include them in the keymaps. The first allows it to work under termio. The second causes changes to be made in both emacs and vi keymaps, so that a change in editing-mode won't affect those keys. Trip Martin --------------------------- cut here ----------------------------- *** flags.c Sun Nov 12 23:36:37 1989 --- flags.c Sun Nov 12 23:36:14 1989 *************** *** 96,101 **** --- 96,109 ---- This means !22 gets the 22nd line of history. */ int history_expansion = 1; + /* Non-zero means emacs-editing mode in effect. The variable is + already defined in readline/readline.c */ + extern int rl_editing_mode; + + /* Non-zero means that horizontal-scroll mode is in effect. The + variable is already defined in readline/readline.c */ + extern int horizontal_scroll_mode; + /* **************************************************************** */ /* */ /* The Flags ALIST. */ *************** *** 123,128 **** --- 131,138 ---- /* New flags that control non-standard things. */ {"l", &lexical_scoping}, {"i", &no_invisible_vars}, + {"z", &rl_editing_mode}, + {"s", &horizontal_scroll_mode}, /* I want `h', but locate_commands_in_functions has it. Great. */ {"d", &hashing_disabled}, *** builtins.c Sun Nov 12 23:38:32 1989 --- builtins.c Sun Nov 12 23:46:09 1989 *************** *** 35,40 **** --- 35,41 ---- #include "trap.h" #include "flags.h" #include + #include #ifdef JOB_CONTROL #include "jobs.h" *************** *** 85,90 **** --- 86,96 ---- word to be checked for alias substitution. Alias returns true\n\ unless a NAME is given for which no alias has been defined" }, + { "bind", bind_builtin, 1, "bind [ [[macro] key [predicate]] ... ]", + " Bind the key sequence KEY to PREDICATE, which can be either a\n\ + function or a macro sequence. If PREDICATE is to be a function\n\ + and is either not present or is \"nil\", KEY is unbound" }, + #ifdef JOB_CONTROL { "bg", bg_builtin, 1, "bg [job_spec]", " Place JOB_SPEC in the background, as if it had been started with\n\ *************** *** 264,270 **** " Causes a function to exit with the return value specified by N.\n\ If N is omitted, the return status is that of the last command" }, ! { "set", set_builtin, 1, "set [-aefhkntuvx] [arg ...]", " -a Mark variables which are modified or created for export\n\ -e Exit immediately if a command exits with a non-zero status\n\ -f Disable file name generation (globbing)\n\ --- 270,276 ---- " Causes a function to exit with the return value specified by N.\n\ If N is omitted, the return status is that of the last command" }, ! { "set", set_builtin, 1, "set [-aefhknstuvxz] [arg ...]", " -a Mark variables which are modified or created for export\n\ -e Exit immediately if a command exits with a non-zero status\n\ -f Disable file name generation (globbing)\n\ *************** *** 282,287 **** --- 288,296 ---- -d Disable the hashing of commands that are looked up for execution.\n\ Normally, commands are remembered in a hash table, and once\n\ found, do not have to be looked up again\n\ + -s Enable horizontal-scroll-mode for command line editing\n\ + -z Enable emacs-mode for command line editing (disabling\n\ + emacs-mode enables vi-mode)\n\ -o Enable ! style history substitution. This flag is on by\n\ by default.\n\ \n\ *************** *** 3293,3295 **** --- 3302,3388 ---- #endif /* JOB_CONTROL */ + /* We need the current keymap to pass to rl_set_key() */ + extern Keymap keymap; + extern Function *rl_named_function(); + + bind_builtin (list) + WORD_LIST *list; + { + int keyseqlen, macro_len, bind_type; + char *key, *bind_name, keyseq[10], macro_keys[10]; + Function *funcall; + + while (list) + { + key = list->word->word; + list = list->next; + + /* Is this a macro or function definition? */ + if (strcmp (key, "macro") == 0) + { + bind_type = ISMACR; + if (list) + { + key = list->word->word; + list = list->next; + } + else + { + report_error ("bind: Missing macro definition"); + return (EXECUTION_FAILURE); + } + } + else + bind_type = ISFUNC; + + /* Get binding predicate */ + if (list) + { + bind_name = list->word->word; + list = list->next; + } + else + bind_name = (char *) NULL; + + /* See if the key is to be unbound */ + if (bind_type == ISFUNC && strcmp (bind_name, "nil") == 0) + bind_name = (char *) NULL; + + /* See that the key given is valid */ + if (rl_translate_keyseq (key, keyseq, &keyseqlen)) + { + report_error ("bind: Invalid key %s",key); + return (EXECUTION_FAILURE); + } + else + keyseq[keyseqlen] = '\0'; + + /* Make sure binding is valid */ + if (bind_type == ISFUNC) + { + /* Function key-binding -- make sure function actually exists */ + if (bind_name && !(funcall = rl_named_function (bind_name))) + { + report_error ("bind: Invalid function %s",bind_name); + return (EXECUTION_FAILURE); + } + } + else + if (bind_name && + !rl_translate_keyseq (bind_name, macro_keys, ¯o_len)) + macro_keys[macro_len] = '\0'; + else + { + report_error ("bind: Invalid macro sequence: %s", bind_name); + return (EXECUTION_FAILURE); + } + + /* Everything checks out -- do key binding */ + if (bind_type == ISFUNC) + rl_generic_bind (ISFUNC, keyseq, funcall, keymap); + else + rl_generic_bind (ISMACR, keyseq, macro_keys, keymap); + } + return (EXECUTION_SUCCESS); + } *** readline.c Sun Nov 12 23:52:29 1989 --- readline.c Mon Nov 13 00:10:42 1989 *************** *** 1043,1053 **** int erase = ttybuff.sg_erase, kill = ttybuff.sg_kill; if (erase != -1 && keymap[erase].type == ISFUNC) ! keymap[erase].function = rl_rubout; if (kill != -1 && keymap[kill].type == ISFUNC) ! keymap[kill].function = rl_unix_line_discard; } #ifdef TIOCGLTC { --- 1043,1059 ---- int erase = ttybuff.sg_erase, kill = ttybuff.sg_kill; if (erase != -1 && keymap[erase].type == ISFUNC) ! { ! emacs_standard_keymap[erase].function = rl_rubout; ! vi_insertion_keymap[erase].function = rl_rubout; ! } if (kill != -1 && keymap[kill].type == ISFUNC) ! { ! emacs_standard_keymap[kill].function = rl_unix_line_discard; ! vi_insertion_keymap[kill].function = rl_unix_line_discard; } + } #ifdef TIOCGLTC { *************** *** 1065,1070 **** --- 1071,1098 ---- } } #endif /* TIOCGLTC */ + #else + #ifdef TCGETA + struct termio ttybuff; + int tty = fileno (rl_instream); + + if (ioctl (tty, TCGETA, &ttybuff) != -1) + { + int erase = ttybuff.c_cc[VERASE], kill = ttybuff.c_cc[VKILL]; + + if (erase != -1 && keymap[erase].type == ISFUNC) + { + emacs_standard_keymap[erase].function = rl_rubout; + vi_insertion_keymap[erase].function = rl_rubout; + } + + if (kill != -1 && keymap[kill].type == ISFUNC) + { + emacs_standard_keymap[kill].function = rl_unix_line_discard; + vi_insertion_keymap[kill].function = rl_unix_line_discard; + } + } + #endif /* TCGETA */ #endif /* TIOCGETP */ } *************** *** 1311,1319 **** --- 1339,1355 ---- #endif else if (c < 32) { + if (rl_editing_mode == emacs_mode) + { line[out++] = 'C'; line[out++] = '-'; line[out++] = c + 64; + } + else + { + line[out++] = '^'; + line[out++] = c + 64; + } } else line[out++] = c;