Created
July 15, 2011 01:28
-
-
Save johnbintz/1083859 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
+++ bind.c 2010-10-28 23:09:12.788260925 +0200 | |
@@ -1508,6 +1508,9 @@ | |
static int sv_histsize PARAMS((const char *)); | |
static int sv_isrchterm PARAMS((const char *)); | |
static int sv_keymap PARAMS((const char *)); | |
+static int sv_vi_insert_prompt PARAMS((const char *)); | |
+static int sv_vi_command_prompt PARAMS((const char *)); | |
+static int sv_vi_mode_changed_bin PARAMS((const char *)); | |
static const struct { | |
const char * const name; | |
@@ -1522,6 +1525,9 @@ | |
{ "history-size", V_INT, sv_histsize }, | |
{ "isearch-terminators", V_STRING, sv_isrchterm }, | |
{ "keymap", V_STRING, sv_keymap }, | |
+ { "vi-insert-prompt", V_STRING, sv_vi_insert_prompt }, | |
+ { "vi-command-prompt", V_STRING, sv_vi_command_prompt }, | |
+ { "vi-mode-changed-bin", V_STRING, sv_vi_mode_changed_bin }, | |
{ (char *)NULL, 0 } | |
}; | |
@@ -1694,6 +1700,30 @@ | |
} | |
static int | |
+sv_vi_insert_prompt (value) | |
+ const char *value; | |
+{ | |
+ _rl_set_vi_insert_prompt (value); | |
+ return 0; | |
+} | |
+ | |
+static int | |
+sv_vi_command_prompt (value) | |
+ const char *value; | |
+{ | |
+ _rl_set_vi_command_prompt (value); | |
+ return 0; | |
+} | |
+ | |
+static int | |
+sv_vi_mode_changed_bin (value) | |
+ const char *value; | |
+{ | |
+ _rl_set_vi_mode_changed_bin (value); | |
+ return 0; | |
+} | |
+ | |
+static int | |
sv_bell_style (value) | |
const char *value; | |
{ | |
+++ rlprivate.h 2010-10-28 23:09:45.788262324 +0200 | |
@@ -361,6 +361,9 @@ | |
extern int (_rl_digit_value) PARAMS((int)); | |
/* vi_mode.c */ | |
+extern void _rl_set_vi_insert_prompt PARAMS((const char *)); | |
+extern void _rl_set_vi_command_prompt PARAMS((const char *)); | |
+extern void _rl_set_vi_mode_changed_bin PARAMS((const char *)); | |
extern void _rl_vi_initialize_line PARAMS((void)); | |
extern void _rl_vi_reset_last PARAMS((void)); | |
extern void _rl_vi_set_last PARAMS((int, int, int)); | |
+++ vi_mode.c 2010-10-28 23:21:54.038261767 +0200 | |
@@ -49,6 +49,8 @@ | |
#include <stdio.h> | |
+#include <fcntl.h> | |
+ | |
/* Some standard library routines. */ | |
#include "rldefs.h" | |
#include "rlmbutil.h" | |
@@ -128,16 +130,121 @@ | |
static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *)); | |
#endif | |
+#define _RL_PROMPT_INITIAL_SIZE 256 | |
+#define _VI_MODE_PROMPT_FORMAT_SIZE 256 | |
+#define _VI_MODE_PROMPT_SIZE _RL_PROMPT_INITIAL_SIZE + _VI_MODE_PROMPT_FORMAT_SIZE | |
+static char _rl_prompt_initial[_RL_PROMPT_INITIAL_SIZE] = "\0"; | |
+static char *_rl_prompt_initial_last_line; | |
+static char _rl_vi_insert_prompt[_VI_MODE_PROMPT_FORMAT_SIZE] = "\0"; | |
+static char _rl_vi_command_prompt[_VI_MODE_PROMPT_FORMAT_SIZE] = "\0"; | |
+#define _VI_MODE_CHANGED_BIN_SIZE 256 | |
+static char _rl_vi_mode_changed_bin[_VI_MODE_CHANGED_BIN_SIZE] = "\0"; | |
+ | |
+void _rl_set_vi_insert_prompt PARAMS((const char *)); | |
+void _rl_set_vi_command_prompt PARAMS((const char *)); | |
+void _rl_set_vi_mode_changed_bin PARAMS((const char *)); | |
+ | |
+static void vi_mode_changed_prompt PARAMS((void)); | |
+static void vi_mode_changed_bin PARAMS((void)); | |
+static void vi_mode_changed PARAMS((void)); | |
+ | |
+static char * | |
+safe_strncpy (dest, src, n) | |
+ char *dest; | |
+ const char *src; | |
+ int n; | |
+{ | |
+ if (src) { | |
+ strncpy (dest, src, n); | |
+ dest[n - 1] = '\0'; | |
+ } | |
+ else { | |
+ dest[0] = '\0'; | |
+ } | |
+ return dest; | |
+} | |
+ | |
+static char * | |
+parse_prompt_format_escapes (src) | |
+ char *src; | |
+{ | |
+ char *r, *w, c, o; | |
+ static char buf[4] = "000"; | |
+ | |
+ r = src; | |
+ w = r; | |
+ while (*r) { | |
+ c = *r; | |
+ if (c == '\\') { | |
+ r++; | |
+ if (*r == '\\') { | |
+ c = '\\'; | |
+ } | |
+ else if (*r == '0') { | |
+ c = *r; | |
+ buf[1] = *(r + 1); | |
+ buf[2] = *(r + 2); | |
+ o = strtol (buf, NULL, 8); | |
+ if (o > 0) { | |
+ r += 2; | |
+ c = o; | |
+ } | |
+ } | |
+ } | |
+ r++; | |
+ if (c > 0) { | |
+ *w = c; | |
+ w++; | |
+ } | |
+ } | |
+ *w = '\0'; | |
+ return src; | |
+} | |
+ | |
+void | |
+_rl_set_vi_insert_prompt (value) | |
+ const char *value; | |
+{ | |
+ safe_strncpy (_rl_vi_insert_prompt, value, _VI_MODE_PROMPT_FORMAT_SIZE); | |
+ parse_prompt_format_escapes (_rl_vi_insert_prompt); | |
+} | |
+ | |
+void | |
+_rl_set_vi_command_prompt (value) | |
+ const char *value; | |
+{ | |
+ safe_strncpy (_rl_vi_command_prompt, value, _VI_MODE_PROMPT_FORMAT_SIZE); | |
+ parse_prompt_format_escapes (_rl_vi_command_prompt); | |
+} | |
+ | |
+void | |
+_rl_set_vi_mode_changed_bin (value) | |
+ const char *value; | |
+{ | |
+ safe_strncpy (_rl_vi_mode_changed_bin, value, _VI_MODE_CHANGED_BIN_SIZE); | |
+} | |
+ | |
void | |
_rl_vi_initialize_line () | |
{ | |
register int i, n; | |
+ char *p; | |
n = sizeof (vi_mark_chars) / sizeof (vi_mark_chars[0]); | |
for (i = 0; i < n; i++) | |
vi_mark_chars[i] = -1; | |
RL_UNSETSTATE(RL_STATE_VICMDONCE); | |
+ | |
+ safe_strncpy (_rl_prompt_initial, rl_prompt, _RL_PROMPT_INITIAL_SIZE); | |
+ p = strrchr (_rl_prompt_initial, '\n'); | |
+ if (p) { | |
+ p++; | |
+ } | |
+ else { | |
+ p = _rl_prompt_initial; | |
+ } | |
+ _rl_prompt_initial_last_line = p; | |
} | |
void | |
@@ -655,6 +762,86 @@ | |
/* Insertion mode stuff. */ | |
+/* This is meant to be called after vi mode changes. */ | |
+static void | |
+vi_mode_changed_prompt () | |
+{ | |
+ char *prompt, *p; | |
+ char pattern[] = "{}"; | |
+ static char buf[_VI_MODE_PROMPT_SIZE]; | |
+ int i, j; | |
+ | |
+ if (VI_INSERT_MODE()) { | |
+ prompt = _rl_vi_insert_prompt; | |
+ } | |
+ else if (VI_COMMAND_MODE()) { | |
+ prompt = _rl_vi_command_prompt; | |
+ } | |
+ if (strlen (prompt)) { | |
+ i = _rl_prompt_initial_last_line - _rl_prompt_initial; | |
+ memcpy (buf, _rl_prompt_initial, i); | |
+ buf[i] = '\0'; | |
+ p = strstr (prompt, pattern); | |
+ if (p) { | |
+ j = p - prompt; | |
+ memcpy (buf + i, prompt, j); | |
+ buf[i + j] = '\0'; | |
+ strcat (buf, _rl_prompt_initial_last_line); | |
+ strcat (buf, p + strlen (pattern)); | |
+ } | |
+ else { | |
+ strcat (buf, prompt); | |
+ } | |
+ prompt = buf; | |
+ } | |
+ else { | |
+ prompt = _rl_prompt_initial; | |
+ } | |
+ rl_set_prompt (prompt); | |
+ _rl_redisplay_after_sigwinch (); | |
+} | |
+ | |
+static void | |
+vi_mode_changed_bin () | |
+{ | |
+ pid_t pid; | |
+ int status, fd_devnull; | |
+ char *bin = _rl_vi_mode_changed_bin; | |
+ | |
+ if (!strlen (bin)) { | |
+ return; | |
+ } | |
+ pid = fork (); | |
+ if (pid < 0) { | |
+ perror ("vi_mode_changed_bin: fork failed"); | |
+ return; | |
+ } | |
+ else if (pid == 0) { | |
+ close (STDIN_FILENO); | |
+ fd_devnull = open ("/dev/null", O_RDONLY); | |
+ dup2 (fd_devnull, STDIN_FILENO); | |
+ if (VI_INSERT_MODE()) { | |
+ execl (bin, bin, "insert", NULL); | |
+ } | |
+ else if (VI_COMMAND_MODE()) { | |
+ execl (bin, bin, "command", NULL); | |
+ } | |
+ perror ("vi_mode_changed_bin: execv failed"); | |
+ exit (1); | |
+ } | |
+ waitpid (pid, &status, 0); | |
+} | |
+ | |
+static void | |
+vi_mode_changed () | |
+{ | |
+ if (!isatty (STDIN_FILENO) || !isatty (STDOUT_FILENO)) { | |
+ return; | |
+ } | |
+ vi_mode_changed_prompt (); | |
+ vi_mode_changed_bin (); | |
+} | |
+ | |
/* Switching from one mode to the other really just involves | |
switching keymaps. */ | |
int | |
@@ -663,6 +850,9 @@ | |
{ | |
_rl_keymap = vi_insertion_keymap; | |
_rl_vi_last_key_before_insert = key; | |
+ | |
+ vi_mode_changed (); | |
+ | |
return (0); | |
} | |
@@ -747,6 +937,9 @@ | |
rl_free_undo_list (); | |
RL_SETSTATE (RL_STATE_VICMDONCE); | |
+ | |
+ vi_mode_changed (); | |
+ | |
return (0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment