summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2005-01-21 11:55:25 +0000
committerBram Moolenaar <Bram@vim.org>2005-01-21 11:55:25 +0000
commitdcaf10e19aac2af7c93d6dd23cb6241f971f2b19 (patch)
treed704aec40840d64d81fbf7225fcd5dd64eab847f /src
parentca4729948bdc79d2175607194fdd98df7d6eb529 (diff)
updated for version 7.0043
Diffstat (limited to 'src')
-rw-r--r--src/ex_cmds2.c28
-rw-r--r--src/fileio.c42
-rw-r--r--src/hashtable.c43
-rw-r--r--src/main.c3
-rw-r--r--src/proto/eval.pro5
-rw-r--r--src/proto/fileio.pro2
-rw-r--r--src/proto/hashtable.pro3
-rw-r--r--src/quickfix.c73
-rw-r--r--src/structs.h75
-rw-r--r--src/testdir/test55.in36
-rw-r--r--src/testdir/test55.ok9
-rw-r--r--src/version.h4
12 files changed, 226 insertions, 97 deletions
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 2600a1b245..8ba1744d00 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1618,7 +1618,6 @@ ex_listdo(eap)
int next_fnum = 0;
#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
char_u *save_ei = NULL;
- char_u *new_ei;
#endif
char_u *p_shm_save;
@@ -1632,22 +1631,9 @@ ex_listdo(eap)
#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
if (eap->cmdidx != CMD_windo)
- {
- /* Add "Syntax" to 'eventignore' to skip loading syntax highlighting
- * for every buffer loaded into the window. A considerable speed
- * improvement. */
- save_ei = vim_strsave(p_ei);
- if (save_ei != NULL)
- {
- new_ei = vim_strnsave(p_ei, (int)STRLEN(p_ei) + 8);
- if (new_ei != NULL)
- {
- STRCAT(new_ei, ",Syntax");
- set_string_option_direct((char_u *)"ei", -1, new_ei, OPT_FREE);
- vim_free(new_ei);
- }
- }
- }
+ /* Don't do syntax HL autocommands. Skipping the syntax file is a
+ * great speed improvement. */
+ save_ei = au_event_disable(",Syntax");
#endif
if (eap->cmdidx == CMD_windo
@@ -1755,13 +1741,7 @@ ex_listdo(eap)
}
#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
- if (save_ei != NULL)
- {
- set_string_option_direct((char_u *)"ei", -1, save_ei, OPT_FREE);
- apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
- curbuf->b_fname, TRUE, curbuf);
- vim_free(save_ei);
- }
+ au_event_restore(save_ei);
#endif
}
diff --git a/src/fileio.c b/src/fileio.c
index accd81cf07..c888f35338 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -7132,6 +7132,48 @@ check_ei()
return OK;
}
+# if defined(FEAT_SYN_HL) || defined(PROTO)
+
+/*
+ * Add "what" to 'eventignore' to skip loading syntax highlighting for every
+ * buffer loaded into the window. "what" must start with a comma.
+ * Returns the old value of 'eventignore' in allocated memory.
+ */
+ char_u *
+au_event_disable(what)
+ char *what;
+{
+ char_u *new_ei;
+ char_u *save_ei;
+
+ save_ei = vim_strsave(p_ei);
+ if (save_ei != NULL)
+ {
+ new_ei = vim_strnsave(p_ei, (int)STRLEN(p_ei) + 8);
+ if (new_ei != NULL)
+ {
+ STRCAT(new_ei, what);
+ set_string_option_direct((char_u *)"ei", -1, new_ei, OPT_FREE);
+ vim_free(new_ei);
+ }
+ }
+ return save_ei;
+}
+
+ void
+au_event_restore(old_ei)
+ char_u *old_ei;
+{
+ if (old_ei != NULL)
+ {
+ set_string_option_direct((char_u *)"ei", -1, old_ei, OPT_FREE);
+ apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
+ curbuf->b_fname, TRUE, curbuf);
+ vim_free(old_ei);
+ }
+}
+# endif /* FEAT_SYN_HL */
+
/*
* do_autocmd() -- implements the :autocmd command. Can be used in the
* following ways:
diff --git a/src/hashtable.c b/src/hashtable.c
index 4b378aa0c6..11cb469e97 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -73,19 +73,17 @@ hash_init(ht)
ht->ht_mask = HT_INIT_SIZE - 1;
}
-#if 0 /* not used */
/*
- * Free a hash table. Does not free the items it contains!
+ * Free the array of a hash table. Does not free the items it contains!
+ * If "ht" is not freed then you should call hash_init() next!
*/
void
-hash_free(ht)
+hash_clear(ht)
hashtable *ht;
{
if (ht->ht_array != ht->ht_smallarray)
vim_free(ht->ht_array);
- vim_free(ht);
}
-#endif
/*
* Find "key" in hashtable "ht". "key" must not be NULL.
@@ -228,8 +226,8 @@ hash_set(hi, key)
/*
* Remove item "hi" from hashtable "ht". "hi" must have been obtained with
- * hash_lookup() and point to a used empty item.
- * The caller must take care of freeing the item.
+ * hash_lookup() and point to an empty item.
+ * The caller must take care of freeing the item itself.
*/
void
hash_remove(ht, hi)
@@ -242,6 +240,31 @@ hash_remove(ht, hi)
}
/*
+ * Lock a hashtable: prevent that ht_array changes.
+ * Don't use this when items are to be added!
+ * Must call hash_unlock() later.
+ */
+ void
+hash_lock(ht)
+ hashtable *ht;
+{
+ ++ht->ht_locked;
+}
+
+/*
+ * Unlock a hashtable: allow ht_array changes again.
+ * Table will be resized (shrink) when necessary.
+ * This must balance a call to hash_lock().
+ */
+ void
+hash_unlock(ht)
+ hashtable *ht;
+{
+ --ht->ht_locked;
+ (void)hash_may_resize(ht);
+}
+
+/*
* Shrink a hashtable when there is too much empty space.
* Grow a hashtable when there is not enough empty space.
* Returns OK or FAIL (out of memory).
@@ -260,6 +283,10 @@ hash_may_resize(ht)
long_u newmask;
long_u perturb;
+ /* Don't resize a locked table. */
+ if (ht->ht_locked > 0)
+ return OK;
+
#ifdef HT_DEBUG
if (ht->ht_used > ht->ht_filled)
EMSG("hash_may_resize(): more used than filled");
@@ -282,7 +309,7 @@ hash_may_resize(ht)
if (ht->ht_filled * 3 < oldsize * 2 && ht->ht_used > oldsize / 5)
return OK;
- if (ht->ht_used > 10000)
+ if (ht->ht_used > 1000)
minsize = ht->ht_used * 2; /* it's big, don't make too much room */
else
minsize = ht->ht_used * 4; /* make plenty of room */
diff --git a/src/main.c b/src/main.c
index 7ab914cb58..3b888f278b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -177,6 +177,9 @@ main
#ifdef FEAT_MBYTE
(void)mb_init(); /* init mb_bytelen_tab[] to ones */
#endif
+#ifdef FEAT_EVAL
+ eval_init(); /* init global variables */
+#endif
#ifdef __QNXNTO__
qnx_init(); /* PhAttach() for clipboard, (and gui) */
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 64fb62a524..19d993552d 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -1,4 +1,5 @@
/* eval.c */
+void eval_init __ARGS((void));
char_u *func_name __ARGS((void *cookie));
linenr_T *func_breakpoint __ARGS((void *cookie));
int *func_dbg_tick __ARGS((void *cookie));
@@ -41,8 +42,8 @@ char_u *v_throwpoint __ARGS((char_u *oldval));
char_u *set_cmdarg __ARGS((exarg_T *eap, char_u *oldarg));
char_u *get_var_value __ARGS((char_u *name));
void new_script_vars __ARGS((scid_T id));
-void vars_init __ARGS((garray_T *gap));
-void vars_clear __ARGS((garray_T *gap));
+void vars_init __ARGS((hashtable *ht));
+void vars_clear __ARGS((hashtable *ht));
void ex_echo __ARGS((exarg_T *eap));
void ex_echohl __ARGS((exarg_T *eap));
void ex_execute __ARGS((exarg_T *eap));
diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro
index c3a872c587..d7c80956cb 100644
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -23,6 +23,8 @@ void forward_slash __ARGS((char_u *fname));
void aubuflocal_remove __ARGS((buf_T *buf));
void do_augroup __ARGS((char_u *arg, int del_group));
int check_ei __ARGS((void));
+char_u *au_event_disable __ARGS((char *what));
+void au_event_restore __ARGS((char_u *old_ei));
void do_autocmd __ARGS((char_u *arg, int forceit));
int do_doautocmd __ARGS((char_u *arg, int do_msg));
void ex_doautoall __ARGS((exarg_T *eap));
diff --git a/src/proto/hashtable.pro b/src/proto/hashtable.pro
index f6cb77ad92..6cc8041d99 100644
--- a/src/proto/hashtable.pro
+++ b/src/proto/hashtable.pro
@@ -1,6 +1,9 @@
/* hashtable.c */
void hash_init __ARGS((hashtable *ht));
+void hash_clear __ARGS((hashtable *ht));
hashitem *hash_find __ARGS((hashtable *ht, char_u *key));
int hash_add __ARGS((hashtable *ht, char_u *key));
void hash_remove __ARGS((hashtable *ht, hashitem *hi));
+void hash_lock __ARGS((hashtable *ht));
+void hash_unlock __ARGS((hashtable *ht));
/* vim: set ft=c : */
diff --git a/src/quickfix.c b/src/quickfix.c
index 8bb2bbe760..0c5a050d9b 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -2269,7 +2269,12 @@ ex_vimgrep(eap)
int duplicate_name = FALSE;
int using_dummy;
int found_match;
- int first_match = TRUE;
+ buf_T *first_match_buf = NULL;
+ time_t seconds = 0;
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+ char_u *save_ei = NULL;
+ aco_save_T aco;
+#endif
/* Make 'cpoptions' empty, the 'l' flag should not be used here. */
save_cpo = p_cpo;
@@ -2330,24 +2335,59 @@ ex_vimgrep(eap)
goto theend;
}
+ seconds = (time_t)0;
for (fi = 0; fi < fcount && !got_int; ++fi)
{
+ if (time(NULL) > seconds)
+ {
+ /* Display the file name every second or so. */
+ seconds = time(NULL);
+ msg_start();
+ p = msg_strtrunc(fnames[fi]);
+ if (p == NULL)
+ msg_outtrans(fnames[fi]);
+ else
+ {
+ msg_outtrans(p);
+ vim_free(p);
+ }
+ msg_clr_eos();
+ msg_didout = FALSE; /* overwrite this message */
+ msg_nowait = TRUE; /* don't wait for this message */
+ msg_col = 0;
+ out_flush();
+ }
+
buf = buflist_findname_exp(fnames[fi]);
if (buf == NULL || buf->b_ml.ml_mfp == NULL)
{
/* Remember that a buffer with this name already exists. */
duplicate_name = (buf != NULL);
+ using_dummy = TRUE;
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+ /* Don't do Filetype autocommands to avoid loading syntax and
+ * indent scripts, a great speed improvement. */
+ save_ei = au_event_disable(",Filetype");
+#endif
/* Load file into a buffer, so that 'fileencoding' is detected,
* autocommands applied, etc. */
buf = load_dummy_buffer(fnames[fi]);
- using_dummy = TRUE;
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+ au_event_restore(save_ei);
+#endif
}
else
/* Use existing, loaded buffer. */
using_dummy = FALSE;
+
if (buf == NULL)
- smsg((char_u *)_("Cannot open file \"%s\""), fnames[fi]);
+ {
+ if (!got_int)
+ smsg((char_u *)_("Cannot open file \"%s\""), fnames[fi]);
+ }
else
{
found_match = FALSE;
@@ -2382,10 +2422,15 @@ ex_vimgrep(eap)
if (using_dummy)
{
+ if (found_match && first_match_buf == NULL)
+ first_match_buf = buf;
if (duplicate_name)
+ {
/* Never keep a dummy buffer if there is another buffer
* with the same name. */
wipe_dummy_buffer(buf);
+ buf = NULL;
+ }
else if (!buf_hide(buf))
{
/* When not hiding the buffer and no match was found we
@@ -2393,13 +2438,29 @@ ex_vimgrep(eap)
* there was a match and it wasn't the first one: only
* unload the buffer. */
if (!found_match)
+ {
wipe_dummy_buffer(buf);
- else if (!first_match)
+ buf = NULL;
+ }
+ else if (buf != first_match_buf)
+ {
unload_dummy_buffer(buf);
+ buf = NULL;
+ }
+ }
+
+#if defined(FEAT_AUTOCMD) && defined(FEAT_SYN_HL)
+ if (buf != NULL)
+ {
+ /* The buffer is still loaded, the Filetype autocommands
+ * need to be done now, in that buffer. */
+ aucmd_prepbuf(&aco, buf);
+ apply_autocmds(EVENT_FILETYPE, buf->b_p_ft,
+ buf->b_fname, TRUE, buf);
+ aucmd_restbuf(&aco);
}
+#endif
}
- if (found_match)
- first_match = FALSE;
}
}
diff --git a/src/structs.h b/src/structs.h
index 051eb2df06..a5e9e8d9ca 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -910,6 +910,42 @@ struct stl_hlrec
int userhl;
};
+/* Item for a hashtable. "hi_key" can be one of three values:
+ * NULL: Never been used
+ * HI_KEY_REMOVED: Entry was removed
+ * Otherwise: Used item, pointer to the actual key; this usually is
+ * inside the item, subtract an offset to locate the item.
+ * This reduces the size of hashitem by 1/3.
+ */
+typedef struct hashitem_S
+{
+ long_u hi_hash; /* cached hash number of hi_key */
+ char_u *hi_key;
+} hashitem;
+
+/* The address of "hash_removed" is used as a magic number for hi_key to
+ * indicate a removed item. */
+#define HI_KEY_REMOVED &hash_removed
+#define HASHITEM_EMPTY(hi) ((hi)->hi_key == NULL || (hi)->hi_key == &hash_removed)
+
+/* Initial size for a hashtable. Our items are relatively small and growing
+ * is expensive, thus use 16 as a start. Must be a power of 2. */
+#define HT_INIT_SIZE 16
+
+typedef struct hashtable_S
+{
+ long_u ht_mask; /* mask used for hash value (nr of items in
+ * array is "ht_mask" + 1) */
+ int ht_used; /* number of items used */
+ int ht_filled; /* number of items used + removed */
+ int ht_locked; /* counter for hash_lock() */
+ int ht_error; /* when set growing failed, can't add more
+ items before growing works */
+ hashitem *ht_array; /* points to the array, allocated when it's
+ not "ht_smallarray" */
+ hashitem ht_smallarray[HT_INIT_SIZE]; /* initial array */
+} hashtable;
+
/*
* buffer: structure that holds information about one file
*
@@ -1223,7 +1259,7 @@ struct file_buffer
#endif
#ifdef FEAT_EVAL
- garray_T b_vars; /* internal variables, local to buffer */
+ hashtable b_vars; /* internal variables, local to buffer */
#endif
/* When a buffer is created, it starts without a swap file. b_may_swap is
@@ -1567,7 +1603,7 @@ struct window
#endif
#ifdef FEAT_EVAL
- garray_T w_vars; /* internal variables, local to window */
+ hashtable w_vars; /* internal variables, local to window */
#endif
#if defined(FEAT_RIGHTLEFT) && defined(FEAT_FKMAP)
@@ -1929,38 +1965,3 @@ typedef struct
} prt_settings_T;
#define PRINT_NUMBER_WIDTH 8
-
-/* Item for a hashtable. "hi_key" can be one of three values:
- * NULL: Never been used
- * HI_KEY_REMOVED: Entry was removed
- * Otherwise: Used item, pointer to the actual key; this usually is
- * inside the item, subtract an offset to locate the item.
- * This reduces the size of hashitem by 1/3.
- */
-typedef struct hashitem_S
-{
- long_u hi_hash; /* cached hash number of hi_key */
- char_u *hi_key;
-} hashitem;
-
-/* The address of "hash_removed" is used as a magic number for hi_key to
- * indicate a removed item. */
-#define HI_KEY_REMOVED &hash_removed
-#define HASHITEM_EMPTY(hi) ((hi)->hi_key == NULL || (hi)->hi_key == &hash_removed)
-
-/* Initial size for a hashtable. Our items are relatively small and growing
- * is expensive, thus use 16 as a start. Must be a power of 2. */
-#define HT_INIT_SIZE 16
-
-typedef struct hashtable_S
-{
- long_u ht_mask; /* mask used for hash value (nr of items in
- * array is "ht_mask" + 1) */
- int ht_used; /* number of items used */
- int ht_filled; /* number of items used + removed */
- int ht_error; /* when set growing failed, can't add more
- items before growing works */
- hashitem *ht_array; /* points to the array, allocated when it's
- not "ht_smallarray" */
- hashitem ht_smallarray[HT_INIT_SIZE]; /* initial array */
-} hashtable;
diff --git a/src/testdir/test55.in b/src/testdir/test55.in
index a757dae125..2fa26bf903 100644
--- a/src/testdir/test55.in
+++ b/src/testdir/test55.in
@@ -76,20 +76,20 @@ STARTTEST
:unlet d[-1]
:$put =string(d)
:"
-:" manipulating a big Dictionary
+:" manipulating a big Dictionary (hashtable.c has a border of 1000 entries)
:let d = {}
-:for i in range(15000)
-: let d[i] = 30000 - i
+:for i in range(1500)
+: let d[i] = 3000 - i
:endfor
-:$put =d[0] . ' ' . d[100] . ' ' . d[999] . ' ' . d[14000] . ' ' . d[14999]
+:$put =d[0] . ' ' . d[100] . ' ' . d[999] . ' ' . d[1400] . ' ' . d[1499]
:try
-: let n = d[15000]
+: let n = d[1500]
:catch
-: $put =v:exception[:14] . v:exception[-5:-1]
+: $put =v:exception[:14] . v:exception[-4:-1]
:endtry
:" lookup each items
-:for i in range(15000)
-: if d[i] != 30000 - i
+:for i in range(1500)
+: if d[i] != 3000 - i
: $put =d[i]
: endif
:endfor
@@ -99,12 +99,12 @@ STARTTEST
: let i -= 2
: unlet d[i]
:endwhile
-:$put =get(d, 15000 - 100, 'NONE') . ' ' . d[1]
+:$put =get(d, 1500 - 100, 'NONE') . ' ' . d[1]
:" delete odd items, checking value, one intentionally wrong
:let d[33] = 999
:let i = 1
-:while i < 15000
-: if d[i] != 30000 - i
+:while i < 1500
+: if d[i] != 3000 - i
: $put =i . '=' . d[i]
: else
: unlet d[i]
@@ -121,14 +121,22 @@ STARTTEST
:endfunc
:let dict.data = [1,2,3]
:call dict.func("len: ")
-:echo dict.func("again: ")
+:let x = dict.func("again: ")
:try
: let Fn = dict.func
: call Fn('xxx')
:catch
: $put =v:exception[:15]
:endtry
-:sleep 5
+:"
+:" Function in script-local List or Dict
+:let g:dict = {}
+:function g:dict.func() dict
+: $put ='g:dict.func'.self.foo[1].self.foo[0]('asdf')
+:endfunc
+:let g:dict.foo = ['-', 2, 3]
+:call insert(g:dict.foo, function('strlen'))
+:call g:dict.func()
:"
:" Nasty: remove func from Dict that's being called (works)
:let d = {1:1}
@@ -148,7 +156,7 @@ STARTTEST
:endtry
:"
:endfun
-:call Test()
+:call Test() " This may take a while
:"
:/^start:/,$wq! test.out
ENDTEST
diff --git a/src/testdir/test55.ok b/src/testdir/test55.ok
index 407b7a1b5f..868b116fb1 100644
--- a/src/testdir/test55.ok
+++ b/src/testdir/test55.ok
@@ -19,13 +19,14 @@ Vim(let):E706: l
[1, 'as''d', {'a': 1}]
[4]
{'1': 99, '3': 33}
-30000 29900 29001 16000 15001
-Vim(let):E716: 15000
-NONE 29999
+3000 2900 2001 1600 1501
+Vim(let):E716: 1500
+NONE 2999
33=999
{'33': 999}
len: 3
again: 3
Vim(call):E725:
-a:function('2')
+g:dict.func-4
+a:function('3')
Vim(let):E698:
diff --git a/src/version.h b/src/version.h
index 18f33b7d48..8b531751dc 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 (2004 Jan 19)"
-#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 19, compiled "
+#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 20)"
+#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2004 Jan 20, compiled "