+ vi_mode = viflag;
+}
+
+static void
+vi_Word_motion(char *command, int eat)
+{
+ while (cursor < len && !isspace(command[cursor]))
+ input_forward();
+ if (eat) while (cursor < len && isspace(command[cursor]))
+ input_forward();
+}
+
+static void
+vi_word_motion(char *command, int eat)
+{
+ if (isalnum(command[cursor]) || command[cursor] == '_') {
+ while (cursor < len
+ && (isalnum(command[cursor+1]) || command[cursor+1] == '_'))
+ input_forward();
+ } else if (ispunct(command[cursor])) {
+ while (cursor < len && ispunct(command[cursor+1]))
+ input_forward();
+ }
+
+ if (cursor < len)
+ input_forward();
+
+ if (eat && cursor < len && isspace(command[cursor]))
+ while (cursor < len && isspace(command[cursor]))
+ input_forward();
+}
+
+static void
+vi_End_motion(char *command)
+{
+ input_forward();
+ while (cursor < len && isspace(command[cursor]))
+ input_forward();
+ while (cursor < len-1 && !isspace(command[cursor+1]))
+ input_forward();
+}
+
+static void
+vi_end_motion(char *command)
+{
+ if (cursor >= len-1)
+ return;
+ input_forward();
+ while (cursor < len-1 && isspace(command[cursor]))
+ input_forward();
+ if (cursor >= len-1)
+ return;
+ if (isalnum(command[cursor]) || command[cursor] == '_') {
+ while (cursor < len-1
+ && (isalnum(command[cursor+1]) || command[cursor+1] == '_')
+ ) {
+ input_forward();
+ }
+ } else if (ispunct(command[cursor])) {
+ while (cursor < len-1 && ispunct(command[cursor+1]))
+ input_forward();
+ }
+}
+
+static void
+vi_Back_motion(char *command)
+{
+ while (cursor > 0 && isspace(command[cursor-1]))
+ input_backward(1);
+ while (cursor > 0 && !isspace(command[cursor-1]))
+ input_backward(1);
+}
+
+static void
+vi_back_motion(char *command)
+{
+ if (cursor <= 0)
+ return;
+ input_backward(1);
+ while (cursor > 0 && isspace(command[cursor]))
+ input_backward(1);
+ if (cursor <= 0)
+ return;
+ if (isalnum(command[cursor]) || command[cursor] == '_') {
+ while (cursor > 0
+ && (isalnum(command[cursor-1]) || command[cursor-1] == '_')
+ ) {
+ input_backward(1);
+ }
+ } else if (ispunct(command[cursor])) {
+ while (cursor > 0 && ispunct(command[cursor-1]))
+ input_backward(1);
+ }
+}
+#endif
+
+/*
+ * the emacs and vi modes share much of the code in the big
+ * command loop. commands entered when in vi's command mode (aka
+ * "escape mode") get an extra bit added to distinguish them --
+ * this keeps them from being self-inserted. this clutters the
+ * big switch a bit, but keeps all the code in one place.
+ */
+
+#define vbit 0x100
+
+/* leave out the "vi-mode"-only case labels if vi editing isn't
+ * configured. */
+#define vi_case(caselabel) USE_FEATURE_COMMAND_EDITING(caselabel)
+
+/* convert uppercase ascii to equivalent control char, for readability */
+#define CNTRL(uc_char) ((uc_char) - 0x40)