diff options
-rw-r--r-- | Filelist | 2 | ||||
-rw-r--r-- | src/Make_cyg_ming.mak | 1 | ||||
-rw-r--r-- | src/Make_morph.mak | 1 | ||||
-rw-r--r-- | src/Make_mvc.mak | 4 | ||||
-rw-r--r-- | src/Make_vms.mms | 6 | ||||
-rw-r--r-- | src/Makefile | 24 | ||||
-rw-r--r-- | src/README.md | 1 | ||||
-rw-r--r-- | src/cmdexpand.c | 56 | ||||
-rw-r--r-- | src/ex_cmds.c | 1274 | ||||
-rw-r--r-- | src/help.c | 1295 | ||||
-rw-r--r-- | src/proto.h | 1 | ||||
-rw-r--r-- | src/proto/ex_cmds.pro | 9 | ||||
-rw-r--r-- | src/proto/help.pro | 14 | ||||
-rw-r--r-- | src/version.c | 2 |
14 files changed, 1344 insertions, 1346 deletions
@@ -68,6 +68,7 @@ SRC_ALL = \ src/gui_beval.c \ src/hardcopy.c \ src/hashtab.c \ + src/help.c \ src/highlight.c \ src/indent.c \ src/insexpand.c \ @@ -240,6 +241,7 @@ SRC_ALL = \ src/proto/gui_beval.pro \ src/proto/hardcopy.pro \ src/proto/hashtab.pro \ + src/proto/help.pro \ src/proto/highlight.pro \ src/proto/indent.pro \ src/proto/insexpand.pro \ diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 157dc94956..3e8bb04e0f 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -744,6 +744,7 @@ OBJ = \ $(OUTDIR)/gui_xim.o \ $(OUTDIR)/hardcopy.o \ $(OUTDIR)/hashtab.o \ + $(OUTDIR)/help.o \ $(OUTDIR)/highlight.o \ $(OUTDIR)/if_cscope.o \ $(OUTDIR)/indent.o \ diff --git a/src/Make_morph.mak b/src/Make_morph.mak index bd95115a39..6fc50ed1fd 100644 --- a/src/Make_morph.mak +++ b/src/Make_morph.mak @@ -64,6 +64,7 @@ SRC = arabic.c \ gui_xim.c \ hardcopy.c \ hashtab.c \ + help.c \ highlight.c \ indent.c \ insexpand.c \ diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index b1bb8836e0..65d530f359 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -766,6 +766,7 @@ OBJ = \ $(OUTDIR)\gui_xim.obj \ $(OUTDIR)\hardcopy.obj \ $(OUTDIR)\hashtab.obj \ + $(OUTDIR)\help.obj \ $(OUTDIR)\highlight.obj \ $(OBJDIR)\if_cscope.obj \ $(OUTDIR)\indent.obj \ @@ -1608,6 +1609,8 @@ $(OUTDIR)/hardcopy.obj: $(OUTDIR) hardcopy.c $(INCL) version.h $(OUTDIR)/hashtab.obj: $(OUTDIR) hashtab.c $(INCL) +$(OUTDIR)/help.obj: $(OUTDIR) help.c $(INCL) + $(OUTDIR)/highlight.obj: $(OUTDIR) highlight.c $(INCL) $(OUTDIR)/indent.obj: $(OUTDIR) indent.c $(INCL) @@ -1930,6 +1933,7 @@ proto.h: \ proto/gui_xim.pro \ proto/hardcopy.pro \ proto/hashtab.pro \ + proto/help.pro \ proto/highlight.pro \ proto/indent.pro \ proto/insexpand.pro \ diff --git a/src/Make_vms.mms b/src/Make_vms.mms index 78f9dab5db..0d80c0617b 100644 --- a/src/Make_vms.mms +++ b/src/Make_vms.mms @@ -337,6 +337,7 @@ SRC = \ gui_xim.c \ hardcopy.c \ hashtab.c \ + help.c \ highlight.c \ if_cscope.c \ if_xcmdsrv.c \ @@ -450,6 +451,7 @@ OBJ = \ gui_xim.obj \ hardcopy.obj \ hashtab.obj \ + help.obj \ highlight.obj \ if_cscope.obj \ if_mzsch.obj \ @@ -834,6 +836,10 @@ hashtab.obj : hashtab.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ globals.h +help.obj : help.c vim.h [.auto]config.h feature.h os_unix.h \ + ascii.h keymap.h term.h macros.h structs.h regexp.h \ + gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ + globals.h highlight.obj : highlight.c vim.h [.auto]config.h feature.h os_unix.h \ ascii.h keymap.h term.h macros.h structs.h regexp.h \ gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \ diff --git a/src/Makefile b/src/Makefile index 2b10024401..36635bdbf5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -404,7 +404,7 @@ CClink = $(CC) # Use --with-luajit if you want to use LuaJIT instead of Lua. # Set PATH environment variable to find lua or luajit executable. # This requires at least "normal" features, "tiny" and "small" don't work. -#CONF_OPT_LUA = --enable-luainterp +CONF_OPT_LUA = --enable-luainterp #CONF_OPT_LUA = --enable-luainterp=dynamic #CONF_OPT_LUA = --enable-luainterp --with-luajit #CONF_OPT_LUA = --enable-luainterp=dynamic --with-luajit @@ -447,10 +447,10 @@ CClink = $(CC) # dlopen(), dlsym(), dlclose(), i.e. pythonX.Y.so must be available # However, this may still cause problems, such as "import termios" failing. # Build two separate versions of Vim in that case. -#CONF_OPT_PYTHON = --enable-pythoninterp +CONF_OPT_PYTHON = --enable-pythoninterp #CONF_OPT_PYTHON = --enable-pythoninterp --with-python-command=python2.7 #CONF_OPT_PYTHON = --enable-pythoninterp=dynamic -#CONF_OPT_PYTHON3 = --enable-python3interp +CONF_OPT_PYTHON3 = --enable-python3interp #CONF_OPT_PYTHON3 = --enable-python3interp --with-python3-command=python3.6 #CONF_OPT_PYTHON3 = --enable-python3interp=dynamic @@ -472,7 +472,7 @@ CClink = $(CC) # CSCOPE # Uncomment this when you want to include the Cscope interface. -#CONF_OPT_CSCOPE = --enable-cscope +CONF_OPT_CSCOPE = --enable-cscope # NETBEANS - NetBeans interface. Only works with Motif, GTK, and gnome. # Motif version must have XPM libraries (see |netbeans-xpm|). @@ -540,7 +540,7 @@ CClink = $(CC) #CONF_OPT_FEAT = --with-features=small #CONF_OPT_FEAT = --with-features=normal #CONF_OPT_FEAT = --with-features=big -#CONF_OPT_FEAT = --with-features=huge +CONF_OPT_FEAT = --with-features=huge # COMPILED BY - For including a specific e-mail address for ":version". #CONF_OPT_COMPBY = "--with-compiledby=John Doe <JohnDoe@yahoo.com>" @@ -614,7 +614,7 @@ CClink = $(CC) # Use this with GCC to check for mistakes, unused arguments, etc. # Note: If you use -Wextra and get warnings in GTK code about function # parameters, you can add -Wno-cast-function-type -#CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -Wno-cast-function-type -Wno-deprecated-declarations -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 +CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wunreachable-code -Wno-cast-function-type -Wno-deprecated-declarations -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 # Add -Wpedantic to find // comments and other C99 constructs. # Better disable Perl and Python to avoid a lot of warnings. #CFLAGS = -g -Wall -Wextra -Wshadow -Wmissing-prototypes -Wpedantic -Wunreachable-code -Wunused-result -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 @@ -709,7 +709,7 @@ SANITIZER_LIBS = $(SANITIZER_CFLAGS) # Configuration is in the .ccmalloc or ~/.ccmalloc file. # Doesn't work very well, since memory linked to from global variables # (in libraries) is also marked as leaked memory. -#LEAK_CFLAGS = -DEXITFREE +LEAK_CFLAGS = -DEXITFREE #LEAK_LIBS = -lccmalloc # Uncomment this line to have Vim call abort() when an internal error is @@ -1639,6 +1639,7 @@ BASIC_SRC = \ gui_xim.c \ hardcopy.c \ hashtab.c \ + help.c \ highlight.c \ if_cscope.c \ if_xcmdsrv.c \ @@ -1790,6 +1791,7 @@ OBJ_COMMON = \ objects/gui_xim.o \ objects/hardcopy.o \ objects/hashtab.o \ + objects/help.o \ objects/highlight.o \ objects/if_cscope.o \ objects/if_xcmdsrv.o \ @@ -1958,6 +1960,7 @@ PRO_AUTO = \ gui_beval.pro \ hardcopy.pro \ hashtab.pro \ + help.pro \ highlight.pro \ if_cscope.pro \ if_lua.pro \ @@ -3264,6 +3267,9 @@ objects/hardcopy.o: hardcopy.c objects/hashtab.o: hashtab.c $(CCC) -o $@ hashtab.c +objects/help.o: help.c + $(CCC) -o $@ help.c + objects/gui.o: gui.c $(CCC) -o $@ gui.c @@ -3930,6 +3936,10 @@ objects/hashtab.o: hashtab.c vim.h protodef.h auto/config.h feature.h os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ proto.h globals.h +objects/help.o: help.c vim.h protodef.h auto/config.h feature.h os_unix.h \ + auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ + proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ + proto.h globals.h objects/highlight.o: highlight.c vim.h protodef.h auto/config.h feature.h \ os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \ proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \ diff --git a/src/README.md b/src/README.md index a196f2b954..f499c4cdb2 100644 --- a/src/README.md +++ b/src/README.md @@ -48,6 +48,7 @@ filepath.c | dealing with file names and paths findfile.c | search for files in 'path' fold.c | folding getchar.c | getting characters and key mapping +help.c | vim help related functions highlight.c | syntax highlighting indent.c | text indentation insexpand.c | Insert mode completion diff --git a/src/cmdexpand.c b/src/cmdexpand.c index d92366c61e..a10fff8b3d 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -1887,62 +1887,6 @@ expand_cmdline( return EXPAND_OK; } -#ifdef FEAT_MULTI_LANG -/* - * Cleanup matches for help tags: - * Remove "@ab" if the top of 'helplang' is "ab" and the language of the first - * tag matches it. Otherwise remove "@en" if "en" is the only language. - */ - static void -cleanup_help_tags(int num_file, char_u **file) -{ - int i, j; - int len; - char_u buf[4]; - char_u *p = buf; - - if (p_hlg[0] != NUL && (p_hlg[0] != 'e' || p_hlg[1] != 'n')) - { - *p++ = '@'; - *p++ = p_hlg[0]; - *p++ = p_hlg[1]; - } - *p = NUL; - - for (i = 0; i < num_file; ++i) - { - len = (int)STRLEN(file[i]) - 3; - if (len <= 0) - continue; - if (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) - // item only exists with @en, remove it - file[i][len] = NUL; - } - } - - if (*buf != NUL) - for (i = 0; i < num_file; ++i) - { - len = (int)STRLEN(file[i]) - 3; - if (len <= 0) - continue; - if (STRCMP(file[i] + len, buf) == 0) - { - // remove the default language - file[i][len] = NUL; - } - } -} -#endif - /* * Function given to ExpandGeneric() to obtain the possible arguments of the * ":behave {mswin,xterm}" command. diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 11894f6387..59c562b917 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -23,8 +23,6 @@ static void do_filter(linenr_T line1, linenr_T line2, exarg_T *eap, char_u *cmd, static int not_writing(void); static int check_readonly(int *forceit, buf_T *buf); static void delbuf_msg(char_u *name); -static int help_compare(const void *s1, const void *s2); -static void prepare_help_buffer(void); /* * ":ascii" and "ga". @@ -5035,1278 +5033,6 @@ prepare_tagpreview( #endif - -/* - * ":help": open a read-only window on a help file - */ - void -ex_help(exarg_T *eap) -{ - char_u *arg; - char_u *tag; - FILE *helpfd; // file descriptor of help file - int n; - int i; - win_T *wp; - 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; -#endif -#ifdef FEAT_FOLDING - int old_KeyTyped = KeyTyped; -#endif - - if (eap != NULL) - { - /* - * A ":help" command ends at the first LF, or at a '|' that is - * followed by some text. Set nextcmd to the following command. - */ - for (arg = eap->arg; *arg; ++arg) - { - if (*arg == '\n' || *arg == '\r' - || (*arg == '|' && arg[1] != NUL && arg[1] != '|')) - { - *arg++ = NUL; - eap->nextcmd = arg; - break; - } - } - arg = eap->arg; - - if (eap->forceit && *arg == NUL && !curbuf->b_help) - { - 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 - lang = check_help_lang(arg); -#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 = (int)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) - semsg(_("E661: Sorry, no '%s' help for %s"), lang, arg); - else -#endif - semsg(_("E149: Sorry, no help for %s"), arg); - if (n != FAIL) - FreeWild(num_matches, matches); - 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 - - /* - * Re-use an existing help window or open a new one. - * Always open a new one for ":tab help". - */ - if (!bt_help(curwin->w_buffer) || cmdmod.tab != 0) - { - if (cmdmod.tab != 0) - wp = NULL; - else - FOR_ALL_WINDOWS(wp) - if (bt_help(wp->w_buffer)) - break; - if (wp != NULL && wp->w_buffer->b_nwindows > 0) - win_enter(wp, TRUE); - else - { - /* - * There is no help window yet. - * Try to open the file specified by the "helpfile" option. - */ - if ((helpfd = mch_fopen((char *)p_hf, READBIN)) == NULL) - { - smsg(_("Sorry, help file \"%s\" not found"), p_hf); - goto erret; - } - fclose(helpfd); - - // Split off help window; put it at far top if no position - // specified, the current window is vertically split and - // narrow. - n = WSP_HELP; - if (cmdmod.split == 0 && curwin->w_width != Columns - && curwin->w_width < 80) - n |= WSP_TOP; - if (win_split(0, n) == FAIL) - goto erret; - - if (curwin->w_height < p_hh) - win_setheight((int)p_hh); - - /* - * Open help file (do_ecmd() will set b_help flag, readfile() will - * set b_p_ro flag). - * Set the alternate file to the previously edited file. - */ - alt_fnum = curbuf->b_fnum; - (void)do_ecmd(0, NULL, NULL, NULL, ECMD_LASTL, - ECMD_HIDE + ECMD_SET_HELP, - NULL); // buffer is still open, don't store info - if (!cmdmod.keepalt) - curwin->w_alt_fnum = alt_fnum; - empty_fnum = curbuf->b_fnum; - } - } - - if (!p_im) - restart_edit = 0; // don't want insert mode in help file - -#ifdef FEAT_FOLDING - // Restore KeyTyped, setting 'filetype=help' may reset it. - // It is needed for do_tag top open folds under the cursor. - KeyTyped = old_KeyTyped; -#endif - - if (tag != NULL) - do_tag(tag, DT_HELP, 1, FALSE, TRUE); - - // Delete the empty buffer if we're not using it. Careful: autocommands - // may have jumped to another window, check that the buffer is not in a - // window. - if (empty_fnum != 0 && curbuf->b_fnum != empty_fnum) - { - buf = buflist_findnr(empty_fnum); - if (buf != NULL && buf->b_nwindows == 0) - wipe_buffer(buf, TRUE); - } - - // keep the previous alternate file - if (alt_fnum != 0 && curwin->w_alt_fnum == empty_fnum && !cmdmod.keepalt) - curwin->w_alt_fnum = alt_fnum; - -erret: - vim_free(tag); -} - -/* - * ":helpclose": Close one help window - */ - void -ex_helpclose(exarg_T *eap UNUSED) -{ - win_T *win; - - FOR_ALL_WINDOWS(win) - { - if (bt_help(win->w_buffer)) - { - win_close(win, FALSE); - return; - } - } -} - -#if defined(FEAT_MULTI_LANG) || defined(PROTO) -/* - * In an argument search for a language specifiers in the form "@xx". - * Changes the "@" to NUL if found, and returns a pointer to "xx". - * Returns NULL if not found. - */ - char_u * -check_help_lang(char_u *arg) -{ - int len = (int)STRLEN(arg); - - if (len >= 3 && arg[len - 3] == '@' && ASCII_ISALPHA(arg[len - 2]) - && ASCII_ISALPHA(arg[len - 1])) - { - arg[len - 3] = NUL; // remove the '@' - return arg + len - 2; - } - return NULL; -} -#endif - -/* - * Return a heuristic indicating how well the given string matches. The - * smaller the number, the better the match. This is the order of priorities, - * from best match to worst match: - * - Match with least alphanumeric characters is better. - * - Match with least total characters is better. - * - Match towards the start is better. - * - Match starting with "+" is worse (feature instead of command) - * Assumption is made that the matched_string passed has already been found to - * match some string for which help is requested. webb. - */ - int -help_heuristic( - char_u *matched_string, - int offset, // offset for match - int wrong_case) // no matching case -{ - int num_letters; - char_u *p; - - num_letters = 0; - for (p = matched_string; *p; p++) - if (ASCII_ISALNUM(*p)) - num_letters++; - - /* - * Multiply the number of letters by 100 to give it a much bigger - * weighting than the number of characters. - * If there only is a match while ignoring case, add 5000. - * If the match starts in the middle of a word, add 10000 to put it - * somewhere in the last half. - * If the match is more than 2 chars from the start, multiply by 200 to - * put it after matches at the start. - */ - if (ASCII_ISALNUM(matched_string[offset]) && offset > 0 - && ASCII_ISALNUM(matched_string[offset - 1])) - offset += 10000; - else if (offset > 2) - offset *= 200; - if (wrong_case) - offset += 5000; - // Features are less interesting than the subjects themselves, but "+" - // alone is not a feature. - if (matched_string[0] == '+' && matched_string[1] != NUL) - offset += 100; - return (int)(100 * num_letters + STRLEN(matched_string) + offset); -} - -/* - * Compare functions for qsort() below, that checks the help heuristics number - * that has been put after the tagname by find_tags(). - */ - static int -help_compare(const void *s1, const void *s2) -{ - char *p1; - char *p2; - int cmp; - - p1 = *(char **)s1 + strlen(*(char **)s1) + 1; - p2 = *(char **)s2 + strlen(*(char **)s2) + 1; - - // Compare by help heuristic number first. - cmp = strcmp(p1, p2); - if (cmp != 0) - return cmp; - - // Compare by strings as tie-breaker when same heuristic number. - return strcmp(*(char **)s1, *(char **)s2); -} - -/* - * 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( - char_u *arg, - int *num_matches, - char_u ***matches, - int keep_lang) -{ - char_u *s, *d; - int i; - static char *(mtable[]) = {"*", "g*", "[*", "]*", ":*", - "/*", "/\\*", "\"*", "**", - "cpo-*", "/\\(\\)", "/\\%(\\)", - "?", ":?", "?<CR>", "g?", "g?g?", "g??", - "-?", "q?", "v_g?", - "/\\?", "/\\z(\\)", "\\=", ":s\\=", - "[count]", "[quotex]", - "[range]", ":[range]", - "[pattern]", "\\|", "\\%$", - "s/\\~", "s/\\U", "s/\\L", - "s/\\1", "s/\\2", "s/\\3", "s/\\9"}; - static char *(rtable[]) = {"star", "gstar", "[star", "]star", ":star", - "/star", "/\\\\star", "quotestar", "starstar", - "cpo-star", "/\\\\(\\\\)", "/\\\\%(\\\\)", - "?", ":?", "?<CR>", "g?", "g?g?", "g??", - "-?", "q?", "v_g?", - "/\\\\?", "/\\\\z(\\\\)", "\\\\=", ":s\\\\=", - "\\[count]", "\\[quotex]", - "\\[range]", ":\\[range]", - "\\[pattern]", "\\\\bar", "/\\\\%\\$", - "s/\\\\\\~", "s/\\\\U", "s/\\\\L", - "s/\\\\1", "s/\\\\2", "s/\\\\3", "s/\\\\9"}; - static char *(expr_table[]) = {"!=?", "!~?", "<=?", "<?", "==?", "=~?", - ">=?", ">?", "is?", "isnot?"}; - int flags; - - d = IObuff; // assume IObuff is long enough! - - if (STRNICMP(arg, "expr-", 5) == 0) - { - // When the string starting with "expr-" and containing '?' and matches - // the table, it is taken literally (but ~ is escaped). Otherwise '?' - // is recognized as a wildcard. - for (i = (int)(sizeof(expr_table) / sizeof(char *)); --i >= 0; ) - if (STRCMP(arg + 5, expr_table[i]) == 0) - { - int si = 0, di = 0; - - for (;;) - { - if (arg[si] == '~') - d[di++] = '\\'; - d[di++] = arg[si]; - if (arg[si] == NUL) - break; - ++si; - } - break; - } - } - else - { - // Recognize a few exceptions to the rule. Some strings that contain - // '*' with "star". Otherwise '*' is recognized as a wildcard. - for (i = (int)(sizeof(mtable) / sizeof(char *)); --i >= 0; ) - if (STRCMP(arg, mtable[i]) == 0) - { - STRCPY(d, rtable[i]); - break; - } - } - - if (i < 0) // no match in table - { - // Replace "\S" with "/\\S", etc. Otherwise every tag is matched. - // Also replace "\%^" and "\%(", they match every tag too. - // Also "\zs", "\z1", etc. - // Also "\@<", "\@=", "\@<=", etc. - // And also "\_$" and "\_^". - if (arg[0] == '\\' - && ((arg[1] != NUL && arg[2] == NUL) - || (vim_strchr((char_u *)"%_z@", arg[1]) != NULL - && arg[2] != NUL))) - { - STRCPY(d, "/\\\\"); - STRCPY(d + 3, arg + 1); - // Check for "/\\_$", should be "/\\_\$" - if (d[3] == '_' && d[4] == '$') - STRCPY(d + 4, "\\$"); - } - else - { - // Replace: - // "[:...:]" with "\[:...:]" - // "[++...]" with "\[++...]" - // "\{" with "\\{" -- matching "} \}" - if ((arg[0] == '[' && (arg[1] == ':' - || (arg[1] == '+' && arg[2] == '+'))) - || (arg[0] == '\\' && arg[1] == '{')) - *d++ = '\\'; - - /* - * If tag starts with "('", skip the "(". Fixes CTRL-] on ('option'. - */ - if (*arg == '(' && arg[1] == '\'') - arg++; - for (s = arg; *s; ++s) - { - /* - * Replace "|" with "bar" and '"' with "quote" to match the name of - * the tags for these commands. - * Replace "*" with ".*" and "?" with "." to match command line - * completion. - * Insert a backslash before '~', '$' and '.' to avoid their - * special meaning. - */ - if (d - IObuff > IOSIZE - 10) // getting too long!? - break; - switch (*s) - { - case '|': STRCPY(d, "bar"); - d += 3; - continue; - case '"': STRCPY(d, "quote"); - d += 5; - continue; - case '*': *d++ = '.'; - break; - case '?': *d++ = '.'; - continue; - case '$': - case '.': - case '~': *d++ = '\\'; - break; - } - - /* - * Replace "^x" by "CTRL-X". Don't do this for "^_" to make - * ":help i_^_CTRL-D" work. - * Insert '-' before and after "CTRL-X" when applicable. - */ - if (*s < ' ' || (*s == '^' && s[1] && (ASCII_ISALPHA(s[1]) - || vim_strchr((char_u *)"?@[\\]^", s[1]) != NULL))) - { - if (d > IObuff && d[-1] != '_' && d[-1] != '\\') - *d++ = '_'; // prepend a '_' to make x_CTRL-x - STRCPY(d, "CTRL-"); - d += 5; - if (*s < ' ') - { -#ifdef EBCDIC - *d++ = CtrlChar(*s); -#else - *d++ = *s + '@'; -#endif - if (d[-1] == '\\') - *d++ = '\\'; // double a backslash - } - else - *d++ = *++s; - if (s[1] != NUL && s[1] != '_') - *d++ = '_'; // append a '_' - continue; - } - else if (*s == '^') // "^" or "CTRL-^" or "^_" - *d++ = '\\'; - - /* - * Insert a backslash before a backslash after a slash, for search - * pattern tags: "/\|" --> "/\\|". - */ - else if (s[0] == '\\' && s[1] != '\\' - && *arg == '/' && s == arg + 1) - *d++ = '\\'; - - // "CTRL-\_" -> "CTRL-\\_" to avoid the special meaning of "\_" in - // "CTRL-\_CTRL-N" - if (STRNICMP(s, "CTRL-\\_", 7) == 0) - { - STRCPY(d, "CTRL-\\\\"); - d += 7; - s += 6; - } - - *d++ = *s; - - /* - * If tag contains "({" or "([", tag terminates at the "(". - * This is for help on functions, e.g.: abs({expr}). - */ - if (*s == '(' && (s[1] == '{' || s[1] =='[')) - break; - - /* - * If tag starts with ', toss everything after a second '. Fixes - * CTRL-] on 'option'. (would include the trailing '.'). - */ - if (*s == '\'' && s > arg && *arg == '\'') - break; - // Also '{' and '}'. - if (*s == '}' && s > arg && *arg == '{') - break; - } - *d = NUL; - - if (*IObuff == '`') - { - if (d > IObuff + 2 && d[-1] == '`') - { - // remove the backticks from `command` - mch_memmove(IObuff, IObuff + 1, STRLEN(IObuff)); - d[-2] = NUL; - } - else if (d > IObuff + 3 && d[-2] == '`' && d[-1] == ',') - { - // remove the backticks and comma from `command`, - mch_memmove(IObuff, IObuff + 1, STRLEN(IObuff)); - d[-3] = NUL; - } - else if (d > IObuff + 4 && d[-3] == '`' - && d[-2] == '\\' && d[-1] == '.') - { - // remove the backticks and dot from `command`\. - mch_memmove(IObuff, IObuff + 1, STRLEN(IObuff)); - d[-4] = NUL; - } - } - } - } - - *matches = (char_u **)""; - *num_matches = 0; - flags = TAG_HELP | TAG_REGEXP | TAG_NAMES | TAG_VERBOSE | TAG_NO_TAGFUNC; - if (keep_lang) - flags |= TAG_KEEP_LANG; - if (find_tags(IObuff, num_matches, matches, flags, (int)MAXCOL, NULL) == 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); - // Delete more than TAG_MANY to reduce the size of the listing. - while (*num_matches > TAG_MANY) - vim_free((*matches)[--*num_matches]); - } - return OK; -} - -/* - * Called when starting to edit a buffer for a help file. - */ - static void -prepare_help_buffer(void) -{ - char_u *p; - - curbuf->b_help = TRUE; -#ifdef FEAT_QUICKFIX - set_string_option_direct((char_u *)"buftype", -1, - (char_u *)"help", OPT_FREE|OPT_LOCAL, 0); -#endif - - /* - * Always set these options after jumping to a help tag, because the - * user may have an autocommand that gets in the way. - * Accept all ASCII chars for keywords, except ' ', '*', '"', '|', and - * latin1 word characters (for translated help files). - * Only set it when needed, buf_init_chartab() is some work. - */ - p = -#ifdef EBCDIC - (char_u *)"65-255,^*,^|,^\""; -#else - (char_u *)"!-~,^*,^|,^\",192-255"; -#endif - if (STRCMP(curbuf->b_p_isk, p) != 0) - { - set_string_option_direct((char_u *)"isk", -1, p, OPT_FREE|OPT_LOCAL, 0); - check_buf_options(curbuf); - (void)buf_init_chartab(curbuf, FALSE); - } - -#ifdef FEAT_FOLDING - // Don't use the global foldmethod. - set_string_option_direct((char_u *)"fdm", -1, (char_u *)"manual", - OPT_FREE|OPT_LOCAL, 0); -#endif - - curbuf->b_p_ts = 8; // 'tabstop' is 8 - curwin->w_p_list = FALSE; // no list mode - - curbuf->b_p_ma = FALSE; // not modifiable - curbuf->b_p_bin = FALSE; // reset 'bin' before reading file - curwin->w_p_nu = 0; // no line numbers - curwin->w_p_rnu = 0; // no relative line numbers - RESET_BINDING(curwin); // no scroll or cursor binding -#ifdef FEAT_ARABIC - curwin->w_p_arab = FALSE; // no arabic mode -#endif -#ifdef FEAT_RIGHTLEFT - curwin->w_p_rl = FALSE; // help window is left-to-right -#endif -#ifdef FEAT_FOLDING - curwin->w_p_fen = FALSE; // No folding in the help window -#endif -#ifdef FEAT_DIFF - curwin->w_p_diff = FALSE; // No 'diff' -#endif -#ifdef FEAT_SPELL - curwin->w_p_spell = FALSE; // No spell checking -#endif - - set_buflisted(FALSE); -} - -/* - * After reading a help file: May cleanup a help buffer when syntax - * highlighting is not used. - */ - void -fix_help_buffer(void) -{ - linenr_T lnum; - char_u *line; - int in_example = FALSE; - int len; - char_u *fname; - char_u *p; - char_u *rt; - int mustfree; - - // Set filetype to "help" if still needed. - if (STRCMP(curbuf->b_p_ft, "help") != 0) - { - ++curbuf_lock; - set_option_value((char_u *)"ft", 0L, (char_u *)"help", OPT_LOCAL); - --curbuf_lock; - } - -#ifdef FEAT_SYN_HL - if (!syntax_present(curwin)) -#endif - { - for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) - { - line = ml_get_buf(curbuf, lnum, FALSE); - len = (int)STRLEN(line); - if (in_example && len > 0 && !VIM_ISWHITE(line[0])) - { - // End of example: non-white or '<' in first column. - if (line[0] == '<') - { - // blank-out a '<' in the first column - line = ml_get_buf(curbuf, lnum, TRUE); - line[0] = ' '; - } - in_example = FALSE; - } - if (!in_example && len > 0) - { - if (line[len - 1] == '>' && (len == 1 || line[len - 2] == ' ')) - { - // blank-out a '>' in the last column (start of example) - line = ml_get_buf(curbuf, lnum, TRUE); - line[len - 1] = ' '; - in_example = TRUE; - } - else if (line[len - 1] == '~') - { - // blank-out a '~' at the end of line (header marker) - line = ml_get_buf(curbuf, lnum, TRUE); - line[len - 1] = ' '; - } - } - } - } - - /* - * In the "help.txt" and "help.abx" file, add the locally added help - * files. This uses the very first line in the help file. - */ - fname = gettail(curbuf->b_fname); - if (fnamecmp(fname, "help.txt") == 0 -#ifdef FEAT_MULTI_LANG - || (fnamencmp(fname, "help.", 5) == 0 - && ASCII_ISALPHA(fname[5]) - && ASCII_ISALPHA(fname[6]) - && TOLOWER_ASC(fname[7]) == 'x' - && fname[8] == NUL) -#endif - ) - { - for (lnum = 1; lnum < curbuf->b_ml.ml_line_count; ++lnum) - { - line = ml_get_buf(curbuf, lnum, FALSE); - if (strstr((char *)line, "*local-additions*") == NULL) - continue; - - // Go through all directories in 'runtimepath', skipping - // $VIMRUNTIME. - p = p_rtp; - while (*p != NUL) - { - copy_option_part(&p, NameBuff, MAXPATHL, ","); - mustfree = FALSE; - rt = vim_getenv((char_u *)"VIMRUNTIME", &mustfree); - if (rt != NULL && - fullpathcmp(rt, NameBuff, FALSE, TRUE) != FPC_SAME) - { - int fcount; - char_u **fnames; - FILE *fd; - char_u *s; - int fi; - vimconv_T vc; - char_u *cp; - - // Find all "doc/ *.txt" files in this directory. - add_pathsep(NameBuff); -#ifdef FEAT_MULTI_LANG - STRCAT(NameBuff, "doc/*.??[tx]"); -#else - STRCAT(NameBuff, "doc/*.txt"); -#endif - if (gen_expand_wildcards(1, &NameBuff, &fcount, - &fnames, EW_FILE|EW_SILENT) == |