summaryrefslogtreecommitdiffstats
path: root/src/ex_getln.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-02-22 08:49:11 +0000
committerBram Moolenaar <Bram@vim.org>2005-02-22 08:49:11 +0000
commit26a60b45245080771bc2452b2634cb1f5acd60ed (patch)
tree82a54fd6544b2c2a57b5c52cb4d64c42dcd640a3 /src/ex_getln.c
parentdf177f679e950a2ab2ad5fe7d45c1daface004d7 (diff)
updated for version 7.0051
Diffstat (limited to 'src/ex_getln.c')
-rw-r--r--src/ex_getln.c359
1 files changed, 179 insertions, 180 deletions
diff --git a/src/ex_getln.c b/src/ex_getln.c
index 05c85b49fd..4c9d17d78f 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -681,16 +681,29 @@ getcmdline(firstc, count, indent)
if (c == '\n' || c == '\r' || c == K_KENTER || (c == ESC
&& (!KeyTyped || vim_strchr(p_cpo, CPO_ESC) != NULL)))
{
- gotesc = FALSE; /* Might have typed ESC previously, don't
- truncate the cmdline now. */
- if (ccheck_abbr(c + ABBR_OFF))
- goto cmdline_changed;
- if (!cmd_silent)
+ /* In Ex mode a backslash escapes a newline. */
+ if (exmode_active
+ && c != ESC
+ && ccline.cmdpos > 0
+ && ccline.cmdpos == ccline.cmdlen
+ && ccline.cmdbuff[ccline.cmdpos - 1] == '\\')
{
- windgoto(msg_row, 0);
- out_flush();
+ if (c == K_KENTER)
+ c = '\n';
+ }
+ else
+ {
+ gotesc = FALSE; /* Might have typed ESC previously, don't
+ truncate the cmdline now. */
+ if (ccheck_abbr(c + ABBR_OFF))
+ goto cmdline_changed;
+ if (!cmd_silent)
+ {
+ windgoto(msg_row, 0);
+ out_flush();
+ }
+ break;
}
- break;
}
/*
@@ -1879,25 +1892,24 @@ getexline(c, dummy, indent)
* Get an Ex command line for Ex mode.
* In Ex mode we only use the OS supplied line editing features and no
* mappings or abbreviations.
+ * Returns a string in allocated memory or NULL.
*/
/* ARGSUSED */
char_u *
-getexmodeline(c, dummy, indent)
- int c; /* normally ':', NUL for ":append" */
+getexmodeline(promptc, dummy, indent)
+ int promptc; /* normally ':', NUL for ":append" and '?' for
+ :s prompt */
void *dummy; /* cookie not used */
int indent; /* indent for inside conditionals */
{
- garray_T line_ga;
- int len;
- int off = 0;
- char_u *pend;
- int finished = FALSE;
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
- int startcol = 0;
- int c1;
- int escaped = FALSE; /* CTRL-V typed */
- int vcol = 0;
-#endif
+ garray_T line_ga;
+ char_u *pend;
+ int startcol = 0;
+ int c1;
+ int escaped = FALSE; /* CTRL-V typed */
+ int vcol = 0;
+ char_u *p;
+ int prev_char = 0;
/* Switch cursor on now. This avoids that it happens after the "\n", which
* confuses the system function that computes tabstops. */
@@ -1905,27 +1917,24 @@ getexmodeline(c, dummy, indent)
/* always start in column 0; write a newline if necessary */
compute_cmdrow();
- if (msg_col)
+ if ((msg_col || msg_didout) && promptc != '?')
msg_putchar('\n');
- if (c == ':')
+ if (promptc == ':')
{
/* indent that is only displayed, not in the line itself */
- msg_putchar(':');
+ if (p_prompt)
+ msg_putchar(':');
while (indent-- > 0)
msg_putchar(' ');
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
startcol = msg_col;
-#endif
}
ga_init2(&line_ga, 1, 30);
/* autoindent for :insert and :append is in the line itself */
- if (c <= 0)
+ if (promptc <= 0)
{
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
vcol = indent;
-#endif
while (indent >= 8)
{
ga_append(&line_ga, TAB);
@@ -1938,198 +1947,180 @@ getexmodeline(c, dummy, indent)
msg_putchar(' ');
}
}
+ ++no_mapping;
+ ++allow_keys;
/*
* Get the line, one character at a time.
*/
got_int = FALSE;
- while (!got_int && !finished)
+ while (!got_int)
{
if (ga_grow(&line_ga, 40) == FAIL)
break;
pend = (char_u *)line_ga.ga_data + line_ga.ga_len;
- /* Get one character (inchar gets a third of maxlen characters!) */
- len = inchar(pend + off, 3, -1L, 0);
- if (len < 0)
- continue; /* end of input script reached */
- /* for a special character, we need at least three characters */
- if ((*pend == K_SPECIAL || *pend == CSI) && off + len < 3)
- {
- off += len;
- continue;
- }
- len += off;
- off = 0;
+ /* Get one character at a time. Don't use inchar(), it can't handle
+ * special characters. */
+ c1 = vgetc();
/*
- * When using the GUI, and for systems that don't have cooked input,
- * handle line editing here.
+ * Handle line editing.
+ * Previously this was left to the system, putting the terminal in
+ * cooked mode, but then CTRL-D and CTRL-T can't be used properly.
*/
-#if defined(FEAT_GUI) || defined(NO_COOKED_INPUT)
-# ifndef NO_COOKED_INPUT
- if (gui.in_use)
-# endif
+ if (got_int)
{
- if (got_int)
- {
- msg_putchar('\n');
- break;
- }
+ msg_putchar('\n');
+ break;
+ }
- while (len > 0)
+ if (!escaped)
+ {
+ /* CR typed means "enter", which is NL */
+ if (c1 == '\r')
+ c1 = '\n';
+
+ if (c1 == BS || c1 == K_BS
+ || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
{
- c1 = *pend++;
- --len;
- if ((c1 == K_SPECIAL
-# if !defined(NO_COOKED_INPUT) || defined(FEAT_GUI)
- || c1 == CSI
-# endif
- ) && len >= 2)
+ if (line_ga.ga_len > 0)
{
- c1 = TO_SPECIAL(pend[0], pend[1]);
- pend += 2;
- len -= 2;
+ --line_ga.ga_len;
+ goto redraw;
}
+ continue;
+ }
- if (!escaped)
- {
- /* CR typed means "enter", which is NL */
- if (c1 == '\r')
- c1 = '\n';
-
- if (c1 == BS || c1 == K_BS
- || c1 == DEL || c1 == K_DEL || c1 == K_KDEL)
- {
- if (line_ga.ga_len > 0)
- {
- int i, v;
- char_u *q;
-
- --line_ga.ga_len;
- /* compute column that cursor should be in */
- v = 0;
- q = ((char_u *)line_ga.ga_data);
- for (i = 0; i < line_ga.ga_len; ++i)
- {
- if (*q == TAB)
- v += 8 - v % 8;
- else
- v += ptr2cells(q);
- ++q;
- }
- /* erase characters to position cursor */
- while (vcol > v)
- {
- msg_putchar('\b');
- msg_putchar(' ');
- msg_putchar('\b');
- --vcol;
- }
- }
- continue;
- }
-
- if (c1 == Ctrl_U)
- {
- msg_col = startcol;
- msg_clr_eos();
- line_ga.ga_len = 0;
- continue;
- }
+ if (c1 == Ctrl_U)
+ {
+ msg_col = startcol;
+ msg_clr_eos();
+ line_ga.ga_len = 0;
+ continue;
+ }
- if (c1 == Ctrl_T)
- c1 = TAB; /* very simplistic... */
+ if (c1 == Ctrl_T)
+ {
+ p = (char_u *)line_ga.ga_data;
+ p[line_ga.ga_len] = NUL;
+ indent = get_indent_str(p, 8);
+ indent += curbuf->b_p_sw - indent % curbuf->b_p_sw;
+add_indent:
+ while (get_indent_str(p, 8) < indent)
+ {
+ char_u *s = skipwhite(p);
- if (c1 == Ctrl_D)
+ ga_grow(&line_ga, 1);
+ mch_memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
+ *s = ' ';
+ ++line_ga.ga_len;
+ }
+redraw:
+ /* redraw the line */
+ msg_col = startcol;
+ windgoto(msg_row, msg_col);
+ vcol = 0;
+ for (p = (char_u *)line_ga.ga_data;
+ p < (char_u *)line_ga.ga_data + line_ga.ga_len; ++p)
+ {
+ if (*p == TAB)
{
- char_u *p;
-
- /* Delete one shiftwidth. */
- p = (char_u *)line_ga.ga_data;
- p[line_ga.ga_len] = NUL;
- indent = get_indent_str(p, 8);
- --indent;
- indent -= indent % 8;
- while (get_indent_str(p, 8) > indent)
- {
- char_u *s = skipwhite(p);
-
- mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
- --line_ga.ga_len;
- }
- msg_col = startcol;
- for (vcol = 0; *p != NUL; ++p)
+ do
{
- if (*p == TAB)
- {
- do
- {
- msg_putchar(' ');
- } while (++vcol % 8);
- }
- else
- {
- msg_outtrans_len(p, 1);
- vcol += char2cells(*p);
- }
- }
- msg_clr_eos();
- continue;
+ msg_putchar(' ');
+ } while (++vcol % 8);
}
-
- if (c1 == Ctrl_V)
+ else
{
- escaped = TRUE;
- continue;
+ msg_outtrans_len(p, 1);
+ vcol += char2cells(*p);
}
}
+ msg_clr_eos();
+ continue;
+ }
- if (IS_SPECIAL(c1))
- c1 = '?';
- ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
- if (c1 == '\n')
- msg_putchar('\n');
- else if (c1 == TAB)
+ if (c1 == Ctrl_D)
+ {
+ /* Delete one shiftwidth. */
+ p = (char_u *)line_ga.ga_data;
+ if (prev_char == '0' || prev_char == '^')
{
- /* Don't use chartabsize(), 'ts' can be different */
- do
- {
- msg_putchar(' ');
- } while (++vcol % 8);
+ if (prev_char == '^')
+ ex_keep_indent = TRUE;
+ indent = 0;
+ p[--line_ga.ga_len] = NUL;
}
else
{
- msg_outtrans_len(
- ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
- vcol += char2cells(c1);
+ p[line_ga.ga_len] = NUL;
+ indent = get_indent_str(p, 8);
+ --indent;
+ indent -= indent % curbuf->b_p_sw;
+ }
+ while (get_indent_str(p, 8) > indent)
+ {
+ char_u *s = skipwhite(p);
+
+ mch_memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
+ --line_ga.ga_len;
}
- ++line_ga.ga_len;
- escaped = FALSE;
+ goto add_indent;
+ }
+
+ if (c1 == Ctrl_V || c1 == Ctrl_Q)
+ {
+ escaped = TRUE;
+ continue;
}
- windgoto(msg_row, msg_col);
+
+ /* Ignore special key codes: mouse movement, K_IGNORE, etc. */
+ if (IS_SPECIAL(c1))
+ continue;
+ }
+
+ if (IS_SPECIAL(c1))
+ c1 = '?';
+ ((char_u *)line_ga.ga_data)[line_ga.ga_len] = c1;
+ prev_char = c1;
+ if (c1 == '\n')
+ msg_putchar('\n');
+ else if (c1 == TAB)
+ {
+ /* Don't use chartabsize(), 'ts' can be different */
+ do
+ {
+ msg_putchar(' ');
+ } while (++vcol % 8);
}
-# ifndef NO_COOKED_INPUT
else
-# endif
-#endif
-#ifndef NO_COOKED_INPUT
{
- line_ga.ga_len += len;
+ msg_outtrans_len(
+ ((char_u *)line_ga.ga_data) + line_ga.ga_len, 1);
+ vcol += char2cells(c1);
}
-#endif
+ ++line_ga.ga_len;
+ escaped = FALSE;
+
+ windgoto(msg_row, msg_col);
pend = (char_u *)(line_ga.ga_data) + line_ga.ga_len;
- if (line_ga.ga_len && pend[-1] == '\n')
+
+ /* we are done when a NL is entered, but not when it comes after a
+ * backslash */
+ if (line_ga.ga_len > 0 && pend[-1] == '\n'
+ && (line_ga.ga_len <= 1 || pend[-2] != '\\'))
{
- finished = TRUE;
--line_ga.ga_len;
--pend;
*pend = NUL;
+ break;
}
}
- /* note that cursor has moved, because of the echoed <CR> */
- screen_down();
+ --no_mapping;
+ --allow_keys;
+
/* make following messages go to the next line */
msg_didout = FALSE;
msg_col = 0;
@@ -3797,10 +3788,10 @@ addstar(fname, len, context)
set_expand_context(xp)
expand_T *xp;
{
- /* only expansion for ':' and '>' commands */
+ /* only expansion for ':', '>' and '=' command-lines */
if (ccline.cmdfirstc != ':'
#ifdef FEAT_EVAL
- && ccline.cmdfirstc != '>'
+ && ccline.cmdfirstc != '>' && ccline.cmdfirstc != '='
#endif
)
{
@@ -3828,8 +3819,16 @@ set_cmd_context(xp, str, len, col)
old_char = str[col];
str[col] = NUL;
nextcomm = str;
- while (nextcomm != NULL)
- nextcomm = set_one_cmd_context(xp, nextcomm);
+
+#ifdef FEAT_EVAL
+ if (ccline.cmdfirstc == '=')
+ /* pass CMD_SIZE because there is no real command */
+ set_context_for_expression(xp, str, CMD_SIZE);
+ else
+#endif
+ while (nextcomm != NULL)
+ nextcomm = set_one_cmd_context(xp, nextcomm);
+
str[col] = old_char;
}
@@ -5477,7 +5476,7 @@ ex_window()
* Call the main loop until <CR> or CTRL-C is typed.
*/
cmdwin_result = 0;
- main_loop(TRUE);
+ main_loop(TRUE, FALSE);
RedrawingDisabled = i;