summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-07-27 21:13:01 +0000
committerBram Moolenaar <Bram@vim.org>2005-07-27 21:13:01 +0000
commit87e25fdf80c7b45deee9c59389b51503e906d93b (patch)
treee477f86746245499e324e1d1e9ccada6aed035e9 /src
parent231334e6efbf3a7f89183f8257e09492534a5f8c (diff)
downloadvim-git-87e25fdf80c7b45deee9c59389b51503e906d93b.tar.gz
updated for version 7.0117v7.0117
Diffstat (limited to 'src')
-rw-r--r--src/Make_ivc.mak4
-rw-r--r--src/Makefile18
-rw-r--r--src/buffer.c1
-rw-r--r--src/eval.c80
-rw-r--r--src/ex_cmds.h4
-rw-r--r--src/ex_docmd.c1
-rw-r--r--src/globals.h2
-rw-r--r--src/gui.c1
-rw-r--r--src/main.aap19
-rw-r--r--src/main.c1
-rw-r--r--src/message.c843
-rw-r--r--src/ops.c11
-rw-r--r--src/proto/eval.pro2
-rw-r--r--src/proto/message.pro1
-rw-r--r--src/proto/quickfix.pro1
-rw-r--r--src/proto/screen.pro1
-rw-r--r--src/quickfix.c217
-rw-r--r--src/screen.c3
-rw-r--r--src/tag.c5
-rw-r--r--src/version.h4
20 files changed, 845 insertions, 374 deletions
diff --git a/src/Make_ivc.mak b/src/Make_ivc.mak
index 44f58fb94..2326c3086 100644
--- a/src/Make_ivc.mak
+++ b/src/Make_ivc.mak
@@ -88,8 +88,8 @@ LINK32=link.exe
CPP_PROJ= /nologo /MT /W3 /GX /I ".\proto" /D "WIN32" /c
# ADD CPP /nologo /MT /W3 /GX /I ".\proto" /D "WIN32" /c
-LINK32_FLAGS= oldnames.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib uuid.lib /nologo /machine:I386 /nodefaultlib
-# ADD LINK32 oldnames.lib kernel32.lib user32.lib gdi32.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib uuid.lib /nologo /machine:I386 /nodefaultlib
+LINK32_FLAGS= oldnames.lib kernel32.lib user32.lib gdi32.lib version.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib uuid.lib /nologo /machine:I386 /nodefaultlib
+# ADD LINK32 oldnames.lib kernel32.lib user32.lib gdi32.lib version.lib comdlg32.lib comctl32.lib advapi32.lib shell32.lib ole32.lib uuid.lib /nologo /machine:I386 /nodefaultlib
# SUBTRACT LINK32 /incremental:yes
RSC_PROJ= /l 0x409 /d "FEAT_GUI_W32"
diff --git a/src/Makefile b/src/Makefile
index 83732a28a..2a74f4ed7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -879,6 +879,7 @@ HELPSUBDIR = /doc
COLSUBDIR = /colors
SYNSUBDIR = /syntax
INDSUBDIR = /indent
+AUTOSUBDIR = /autoload
PLUGSUBDIR = /plugin
FTPLUGSUBDIR = /ftplugin
LANGSUBDIR = /lang
@@ -899,6 +900,7 @@ PODIR = po
### COLSUBLOC location for colorscheme files
### SYNSUBLOC location for syntax files
### INDSUBLOC location for indent files
+### AUTOSUBLOC location for standard autoload files
### PLUGSUBLOC location for standard plugin files
### FTPLUGSUBLOC location for ftplugin files
### LANGSUBLOC location for language files
@@ -919,6 +921,7 @@ HELPSUBLOC = $(VIMRTLOC)$(HELPSUBDIR)
COLSUBLOC = $(VIMRTLOC)$(COLSUBDIR)
SYNSUBLOC = $(VIMRTLOC)$(SYNSUBDIR)
INDSUBLOC = $(VIMRTLOC)$(INDSUBDIR)
+AUTOSUBLOC = $(VIMRTLOC)$(AUTOSUBDIR)
PLUGSUBLOC = $(VIMRTLOC)$(PLUGSUBDIR)
FTPLUGSUBLOC = $(VIMRTLOC)$(FTPLUGSUBDIR)
LANGSUBLOC = $(VIMRTLOC)$(LANGSUBDIR)
@@ -1018,6 +1021,9 @@ SYNSOURCE = ../runtime/syntax
INDSOURCE = ../runtime/indent
# Where to copy the standard plugin files from
+AUTOSOURCE = ../runtime/autoload
+
+# Where to copy the standard plugin files from
PLUGSOURCE = ../runtime/plugin
# Where to copy the ftplugin files from
@@ -1290,6 +1296,7 @@ DEST_HELP = $(DESTDIR)$(HELPSUBLOC)
DEST_COL = $(DESTDIR)$(COLSUBLOC)
DEST_SYN = $(DESTDIR)$(SYNSUBLOC)
DEST_IND = $(DESTDIR)$(INDSUBLOC)
+DEST_AUTO = $(DESTDIR)$(AUTOSUBLOC)
DEST_PLUG = $(DESTDIR)$(PLUGSUBLOC)
DEST_FTP = $(DESTDIR)$(FTPLUGSUBLOC)
DEST_LANG = $(DESTDIR)$(LANGSUBLOC)
@@ -1739,7 +1746,8 @@ INSTALLMANARGS = $(VIMLOC) $(SCRIPTLOC) $(VIMRCLOC) $(HELPSOURCE) $(MANMOD) \
# install the help files; first adjust the contents for the final location
installruntime: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \
$(DEST_HELP) $(DEST_PRINT) $(DEST_COL) $(DEST_SYN) $(DEST_IND) \
- $(DEST_FTP) $(DEST_PLUG) $(DEST_TUTOR) $(DEST_SPELL) $(DEST_COMP)
+ $(DEST_FTP) $(DEST_AUTO) $(DEST_PLUG) $(DEST_TUTOR) \
+ $(DEST_SPELL) $(DEST_COMP)
-$(SHELL) ./installman.sh install $(DEST_MAN) "" $(INSTALLMANARGS)
@echo generating help tags
# Generate the help tags with ":helptags" to handle all languages.
@@ -1801,6 +1809,9 @@ installruntime: $(HELPSOURCE)/vim.1 $(DEST_VIM) $(DEST_RT) \
# install the indent files
cd $(INDSOURCE); $(INSTALL_DATA) *.vim README.txt $(DEST_IND)
cd $(DEST_IND); chmod $(HELPMOD) *.vim README.txt
+# install the standard autoload files
+ cd $(AUTOSOURCE); $(INSTALL_DATA) *.vim README.txt $(DEST_AUTO)
+ cd $(DEST_AUTO); chmod $(HELPMOD) *.vim README.txt
# install the standard plugin files
cd $(PLUGSOURCE); $(INSTALL_DATA) *.vim README.txt $(DEST_PLUG)
cd $(DEST_PLUG); chmod $(HELPMOD) *.vim README.txt
@@ -1965,7 +1976,7 @@ $(DESTDIR)$(exec_prefix) $(DEST_BIN) \
$(DEST_PRINT) $(DEST_COL) $(DEST_SYN) $(DEST_IND) $(DEST_FTP) \
$(DEST_LANG) $(DEST_KMAP) $(DEST_COMP) \
$(DEST_MACRO) $(DEST_TOOLS) $(DEST_TUTOR) $(DEST_SPELL) \
- $(DEST_PLUG):
+ $(DEST_AUTO) $(DEST_PLUG):
-$(SHELL) ./mkinstalldirs $@
-chmod $(DIRMOD) $@
@@ -2103,8 +2114,9 @@ uninstall_runtime:
-rm -f $(DEST_PRINT)/*.ps
-rmdir $(DEST_HELP) $(DEST_PRINT) $(DEST_COL) $(DEST_SYN) $(DEST_IND)
-rm -rf $(DEST_FTP)/*.vim $(DEST_FTP)/README.txt
+ -rm -f $(DEST_AUTO)/*.vim $(DEST_AUTO)/README.txt
-rm -f $(DEST_PLUG)/*.vim $(DEST_PLUG)/README.txt
- -rmdir $(DEST_FTP) $(DEST_PLUG) $(DEST_RT)
+ -rmdir $(DEST_FTP) $(DEST_AUTO) $(DEST_PLUG) $(DEST_RT)
# This will fail when other Vim versions are installed, no worries.
-rmdir $(DEST_VIM)
diff --git a/src/buffer.c b/src/buffer.c
index 07e9723a0..09ca27db8 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -25,7 +25,6 @@
* The current implementation remembers all file names ever used.
*/
-
#include "vim.h"
#if defined(FEAT_CMDL_COMPL) || defined(FEAT_LISTCMDS) || defined(FEAT_EVAL) || defined(FEAT_PERL)
diff --git a/src/eval.c b/src/eval.c
index f18a3a95b..f2cc2a0b7 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -639,7 +639,6 @@ static int handle_subscript __ARGS((char_u **arg, typval_T *rettv, int evaluate,
static typval_T *alloc_tv __ARGS((void));
static typval_T *alloc_string_tv __ARGS((char_u *string));
static void free_tv __ARGS((typval_T *varp));
-static void clear_tv __ARGS((typval_T *varp));
static void init_tv __ARGS((typval_T *varp));
static long get_tv_number __ARGS((typval_T *varp));
static long get_tv_number_chk __ARGS((typval_T *varp, int *denote));
@@ -683,7 +682,7 @@ static int
# endif
prof_self_cmp __ARGS((const void *s1, const void *s2));
#endif
-static int script_autoload __ARGS((char_u *name));
+static int script_autoload __ARGS((char_u *name, int reload));
static char_u *autoload_name __ARGS((char_u *name));
static void cat_func_name __ARGS((char_u *buf, ufunc_T *fp));
static void func_free __ARGS((ufunc_T *fp));
@@ -1308,6 +1307,30 @@ get_spellword(list, pp)
}
#endif
+/*
+ * Top level evaluation function,
+ */
+ typval_T *
+eval_expr(arg, nextcmd)
+ char_u *arg;
+ char_u **nextcmd;
+{
+ typval_T *tv;
+
+ tv = (typval_T *)alloc(sizeof(typval_T));
+ if (!tv)
+ return NULL;
+
+ if (eval0(arg, tv, nextcmd, TRUE) == FAIL)
+ {
+ vim_free(tv);
+ return NULL;
+ }
+
+ return tv;
+}
+
+
#if (defined(FEAT_USR_CMDS) && defined(FEAT_CMDL_COMPL)) || defined(PROTO)
/*
* Call some vimL function and return the result in "*rettv".
@@ -7101,7 +7124,7 @@ call_func(name, len, rettv, argcount, argvars, firstline, lastline,
}
#endif
/* Try loading a package. */
- if (fp == NULL && script_autoload(fname) && !aborting())
+ if (fp == NULL && script_autoload(fname, TRUE) && !aborting())
{
/* loaded a package, search for the function again */
fp = find_func(fname);
@@ -15528,7 +15551,7 @@ free_tv(varp)
/*
* Free the memory for a variable value and set the value to NULL or 0.
*/
- static void
+ void
clear_tv(varp)
typval_T *varp;
{
@@ -15774,9 +15797,11 @@ find_var_in_ht(ht, varname, writing)
if (HASHITEM_EMPTY(hi))
{
/* For global variables we may try auto-loading the script. If it
- * worked find the variable again. */
+ * worked find the variable again. Don't auto-load a script if it was
+ * loaded already, otherwise it would be loaded every time when
+ * checking if a function name is a Funcref variable. */
if (ht == &globvarht && !writing
- && script_autoload(varname) && !aborting())
+ && script_autoload(varname, FALSE) && !aborting())
hi = hash_find(ht, varname);
if (HASHITEM_EMPTY(hi))
return NULL;
@@ -17566,29 +17591,52 @@ prof_self_cmp(s1, s2)
#endif
+/* The names of packages that once were loaded is remembered. */
+static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL};
+
/*
* If "name" has a package name try autoloading the script for it.
* Return TRUE if a package was loaded.
*/
static int
-script_autoload(name)
- char_u *name;
+script_autoload(name, reload)
+ char_u *name;
+ int reload; /* load script again when already loaded */
{
char_u *p;
- char_u *scriptname;
+ char_u *scriptname, *tofree;
int ret = FALSE;
+ int i;
- /* If there is no colon after name[1] there is no package name. */
+ /* If there is no '#' after name[0] there is no package name. */
p = vim_strchr(name, AUTOLOAD_CHAR);
- if (p == NULL || p <= name + 2)
+ if (p == NULL || p == name)
return FALSE;
- /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
- scriptname = autoload_name(name);
- if (cmd_runtime(scriptname, FALSE) == OK)
- ret = TRUE;
+ tofree = scriptname = autoload_name(name);
+
+ /* Find the name in the list of previously loaded package names. Skip
+ * "autoload/", it's always the same. */
+ for (i = 0; i < ga_loaded.ga_len; ++i)
+ if (STRCMP(((char_u **)ga_loaded.ga_data)[i] + 9, scriptname + 9) == 0)
+ break;
+ if (!reload && i < ga_loaded.ga_len)
+ ret = FALSE; /* was loaded already */
+ else
+ {
+ /* Remember the name if it wasn't loaded already. */
+ if (i == ga_loaded.ga_len && ga_grow(&ga_loaded, 1) == OK)
+ {
+ ((char_u **)ga_loaded.ga_data)[ga_loaded.ga_len++] = scriptname;
+ tofree = NULL;
+ }
+
+ /* Try loading the package from $VIMRUNTIME/autoload/<name>.vim */
+ if (cmd_runtime(scriptname, FALSE) == OK)
+ ret = TRUE;
+ }
- vim_free(scriptname);
+ vim_free(tofree);
return ret;
}
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index 51053c9b2..c5adaeb1b 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -187,6 +187,8 @@ EX(CMD_cabbrev, "cabbrev", ex_abbreviate,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN),
EX(CMD_cabclear, "cabclear", ex_abclear,
EXTRA|TRLBAR|CMDWIN),
+EX(CMD_caddfile, "caddfile", ex_cfile,
+ TRLBAR|FILE1),
EX(CMD_call, "call", ex_call,
RANGE|NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN),
EX(CMD_catch, "catch", ex_catch,
@@ -201,6 +203,8 @@ EX(CMD_cd, "cd", ex_cd,
BANG|FILE1|TRLBAR|CMDWIN),
EX(CMD_center, "center", ex_align,
TRLBAR|RANGE|WHOLEFOLD|EXTRA|CMDWIN|MODIFY),
+EX(CMD_cexpr, "cexpr", ex_cexpr,
+ NEEDARG|WORD1|NOTRLCOM|TRLBAR|BANG),
EX(CMD_cfile, "cfile", ex_cfile,
TRLBAR|FILE1|BANG),
EX(CMD_cfirst, "cfirst", ex_cc,
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 5b07cf613..ab11dffd7 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -114,6 +114,7 @@ static int getargopt __ARGS((exarg_T *eap));
# define ex_cc ex_ni
# define ex_cnext ex_ni
# define ex_cfile ex_ni
+# define ex_cexpr ex_ni
# define qf_list ex_ni
# define qf_age ex_ni
# define ex_helpgrep ex_ni
diff --git a/src/globals.h b/src/globals.h
index 8460b49ba..fc1e61f0b 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -166,8 +166,6 @@ EXTERN int need_maketitle INIT(= TRUE); /* call maketitle() soon */
#endif
EXTERN int quit_more INIT(= FALSE); /* 'q' hit at "--more--" msg */
-EXTERN int more_back INIT(= 0); /* 'b' or 'u' at "--more--" msg */
-EXTERN int more_back_used INIT(= FALSE); /* using more_back */
#if defined(UNIX) || defined(__EMX__) || defined(VMS) || defined(MACOS_X)
EXTERN int newline_on_exit INIT(= FALSE); /* did msg in altern. screen */
EXTERN int intr_char INIT(= 0); /* extra interrupt character */
diff --git a/src/gui.c b/src/gui.c
index f0a595885..fd0c0466e 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -455,6 +455,7 @@ gui_init()
* where Vim was started. */
emsg_on_display = FALSE;
msg_scrolled = 0;
+ clear_sb_text();
need_wait_return = FALSE;
msg_didany = FALSE;
diff --git a/src/main.aap b/src/main.aap
index daa6e8b0b..83a9cd8ed 100644
--- a/src/main.aap
+++ b/src/main.aap
@@ -237,6 +237,7 @@ Source =
fileio.c
fold.c
getchar.c
+ hardcopy.c
hashtable.c
if_cscope.c
if_xcmdsrv.c
@@ -440,6 +441,7 @@ HELPSUBDIR = /doc
COLSUBDIR = /colors
SYNSUBDIR = /syntax
INDSUBDIR = /indent
+AUTOSUBDIR = /autoload
PLUGSUBDIR = /plugin
FTPLUGSUBDIR = /ftplugin
LANGSUBDIR = /lang
@@ -459,6 +461,7 @@ PODIR = po
### COLSUBLOC location for colorscheme files
### SYNSUBLOC location for syntax files
### INDSUBLOC location for indent files
+### AUTOSUBLOC location for standard autoload files
### PLUGSUBLOC location for standard plugin files
### FTPLUGSUBLOC location for ftplugin files
### LANGSUBLOC location for language files
@@ -478,6 +481,7 @@ HELPSUBLOC = $VIMRTLOC$HELPSUBDIR
COLSUBLOC = $VIMRTLOC$COLSUBDIR
SYNSUBLOC = $VIMRTLOC$SYNSUBDIR
INDSUBLOC = $VIMRTLOC$INDSUBDIR
+AUTOSUBLOC = $VIMRTLOC$AUTOSUBDIR
PLUGSUBLOC = $VIMRTLOC$PLUGSUBDIR
FTPLUGSUBLOC = $VIMRTLOC$FTPLUGSUBDIR
LANGSUBLOC = $VIMRTLOC$LANGSUBDIR
@@ -566,6 +570,9 @@ SYNSOURCE = ../runtime/syntax
INDSOURCE = ../runtime/indent
# Where to copy the standard plugin files from
+AUTOSOURCE = ../runtime/autoload
+
+# Where to copy the standard plugin files from
PLUGSOURCE = ../runtime/plugin
# Where to copy the ftplugin files from
@@ -600,6 +607,7 @@ DEST_HELP = $DESTDIR$HELPSUBLOC
DEST_COL = $DESTDIR$COLSUBLOC
DEST_SYN = $DESTDIR$SYNSUBLOC
DEST_IND = $DESTDIR$INDSUBLOC
+DEST_AUTO = $DESTDIR$AUTOSUBLOC
DEST_PLUG = $DESTDIR$PLUGSUBLOC
DEST_FTP = $DESTDIR$FTPLUGSUBLOC
DEST_LANG = $DESTDIR$LANGSUBLOC
@@ -614,7 +622,7 @@ DEST_MAN = $DESTDIR$MANSUBDIR
# These are directories, create them when needed.
:attr {directory = $DIRMOD} $DEST_BIN $DEST_VIM $DEST_RT $DEST_HELP $DEST_COL
- $DEST_SYN $DEST_IND $DEST_PLUG $DEST_FTP $DEST_LANG
+ $DEST_SYN $DEST_IND $DEST_AUTO $DEST_PLUG $DEST_FTP $DEST_LANG
$DEST_COMP $DEST_KMAP $DEST_MACRO $DEST_TOOLS $DEST_TUTOR
$DEST_SCRIPT $DEST_PRINT $DEST_MAN
@@ -657,7 +665,8 @@ installvimbin {virtual}{force}: $Target $DEST_BIN
# install the help files; first adjust the contents for the location
installruntime {virtual}{force}: $HELPSOURCE/vim.1 $DEST_MAN $DEST_VIM
$DEST_RT $DEST_HELP $DEST_COL $DEST_SYN $DEST_IND
- $DEST_FTP $DEST_PLUG $DEST_TUTOR $DEST_COMP $DEST_PRINT
+ $DEST_FTP $DEST_AUTO $DEST_PLUG $DEST_TUTOR $DEST_COMP
+ $DEST_PRINT
:print generating $DEST_MAN/$(VIMNAME).1
:cat $HELPSOURCE/vim.1 |
:eval re.sub("/usr/local/lib/vim", _no.VIMLOC, stdin) |
@@ -762,6 +771,9 @@ installruntime {virtual}{force}: $HELPSOURCE/vim.1 $DEST_MAN $DEST_VIM
# install the indent files
:copy $INDSOURCE/*.vim $INDSOURCE/README.txt $DEST_IND
:chmod $HELPMOD $DEST_IND/*.vim
+# install the standard autoload files
+ :copy $AUTOSOURCE/*.vim $AUTOSOURCE/README.txt $DEST_AUTO
+ :chmod $HELPMOD $DEST_AUTO/*.vim $DEST_AUTO/README.txt
# install the standard plugin files
:copy $PLUGSOURCE/*.vim $PLUGSOURCE/README.txt $DEST_PLUG
:chmod $HELPMOD $DEST_PLUG/*.vim $DEST_PLUG/README.txt
@@ -1041,8 +1053,9 @@ uninstall_runtime {virtual}{force}:
:del {force}{recursive} $DEST_COMP
:deldir {force} $DEST_HELP $DEST_COL $DEST_SYN $DEST_IND
:del {force}{recursive} $DEST_FTP/*.vim $DEST_FTP/README.txt
+ :del {force} $DEST_AUTO/*.vim $DEST_AUTO/README.txt
:del {force} $DEST_PLUG/*.vim $DEST_PLUG/README.txt
- :deldir {force} $DEST_FTP $DEST_PLUG $DEST_PRINT $DEST_RT
+ :deldir {force} $DEST_FTP $DEST_AUTO $DEST_PLUG $DEST_PRINT $DEST_RT
# This will fail when other Vim versions are installed, no worries.
@try:
:deldir $DEST_VIM
diff --git a/src/main.c b/src/main.c
index f6a31aa11..876289f67 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1034,6 +1034,7 @@ main_loop(cmdwin, noexmode)
emsg_on_display = FALSE; /* can delete error message now */
did_emsg = FALSE;
msg_didany = FALSE; /* reset lines_left in msg_start() */
+ clear_sb_text(); /* clear scroll-back text */
showruler(FALSE);
setcursor();
diff --git a/src/message.c b/src/message.c
index 94b885199..81c0a8e6e 100644
--- a/src/message.c
+++ b/src/message.c
@@ -29,7 +29,12 @@ static void msg_home_replace_attr __ARGS((char_u *fname, int attr));
static char_u *screen_puts_mbyte __ARGS((char_u *s, int l, int attr));
#endif
static void msg_puts_attr_len __ARGS((char_u *str, int maxlen, int attr));
-static void t_puts __ARGS((int t_col, char_u *t_s, char_u *s, int attr));
+static void msg_puts_display __ARGS((char_u *str, int maxlen, int attr, int recurse));
+static void msg_scroll_up __ARGS((void));
+static void store_sb_text __ARGS((char_u **sb_str, char_u *s, int attr, int *sb_col, int finish));
+static void t_puts __ARGS((int *t_col, char_u *t_s, char_u *s, int attr));
+static void msg_puts_printf __ARGS((char_u *str, int maxlen));
+static int do_more_prompt __ARGS((int typed_char));
static void msg_screen_putchar __ARGS((int c, int attr));
static int msg_check_screen __ARGS((void));
static void redir_write __ARGS((char_u *s, int maxlen));
@@ -924,6 +929,22 @@ wait_return(redraw)
c = K_IGNORE;
}
#endif
+ if (p_more && !p_cp && (c == 'b' || c == 'k' || c == 'u'))
+ {
+ /* scroll back to show older messages */
+ do_more_prompt(c);
+ if (quit_more)
+ {
+ c = CAR; /* just pretend CR was hit */
+ quit_more = FALSE;
+ got_int = FALSE;
+ }
+ else
+ {
+ c = K_IGNORE;
+ hit_return_msg();
+ }
+ }
} while ((had_got_int && c == Ctrl_C)
|| c == K_IGNORE
#ifdef FEAT_GUI
@@ -1031,14 +1052,18 @@ wait_return(redraw)
static void
hit_return_msg()
{
- if (msg_didout) /* start on a new line */
+ int save_p_more = p_more;
+
+ p_more = FALSE; /* don't want see this message when scrolling back */
+ if (msg_didout) /* start on a new line */
msg_putchar('\n');
if (got_int)
MSG_PUTS(_("Interrupt: "));
- MSG_PUTS_ATTR(_("Hit ENTER or type command to continue"), hl_attr(HLF_R));
+ MSG_PUTS_ATTR(_("Press ENTER or type command to continue"), hl_attr(HLF_R));
if (!msg_use_printf())
msg_clr_eos();
+ p_more = save_p_more;
}
/*
@@ -1515,7 +1540,7 @@ msg_prt_line(s, list)
if (*s == NUL && !(list && lcs_eol != NUL))
msg_putchar(' ');
- for (;;)
+ while (!got_int)
{
if (n_extra)
{
@@ -1711,22 +1736,10 @@ msg_puts_attr_len(str, maxlen, attr)
int maxlen;
int attr;
{
- int oldState;
- char_u *s = str;
- char_u *p;
- char_u buf[4];
- char_u *t_s = str; /* string from "t_s" to "s" is still todo */
- int t_col = 0; /* screen cells todo, 0 when "t_s" not used */
-#ifdef FEAT_MBYTE
- int l;
- int cw;
-#endif
- int c;
-
/*
* If redirection is on, also write to the redirection file.
*/
- redir_write(s, maxlen);
+ redir_write(str, maxlen);
/*
* Don't print anything when using ":silent cmd".
@@ -1737,7 +1750,7 @@ msg_puts_attr_len(str, maxlen, attr)
/* if MSG_HIST flag set, add message to history */
if ((attr & MSG_HIST) && maxlen < 0)
{
- add_msg_hist(s, -1, attr);
+ add_msg_hist(str, -1, attr);
attr &= ~MSG_HIST;
}
@@ -1759,72 +1772,42 @@ msg_puts_attr_len(str, maxlen, attr)
* cursor is.
*/
if (msg_use_printf())
- {
-#ifdef WIN3264
- if (!(silent_mode && p_verbose == 0))
- mch_settmode(TMODE_COOK); /* handle '\r' and '\n' correctly */
-#endif
- while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
- {
- if (!(silent_mode && p_verbose == 0))
- {
- p = &buf[0];
- /* NL --> CR NL translation (for Unix, not for "--version") */
- /* NL --> CR translation (for Mac) */
- if (*s == '\n' && !info_message)
- *p++ = '\r';
-#if defined(USE_CR) && !defined(MACOS_X_UNIX)
- else
-#endif
- *p++ = *s;
- *p = '\0';
- if (info_message) /* informative message, not an error */
- mch_msg((char *)buf);
- else
- mch_errmsg((char *)buf);
- }
-
- /* primitive way to compute the current column */
-#ifdef FEAT_RIGHTLEFT
- if (cmdmsg_rl)
- {
- if (*s == '\r' || *s == '\n')
- msg_col = Columns - 1;
- else
- --msg_col;
- }
- else
-#endif
- {
- if (*s == '\r' || *s == '\n')
- msg_col = 0;
- else
- ++msg_col;
- }
- ++s;
- }
- msg_didout = TRUE; /* assume that line is not empty */
+ msg_puts_printf(str, maxlen);
+ else
+ msg_puts_display(str, maxlen, attr, FALSE);
+}
-#ifdef WIN3264
- if (!(silent_mode && p_verbose == 0))
- mch_settmode(TMODE_RAW);
+/*
+ * The display part of msg_puts_attr_len().
+ * May be called recursively to display scroll-back text.
+ */
+ static void
+msg_puts_display(str, maxlen, attr, recurse)
+ char_u *str;
+ int maxlen;
+ int attr;
+ int recurse;
+{
+ char_u *s = str;
+ char_u *t_s = str; /* string from "t_s" to "s" is still todo */
+ int t_col = 0; /* screen cells todo, 0 when "t_s" not used */
+#ifdef FEAT_MBYTE
+ int l;
+ int cw;
#endif
- return;
- }
+ char_u *sb_str = str;
+ int sb_col = msg_col;
+ int wrap;
did_wait_return = FALSE;
while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
{
/*
- * The screen is scrolled up when:
- * - When outputting a newline in the last row
- * - when outputting a character in the last column of the last row
- * (some terminals scroll automatically, some don't. To avoid
- * problems we scroll ourselves)
+ * We are at the end of the screen line when:
+ * - When outputting a newline.
+ * - When outputting a character in the last column.
*/
- if (msg_row >= Rows - 1
- && (*s == '\n'
- || (
+ if (!recurse && msg_row >= Rows - 1 && (*s == '\n' || (
#ifdef FEAT_RIGHTLEFT
cmdmsg_rl
? (
@@ -1844,47 +1827,55 @@ msg_puts_attr_len(str, maxlen, attr)
# endif
))))
{
+ /*
+ * The screen is scrolled up when at the last row (some terminals
+ * scroll automatically, some don't. To avoid problems we scroll
+ * ourselves).
+ */
if (t_col > 0)
- {
/* output postponed text */
- t_puts(t_col, t_s, s, attr);
- t_col = 0;
- }
+ t_puts(&t_col, t_s, s, attr);
/* When no more prompt an no more room, truncate here */
if (msg_no_more && lines_left == 0)
break;
-#ifdef FEAT_GUI
- /* Remove the cursor before scrolling, ScreenLines[] is going to
- * become invalid. */
- if (gui.in_use)
- gui_undraw_cursor();
-#endif
- /* scrolling up always works */
- screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
- if (!can_clear((char_u *)" "))
- {
- /* Scrolling up doesn't result in the right background. Set
- * the background here. It's not efficient, but avoids that
- * we have to do it all over the code. */
- screen_fill((int)Rows - 1, (int)Rows, 0,
- (int)Columns, ' ', ' ', 0);
-
- /* Also clear the last char of the last but one line if it was
- * not cleared before to avoid a scroll-up. */
- if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1]
- == (sattr_T)-1)
- screen_fill((int)Rows - 2, (int)Rows - 1,
- (int)Columns - 1, (int)Columns, ' ', ' ', 0);
- }
+ /* Scroll the screen up one line. */
+ msg_scroll_up();
msg_row = Rows - 2;
if (msg_col >= Columns) /* can happen after screen resize */
msg_col = Columns - 1;
+ /* Display char in last column before showing more-prompt. */
+ if (*s >= ' '
+#ifdef FEAT_RIGHTLEFT
+ && !cmdmsg_rl
+#endif
+ )
+ {
+#ifdef FEAT_MBYTE
+ if (has_mbyte)
+ {
+ if (enc_utf8 && maxlen >= 0)
+ /* avoid including composing chars after the end */
+ l = utfc_ptr2len_check_len(s,
+ (int)((str + maxlen) - s));
+ else
+ l = (*mb_ptr2len_check)(s);
+ s = screen_puts_mbyte(s, l, attr);
+ }
+ else
+#endif
+ msg_screen_putchar(*s++, attr);
+ }
+
+ if (p_more)
+ /* store text for scrolling back */
+ store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
+
++msg_scrolled;
- need_wait_return = TRUE; /* may need wait_return in main() */
+ need_wait_return = TRUE; /* may need wait_return in main() */
if (must_redraw < VALID)
must_redraw = VALID;
redraw_cmdline = TRUE;
@@ -1892,170 +1883,38 @@ msg_puts_attr_len(str, maxlen, attr)
--cmdline_row;
/*
- * if screen is completely filled wait for a character
+ * If screen is completely filled and 'more' is set then wait
+ * for a character.
*/
if (p_more && --lines_left == 0 && State != HITRETURN
&& !msg_no_more && !exmode_active)
{
- oldState = State;
- State = ASKMORE;
-#ifdef FEAT_MOUSE
- setmouse();
-#endif
- msg_moremsg(FALSE);
- for (;;)
- {
- /*
- * Get a typed character directly from the user.
- */
- c = get_keystroke();
-
-#if defined(FEAT_MENU) && defined(FEAT_GUI)
- if (c == K_MENU)
- {
- int idx = get_menu_index(current_menu, ASKMORE);
-
- /* Used a menu. If it starts with CTRL-Y, it must
- * be a "Copy" for the clipboard. Otherwise
- * assume that we end */
- if (idx == MENU_INDEX_INVALID)
- continue;
- c = *current_menu->strings[idx];
- if (c != NUL && current_menu->strings[idx][1] != NUL)
- ins_typebuf(current_menu->strings[idx] + 1,
- current_menu->noremap[idx], 0, TRUE,
- current_menu->silent[idx]);
- }
-#endif
-
- switch (c)
- {
- case BS:
- case 'k':
- case K_UP:
- if (!more_back_used)
- {
- msg_moremsg(TRUE);
- continue;
- }
- more_back = 1;
- lines_left = 1;
- break;
- case CAR: /* one extra line */
- case NL:
- case 'j':
- case K_DOWN:
- lines_left = 1;
- break;
- case ':': /* start new command line */
-#ifdef FEAT_CON_DIALOG
- if (!confirm_msg_used)
-#endif
- {
- /* Since got_int is set all typeahead will be
- * flushed, but we want to keep this ':', remember
- * that in a special way. */
- typeahead_noflush(':');
- cmdline_row = Rows - 1; /* put ':' on this line */
- skip_redraw = TRUE; /* skip redraw once */
- need_wait_return = FALSE; /* don't wait in main() */
- }
- /*FALLTHROUGH*/
- case 'q': /* quit */
- case Ctrl_C:
- case ESC:
#ifdef FEAT_CON_DIALOG
- if (confirm_msg_used)
- {
- /* Jump to the choices of the dialog. */
- s = confirm_msg_tail;
- lines_left = Rows - 1;
- }
- else
-#endif
- {
- got_int = TRUE;
- quit_more = TRUE;
- }
- break;
- case 'u': /* Up half a page */
- case K_PAGEUP:
- if (!more_back_used)
- {
- msg_moremsg(TRUE);
- continue;
- }
- more_back = Rows / 2;
- /*FALLTHROUGH*/
- case 'd': /* Down half a page */
- lines_left = Rows / 2;
- break;
- case 'b': /* one page back */
- if (!more_back_used)
- {
- msg_moremsg(TRUE);
- continue;
- }
- more_back = Rows - 1;
- /*FALLTHROUGH*/
- case ' ': /* one extra page */
- case K_PAGEDOWN:
- case K_LEFTMOUSE:
- lines_left = Rows - 1;
- break;
-
-#ifdef FEAT_CLIPBOARD
- case Ctrl_Y:
- /* Strange way to allow copying (yanking) a modeless
- * selection at the more prompt. Use CTRL-Y,
- * because the same is used in Cmdline-mode and at the
- * hit-enter prompt. However, scrolling one line up
- * might be expected... */
- if (clip_star.state == SELECT_DONE)
- clip_copy_modeless_selection(TRUE);
- continue;
-#endif
- default: /* no valid response */
- msg_moremsg(TRUE);
- continue;
- }
- break;
- }
-
- /* clear the --more-- message */
- screen_fill((int)Rows - 1, (int)Rows,
- 0, (int)Columns, ' ', ' ', 0);
- State = oldState;
-#ifdef FEAT_MOUSE
- setmouse();
+ if (do_more_prompt(NUL))
+ s = confirm_msg_tail;
+#else
+ (void)do_more_prompt(NUL);
#endif
if (quit_more)
- {
- msg_row = Rows - 1;
- msg_col = 0;
- return; /* the string is not displayed! */
- }
-#ifdef FEAT_RIGHTLEFT
- if (cmdmsg_rl)
- msg_col = Columns - 1;
-#endif
+ return;
}
}
- if (t_col > 0
- && (vim_strchr((char_u *)"\n\r\b\t", *s) != NULL
- || *s == BELL
+ wrap = *s == '\n'
|| msg_col + t_col >= Columns
#ifdef FEAT_MBYTE
|| (has_mbyte && (*mb_ptr2cells)(s) > 1
&& msg_col + t_col >= Columns - 1)
#endif
- ))
- {
+ ;
+ if (t_col > 0 && (wrap || *s == '\r' || *s == '\b'
+ || *s == '\t' || *s == BELL))
/* output any postponed text */
- t_puts(t_col, t_s, s, attr);
- t_col = 0;
- }
+ t_puts(&t_col, t_s, s, attr);
+
+ if (wrap && p_more && !recurse)
+ /* store text for scrolling back */
+ store_sb_text(&sb_str, s, attr, &sb_col, TRUE);
if (*s == '\n') /* go to next line */
{
@@ -2073,7 +1932,7 @@ msg_puts_attr_len(str, maxlen, attr)
if (msg_col)
--msg_col;
}
- else if (*s == TAB) /* translate into spaces */
+ else if (*s == TAB) /* translate Tab into spaces */
{
do
msg_screen_putchar(' ', attr);
@@ -2141,17 +2000,172 @@ msg_puts_attr_len(str, maxlen, attr)
/* output any postponed text */
if (t_col > 0)
- t_puts(t_col, t_s, s, attr);
+ t_puts(&t_col, t_s, s, attr);
+ if (p_more && !recurse)
+ store_sb_text(&sb_str, s, attr, &sb_col, FALSE);
msg_check();
}
/*
+ * Scroll the screen up one line for displaying the next message line.
+ */
+ static void
+msg_scroll_up()
+{
+#ifdef FEAT_GUI
+ /* Remove the cursor before scrolling, ScreenLines[] is going
+ * to become invalid. */
+ if (gui.in_use)
+ gui_undraw_cursor();
+#endif
+ /* scrolling up always works */
+ screen_del_lines(0, 0, 1, (int)Rows, TRUE, NULL);
+
+ if (!can_clear((char_u *)" "))
+ {
+ /* Scrolling up doesn't result in the right background. Set the
+ * background here. It's not efficient, but avoids that we have to do
+ * it all over the code. */
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+
+ /* Also clear the last char of the last but one line if it was not
+ * cleared before to avoid a scroll-up. */
+ if (ScreenAttrs[LineOffset[Rows - 2] + Columns - 1] == (sattr_T)-1)
+ screen_fill((int)Rows - 2, (int)Rows - 1,
+ (int)Columns - 1, (int)Columns, ' ', ' ', 0);
+ }
+}
+
+/*
+ * To be able to scroll back at the "more" and "hit-enter" prompts we need to
+ * store the displayed text and remember where screen lines start.
+ */
+typedef struct msgchunk_S msgchunk_T;
+struct msgchunk_S
+{
+ msgchunk_T *sb_next;
+ msgchunk_T *sb_prev;
+ char sb_eol; /* TRUE when line ends after this text */
+ int sb_msg_col; /* column in which text starts */
+ int sb_attr; /* text attributes */
+ char_u sb_text[1]; /* text to be displayed, actually longer */
+};
+
+static msgchunk_T *last_msgchunk = NULL; /* last displayed text */
+
+static msgchunk_T *msg_sb_start __ARGS((msgchunk_T *mps));
+static msgchunk_T *disp_sb_line __ARGS((int row, msgchunk_T *smp));
+
+/*
+ * Store part of a printed message for displaying when scrolling back.
+ */
+ static void
+store_sb_text(sb_str, s, attr, sb_col, finish)
+ char_u **sb_str; /* start of string */
+ char_u *s; /* just after string */
+ int attr;
+ int *sb_col;
+ int finish; /* line ends */
+{
+ msgchunk_T *mp;
+
+ if (s > *sb_str)
+ {
+ mp = (msgchunk_T *)alloc((int)(sizeof(msgchunk_T) + (s - *sb_str)));
+ if (mp != NULL)
+ {
+ mp->sb_eol = finish;
+ mp->sb_msg_col = *sb_col;
+ mp->sb_attr = attr;
+ vim_strncpy(mp->sb_text, *sb_str, s - *sb_str);
+
+ if (last_msgchunk == NULL)
+ {
+ last_msgchunk = mp;
+ mp->sb_prev = NULL;
+ }
+ else
+ {
+ mp->sb_prev = last_msgchunk;
+ last_msgchunk->sb_next = mp;
+ last_msgchunk = mp;
+ }
+ mp->sb_next = NULL;
+ }
+ }
+ else if (finish && last_msgchunk != NULL)
+ last_msgchunk->sb_eol = TRUE;
+
+ *sb_str = s;
+ *sb_col = 0;
+}
+
+/*
+ * Clear any text remembered for scrolling back.
+ * Called when redrawing the screen.
+ */
+ void
+clear_sb_text()
+{
+ msgchunk_T *mp;
+
+ while (last_msgchunk != NULL)
+ {
+ mp = last_msgchunk->sb_prev;
+ vim_free(last_msgchunk);
+ last_msgchunk = mp;
+ }
+ last_msgchunk = NULL;
+}
+
+/*
+ * Move to the start of screen line in already displayed text.
+ */
+ static msgchunk_T *
+msg_sb_start(mps)
+ msgchunk_T *mps;
+{
+ msgchunk_T *mp = mps;
+
+ while (mp != NULL && mp->sb_prev != NULL && !mp->sb_prev->sb_eol)
+ mp = mp->sb_prev;
+ return mp;
+}
+
+/*
+ * Display a screen line from previously displayed text at row "row".
+ * Returns a pointer to the text for the next line (can be NULL).
+ */
+ static msgchunk_T *
+disp_sb_line(row, smp)
+ int row;
+ msgchunk_T *smp;
+{
+ msgchunk_T *mp = smp;
+ char_u *p;
+
+ for (;;)
+ {
+ msg_row = row;
+ msg_col = mp->sb_msg_col;
+ p = mp->sb_text;
+ if (*p == '\n') /* don't display the line break */
+ ++p;
+ msg_puts_display(p, -1, mp->sb_attr, TRUE);
+ if (mp->sb_eol || mp->sb_next == NULL)
+ break;
+ mp = mp->sb_next;
+ }
+ return mp->sb_next;
+}
+
+/*
* Output any postponed text for msg_puts_attr_len().
*/
static void
t_puts(t_col, t_s, s, attr)
- int t_col;
+ int *t_col;
char_u *t_s;
char_u *s;
int attr;
@@ -2159,7 +2173,8 @@ t_puts(t_col, t_s, s, attr)
/* output postponed text */
msg_didout = TRUE; /* remember that line is not empty */
screen_puts_len(t_s, (int)(s - t_s), msg_row, msg_col, attr);
- msg_col += t_col;
+ msg_col += *t_col;
+ *t_col = 0;
#ifdef FEAT_MBYTE
/* If the string starts with a composing character don't increment the
* column position for it. */
@@ -2173,7 +2188,6 @@ t_puts(t_col, t_s, s, attr)
}
}
-
/*
* Returns TRUE when messages should be printed with mch_errmsg().
* This is used when there is no valid screen, so we can see error messages.
@@ -2193,6 +2207,309 @@ msg_use_printf()
);
}
+/*
+ * Print a message when there is no valid screen.
+ */
+ static void
+msg_puts_printf(str, maxlen)
+ char_u *str;
+ int maxlen;
+{
+ char_u *s = str;
+ char_u buf[4];
+ char_u *p;
+
+#ifdef WIN3264
+ if (!(silent_mode && p_verbose == 0))
+ mch_settmode(TMODE_COOK); /* handle '\r' and '\n' correctly */
+#endif
+ while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
+ {
+ if (!(silent_mode && p_verbose == 0))
+ {
+ /* NL --> CR NL translation (for Unix, not for "--version") */
+ /* NL --> CR translation (for Mac) */
+ p = &buf[0];
+ if (*s == '\n' && !info_message)
+ *p++ = '\r';
+#if defined(USE_CR) && !defined(MACOS_X_UNIX)
+ else
+#endif
+ *p++ = *s;
+ *p = '\0';
+ if (info_message) /* informative message, not an error */
+ mch_msg((char *)buf);
+ else
+ mch_errmsg((char *)buf);
+ }
+
+ /* primitive way to compute the current column */
+#ifdef FEAT_RIGHTLEFT
+ if (cmdmsg_rl)
+ {
+ if (*s == '\r' || *s == '\n')
+ msg_col = Columns - 1;
+ else
+ --msg_col;
+ }
+ else
+#endif
+ {
+ if (*s == '\r' || *s == '\n')
+ msg_col = 0;
+ else
+ ++msg_col;
+ }
+ ++s;
+ }
+ msg_didout = TRUE; /* assume that line is not empty */
+
+#ifdef WIN3264
+ if (!(silent_mode && p_verbose == 0))
+ mch_settmode(TMODE_RAW);
+#endif
+}
+
+/*
+ * Show the more-prompt and handle the user response.
+ * This takes care of scrolling back and displaying previously displayed text.
+ * When at hit-enter prompt "typed_char" is the already typed character.
+ * Returns TRUE when jumping ahead to "confirm_msg_tail".
+ */
+ static int
+do_more_prompt(typed_char)
+ int typed_char;
+{
+ int used_typed_char = typed_char;
+ int oldState = State;
+ int c;
+#ifdef FEAT_CON_DIALOG
+ int retval = FALSE;
+#endif
+ int scroll;
+ msgchunk_T *mp_last = NULL;
+ msgchunk_T *mp;
+ int i;
+
+ State = ASKMORE;
+#ifdef FEAT_MOUSE
+ setmouse();
+#endif
+ msg_moremsg(FALSE);
+ for (;;)
+ {
+ /*
+ * Get a typed character directly from the user.
+ */
+ if (used_typed_char != NUL)
+ {
+ c = used_typed_char; /* was typed at hit-enter prompt */
+ used_typed_char = NUL;
+ }
+ else
+ c = get_keystroke();
+
+#if defined(FEAT_MENU) && defined(FEAT_GUI)
+ if (c == K_MENU)
+ {
+ int idx = get_menu_index(current_menu, ASKMORE);
+
+ /* Used a menu. If it starts with CTRL-Y, it must
+ * be a "Copy" for the clipboard. Otherwise
+ * assume that we end */
+ if (idx == MENU_INDEX_INVALID)
+ continue;
+ c = *current_menu->strings[idx];
+ if (c != NUL && current_menu->strings[idx][1] != NUL)
+ ins_typebuf(current_menu->strings[idx] + 1,
+ current_menu->noremap[idx], 0, TRUE,
+ current_menu->silent[idx]);
+ }
+#endif
+
+ scroll = 0;
+ switch (c)
+ {
+ case BS: /* scroll one line back */
+ case K_BS:
+ case 'k':
+ case K_UP:
+ scroll = -1;
+ break;
+
+ case CAR: /* one extra line */
+ case NL:
+ case 'j':
+ case K_DOWN:
+ scroll = 1;
+ break;
+
+ case 'u': /* Up half a page */
+ case K_PAGEUP:
+ scroll = -(Rows / 2);
+ break;
+
+ case 'd': /* Down half a page */
+ scroll = Rows / 2;
+ break;
+
+ case 'b': /* one page back */
+ scroll = -(Rows - 1);
+ break;
+
+ case ' ': /* one extra page */
+ case K_PAGEDOWN:
+ case K_LEFTMOUSE:
+ scroll = Rows - 1;
+ break;
+
+ case ':': /* start new command line */
+#ifdef FEAT_CON_DIALOG
+ if (!confirm_msg_used)
+#endif
+ {
+ /* Since got_int is set all typeahead will be flushed, but we
+ * want to keep this ':', remember that in a special way. */
+ typeahead_noflush(':');
+ cmdline_row = Rows - 1; /* put ':' on this line */
+ skip_redraw = TRUE; /* skip redraw once */
+ need_wait_return = FALSE; /* don't wait in main() */
+ }
+ /*FALLTHROUGH*/
+ case 'q': /* quit */
+ case Ctrl_C:
+ case ESC:
+#ifdef FEAT_CON_DIALOG
+ if (confirm_msg_used)
+ {
+ /* Jump to the choices of the dialog. */
+ retval = TRUE;
+ lines_left = Rows - 1;
+ }
+ else
+#endif
+ {
+ got_int = TRUE;
+ quit_more = TRUE;
+ }
+ break;
+
+#ifdef FEAT_CLIPBOARD
+ case Ctrl_Y:
+ /* Strange way to allow copying (yanking) a modeless
+ * selection at the more prompt. Use CTRL-Y,
+ * because the same is used in Cmdline-mode and at the
+ * hit-enter prompt. However, scrolling one line up
+ * might be expected... */
+ if (clip_star.state == SELECT_DONE)
+ clip_copy_modeless_selection(TRUE);
+ continue;
+#endif
+ default: /* no valid response */
+ msg_moremsg(TRUE);
+ continue;
+ }
+
+ if (scroll != 0)
+ {
+ if (scroll < 0)
+ {
+ /* go to start of last line */
+ if (mp_last == NULL)
+ mp = msg_sb_start(last_msgchunk);
+ else if (mp_last->sb_prev != NULL)
+ mp = msg_sb_start(mp_last->sb_prev);
+ else
+ mp = NULL;
+
+ /* go to start of line at top of the screen */
+ for (i = 0; i < Rows - 2 && mp != NULL && mp->sb_prev != NULL;
+ ++i)
+ mp = msg_sb_start(mp->sb_prev);
+
+ if (mp != NULL && mp->sb_prev != NULL)
+ {
+ /* Find line to be displayed at top. */
+ for (i = 0; i > scroll; --i)
+ {
+ if (mp == NULL || mp->sb_prev == NULL)
+ break;
+ mp = msg_sb_start(mp->sb_prev);
+ if (mp_last == NULL)
+ mp_last = msg_sb_start(last_msgchunk);
+ else
+ mp_last = msg_sb_start(mp_last->sb_prev);
+ }
+
+ if (scroll == -1 && screen_ins_lines(0, 0, 1,
+ (int)Rows, NULL) == OK)
+ {
+ /* clear last line, display line at top */
+ screen_fill((int)Rows - 1, (int)Rows, 0,
+ (int)Columns, ' ', ' ', 0);
+ (void)disp_sb_line(0, mp);
+ }
+ else
+ {
+ /* redisplay */
+ screenclear();
+ for (i = 0; i < Rows - 1; ++i)
+ mp = disp_sb_line(i, mp);
+ }
+ scroll = 0;
+ }
+ }
+ else
+ {
+ /* First display any text that we scrolled back. */
+ while (scroll > 0 && mp_last != NULL)
+ {
+ /* scroll up, display line at bottom */
+ msg_scroll_up();
+ screen_fill((int)Rows - 2, (int)Rows - 1, 0,
+ (int)Columns, ' ', ' ', 0);
+ mp_last = disp_sb_line((int)Rows - 2, mp_last);
+ --scroll;
+ }
+ }
+
+ if (scroll <= 0)
+ {
+ /* displayed the requested text, more prompt again */
+ msg_moremsg(FALSE);
+ continue;
+ }
+
+ /* display more text, return to caller */
+ lines_left = scroll;
+ }
+
+ break;
+ }
+
+ /* clear the --more-- message */
+ screen_fill((int)Rows - 1, (int)Rows, 0, (int)Columns, ' ', ' ', 0);
+ State = oldState;
+#ifdef FEAT_MOUSE
+ setmouse();
+#endif
+ if (quit_more)
+ {
+ msg_row = Rows - 1;
+ msg_col = 0;
+ }
+#ifdef FEAT_RIGHTLEFT
+ else if (cmdmsg_rl)
+ msg_col = Columns - 1;
+#endif
+
+#ifdef FEAT_CON_DIALOG
+ return retval;
+#else
+ return FALSE;
+#endif
+}
+
#if defined(USE_MCH_ERRMSG) || defined(PROTO)
#ifdef mch_errmsg
@@ -2344,15 +2661,15 @@ msg_screen_putchar(c, attr)
msg_moremsg(full)
int full;
{
- int attr;
+ int attr;
+ char_u *s = (char_u *)_("-- More --");
attr = hl_attr(HLF_M);
- screen_puts((char_u *)_("-- More --"), (int)Rows - 1, 0, attr);
+ screen_puts(s, (int)Rows - 1, 0, attr);
if (full)
- screen_puts(more_back_used
- ? (char_u *)_(" (RET/BS: line, SPACE/b: page, d/u: half page, q: quit)")
- : (char_u *)_(" (RET: line, SPACE: page, d: half page, q: quit)"),
- (int)Rows - 1, 10, attr);
+ screen_puts((char_u *)
+ _(" SPACE/d/j: screen/page/line down, b/u/k: up, q: quit "),
+ (int)Rows - 1, vim_strsize(s), attr);
}
/*
diff --git a/src/ops.c b/src/ops.c
index 894194135..b5492c680 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -1580,9 +1580,15 @@ op_delete(oap)
&& *ml_get(oap->start.lnum) == NUL)
{
/*
- * It's an error to operate on an empty region, when 'E' inclucded in
+ * It's an error to operate on an empty region, when 'E' included in
* 'cpoptions' (Vi compatible).
*/
+#ifdef FEAT_VIRTUALEDIT
+ if (virtual_op)
+ /* Virtual editing: Nothing gets deleted, but we set the '[ and ']
+ * marks as if it happened. */
+ goto setmarks;
+#endif
if (vim_strchr(p_cpo, CPO_EMPTYREGION) != NULL)
beep_flush();
return OK;
@@ -1858,6 +1864,9 @@ op_delete(oap)
msgmore(curbuf->b_ml.ml_line_count - old_lcount);
+#ifdef FEAT_VIRTUALEDIT
+setmarks:
+#endif
#ifdef FEAT_VISUAL
if (oap->block_mode)
{
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 6a2d44e7d..86ea3968f 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -22,6 +22,7 @@ char_u *eval_to_string_safe __ARGS((char_u *arg, char_u **nextcmd));
int eval_to_number __ARGS((char_u *expr));
list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr));
int get_spellword __ARGS((list_T *list, char_u **pp));
+typval_T *eval_expr __ARGS((char_u *arg, char_u **nextcmd));
void *call_func_retstr __ARGS((char_u *func, int argc, char_u **argv, int safe));
void *call_func_retlist __ARGS((char_u *func, int argc, char_u **argv, int safe));
void *save_funccal __ARGS((void));
@@ -59,6 +60,7 @@ void set_reg_var __ARGS((int c));
char_u *v_exception __ARGS((char_u *oldval));
char_u *v_throwpoint __ARGS((char_u *oldval));
char_u *set_cmdarg __ARGS((exarg_T *eap, char_u *oldarg));
+void clear_tv __ARGS((typval_T *varp));
char_u *get_var_value __ARGS((char_u *name));
void new_script_vars __ARGS((scid_T id));
void init_var_dict __ARGS((dict_T *dict, dictitem_T *dict_var));
diff --git a/src/proto/message.pro b/src/proto/message.pro
index db09d855c..faa03680c 100644
--- a/src/proto/message.pro
+++ b/src/proto/message.pro
@@ -39,6 +39,7 @@ void msg_puts_title __ARGS((char_u *s));
void msg_puts_long_attr __ARGS((char_u *longstr, int attr));
void msg_puts_long_len_attr __ARGS((char_u *longstr, int len, int attr));
void msg_puts_attr __ARGS((char_u *s, int attr));
+void clear_sb_text __ARGS((void));
int msg_use_printf __ARGS((void));
void mch_errmsg __ARGS((char *str));
void mch_msg __ARGS((char *str));
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
index 7369a6441..6712cf151 100644
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -24,5 +24,6 @@ char_u *skip_vimgrep_pat __ARGS((char_u *p, char_u **s, int *flags));
int get_errorlist __ARGS((list_T *list));
int set_errorlist __ARGS((list_T *list, int action));
void ex_cbuffer __ARGS((exarg_T *eap));
+void ex_cexpr __ARGS((exarg_T *eap));
void ex_helpgrep __ARGS((exarg_T *eap));
/* vim: set ft=c : */
diff --git a/src/proto/screen.pro b/src/proto/screen.pro
index b5b6eec68..fd6a1fa92 100644
--- a/src/proto/screen.pro
+++ b/src/proto/screen.pro
@@ -37,6 +37,7 @@ void windgoto __ARGS((int row, int col));
void setcursor __ARGS((void));
int win_ins_lines __ARGS((win_T *wp, int row, int line_count, int invalid, int mayclear));
int win_del_lines __ARGS((win_T *wp, int row, int line_count, int invalid, int mayclear));
+int screen_ins_lines __ARGS((int off, int row, int line_count, int end, win_T *wp));
int screen_del_lines __ARGS((int off, int row, int line_count, int end, int force, win_T *wp));
int showmode __ARGS((void));
void unshowmode __ARGS((int force));
diff --git a/src/quickfix.c b/src/quickfix.c
index d46578701..5847ae19d 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -88,7 +88,7 @@ struct eformat
/* '-' do not include this line */
};
-static int qf_init_ext __ARGS((char_u *efile, buf_T *buf, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
+static int qf_init_ext __ARGS((char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast));
static void qf_new_list __ARGS((void));
static int qf_add_entry __ARGS((qfline_T **prevp, char_u *dir, char_u *fname, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
static void qf_msg __ARGS((void));
@@ -124,7 +124,7 @@ qf_init(efile, errorformat, newlist)
{
if (efile == NULL)
return FAIL;
- return qf_init_ext(efile, curbuf, errorformat, newlist,
+ return qf_init_ext(efile, curbuf, NULL, errorformat, newlist,
(linenr_T)0, (linenr_T)0);
}
@@ -137,9 +137,10 @@ qf_init(efile, errorformat, newlist)
* Return -1 for error, number of errors for success.
*/
static int
-qf_init_ext(efile, buf, errorformat, newlist, lnumfirst, lnumlast)
+qf_init_ext(efile, buf, tv, errorformat, newlist, lnumfirst, lnumlast)
char_u *efile;
buf_T *buf;
+ typval_T *tv;
char_u *errorformat;
int newlist; /* TRUE: start a new error list */
linenr_T lnumfirst; /* first line number to use */
@@ -176,6 +177,8 @@ qf_init_ext(efile, buf, errorformat, newlist, lnumfirst, lnumlast)
char_u *directory = NULL;
char_u *currfile = NULL;
char_u *tail = NULL;
+ char_u *p_str = NULL;
+ listitem_T *p_li = NULL;
struct dir_stack_T *file_stack = NULL;
regmatch_T regmatch;
static struct fmtpattern
@@ -222,7 +225,7 @@ qf_init_ext(efile, buf, errorformat, newlist, lnumfirst, lnumlast)
* regex prog. Only a few % characters are allowed.
*/
/* Use the local value of 'errorformat' if it's set. */
- if (errorformat == p_efm && *buf->b_p_efm != NUL)
+ if (errorformat == p_efm && tv == NULL && *buf->b_p_efm != NUL)
efm = buf->b_p_efm;
else
efm = errorformat;
@@ -432,6 +435,14 @@ qf_init_ext(efile, buf, errorformat, newlist, lnumfirst, lnumlast)
/* Always ignore case when looking for a matching error. */
regmatch.rm_ic = TRUE;
+ if (tv != NULL)
+ {
+ if (tv->v_type == VAR_STRING)
+ p_str = tv->vval.v_string;
+ else if (tv->v_type == VAR_LIST)
+ p_li = tv->vval.v_list->lv_first;
+ }
+
/*
* Read the lines in the error file one by one.
* Try to recognize one of the error formats in each line.
@@ -441,10 +452,57 @@ qf_init_ext(efile, buf, errorformat, newlist, lnumfirst, lnumlast)
/* Get the next line. */
if (fd == NULL)
{
- if (buflnum > lnumlast)
- break;
- vim_strncpy(IObuff, ml_get_buf(buf, buflnum++, FALSE),
- CMDBUFFSIZE - 2);
+ if (tv != NULL)
+ {
+ int len;
+
+ if (tv->v_type == VAR_STRING)
+ {
+ /* Get the next line from the supplied string */
+ char_u *p;
+
+ if (!*p_str) /* Reached the end of the string */
+ break;
+
+ p = vim_strchr(p_str, '\n');
+ if (p)
+ len = p - p_str + 1;
+ else
+ len = STRLEN(p_str);
+
+ if (len > CMDBUFFSIZE - 2)
+ vim_strncpy(IObuff, p_str, CMDBUFFSIZE - 2);
+ else
+ vim_strncpy(IObuff, p_str, len);
+
+ p_str += len;
+ }
+ else if (tv->v_type == VAR_LIST)
+ {
+ /* Get the next line from the supplied list */
+ while (p_li && p_li->li_tv.v_type != VAR_STRING)
+ p_li = p_li->li_next; /* Skip non-string items */
+
+ if (!p_li) /* End of the list */
+ break;
+
+ len = STRLEN(p_li->li_tv.vval.v_string);
+ if (len > CMDBUFFSIZE - 2)
+ len = CMDBUFFSIZE - 2;
+
+ vim_strncpy(IObuff, p_li->li_tv.vval.v_string, len);
+
+ p_li = p_li->li_next; /* next item */
+ }
+ }
+ else
+ {
+ /* Get the next line from the supplied buffer */
+ if (buflnum > lnumlast)
+ break;
+ vim_strncpy(IObuff, ml_get_buf(buf, buflnum++, FALSE),
+ CMDBUFFSIZE - 2);
+ }
}
else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
break;
@@ -1446,7 +1504,6 @@ qf_list(eap)
int idx1 = 1;
int idx2 = -1;
int need_return = TRUE;
- int last_printed = 1;
char_u *arg = eap->arg;
int all = eap->forceit; /* if not :cl!, only show
recognised errors */
@@ -1467,7 +1524,6 @@ qf_list(eap)
if (idx2 < 0)
idx2 = (-idx2 > i) ? 0 : idx2 + i + 1;
- more_back_used = TRUE;
if (qf_lists[qf_curlist].qf_nonevalid)
all = TRUE;
qfp = qf_lists[qf_curlist].qf_start;
@@ -1478,79 +1534,59 @@ qf_list(eap)
if (need_return)
{
msg_putchar('\n');
+ if (got_int)
+ break;
need_return = FALSE;
}
- if (more_back == 0)
- {
- fname = NULL;
- if (qfp->qf_fnum != 0
+
+ fname = NULL;
+ if (qfp->qf_fnum != 0
&& (buf = buflist_findnr(qfp->qf_fnum)) != NULL)
- {
- fname = buf->b_fname;
- if (qfp->qf_type == 1) /* :helpgrep */
- fname = gettail(fname);
- }
- if (fname == NULL)
- sprintf((char *)IObuff, "%2d", i);
- else
- vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
+ {
+ fname = buf->b_fname;
+ if (qfp->qf_type == 1) /* :helpgrep */
+ fname = gettail(fname);
+ }
+ if (fname == NULL)
+ sprintf((char *)IObuff, "%2d", i);
+ else
+ vim_snprintf((char *)IObuff, IOSIZE, "%2d %s",
i, (char *)fname);
- msg_outtrans_attr(IObuff, i == qf_lists[qf_curlist].qf_index
- ? hl_attr(HLF_L) : hl_attr(HLF_D));
- if (qfp->qf_lnum == 0)
- IObuff[0] = NUL;
- else if (qfp->qf_col == 0)
- sprintf((char *)IObuff, ":%ld", qfp->qf_lnum);
- else
- sprintf((char *)IObuff, ":%ld col %d",
+ msg_outtrans_attr(IObuff, i == qf_lists[qf_curlist].qf_index
+ ? hl_attr(HLF_L) : hl_attr(HLF_D));
+ if (qfp->qf_lnum == 0)
+ IObuff[0] = NUL;
+ else if (qfp->qf_col == 0)
+ sprintf((char *)IObuff, ":%ld", qfp->qf_lnum);
+ else
+ sprintf((char *)IObuff, ":%ld col %d",
qfp->qf_lnum, qfp->qf_col);
- sprintf((char *)IObuff + STRLEN(IObuff), "%s:",
+ sprintf((char *)IObuff + STRLEN(IObuff), "%s:",
(char *)qf_types(qfp->qf_type, qfp->qf_nr));
- msg_puts_attr(IObuff, hl_attr(HLF_N));
- if (qfp->qf_pattern != NULL)
- {
- qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
- STRCAT(IObuff, ":");
- msg_puts(IObuff);
- }
- msg_puts((char_u *)" ");
+ msg_puts_attr(IObuff, hl_attr(HLF_N));
+ if (qfp->qf_pattern != NULL)
+ {
+ qf_fmt_text(qfp->qf_pattern, IObuff, IOSIZE);
+ STRCAT(IObuff, ":");
+ msg_puts(IObuff);
+ }
+ msg_puts((char_u *)" ");
- /* Remove newlines and leading whitespace from the text.
- * For an unrecognized line keep the indent, the compiler may
- * mark a word with ^^^^. */
- qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
+ /* Remove newlines and leading whitespace from the text. For an
+ * unrecognized line keep the indent, the compiler may mark a word
+ * with ^^^^. */
+ qf_fmt_text((fname != NULL || qfp->qf_lnum != 0)
? skipwhite(qfp->qf_text) : qfp->qf_text,
IObuff, IOSIZE);
- msg_prt_line(IObuff, FALSE);
- out_flush(); /* show one line at a time */
- need_return = TRUE;
- last_printed = i;
- }
- }
- if (more_back)
- {
- /* scrolling backwards from the more-prompt */
- /* TODO: compute the number of items from the screen lines */
- more_back = more_back * 2 - 1;
- while (i > last_printed - more_back && i > idx1)
- {
- do
- {
- qfp = qfp->qf_prev;
- --i;
- }
- while (i > idx1 && !qfp->qf_valid && !all);
- }
- more_back = 0;
- }
- else
- {
- qfp = qfp->qf_next;
- ++i;
+ msg_prt_line(IObuff, FALSE);
+ out_flush(); /* show one line at a time */
+ need_return = TRUE;
}
+
+ qfp = qfp->qf_next;
+ ++i;
ui_breakcheck();
}
- more_back_used = FALSE;
}
/*
@@ -2330,7 +2366,7 @@ ex_cnext(eap)
}
/*
- * ":cfile" command.
+ * ":cfile"/":cgetfile"/":caddfile" commands.
*/
void
ex_cfile(eap)
@@ -2338,7 +2374,19 @@ ex_cfile(eap)
{
if (*eap->arg != NUL)
set_string_option_direct((char_u *)"ef", -1, eap->arg, OPT_FREE);
- if (qf_init(p_ef, p_efm, TRUE) > 0 && eap->cmdidx == CMD_cfile)
+
+ /*
+ * This function is used by the :cfile, :cgetfile and :caddfile
+ * commands.
+ * :cfile always creates a new quickfix list and jumps to the
+ * first error.
+ * :cgetfile creates a new quickfix list but doesn't jump to the
+ * first error.
+ * :caddfile adds to an existing quickfix list. If there is no
+ * quickfix list then a new list is created.
+ */
+ if (qf_init(p_ef, p_efm, eap->cmdidx != CMD_caddfile) > 0
+ && eap->cmdidx == CMD_cfile)
qf_jump(0, 0, eap->forceit); /* display first error */
}
@@ -2917,11 +2965,32 @@ ex_cbuffer(eap)
|| eap->line2 < 1 || eap->line2 > buf->b_ml.ml_line_count)
EMSG(_(e_invrange));
else
- qf_init_ext(NULL, buf, p_efm, TRUE, eap->line1, eap->line2);
+ qf_init_ext(NULL, buf, NULL, p_efm, TRUE, eap->line1, eap->line2);
}
}
/*
+ * ":cexpr {expr}" command.
+ */
+ void
+ex_cexpr(eap)
+ exarg_T *eap;
+{
+ typval_T *tv;
+
+ tv = eval_expr(eap->arg, NULL);
+ if (!tv || (tv->v_type != VAR_STRING && tv->v_type != VAR_LIST) ||
+ (tv->v_type == VAR_STRING && !tv->vval.v_string) ||
+ (tv->v_type == VAR_LIST && !tv->vval.v_list))
+ return;
+
+ if (qf_init_ext(NULL, NULL, tv, p_efm, TRUE, (linenr_T)0, (linenr_T)0) > 0)
+ qf_jump(0, 0, eap->forceit); /* display first error */
+
+ clear_tv(tv);
+}
+
+/*
* ":helpgrep {pattern}"
*/
void
diff --git a/src/screen.c b/src/screen.c
index c07691e86..a3f3e0bd1 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -169,7 +169,6 @@ static void redraw_block __ARGS((int row, int end, win_T *wp));
#endif
static int win_do_lines __ARGS((win_T *wp, int row, int line_count, int mayclear, int del));
static void win_rest_invalid __ARGS((win_T *wp));
-static int screen_ins_lines __ARGS((int, int, int, int, win_T *wp));
static void msg_pos_mode __ARGS((void));
#if defined(FEAT_WINDOWS) || defined(FEAT_WILDMENU) || defined(FEAT_STL_OPT)
static int fillchar_status __ARGS((int *attr, int is_curwin));
@@ -7618,7 +7617,7 @@ win_rest_invalid(wp)
*
* return FAIL for failure, OK for success.
*/
- static int
+ int
screen_ins_lines(off, row, line_count, end, wp)
int off;
int row;
diff --git a/src/tag.c b/src/tag.c
index f46ae72f4..03f498bf6 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -770,11 +770,6 @@ do_tag(tag, type, count, forceit, verbose)
#endif
break;
}
-#if 0
- /* avoid the need to hit <CR> when jumping to another file */
- msg_scrolled = 0;
- redraw_all_later(NOT_VALID);
-#endif
cur_match = i - 1;
}
diff --git a/src/version.h b/src/version.h
index a2074a2f8..03557c29a 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
#define VIM_VERSION_NODOT "vim70aa"
#define VIM_VERSION_SHORT "7.0aa"
#define VIM_VERSION_MEDIUM "7.0aa ALPHA"
-#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 25)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 25, compiled "
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 27)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2005 Jul 27, compiled "