comparison src/quickfix.c @ 12503:4d40b2644e92 v8.0.1130

patch 8.0.1130: the qf_jump() function is still too long commit https://github.com/vim/vim/commit/9cb03716c963338f9a98d2ebc7aa3ac8b9c1eea6 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Sep 20 22:43:02 2017 +0200 patch 8.0.1130: the qf_jump() function is still too long Problem: The qf_jump() function is still too long. Solution: Split of parts to separate functions. (Yegappan Lakshmanan)
author Christian Brabandt <cb@256bit.org>
date Wed, 20 Sep 2017 22:45:04 +0200
parents 68d7bc045dbe
children 972ea22c946f
comparison
equal deleted inserted replaced
12502:ed85dd1b8c80 12503:4d40b2644e92
1952 return TRUE; 1952 return TRUE;
1953 } 1953 }
1954 1954
1955 /* 1955 /*
1956 * Get the next valid entry in the current quickfix/location list. The search 1956 * Get the next valid entry in the current quickfix/location list. The search
1957 * starts from the current entry. If next_file is TRUE, then return the next 1957 * starts from the current entry. Returns NULL on failure.
1958 * valid entry in the next file in the list. Returns NULL on failure.
1959 */ 1958 */
1960 static qfline_T * 1959 static qfline_T *
1961 get_next_valid_entry( 1960 get_next_valid_entry(
1962 qf_info_T *qi, 1961 qf_info_T *qi,
1963 qfline_T *qf_ptr, 1962 qfline_T *qf_ptr,
1985 return qf_ptr; 1984 return qf_ptr;
1986 } 1985 }
1987 1986
1988 /* 1987 /*
1989 * Get the previous valid entry in the current quickfix/location list. The 1988 * Get the previous valid entry in the current quickfix/location list. The
1990 * search starts from the current entry. If prev_file is TRUE, then return the 1989 * search starts from the current entry. Returns NULL on failure.
1991 * previous valid entry in the previous file in the list. Returns NULL on
1992 * failure.
1993 */ 1990 */
1994 static qfline_T * 1991 static qfline_T *
1995 get_prev_valid_entry( 1992 get_prev_valid_entry(
1996 qf_info_T *qi, 1993 qf_info_T *qi,
1997 qfline_T *qf_ptr, 1994 qfline_T *qf_ptr,
2063 2060
2064 return qf_ptr; 2061 return qf_ptr;
2065 } 2062 }
2066 2063
2067 /* 2064 /*
2068 * Get n'th quickfix entry 2065 * Get n'th (errornr) quickfix entry
2069 */ 2066 */
2070 static qfline_T * 2067 static qfline_T *
2071 get_nth_entry( 2068 get_nth_entry(
2072 qf_info_T *qi, 2069 qf_info_T *qi,
2073 int errornr, 2070 int errornr,
2074 qfline_T *qf_ptr, 2071 qfline_T *qf_ptr,
2075 int *qf_index) 2072 int *cur_qfidx)
2076 { 2073 {
2077 int qf_idx = *qf_index; 2074 int qf_idx = *cur_qfidx;
2078 2075
2076 /* New error number is less than the current error number */
2079 while (errornr < qf_idx && qf_idx > 1 && qf_ptr->qf_prev != NULL) 2077 while (errornr < qf_idx && qf_idx > 1 && qf_ptr->qf_prev != NULL)
2080 { 2078 {
2081 --qf_idx; 2079 --qf_idx;
2082 qf_ptr = qf_ptr->qf_prev; 2080 qf_ptr = qf_ptr->qf_prev;
2083 } 2081 }
2082 /* New error number is greater than the current error number */
2084 while (errornr > qf_idx && 2083 while (errornr > qf_idx &&
2085 qf_idx < qi->qf_lists[qi->qf_curlist].qf_count && 2084 qf_idx < qi->qf_lists[qi->qf_curlist].qf_count &&
2086 qf_ptr->qf_next != NULL) 2085 qf_ptr->qf_next != NULL)
2087 { 2086 {
2088 ++qf_idx; 2087 ++qf_idx;
2089 qf_ptr = qf_ptr->qf_next; 2088 qf_ptr = qf_ptr->qf_next;
2090 } 2089 }
2091 2090
2092 *qf_index = qf_idx; 2091 *cur_qfidx = qf_idx;
2093 return qf_ptr; 2092 return qf_ptr;
2094 } 2093 }
2095 2094
2096 /* 2095 /*
2097 * Find a help window or open one. 2096 * Find a help window or open one.
2144 2143
2145 return OK; 2144 return OK;
2146 } 2145 }
2147 2146
2148 /* 2147 /*
2149 * jump to a quickfix line 2148 * Find a suitable window for opening a file (qf_fnum) and jump to it.
2150 * if dir == FORWARD go "errornr" valid entries forward 2149 * If the file is already opened in a window, jump to it.
2151 * if dir == BACKWARD go "errornr" valid entries backward 2150 */
2152 * if dir == FORWARD_FILE go "errornr" valid entries files backward 2151 static int
2153 * if dir == BACKWARD_FILE go "errornr" valid entries files backward 2152 qf_jump_to_usable_window(int qf_fnum, int *opened_window)
2154 * else if "errornr" is zero, redisplay the same line 2153 {
2155 * else go to entry "errornr" 2154 win_T *usable_win_ptr = NULL;
2156 */ 2155 int usable_win;
2157 void 2156 qf_info_T *ll_ref;
2158 qf_jump(qf_info_T *qi, 2157 int flags;
2159 int dir, 2158 win_T *win;
2160 int errornr, 2159 win_T *altwin;
2161 int forceit) 2160
2162 { 2161 usable_win = 0;
2163 qf_info_T *ll_ref; 2162
2164 qfline_T *qf_ptr; 2163 ll_ref = curwin->w_llist_ref;
2165 qfline_T *old_qf_ptr; 2164 if (ll_ref != NULL)
2166 int qf_index; 2165 {
2167 int old_qf_index; 2166 /* Find a window using the same location list that is not a
2168 linenr_T i; 2167 * quickfix window. */
2169 buf_T *old_curbuf; 2168 FOR_ALL_WINDOWS(usable_win_ptr)
2170 linenr_T old_lnum; 2169 if (usable_win_ptr->w_llist == ll_ref
2171 colnr_T screen_col; 2170 && !bt_quickfix(usable_win_ptr->w_buffer))
2172 colnr_T char_col; 2171 {
2173 char_u *line; 2172 usable_win = 1;
2174 char_u *old_swb = p_swb; 2173 break;
2175 unsigned old_swb_flags = swb_flags; 2174 }
2176 int opened_window = FALSE; 2175 }
2177 win_T *win; 2176
2178 win_T *altwin; 2177 if (!usable_win)
2179 int flags; 2178 {
2180 win_T *oldwin = curwin; 2179 /* Locate a window showing a normal buffer */
2181 int print_message = TRUE; 2180 FOR_ALL_WINDOWS(win)
2182 int len; 2181 if (win->w_buffer->b_p_bt[0] == NUL)
2183 #ifdef FEAT_FOLDING 2182 {
2184 int old_KeyTyped = KeyTyped; /* getting file may reset it */ 2183 usable_win = 1;
2185 #endif 2184 break;
2186 int ok = OK; 2185 }
2187 int usable_win; 2186 }
2188
2189 if (qi == NULL)
2190 qi = &ql_info;
2191
2192 if (qi->qf_curlist >= qi->qf_listcount
2193 || qi->qf_lists[qi->qf_curlist].qf_count == 0)
2194 {
2195 EMSG(_(e_quickfix));
2196 return;
2197 }
2198
2199 qf_ptr = qi->qf_lists[qi->qf_curlist].qf_ptr;
2200 old_qf_ptr = qf_ptr;
2201 qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
2202 old_qf_index = qf_index;
2203 if (dir != 0) /* next/prev valid entry */
2204 {
2205 qf_ptr = get_nth_valid_entry(qi, errornr, qf_ptr, &qf_index, dir);
2206 if (qf_ptr == NULL)
2207 {
2208 qf_ptr = old_qf_ptr;
2209 qf_index = old_qf_index;
2210 goto theend;
2211 }
2212 }
2213 else if (errornr != 0) /* go to specified number */
2214 qf_ptr = get_nth_entry(qi, errornr, qf_ptr, &qf_index);
2215
2216 qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
2217 if (qf_win_pos_update(qi, old_qf_index))
2218 /* No need to print the error message if it's visible in the error
2219 * window */
2220 print_message = FALSE;
2221 2187
2222 /* 2188 /*
2223 * For ":helpgrep" find a help window or open one. 2189 * If no usable window is found and 'switchbuf' contains "usetab"
2190 * then search in other tabs.
2224 */ 2191 */
2225 if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) 2192 if (!usable_win && (swb_flags & SWB_USETAB))
2226 { 2193 {
2227 if (jump_to_help_window(qi, &opened_window) == FAIL) 2194 tabpage_T *tp;
2228 goto theend; 2195 win_T *wp;
2229 } 2196
2197 FOR_ALL_TAB_WINDOWS(tp, wp)
2198 {
2199 if (wp->w_buffer->b_fnum == qf_fnum)
2200 {
2201 goto_tabpage_win(tp, wp);
2202 usable_win = 1;
2203 goto win_found;
2204 }
2205 }
2206 }
2207 win_found:
2230 2208
2231 /* 2209 /*
2232 * If currently in the quickfix window, find another window to show the 2210 * If there is only one window and it is the quickfix window, create a
2233 * file in. 2211 * new one above the quickfix window.
2234 */ 2212 */
2235 if (bt_quickfix(curbuf) && !opened_window) 2213 if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win)
2236 { 2214 {
2237 win_T *usable_win_ptr = NULL; 2215 flags = WSP_ABOVE;
2238
2239 /*
2240 * If there is no file specified, we don't know where to go.
2241 * But do advance, otherwise ":cn" gets stuck.
2242 */
2243 if (qf_ptr->qf_fnum == 0)
2244 goto theend;
2245
2246 usable_win = 0;
2247
2248 ll_ref = curwin->w_llist_ref;
2249 if (ll_ref != NULL) 2216 if (ll_ref != NULL)
2250 { 2217 flags |= WSP_NEWLOC;
2251 /* Find a window using the same location list that is not a 2218 if (win_split(0, flags) == FAIL)
2252 * quickfix window. */ 2219 return FAIL; /* not enough room for window */
2253 FOR_ALL_WINDOWS(usable_win_ptr) 2220 *opened_window = TRUE; /* close it when fail */
2254 if (usable_win_ptr->w_llist == ll_ref 2221 p_swb = empty_option; /* don't split again */
2255 && !bt_quickfix(usable_win_ptr->w_buffer)) 2222 swb_flags = 0;
2223 RESET_BINDING(curwin);
2224 if (ll_ref != NULL)
2225 {
2226 /* The new window should use the location list from the
2227 * location list window */
2228 curwin->w_llist = ll_ref;
2229 ll_ref->qf_refcount++;
2230 }
2231 }
2232 else
2233 {
2234 if (curwin->w_llist_ref != NULL)
2235 {
2236 /* In a location window */
2237 win = usable_win_ptr;
2238 if (win == NULL)
2239 {
2240 /* Find the window showing the selected file */
2241 FOR_ALL_WINDOWS(win)
2242 if (win->w_buffer->b_fnum == qf_fnum)
2243 break;
2244 if (win == NULL)
2256 { 2245 {
2257 usable_win = 1; 2246 /* Find a previous usable window */
2258 break; 2247 win = curwin;
2259 } 2248 do
2260 } 2249 {
2261 2250 if (win->w_buffer->b_p_bt[0] == NUL)
2262 if (!usable_win) 2251 break;
2263 { 2252 if (win->w_prev == NULL)
2264 /* Locate a window showing a normal buffer */ 2253 win = lastwin; /* wrap around the top */
2265 FOR_ALL_WINDOWS(win) 2254 else
2266 if (win->w_buffer->b_p_bt[0] == NUL) 2255 win = win->w_prev; /* go to previous window */
2267 { 2256 } while (win != curwin);
2268 usable_win = 1;
2269 break;
2270 }
2271 }
2272
2273 /*
2274 * If no usable window is found and 'switchbuf' contains "usetab"
2275 * then search in other tabs.
2276 */
2277 if (!usable_win && (swb_flags & SWB_USETAB))
2278 {
2279 tabpage_T *tp;
2280 win_T *wp;
2281
2282 FOR_ALL_TAB_WINDOWS(tp, wp)
2283 {
2284 if (wp->w_buffer->b_fnum == qf_ptr->qf_fnum)
2285 {
2286 goto_tabpage_win(tp, wp);
2287 usable_win = 1;
2288 goto win_found;
2289 } 2257 }
2290 } 2258 }
2291 } 2259 win_goto(win);
2292 win_found: 2260
2293 2261 /* If the location list for the window is not set, then set it
2294 /* 2262 * to the location list from the location window */
2295 * If there is only one window and it is the quickfix window, create a 2263 if (win->w_llist == NULL)
2296 * new one above the quickfix window.
2297 */
2298 if ((ONE_WINDOW && bt_quickfix(curbuf)) || !usable_win)
2299 {
2300 flags = WSP_ABOVE;
2301 if (ll_ref != NULL)
2302 flags |= WSP_NEWLOC;
2303 if (win_split(0, flags) == FAIL)
2304 goto failed; /* not enough room for window */
2305 opened_window = TRUE; /* close it when fail */
2306 p_swb = empty_option; /* don't split again */
2307 swb_flags = 0;
2308 RESET_BINDING(curwin);
2309 if (ll_ref != NULL)
2310 { 2264 {
2311 /* The new window should use the location list from the 2265 win->w_llist = ll_ref;
2312 * location list window */
2313 curwin->w_llist = ll_ref;
2314 ll_ref->qf_refcount++; 2266 ll_ref->qf_refcount++;
2315 } 2267 }
2316 } 2268 }
2317 else 2269 else
2318 { 2270 {
2319 if (curwin->w_llist_ref != NULL)
2320 {
2321 /* In a location window */
2322 win = usable_win_ptr;
2323 if (win == NULL)
2324 {
2325 /* Find the window showing the selected file */
2326 FOR_ALL_WINDOWS(win)
2327 if (win->w_buffer->b_fnum == qf_ptr->qf_fnum)
2328 break;
2329 if (win == NULL)
2330 {
2331 /* Find a previous usable window */
2332 win = curwin;
2333 do
2334 {
2335 if (win->w_buffer->b_p_bt[0] == NUL)
2336 break;
2337 if (win->w_prev == NULL)
2338 win = lastwin; /* wrap around the top */
2339 else
2340 win = win->w_prev; /* go to previous window */
2341 } while (win != curwin);
2342 }
2343 }
2344 win_goto(win);
2345
2346 /* If the location list for the window is not set, then set it
2347 * to the location list from the location window */
2348 if (win->w_llist == NULL)
2349 {
2350 win->w_llist = ll_ref;
2351 ll_ref->qf_refcount++;
2352 }
2353 }
2354 else
2355 {
2356 2271
2357 /* 2272 /*
2358 * Try to find a window that shows the right buffer. 2273 * Try to find a window that shows the right buffer.
2359 * Default to the window just above the quickfix buffer. 2274 * Default to the window just above the quickfix buffer.
2360 */ 2275 */
2361 win = curwin; 2276 win = curwin;
2362 altwin = NULL; 2277 altwin = NULL;
2363 for (;;) 2278 for (;;)
2364 { 2279 {
2365 if (win->w_buffer->b_fnum == qf_ptr->qf_fnum) 2280 if (win->w_buffer->b_fnum == qf_fnum)
2366 break; 2281 break;
2367 if (win->w_prev == NULL) 2282 if (win->w_prev == NULL)
2368 win = lastwin; /* wrap around the top */ 2283 win = lastwin; /* wrap around the top */
2369 else 2284 else
2370 win = win->w_prev; /* go to previous window */ 2285 win = win->w_prev; /* go to previous window */
2382 break; 2297 break;
2383 } 2298 }
2384 2299
2385 /* Remember a usable window. */ 2300 /* Remember a usable window. */
2386 if (altwin == NULL && !win->w_p_pvw 2301 if (altwin == NULL && !win->w_p_pvw
2387 && win->w_buffer->b_p_bt[0] == NUL) 2302 && win->w_buffer->b_p_bt[0] == NUL)
2388 altwin = win; 2303 altwin = win;
2389 } 2304 }
2390 2305
2391 win_goto(win); 2306 win_goto(win);
2307 }
2308 }
2309
2310 return OK;
2311 }
2312
2313 /*
2314 * Edit the selected file or help file.
2315 */
2316 static int
2317 qf_jump_edit_buffer(
2318 qf_info_T *qi,
2319 qfline_T *qf_ptr,
2320 int forceit,
2321 win_T *oldwin,
2322 int *opened_window,
2323 int *abort)
2324 {
2325 int retval = OK;
2326
2327 if (qf_ptr->qf_type == 1)
2328 {
2329 /* Open help file (do_ecmd() will set b_help flag, readfile() will
2330 * set b_p_ro flag). */
2331 if (!can_abandon(curbuf, forceit))
2332 {
2333 no_write_message();
2334 retval = FALSE;
2335 }
2336 else
2337 retval = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1,
2338 ECMD_HIDE + ECMD_SET_HELP,
2339 oldwin == curwin ? curwin : NULL);
2340 }
2341 else
2342 {
2343 int old_qf_curlist = qi->qf_curlist;
2344
2345 retval = buflist_getfile(qf_ptr->qf_fnum,
2346 (linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
2347 if (qi != &ql_info && !win_valid_any_tab(oldwin))
2348 {
2349 EMSG(_("E924: Current window was closed"));
2350 *abort = TRUE;
2351 *opened_window = FALSE;
2352 }
2353 else if (old_qf_curlist != qi->qf_curlist
2354 || !is_qf_entry_present(qi, qf_ptr))
2355 {
2356 if (qi == &ql_info)
2357 EMSG(_("E925: Current quickfix was changed"));
2358 else
2359 EMSG(_("E926: Current location list was changed"));
2360 *abort = TRUE;
2361 }
2362
2363 if (*abort)
2364 retval = FALSE;
2365 }
2366
2367 return retval;
2368 }
2369
2370 /*
2371 * Goto the error line in the current file using either line/column number or a
2372 * search pattern.
2373 */
2374 static void
2375 qf_jump_goto_line(
2376 linenr_T qf_lnum,
2377 int qf_col,
2378 char_u qf_viscol,
2379 char_u *qf_pattern)
2380 {
2381 linenr_T i;
2382 char_u *line;
2383 colnr_T screen_col;
2384 colnr_T char_col;
2385
2386 if (qf_pattern == NULL)
2387 {
2388 /*
2389 * Go to line with error, unless qf_lnum is 0.
2390 */
2391 i = qf_lnum;
2392 if (i > 0)
2393 {
2394 if (i > curbuf->b_ml.ml_line_count)
2395 i = curbuf->b_ml.ml_line_count;
2396 curwin->w_cursor.lnum = i;
2397 }
2398 if (qf_col > 0)
2399 {
2400 curwin->w_cursor.col = qf_col - 1;
2401 #ifdef FEAT_VIRTUALEDIT
2402 curwin->w_cursor.coladd = 0;
2403 #endif
2404 if (qf_viscol == TRUE)
2405 {
2406 /*
2407 * Check each character from the beginning of the error
2408 * line up to the error column. For each tab character
2409 * found, reduce the error column value by the length of
2410 * a tab character.
2411 */
2412 line = ml_get_curline();
2413 screen_col = 0;
2414 for (char_col = 0; char_col < curwin->w_cursor.col; ++char_col)
2415 {
2416 if (*line == NUL)
2417 break;
2418 if (*line++ == '\t')
2419 {
2420 curwin->w_cursor.col -= 7 - (screen_col % 8);
2421 screen_col += 8 - (screen_col % 8);
2422 }
2423 else
2424 ++screen_col;
2425 }
2392 } 2426 }
2393 } 2427 check_cursor();
2428 }
2429 else
2430 beginline(BL_WHITE | BL_FIX);
2431 }
2432 else
2433 {
2434 pos_T save_cursor;
2435
2436 /* Move the cursor to the first line in the buffer */
2437 save_cursor = curwin->w_cursor;
2438 curwin->w_cursor.lnum = 0;
2439 if (!do_search(NULL, '/', qf_pattern, (long)1,
2440 SEARCH_KEEP, NULL, NULL))
2441 curwin->w_cursor = save_cursor;
2442 }
2443 }
2444
2445 /*
2446 * Display quickfix list index and size message
2447 */
2448 static void
2449 qf_jump_print_msg(
2450 qf_info_T *qi,
2451 int qf_index,
2452 qfline_T *qf_ptr,
2453 buf_T *old_curbuf,
2454 linenr_T old_lnum)
2455 {
2456 linenr_T i;
2457 int len;
2458
2459 /* Update the screen before showing the message, unless the screen
2460 * scrolled up. */
2461 if (!msg_scrolled)
2462 update_topline_redraw();
2463 sprintf((char *)IObuff, _("(%d of %d)%s%s: "), qf_index,
2464 qi->qf_lists[qi->qf_curlist].qf_count,
2465 qf_ptr->qf_cleared ? _(" (line deleted)") : "",
2466 (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
2467 /* Add the message, skipping leading whitespace and newlines. */
2468 len = (int)STRLEN(IObuff);
2469 qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len);
2470
2471 /* Output the message. Overwrite to avoid scrolling when the 'O'
2472 * flag is present in 'shortmess'; But when not jumping, print the
2473 * whole message. */
2474 i = msg_scroll;
2475 if (curbuf == old_curbuf && curwin->w_cursor.lnum == old_lnum)
2476 msg_scroll = TRUE;
2477 else if (!msg_scrolled && shortmess(SHM_OVERALL))
2478 msg_scroll = FALSE;
2479 msg_attr_keep(IObuff, 0, TRUE);
2480 msg_scroll = i;
2481 }
2482
2483 /*
2484 * jump to a quickfix line
2485 * if dir == FORWARD go "errornr" valid entries forward
2486 * if dir == BACKWARD go "errornr" valid entries backward
2487 * if dir == FORWARD_FILE go "errornr" valid entries files backward
2488 * if dir == BACKWARD_FILE go "errornr" valid entries files backward
2489 * else if "errornr" is zero, redisplay the same line
2490 * else go to entry "errornr"
2491 */
2492 void
2493 qf_jump(qf_info_T *qi,
2494 int dir,
2495 int errornr,
2496 int forceit)
2497 {
2498 qfline_T *qf_ptr;
2499 qfline_T *old_qf_ptr;
2500 int qf_index;
2501 int old_qf_index;
2502 buf_T *old_curbuf;
2503 linenr_T old_lnum;
2504 char_u *old_swb = p_swb;
2505 unsigned old_swb_flags = swb_flags;
2506 int opened_window = FALSE;
2507 win_T *oldwin = curwin;
2508 int print_message = TRUE;
2509 #ifdef FEAT_FOLDING
2510 int old_KeyTyped = KeyTyped; /* getting file may reset it */
2511 #endif
2512 int retval = OK;
2513
2514 if (qi == NULL)
2515 qi = &ql_info;
2516
2517 if (qi->qf_curlist >= qi->qf_listcount
2518 || qi->qf_lists[qi->qf_curlist].qf_count == 0)
2519 {
2520 EMSG(_(e_quickfix));
2521 return;
2522 }
2523
2524 qf_ptr = qi->qf_lists[qi->qf_curlist].qf_ptr;
2525 old_qf_ptr = qf_ptr;
2526 qf_index = qi->qf_lists[qi->qf_curlist].qf_index;
2527 old_qf_index = qf_index;
2528 if (dir != 0) /* next/prev valid entry */
2529 {
2530 qf_ptr = get_nth_valid_entry(qi, errornr, qf_ptr, &qf_index, dir);
2531 if (qf_ptr == NULL)
2532 {
2533 qf_ptr = old_qf_ptr;
2534 qf_index = old_qf_index;
2535 goto theend;
2536 }
2537 }
2538 else if (errornr != 0) /* go to specified number */
2539 qf_ptr = get_nth_entry(qi, errornr, qf_ptr, &qf_index);
2540
2541 qi->qf_lists[qi->qf_curlist].qf_index = qf_index;
2542 if (qf_win_pos_update(qi, old_qf_index))
2543 /* No need to print the error message if it's visible in the error
2544 * window */
2545 print_message = FALSE;
2546
2547 /*
2548 * For ":helpgrep" find a help window or open one.
2549 */
2550 if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0))
2551 if (jump_to_help_window(qi, &opened_window) == FAIL)
2552 goto theend;
2553
2554 /*
2555 * If currently in the quickfix window, find another window to show the
2556 * file in.
2557 */
2558 if (bt_quickfix(curbuf) && !opened_window)
2559 {
2560 /*
2561 * If there is no file specified, we don't know where to go.
2562 * But do advance, otherwise ":cn" gets stuck.
2563 */
2564 if (qf_ptr->qf_fnum == 0)
2565 goto theend;
2566
2567 if (qf_jump_to_usable_window(qf_ptr->qf_fnum, &opened_window) == FAIL)
2568 goto failed;
2394 } 2569 }
2395 2570
2396 /* 2571 /*
2397 * If there is a file name, 2572 * If there is a file name,
2398 * read the wanted file if needed, and check autowrite etc. 2573 * read the wanted file if needed, and check autowrite etc.
2400 old_curbuf = curbuf; 2575 old_curbuf = curbuf;
2401 old_lnum = curwin->w_cursor.lnum; 2576 old_lnum = curwin->w_cursor.lnum;
2402 2577
2403 if (qf_ptr->qf_fnum != 0) 2578 if (qf_ptr->qf_fnum != 0)
2404 { 2579 {
2405 if (qf_ptr->qf_type == 1) 2580 int abort = FALSE;
2406 { 2581
2407 /* Open help file (do_ecmd() will set b_help flag, readfile() will 2582 retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, oldwin,
2408 * set b_p_ro flag). */ 2583 &opened_window, &abort);
2409 if (!can_abandon(curbuf, forceit)) 2584 if (abort)
2410 { 2585 {
2411 no_write_message(); 2586 qi = NULL;
2412 ok = FALSE; 2587 qf_ptr = NULL;
2413 } 2588 }
2414 else 2589 }
2415 ok = do_ecmd(qf_ptr->qf_fnum, NULL, NULL, NULL, (linenr_T)1, 2590
2416 ECMD_HIDE + ECMD_SET_HELP, 2591 if (retval == OK)
2417 oldwin == curwin ? curwin : NULL);
2418 }
2419 else
2420 {
2421 int old_qf_curlist = qi->qf_curlist;
2422 int is_abort = FALSE;
2423
2424 ok = buflist_getfile(qf_ptr->qf_fnum,
2425 (linenr_T)1, GETF_SETMARK | GETF_SWITCH, forceit);
2426 if (qi != &ql_info && !win_valid_any_tab(oldwin))
2427 {
2428 EMSG(_("E924: Current window was closed"));
2429 is_abort = TRUE;
2430 opened_window = FALSE;
2431 }
2432 else if (old_qf_curlist != qi->qf_curlist
2433 || !is_qf_entry_present(qi, qf_ptr))
2434 {
2435 if (qi == &ql_info)
2436 EMSG(_("E925: Current quickfix was changed"));
2437 else
2438 EMSG(_("E926: Current location list was changed"));
2439 is_abort = TRUE;
2440 }
2441
2442 if (is_abort)
2443 {
2444 ok = FALSE;
2445 qi = NULL;
2446 qf_ptr = NULL;
2447 }
2448 }
2449 }
2450
2451 if (ok == OK)
2452 { 2592 {
2453 /* When not switched to another buffer, still need to set pc mark */ 2593 /* When not switched to another buffer, still need to set pc mark */
2454 if (curbuf == old_curbuf) 2594 if (curbuf == old_curbuf)
2455 setpcmark(); 2595 setpcmark();
2456 2596
2457 if (qf_ptr->qf_pattern == NULL) 2597 qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, qf_ptr->qf_viscol,
2458 { 2598 qf_ptr->qf_pattern);
2459 /*
2460 * Go to line with error, unless qf_lnum is 0.
2461 */
2462 i = qf_ptr->qf_lnum;
2463 if (i > 0)
2464 {
2465 if (i > curbuf->b_ml.ml_line_count)
2466 i = curbuf->b_ml.ml_line_count;
2467 curwin->w_cursor.lnum = i;
2468 }
2469 if (qf_ptr->qf_col > 0)
2470 {
2471 curwin->w_cursor.col = qf_ptr->qf_col - 1;
2472 #ifdef FEAT_VIRTUALEDIT
2473 curwin->w_cursor.coladd = 0;
2474 #endif
2475 if (qf_ptr->qf_viscol == TRUE)
2476 {
2477 /*
2478 * Check each character from the beginning of the error
2479 * line up to the error column. For each tab character
2480 * found, reduce the error column value by the length of
2481 * a tab character.
2482 */
2483 line = ml_get_curline();
2484 screen_col = 0;
2485 for (char_col = 0; char_col < curwin->w_cursor.col; ++char_col)
2486 {
2487 if (*line == NUL)
2488 break;
2489 if (*line++ == '\t')
2490 {
2491 curwin->w_cursor.col -= 7 - (screen_col % 8);
2492 screen_col += 8 - (screen_col % 8);
2493 }
2494 else
2495 ++screen_col;
2496 }
2497 }
2498 check_cursor();
2499 }
2500 else
2501 beginline(BL_WHITE | BL_FIX);
2502 }
2503 else
2504 {
2505 pos_T save_cursor;
2506
2507 /* Move the cursor to the first line in the buffer */
2508 save_cursor = curwin->w_cursor;
2509 curwin->w_cursor.lnum = 0;
2510 if (!do_search(NULL, '/', qf_ptr->qf_pattern, (long)1,
2511 SEARCH_KEEP, NULL, NULL))
2512 curwin->w_cursor = save_cursor;
2513 }
2514 2599
2515 #ifdef FEAT_FOLDING 2600 #ifdef FEAT_FOLDING
2516 if ((fdo_flags & FDO_QUICKFIX) && old_KeyTyped) 2601 if ((fdo_flags & FDO_QUICKFIX) && old_KeyTyped)
2517 foldOpenCursor(); 2602 foldOpenCursor();
2518 #endif 2603 #endif
2519 if (print_message) 2604 if (print_message)
2520 { 2605 qf_jump_print_msg(qi, qf_index, qf_ptr, old_curbuf, old_lnum);
2521 /* Update the screen before showing the message, unless the screen
2522 * scrolled up. */
2523 if (!msg_scrolled)
2524 update_topline_redraw();
2525 sprintf((char *)IObuff, _("(%d of %d)%s%s: "), qf_index,
2526 qi->qf_lists[qi->qf_curlist].qf_count,
2527 qf_ptr->qf_cleared ? _(" (line deleted)") : "",
2528 (char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
2529 /* Add the message, skipping leading whitespace and newlines. */
2530 len = (int)STRLEN(IObuff);
2531 qf_fmt_text(skipwhite(qf_ptr->qf_text), IObuff + len, IOSIZE - len);
2532
2533 /* Output the message. Overwrite to avoid scrolling when the 'O'
2534 * flag is present in 'shortmess'; But when not jumping, print the
2535 * whole message. */
2536 i = msg_scroll;
2537 if (curbuf == old_curbuf && curwin->w_cursor.lnum == old_lnum)
2538 msg_scroll = TRUE;
2539 else if (!msg_scrolled && shortmess(SHM_OVERALL))
2540 msg_scroll = FALSE;
2541 msg_attr_keep(IObuff, 0, TRUE);
2542 msg_scroll = i;
2543 }
2544 } 2606 }
2545 else 2607 else
2546 { 2608 {
2547 if (opened_window) 2609 if (opened_window)
2548 win_close(curwin, TRUE); /* Close opened window */ 2610 win_close(curwin, TRUE); /* Close opened window */