📄 bind.c
字号:
return ((Function *)NULL);}/* Return the function (or macro) definition which would be invoked via KEYSEQ if executed in MAP. If MAP is NULL, then the current keymap is used. TYPE, if non-NULL, is a pointer to an int which will receive the type of the object pointed to. One of ISFUNC (function), ISKMAP (keymap), or ISMACR (macro). */Function *rl_function_of_keyseq (keyseq, map, type) char *keyseq; Keymap map; int *type;{ register int i; if (!map) map = _rl_keymap; for (i = 0; keyseq && keyseq[i]; i++) { int ic = keyseq[i]; if (META_CHAR (ic) && _rl_convert_meta_chars_to_ascii) { if (map[ESC].type != ISKMAP) { if (type) *type = map[ESC].type; return (map[ESC].function); } else { map = FUNCTION_TO_KEYMAP (map, ESC); ic = UNMETA (ic); } } if (map[ic].type == ISKMAP) { /* If this is the last key in the key sequence, return the map. */ if (!keyseq[i + 1]) { if (type) *type = ISKMAP; return (map[ic].function); } else map = FUNCTION_TO_KEYMAP (map, ic); } else { if (type) *type = map[ic].type; return (map[ic].function); } } return ((Function *) NULL);}/* The last key bindings file read. */static char *last_readline_init_file = (char *)NULL;/* The file we're currently reading key bindings from. */static char *current_readline_init_file;static int current_readline_init_include_level;static int current_readline_init_lineno;/* Read FILENAME into a locally-allocated buffer and return the buffer. The size of the buffer is returned in *SIZEP. Returns NULL if any errors were encountered. */static char *_rl_read_file (filename, sizep) char *filename; size_t *sizep;{ struct stat finfo; size_t file_size; char *buffer; int i, file; if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0) return ((char *)NULL); file_size = (size_t)finfo.st_size; /* check for overflow on very large files */ if (file_size != finfo.st_size || file_size + 1 < file_size) { if (file >= 0) close (file);#if defined (EFBIG) errno = EFBIG;#endif return ((char *)NULL); } /* Read the file into BUFFER. */ buffer = (char *)xmalloc (file_size + 1); i = read (file, buffer, file_size); close (file);#if 0 if (i < file_size)#else if (i < 0)#endif { free (buffer); return ((char *)NULL); }#if 0 buffer[file_size] = '\0'; if (sizep) *sizep = file_size;#else buffer[i] = '\0'; if (sizep) *sizep = i;#endif return (buffer);}/* Re-read the current keybindings file. */intrl_re_read_init_file (count, ignore) int count, ignore;{ int r; r = rl_read_init_file ((char *)NULL); rl_set_keymap_from_edit_mode (); return r;}/* Do key bindings from a file. If FILENAME is NULL it defaults to the first non-null filename from this list: 1. the filename used for the previous call 2. the value of the shell variable `INPUTRC' 3. ~/.inputrc If the file existed and could be opened and read, 0 is returned, otherwise errno is returned. */intrl_read_init_file (filename) char *filename;{ /* Default the filename. */ if (filename == 0) { filename = last_readline_init_file; if (filename == 0) filename = get_env_value ("INPUTRC"); if (filename == 0) filename = DEFAULT_INPUTRC; } if (*filename == 0) filename = DEFAULT_INPUTRC;#if defined (__MSDOS__) if (_rl_read_init_file (filename, 0) == 0) return 0; filename = "~/_inputrc";#endif return (_rl_read_init_file (filename, 0));}static int_rl_read_init_file (filename, include_level) char *filename; int include_level;{ register int i; char *buffer, *openname, *line, *end; size_t file_size; current_readline_init_file = filename; current_readline_init_include_level = include_level; openname = tilde_expand (filename); buffer = _rl_read_file (openname, &file_size); free (openname); if (buffer == 0) return (errno); if (include_level == 0 && filename != last_readline_init_file) { FREE (last_readline_init_file); last_readline_init_file = savestring (filename); } currently_reading_init_file = 1; /* Loop over the lines in the file. Lines that start with `#' are comments; all other lines are commands for readline initialization. */ current_readline_init_lineno = 1; line = buffer; end = buffer + file_size; while (line < end) { /* Find the end of this line. */ for (i = 0; line + i != end && line[i] != '\n'; i++);#if defined (__CYGWIN32__) /* ``Be liberal in what you accept.'' */ if (line[i] == '\n' && line[i-1] == '\r') line[i - 1] = '\0';#endif /* Mark end of line. */ line[i] = '\0'; /* Skip leading whitespace. */ while (*line && whitespace (*line)) { line++; i--; } /* If the line is not a comment, then parse it. */ if (*line && *line != '#') rl_parse_and_bind (line); /* Move to the next line. */ line += i + 1; current_readline_init_lineno++; } free (buffer); currently_reading_init_file = 0; return (0);}static void_rl_init_file_error (msg) char *msg;{ if (currently_reading_init_file) fprintf (stderr, "readline: %s: line %d: %s\n", current_readline_init_file, current_readline_init_lineno, msg); else fprintf (stderr, "readline: %s\n", msg);}/* **************************************************************** *//* *//* Parser Directives *//* *//* **************************************************************** *//* Conditionals. *//* Calling programs set this to have their argv[0]. */char *rl_readline_name = "other";/* Stack of previous values of parsing_conditionalized_out. */static unsigned char *if_stack = (unsigned char *)NULL;static int if_stack_depth;static int if_stack_size;/* Push _rl_parsing_conditionalized_out, and set parser state based on ARGS. */static intparser_if (args) char *args;{ register int i; /* Push parser state. */ if (if_stack_depth + 1 >= if_stack_size) { if (!if_stack) if_stack = (unsigned char *)xmalloc (if_stack_size = 20); else if_stack = (unsigned char *)xrealloc (if_stack, if_stack_size += 20); } if_stack[if_stack_depth++] = _rl_parsing_conditionalized_out; /* If parsing is turned off, then nothing can turn it back on except for finding the matching endif. In that case, return right now. */ if (_rl_parsing_conditionalized_out) return 0; /* Isolate first argument. */ for (i = 0; args[i] && !whitespace (args[i]); i++); if (args[i]) args[i++] = '\0'; /* Handle "$if term=foo" and "$if mode=emacs" constructs. If this isn't term=foo, or mode=emacs, then check to see if the first word in ARGS is the same as the value stored in rl_readline_name. */ if (rl_terminal_name && _rl_strnicmp (args, "term=", 5) == 0) { char *tem, *tname; /* Terminals like "aaa-60" are equivalent to "aaa". */ tname = savestring (rl_terminal_name); tem = strchr (tname, '-'); if (tem) *tem = '\0'; /* Test the `long' and `short' forms of the terminal name so that if someone has a `sun-cmd' and does not want to have bindings that will be executed if the terminal is a `sun', they can put `$if term=sun-cmd' into their .inputrc. */ _rl_parsing_conditionalized_out = _rl_stricmp (args + 5, tname) && _rl_stricmp (args + 5, rl_terminal_name); free (tname); }#if defined (VI_MODE) else if (_rl_strnicmp (args, "mode=", 5) == 0) { int mode; if (_rl_stricmp (args + 5, "emacs") == 0) mode = emacs_mode; else if (_rl_stricmp (args + 5, "vi") == 0) mode = vi_mode; else mode = no_mode; _rl_parsing_conditionalized_out = mode != rl_editing_mode; }#endif /* VI_MODE */ /* Check to see if the first word in ARGS is the same as the value stored in rl_readline_name. */ else if (_rl_stricmp (args, rl_readline_name) == 0) _rl_parsing_conditionalized_out = 0; else _rl_parsing_conditionalized_out = 1; return 0;}/* Invert the current parser state if there is anything on the stack. */static intparser_else (args) char *args;{ register int i; if (if_stack_depth == 0) { _rl_init_file_error ("$else found without matching $if"); return 0; } /* Check the previous (n - 1) levels of the stack to make sure that we haven't previously turned off parsing. */ for (i = 0; i < if_stack_depth - 1; i++) if (if_stack[i] == 1) return 0; /* Invert the state of parsing if at top level. */ _rl_parsing_conditionalized_out = !_rl_parsing_conditionalized_out; return 0;}/* Terminate a conditional, popping the value of _rl_parsing_conditionalized_out from the stack. */static intparser_endif (args) char *args;{ if (if_stack_depth) _rl_parsing_conditionalized_out = if_stack[--if_stack_depth]; else _rl_init_file_error ("$endif without matching $if"); return 0;}static intparser_include (args) char *args;{ char *old_init_file, *e; int old_line_number, old_include_level, r; if (_rl_parsing_conditionalized_out) return (0); old_init_file = current_readline_init_file; old_line_number = current_readline_init_lineno; old_include_level = current_readline_init_include_level; e = strchr (args, '\n'); if (e) *e = '\0'; r = _rl_read_init_file (args, old_include_level + 1); current_readline_init_file = old_init_file; current_readline_init_lineno = old_line_number; current_readline_init_include_level = old_include_level; return r;} /* Associate textual names with actual functions. */static struct { char *name; Function *function;} parser_directives [] = { { "if", parser_if }, { "endif", parser_endif }, { "else", parser_else }, { "include", parser_include }, { (char *)0x0, (Function *)0x0 }};/* Handle a parser directive. STATEMENT is the line of the directive without any leading `$'. */static inthandle_parser_directive (statement) char *statement;{ register int i; char *directive, *args; /* Isolate the actual directive. */ /* Skip whitespace. */ for (i = 0; whitespace (statement[i]); i++); directive = &statement[i]; for (; statement[i] && !whitespace (statement[i]); i++); if (statement[i]) statement[i++] = '\0'; for (; statement[i] && whitespace (statement[i]); i++); args = &statement[i]; /* Lookup the command, and act on it. */ for (i = 0; parser_directives[i].name; i++) if (_rl_stricmp (directive, parser_directives[i].name) == 0) { (*parser_directives[i].function) (args); return (0); } /* display an error message about the unknown parser directive */ _rl_init_file_error ("unknown parser directive"); return (1);}/* Read the binding command from STRING and perform it. A key binding command looks like: Keyname: function-name\0, a variable binding command looks like: set variable value. A new-style keybinding looks like "\C-x\C-x": exchange-point-and-mark. */intrl_parse_and_bind (string) char *string;{ char *funname, *kname; register int c, i; int key, equivalency; while (string && whitespace (*string)) string++; if (!string || !*string || *string == '#') return 0; /* If this is a parser directive, act on it. */ if (*string == '$') { handle_parser_directive (&string[1]); return 0; } /* If we aren't supposed to be parsing right now, then we're done. */ if (_rl_parsing_conditionalized_out) return 0; i = 0; /* If this keyname is a complex key expression surrounded by quotes, advance to after the matching close quote. This code allows the backslash to quote characters in the key expression. */ if (*string == '"') { int passc = 0; for (i = 1; c = string[i]; i++) { if (passc) { passc = 0; continue; } if (c == '\\') { passc++; continue; } if (c == '"') break; } /* If we didn't find a closing quote, abort the line. */ if (string[i] == '\0') { _rl_init_file_error ("no closing `\"' in key binding"); return 1; } } /* Advance to the colon (:) or whitespace which separates the two objects. */ for (; (c = string[i]) && c != ':' && c != ' ' && c != '\t'; i++ ); equivalency = (c == ':' && string[i + 1] == '='); /* Mark the end of the command (or keyname). */ if (string[i]) string[i++] = '\0'; /* If doing assignment, skip the '=' sign as well. */ if (equivalency)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -