To: vim_dev@googlegroups.com Subject: Patch 7.4.1551 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1551 Problem: Cannot generate help tags in all doc directories. Solution: Make ":helptags ALL" work. Files: src/ex_cmds2.c, src/proto/ex_cmds2.pro, src/ex_cmds.c, src/vim.h, src/testdir/test_packadd.vim *** ../vim-7.4.1550/src/ex_cmds2.c 2016-03-12 20:34:22.820382141 +0100 --- src/ex_cmds2.c 2016-03-12 21:07:27.455596807 +0100 *************** *** 2928,2937 **** return do_in_runtimepath(name, all, source_callback, NULL); } - #define DIP_ALL 1 /* all matches, not just the first one */ - #define DIP_DIR 2 /* find directories instead of files. */ - #define DIP_ERR 4 /* give an error message when none found. */ - /* * Find the file "name" in all directories in "path" and invoke * "callback(fname, cookie)". --- 2928,2933 ---- *************** *** 2942,2948 **** * * return FAIL when no file could be sourced, OK otherwise. */ ! static int do_in_path( char_u *path, char_u *name, --- 2938,2944 ---- * * return FAIL when no file could be sourced, OK otherwise. */ ! int do_in_path( char_u *path, char_u *name, *** ../vim-7.4.1550/src/proto/ex_cmds2.pro 2016-03-12 20:34:22.820382141 +0100 --- src/proto/ex_cmds2.pro 2016-03-12 21:15:02.506822516 +0100 *************** *** 61,66 **** --- 61,67 ---- void ex_compiler(exarg_T *eap); void ex_runtime(exarg_T *eap); int source_runtime(char_u *name, int all); + int do_in_path(char_u *path, char_u *name, int flags, void (*callback)(char_u *fname, void *ck), void *cookie); int do_in_runtimepath(char_u *name, int all, void (*callback)(char_u *fname, void *ck), void *cookie); void ex_packloadall(exarg_T *eap); void ex_packadd(exarg_T *eap); *** ../vim-7.4.1550/src/ex_cmds.c 2016-02-23 14:52:31.877232254 +0100 --- src/ex_cmds.c 2016-03-12 21:15:25.498581359 +0100 *************** *** 6575,6709 **** do_cmdline_cmd((char_u *)"help normal-index"); } - static void helptags_one(char_u *dir, char_u *ext, char_u *lang, int add_help_tags); - /* ! * ":helptags" */ - void - ex_helptags(exarg_T *eap) - { - expand_T xpc; - char_u *dirname; - int add_help_tags = FALSE; - #ifdef FEAT_MULTI_LANG - int len; - int i, j; - garray_T ga; - char_u lang[2]; - char_u ext[5]; - char_u fname[8]; - int filecount; - char_u **files; - #endif - - /* Check for ":helptags ++t {dir}". */ - if (STRNCMP(eap->arg, "++t", 3) == 0 && vim_iswhite(eap->arg[3])) - { - add_help_tags = TRUE; - eap->arg = skipwhite(eap->arg + 3); - } - - ExpandInit(&xpc); - xpc.xp_context = EXPAND_DIRECTORIES; - dirname = ExpandOne(&xpc, eap->arg, NULL, - WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); - if (dirname == NULL || !mch_isdir(dirname)) - { - EMSG2(_("E150: Not a directory: %s"), eap->arg); - vim_free(dirname); - return; - } - - #ifdef FEAT_MULTI_LANG - /* Get a list of all files in the help directory and in subdirectories. */ - STRCPY(NameBuff, dirname); - 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); - vim_free(dirname); - 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 = (int)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]; - } - } - } - - /* - * 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(dirname, ext, fname, add_help_tags); - } - - ga_clear(&ga); - FreeWild(filecount, files); - - #else - /* No language support, just use "*.txt" and "tags". */ - helptags_one(dirname, (char_u *)".txt", (char_u *)"tags", add_help_tags); - #endif - vim_free(dirname); - } - static void helptags_one( char_u *dir, /* doc directory */ --- 6575,6583 ---- do_cmdline_cmd((char_u *)"help normal-index"); } /* ! * Generate tags in one help directory. */ static void helptags_one( char_u *dir, /* doc directory */ *************** *** 6960,6965 **** --- 6834,6984 ---- fclose(fd_tags); /* there is no check for an error... */ } + /* + * Generate tags in one help directory, taking care of translations. + */ + static void + do_helptags(char_u *dirname, int add_help_tags) + { + #ifdef FEAT_MULTI_LANG + int len; + int i, j; + garray_T ga; + char_u lang[2]; + char_u ext[5]; + char_u fname[8]; + int filecount; + char_u **files; + + /* Get a list of all files in the help directory and in subdirectories. */ + STRCPY(NameBuff, dirname); + 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); + vim_free(dirname); + 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 = (int)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]; + } + } + } + + /* + * 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(dirname, ext, fname, add_help_tags); + } + + ga_clear(&ga); + FreeWild(filecount, files); + + #else + /* No language support, just use "*.txt" and "tags". */ + helptags_one(dirname, (char_u *)".txt", (char_u *)"tags", add_help_tags); + #endif + } + + static void + helptags_cb(char_u *fname, void *cookie) + { + do_helptags(fname, *(int *)cookie); + } + + /* + * ":helptags" + */ + void + ex_helptags(exarg_T *eap) + { + expand_T xpc; + char_u *dirname; + int add_help_tags = FALSE; + + /* Check for ":helptags ++t {dir}". */ + if (STRNCMP(eap->arg, "++t", 3) == 0 && vim_iswhite(eap->arg[3])) + { + add_help_tags = TRUE; + eap->arg = skipwhite(eap->arg + 3); + } + + if (STRCMP(eap->arg, "ALL") == 0) + { + do_in_path(p_rtp, (char_u *)"doc", DIP_ALL + DIP_DIR, + helptags_cb, &add_help_tags); + } + else + { + ExpandInit(&xpc); + xpc.xp_context = EXPAND_DIRECTORIES; + dirname = ExpandOne(&xpc, eap->arg, NULL, + WILD_LIST_NOTFOUND|WILD_SILENT, WILD_EXPAND_FREE); + if (dirname == NULL || !mch_isdir(dirname)) + EMSG2(_("E150: Not a directory: %s"), eap->arg); + else + do_helptags(dirname, add_help_tags); + vim_free(dirname); + } + } + #if defined(FEAT_SIGNS) || defined(PROTO) /* *** ../vim-7.4.1550/src/vim.h 2016-03-11 22:52:00.742438030 +0100 --- src/vim.h 2016-03-12 21:07:33.615532161 +0100 *************** *** 2288,2291 **** --- 2288,2296 ---- int vim_main2(int argc, char **argv); #endif + /* Used for flags of do_in_path() */ + #define DIP_ALL 1 /* all matches, not just the first one */ + #define DIP_DIR 2 /* find directories instead of files. */ + #define DIP_ERR 4 /* give an error message when none found. */ + #endif /* VIM__H */ *** ../vim-7.4.1550/src/testdir/test_packadd.vim 2016-03-12 20:34:22.820382141 +0100 --- src/testdir/test_packadd.vim 2016-03-12 21:24:13.181046016 +0100 *************** *** 97,99 **** --- 97,116 ---- packloadall! call assert_equal(4321, g:plugin_bar_number) endfunc + + func Test_helptags() + let docdir1 = &packpath . '/pack/mine/start/foo/doc' + let docdir2 = &packpath . '/pack/mine/start/bar/doc' + call mkdir(docdir1, 'p') + call mkdir(docdir2, 'p') + call writefile(['look here: *look-here*'], docdir1 . '/bar.txt') + call writefile(['look away: *look-away*'], docdir2 . '/foo.txt') + exe 'set rtp=' . &packpath . '/pack/mine/start/foo,' . &packpath . '/pack/mine/start/bar' + + helptags ALL + + let tags1 = readfile(docdir1 . '/tags') + call assert_true(tags1[0] =~ 'look-here') + let tags2 = readfile(docdir2 . '/tags') + call assert_true(tags2[0] =~ 'look-away') + endfunc *** ../vim-7.4.1550/src/version.c 2016-03-12 20:34:22.820382141 +0100 --- src/version.c 2016-03-12 21:27:31.538965225 +0100 *************** *** 745,746 **** --- 745,748 ---- { /* Add new patch number below this line */ + /**/ + 1551, /**/ -- 'Well, here's something to occupy you and keep your mind off things.' 'It won't work, I have an exceptionally large mind.' -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy" /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///