Mercurial > vim
comparison src/quickfix.c @ 13882:f48fcaa196a9 v8.0.1812
patch 8.0.1812: the qf_jump_to_usable_window() function is too long
commit https://github.com/vim/vim/commit/7a2b0e55e9460493c4a949bda8be70950dbb8f85
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu May 10 18:55:28 2018 +0200
patch 8.0.1812: the qf_jump_to_usable_window() function is too long
Problem: The qf_jump_to_usable_window() function is too long.
Solution: Split it in parts. (Yegappan Lakshmanan, closes https://github.com/vim/vim/issues/2891)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Thu, 10 May 2018 19:00:07 +0200 |
parents | 1282a54c1f5a |
children | 3b6c29f8c1a2 |
comparison
equal
deleted
inserted
replaced
13881:a0cf2482b430 | 13882:f48fcaa196a9 |
---|---|
2025 * found. | 2025 * found. |
2026 * Returns a pointer to the directory name or NULL if not found. | 2026 * Returns a pointer to the directory name or NULL if not found. |
2027 * Cleans up intermediate directory entries. | 2027 * Cleans up intermediate directory entries. |
2028 * | 2028 * |
2029 * TODO: How to solve the following problem? | 2029 * TODO: How to solve the following problem? |
2030 * If we have the this directory tree: | 2030 * If we have this directory tree: |
2031 * ./ | 2031 * ./ |
2032 * ./aa | 2032 * ./aa |
2033 * ./aa/bb | 2033 * ./aa/bb |
2034 * ./bb | 2034 * ./bb |
2035 * ./bb/x.c | 2035 * ./bb/x.c |
2077 qfl->qf_dir_stack->next = qfl->qf_dir_stack->next->next; | 2077 qfl->qf_dir_stack->next = qfl->qf_dir_stack->next->next; |
2078 vim_free(ds_tmp->dirname); | 2078 vim_free(ds_tmp->dirname); |
2079 vim_free(ds_tmp); | 2079 vim_free(ds_tmp); |
2080 } | 2080 } |
2081 | 2081 |
2082 return ds_ptr==NULL? NULL: ds_ptr->dirname; | 2082 return ds_ptr == NULL ? NULL : ds_ptr->dirname; |
2083 } | 2083 } |
2084 | 2084 |
2085 /* | 2085 /* |
2086 * Returns TRUE if a quickfix/location list with the given identifier exists. | 2086 * Returns TRUE if a quickfix/location list with the given identifier exists. |
2087 */ | 2087 */ |
2106 } | 2106 } |
2107 | 2107 |
2108 /* | 2108 /* |
2109 * When loading a file from the quickfix, the auto commands may modify it. | 2109 * When loading a file from the quickfix, the auto commands may modify it. |
2110 * This may invalidate the current quickfix entry. This function checks | 2110 * This may invalidate the current quickfix entry. This function checks |
2111 * whether a entry is still present in the quickfix. | 2111 * whether an entry is still present in the quickfix list. |
2112 * Similar to location list. | 2112 * Similar to location list. |
2113 */ | 2113 */ |
2114 static int | 2114 static int |
2115 is_qf_entry_present(qf_info_T *qi, qfline_T *qf_ptr) | 2115 is_qf_entry_present(qf_info_T *qi, qfline_T *qf_ptr) |
2116 { | 2116 { |
2271 *cur_qfidx = qf_idx; | 2271 *cur_qfidx = qf_idx; |
2272 return qf_ptr; | 2272 return qf_ptr; |
2273 } | 2273 } |
2274 | 2274 |
2275 /* | 2275 /* |
2276 * Find a window displaying a Vim help file. | |
2277 */ | |
2278 static win_T * | |
2279 qf_find_help_win(void) | |
2280 { | |
2281 win_T *wp; | |
2282 | |
2283 FOR_ALL_WINDOWS(wp) | |
2284 if (bt_help(wp->w_buffer)) | |
2285 return wp; | |
2286 | |
2287 return NULL; | |
2288 } | |
2289 | |
2290 /* | |
2276 * Find a help window or open one. | 2291 * Find a help window or open one. |
2277 */ | 2292 */ |
2278 static int | 2293 static int |
2279 jump_to_help_window(qf_info_T *qi, int *opened_window) | 2294 jump_to_help_window(qf_info_T *qi, int *opened_window) |
2280 { | 2295 { |
2282 int flags; | 2297 int flags; |
2283 | 2298 |
2284 if (cmdmod.tab != 0) | 2299 if (cmdmod.tab != 0) |
2285 wp = NULL; | 2300 wp = NULL; |
2286 else | 2301 else |
2287 FOR_ALL_WINDOWS(wp) | 2302 wp = qf_find_help_win(); |
2288 if (bt_help(wp->w_buffer)) | |
2289 break; | |
2290 if (wp != NULL && wp->w_buffer->b_nwindows > 0) | 2303 if (wp != NULL && wp->w_buffer->b_nwindows > 0) |
2291 win_enter(wp, TRUE); | 2304 win_enter(wp, TRUE); |
2292 else | 2305 else |
2293 { | 2306 { |
2294 /* | 2307 /* |
2323 | 2336 |
2324 return OK; | 2337 return OK; |
2325 } | 2338 } |
2326 | 2339 |
2327 /* | 2340 /* |
2328 * Find a suitable window for opening a file (qf_fnum) and jump to it. | 2341 * Find a non-quickfix window using the given location list. |
2329 * If the file is already opened in a window, jump to it. | 2342 * Returns NULL if a matching window is not found. |
2343 */ | |
2344 static win_T * | |
2345 qf_find_win_with_loclist(qf_info_T *ll) | |
2346 { | |
2347 win_T *wp; | |
2348 | |
2349 FOR_ALL_WINDOWS(wp) | |
2350 if (wp->w_llist == ll && !bt_quickfix(wp->w_buffer)) | |
2351 return wp; | |
2352 | |
2353 return NULL; | |
2354 } | |
2355 | |
2356 /* | |
2357 * Find a window containing a normal buffer | |
2358 */ | |
2359 static win_T * | |
2360 qf_find_win_with_normal_buf(void) | |
2361 { | |
2362 win_T *wp; | |
2363 | |
2364 FOR_ALL_WINDOWS(wp) | |
2365 if (wp->w_buffer->b_p_bt[0] == NUL) | |
2366 return wp; | |
2367 | |
2368 return NULL; | |
2369 } | |
2370 | |
2371 /* | |
2372 * Go to a window in any tabpage containing the specified file. Returns TRUE | |
2373 * if successfully jumped to the window. Otherwise returns FALSE. | |
2374 */ | |
2375 static int | |
2376 qf_goto_tabwin_with_file(int fnum) | |
2377 { | |
2378 tabpage_T *tp; | |
2379 win_T *wp; | |
2380 | |
2381 FOR_ALL_TAB_WINDOWS(tp, wp) | |
2382 if (wp->w_buffer->b_fnum == fnum) | |
2383 { | |
2384 goto_tabpage_win(tp, wp); | |
2385 return TRUE; | |
2386 } | |
2387 | |
2388 return FALSE; | |
2389 } | |
2390 | |
2391 /* | |
2392 * Create a new window to show a file above the quickfix window. Called when | |
2393 * only the quickfix window is present. | |
2394 */ | |
2395 static int | |
2396 qf_open_new_file_win(qf_info_T *ll_ref) | |
2397 { | |
2398 int flags; | |
2399 | |
2400 flags = WSP_ABOVE; | |
2401 if (ll_ref != NULL) | |
2402 flags |= WSP_NEWLOC; | |
2403 if (win_split(0, flags) == FAIL) | |
2404 return FAIL; /* not enough room for window */ | |
2405 p_swb = empty_option; /* don't split again */ | |
2406 swb_flags = 0; | |
2407 RESET_BINDING(curwin); | |
2408 if (ll_ref != NULL) | |
2409 { | |
2410 /* The new window should use the location list from the | |
2411 * location list window */ | |
2412 curwin->w_llist = ll_ref; | |
2413 ll_ref->qf_refcount++; | |
2414 } | |
2415 return OK; | |
2416 } | |
2417 | |
2418 /* | |
2419 * Go to a window that shows the right buffer. If the window is not found, go | |
2420 * to the window just above the location list window. This is used for opening | |
2421 * a file from a location window and not from a quickfix window. If some usable | |
2422 * window is previously found, then it is supplied in 'use_win'. | |
2423 */ | |
2424 static void | |
2425 qf_goto_win_with_ll_file(win_T *use_win, int qf_fnum, qf_info_T *ll_ref) | |
2426 { | |
2427 win_T *win = use_win; | |
2428 | |
2429 if (win == NULL) | |
2430 { | |
2431 /* Find the window showing the selected file */ | |
2432 FOR_ALL_WINDOWS(win) | |
2433 if (win->w_buffer->b_fnum == qf_fnum) | |
2434 break; | |
2435 if (win == NULL) | |
2436 { | |
2437 /* Find a previous usable window */ | |
2438 win = curwin; | |
2439 do | |
2440 { | |
2441 if (win->w_buffer->b_p_bt[0] == NUL) | |
2442 break; | |
2443 if (win->w_prev == NULL) | |
2444 win = lastwin; /* wrap around the top */ | |
2445 else | |
2446 win = win->w_prev; /* go to previous window */ | |
2447 } while (win != curwin); | |
2448 } | |
2449 } | |
2450 win_goto(win); | |
2451 | |
2452 /* If the location list for the window is not set, then set it | |
2453 * to the location list from the location window */ | |
2454 if (win->w_llist == NULL) | |
2455 { | |
2456 win->w_llist = ll_ref; | |
2457 ll_ref->qf_refcount++; | |
2458 } | |
2459 } | |
2460 | |
2461 /* | |
2462 * Go to a window that shows the specified file. If a window is not found, go | |
2463 * to the window just above the quickfix window. This is used for opening a | |
2464 * file from a quickfix window and not from a location window. | |
2465 */ | |
2466 static void | |
2467 qf_goto_win_with_qfl_file(int qf_fnum) | |
2468 { | |
2469 win_T *win; | |
2470 win_T *altwin; | |
2471 | |
2472 win = curwin; | |
2473 altwin = NULL; | |
2474 for (;;) | |
2475 { | |
2476 if (win->w_buffer->b_fnum == qf_fnum) | |
2477 break; | |
2478 if (win->w_prev == NULL) | |
2479 win = lastwin; /* wrap around the top */ | |
2480 else | |
2481 win = win->w_prev; /* go to previous window */ | |
2482 | |
2483 if (IS_QF_WINDOW(win)) | |
2484 { | |
2485 /* Didn't find it, go to the window before the quickfix | |
2486 * window. */ | |
2487 if (altwin != NULL) | |
2488 win = altwin; | |
2489 else if (curwin->w_prev != NULL) | |
2490 win = curwin->w_prev; | |
2491 else | |
2492 win = curwin->w_next; | |
2493 break; | |
2494 } | |
2495 | |
2496 /* Remember a usable window. */ | |
2497 if (altwin == NULL && !win->w_p_pvw | |
2498 && win->w_buffer->b_p_bt[0] == NUL) | |
2499 altwin = win; | |
2500 } | |
2501 | |
2502 win_goto(win); | |
2503 } | |
2504 | |
2505 /* | |
2506 * Find a suitable window for opening a file (qf_fnum) from the | |
2507 * quickfix/location list and jump to it. If the file is already opened in a | |
2508 * window, jump to it. Otherwise open a new window to display the file. This is | |
2509 * called from either a quickfix or a location list window. | |
2330 */ | 2510 */ |
2331 static int | 2511 static int |
2332 qf_jump_to_usable_window(int qf_fnum, int *opened_window) | 2512 qf_jump_to_usable_window(int qf_fnum, int *opened_window) |
2333 { | 2513 { |
2334 win_T *usable_win_ptr = NULL; | 2514 win_T *usable_win_ptr = NULL; |
2335 int usable_win; | 2515 int usable_win; |
2336 qf_info_T *ll_ref; | 2516 qf_info_T *ll_ref; |
2337 int flags; | |
2338 win_T *win; | 2517 win_T *win; |
2339 win_T *altwin; | |
2340 | 2518 |
2341 usable_win = 0; | 2519 usable_win = 0; |
2342 | 2520 |
2343 ll_ref = curwin->w_llist_ref; | 2521 ll_ref = curwin->w_llist_ref; |
2344 if (ll_ref != NULL) | 2522 if (ll_ref != NULL) |
2345 { | 2523 { |
2346 /* Find a window using the same location list that is not a | 2524 /* Find a non-quickfix window with this location list */ |
2347 * quickfix window. */ | 2525 usable_win_ptr = qf_find_win_with_loclist(ll_ref); |
2348 FOR_ALL_WINDOWS(usable_win_ptr) | 2526 if (usable_win_ptr != NULL) |
2349 if (usable_win_ptr->w_llist == ll_ref | 2527 usable_win = 1; |
2350 && !bt_quickfix(usable_win_ptr->w_buffer)) | |
2351 { | |
2352 usable_win = 1; | |
2353 break; | |
2354 } | |
2355 } | 2528 } |
2356 | 2529 |
2357 if (!usable_win) | 2530 if (!usable_win) |
2358 { | 2531 { |
2359 /* Locate a window showing a normal buffer */ | 2532 /* Locate a window showing a normal buffer */ |
2360 FOR_ALL_WINDOWS(win) | 2533 win = qf_find_win_with_normal_buf(); |
2361 if (win->w_buffer->b_p_bt[0] == NUL) | 2534 if (win != NULL) |
2362 { | 2535 usable_win = 1; |
2363 usable_win = 1; | |
2364 break; | |
2365 } | |
2366 } | 2536 } |
2367 | 2537 |
2368 /* | 2538 /* |
2369 * If no usable window is found and 'switchbuf' contains "usetab" | 2539 * If no usable window is found and 'switchbuf' contains "usetab" |
2370 * then search in other tabs. | 2540 * then search in other tabs. |
2371 */ | 2541 */ |
2372 if (!usable_win && (swb_flags & SWB_USETAB)) | 2542 if (!usable_win && (swb_flags & SWB_USETAB)) |
2373 { | 2543 usable_win = qf_goto_tabwin_with_file(qf_fnum); |
2374 tabpage_T *tp; | |
2375 win_T *wp; | |
2376 | |
2377 FOR_ALL_TAB_WINDOWS(tp, wp) | |
2378 { | |
2379 if (wp->w_buffer->b_fnum == qf_fnum) | |
2380 { | |
2381 goto_tabpage_win(tp, wp); | |
2382 usable_win = 1; | |
2383 goto win_found; | |
2384 } | |
2385 } | |
2386 } | |
2387 win_found: | |
2388 | 2544 |
2389 /* | 2545 /* |
2390 * If there is only one window and it is the quickfix window, create a | 2546 * If there is only one window and it is the quickfix window, create a |
2391 * new one above the quickfix window. | 2547 * new one above the quickfix window. |
2392 */ | 2548 */ |
2393 if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win) | 2549 if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win) |
2394 { | 2550 { |
2395 flags = WSP_ABOVE; | 2551 if (qf_open_new_file_win(ll_ref) != OK) |
2396 if (ll_ref != NULL) | 2552 return FAIL; |
2397 flags |= WSP_NEWLOC; | |
2398 if (win_split(0, flags) == FAIL) | |
2399 return FAIL; /* not enough room for window */ | |
2400 *opened_window = TRUE; /* close it when fail */ | 2553 *opened_window = TRUE; /* close it when fail */ |
2401 p_swb = empty_option; /* don't split again */ | |
2402 swb_flags = 0; | |
2403 RESET_BINDING(curwin); | |
2404 if (ll_ref != NULL) | |
2405 { | |
2406 /* The new window should use the location list from the | |
2407 * location list window */ | |
2408 curwin->w_llist = ll_ref; | |
2409 ll_ref->qf_refcount++; | |
2410 } | |
2411 } | 2554 } |
2412 else | 2555 else |
2413 { | 2556 { |
2414 if (curwin->w_llist_ref != NULL) | 2557 if (curwin->w_llist_ref != NULL) /* In a location window */ |
2415 { | 2558 qf_goto_win_with_ll_file(usable_win_ptr, qf_fnum, ll_ref); |
2416 /* In a location window */ | 2559 else /* In a quickfix window */ |
2417 win = usable_win_ptr; | 2560 qf_goto_win_with_qfl_file(qf_fnum); |
2418 if (win == NULL) | |
2419 { | |
2420 /* Find the window showing the selected file */ | |
2421 FOR_ALL_WINDOWS(win) | |
2422 if (win->w_buffer->b_fnum == qf_fnum) | |
2423 break; | |
2424 if (win == NULL) | |
2425 { | |
2426 /* Find a previous usable window */ | |
2427 win = curwin; | |
2428 do | |
2429 { | |
2430 if (win->w_buffer->b_p_bt[0] == NUL) | |
2431 break; | |
2432 if (win->w_prev == NULL) | |
2433 win = lastwin; /* wrap around the top */ | |
2434 else | |
2435 win = win->w_prev; /* go to previous window */ | |
2436 } while (win != curwin); | |
2437 } | |
2438 } | |
2439 win_goto(win); | |
2440 | |
2441 /* If the location list for the window is not set, then set it | |
2442 * to the location list from the location window */ | |
2443 if (win->w_llist == NULL) | |
2444 { | |
2445 win->w_llist = ll_ref; | |
2446 ll_ref->qf_refcount++; | |
2447 } | |
2448 } | |
2449 else | |
2450 { | |
2451 | |
2452 /* | |
2453 * Try to find a window that shows the right buffer. | |
2454 * Default to the window just above the quickfix buffer. | |
2455 */ | |
2456 win = curwin; | |
2457 altwin = NULL; | |
2458 for (;;) | |
2459 { | |
2460 if (win->w_buffer->b_fnum == qf_fnum) | |
2461 break; | |
2462 if (win->w_prev == NULL) | |
2463 win = lastwin; /* wrap around the top */ | |
2464 else | |
2465 win = win->w_prev; /* go to previous window */ | |
2466 | |
2467 if (IS_QF_WINDOW(win)) | |
2468 { | |
2469 /* Didn't find it, go to the window before the quickfix | |
2470 * window. */ | |
2471 if (altwin != NULL) | |
2472 win = altwin; | |
2473 else if (curwin->w_prev != NULL) | |
2474 win = curwin->w_prev; | |
2475 else | |
2476 win = curwin->w_next; | |
2477 break; | |
2478 } | |
2479 | |
2480 /* Remember a usable window. */ | |
2481 if (altwin == NULL && !win->w_p_pvw | |
2482 && win->w_buffer->b_p_bt[0] == NUL) | |
2483 altwin = win; | |
2484 } | |
2485 | |
2486 win_goto(win); | |
2487 } | |
2488 } | 2561 } |
2489 | 2562 |
2490 return OK; | 2563 return OK; |
2491 } | 2564 } |
2492 | 2565 |
2560 | 2633 |
2561 return retval; | 2634 return retval; |
2562 } | 2635 } |
2563 | 2636 |
2564 /* | 2637 /* |
2565 * Goto the error line in the current file using either line/column number or a | 2638 * Go to the error line in the current file using either line/column number or |
2566 * search pattern. | 2639 * a search pattern. |
2567 */ | 2640 */ |
2568 static void | 2641 static void |
2569 qf_jump_goto_line( | 2642 qf_jump_goto_line( |
2570 linenr_T qf_lnum, | 2643 linenr_T qf_lnum, |
2571 int qf_col, | 2644 int qf_col, |
5777 } | 5850 } |
5778 | 5851 |
5779 /* | 5852 /* |
5780 * Set quickfix/location list properties (title, items, context). | 5853 * Set quickfix/location list properties (title, items, context). |
5781 * Also used to add items from parsing a list of lines. | 5854 * Also used to add items from parsing a list of lines. |
5782 * Used by the setqflist() and setloclist() VimL functions. | 5855 * Used by the setqflist() and setloclist() Vim script functions. |
5783 */ | 5856 */ |
5784 static int | 5857 static int |
5785 qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title) | 5858 qf_set_properties(qf_info_T *qi, dict_T *what, int action, char_u *title) |
5786 { | 5859 { |
5787 dictitem_T *di; | 5860 dictitem_T *di; |
6160 /* If the current window is a help window, then use it */ | 6233 /* If the current window is a help window, then use it */ |
6161 if (bt_help(curwin->w_buffer)) | 6234 if (bt_help(curwin->w_buffer)) |
6162 wp = curwin; | 6235 wp = curwin; |
6163 else | 6236 else |
6164 /* Find an existing help window */ | 6237 /* Find an existing help window */ |
6165 FOR_ALL_WINDOWS(wp) | 6238 wp = qf_find_help_win(); |
6166 if (bt_help(wp->w_buffer)) | |
6167 break; | |
6168 | 6239 |
6169 if (wp == NULL) /* Help window not found */ | 6240 if (wp == NULL) /* Help window not found */ |
6170 qi = NULL; | 6241 qi = NULL; |
6171 else | 6242 else |
6172 qi = wp->w_llist; | 6243 qi = wp->w_llist; |