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;