From 5d81ef5823e51b4c5d9bba1211afc56caafdf840 Mon Sep 17 00:00:00 2001 From: edyfox Date: Mon, 23 Feb 2009 04:02:27 +0000 Subject: [PATCH] Merged from the latest developing branch. git-svn-id: https://vim.svn.sourceforge.net/svnroot/vim/trunk@1382 2a77ed30-b011-0410-a7ad-c7884a0aa172 --- runtime/doc/options.txt | 3 -- src/buffer.c | 3 +- src/edit.c | 4 -- src/ex_docmd.c | 2 +- src/getchar.c | 4 ++ src/macros.h | 26 ++++++++--- src/message.c | 5 ++- src/nbdebug.c | 37 --------------- src/nbdebug.h | 16 ------- src/netbeans.c | 6 +-- src/normal.c | 15 ------- src/option.c | 116 +++++++++++++++++++++++++++++++++++++++++++----- src/os_unix.c | 53 +++++++++++++++++----- src/proto/option.pro | 1 + src/quickfix.c | 26 ++++++----- src/regexp.c | 10 ++--- src/screen.c | 30 ++++++++++--- src/tag.c | 26 ++++++++--- src/version.c | 32 +++++++++++++ src/vim.h | 1 + src/window.c | 23 +++++++--- 21 files changed, 295 insertions(+), 144 deletions(-) diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 786e83c7..bebaa03b 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4175,9 +4175,6 @@ A jump table for the options with a short description can be found at |Q_op|. be able to execute Normal mode commands. This is the opposite of the 'keymap' option, where characters are mapped in Insert mode. - This only works for 8-bit characters. The value of 'langmap' may be - specified with multi-byte characters (e.g., UTF-8), but only the lower - 8 bits of each character will be used. Example (for Greek, in UTF-8): *greek* > :set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz diff --git a/src/buffer.c b/src/buffer.c index b510bf96..a052e12c 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -5098,7 +5098,8 @@ buf_spname(buf) */ FOR_ALL_TAB_WINDOWS(tp, win) if (win->w_buffer == buf) - break; + goto win_found; +win_found: if (win != NULL && win->w_llist_ref != NULL) return _("[Location List]"); else diff --git a/src/edit.c b/src/edit.c index 24f14963..b998f8df 100644 --- a/src/edit.c +++ b/src/edit.c @@ -7703,9 +7703,7 @@ ins_reg() */ ++no_mapping; regname = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(regname, TRUE); -#endif if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) { /* Get a third key for literal register insertion */ @@ -7714,9 +7712,7 @@ ins_reg() add_to_showcmd_c(literally); #endif regname = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(regname, TRUE); -#endif } --no_mapping; diff --git a/src/ex_docmd.c b/src/ex_docmd.c index b5d76c1e..60bbb5f8 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -5916,7 +5916,7 @@ do_ucmd(eap) char_u *q; char_u *start; - char_u *end; + char_u *end = NULL; char_u *ksp; size_t len, totlen; diff --git a/src/getchar.c b/src/getchar.c index 081368d0..0947f35f 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -3816,7 +3816,11 @@ showmap(mp, local) int len = 1; if (msg_didout || msg_silent != 0) + { msg_putchar('\n'); + if (got_int) /* 'q' typed at MORE prompt */ + return; + } if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE) msg_putchar('!'); /* :map! */ else if (mp->m_mode & INSERT) diff --git a/src/macros.h b/src/macros.h index f2230995..afe3572b 100644 --- a/src/macros.h +++ b/src/macros.h @@ -127,15 +127,31 @@ #ifdef FEAT_LANGMAP /* * Adjust chars in a language according to 'langmap' option. - * NOTE that there is NO overhead if 'langmap' is not set; but even - * when set we only have to do 2 ifs and an array lookup. + * NOTE that there is no noticeable overhead if 'langmap' is not set. + * When set the overhead for characters < 256 is small. * Don't apply 'langmap' if the character comes from the Stuff buffer. * The do-while is just to ignore a ';' after the macro. */ -# define LANGMAP_ADJUST(c, condition) do { \ - if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \ - c = langmap_mapchar[c]; \ +# ifdef FEAT_MBYTE +# define LANGMAP_ADJUST(c, condition) \ + do { \ + if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) \ + { \ + if ((c) < 256) \ + c = langmap_mapchar[c]; \ + else \ + c = langmap_adjust_mb(c); \ + } \ } while (0) +# else +# define LANGMAP_ADJUST(c, condition) \ + do { \ + if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \ + c = langmap_mapchar[c]; \ + } while (0) +# endif +#else +# define LANGMAP_ADJUST(c, condition) /* nop */ #endif /* diff --git a/src/message.c b/src/message.c index e0f28976..66bab9e9 100644 --- a/src/message.c +++ b/src/message.c @@ -976,7 +976,7 @@ wait_return(redraw) } } else if (msg_scrolled > Rows - 2 - && (c == 'j' || c == K_DOWN || c == 'd')) + && (c == 'j' || c == K_DOWN || c == 'd' || c == 'f')) c = K_IGNORE; } } while ((had_got_int && c == Ctrl_C) @@ -2504,7 +2504,6 @@ do_more_prompt(typed_char) break; case 'u': /* Up half a page */ - case K_PAGEUP: scroll = -(Rows / 2); break; @@ -2513,10 +2512,12 @@ do_more_prompt(typed_char) break; case 'b': /* one page back */ + case K_PAGEUP: scroll = -(Rows - 1); break; case ' ': /* one extra page */ + case 'f': case K_PAGEDOWN: case K_LEFTMOUSE: scroll = Rows - 1; diff --git a/src/nbdebug.c b/src/nbdebug.c index 3dfe86ae..20125ca5 100644 --- a/src/nbdebug.c +++ b/src/nbdebug.c @@ -33,7 +33,6 @@ FILE *nb_debug = NULL; u_int nb_dlevel = 0; /* nb_debug verbosity level */ void nbdb(char *, ...); -void nbtrace(char *, ...); static int lookup(char *); #ifdef USE_NB_ERRORHANDLER @@ -100,25 +99,6 @@ nbdebug_log_init( } /* end nbdebug_log_init */ - - -void -nbtrace( - char *fmt, - ...) -{ - va_list ap; - - if (nb_debug!= NULL && (nb_dlevel & (NB_TRACE | NB_TRACE_VERBOSE))) { - va_start(ap, fmt); - vfprintf(nb_debug, fmt, ap); - va_end(ap); - fflush(nb_debug); - } - -} /* end nbtrace */ - - void nbdbg( char *fmt, @@ -136,23 +116,6 @@ nbdbg( } /* end nbdbg */ -void -nbprt( - char *fmt, - ...) -{ - va_list ap; - - if (nb_debug != NULL && nb_dlevel & NB_PRINT) { - va_start(ap, fmt); - vfprintf(nb_debug, fmt, ap); - va_end(ap); - fflush(nb_debug); - } - -} /* end nbprt */ - - static int lookup( char *file) diff --git a/src/nbdebug.h b/src/nbdebug.h index 65bb940b..95109144 100644 --- a/src/nbdebug.h +++ b/src/nbdebug.h @@ -43,8 +43,6 @@ typedef enum { void nbdbg(char *, ...); -void nbprt(char *, ...); -void nbtrace(char *, ...); void nbdebug_wait __ARGS((u_int wait_flags, char *wait_var, u_int wait_secs)); void nbdebug_log_init __ARGS((char *log_var, char *level_var)); @@ -70,19 +68,5 @@ nbdbg( { } -void -nbprt( - char *fmt, - ...) -{ -} - -void -nbtrace( - char *fmt, - ...) -{ -} - #endif /* NBDEBUG */ #endif /* NBDEBUG_H */ diff --git a/src/netbeans.c b/src/netbeans.c index 5fc42f21..d3a5c595 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -1924,7 +1924,7 @@ nb_do_cmd( vim_free(path); if (bufp == NULL) { - nbdebug((" File %s not found in setBufferNumber\n", args)); + nbdebug((" File %s not found in setBufferNumber\n", args)); EMSG2("E642: File %s not found in setBufferNumber", args); return FAIL; } @@ -2318,7 +2318,7 @@ nb_do_cmd( } if (pos) { - coloncmd(":sign place %d line=%d name=%d buffer=%d", + coloncmd(":sign place %d line=%ld name=%d buffer=%d", serNum, pos->lnum, typeNum, buf->bufp->b_fnum); if (typeNum == curPCtype) coloncmd(":sign jump %d buffer=%d", serNum, @@ -2422,7 +2422,7 @@ nb_do_cmd( GUARDED) == 0) { coloncmd( - ":sign place %d line=%d name=%d buffer=%d", + ":sign place %d line=%ld name=%d buffer=%d", guardId++, lnum, GUARDED, buf->bufp->b_fnum); } diff --git a/src/normal.c b/src/normal.c index 30678a42..32413304 100644 --- a/src/normal.c +++ b/src/normal.c @@ -651,10 +651,7 @@ normal_cmd(oap, toplevel) * Get the command character from the user. */ c = safe_vgetc(); - -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(c, TRUE); -#endif #ifdef FEAT_VISUAL /* @@ -744,9 +741,7 @@ getcount: } ++no_zero_mapping; /* don't map zero here */ c = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(c, TRUE); -#endif --no_zero_mapping; if (ctrl_w) { @@ -769,9 +764,7 @@ getcount: ++no_mapping; ++allow_keys; /* no mapping for nchar, but keys */ c = plain_vgetc(); /* get next character */ -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(c, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO @@ -959,9 +952,7 @@ getcount: * "gr", "g'" and "g`". */ ca.nchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(ca.nchar, TRUE); -#endif #ifdef FEAT_CMDL_INFO need_flushbuf |= add_to_showcmd(ca.nchar); #endif @@ -1062,10 +1053,8 @@ getcount: } #endif -#ifdef FEAT_LANGMAP /* adjust chars > 127, except after "tTfFr" commands */ LANGMAP_ADJUST(*cp, !lang); -#endif #ifdef FEAT_RIGHTLEFT /* adjust Hebrew mapped char */ if (p_hkmap && lang && KeyTyped) @@ -4630,9 +4619,7 @@ nv_zet(cap) ++no_mapping; ++allow_keys; /* no mapping for nchar, but allow key codes */ nchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(nchar, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO @@ -4988,9 +4975,7 @@ dozet: ++no_mapping; ++allow_keys; /* no mapping for nchar, but allow key codes */ nchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(nchar, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO diff --git a/src/option.c b/src/option.c index bd12b8ba..87497ea6 100644 --- a/src/option.c +++ b/src/option.c @@ -10153,25 +10153,110 @@ wc_use_keyname(varp, wcp) #ifdef FEAT_LANGMAP /* - * Any character has an equivalent character. This is used for keyboards that - * have a special language mode that sends characters above 128 (although - * other characters can be translated too). + * Any character has an equivalent 'langmap' character. This is used for + * keyboards that have a special language mode that sends characters above + * 128 (although other characters can be translated too). The "to" field is a + * Vim command character. This avoids having to switch the keyboard back to + * ASCII mode when leaving Insert mode. + * + * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim + * commands. + * When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of + * langmap_entry_T. This does the same as langmap_mapchar[] for characters >= + * 256. + */ +# ifdef FEAT_MBYTE +/* + * With multi-byte support use growarray for 'langmap' chars >= 256 + */ +typedef struct +{ + int from; + int to; +} langmap_entry_T; + +static garray_T langmap_mapga; +static void langmap_set_entry __ARGS((int from, int to)); + +/* + * Search for an entry in "langmap_mapga" for "from". If found set the "to" + * field. If not found insert a new entry at the appropriate location. */ + static void +langmap_set_entry(from, to) + int from; + int to; +{ + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); + int a = 0; + int b = langmap_mapga.ga_len; + + /* Do a binary search for an existing entry. */ + while (a != b) + { + int i = (a + b) / 2; + int d = entries[i].from - from; + + if (d == 0) + { + entries[i].to = to; + return; + } + if (d < 0) + a = i + 1; + else + b = i; + } + + if (ga_grow(&langmap_mapga, 1) != OK) + return; /* out of memory */ + + /* insert new entry at position "a" */ + entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a; + mch_memmove(entries + 1, entries, + (langmap_mapga.ga_len - a) * sizeof(langmap_entry_T)); + ++langmap_mapga.ga_len; + entries[0].from = from; + entries[0].to = to; +} /* - * char_u langmap_mapchar[256]; - * Normally maps each of the 128 upper chars to an <128 ascii char; used to - * "translate" native lang chars in normal mode or some cases of - * insert mode without having to tediously switch lang mode back&forth. + * Apply 'langmap' to multi-byte character "c" and return the result. */ + int +langmap_adjust_mb(c) + int c; +{ + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); + int a = 0; + int b = langmap_mapga.ga_len; + + while (a != b) + { + int i = (a + b) / 2; + int d = entries[i].from - c; + + if (d == 0) + return entries[i].to; /* found matching entry */ + if (d < 0) + a = i + 1; + else + b = i; + } + return c; /* no entry found, return "c" unmodified */ +} +# endif static void langmap_init() { int i; - for (i = 0; i < 256; i++) /* we init with a-one-to one map */ - langmap_mapchar[i] = i; + for (i = 0; i < 256; i++) + langmap_mapchar[i] = i; /* we init with a one-to-one map */ +# ifdef FEAT_MBYTE + ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8); +# endif } /* @@ -10185,7 +10270,10 @@ langmap_set() char_u *p2; int from, to; - langmap_init(); /* back to one-to-one map first */ +#ifdef FEAT_MBYTE + ga_clear(&langmap_mapga); /* clear the previous map first */ +#endif + langmap_init(); /* back to one-to-one map */ for (p = p_langmap; p[0] != NUL; ) { @@ -10235,7 +10323,13 @@ langmap_set() transchar(from)); return; } - langmap_mapchar[from & 255] = to; + +#ifdef FEAT_MBYTE + if (from >= 256) + langmap_set_entry(from, to); + else +#endif + langmap_mapchar[from & 255] = to; /* Advance to next pair */ mb_ptr_adv(p); diff --git a/src/os_unix.c b/src/os_unix.c index 27ee65e2..36872ad0 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4092,6 +4092,9 @@ mch_call_shell(cmd, options) int fromshell_fd; garray_T ga; int noread_cnt; +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + struct timeval start_tv; +# endif # ifdef FEAT_GUI if (pty_master_fd >= 0) @@ -4201,7 +4204,9 @@ mch_call_shell(cmd, options) ga_init2(&ga, 1, BUFLEN); noread_cnt = 0; - +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + gettimeofday(&start_tv, NULL); +# endif for (;;) { /* @@ -4214,25 +4219,34 @@ mch_call_shell(cmd, options) * that a typed password is echoed for ssh or gpg command. * Don't get characters when the child has already * finished (wait_pid == 0). - * Don't get extra characters when we already have one. * Don't read characters unless we didn't get output for a - * while, avoids that ":r !ls" eats typeahead. + * while (noread_cnt > 4), avoids that ":r !ls" eats + * typeahead. */ len = 0; if (!(options & SHELL_EXPAND) && ((options & (SHELL_READ|SHELL_WRITE|SHELL_COOKED)) != (SHELL_READ|SHELL_WRITE|SHELL_COOKED) -#ifdef FEAT_GUI +# ifdef FEAT_GUI || gui.in_use -#endif +# endif ) && wait_pid == 0 - && (ta_len > 0 - || (noread_cnt > 4 - && (len = ui_inchar(ta_buf, - BUFLEN, 10L, 0)) > 0))) + && (ta_len > 0 || noread_cnt > 4)) { + if (ta_len == 0) + { + /* Get extra characters when we don't have any. + * Reset the counter and timer. */ + noread_cnt = 0; +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + gettimeofday(&start_tv, NULL); +# endif + len = ui_inchar(ta_buf, BUFLEN, 10L, 0); + } + if (ta_len > 0 || len > 0) + { /* * For pipes: * Check for CTRL-C: send interrupt signal to child. @@ -4334,9 +4348,9 @@ mch_call_shell(cmd, options) { ta_len -= len; mch_memmove(ta_buf, ta_buf + len, ta_len); - noread_cnt = 0; } } + } } if (got_int) @@ -4444,6 +4458,25 @@ mch_call_shell(cmd, options) out_flush(); if (got_int) break; + +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H) + { + struct timeval now_tv; + long msec; + + /* Avoid that we keep looping here without + * checking for a CTRL-C for a long time. Don't + * break out too often to avoid losing typeahead. */ + gettimeofday(&now_tv, NULL); + msec = (now_tv.tv_sec - start_tv.tv_sec) * 1000L + + (now_tv.tv_usec - start_tv.tv_usec) / 1000L; + if (msec > 2000) + { + noread_cnt = 5; + break; + } + } +# endif } /* If we already detected the child has finished break the diff --git a/src/proto/option.pro b/src/proto/option.pro index bb50ef14..39ee7be2 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -44,6 +44,7 @@ void set_imsearch_global __ARGS((void)); void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags)); int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)); int ExpandOldSetting __ARGS((int *num_file, char_u ***file)); +int langmap_adjust_mb __ARGS((int c)); int has_format_option __ARGS((int x)); int shortmess __ARGS((int x)); void vimrc_found __ARGS((char_u *fname, char_u *envname)); diff --git a/src/quickfix.c b/src/quickfix.c index 5c3ae381..ee841602 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -1419,6 +1419,7 @@ qf_jump(qi, dir, errornr, forceit) int opened_window = FALSE; win_T *win; win_T *altwin; + int flags; #endif win_T *oldwin = curwin; int print_message = TRUE; @@ -1531,7 +1532,6 @@ qf_jump(qi, dir, errornr, forceit) if (qf_ptr->qf_type == 1 && (!curwin->w_buffer->b_help || cmdmod.tab != 0)) { win_T *wp; - int n; if (cmdmod.tab != 0) wp = NULL; @@ -1547,13 +1547,16 @@ qf_jump(qi, dir, errornr, forceit) * Split off help window; put it at far top if no position * specified, the current window is vertically split and narrow. */ - n = WSP_HELP; + flags = WSP_HELP; # ifdef FEAT_VERTSPLIT if (cmdmod.split == 0 && curwin->w_width != Columns && curwin->w_width < 80) - n |= WSP_TOP; + flags |= WSP_TOP; # endif - if (win_split(0, n) == FAIL) + if (qi != &ql_info) + flags |= WSP_NEWLOC; /* don't copy the location list */ + + if (win_split(0, flags) == FAIL) goto theend; opened_window = TRUE; /* close it when fail */ @@ -1563,7 +1566,6 @@ qf_jump(qi, dir, errornr, forceit) if (qi != &ql_info) /* not a quickfix list */ { /* The new window should use the supplied location list */ - qf_free_all(curwin); curwin->w_llist = qi; qi->qf_refcount++; } @@ -1610,10 +1612,11 @@ qf_jump(qi, dir, errornr, forceit) { goto_tabpage_win(tp, wp); usable_win = 1; - break; + goto win_found; } } } +win_found: /* * If there is only one window and it is the quickfix window, create a @@ -1623,7 +1626,10 @@ qf_jump(qi, dir, errornr, forceit) { ll_ref = curwin->w_llist_ref; - if (win_split(0, WSP_ABOVE) == FAIL) + flags = WSP_ABOVE; + if (ll_ref != NULL) + flags |= WSP_NEWLOC; + if (win_split(0, flags) == FAIL) goto failed; /* not enough room for window */ opened_window = TRUE; /* close it when fail */ p_swb = empty_option; /* don't split again */ @@ -1635,7 +1641,6 @@ qf_jump(qi, dir, errornr, forceit) { /* The new window should use the location list from the * location list window */ - qf_free_all(curwin); curwin->w_llist = ll_ref; ll_ref->qf_refcount++; } @@ -2310,15 +2315,12 @@ ex_copen(eap) if (eap->cmdidx == CMD_copen || eap->cmdidx == CMD_cwindow) /* Create the new window at the very bottom. */ win_goto(lastwin); - if (win_split(height, WSP_BELOW) == FAIL) + if (win_split(height, WSP_BELOW | WSP_NEWLOC) == FAIL) return; /* not enough room for window */ #ifdef FEAT_SCROLLBIND curwin->w_p_scb = FALSE; #endif - /* Remove the location list for the quickfix window */ - qf_free_all(curwin); - if (eap->cmdidx == CMD_lopen || eap->cmdidx == CMD_lwindow) { /* diff --git a/src/regexp.c b/src/regexp.c index ac60c695..00df12d5 100644 --- a/src/regexp.c +++ b/src/regexp.c @@ -4532,7 +4532,7 @@ regmatch(scan) cleanup_subexpr(); if (!REG_MULTI) /* Single-line regexp */ { - if (reg_endp[no] == NULL) + if (reg_startp[no] == NULL || reg_endp[no] == NULL) { /* Backref was not set: Match an empty string. */ len = 0; @@ -4548,7 +4548,7 @@ regmatch(scan) } else /* Multi-line regexp */ { - if (reg_endpos[no].lnum < 0) + if (reg_startpos[no].lnum < 0 || reg_endpos[no].lnum < 0) { /* Backref was not set: Match an empty string. */ len = 0; @@ -7279,13 +7279,11 @@ reg_submatch(no) } else { - if (submatch_match->endp[no] == NULL) + s = submatch_match->startp[no]; + if (s == NULL || submatch_match->endp[no] == NULL) retval = NULL; else - { - s = submatch_match->startp[no]; retval = vim_strnsave(s, (int)(submatch_match->endp[no] - s)); - } } return retval; diff --git a/src/screen.c b/src/screen.c index 684c3942..6d408eb9 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2596,6 +2596,7 @@ win_line(wp, lnum, startrow, endrow, nochange) int noinvcur = FALSE; /* don't invert the cursor */ #ifdef FEAT_VISUAL pos_T *top, *bot; + int lnum_in_visual_area = FALSE; #endif pos_T pos; long v; @@ -2792,9 +2793,10 @@ win_line(wp, lnum, startrow, endrow, nochange) top = &VIsual; bot = &curwin->w_cursor; } + lnum_in_visual_area = (lnum >= top->lnum && lnum <= bot->lnum); if (VIsual_mode == Ctrl_V) /* block mode */ { - if (lnum >= top->lnum && lnum <= bot->lnum) + if (lnum_in_visual_area) { fromcol = wp->w_old_cursor_fcol; tocol = wp->w_old_cursor_lcol; @@ -3420,6 +3422,7 @@ win_line(wp, lnum, startrow, endrow, nochange) && (*mb_ptr2cells)(ptr) > 1) #endif || ((int)vcol_prev == fromcol_prev + && vcol_prev < vcol /* not at margin */ && vcol < tocol)) area_attr = attr; /* start highlighting */ else if (area_attr != 0 @@ -4557,7 +4560,8 @@ win_line(wp, lnum, startrow, endrow, nochange) * highlight the cursor position itself. */ if (wp->w_p_cuc && vcol == (long)wp->w_virtcol && lnum != wp->w_cursor.lnum - && draw_state == WL_LINE) + && draw_state == WL_LINE + && !lnum_in_visual_area) { vcol_save_attr = char_attr; char_attr = hl_combine_attr(char_attr, hl_attr(HLF_CUC)); @@ -6358,7 +6362,7 @@ screen_puts_len(text, len, row, col, attr) && c == 0x8e && ScreenLines2[off] != ptr[1]) || (enc_utf8 - && (ScreenLinesUC[off] != (u8char_T)u8c + && (ScreenLinesUC[off] != (u8char_T)(c >= 0x80 ? u8c : 0) || screen_comp_differs(off, u8cc))) #endif || ScreenAttrs[off] != attr @@ -7364,7 +7368,11 @@ screenalloc(clear) #endif static int entered = FALSE; /* avoid recursiveness */ static int done_outofmem_msg = FALSE; /* did outofmem message */ +#ifdef FEAT_AUTOCMD + int retry_count = 0; +retry: +#endif /* * Allocation of the screen buffers is done only when the size changes and * when Rows and Columns have been set and we have started doing full @@ -7448,10 +7456,13 @@ screenalloc(clear) { outofmem = TRUE; #ifdef FEAT_WINDOWS - break; + goto give_up; #endif } } +#ifdef FEAT_WINDOWS +give_up: +#endif #ifdef FEAT_MBYTE for (i = 0; i < p_mco; ++i) @@ -7636,8 +7647,17 @@ screenalloc(clear) --RedrawingDisabled; #ifdef FEAT_AUTOCMD - if (starting == 0) + /* + * Do not apply autocommands more than 3 times to avoid an endless loop + * in case applying autocommands always changes Rows or Columns. + */ + if (starting == 0 && ++retry_count <= 3) + { apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf); + /* In rare cases, autocommands may have altered Rows or Columns, + * jump back to check if we need to allocate the screen again. */ + goto retry; + } #endif } diff --git a/src/tag.c b/src/tag.c index 8c36ec3f..391b1068 100644 --- a/src/tag.c +++ b/src/tag.c @@ -618,7 +618,7 @@ do_tag(tag, type, count, forceit, verbose) taglen_advance(taglen); MSG_PUTS_ATTR(_("file\n"), hl_attr(HLF_T)); - for (i = 0; i < num_matches; ++i) + for (i = 0; i < num_matches && !got_int; ++i) { parse_match(matches[i], &tagp); if (!new_tag && ( @@ -655,6 +655,8 @@ do_tag(tag, type, count, forceit, verbose) } if (msg_col > 0) msg_putchar('\n'); + if (got_int) + break; msg_advance(15); /* print any extra fields */ @@ -689,6 +691,8 @@ do_tag(tag, type, count, forceit, verbose) if (msg_col + ptr2cells(p) >= Columns) { msg_putchar('\n'); + if (got_int) + break; msg_advance(15); } p = msg_outtrans_one(p, attr); @@ -704,6 +708,8 @@ do_tag(tag, type, count, forceit, verbose) if (msg_col > 15) { msg_putchar('\n'); + if (got_int) + break; msg_advance(15); } } @@ -734,6 +740,8 @@ do_tag(tag, type, count, forceit, verbose) { if (msg_col + (*p == TAB ? 1 : ptr2cells(p)) > Columns) msg_putchar('\n'); + if (got_int) + break; msg_advance(15); /* skip backslash used for escaping command char */ @@ -760,12 +768,9 @@ do_tag(tag, type, count, forceit, verbose) if (msg_col) msg_putchar('\n'); ui_breakcheck(); - if (got_int) - { - got_int = FALSE; /* only stop the listing */ - break; - } } + if (got_int) + got_int = FALSE; /* only stop the listing */ ask_for_selection = TRUE; } #if defined(FEAT_QUICKFIX) && defined(FEAT_EVAL) @@ -2542,6 +2547,15 @@ free_tag_stuff() { ga_clear_strings(&tag_fnames); do_tag(NULL, DT_FREE, 0, 0, 0); + tag_freematch(); + +# if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) + if (ptag_entry.tagname) + { + vim_free(ptag_entry.tagname); + ptag_entry.tagname = NULL; + } +# endif } #endif diff --git a/src/version.c b/src/version.c index 7a837886..b56d5df1 100644 --- a/src/version.c +++ b/src/version.c @@ -677,6 +677,38 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 124, +/**/ + 123, +/**/ + 122, +/**/ + 121, +/**/ + 120, +/**/ + 119, +/**/ + 118, +/**/ + 117, +/**/ + 116, +/**/ + 115, +/**/ + 114, +/**/ + 113, +/**/ + 112, +/**/ + 111, +/**/ + 110, +/**/ + 109, +/**/ 108, /**/ 107, diff --git a/src/vim.h b/src/vim.h index 0a979e4e..e8a623ea 100644 --- a/src/vim.h +++ b/src/vim.h @@ -1057,6 +1057,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname); #define WSP_HELP 16 /* creating the help window */ #define WSP_BELOW 32 /* put new window below/right */ #define WSP_ABOVE 64 /* put new window above/left */ +#define WSP_NEWLOC 128 /* don't copy location list */ /* * arguments for gui_set_shellsize() diff --git a/src/window.c b/src/window.c index b360f54e..81caee93 100644 --- a/src/window.c +++ b/src/window.c @@ -12,7 +12,7 @@ static int path_is_url __ARGS((char_u *p)); #if defined(FEAT_WINDOWS) || defined(PROTO) static int win_split_ins __ARGS((int size, int flags, win_T *newwin, int dir)); -static void win_init __ARGS((win_T *newp, win_T *oldp)); +static void win_init __ARGS((win_T *newp, win_T *oldp, int flags)); static void frame_comp_pos __ARGS((frame_T *topfrp, int *row, int *col)); static void frame_setheight __ARGS((frame_T *curfrp, int height)); #ifdef FEAT_VERTSPLIT @@ -594,9 +594,7 @@ wingotofile: ++allow_keys; /* no mapping for xchar, but allow key codes */ if (xchar == NUL) xchar = plain_vgetc(); -#ifdef FEAT_LANGMAP LANGMAP_ADJUST(xchar, TRUE); -#endif --no_mapping; --allow_keys; #ifdef FEAT_CMDL_INFO @@ -913,7 +911,7 @@ win_split_ins(size, flags, newwin, dir) return FAIL; /* make the contents of the new window the same as the current one */ - win_init(wp, curwin); + win_init(wp, curwin, flags); } /* @@ -1162,11 +1160,15 @@ win_split_ins(size, flags, newwin, dir) * Initialize window "newp" from window "oldp". * Used when splitting a window and when creating a new tab page. * The windows will both edit the same buffer. + * WSP_NEWLOC may be specified in flags to prevent the location list from + * being copied. */ +/*ARGSUSED*/ static void -win_init(newp, oldp) +win_init(newp, oldp, flags) win_T *newp; win_T *oldp; + int flags; { int i; @@ -1191,7 +1193,14 @@ win_init(newp, oldp) copy_jumplist(oldp, newp); #endif #ifdef FEAT_QUICKFIX - copy_loclist(oldp, newp); + if (flags & WSP_NEWLOC) + { + /* Don't copy the location list. */ + newp->w_llist = NULL; + newp->w_llist_ref = NULL; + } + else + copy_loclist(oldp, newp); #endif if (oldp->w_localdir != NULL) newp->w_localdir = vim_strsave(oldp->w_localdir); @@ -3221,7 +3230,7 @@ win_alloc_firstwin(oldwin) else { /* First window in new tab page, initialize it from "oldwin". */ - win_init(curwin, oldwin); + win_init(curwin, oldwin, 0); # ifdef FEAT_SCROLLBIND /* We don't want scroll-binding in the first window. */ -- 2.11.4.GIT