@@ -5942,32 +5942,227 @@ ex_cexpr(exarg_T *eap)
59425942#endif
59435943
59445944/*
5945- * ":helpgrep {pattern} "
5945+ * Get the location list for ":lhelpgrep "
59465946 */
5947- void
5948- ex_helpgrep (exarg_T * eap )
5947+ static qf_info_T *
5948+ hgr_get_ll (int * new_ll )
5949+ {
5950+ win_T * wp ;
5951+ qf_info_T * qi ;
5952+
5953+ /* If the current window is a help window, then use it */
5954+ if (bt_help (curwin -> w_buffer ))
5955+ wp = curwin ;
5956+ else
5957+ /* Find an existing help window */
5958+ FOR_ALL_WINDOWS (wp )
5959+ if (bt_help (wp -> w_buffer ))
5960+ break ;
5961+
5962+ if (wp == NULL ) /* Help window not found */
5963+ qi = NULL ;
5964+ else
5965+ qi = wp -> w_llist ;
5966+
5967+ if (qi == NULL )
5968+ {
5969+ /* Allocate a new location list for help text matches */
5970+ if ((qi = ll_new_list ()) == NULL )
5971+ return NULL ;
5972+ * new_ll = TRUE;
5973+ }
5974+
5975+ return qi ;
5976+ }
5977+
5978+ /*
5979+ * Search for a pattern in a help file.
5980+ */
5981+ static void
5982+ hgr_search_file (
5983+ qf_info_T * qi ,
5984+ char_u * fname ,
5985+ #ifdef FEAT_MBYTE
5986+ vimconv_T * p_vc ,
5987+ #endif
5988+ regmatch_T * p_regmatch )
5989+ {
5990+ FILE * fd ;
5991+ long lnum ;
5992+
5993+ fd = mch_fopen ((char * )fname , "r" );
5994+ if (fd == NULL )
5995+ return ;
5996+
5997+ lnum = 1 ;
5998+ while (!vim_fgets (IObuff , IOSIZE , fd ) && !got_int )
5999+ {
6000+ char_u * line = IObuff ;
6001+ #ifdef FEAT_MBYTE
6002+ /* Convert a line if 'encoding' is not utf-8 and
6003+ * the line contains a non-ASCII character. */
6004+ if (p_vc -> vc_type != CONV_NONE
6005+ && has_non_ascii (IObuff ))
6006+ {
6007+ line = string_convert (p_vc , IObuff , NULL );
6008+ if (line == NULL )
6009+ line = IObuff ;
6010+ }
6011+ #endif
6012+
6013+ if (vim_regexec (p_regmatch , line , (colnr_T )0 ))
6014+ {
6015+ int l = (int )STRLEN (line );
6016+
6017+ /* remove trailing CR, LF, spaces, etc. */
6018+ while (l > 0 && line [l - 1 ] <= ' ' )
6019+ line [-- l ] = NUL ;
6020+
6021+ if (qf_add_entry (qi ,
6022+ qi -> qf_curlist ,
6023+ NULL , /* dir */
6024+ fname ,
6025+ 0 ,
6026+ line ,
6027+ lnum ,
6028+ (int )(p_regmatch -> startp [0 ] - line )
6029+ + 1 , /* col */
6030+ FALSE, /* vis_col */
6031+ NULL , /* search pattern */
6032+ 0 , /* nr */
6033+ 1 , /* type */
6034+ TRUE /* valid */
6035+ ) == FAIL )
6036+ {
6037+ got_int = TRUE;
6038+ #ifdef FEAT_MBYTE
6039+ if (line != IObuff )
6040+ vim_free (line );
6041+ #endif
6042+ break ;
6043+ }
6044+ }
6045+ #ifdef FEAT_MBYTE
6046+ if (line != IObuff )
6047+ vim_free (line );
6048+ #endif
6049+ ++ lnum ;
6050+ line_breakcheck ();
6051+ }
6052+ fclose (fd );
6053+ }
6054+
6055+ /*
6056+ * Search for a pattern in all the help files in the doc directory under
6057+ * the given directory.
6058+ */
6059+ static void
6060+ hgr_search_files_in_dir (
6061+ qf_info_T * qi ,
6062+ char_u * dirname ,
6063+ regmatch_T * p_regmatch
6064+ #ifdef FEAT_MBYTE
6065+ , vimconv_T * p_vc
6066+ #endif
6067+ #ifdef FEAT_MULTI_LANG
6068+ , char_u * lang
6069+ #endif
6070+ )
59496071{
5950- regmatch_T regmatch ;
5951- char_u * save_cpo ;
5952- char_u * p ;
59536072 int fcount ;
59546073 char_u * * fnames ;
5955- FILE * fd ;
59566074 int fi ;
5957- long lnum ;
6075+
6076+ /* Find all "*.txt" and "*.??x" files in the "doc" directory. */
6077+ add_pathsep (dirname );
6078+ STRCAT (dirname , "doc/*.\\(txt\\|??x\\)" );
6079+ if (gen_expand_wildcards (1 , & dirname , & fcount ,
6080+ & fnames , EW_FILE |EW_SILENT ) == OK
6081+ && fcount > 0 )
6082+ {
6083+ for (fi = 0 ; fi < fcount && !got_int ; ++ fi )
6084+ {
6085+ #ifdef FEAT_MULTI_LANG
6086+ /* Skip files for a different language. */
6087+ if (lang != NULL
6088+ && STRNICMP (lang , fnames [fi ]
6089+ + STRLEN (fnames [fi ]) - 3 , 2 ) != 0
6090+ && !(STRNICMP (lang , "en" , 2 ) == 0
6091+ && STRNICMP ("txt" , fnames [fi ]
6092+ + STRLEN (fnames [fi ]) - 3 , 3 ) == 0 ))
6093+ continue ;
6094+ #endif
6095+
6096+ hgr_search_file (qi , fnames [fi ],
6097+ #ifdef FEAT_MBYTE
6098+ p_vc ,
6099+ #endif
6100+ p_regmatch );
6101+ }
6102+ FreeWild (fcount , fnames );
6103+ }
6104+ }
6105+
6106+ /*
6107+ * Search for a pattern in all the help files in the 'runtimepath'.
6108+ */
6109+ static void
6110+ hgr_search_in_rtp (qf_info_T * qi , regmatch_T * p_regmatch , char_u * arg )
6111+ {
6112+ char_u * p ;
59586113#ifdef FEAT_MULTI_LANG
59596114 char_u * lang ;
59606115#endif
5961- qf_info_T * qi = & ql_info ;
5962- int new_qi = FALSE;
5963- win_T * wp ;
5964- char_u * au_name = NULL ;
6116+
6117+ #ifdef FEAT_MBYTE
6118+ vimconv_T vc ;
6119+
6120+ /* Help files are in utf-8 or latin1, convert lines when 'encoding'
6121+ * differs. */
6122+ vc .vc_type = CONV_NONE ;
6123+ if (!enc_utf8 )
6124+ convert_setup (& vc , (char_u * )"utf-8" , p_enc );
6125+ #endif
59656126
59666127#ifdef FEAT_MULTI_LANG
59676128 /* Check for a specified language */
5968- lang = check_help_lang (eap -> arg );
6129+ lang = check_help_lang (arg );
59696130#endif
59706131
6132+ /* Go through all directories in 'runtimepath' */
6133+ p = p_rtp ;
6134+ while (* p != NUL && !got_int )
6135+ {
6136+ copy_option_part (& p , NameBuff , MAXPATHL , "," );
6137+
6138+ hgr_search_files_in_dir (qi , NameBuff , p_regmatch
6139+ #ifdef FEAT_MBYTE
6140+ , & vc
6141+ #endif
6142+ #ifdef FEAT_MULTI_LANG
6143+ , lang
6144+ #endif
6145+ );
6146+ }
6147+
6148+ #ifdef FEAT_MBYTE
6149+ if (vc .vc_type != CONV_NONE )
6150+ convert_setup (& vc , NULL , NULL );
6151+ #endif
6152+ }
6153+
6154+ /*
6155+ * ":helpgrep {pattern}"
6156+ */
6157+ void
6158+ ex_helpgrep (exarg_T * eap )
6159+ {
6160+ regmatch_T regmatch ;
6161+ char_u * save_cpo ;
6162+ qf_info_T * qi = & ql_info ;
6163+ int new_qi = FALSE;
6164+ char_u * au_name = NULL ;
6165+
59716166 switch (eap -> cmdidx )
59726167 {
59736168 case CMD_helpgrep : au_name = (char_u * )"helpgrep" ; break ;
@@ -5989,141 +6184,21 @@ ex_helpgrep(exarg_T *eap)
59896184
59906185 if (eap -> cmdidx == CMD_lhelpgrep )
59916186 {
5992- /* If the current window is a help window, then use it */
5993- if (bt_help (curwin -> w_buffer ))
5994- wp = curwin ;
5995- else
5996- /* Find an existing help window */
5997- FOR_ALL_WINDOWS (wp )
5998- if (bt_help (wp -> w_buffer ))
5999- break ;
6000-
6001- if (wp == NULL ) /* Help window not found */
6002- qi = NULL ;
6003- else
6004- qi = wp -> w_llist ;
6005-
6187+ qi = hgr_get_ll (& new_qi );
60066188 if (qi == NULL )
6007- {
6008- /* Allocate a new location list for help text matches */
6009- if ((qi = ll_new_list ()) == NULL )
6010- return ;
6011- new_qi = TRUE;
6012- }
6189+ return ;
60136190 }
60146191
60156192 regmatch .regprog = vim_regcomp (eap -> arg , RE_MAGIC + RE_STRING );
60166193 regmatch .rm_ic = FALSE;
60176194 if (regmatch .regprog != NULL )
60186195 {
6019- #ifdef FEAT_MBYTE
6020- vimconv_T vc ;
6021-
6022- /* Help files are in utf-8 or latin1, convert lines when 'encoding'
6023- * differs. */
6024- vc .vc_type = CONV_NONE ;
6025- if (!enc_utf8 )
6026- convert_setup (& vc , (char_u * )"utf-8" , p_enc );
6027- #endif
6028-
60296196 /* create a new quickfix list */
60306197 qf_new_list (qi , * eap -> cmdlinep );
60316198
6032- /* Go through all directories in 'runtimepath' */
6033- p = p_rtp ;
6034- while (* p != NUL && !got_int )
6035- {
6036- copy_option_part (& p , NameBuff , MAXPATHL , "," );
6037-
6038- /* Find all "*.txt" and "*.??x" files in the "doc" directory. */
6039- add_pathsep (NameBuff );
6040- STRCAT (NameBuff , "doc/*.\\(txt\\|??x\\)" );
6041- if (gen_expand_wildcards (1 , & NameBuff , & fcount ,
6042- & fnames , EW_FILE |EW_SILENT ) == OK
6043- && fcount > 0 )
6044- {
6045- for (fi = 0 ; fi < fcount && !got_int ; ++ fi )
6046- {
6047- #ifdef FEAT_MULTI_LANG
6048- /* Skip files for a different language. */
6049- if (lang != NULL
6050- && STRNICMP (lang , fnames [fi ]
6051- + STRLEN (fnames [fi ]) - 3 , 2 ) != 0
6052- && !(STRNICMP (lang , "en" , 2 ) == 0
6053- && STRNICMP ("txt" , fnames [fi ]
6054- + STRLEN (fnames [fi ]) - 3 , 3 ) == 0 ))
6055- continue ;
6056- #endif
6057- fd = mch_fopen ((char * )fnames [fi ], "r" );
6058- if (fd != NULL )
6059- {
6060- lnum = 1 ;
6061- while (!vim_fgets (IObuff , IOSIZE , fd ) && !got_int )
6062- {
6063- char_u * line = IObuff ;
6064- #ifdef FEAT_MBYTE
6065- /* Convert a line if 'encoding' is not utf-8 and
6066- * the line contains a non-ASCII character. */
6067- if (vc .vc_type != CONV_NONE
6068- && has_non_ascii (IObuff ))
6069- {
6070- line = string_convert (& vc , IObuff , NULL );
6071- if (line == NULL )
6072- line = IObuff ;
6073- }
6074- #endif
6075-
6076- if (vim_regexec (& regmatch , line , (colnr_T )0 ))
6077- {
6078- int l = (int )STRLEN (line );
6079-
6080- /* remove trailing CR, LF, spaces, etc. */
6081- while (l > 0 && line [l - 1 ] <= ' ' )
6082- line [-- l ] = NUL ;
6083-
6084- if (qf_add_entry (qi ,
6085- qi -> qf_curlist ,
6086- NULL , /* dir */
6087- fnames [fi ],
6088- 0 ,
6089- line ,
6090- lnum ,
6091- (int )(regmatch .startp [0 ] - line )
6092- + 1 , /* col */
6093- FALSE, /* vis_col */
6094- NULL , /* search pattern */
6095- 0 , /* nr */
6096- 1 , /* type */
6097- TRUE /* valid */
6098- ) == FAIL )
6099- {
6100- got_int = TRUE;
6101- #ifdef FEAT_MBYTE
6102- if (line != IObuff )
6103- vim_free (line );
6104- #endif
6105- break ;
6106- }
6107- }
6108- #ifdef FEAT_MBYTE
6109- if (line != IObuff )
6110- vim_free (line );
6111- #endif
6112- ++ lnum ;
6113- line_breakcheck ();
6114- }
6115- fclose (fd );
6116- }
6117- }
6118- FreeWild (fcount , fnames );
6119- }
6120- }
6199+ hgr_search_in_rtp (qi , & regmatch , eap -> arg );
61216200
61226201 vim_regfree (regmatch .regprog );
6123- #ifdef FEAT_MBYTE
6124- if (vc .vc_type != CONV_NONE )
6125- convert_setup (& vc , NULL , NULL );
6126- #endif
61276202
61286203 qi -> qf_lists [qi -> qf_curlist ].qf_nonevalid = FALSE;
61296204 qi -> qf_lists [qi -> qf_curlist ].qf_ptr =
0 commit comments