To: vim_dev@googlegroups.com Subject: Patch 8.0.1754 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1754 Problem: ex_helpgrep() is too long. Solution: Refactor the function. (Yegappan Lakshmanan, closes #2766) Files: src/quickfix.c, src/testdir/test_quickfix.vim *** ../vim-8.0.1753/src/quickfix.c 2018-04-24 13:54:56.157455279 +0200 --- src/quickfix.c 2018-04-24 15:39:12.411945528 +0200 *************** *** 5942,5972 **** #endif /* ! * ":helpgrep {pattern}" */ ! void ! ex_helpgrep(exarg_T *eap) { - regmatch_T regmatch; - char_u *save_cpo; - char_u *p; int fcount; char_u **fnames; - FILE *fd; int fi; ! long lnum; #ifdef FEAT_MULTI_LANG char_u *lang; #endif ! qf_info_T *qi = &ql_info; ! int new_qi = FALSE; ! win_T *wp; ! char_u *au_name = NULL; #ifdef FEAT_MULTI_LANG /* Check for a specified language */ ! lang = check_help_lang(eap->arg); #endif switch (eap->cmdidx) { --- 5942,6167 ---- #endif /* ! * Get the location list for ":lhelpgrep" */ ! static qf_info_T * ! hgr_get_ll(int *new_ll) ! { ! win_T *wp; ! qf_info_T *qi; ! ! /* If the current window is a help window, then use it */ ! if (bt_help(curwin->w_buffer)) ! wp = curwin; ! else ! /* Find an existing help window */ ! FOR_ALL_WINDOWS(wp) ! if (bt_help(wp->w_buffer)) ! break; ! ! if (wp == NULL) /* Help window not found */ ! qi = NULL; ! else ! qi = wp->w_llist; ! ! if (qi == NULL) ! { ! /* Allocate a new location list for help text matches */ ! if ((qi = ll_new_list()) == NULL) ! return NULL; ! *new_ll = TRUE; ! } ! ! return qi; ! } ! ! /* ! * Search for a pattern in a help file. ! */ ! static void ! hgr_search_file( ! qf_info_T *qi, ! char_u *fname, ! #ifdef FEAT_MBYTE ! vimconv_T *p_vc, ! #endif ! regmatch_T *p_regmatch) ! { ! FILE *fd; ! long lnum; ! ! fd = mch_fopen((char *)fname, "r"); ! if (fd == NULL) ! return; ! ! lnum = 1; ! while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) ! { ! char_u *line = IObuff; ! #ifdef FEAT_MBYTE ! /* Convert a line if 'encoding' is not utf-8 and ! * the line contains a non-ASCII character. */ ! if (p_vc->vc_type != CONV_NONE ! && has_non_ascii(IObuff)) ! { ! line = string_convert(p_vc, IObuff, NULL); ! if (line == NULL) ! line = IObuff; ! } ! #endif ! ! if (vim_regexec(p_regmatch, line, (colnr_T)0)) ! { ! int l = (int)STRLEN(line); ! ! /* remove trailing CR, LF, spaces, etc. */ ! while (l > 0 && line[l - 1] <= ' ') ! line[--l] = NUL; ! ! if (qf_add_entry(qi, ! qi->qf_curlist, ! NULL, /* dir */ ! fname, ! 0, ! line, ! lnum, ! (int)(p_regmatch->startp[0] - line) ! + 1, /* col */ ! FALSE, /* vis_col */ ! NULL, /* search pattern */ ! 0, /* nr */ ! 1, /* type */ ! TRUE /* valid */ ! ) == FAIL) ! { ! got_int = TRUE; ! #ifdef FEAT_MBYTE ! if (line != IObuff) ! vim_free(line); ! #endif ! break; ! } ! } ! #ifdef FEAT_MBYTE ! if (line != IObuff) ! vim_free(line); ! #endif ! ++lnum; ! line_breakcheck(); ! } ! fclose(fd); ! } ! ! /* ! * Search for a pattern in all the help files in the doc directory under ! * the given directory. ! */ ! static void ! hgr_search_files_in_dir( ! qf_info_T *qi, ! char_u *dirname, ! regmatch_T *p_regmatch ! #ifdef FEAT_MBYTE ! , vimconv_T *p_vc ! #endif ! #ifdef FEAT_MULTI_LANG ! , char_u *lang ! #endif ! ) { int fcount; char_u **fnames; int fi; ! ! /* Find all "*.txt" and "*.??x" files in the "doc" directory. */ ! add_pathsep(dirname); ! STRCAT(dirname, "doc/*.\\(txt\\|??x\\)"); ! if (gen_expand_wildcards(1, &dirname, &fcount, ! &fnames, EW_FILE|EW_SILENT) == OK ! && fcount > 0) ! { ! for (fi = 0; fi < fcount && !got_int; ++fi) ! { ! #ifdef FEAT_MULTI_LANG ! /* Skip files for a different language. */ ! if (lang != NULL ! && STRNICMP(lang, fnames[fi] ! + STRLEN(fnames[fi]) - 3, 2) != 0 ! && !(STRNICMP(lang, "en", 2) == 0 ! && STRNICMP("txt", fnames[fi] ! + STRLEN(fnames[fi]) - 3, 3) == 0)) ! continue; ! #endif ! ! hgr_search_file(qi, fnames[fi], ! #ifdef FEAT_MBYTE ! p_vc, ! #endif ! p_regmatch); ! } ! FreeWild(fcount, fnames); ! } ! } ! ! /* ! * Search for a pattern in all the help files in the 'runtimepath'. ! */ ! static void ! hgr_search_in_rtp(qf_info_T *qi, regmatch_T *p_regmatch, char_u *arg) ! { ! char_u *p; #ifdef FEAT_MULTI_LANG char_u *lang; #endif ! ! #ifdef FEAT_MBYTE ! vimconv_T vc; ! ! /* Help files are in utf-8 or latin1, convert lines when 'encoding' ! * differs. */ ! vc.vc_type = CONV_NONE; ! if (!enc_utf8) ! convert_setup(&vc, (char_u *)"utf-8", p_enc); ! #endif #ifdef FEAT_MULTI_LANG /* Check for a specified language */ ! lang = check_help_lang(arg); ! #endif ! ! /* Go through all directories in 'runtimepath' */ ! p = p_rtp; ! while (*p != NUL && !got_int) ! { ! copy_option_part(&p, NameBuff, MAXPATHL, ","); ! ! hgr_search_files_in_dir(qi, NameBuff, p_regmatch ! #ifdef FEAT_MBYTE ! , &vc #endif + #ifdef FEAT_MULTI_LANG + , lang + #endif + ); + } + + #ifdef FEAT_MBYTE + if (vc.vc_type != CONV_NONE) + convert_setup(&vc, NULL, NULL); + #endif + } + + /* + * ":helpgrep {pattern}" + */ + void + ex_helpgrep(exarg_T *eap) + { + regmatch_T regmatch; + char_u *save_cpo; + qf_info_T *qi = &ql_info; + int new_qi = FALSE; + char_u *au_name = NULL; switch (eap->cmdidx) { *************** *** 5989,6129 **** if (eap->cmdidx == CMD_lhelpgrep) { ! /* If the current window is a help window, then use it */ ! if (bt_help(curwin->w_buffer)) ! wp = curwin; ! else ! /* Find an existing help window */ ! FOR_ALL_WINDOWS(wp) ! if (bt_help(wp->w_buffer)) ! break; ! ! if (wp == NULL) /* Help window not found */ ! qi = NULL; ! else ! qi = wp->w_llist; ! if (qi == NULL) ! { ! /* Allocate a new location list for help text matches */ ! if ((qi = ll_new_list()) == NULL) ! return; ! new_qi = TRUE; ! } } regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING); regmatch.rm_ic = FALSE; if (regmatch.regprog != NULL) { - #ifdef FEAT_MBYTE - vimconv_T vc; - - /* Help files are in utf-8 or latin1, convert lines when 'encoding' - * differs. */ - vc.vc_type = CONV_NONE; - if (!enc_utf8) - convert_setup(&vc, (char_u *)"utf-8", p_enc); - #endif - /* create a new quickfix list */ qf_new_list(qi, *eap->cmdlinep); ! /* Go through all directories in 'runtimepath' */ ! p = p_rtp; ! while (*p != NUL && !got_int) ! { ! copy_option_part(&p, NameBuff, MAXPATHL, ","); ! ! /* Find all "*.txt" and "*.??x" files in the "doc" directory. */ ! add_pathsep(NameBuff); ! STRCAT(NameBuff, "doc/*.\\(txt\\|??x\\)"); ! if (gen_expand_wildcards(1, &NameBuff, &fcount, ! &fnames, EW_FILE|EW_SILENT) == OK ! && fcount > 0) ! { ! for (fi = 0; fi < fcount && !got_int; ++fi) ! { ! #ifdef FEAT_MULTI_LANG ! /* Skip files for a different language. */ ! if (lang != NULL ! && STRNICMP(lang, fnames[fi] ! + STRLEN(fnames[fi]) - 3, 2) != 0 ! && !(STRNICMP(lang, "en", 2) == 0 ! && STRNICMP("txt", fnames[fi] ! + STRLEN(fnames[fi]) - 3, 3) == 0)) ! continue; ! #endif ! fd = mch_fopen((char *)fnames[fi], "r"); ! if (fd != NULL) ! { ! lnum = 1; ! while (!vim_fgets(IObuff, IOSIZE, fd) && !got_int) ! { ! char_u *line = IObuff; ! #ifdef FEAT_MBYTE ! /* Convert a line if 'encoding' is not utf-8 and ! * the line contains a non-ASCII character. */ ! if (vc.vc_type != CONV_NONE ! && has_non_ascii(IObuff)) ! { ! line = string_convert(&vc, IObuff, NULL); ! if (line == NULL) ! line = IObuff; ! } ! #endif ! ! if (vim_regexec(®match, line, (colnr_T)0)) ! { ! int l = (int)STRLEN(line); ! ! /* remove trailing CR, LF, spaces, etc. */ ! while (l > 0 && line[l - 1] <= ' ') ! line[--l] = NUL; ! ! if (qf_add_entry(qi, ! qi->qf_curlist, ! NULL, /* dir */ ! fnames[fi], ! 0, ! line, ! lnum, ! (int)(regmatch.startp[0] - line) ! + 1, /* col */ ! FALSE, /* vis_col */ ! NULL, /* search pattern */ ! 0, /* nr */ ! 1, /* type */ ! TRUE /* valid */ ! ) == FAIL) ! { ! got_int = TRUE; ! #ifdef FEAT_MBYTE ! if (line != IObuff) ! vim_free(line); ! #endif ! break; ! } ! } ! #ifdef FEAT_MBYTE ! if (line != IObuff) ! vim_free(line); ! #endif ! ++lnum; ! line_breakcheck(); ! } ! fclose(fd); ! } ! } ! FreeWild(fcount, fnames); ! } ! } vim_regfree(regmatch.regprog); - #ifdef FEAT_MBYTE - if (vc.vc_type != CONV_NONE) - convert_setup(&vc, NULL, NULL); - #endif qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE; qi->qf_lists[qi->qf_curlist].qf_ptr = --- 6184,6204 ---- if (eap->cmdidx == CMD_lhelpgrep) { ! qi = hgr_get_ll(&new_qi); if (qi == NULL) ! return; } regmatch.regprog = vim_regcomp(eap->arg, RE_MAGIC + RE_STRING); regmatch.rm_ic = FALSE; if (regmatch.regprog != NULL) { /* create a new quickfix list */ qf_new_list(qi, *eap->cmdlinep); ! hgr_search_in_rtp(qi, ®match, eap->arg); vim_regfree(regmatch.regprog); qi->qf_lists[qi->qf_curlist].qf_nonevalid = FALSE; qi->qf_lists[qi->qf_curlist].qf_ptr = *** ../vim-8.0.1753/src/testdir/test_quickfix.vim 2018-04-24 13:54:56.165455234 +0200 --- src/testdir/test_quickfix.vim 2018-04-24 15:33:25.489997683 +0200 *************** *** 2302,2307 **** --- 2302,2313 ---- call assert_equal('Xtestfile2', bufname('')) call assert_equal('Editor:Emacs EmAcS', l[0].text) + " Test for unloading a buffer after vimgrep searched the buffer + %bwipe + Xvimgrep /Editor/j Xtestfile* + call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded) + call assert_equal([], getbufinfo('Xtestfile2')) + call delete('Xtestfile1') call delete('Xtestfile2') endfunc *** ../vim-8.0.1753/src/version.c 2018-04-24 15:19:00.507068755 +0200 --- src/version.c 2018-04-24 15:32:44.434240181 +0200 *************** *** 763,764 **** --- 763,766 ---- { /* Add new patch number below this line */ + /**/ + 1754, /**/ -- XML is a nice language for computers. Not for humans. /// 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 ///