night@pawl.rpi.edu (Trip Martin) (11/09/89)
I realize this group is for bash bugs, but I couldn't find any other group which was more suitable. My apologies if this is the wrong group. I just got bash up and running on a 3B2, and looking through the documentation, I noticed that the only way to enter vi-mode is by having a .inputrc when the program is first run. There are times when I would like to be able to switch to vi-mode after bash is already running. Why is the extra rc file (.inputrc) necessary, and why is that the only way to enter vi-mode? Trip Martin KA2LIV night@pawl.rpi.edu Finite state machinist night@uruguay.acm.rpi.edu -- Trip Martin KA2LIV night@pawl.rpi.edu Finite state machinist night@uruguay.acm.rpi.edu
bfox%vision@HUB.UCSB.EDU (Brian Fox) (11/11/89)
Posted-Date: 9 Nov 89 02:38:42 GMT Date: 9 Nov 89 02:38:42 GMT From: rpi!night@cis.ohio-state.edu (Trip Martin) Organization: Rensselaer Polytechnic Institute, Troy NY Sender: bug-bash-request@prep.ai.mit.edu I just got bash up and running on a 3B2, and looking through the documentation, I noticed that the only way to enter vi-mode is by having a .inputrc when the program is first run. There are times when I would like to be able to switch to vi-mode after bash is already running. Why is the extra rc file (.inputrc) necessary, and why is that the only way to enter vi-mode? M-C-j toggles between the two modes. Placing "set editing-mode vi" in your .inputrc file brings up line editing in vi mode. Typing C-x C-r re-reads your .inputrc file. Brian
night@PAWL.RPI.EDU (Trip Martin KA2LIV night@pawl.rpi.edu) (11/13/89)
Thanks for the info regarding vi-mode. I've made some changes so that all the stuff that's done in the .inputrc can be done from the shell as well. I've added two flags to set: "+z" for vi-mode, and "-s" for horizontal-scroll-mode. For rebinding keys, I've added the builtin "bind", which can handle both functions and macros (using the "macro" keyword). I've also changed vi-mode so that control chars come out as ^X rather than C-X (vi does it this way, so I think bash should too in vi-mode). Also, the builtin documentation has been updated to reflect these changes. I'd like to see these changes incorporated into the bash distribution. If you'd like to use them, just send me a message, and I'll send you the patches. -- Trip Martin KA2LIV night@pawl.rpi.edu Finite state machinist night@uruguay.acm.rpi.edu
night@PAWL.RPI.EDU (Trip Martin KA2LIV night@pawl.rpi.edu) (11/13/89)
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 <readline/history.h> + #include <readline/readline.h> #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;