To: vim-dev@vim.org Subject: Patch 6.2.299 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.299 Problem: Can only use one language for help files. Solution: Add the 'helplang' option to select the preferred language(s). Make ":helptags" generate tags files for all languages. Files: runtime/doc/options.txt, runtime/doc/various.txt, src/Makefile, src/ex_cmds.c, src/ex_cmds2.c, src/ex_cmds.h, src/ex_getln.c, src/normal.c, src/option.c, src/option.h, src/proto/ex_cmds.pro, src/proto/ex_cmds2.pro, src/proto/option.pro, src/structs.h, src/tag.c, src/vim.h *** ../vim-6.2.298/runtime/doc/options.txt Sun Jan 25 20:42:15 2004 --- runtime/doc/options.txt Tue Feb 24 19:52:50 2004 *************** *** 1,4 **** ! *options.txt* For Vim version 6.2. Last change: 2004 Jan 22 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *options.txt* For Vim version 6.2. Last change: 2004 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 2991,2996 **** --- 3008,3032 ---- windows. When the height is less than 'helpheight', the height is set to 'helpheight'. Set to zero to disable. + *'helplang'* *'hlg'* + 'helplang' 'hlg' string (default: messages language or emtpy) + global + {only available when compiled with the |+multi_lang| + feature} + {not in Vi} + Comma separated list of languages. Vim will use the first language + for which the desired help can be found. The English help will always + be used as a last resort. You can add "en" to prefer English over + another language, but that will only find tags that exist in that + language and not in the English help. + Example: > + :set helplang=de,it + < This will first search German, then Italian and finally English help + files. + When using |CTRL-]| and ":help!" in a non-English help file Vim will + try to find the tag in the current language before using this option. + See |help-translated|. + *'hidden'* *'hid'* *'nohidden'* *'nohid'* 'hidden' 'hid' boolean (default off) global *** ../vim-6.2.298/runtime/doc/various.txt Sun Jan 25 19:32:46 2004 --- runtime/doc/various.txt Tue Feb 24 19:53:44 2004 *************** *** 1,4 **** ! *various.txt* For Vim version 6.2. Last change: 2004 Jan 21 VIM REFERENCE MANUAL by Bram Moolenaar --- 1,4 ---- ! *various.txt* For Vim version 6.2. Last change: 2004 Feb 24 VIM REFERENCE MANUAL by Bram Moolenaar *************** *** 507,515 **** wide, the help window will appear just above the current window. Otherwise the new window is put at the very top. {not in Vi} ! *{subject}* *E149* :h[elp] {subject} Like ":help", additionally jump to the tag {subject}. {subject} can include wildcards like "*", "?" and "[a-z]": --- 507,517 ---- wide, the help window will appear just above the current window. Otherwise the new window is put at the very top. + The 'helplang' option is used to select a language, if + the main help file is available in several languages. {not in Vi} ! *{subject}* *E149* *E661* :h[elp] {subject} Like ":help", additionally jump to the tag {subject}. {subject} can include wildcards like "*", "?" and "[a-z]": *************** *** 529,534 **** --- 531,543 ---- better than a match further on. - The more alphanumeric characters match, the better. - The shorter the length of the match, the better. + + The 'helplang' option is used to select a language, if + the {subject} is available in several languages. + To find a tag in a specific language, append '@ab", + where "ab" is the two-letter language code. See + |help-translated|. + Note that the longer the {subject} you give, the less matches will be found. You can get an idea how this all works by using commandline completion (type CTRL-D *************** *** 554,559 **** --- 563,572 ---- :help soonly < {not in Vi} + :h[elp]! [subject] Like ":help", but in non-English help files prefer to + find a tag in a file with the same language as the + current file. See |help-translated|. + *:helpg* *:helpgrep* :helpg[rep] {pattern} Search all help text files and make a list of lines *************** *** 610,632 **** *help-xterm-window* If you want to have the help in another xterm window, you could use this ! command: :!xterm -e vim +help & ! *:helpfind* *:helpf* :helpf[ind] Like |:help|, but use a dialog to enter the argument. ! Only for backwards compatibilty. It now executes the ! ToolBar.HelpFind menu entry instead of using a builtin dialog. {only when compiled with |+GUI_GTK|} ! *:helpt* *:helptags* *E154* *E150* *E151* *E152* *E153* ! :helpt[ags] {dir} Generate the help tags file for directory {dir}. All ! "*.txt" files in the directory are scanned for a help ! tag definition in between stars. The generated tags ! file is sorted. When there are duplicates an error ! message is given. An existing tags file is silently ! overwritten. ============================================================================== 3. Printing *printing* --- 623,702 ---- *help-xterm-window* If you want to have the help in another xterm window, you could use this ! command: > :!xterm -e vim +help & ! < *:helpfind* *:helpf* :helpf[ind] Like |:help|, but use a dialog to enter the argument. ! Only for backwards compatibility. It now executes the ! ToolBar.FindHelp menu entry instead of using a builtin dialog. {only when compiled with |+GUI_GTK|} ! *:helpt* *:helptags* ! *E154* *E150* *E151* *E152* *E153* ! :helpt[ags] {dir} Generate the help tags file(s) for directory {dir}. ! All "*.txt" and "*.??x" files in the directory are ! scanned for a help tag definition in between stars. ! The "*.??x" files are for translated docs, they ! generate the "tags-??" file, see |help-translated|. ! The generated tags files are sorted. ! When there are duplicates an error message is given. ! An existing tags file is silently overwritten. ! To rebuild the help tags in the runtime directory ! (requires write permission there): > ! :helptags $VIMRUNTIME/doc ! ! ! TRANSLATED HELP *help-translated* ! ! It is possible to add translated help files, next to the original English help ! files. Vim will search for all help in "doc" directories in 'runtimepath'. ! This is only available when compiled with the |+multi_lang| feature. ! ! A set of translated help files consists of these files: ! ! help.abx ! howto.abx ! ... ! tags-ab ! ! "ab" is the two-letter language code. Thus for Italian the names are: ! ! help.itx ! howto.itx ! ... ! tags-it ! ! The 'helplang' option can be set to the preferred language(s). The default is ! set according to the environment. Vim will first try to find a matching tag ! in the preferred language(s). English is used when it cannot be found. ! ! To find a tag in a specific language, append "@ab" to a tag, where "ab" is the ! two-letter language code. Example: > ! :he user-manual@it ! :he user-manual@en ! The first one finds the Italian user manual, even when 'helplang' is empty. ! The second one finds the English user manual, even when 'helplang' is set to ! "it". ! ! When using command-line completion for the ":help" command, the "@en" ! extention is only shown when a tag exists for multiple languages. When the ! tag only exists for English "@en" is omitted. ! ! When using |CTRL-]| or ":help!" in a non-English help file Vim will try to ! find the tag in the same language. If not found then 'helplang' will be used ! to select a language. ! ! Hints for translators: ! - Do not translate the tags. This makes it possible to use 'helplang' to ! specify the preferred language. ! - When you do not translate a part of a file, add tags to the English version, ! using the "tag@en" notation. ! - Make a package with all the files and the tags file available for download. ! Users can drop it in one of the "doc" directories and start use it. ! - Use the |:helptags| command to generate the tags files. It will find all ! languages in the specified directory. ============================================================================== 3. Printing *printing* *** ../vim-6.2.298/src/Makefile Thu Feb 19 14:48:06 2004 --- src/Makefile Sat Feb 28 17:09:19 2004 *************** *** 1654,1662 **** $(HELPSOURCE)/evim.1 > $(DEST_MAN)/$(EVIMNAME).1 chmod $(MANMOD) $(DEST_MAN)/$(EVIMNAME).1 @echo generating help tags ! -@cd $(HELPSOURCE); $(MAKE) tags ! cd $(HELPSOURCE); $(INSTALL_DATA) *.txt tags $(DEST_HELP) ! cd $(DEST_HELP); chmod $(HELPMOD) *.txt tags $(INSTALL_DATA) $(HELPSOURCE)/*.pl $(DEST_HELP) chmod $(SCRIPTMOD) $(DEST_HELP)/*.pl # install the menu files --- 1664,1676 ---- $(HELPSOURCE)/evim.1 > $(DEST_MAN)/$(EVIMNAME).1 chmod $(MANMOD) $(DEST_MAN)/$(EVIMNAME).1 @echo generating help tags ! # Generate the help tags with ":helptags" to handle all languages. ! -@cd $(HELPSOURCE); VIMEXE=$(VIMTARGET) $(MAKE) vimtags ! cd $(HELPSOURCE); \ ! files=`ls *.txt *.??x tags tags-??`; \ ! $(INSTALL_DATA) $$files $(DEST_HELP); \ ! cd $(DEST_HELP); \ ! chmod $(HELPMOD) $$files $(INSTALL_DATA) $(HELPSOURCE)/*.pl $(DEST_HELP) chmod $(SCRIPTMOD) $(DEST_HELP)/*.pl # install the menu files *************** *** 1932,1937 **** --- 1946,1952 ---- # Note: the "rmdir" will fail if any files were added after "make install" uninstall_runtime: -rm -f $(DEST_HELP)/*.txt $(DEST_HELP)/tags $(DEST_HELP)/*.pl + -rm -f $(DEST_HELP)/*.??x $(DEST_HELP)/tags-?? -rm -f $(SYS_MENU_FILE) $(SYS_SYNMENU_FILE) $(SYS_DELMENU_FILE) -rm -f $(SYS_BUGR_FILE) $(EVIM_FILE) $(MSWIN_FILE) -rm -f $(DEST_SCRIPT)/gvimrc_example.vim $(DEST_SCRIPT)/vimrc_example.vim *** ../vim-6.2.298/src/ex_cmds.c Fri Feb 20 22:08:18 2004 --- src/ex_cmds.c Sun Feb 29 17:06:24 2004 *************** *** 4533,4550 **** exarg_T *eap; { char_u *arg; FILE *helpfd; /* file descriptor of help file */ int n; #ifdef FEAT_WINDOWS win_T *wp; #endif int num_matches; char_u **matches; - int need_free = FALSE; char_u *p; int empty_fnum = 0; int alt_fnum = 0; buf_T *buf; if (eap != NULL) { --- 4533,4555 ---- exarg_T *eap; { char_u *arg; + char_u *tag; FILE *helpfd; /* file descriptor of help file */ int n; + int i; #ifdef FEAT_WINDOWS win_T *wp; #endif int num_matches; char_u **matches; char_u *p; int empty_fnum = 0; int alt_fnum = 0; buf_T *buf; + #ifdef FEAT_MULTI_LANG + int len; + char_u *lang = NULL; + #endif if (eap != NULL) { *************** *** 4564,4598 **** } arg = eap->arg; if (eap->skip) /* not executing commands */ return; } else arg = (char_u *)""; /* ! * If an argument is given, check if there is a match for it. */ ! if (*arg != NUL) ! { ! /* remove trailing blanks */ ! p = arg + STRLEN(arg) - 1; ! while (p > arg && vim_iswhite(*p) && p[-1] != '\\') ! *p-- = NUL; ! n = find_help_tags(arg, &num_matches, &matches); ! if (num_matches == 0 || n == FAIL) ! { ! EMSG2(_("E149: Sorry, no help for %s"), arg); ! return; } ! ! /* The first match is the best match. */ ! arg = vim_strsave(matches[0]); ! need_free = TRUE; ! FreeWild(num_matches, matches); } #ifdef FEAT_GUI need_mouse_correct = TRUE; #endif --- 4569,4639 ---- } arg = eap->arg; + if (eap->forceit && *arg == NUL) + { + EMSG(_("E478: Don't panic!")); + return; + } + if (eap->skip) /* not executing commands */ return; } else arg = (char_u *)""; + /* remove trailing blanks */ + p = arg + STRLEN(arg) - 1; + while (p > arg && vim_iswhite(*p) && p[-1] != '\\') + *p-- = NUL; + + #ifdef FEAT_MULTI_LANG + /* Check for a specified language */ + len = STRLEN(arg); + if (len >= 3 && arg[len - 3] == '@' && ASCII_ISALPHA(arg[len - 2]) + && ASCII_ISALPHA(arg[len - 1])) + { + lang = arg + len - 2; + lang[-1] = NUL; /* remove the '@' */ + } + #endif + + /* When no argument given go to the index. */ + if (*arg == NUL) + arg = (char_u *)"help.txt"; + /* ! * Check if there is a match for the argument. */ ! n = find_help_tags(arg, &num_matches, &matches, ! eap != NULL && eap->forceit); ! i = 0; ! #ifdef FEAT_MULTI_LANG ! if (n != FAIL && lang != NULL) ! /* Find first item with the requested language. */ ! for (i = 0; i < num_matches; ++i) ! { ! len = STRLEN(matches[i]); ! if (len > 3 && matches[i][len - 3] == '@' ! && STRICMP(matches[i] + len - 2, lang) == 0) ! break; } ! #endif ! if (i >= num_matches || n == FAIL) ! { ! #ifdef FEAT_MULTI_LANG ! if (lang != NULL) ! EMSG3(_("E661: Sorry, no '%s' help for %s"), lang, arg); ! else ! #endif ! EMSG2(_("E149: Sorry, no help for %s"), arg); ! return; } + /* The first match (in the requested language) is the best match. */ + tag = vim_strsave(matches[i]); + FreeWild(num_matches, matches); + #ifdef FEAT_GUI need_mouse_correct = TRUE; #endif *************** *** 4660,4671 **** if (!p_im) restart_edit = 0; /* don't want insert mode in help file */ ! if (arg == NULL || *arg == NUL) ! { ! arg = (char_u *)"help.txt"; /* go to the index */ ! need_free = FALSE; ! } ! do_tag(arg, DT_HELP, 1, FALSE, TRUE); /* Delete the empty buffer if we're not using it. */ if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum) --- 4701,4708 ---- if (!p_im) restart_edit = 0; /* don't want insert mode in help file */ ! if (tag != NULL) ! do_tag(tag, DT_HELP, 1, FALSE, TRUE); /* Delete the empty buffer if we're not using it. */ if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum) *************** *** 4680,4687 **** curwin->w_alt_fnum = alt_fnum; erret: ! if (need_free) ! vim_free(arg); } --- 4717,4723 ---- curwin->w_alt_fnum = alt_fnum; erret: ! vim_free(tag); } *************** *** 4757,4768 **** * Find all help tags matching "arg", sort them and return in matches[], with * the number of matches in num_matches. * The matches will be sorted with a "best" match algorithm. */ int ! find_help_tags(arg, num_matches, matches) char_u *arg; int *num_matches; char_u ***matches; { char_u *s, *d; int i; --- 4793,4806 ---- * Find all help tags matching "arg", sort them and return in matches[], with * the number of matches in num_matches. * The matches will be sorted with a "best" match algorithm. + * When "keep_lang" is TRUE try keeping the language of the current buffer. */ int ! find_help_tags(arg, num_matches, matches, keep_lang) char_u *arg; int *num_matches; char_u ***matches; + int keep_lang; { char_u *s, *d; int i; *************** *** 4778,4783 **** --- 4816,4822 ---- "/\\\\?", "/\\\\z(\\\\)", "\\[count]", "\\[quotex]", "\\[range]", "\\[pattern]", "\\\\bar", "/\\\\%\\$"}; + int flags; d = IObuff; /* assume IObuff is long enough! */ *************** *** 4909,4923 **** *matches = (char_u **)""; *num_matches = 0; ! if (find_tags(IObuff, num_matches, matches, ! TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE, (int)MAXCOL) == OK) ! /* ! * Sort the matches found on the heuristic number that is after the ! * tag name. ! */ qsort((void *)*matches, (size_t)*num_matches, ! sizeof(char_u *), help_compare) ! ; return OK; } --- 4948,4962 ---- *matches = (char_u **)""; *num_matches = 0; ! flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE; ! if (keep_lang) ! flags |= TAG_KEEP_LANG; ! if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL) == OK ! && *num_matches > 0) ! /* Sort the matches found on the heuristic number that is after the ! * tag name. */ qsort((void *)*matches, (size_t)*num_matches, ! sizeof(char_u *), help_compare); return OK; } *************** *** 5081,5086 **** --- 5120,5127 ---- } #if defined(FEAT_EX_EXTRA) || defined(PROTO) + static void helptags_one __ARGS((char_u *dir, char_u *ext, char_u *lang)); + /* * ":helptags" */ *************** *** 5088,5093 **** --- 5129,5243 ---- ex_helptags(eap) exarg_T *eap; { + garray_T ga; + int i, j; + int len; + char_u lang[2]; + char_u ext[5]; + char_u fname[8]; + int filecount; + char_u **files; + + if (!mch_isdir(eap->arg)) + { + EMSG2(_("E150: Not a directory: %s"), eap->arg); + return; + } + + #ifdef FEAT_MULTI_LANG + /* Get a list of all files in the directory. */ + STRCPY(NameBuff, eap->arg); + add_pathsep(NameBuff); + STRCAT(NameBuff, "*"); + if (gen_expand_wildcards(1, &NameBuff, &filecount, &files, + EW_FILE|EW_SILENT) == FAIL + || filecount == 0) + { + EMSG2("E151: No match: %s", NameBuff); + return; + } + + /* Go over all files in the directory to find out what languages are + * present. */ + ga_init2(&ga, 1, 10); + for (i = 0; i < filecount; ++i) + { + len = STRLEN(files[i]); + if (len > 4) + { + if (STRICMP(files[i] + len - 4, ".txt") == 0) + { + /* ".txt" -> language "en" */ + lang[0] = 'e'; + lang[1] = 'n'; + } + else if (files[i][len - 4] == '.' + && ASCII_ISALPHA(files[i][len - 3]) + && ASCII_ISALPHA(files[i][len - 2]) + && TOLOWER_ASC(files[i][len - 1]) == 'x') + { + /* ".abx" -> language "ab" */ + lang[0] = TOLOWER_ASC(files[i][len - 3]); + lang[1] = TOLOWER_ASC(files[i][len - 2]); + } + else + continue; + + /* Did we find this language already? */ + for (j = 0; j < ga.ga_len; j += 2) + if (STRNCMP(lang, ((char_u *)ga.ga_data) + j, 2) == 0) + break; + if (j == ga.ga_len) + { + /* New language, add it. */ + if (ga_grow(&ga, 2) == FAIL) + break; + ((char_u *)ga.ga_data)[ga.ga_len++] = lang[0]; + ((char_u *)ga.ga_data)[ga.ga_len++] = lang[1]; + ga.ga_room -= 2; + } + } + } + + /* + * Loop over the found languages to generate a tags file for each one. + */ + for (j = 0; j < ga.ga_len; j += 2) + { + STRCPY(fname, "tags-xx"); + fname[5] = ((char_u *)ga.ga_data)[j]; + fname[6] = ((char_u *)ga.ga_data)[j + 1]; + if (fname[5] == 'e' && fname[6] == 'n') + { + /* English is an exception: use ".txt" and "tags". */ + fname[4] = NUL; + STRCPY(ext, ".txt"); + } + else + { + /* Language "ab" uses ".abx" and "tags-ab". */ + STRCPY(ext, ".xxx"); + ext[1] = fname[5]; + ext[2] = fname[6]; + } + helptags_one(eap->arg, ext, fname); + } + + ga_clear(&ga); + FreeWild(filecount, files); + + #else + /* No language support, just use "*.txt" and "tags". */ + helptags_one(eap->arg, (char_u *)".txt", (char_u *)"tags"); + #endif + } + + static void + helptags_one(dir, ext, tagfname) + char_u *dir; /* doc directory */ + char_u *ext; /* suffix, ".txt", ".itx", ".frx", etc. */ + char_u *tagfname; /* "tags" for English, "tags-it" for Italian. */ + { FILE *fd_tags; FILE *fd; garray_T ga; *************** *** 5099,5116 **** int i; char_u *fname; - if (!mch_isdir(eap->arg)) - { - EMSG2(_("E150: Not a directory: %s"), eap->arg); - return; - } - /* * Find all *.txt files. */ ! STRCPY(NameBuff, eap->arg); add_pathsep(NameBuff); ! STRCAT(NameBuff, "*.txt"); if (gen_expand_wildcards(1, &NameBuff, &filecount, &files, EW_FILE|EW_SILENT) == FAIL || filecount == 0) --- 5249,5261 ---- int i; char_u *fname; /* * Find all *.txt files. */ ! STRCPY(NameBuff, dir); add_pathsep(NameBuff); ! STRCAT(NameBuff, "*"); ! STRCAT(NameBuff, ext); if (gen_expand_wildcards(1, &NameBuff, &filecount, &files, EW_FILE|EW_SILENT) == FAIL || filecount == 0) *************** *** 5123,5131 **** * Open the tags file for writing. * Do this before scanning through all the files. */ ! STRCPY(NameBuff, eap->arg); add_pathsep(NameBuff); ! STRCAT(NameBuff, "tags"); fd_tags = fopen((char *)NameBuff, "w"); if (fd_tags == NULL) { --- 5268,5276 ---- * Open the tags file for writing. * Do this before scanning through all the files. */ ! STRCPY(NameBuff, dir); add_pathsep(NameBuff); ! STRCAT(NameBuff, tagfname); fd_tags = fopen((char *)NameBuff, "w"); if (fd_tags == NULL) { *************** *** 5138,5154 **** * If generating tags for "$VIMRUNTIME/doc" add the "help-tags" tag. */ ga_init2(&ga, (int)sizeof(char_u *), 100); ! if (fullpathcmp((char_u *)"$VIMRUNTIME/doc", eap->arg, FALSE) == FPC_SAME) { if (ga_grow(&ga, 1) == FAIL) got_int = TRUE; else { ! s = vim_strsave((char_u *)"help-tags\ttags\t1\n"); if (s == NULL) got_int = TRUE; else { ((char_u **)ga.ga_data)[ga.ga_len] = s; ++ga.ga_len; --ga.ga_room; --- 5283,5300 ---- * If generating tags for "$VIMRUNTIME/doc" add the "help-tags" tag. */ ga_init2(&ga, (int)sizeof(char_u *), 100); ! if (fullpathcmp((char_u *)"$VIMRUNTIME/doc", dir, FALSE) == FPC_SAME) { if (ga_grow(&ga, 1) == FAIL) got_int = TRUE; else { ! s = alloc(30); if (s == NULL) got_int = TRUE; else { + sprintf((char *)s, "help-tags\t%s\t1\n", tagfname); ((char_u **)ga.ga_data)[ga.ga_len] = s; ++ga.ga_len; --ga.ga_room; *************** *** 5260,5266 **** for (i = 0; i < ga.ga_len; ++i) { s = ((char_u **)ga.ga_data)[i]; ! if (STRNCMP(s, "help-tags\t", 10) == 0) /* help-tags entry was added in formatted form */ fprintf(fd_tags, (char *)s); else --- 5406,5412 ---- for (i = 0; i < ga.ga_len; ++i) { s = ((char_u **)ga.ga_data)[i]; ! if (STRNCMP(s, "help-tags", 9) == 0) /* help-tags entry was added in formatted form */ fprintf(fd_tags, (char *)s); else *** ../vim-6.2.298/src/ex_cmds2.c Thu Feb 5 16:04:26 2004 --- src/ex_cmds2.c Wed Feb 25 15:11:43 2004 *************** *** 1863,1869 **** if (p_verbose > 2) msg_str((char_u *)_("Searching for \"%s\""), buf); ! /* Expand wildcards and source each match. */ if (gen_expand_wildcards(1, &buf, &num_files, &files, EW_FILE) == OK) { --- 1863,1869 ---- if (p_verbose > 2) msg_str((char_u *)_("Searching for \"%s\""), buf); ! /* Expand wildcards, invoke the callback for each match. */ if (gen_expand_wildcards(1, &buf, &num_files, &files, EW_FILE) == OK) { *************** *** 5301,5310 **** # endif /*FEAT_POSTSCRIPT*/ #endif /*FEAT_PRINTER*/ ! ! #ifdef FEAT_EVAL ! ! # if defined(HAVE_LOCALE_H) || defined(X_LOCALE) static char *get_locale_val __ARGS((int what)); static char * --- 5301,5308 ---- # endif /*FEAT_POSTSCRIPT*/ #endif /*FEAT_PRINTER*/ ! #if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) \ ! && (defined(FEAT_EVAL) || defined(FEAT_MULTI_LANG)) static char *get_locale_val __ARGS((int what)); static char * *************** *** 5317,5323 **** * redefined and it doesn't use the arguments. */ loc = setlocale(what, NULL); ! # if defined(__BORLANDC__) if (loc != NULL) { char_u *p; --- 5315,5321 ---- * redefined and it doesn't use the arguments. */ loc = setlocale(what, NULL); ! # if defined(__BORLANDC__) if (loc != NULL) { char_u *p; *************** *** 5339,5349 **** } } } ! # endif return loc; } # endif /* * Set the "v:lang" variable according to the current locale setting. --- 5337,5422 ---- } } } ! # endif return loc; } + #endif + + + #ifdef WIN32 + /* + * On MS-Windows locale names are strings like "German_Germany.1252", but + * gettext expects "de". Try to translate one into another here for a few + * supported languages. + */ + static char_u * + gettext_lang(char_u *name) + { + int i; + static char *(mtable[]) = { + "afrikaans", "af", + "czech", "cs", + "dutch", "nl", + "german", "de", + "english_united kingdom", "en_GB", + "spanish", "es", + "french", "fr", + "italian", "it", + "japanese", "ja", + "korean", "ko", + "norwegian", "no", + "polish", "pl", + "russian", "ru", + "slovak", "sk", + "swedish", "sv", + "ukrainian", "uk", + "chinese_china", "zh_CN", + "chinese_taiwan", "zh_TW", + NULL}; + + for (i = 0; mtable[i] != NULL; i += 2) + if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0) + return mtable[i + 1]; + return name; + } + #endif + + #if defined(FEAT_MULTI_LANG) || defined(PROTO) + /* + * Obtain the current messages language. Used to set the default for + * 'helplang'. May return NULL or an empty string. + */ + char_u * + get_mess_lang() + { + char_u *p; + + # if (defined(HAVE_LOCALE_H) || defined(X_LOCALE)) + # if defined(LC_MESSAGES) + p = (char_u *)get_locale_val(LC_MESSAGES); + # else + /* This is necessary for Win32, where LC_MESSAGES is not defined and $LANG + * may be set to the LCID number. */ + p = (char_u *)get_locale_val(LC_ALL); + # endif + # else + p = mch_getenv((char_u *)"LC_ALL"); + if (p == NULL || *p == NUL) + { + p = mch_getenv((char_u *)"LC_MESSAGES"); + if (p == NULL || *p == NUL) + p = mch_getenv((char_u *)"LANG"); + } + # endif + # ifdef WIN32 + p = gettext_lang(p); # endif + return p; + } + #endif + + #if defined(FEAT_EVAL) || defined(PROTO) /* * Set the "v:lang" variable according to the current locale setting. *************** *** 5475,5516 **** vim_setenv((char_u *)"LANG", name); if (what != LC_CTYPE) { #ifdef WIN32 ! char_u *mname = name; ! int i; ! static char *(mtable[]) = { ! "afrikaans", "af", ! "czech", "cs", ! "german", "de", ! "english_united kingdom", "en_gb", ! "spanish", "es", ! "french", "fr", ! "italian", "it", ! "japanese", "ja", ! "korean", "ko", ! "norwegian", "no", ! "polish", "pl", ! "russian", "ru", ! "slovak", "sk", ! "swedish", "sv", ! "ukrainian", "uk", ! "chinese_china", "zh_cn", ! "chinese_taiwan", "zh_tw", ! NULL}; ! ! /* On MS-Windows locale names are strings like ! * "German_Germany.1252", but gettext expects "de". Try ! * to translate one into another here for a few supported ! * languages. */ ! for (i = 0; mtable[i] != NULL; i += 2) ! if (STRNICMP(mtable[i], name, STRLEN(mtable[i])) == 0) ! { ! mname = mtable[i + 1]; ! break; ! } ! vim_setenv((char_u *)"LC_MESSAGES", mname); #else ! vim_setenv((char_u *)"LC_MESSAGES", name); #endif } --- 5548,5562 ---- vim_setenv((char_u *)"LANG", name); if (what != LC_CTYPE) { + char_u *mname; #ifdef WIN32 ! mname = gettext_lang(name); #else ! mname = name; ! #endif ! vim_setenv((char_u *)"LC_MESSAGES", mname); ! #ifdef FEAT_MULTI_LANG ! set_helplang_default(mname); #endif } *** ../vim-6.2.298/src/ex_cmds.h Sun Feb 29 20:46:43 2004 --- src/ex_cmds.h Sun Feb 29 18:12:43 2004 *************** *** 389,395 **** EX(CMD_gvim, "gvim", ex_gui, BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN), EX(CMD_help, "help", ex_help, ! EXTRA|NOTRLCOM), EX(CMD_helpfind, "helpfind", ex_helpfind, EXTRA|NOTRLCOM), EX(CMD_helpgrep, "helpgrep", ex_helpgrep, --- 389,395 ---- EX(CMD_gvim, "gvim", ex_gui, BANG|FILES|EDITCMD|ARGOPT|TRLBAR|CMDWIN), EX(CMD_help, "help", ex_help, ! BANG|EXTRA|NOTRLCOM), EX(CMD_helpfind, "helpfind", ex_helpfind, EXTRA|NOTRLCOM), EX(CMD_helpgrep, "helpgrep", ex_helpgrep, *** ../vim-6.2.298/src/ex_getln.c Sun Feb 29 14:45:49 2004 --- src/ex_getln.c Sat Feb 28 16:33:29 2004 *************** *** 3592,3597 **** --- 3594,3632 ---- return EXPAND_OK; } + #ifdef FEAT_MULTI_LANG + /* + * Cleanup matches for help tags: remove "@en" if "en" is the only language. + */ + static void cleanup_help_tags __ARGS((int num_file, char_u **file)); + + static void + cleanup_help_tags(num_file, file) + int num_file; + char_u **file; + { + int i, j; + int len; + + for (i = 0; i < num_file; ++i) + { + len = (int)STRLEN(file[i]) - 3; + if (len > 0 && STRCMP(file[i] + len, "@en") == 0) + { + /* Sorting on priority means the same item in another language may + * be anywhere. Search all items for a match up to the "@en". */ + for (j = 0; j < num_file; ++j) + if (j != i + && (int)STRLEN(file[j]) == len + 3 + && STRNCMP(file[i], file[j], len + 1) == 0) + break; + if (j == num_file) + file[i][len] = NUL; + } + } + } + #endif + /* * Do the expansion based on xp->xp_context and "pat". */ *************** *** 3660,3666 **** *file = (char_u **)""; *num_file = 0; if (xp->xp_context == EXPAND_HELP) ! return find_help_tags(pat, num_file, file); #ifndef FEAT_CMDL_COMPL return FAIL; --- 3695,3710 ---- *file = (char_u **)""; *num_file = 0; if (xp->xp_context == EXPAND_HELP) ! { ! if (find_help_tags(pat, num_file, file, FALSE) == OK) ! { ! #ifdef FEAT_MULTI_LANG ! cleanup_help_tags(*num_file, *file); ! #endif ! return OK; ! } ! return FAIL; ! } #ifndef FEAT_CMDL_COMPL return FAIL; *** ../vim-6.2.298/src/normal.c Sun Feb 29 20:46:43 2004 --- src/normal.c Sun Feb 29 20:33:32 2004 *************** *** 4880,4886 **** case 'K': if (kp_help) ! STRCPY(buf, ":he "); else { /* When a count is given, turn it into a range. Is this --- 4880,4886 ---- case 'K': if (kp_help) ! STRCPY(buf, "he! "); else { /* When a count is given, turn it into a range. Is this *************** *** 4915,4921 **** default: if (curbuf->b_help) ! STRCPY(buf, "he "); else if (g_cmd) STRCPY(buf, "tj "); else --- 4915,4921 ---- default: if (curbuf->b_help) ! STRCPY(buf, "he! "); else if (g_cmd) STRCPY(buf, "tj "); else *** ../vim-6.2.298/src/option.c Tue Feb 17 20:41:09 2004 --- src/option.c Tue Feb 24 19:48:05 2004 *************** *** 1057,1062 **** --- 1057,1071 ---- (char_u *)NULL, PV_NONE, #endif {(char_u *)20L, (char_u *)0L}}, + {"helplang", "hlg", P_STRING|P_VI_DEF|P_COMMA, + #ifdef FEAT_MULTI_LANG + (char_u *)&p_hlg, PV_NONE, + {(char_u *)"", (char_u *)0L} + #else + (char_u *)NULL, PV_NONE, + {(char_u *)0L, (char_u *)0L} + #endif + }, {"hidden", "hid", P_BOOL|P_VI_DEF, (char_u *)&p_hid, PV_NONE, {(char_u *)FALSE, (char_u *)0L}}, *************** *** 2802,2807 **** --- 2811,2821 ---- } } #endif + + #ifdef FEAT_MULTI_LANG + /* Set the default for 'helplang'. */ + set_helplang_default(get_mess_lang()); + #endif } /* *************** *** 3115,3120 **** --- 3129,3162 ---- #endif } + #if defined(FEAT_MULTI_LANG) || defined(PROTO) + /* + * When 'helplang' is still at its default value, set it to "lang". + * Only the first two characters of "lang" are used. + */ + void + set_helplang_default(lang) + char_u *lang; + { + int idx; + + if (lang == NULL || STRLEN(lang) < 2) /* safety check */ + return; + idx = findoption((char_u *)"hlg"); + if (!(options[idx].flags & P_WAS_SET)) + { + if (options[idx].flags & P_ALLOCED) + free_string_option(p_hlg); + p_hlg = vim_strsave(lang); + if (p_hlg == NULL) + p_hlg = empty_option; + else + p_hlg[2] = NUL; + options[idx].flags |= P_ALLOCED; + } + } + #endif + #ifdef FEAT_GUI static char_u *gui_bg_default __ARGS((void)); *************** *** 4591,4596 **** --- 4633,4656 ---- } } + #ifdef FEAT_MULTI_LANG + /* 'helplang' */ + else if (varp == &p_hlg) + { + /* Check for "", "ab", "ab,cd", etc. */ + for (s = p_hlg; *s != NUL; s += 3) + { + if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL)) + { + errmsg = e_invarg; + break; + } + if (s[2] == NUL) + break; + } + } + #endif + /* 'highlight' */ else if (varp == &p_hl) { *** ../vim-6.2.298/src/option.h Sun Jan 25 20:42:15 2004 --- src/option.h Tue Feb 24 19:47:35 2004 *************** *** 471,476 **** --- 471,479 ---- #ifdef FEAT_WINDOWS EXTERN long p_hh; /* 'helpheight' */ #endif + #ifdef FEAT_MULTI_LANG + EXTERN char_u *p_hlg; /* 'helplang' */ + #endif EXTERN int p_hid; /* 'hidden' */ /* Use P_HID to check if a buffer is to be hidden when it is no longer * visible in a window. */ *** ../vim-6.2.298/src/proto/ex_cmds.pro Sun Jun 1 12:26:07 2003 --- src/proto/ex_cmds.pro Mon Feb 16 17:12:54 2004 *************** *** 39,45 **** void prepare_tagpreview __ARGS((void)); void ex_help __ARGS((exarg_T *eap)); int help_heuristic __ARGS((char_u *matched_string, int offset, int wrong_case)); ! int find_help_tags __ARGS((char_u *arg, int *num_matches, char_u ***matches)); void fix_help_buffer __ARGS((void)); void ex_helptags __ARGS((exarg_T *eap)); void ex_sign __ARGS((exarg_T *eap)); --- 39,45 ---- void prepare_tagpreview __ARGS((void)); void ex_help __ARGS((exarg_T *eap)); int help_heuristic __ARGS((char_u *matched_string, int offset, int wrong_case)); ! int find_help_tags __ARGS((char_u *arg, int *num_matches, char_u ***matches, int keep_lang)); void fix_help_buffer __ARGS((void)); void ex_helptags __ARGS((exarg_T *eap)); void ex_sign __ARGS((exarg_T *eap)); *** ../vim-6.2.298/src/proto/ex_cmds2.pro Thu Feb 5 16:04:26 2004 --- src/proto/ex_cmds2.pro Mon Feb 16 21:04:22 2004 *************** *** 68,73 **** --- 68,74 ---- void mch_print_set_font __ARGS((int iBold, int iItalic, int iUnderline)); void mch_print_set_bg __ARGS((long_u bgcol)); void mch_print_set_fg __ARGS((long_u fgcol)); + char_u *get_mess_lang __ARGS((void)); void set_lang_var __ARGS((void)); void ex_language __ARGS((exarg_T *eap)); char_u *get_lang_arg __ARGS((expand_T *xp, int idx)); *** ../vim-6.2.298/src/proto/option.pro Sun Jun 1 12:26:17 2003 --- src/proto/option.pro Mon Feb 16 20:50:10 2004 *************** *** 4,9 **** --- 4,10 ---- void set_number_default __ARGS((char *name, long val)); void set_init_2 __ARGS((void)); void set_init_3 __ARGS((void)); + void set_helplang_default __ARGS((char_u *lang)); void init_gui_options __ARGS((void)); void set_title_defaults __ARGS((void)); int do_set __ARGS((char_u *arg, int opt_flags)); *** ../vim-6.2.298/src/structs.h Sun Feb 29 20:46:43 2004 --- src/structs.h Sun Feb 29 16:45:20 2004 *************** *** 55,60 **** --- 55,62 ---- void *ga_data; /* pointer to the first item */ } garray_T; + #define GA_EMPTY {0, 0, 0, 0, NULL} + /* * This is here because regexp.h needs pos_T and below regprog_T is used. */ *** ../vim-6.2.298/src/tag.c Wed Feb 11 14:40:25 2004 --- src/tag.c Thu Feb 26 22:06:45 2004 *************** *** 986,995 **** * Tags in an emacs-style tags file are always global. * * flags: ! * TAG_HELP only search for help tags ! * TAG_NAMES only return name of tag ! * TAG_REGEXP use "pat" as a regexp ! * TAG_NOIC don't always ignore case */ int find_tags(pat, num_matches, matchesp, flags, mincount) --- 986,996 ---- * Tags in an emacs-style tags file are always global. * * flags: ! * TAG_HELP only search for help tags ! * TAG_NAMES only return name of tag ! * TAG_REGEXP use "pat" as a regexp ! * TAG_NOIC don't always ignore case ! * TAG_KEEP_LANG keep language */ int find_tags(pat, num_matches, matchesp, flags, mincount) *************** *** 1078,1083 **** --- 1079,1090 ---- int mtt; int len; int help_save; + #ifdef FEAT_MULTI_LANG + int help_pri = 0; + char_u *help_lang_find = NULL; /* lang to be found */ + char_u help_lang[3]; /* lang of current tags file */ + char_u *saved_pat = NULL; /* copy of pat[] */ + #endif int patlen; /* length of pat[] */ char_u *pathead; /* start of pattern head */ *************** *** 1102,1112 **** help_save = curbuf->b_help; - if (has_re) - regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); - else - regmatch.regprog = NULL; - /* * Allocate memory for the buffers that are used */ --- 1109,1114 ---- *************** *** 1137,1142 **** --- 1139,1162 ---- curbuf->b_help = TRUE; /* will be restored later */ patlen = (int)STRLEN(pat); + #ifdef FEAT_MULTI_LANG + if (curbuf->b_help) + { + /* When "@ab" is specified use only the "ab" language, otherwise + * search all languages. */ + if (patlen > 3 && pat[patlen - 3] == '@') + { + saved_pat = vim_strnsave(pat, patlen - 3); + if (saved_pat != NULL) + { + help_lang_find = &pat[patlen - 2]; + pat = saved_pat; + patlen -= 3; + } + } + } + #endif + if (p_tl != 0 && patlen > p_tl) /* adjust for 'taglength' */ patlen = p_tl; *************** *** 1161,1166 **** --- 1181,1191 ---- patheadlen = p_tl; } + if (has_re) + regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); + else + regmatch.regprog = NULL; + #ifdef FEAT_TAG_BINS /* This is only to avoid a compiler warning for using search_info * uninitialised. */ *************** *** 1205,1212 **** --- 1230,1287 ---- else #endif { + #ifdef FEAT_MULTI_LANG + if (curbuf->b_help) + { + /* Prefer help tags according to 'helplang'. Put the + * two-letter language name in help_lang[]. */ + i = STRLEN(tag_fname); + if (i > 3 && tag_fname[i - 3] == '-') + STRCPY(help_lang, tag_fname + i - 2); + else + STRCPY(help_lang, "en"); + + /* When searching for a specific language skip tags files + * for other languages. */ + if (help_lang_find != NULL + && STRICMP(help_lang, help_lang_find) != 0) + continue; + + /* For CTRL-] in a help file prefer a match with the same + * language. */ + if ((flags & TAG_KEEP_LANG) + && help_lang_find == NULL + && (i = STRLEN(curbuf->b_fname)) > 4 + && curbuf->b_fname[i - 1] == 'x' + && curbuf->b_fname[i - 4] == '.' + && STRNICMP(curbuf->b_fname + i - 3, help_lang, 2) == 0) + help_pri = 0; + else + { + help_pri = 1; + for (s = p_hlg; *s != NUL; ++s) + { + if (STRNICMP(s, help_lang, 2) == 0) + break; + ++help_pri; + if ((s = vim_strchr(s, ',')) == NULL) + break; + } + if (s == NULL || *s == NUL) + { + /* Language not in 'helplang': use last, prefer English, + * unless found already. */ + ++help_pri; + if (STRICMP(help_lang, "en") != 0) + ++help_pri; + } + } + } + #endif + if ((fp = mch_fopen((char *)tag_fname, "r")) == NULL) continue; + if (p_verbose >= 5) msg_str((char_u *)_("Searching tags file %s"), tag_fname); } *************** *** 1216,1221 **** --- 1291,1297 ---- #ifdef FEAT_EMACS_TAGS is_etag = 0; /* default is: not emacs style */ #endif + /* * Read and parse the lines in the file one by one */ *************** *** 1811,1816 **** --- 1887,1897 ---- { if (help_only) { + #ifdef FEAT_MULTI_LANG + # define ML_EXTRA 3 + #else + # define ML_EXTRA 0 + #endif /* * Append the help-heuristic number after the * tagname, for sorting it later. *************** *** 1818,1832 **** *tagp.tagname_end = NUL; len = (int)(tagp.tagname_end - tagp.tagname); mfp = (struct match_found *) ! alloc(sizeof(struct match_found) + len + 10); if (mfp != NULL) { ! mfp->len = len + 1; /* also compare the NUL */ p = mfp->match; STRCPY(p, tagp.tagname); ! sprintf((char *)p + len + 1, "%06d", help_heuristic(tagp.tagname, ! match_re ? matchoff : 0, !match_no_ic)); } *tagp.tagname_end = TAB; } --- 1899,1925 ---- *tagp.tagname_end = NUL; len = (int)(tagp.tagname_end - tagp.tagname); mfp = (struct match_found *) ! alloc(sizeof(struct match_found) + len ! + 10 + ML_EXTRA); if (mfp != NULL) { ! /* "len" includes the language and the NUL, but ! * not the priority. */ ! mfp->len = len + ML_EXTRA + 1; ! #define ML_HELP_LEN 6 p = mfp->match; STRCPY(p, tagp.tagname); ! #ifdef FEAT_MULTI_LANG ! p[len] = '@'; ! STRCPY(p + len + 1, help_lang); ! #endif ! sprintf((char *)p + len + 1 + ML_EXTRA, "%06d", help_heuristic(tagp.tagname, ! match_re ? matchoff : 0, !match_no_ic) ! #ifdef FEAT_MULTI_LANG ! + help_pri ! #endif ! ); } *tagp.tagname_end = TAB; } *************** *** 2070,2076 **** * match_found into a string. For help the priority was not * included in the length. */ mch_memmove(mfp, mfp->match, ! (size_t)(mfp->len + (help_only ? 9 : 0))); matches[match_count++] = (char_u *)mfp; } } --- 2163,2169 ---- * match_found into a string. For help the priority was not * included in the length. */ mch_memmove(mfp, mfp->match, ! (size_t)(mfp->len + (help_only ? ML_HELP_LEN : 0))); matches[match_count++] = (char_u *)mfp; } } *************** *** 2081,2090 **** --- 2174,2205 ---- *num_matches = match_count; curbuf->b_help = help_save; + #ifdef FEAT_MULTI_LANG + vim_free(saved_pat); + #endif return retval; } + static garray_T tag_fnames = GA_EMPTY; + static void found_tagfile_cb __ARGS((char_u *fname)); + + /* + * Callback function for finding all "tags" and "tags-??" files in + * 'runtimepath' doc directories. + */ + static void + found_tagfile_cb(fname) + char_u *fname; + { + if (ga_grow(&tag_fnames, 1) == OK) + { + ((char_u **)(tag_fnames.ga_data))[tag_fnames.ga_len++] = + vim_strsave(fname); + --tag_fnames.ga_room; + } + } + /* * Get the next name of a tag file from the tag file list. * For help files, use "tags" file only. *************** *** 2099,2105 **** static void *search_ctx = NULL; static char_u *np = NULL; static int did_filefind_init; ! static int did_use_hf = FALSE; char_u *fname = NULL; char_u *r_ptr; --- 2214,2220 ---- static void *search_ctx = NULL; static char_u *np = NULL; static int did_filefind_init; ! static int hf_idx = 0; char_u *fname = NULL; char_u *r_ptr; *************** *** 2107,2114 **** { if (curbuf->b_help) { ! np = p_rtp; ! did_use_hf = FALSE; } else if (*curbuf->b_p_tags != NUL) np = curbuf->b_p_tags; --- 2222,2241 ---- { if (curbuf->b_help) { ! /* ! * For a help window find "doc/tags" and "doc/tags-??" in all ! * directories in 'runtimepath'. ! */ ! ga_clear(&tag_fnames); ! ga_init2(&tag_fnames, sizeof(char_u *), 10); ! do_in_runtimepath((char_u *) ! #ifdef FEAT_MULTI_LANG ! "doc/tags doc/tags-??" ! #else ! "doc/tags" ! #endif ! , TRUE, found_tagfile_cb); ! hf_idx = 0; } else if (*curbuf->b_p_tags != NUL) np = curbuf->b_p_tags; *************** *** 2118,2154 **** did_filefind_init = FALSE; } - /* tried already (or bogus call) */ - if (np == NULL) - return FAIL; - if (curbuf->b_help) { ! /* ! * For a help window find "doc/tags" in all directories in ! * 'runtimepath'. ! */ ! if (*np == NUL || copy_option_part(&np, buf, MAXPATHL, ",") == 0) { ! if (did_use_hf || *p_hf == NUL) return FAIL; ! ! /* Not found in 'runtimepath', use 'helpfile', replacing ! * "help.txt" with "tags". */ ! did_use_hf = TRUE; STRCPY(buf, p_hf); STRCPY(gettail(buf), "tags"); - return OK; } ! add_pathsep(buf); ! #ifndef COLON_AS_PATHSEP ! STRCAT(buf, "doc/tags"); ! #else ! STRCAT(buf, "doc:tags"); ! #endif } else { /* * Loop until we have found a file name that can be used. * There are two states: --- 2245,2274 ---- did_filefind_init = FALSE; } if (curbuf->b_help) { ! if (hf_idx >= tag_fnames.ga_len) { ! /* Not found in 'runtimepath', use 'helpfile', if it exists and ! * wasn't used yet, replacing "help.txt" with "tags". */ ! if (hf_idx > tag_fnames.ga_len || *p_hf == NUL) return FAIL; ! ++hf_idx; STRCPY(buf, p_hf); STRCPY(gettail(buf), "tags"); } ! else ! { ! STRNCPY(buf, ((char_u **)(tag_fnames.ga_data))[hf_idx++], MAXPATHL); ! buf[MAXPATHL - 1] = NUL; ! } } else { + /* tried already (or bogus call) */ + if (np == NULL) + return FAIL; + /* * Loop until we have found a file name that can be used. * There are two states: *************** *** 2637,2644 **** if (keep_help) { ! /* A :ta from a help file will keep the b_help flag set. For ":ptag" we ! * need to use the flag from the window where we came from. */ #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) if (g_do_tagpreview) keep_help_flag = curwin_save->w_buffer->b_help; --- 2757,2764 ---- if (keep_help) { ! /* A :ta from a help file will keep the b_help flag set. For ":ptag" ! * we need to use the flag from the window where we came from. */ #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) if (g_do_tagpreview) keep_help_flag = curwin_save->w_buffer->b_help; *** ../vim-6.2.298/src/vim.h Tue Feb 10 19:35:15 2004 --- src/vim.h Wed Feb 25 14:42:25 2004 *************** *** 893,898 **** --- 893,900 ---- #endif #define TAG_VERBOSE 32 /* message verbosity */ #define TAG_INS_COMP 64 /* Currently doing insert completion */ + #define TAG_KEEP_LANG 128 /* keep current language */ + #define TAG_MANY 200 /* When finding many tags (for completion), find up to this many tags */ *************** *** 1234,1239 **** --- 1236,1242 ---- #define MSG_ATTR(s, attr) msg_attr((char_u *)(s), (attr)) #define EMSG(s) emsg((char_u *)(s)) #define EMSG2(s, p) emsg2((char_u *)(s), (char_u *)(p)) + #define EMSG3(s, p, q) emsg3((char_u *)(s), (char_u *)(p), (char_u *)(q)) #define EMSGN(s, n) emsgn((char_u *)(s), (long)(n)) #define OUT_STR(s) out_str((char_u *)(s)) #define OUT_STR_NF(s) out_str_nf((char_u *)(s)) *** ../vim-6.2.299/src/version.c Sun Feb 29 20:46:43 2004 --- src/version.c Mon Mar 1 10:30:42 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 299, /**/ -- FATHER: Who are you? PRINCE: I'm ... your son ... FATHER: Not you. LAUNCELOT: I'm ... er ... Sir Launcelot, sir. "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///