# HG changeset patch # User Bram Moolenaar # Date 1279119137 -7200 # Node ID ccda151dde4e5d455825204976340a3d398e3c42 # Parent 3e4574a4b6274d4513715537ac70d893d3c2ff50 Support completion for ":find". (Nazri Ramliy) Cleanup white space. diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1098,7 +1098,6 @@ Vim 7.3: - Conceal feature: no update when moving to another window. (Dominique Pelle, 2010 Jul 5) Vince will look into it. Patches to possibly include: -- Win32: patch for better font scaling. (George Reilly, 2009 Mar 26) - Patch for completion of ":find" arguments. (Nazri Ramliy, 2009 Feb 22, 26) 8 For ":find" and ":sfind" expand files found in 'path'. Update 2009 Mar 28. diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -1057,8 +1057,9 @@ mzscheme_base.c: $(OUTDIR)/xpm_w32.obj: $(OUTDIR) xpm_w32.c $(CC) $(CFLAGS) $(XPM_INC) xpm_w32.c -$(OUTDIR)/vim.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h tools.bmp tearoff.bmp \ - vim.ico vim_error.ico vim_alert.ico vim_info.ico vim_quest.ico +$(OUTDIR)/vim.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h tools.bmp \ + tearoff.bmp vim.ico vim_error.ico \ + vim_alert.ico vim_info.ico vim_quest.ico $(RC) /l 0x409 /Fo$(OUTDIR)/vim.res $(RCFLAGS) vim.rc iid_ole.c if_ole.h vim.tlb: if_ole.idl diff --git a/src/blowfish.c b/src/blowfish.c --- a/src/blowfish.c +++ b/src/blowfish.c @@ -421,7 +421,7 @@ bf_key_init(password, salt, salt_len) * See http://en.wikipedia.org/wiki/Key_strengthening. */ key = sha256_key(password, salt, salt_len); for (i = 0; i < 1000; i++) - key = sha256_key(key, salt, salt_len); + key = sha256_key(key, salt, salt_len); /* Convert the key from 64 hex chars to 32 binary chars. */ keylen = (int)STRLEN(key) / 2; @@ -432,8 +432,8 @@ bf_key_init(password, salt, salt_len) } for (i = 0; i < keylen; i++) { - sscanf((char *)&key[i * 2], "%2x", &j); - key[i] = j; + sscanf((char *)&key[i * 2], "%2x", &j); + key[i] = j; } mch_memmove(sbx, sbi, 4 * 4 * 256); @@ -534,7 +534,7 @@ bf_self_test() for (i = 0; i < bn; i++) { bf_key_init((char_u *)(bf_test_data[i].password), - bf_test_data[i].salt, + bf_test_data[i].salt, (int)STRLEN(bf_test_data[i].salt)); if (!bf_check_tables(pax, sbx, bf_test_data[i].keysum)) err++; diff --git a/src/dosinst.c b/src/dosinst.c --- a/src/dosinst.c +++ b/src/dosinst.c @@ -1370,10 +1370,10 @@ reg_create_key( *phKey = NULL; return RegCreateKeyEx( - root, subkey, - 0, NULL, REG_OPTION_NON_VOLATILE, - KEY_WOW64_64KEY | KEY_WRITE, - NULL, phKey, &disp); + root, subkey, + 0, NULL, REG_OPTION_NON_VOLATILE, + KEY_WOW64_64KEY | KEY_WRITE, + NULL, phKey, &disp); } static LONG @@ -1398,8 +1398,8 @@ reg_create_key_and_value( if (ERROR_SUCCESS == lRet) { - lRet = reg_set_string_value(hKey, value_name, data); - RegCloseKey(hKey); + lRet = reg_set_string_value(hKey, value_name, data); + RegCloseKey(hKey); } return lRet; } @@ -1419,13 +1419,13 @@ register_inproc_server( lRet = reg_create_key_and_value(hRootKey, subkey, NULL, extname); if (ERROR_SUCCESS == lRet) { - sprintf(subkey, "CLSID\\%s\\InProcServer32", clsid); - lRet = reg_create_key_and_value(hRootKey, subkey, NULL, module); - if (ERROR_SUCCESS == lRet) - { - lRet = reg_create_key_and_value(hRootKey, subkey, + sprintf(subkey, "CLSID\\%s\\InProcServer32", clsid); + lRet = reg_create_key_and_value(hRootKey, subkey, NULL, module); + if (ERROR_SUCCESS == lRet) + { + lRet = reg_create_key_and_value(hRootKey, subkey, "ThreadingModel", threading_model); - } + } } return lRet; } @@ -1438,27 +1438,27 @@ register_shellex( const char *exe_path) { LONG lRet = reg_create_key_and_value( - hRootKey, - "*\\shellex\\ContextMenuHandlers\\gvim", - NULL, - clsid); + hRootKey, + "*\\shellex\\ContextMenuHandlers\\gvim", + NULL, + clsid); if (ERROR_SUCCESS == lRet) { - lRet = reg_create_key_and_value( - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", - clsid, - name); + lRet = reg_create_key_and_value( + HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", + clsid, + name); - if (ERROR_SUCCESS == lRet) - { - lRet = reg_create_key_and_value( - HKEY_LOCAL_MACHINE, - "Software\\Vim\\Gvim", - "path", - exe_path); - } + if (ERROR_SUCCESS == lRet) + { + lRet = reg_create_key_and_value( + HKEY_LOCAL_MACHINE, + "Software\\Vim\\Gvim", + "path", + exe_path); + } } return lRet; } @@ -1469,25 +1469,25 @@ register_openwith( const char *exe_path) { LONG lRet = reg_create_key_and_value( - hRootKey, - "Applications\\gvim.exe\\shell\\edit\\command", - NULL, - exe_path); + hRootKey, + "Applications\\gvim.exe\\shell\\edit\\command", + NULL, + exe_path); if (ERROR_SUCCESS == lRet) { - int i; - static const char *openwith[] = { - ".htm\\OpenWithList\\gvim.exe", - ".vim\\OpenWithList\\gvim.exe", - "*\\OpenWithList\\gvim.exe", - }; + int i; + static const char *openwith[] = { + ".htm\\OpenWithList\\gvim.exe", + ".vim\\OpenWithList\\gvim.exe", + "*\\OpenWithList\\gvim.exe", + }; - for (i = 0; ERROR_SUCCESS == lRet + for (i = 0; ERROR_SUCCESS == lRet && i < sizeof(openwith) / sizeof(openwith[0]); i++) - { - lRet = reg_create_key_and_value(hRootKey, openwith[i], NULL, ""); - } + { + lRet = reg_create_key_and_value(hRootKey, openwith[i], NULL, ""); + } } return lRet; @@ -1504,7 +1504,7 @@ register_uninstall( "DisplayName", display_name); if (ERROR_SUCCESS == lRet) - lRet = reg_create_key_and_value(hRootKey, appname, + lRet = reg_create_key_and_value(hRootKey, appname, "UninstallString", uninstall_string); return lRet; } @@ -1521,47 +1521,47 @@ register_uninstall( install_registry(void) { #ifdef WIN3264 - LONG lRet = ERROR_SUCCESS; + LONG lRet = ERROR_SUCCESS; const char *vim_ext_ThreadingModel = "Apartment"; const char *vim_ext_name = "Vim Shell Extension"; const char *vim_ext_clsid = "{51EEE242-AD87-11d3-9C1E-0090278BBD99}"; char buf[BUFSIZE]; char vim_exe_path[BUFSIZE]; - char display_name[BUFSIZE]; - char uninstall_string[BUFSIZE]; + char display_name[BUFSIZE]; + char uninstall_string[BUFSIZE]; sprintf(vim_exe_path, "%s\\gvim.exe", installdir); if (install_popup) { - char bufg[BUFSIZE]; - struct stat st; + char bufg[BUFSIZE]; + struct stat st; - if (stat("gvimext.dll", &st) >= 0) - sprintf(bufg, "%s\\gvimext.dll", installdir); - else - /* gvimext.dll is in gvimext subdir */ - sprintf(bufg, "%s\\gvimext\\gvimext.dll", installdir); + if (stat("gvimext.dll", &st) >= 0) + sprintf(bufg, "%s\\gvimext.dll", installdir); + else + /* gvimext.dll is in gvimext subdir */ + sprintf(bufg, "%s\\gvimext\\gvimext.dll", installdir); - printf("Creating \"Edit with Vim\" popup menu entry\n"); + printf("Creating \"Edit with Vim\" popup menu entry\n"); - lRet = register_inproc_server( - HKEY_CLASSES_ROOT, vim_ext_clsid, vim_ext_name, + lRet = register_inproc_server( + HKEY_CLASSES_ROOT, vim_ext_clsid, vim_ext_name, bufg, vim_ext_ThreadingModel); - if (ERROR_SUCCESS != lRet) + if (ERROR_SUCCESS != lRet) return FAIL; - lRet = register_shellex( - HKEY_CLASSES_ROOT, vim_ext_clsid, vim_ext_name, vim_exe_path); - if (ERROR_SUCCESS != lRet) + lRet = register_shellex( + HKEY_CLASSES_ROOT, vim_ext_clsid, vim_ext_name, vim_exe_path); + if (ERROR_SUCCESS != lRet) return FAIL; } if (install_openwith) { - printf("Creating \"Open with ...\" list entry\n"); + printf("Creating \"Open with ...\" list entry\n"); - lRet = register_openwith(HKEY_CLASSES_ROOT, vim_exe_path); - if (ERROR_SUCCESS != lRet) + lRet = register_openwith(HKEY_CLASSES_ROOT, vim_exe_path); + if (ERROR_SUCCESS != lRet) return FAIL; } @@ -1570,20 +1570,20 @@ install_registry(void) /* For the NSIS installer use the generated uninstaller. */ if (interactive) { - sprintf(display_name, "Vim " VIM_VERSION_SHORT); - sprintf(uninstall_string, "%suninstal.exe", buf); + sprintf(display_name, "Vim " VIM_VERSION_SHORT); + sprintf(uninstall_string, "%suninstal.exe", buf); } else { - sprintf(display_name, "Vim " VIM_VERSION_SHORT " (self-installing)"); - sprintf(uninstall_string, "%suninstall-gui.exe", buf); + sprintf(display_name, "Vim " VIM_VERSION_SHORT " (self-installing)"); + sprintf(uninstall_string, "%suninstall-gui.exe", buf); } lRet = register_uninstall( - HKEY_LOCAL_MACHINE, - "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Vim " VIM_VERSION_SHORT, - display_name, - uninstall_string); + HKEY_LOCAL_MACHINE, + "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Vim " VIM_VERSION_SHORT, + display_name, + uninstall_string); if (ERROR_SUCCESS != lRet) return FAIL; #endif /* WIN3264 */ diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3099,8 +3099,8 @@ theend: * ECMD_FORCEIT: ! used for Ex command * ECMD_ADDBUF: don't edit, just add to buffer list * oldwin: Should be "curwin" when editing a new buffer in the current - * window, NULL when splitting the window first. When not NULL info - * of the previous buffer for "oldwin" is stored. + * window, NULL when splitting the window first. When not NULL info + * of the previous buffer for "oldwin" is stored. * * return FAIL for failure, OK otherwise */ @@ -7232,8 +7232,8 @@ set_context_in_sign_cmd(xp, arg) cmd_idx = sign_cmd_idx(arg, end_subcmd); /* :sign {subcmd} {subcmd_args} - * | - * begin_subcmd_args */ + * | + * begin_subcmd_args */ begin_subcmd_args = skipwhite(end_subcmd); p = skiptowhite(begin_subcmd_args); if (*p == NUL) @@ -7261,8 +7261,8 @@ set_context_in_sign_cmd(xp, arg) /* expand last argument of subcmd */ /* :sign define {name} {args}... - * | - * p */ + * | + * p */ /* Loop until reaching last argument. */ do @@ -7275,8 +7275,8 @@ set_context_in_sign_cmd(xp, arg) p = vim_strchr(last, '='); /* :sign define {name} {args}... {last}= - * | | - * last p */ + * | | + * last p */ if (p == NUL) { /* Expand last argument name (before equal sign). */ diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3442,6 +3442,11 @@ set_one_cmd_context(xp, buff) */ switch (ea.cmdidx) { + case CMD_find: + case CMD_sfind: + case CMD_tabfind: + xp->xp_context = EXPAND_FILES_IN_PATH; + break; case CMD_cd: case CMD_chdir: case CMD_lcd: diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4099,6 +4099,7 @@ addstar(fname, len, context) int ends_in_star; if (context != EXPAND_FILES + && context != EXPAND_FILES_IN_PATH && context != EXPAND_SHELLCMD && context != EXPAND_DIRECTORIES) { @@ -4423,7 +4424,9 @@ ExpandFromContext(xp, pat, num_file, fil if (options & WILD_SILENT) flags |= EW_SILENT; - if (xp->xp_context == EXPAND_FILES || xp->xp_context == EXPAND_DIRECTORIES) + if (xp->xp_context == EXPAND_FILES + || xp->xp_context == EXPAND_DIRECTORIES + || xp->xp_context == EXPAND_FILES_IN_PATH) { /* * Expand file or directory names. @@ -4453,6 +4456,8 @@ ExpandFromContext(xp, pat, num_file, fil if (xp->xp_context == EXPAND_FILES) flags |= EW_FILE; + else if (xp->xp_context == EXPAND_FILES_IN_PATH) + flags |= (EW_FILE | EW_PATH); else flags = (flags | EW_DIR) & ~EW_FILE; /* Expand wildcards, supporting %:h and the like. */ diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -2970,8 +2970,8 @@ prepare_crypt_read(fp) return FAIL; method = get_crypt_method((char *)buffer, CRYPT_MAGIC_LEN + - CRYPT_SEED_LEN_MAX + - CRYPT_SALT_LEN_MAX); + CRYPT_SEED_LEN_MAX + + CRYPT_SALT_LEN_MAX); if (method < 0 || method != curbuf->b_p_cm) return FAIL; diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -2941,7 +2941,7 @@ inchar(buf, maxlen, wait_time, tb_change #if defined(FEAT_NETBEANS_INTG) /* Process the queued netbeans messages. */ - netbeans_parse_messages(); + netbeans_parse_messages(); #endif if (got_int || (script_char = getc(scriptin[curscript])) < 0) diff --git a/src/gui.c b/src/gui.c --- a/src/gui.c +++ b/src/gui.c @@ -1383,7 +1383,7 @@ gui_set_shellsize(mustset, fit_to_displa int screen_h; #ifdef FEAT_GUI_GTK int un_maximize = mustset; - int did_adjust = 0; + int did_adjust = 0; #endif int x = -1, y = -1; diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -790,7 +790,7 @@ focus_in_event(GtkWidget *widget, static gint focus_out_event(GtkWidget *widget UNUSED, - GdkEventFocus *event UNUSED, + GdkEventFocus *event UNUSED, gpointer data UNUSED) { gui_focus_change(FALSE); @@ -5456,7 +5456,7 @@ gui_mch_wait_for_chars(long wtime) #if defined(FEAT_NETBEANS_INTG) /* Process the queued netbeans messages. */ - netbeans_parse_messages(); + netbeans_parse_messages(); #endif /* diff --git a/src/gui_w32.c b/src/gui_w32.c --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -2967,7 +2967,7 @@ dialog_callback( * codepage: use wide function and convert text. */ if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT && enc_codepage >= 0 && (int)GetACP() != enc_codepage) - { + { WCHAR *wp = (WCHAR *)alloc(IOSIZE * sizeof(WCHAR)); char_u *p; @@ -4828,7 +4828,7 @@ netbeans_draw_multisign_indicator(int ro int x; if (!netbeans_active()) - return; + return; x = 0; y = TEXT_Y(row); @@ -4855,10 +4855,10 @@ netbeans_init_winsock() int wsaerr; if (WSInitialized) - return; + return; wsaerr = WSAStartup(MAKEWORD(2, 2), &wsaData); if (wsaerr == 0) - WSInitialized = TRUE; + WSInitialized = TRUE; } #endif diff --git a/src/gui_w48.c b/src/gui_w48.c --- a/src/gui_w48.c +++ b/src/gui_w48.c @@ -941,7 +941,7 @@ findrep_wtoa(LPFINDREPLACE lpfr, LPFINDR if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT && enc_codepage >= 0 && (int)GetACP() != enc_codepage) { - findrep_wtoa(&s_findrep_struct, &s_findrep_struct_w); + findrep_wtoa(&s_findrep_struct, &s_findrep_struct_w); } # endif @@ -1999,7 +1999,7 @@ gui_mch_wait_for_chars(int wtime) #ifdef FEAT_NETBEANS_INTG /* Process the queued netbeans messages. */ - netbeans_parse_messages(); + netbeans_parse_messages(); #endif /* @@ -2619,7 +2619,7 @@ gui_mch_find_dialog(exarg_T *eap) if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT && enc_codepage >= 0 && (int)GetACP() != enc_codepage) { - findrep_atow(&s_findrep_struct_w, &s_findrep_struct); + findrep_atow(&s_findrep_struct_w, &s_findrep_struct); s_findrep_hwnd = FindTextW( (LPFINDREPLACEW) &s_findrep_struct_w); } diff --git a/src/gui_x11.c b/src/gui_x11.c --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -3454,7 +3454,7 @@ gui_mch_register_sign(signfile) { /* Sign width is fixed at two columns now. if (sign->width > gui.sign_width) - gui.sign_width = sign->width + 8; */ + gui.sign_width = sign->width + 8; */ } else EMSG(_(e_signdata)); diff --git a/src/gui_xmebw.c b/src/gui_xmebw.c --- a/src/gui_xmebw.c +++ b/src/gui_xmebw.c @@ -143,10 +143,10 @@ static XtResource resources[] = XmPrimitiveClassExtRec xmEnhancedButtonPrimClassExtRec = { /* next_extension */ NULL, - /* record_type */ NULLQUARK, - /* version */ XmPrimitiveClassExtVersion, - /* record_size */ sizeof(XmPrimitiveClassExtRec), - /* widget_baseline */ XmInheritBaselineProc, + /* record_type */ NULLQUARK, + /* version */ XmPrimitiveClassExtVersion, + /* record_size */ sizeof(XmPrimitiveClassExtRec), + /* widget_baseline */ XmInheritBaselineProc, /* widget_display_rect */ XmInheritDisplayRectProc, /* widget_margins */ NULL }; diff --git a/src/if_python.c b/src/if_python.c --- a/src/if_python.c +++ b/src/if_python.c @@ -1160,8 +1160,8 @@ VimToPython(typval_T *our_tv, int depth, || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL)) { sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, - our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list - : (long_u)our_tv->vval.v_dict); + our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list + : (long_u)our_tv->vval.v_dict); result = PyDict_GetItemString(lookupDict, ptrBuf); if (result != NULL) { diff --git a/src/mbyte.c b/src/mbyte.c --- a/src/mbyte.c +++ b/src/mbyte.c @@ -3177,7 +3177,7 @@ show_utf8() clen = utf_ptr2len(line + i); } sprintf((char *)IObuff + rlen, "%02x ", - (line[i] == NL) ? NUL : line[i]); /* NUL is stored as NL */ + (line[i] == NL) ? NUL : line[i]); /* NUL is stored as NL */ --clen; rlen += (int)STRLEN(IObuff + rlen); if (rlen > IOSIZE - 20) diff --git a/src/menu.c b/src/menu.c --- a/src/menu.c +++ b/src/menu.c @@ -1365,7 +1365,7 @@ get_menu_name(xp, idx) str = menu->dname; #ifdef FEAT_MULTI_LANG if (menu->en_dname == NULL) - should_advance = TRUE; + should_advance = TRUE; } #endif else @@ -1374,8 +1374,8 @@ get_menu_name(xp, idx) #ifdef FEAT_MULTI_LANG if (should_advance) #endif - /* Advance to next menu entry. */ - menu = menu->next; + /* Advance to next menu entry. */ + menu = menu->next; #ifdef FEAT_MULTI_LANG should_advance = !should_advance; @@ -1445,18 +1445,18 @@ get_menu_names(xp, idx) } else #ifdef FEAT_MULTI_LANG - { - if (should_advance) - str = menu->en_dname; - else - { + { + if (should_advance) + str = menu->en_dname; + else + { #endif - str = menu->dname; + str = menu->dname; #ifdef FEAT_MULTI_LANG - if (menu->en_dname == NULL) - should_advance = TRUE; - } - } + if (menu->en_dname == NULL) + should_advance = TRUE; + } + } #endif } else @@ -1465,8 +1465,8 @@ get_menu_names(xp, idx) #ifdef FEAT_MULTI_LANG if (should_advance) #endif - /* Advance to next menu entry. */ - menu = menu->next; + /* Advance to next menu entry. */ + menu = menu->next; #ifdef FEAT_MULTI_LANG should_advance = !should_advance; @@ -1514,7 +1514,7 @@ menu_name_equal(name, menu) if (menu->en_name != NULL && (menu_namecmp(name,menu->en_name) || menu_namecmp(name,menu->en_dname))) - return TRUE; + return TRUE; #endif return menu_namecmp(name, menu->name) || menu_namecmp(name, menu->dname); } diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -808,7 +808,7 @@ delete_first_msg() p = first_msg_hist; first_msg_hist = p->next; if (first_msg_hist == NULL) - last_msg_hist = NULL; /* history is empty */ + last_msg_hist = NULL; /* history is empty */ vim_free(p->msg); vim_free(p); --msg_hist_len; diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -9217,6 +9217,205 @@ unix_expandpath(gap, path, wildoff, flag } #endif +#if defined(FEAT_SEARCHPATH) +static int find_previous_pathsep __ARGS((char_u *path, char_u **psep)); +static int is_unique __ARGS((char_u *maybe_unique, garray_T *gap, int i)); +static void uniquefy_paths __ARGS((garray_T *gap, char_u *pattern)); +static int expand_in_path __ARGS((garray_T *gap, char_u *pattern, int flags)); + +/* + * Moves psep to the previous path separator in path, starting from the + * end of path. + * Returns FAIL is psep ends up at the beginning of path. + */ + static int +find_previous_pathsep(path, psep) + char_u *path; + char_u **psep; +{ + /* skip the current separator */ + if (*psep > path && vim_ispathsep(**psep)) + (*psep)--; + + /* find the previous separator */ + while (*psep > path && !vim_ispathsep(**psep)) + (*psep)--; + + if (*psep != path && vim_ispathsep(**psep)) + return OK; + + return FAIL; +} + +/* + * Returns TRUE if maybe_unique is unique wrt other_paths in gap. maybe_unique + * is the end portion of ((char_u **)gap->ga_data)[i]. + */ + static int +is_unique(maybe_unique, gap, i) + char_u *maybe_unique; + garray_T *gap; + int i; +{ + int j; + int candidate_len; + int other_path_len; + char_u *rival; + char_u **other_paths; + + other_paths = (gap->ga_data != NULL) ? (char_u **)gap->ga_data + : (char_u **)""; + + for (j = 0; j < gap->ga_len && !got_int; j++) + { + ui_breakcheck(); + /* don't compare it with itself */ + if (j == i) + continue; + + candidate_len = STRLEN(maybe_unique); + other_path_len = STRLEN(other_paths[j]); + + if (other_path_len < candidate_len) + continue; /* it's different */ + + rival = other_paths[j] + other_path_len - candidate_len; + + if (fnamecmp(maybe_unique, rival) == 0) + return FALSE; + } + + return TRUE; +} + +/* + * Sorts, removes duplicates and modifies all the fullpath names in gap so that + * they are unique with respect to each other while conserving the part that + * matches the pattern. Beware, this is at least O(n^2) wrt gap->ga_len. + */ + static void +uniquefy_paths(gap, pattern) + garray_T *gap; + char_u *pattern; +{ + int i; + int j; + int len; + char_u *pathsep_p; + char_u *path; + char_u **fnames = (char_u **) gap->ga_data; + + int sort_again = 0; + char_u *pat; + char_u *file_pattern; + regmatch_T regmatch; + + /* Remove duplicate entries */ + sort_strings(fnames, gap->ga_len); + for (i = 0; i < gap->ga_len - 1; i++) + if (fnamecmp(fnames[i], fnames[i+1]) == 0) + { + vim_free(fnames[i]); + for (j = i+1; j < gap->ga_len; j++) + fnames[j-1] = fnames[j]; + gap->ga_len--; + i--; + } + + /* + * We need to prepend a '*' at the beginning of file_pattern so that the + * regex matches anywhere in the path. FIXME: is this valid for all + * possible pattern? + */ + len = STRLEN(pattern); + file_pattern = alloc(len + 2); + file_pattern[0] = '*'; + file_pattern[1] = '\0'; + STRCAT(file_pattern, pattern); + pat = file_pat_to_reg_pat(file_pattern, NULL, NULL, TRUE); + vim_free(file_pattern); + regmatch.rm_ic = TRUE; /* always ignore case */ + + if (pat != NULL) + { + regmatch.regprog = vim_regcomp(pat, RE_MAGIC + RE_STRING); + vim_free(pat); + } + if (pat == NULL || regmatch.regprog == NULL) + return; + + for (i = 0; i < gap->ga_len; i++) + { + path = fnames[i]; + len = STRLEN(path); + + /* we start at the end of the path */ + pathsep_p = path + len - 1; + + while (find_previous_pathsep(path, &pathsep_p)) + if (vim_regexec(®match, pathsep_p + 1, (colnr_T)0) + && is_unique(pathsep_p, gap, i)) + { + sort_again = 1; + mch_memmove(path, pathsep_p + 1, STRLEN(pathsep_p)); + break; + } + } + + if (sort_again) + sort_strings(fnames, gap->ga_len); +} + +/* + * Calls globpath with 'path' values for the given pattern and stores + * the result in gap. + * Returns the total number of matches. + */ + static int +expand_in_path(gap, pattern, flags) + garray_T *gap; + char_u *pattern; + int flags; /* EW_* flags */ +{ + int c = 0; + char_u *path_option = *curbuf->b_p_path == NUL + ? p_path : curbuf->b_p_path; + char_u *files; + char_u *s; /* start */ + char_u *e; /* end */ + + files = globpath(path_option, pattern, 0); + if (files == NULL) + return 0; + + /* Copy each path in files into gap */ + s = e = files; + while (*s != '\0') + { + while (*e != '\n' && *e != '\0') + e++; + if (*e == '\0') + { + addfile(gap, s, flags); + break; + } + else + { + /* *e is '\n' */ + *e = '\0'; + addfile(gap, s, flags); + e++; + s = e; + } + } + + c = gap->ga_len; + vim_free(files); + + return c; +} +#endif + /* * Generic wildcard expansion code. * @@ -9325,7 +9524,14 @@ gen_expand_wildcards(num_pat, pat, num_f * when EW_NOTFOUND is given. */ if (mch_has_exp_wildcard(p)) - add_pat = mch_expandpath(&ga, p, flags); + { +#if defined(FEAT_SEARCHPATH) + if (*p != '.' && !vim_ispathsep(*p) && (flags & EW_PATH)) + add_pat = expand_in_path(&ga, p, flags); + else +#endif + add_pat = mch_expandpath(&ga, p, flags); + } } if (add_pat == -1 || (add_pat == 0 && (flags & EW_NOTFOUND))) @@ -9348,6 +9554,11 @@ gen_expand_wildcards(num_pat, pat, num_f vim_free(p); } +#if defined(FEAT_SEARCHPATH) + if (flags & EW_PATH) + uniquefy_paths(&ga, p); +#endif + *num_file = ga.ga_len; *file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data : (char_u **)""; diff --git a/src/ops.c b/src/ops.c --- a/src/ops.c +++ b/src/ops.c @@ -4292,7 +4292,7 @@ do_join(count, insert_space, save_undo) /* * Set the cursor column: * Vi compatible: use the column of the first join - * vim: use the column of the last join + * vim: use the column of the last join */ curwin->w_cursor.col = (vim_strchr(p_cpo, CPO_JOINCOL) != NULL ? currsize : col); diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -10476,8 +10476,8 @@ langmap_set_entry(from, to) int to; { langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); - int a = 0; - int b = langmap_mapga.ga_len; + int a = 0; + int b = langmap_mapga.ga_len; /* Do a binary search for an existing entry. */ while (a != b) diff --git a/src/os_mswin.c b/src/os_mswin.c --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -1240,10 +1240,10 @@ vim_open_clipboard(void) while (!OpenClipboard(NULL)) { - if (delay > 500) - return FALSE; /* waited too long, give up */ - Sleep(delay); - delay *= 2; /* wait for 10, 20, 40, 80, etc. msec */ + if (delay > 500) + return FALSE; /* waited too long, give up */ + Sleep(delay); + delay *= 2; /* wait for 10, 20, 40, 80, etc. msec */ } return TRUE; } diff --git a/src/os_unix.c b/src/os_unix.c --- a/src/os_unix.c +++ b/src/os_unix.c @@ -385,7 +385,7 @@ mch_inchar(buf, maxlen, wtime, tb_change handle_resize(); #ifdef FEAT_NETBEANS_INTG /* Process the queued netbeans messages. */ - netbeans_parse_messages(); + netbeans_parse_messages(); #endif } } @@ -419,7 +419,7 @@ mch_inchar(buf, maxlen, wtime, tb_change #ifdef FEAT_NETBEANS_INTG /* Process the queued netbeans messages. */ - netbeans_parse_messages(); + netbeans_parse_messages(); #endif /* * we want to be interrupted by the winch signal diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -3371,14 +3371,14 @@ mch_call_shell( if (!s_dont_use_vimrun) /* Use vimrun to execute the command. It opens a console * window, which can be closed without killing Vim. */ - vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s", + vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s", vimrun_path, (msg_silent != 0 || (options & SHELL_DOOUT)) ? "-s " : "", p_sh, p_shcf, cmd); else #endif - vim_snprintf((char *)newcmd, cmdlen, "%s %s %s", + vim_snprintf((char *)newcmd, cmdlen, "%s %s %s", p_sh, p_shcf, cmd); x = mch_system((char *)newcmd, options); } diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -349,9 +349,9 @@ free_search_patterns() # ifdef FEAT_RIGHTLEFT if (mr_pattern_alloced) { - vim_free(mr_pattern); - mr_pattern_alloced = FALSE; - mr_pattern = NULL; + vim_free(mr_pattern); + mr_pattern_alloced = FALSE; + mr_pattern = NULL; } # endif } diff --git a/src/sha256.c b/src/sha256.c --- a/src/sha256.c +++ b/src/sha256.c @@ -241,7 +241,7 @@ static char_u sha256_padding[64] = { void sha256_finish(ctx, digest) context_sha256_T *ctx; - char_u digest[32]; + char_u digest[32]; { UINT32_T last, padn; UINT32_T high, low; diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -8572,7 +8572,7 @@ highlight_color(id, what, modec) fg = TRUE; # ifdef FEAT_GUI else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o' - && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') + && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') font = TRUE; else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') sp = TRUE; diff --git a/src/tag.c b/src/tag.c --- a/src/tag.c +++ b/src/tag.c @@ -2551,8 +2551,8 @@ free_tag_stuff() # if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) if (ptag_entry.tagname) { - vim_free(ptag_entry.tagname); - ptag_entry.tagname = NULL; + vim_free(ptag_entry.tagname); + ptag_entry.tagname = NULL; } # endif } @@ -2678,7 +2678,7 @@ get_tagfname(tnp, first, buf) tnp->tn_search_ctx = vim_findfile_init(buf, filename, r_ptr, 100, - FALSE, /* don't free visited list */ + FALSE, /* don't free visited list */ FINDFILE_FILE, /* we search for a file */ tnp->tn_search_ctx, TRUE, curbuf->b_ffname); if (tnp->tn_search_ctx != NULL) diff --git a/src/ui.c b/src/ui.c --- a/src/ui.c +++ b/src/ui.c @@ -2998,7 +2998,7 @@ mouse_comp_pos(win, rowp, colp, lnump) if (col < 0) { #ifdef FEAT_NETBEANS_INTG - netbeans_gutter_click(lnum); + netbeans_gutter_click(lnum); #endif col = 0; } diff --git a/src/undo.c b/src/undo.c --- a/src/undo.c +++ b/src/undo.c @@ -766,7 +766,7 @@ u_get_undo_file_name(buf_ffname, reading dirp = p_udir; while (*dirp != NUL) { - dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); + dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); if (dir_len == 1 && dir_name[0] == '.') { /* Use same directory as the ffname, @@ -1135,9 +1135,9 @@ serialize_uep(fp, buf, uep) for (i = 0; i < uep->ue_size; ++i) { len = STRLEN(uep->ue_array[i]); - if (put_bytes(fp, (long_u)len, 4) == FAIL) + if (put_bytes(fp, (long_u)len, 4) == FAIL) return FAIL; - if (len > 0 && fwrite_crypt(buf, uep->ue_array[i], len, fp) != 1) + if (len > 0 && fwrite_crypt(buf, uep->ue_array[i], len, fp) != 1) return FAIL; } return OK; @@ -1317,7 +1317,7 @@ u_write_undo(name, forceit, buf, hash) if (name == NULL) { - file_name = u_get_undo_file_name(buf->b_ffname, FALSE); + file_name = u_get_undo_file_name(buf->b_ffname, FALSE); if (file_name == NULL) { if (p_verbose > 0) @@ -1331,7 +1331,7 @@ u_write_undo(name, forceit, buf, hash) } } else - file_name = name; + file_name = name; /* * Decide about the permission to use for the undo file. If the buffer @@ -1419,7 +1419,7 @@ u_write_undo(name, forceit, buf, hash) O_CREAT|O_EXTRA|O_WRONLY|O_EXCL|O_NOFOLLOW, perm); if (fd < 0) { - EMSG2(_(e_not_open), file_name); + EMSG2(_(e_not_open), file_name); goto theend; } (void)mch_setperm(file_name, perm); @@ -1457,7 +1457,7 @@ u_write_undo(name, forceit, buf, hash) fp = fdopen(fd, "w"); if (fp == NULL) { - EMSG2(_(e_not_open), file_name); + EMSG2(_(e_not_open), file_name); close(fd); mch_remove(file_name); goto theend; @@ -1483,30 +1483,30 @@ u_write_undo(name, forceit, buf, hash) uhp = buf->b_u_oldhead; while (uhp != NULL) { - /* Serialize current UHP if we haven't seen it */ - if (uhp->uh_walk != mark) - { - uhp->uh_walk = mark; + /* Serialize current UHP if we haven't seen it */ + if (uhp->uh_walk != mark) + { + uhp->uh_walk = mark; #ifdef U_DEBUG ++headers_written; #endif if (serialize_uhp(fp, buf, uhp) == FAIL) goto write_error; - } + } - /* Now walk through the tree - algorithm from undo_time(). */ - if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark) - uhp = uhp->uh_prev.ptr; - else if (uhp->uh_alt_next.ptr != NULL + /* Now walk through the tree - algorithm from undo_time(). */ + if (uhp->uh_prev.ptr != NULL && uhp->uh_prev.ptr->uh_walk != mark) + uhp = uhp->uh_prev.ptr; + else if (uhp->uh_alt_next.ptr != NULL && uhp->uh_alt_next.ptr->uh_walk != mark) - uhp = uhp->uh_alt_next.ptr; - else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL + uhp = uhp->uh_alt_next.ptr; + else if (uhp->uh_next.ptr != NULL && uhp->uh_alt_prev.ptr == NULL && uhp->uh_next.ptr->uh_walk != mark) - uhp = uhp->uh_next.ptr; - else if (uhp->uh_alt_prev.ptr != NULL) - uhp = uhp->uh_alt_prev.ptr; - else - uhp = uhp->uh_next.ptr; + uhp = uhp->uh_next.ptr; + else if (uhp->uh_alt_prev.ptr != NULL) + uhp = uhp->uh_alt_prev.ptr; + else + uhp = uhp->uh_next.ptr; } if (put_bytes(fp, (long_u)UF_HEADER_END_MAGIC, 2) == OK) @@ -1520,7 +1520,7 @@ u_write_undo(name, forceit, buf, hash) write_error: fclose(fp); if (!write_ok) - EMSG2(_("E829: write error in undo file: %s"), file_name); + EMSG2(_("E829: write error in undo file: %s"), file_name); #if defined(MACOS_CLASSIC) || defined(WIN3264) /* Copy file attributes; for systems where this can only be done after @@ -1595,7 +1595,7 @@ u_read_undo(name, hash, orig_name) if (name == NULL) { - file_name = u_get_undo_file_name(curbuf->b_ffname, TRUE); + file_name = u_get_undo_file_name(curbuf->b_ffname, TRUE); if (file_name == NULL) return; @@ -1618,7 +1618,7 @@ u_read_undo(name, hash, orig_name) #endif } else - file_name = name; + file_name = name; if (p_verbose > 0) { @@ -1630,8 +1630,8 @@ u_read_undo(name, hash, orig_name) fp = mch_fopen((char *)file_name, "r"); if (fp == NULL) { - if (name != NULL || p_verbose > 0) - EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name); + if (name != NULL || p_verbose > 0) + EMSG2(_("E822: Cannot open undo file for reading: %s"), file_name); goto error; } @@ -1642,7 +1642,7 @@ u_read_undo(name, hash, orig_name) || memcmp(magic_buf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) { EMSG2(_("E823: Not an undo file: %s"), file_name); - goto error; + goto error; } version = get2c(fp); if (version == UF_VERSION_CRYPT || version == UF_VERSION_CRYPT_PREV) @@ -1661,42 +1661,42 @@ u_read_undo(name, hash, orig_name) } do_decrypt = TRUE; #else - EMSG2(_("E827: Undo file is encrypted: %s"), file_name); - goto error; + EMSG2(_("E827: Undo file is encrypted: %s"), file_name); + goto error; #endif } else if (version != UF_VERSION && version != UF_VERSION_PREV) { - EMSG2(_("E824: Incompatible undo file: %s"), file_name); - goto error; + EMSG2(_("E824: Incompatible undo file: %s"), file_name); + goto error; } new_version = (version == UF_VERSION || version == UF_VERSION_CRYPT); if (fread(read_hash, UNDO_HASH_SIZE, 1, fp) != 1) { corruption_error("hash", file_name); - goto error; + goto error; } line_count = (linenr_T)get4c(fp); if (memcmp(hash, read_hash, UNDO_HASH_SIZE) != 0 || line_count != curbuf->b_ml.ml_line_count) { - if (p_verbose > 0 || name != NULL) - { + if (p_verbose > 0 || name != NULL) + { if (name == NULL) verbose_enter(); - give_warning((char_u *) + give_warning((char_u *) _("File contents changed, cannot use undo info"), TRUE); if (name == NULL) verbose_leave(); - } - goto error; + } + goto error; } /* Read undo data for "U" command. */ str_len = get4c(fp); if (str_len < 0) - goto error; + goto error; if (str_len > 0) line_ptr = read_string_decrypt(curbuf, fp, str_len); line_lnum = (linenr_T)get4c(fp); @@ -1788,61 +1788,61 @@ u_read_undo(name, hash, orig_name) * a pointer corresponding to the header with that sequence number. */ for (i = 0; i < num_head; i++) { - uhp = uhp_table[i]; - if (uhp == NULL) - continue; - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL && i != j + uhp = uhp_table[i]; + if (uhp == NULL) + continue; + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && i != j && uhp_table[i]->uh_seq == uhp_table[j]->uh_seq) - { + { corruption_error("duplicate uh_seq", file_name); - goto error; + goto error; } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && uhp_table[j]->uh_seq == uhp->uh_next.seq) { - uhp->uh_next.ptr = uhp_table[j]; + uhp->uh_next.ptr = uhp_table[j]; SET_FLAG(j); break; } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && uhp_table[j]->uh_seq == uhp->uh_prev.seq) { - uhp->uh_prev.ptr = uhp_table[j]; + uhp->uh_prev.ptr = uhp_table[j]; SET_FLAG(j); break; } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && uhp_table[j]->uh_seq == uhp->uh_alt_next.seq) { - uhp->uh_alt_next.ptr = uhp_table[j]; + uhp->uh_alt_next.ptr = uhp_table[j]; SET_FLAG(j); break; } - for (j = 0; j < num_head; j++) - if (uhp_table[j] != NULL + for (j = 0; j < num_head; j++) + if (uhp_table[j] != NULL && uhp_table[j]->uh_seq == uhp->uh_alt_prev.seq) { - uhp->uh_alt_prev.ptr = uhp_table[j]; + uhp->uh_alt_prev.ptr = uhp_table[j]; SET_FLAG(j); break; } - if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq) + if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq) { - old_idx = i; + old_idx = i; SET_FLAG(i); } - if (new_header_seq > 0 && new_idx < 0 && uhp->uh_seq == new_header_seq) + if (new_header_seq > 0 && new_idx < 0 && uhp->uh_seq == new_header_seq) { - new_idx = i; + new_idx = i; SET_FLAG(i); } - if (cur_header_seq > 0 && cur_idx < 0 && uhp->uh_seq == cur_header_seq) + if (cur_header_seq > 0 && cur_idx < 0 && uhp->uh_seq == cur_header_seq) { - cur_idx = i; + cur_idx = i; SET_FLAG(i); } } @@ -1881,10 +1881,10 @@ error: vim_free(line_ptr); if (uhp_table != NULL) { - for (i = 0; i < num_read_uhps; i++) - if (uhp_table[i] != NULL) + for (i = 0; i < num_read_uhps; i++) + if (uhp_table[i] != NULL) u_free_uhp(uhp_table[i]); - vim_free(uhp_table); + vim_free(uhp_table); } theend: @@ -1893,7 +1893,7 @@ theend: crypt_pop_state(); #endif if (fp != NULL) - fclose(fp); + fclose(fp); if (file_name != name) vim_free(file_name); return; diff --git a/src/vim.h b/src/vim.h --- a/src/vim.h +++ b/src/vim.h @@ -773,6 +773,7 @@ extern char *(*dyn_libintl_textdomain)(c #define EXPAND_PROFILE 35 #define EXPAND_BEHAVE 36 #define EXPAND_FILETYPE 37 +#define EXPAND_FILES_IN_PATH 38 /* Values for exmode_active (0 is no exmode) */ #define EXMODE_NORMAL 1 @@ -804,6 +805,7 @@ extern char *(*dyn_libintl_textdomain)(c #define EW_KEEPALL 0x10 /* keep all matches */ #define EW_SILENT 0x20 /* don't print "1 returned" from shell */ #define EW_EXEC 0x40 /* executable files */ +#define EW_PATH 0x80 /* search in 'path' too */ /* Note: mostly EW_NOTFOUND and EW_SILENT are mutually exclusive: EW_NOTFOUND * is used when executing commands and EW_SILENT for interactive expanding. */