@@ -2918,7 +2918,9 @@ source_callback(char_u *fname, void *cookie UNUSED)
29182918/*
29192919 * Source the file "name" from all directories in 'runtimepath'.
29202920 * "name" can contain wildcards.
2921- * When "all" is TRUE, source all files, otherwise only the first one.
2921+ * When "flags" has DIP_ALL: source all files, otherwise only the first one.
2922+ * When "flags" has DIP_DIR: find directories instead of files.
2923+ *
29222924 * return FAIL when no file could be sourced, OK otherwise.
29232925 */
29242926 int
@@ -2927,11 +2929,14 @@ source_runtime(char_u *name, int all)
29272929 return do_in_runtimepath (name , all , source_callback , NULL );
29282930}
29292931
2932+ #define DIP_ALL 1 /* all matches, not just the first one */
2933+ #define DIP_DIR 2 /* find directories instead of files. */
2934+
29302935 static int
29312936do_in_path (
29322937 char_u * path ,
29332938 char_u * name ,
2934- int all ,
2939+ int flags ,
29352940 void (* callback )(char_u * fname , void * ck ),
29362941 void * cookie )
29372942{
@@ -2968,7 +2973,7 @@ do_in_path(
29682973
29692974 /* Loop over all entries in 'runtimepath'. */
29702975 rtp = rtp_copy ;
2971- while (* rtp != NUL && (all || !did_one ))
2976+ while (* rtp != NUL && (( flags & DIP_ALL ) || !did_one ))
29722977 {
29732978 /* Copy the path from 'runtimepath' to buf[]. */
29742979 copy_option_part (& rtp , buf , MAXPATHL , "," );
@@ -2985,7 +2990,7 @@ do_in_path(
29852990
29862991 /* Loop over all patterns in "name" */
29872992 np = name ;
2988- while (* np != NUL && (all || !did_one ))
2993+ while (* np != NUL && (( flags & DIP_ALL ) || !did_one ))
29892994 {
29902995 /* Append the pattern from "name" to buf[]. */
29912996 copy_option_part (& np , tail , (int )(MAXPATHL - (tail - buf )),
@@ -3000,13 +3005,13 @@ do_in_path(
30003005
30013006 /* Expand wildcards, invoke the callback for each match. */
30023007 if (gen_expand_wildcards (1 , & buf , & num_files , & files ,
3003- EW_FILE ) == OK )
3008+ ( flags & DIP_DIR ) ? EW_DIR : EW_FILE ) == OK )
30043009 {
30053010 for (i = 0 ; i < num_files ; ++ i )
30063011 {
30073012 (* callback )(files [i ], cookie );
30083013 did_one = TRUE;
3009- if (!all )
3014+ if (!( flags & DIP_ALL ) )
30103015 break ;
30113016 }
30123017 FreeWild (num_files , files );
@@ -3049,7 +3054,7 @@ do_in_runtimepath(
30493054 void (* callback )(char_u * fname , void * ck ),
30503055 void * cookie )
30513056{
3052- return do_in_path (p_rtp , name , all , callback , cookie );
3057+ return do_in_path (p_rtp , name , all ? DIP_ALL : 0 , callback , cookie );
30533058}
30543059
30553060/*
@@ -3065,53 +3070,66 @@ may_do_filetypes(char_u *pat)
30653070 if (cmd != NULL && eval_to_number (cmd ) > 0 )
30663071 {
30673072 do_cmdline_cmd ((char_u * )"augroup filetypedetect" );
3068- do_in_path (p_pp , pat , TRUE , source_callback , NULL );
3073+ do_in_path (p_pp , pat , DIP_ALL , source_callback , NULL );
30693074 do_cmdline_cmd ((char_u * )"augroup END" );
30703075 }
30713076 vim_free (cmd );
30723077}
30733078
30743079 static void
3075- source_pack_plugin (char_u * fname , void * cookie UNUSED )
3080+ add_pack_plugin (char_u * fname , void * cookie )
30763081{
3077- char_u * p6 , * p5 , * p4 , * p3 , * p2 , * p1 , * p ;
3078- int c ;
3079- char_u * new_rtp ;
3080- int keep ;
3081- int oldlen ;
3082- int addlen ;
3083-
3084- p6 = p5 = p4 = p3 = p2 = p1 = get_past_head (fname );
3082+ char_u * p6 , * p5 , * p4 , * p3 , * p2 , * p1 , * p ;
3083+ int c ;
3084+ char_u * new_rtp ;
3085+ int keep ;
3086+ int oldlen ;
3087+ int addlen ;
3088+ char_u * ffname = fix_fname (fname );
3089+ int load_file = cookie != NULL ;
3090+
3091+ if (ffname == NULL )
3092+ return ;
3093+ p6 = p5 = p4 = p3 = p2 = p1 = get_past_head (ffname );
30853094 for (p = p1 ; * p ; mb_ptr_adv (p ))
30863095 if (vim_ispathsep_nocolon (* p ))
30873096 {
30883097 p6 = p5 ; p5 = p4 ; p4 = p3 ; p3 = p2 ; p2 = p1 ; p1 = p ;
30893098 }
30903099
3091- /* now we have:
3100+ /* now we have, load_file == TRUE :
30923101 * rtp/pack/name/ever/name/plugin/name.vim
30933102 * p6 p5 p4 p3 p2 p1
3103+ *
3104+ * with load_file == FALSE:
3105+ * rtp/pack/name/ever/name
3106+ * p4 p3 p2 p1
30943107 */
3108+ if (load_file )
3109+ p4 = p6 ;
30953110
30963111 /* find the part up to "pack" in 'runtimepath' */
3097- c = * p6 ;
3098- * p6 = NUL ;
3099- p = (char_u * )strstr ((char * )p_rtp , (char * )fname );
3112+ c = * p4 ;
3113+ * p4 = NUL ;
3114+ p = (char_u * )strstr ((char * )p_rtp , (char * )ffname );
31003115 if (p == NULL )
31013116 /* not found, append at the end */
31023117 p = p_rtp + STRLEN (p_rtp );
31033118 else
31043119 /* append after the matching directory. */
3105- p += STRLEN (fname );
3106- * p6 = c ;
3120+ p += STRLEN (ffname );
3121+ * p4 = c ;
31073122
3108- c = * p2 ;
3109- * p2 = NUL ;
3110- if (strstr ((char * )p_rtp , (char * )fname ) == NULL )
3123+ if (load_file )
3124+ {
3125+ c = * p2 ;
3126+ * p2 = NUL ;
3127+ }
3128+ if (strstr ((char * )p_rtp , (char * )ffname ) == NULL )
31113129 {
31123130 /* directory not in 'runtimepath', add it */
31133131 oldlen = (int )STRLEN (p_rtp );
3114- addlen = (int )STRLEN (fname );
3132+ addlen = (int )STRLEN (ffname );
31153133 new_rtp = alloc (oldlen + addlen + 2 );
31163134 if (new_rtp == NULL )
31173135 {
@@ -3121,16 +3139,17 @@ source_pack_plugin(char_u *fname, void *cookie UNUSED)
31213139 keep = (int )(p - p_rtp );
31223140 mch_memmove (new_rtp , p_rtp , keep );
31233141 new_rtp [keep ] = ',' ;
3124- mch_memmove (new_rtp + keep + 1 , fname , addlen + 1 );
3142+ mch_memmove (new_rtp + keep + 1 , ffname , addlen + 1 );
31253143 if (p_rtp [keep ] != NUL )
31263144 mch_memmove (new_rtp + keep + 1 + addlen , p_rtp + keep ,
31273145 oldlen - keep + 1 );
31283146 set_option_value ((char_u * )"rtp" , 0L , new_rtp , 0 );
31293147 vim_free (new_rtp );
31303148 }
3131- * p2 = c ;
3149+ vim_free ( ffname ) ;
31323150
3133- (void )do_source (fname , FALSE, DOSO_NONE );
3151+ if (load_file )
3152+ (void )do_source (fname , FALSE, DOSO_NONE );
31343153}
31353154
31363155/*
@@ -3140,7 +3159,7 @@ source_pack_plugin(char_u *fname, void *cookie UNUSED)
31403159source_packages ()
31413160{
31423161 do_in_path (p_pp , (char_u * )"pack/*/ever/*/plugin/*.vim" ,
3143- TRUE, source_pack_plugin , NULL );
3162+ DIP_ALL , add_pack_plugin , p_pp );
31443163 may_do_filetypes ((char_u * )"pack/*/ever/*/ftdetect/*.vim" );
31453164}
31463165
@@ -3160,14 +3179,33 @@ ex_loadplugin(exarg_T *eap)
31603179 if (pat == NULL )
31613180 return ;
31623181 vim_snprintf (pat , len , plugpat , eap -> arg );
3163- do_in_path (p_pp , (char_u * )pat , TRUE, source_pack_plugin , NULL );
3182+ do_in_path (p_pp , (char_u * )pat , DIP_ALL , add_pack_plugin , p_pp );
31643183
31653184 vim_snprintf (pat , len , ftpat , eap -> arg );
31663185 may_do_filetypes ((char_u * )pat );
31673186
31683187 vim_free (pat );
31693188}
31703189
3190+ /*
3191+ * ":packadd {name}"
3192+ */
3193+ void
3194+ ex_packadd (exarg_T * eap )
3195+ {
3196+ static char * plugpat = "pack/*/opt/%s" ;
3197+ int len ;
3198+ char * pat ;
3199+
3200+ len = (int )STRLEN (plugpat ) + (int )STRLEN (eap -> arg );
3201+ pat = (char * )alloc (len );
3202+ if (pat == NULL )
3203+ return ;
3204+ vim_snprintf (pat , len , plugpat , eap -> arg );
3205+ do_in_path (p_pp , (char_u * )pat , DIP_ALL + DIP_DIR , add_pack_plugin , NULL );
3206+ vim_free (pat );
3207+ }
3208+
31713209#if defined(FEAT_EVAL ) && defined(FEAT_AUTOCMD )
31723210/*
31733211 * ":options"
0 commit comments