Mercurial > vim
comparison src/quickfix.c @ 14838:6040d93396de v8.1.0431
patch 8.1.0431: the qf_jump() function is too long
commit https://github.com/vim/vim/commit/6dae96ef7ad56191c13c4993f04cbfd450d91ad2
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Sep 24 21:50:12 2018 +0200
patch 8.1.0431: the qf_jump() function is too long
Problem: The qf_jump() function is too long.
Solution: Refactor to split it into several functions. (Yegappan Lakshmanan)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Mon, 24 Sep 2018 22:00:06 +0200 |
parents | 74fd69162d50 |
children | a74786d0370c |
comparison
equal
deleted
inserted
replaced
14837:e6a685b2c5b2 | 14838:6040d93396de |
---|---|
2519 */ | 2519 */ |
2520 static qfline_T * | 2520 static qfline_T * |
2521 get_nth_valid_entry( | 2521 get_nth_valid_entry( |
2522 qf_list_T *qfl, | 2522 qf_list_T *qfl, |
2523 int errornr, | 2523 int errornr, |
2524 qfline_T *qf_ptr, | 2524 int dir, |
2525 int *qf_index, | 2525 int *new_qfidx) |
2526 int dir) | 2526 { |
2527 { | 2527 qfline_T *qf_ptr = qfl->qf_ptr; |
2528 int qf_idx = qfl->qf_index; | |
2528 qfline_T *prev_qf_ptr; | 2529 qfline_T *prev_qf_ptr; |
2529 int prev_index; | 2530 int prev_index; |
2530 static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); | 2531 static char_u *e_no_more_items = (char_u *)N_("E553: No more items"); |
2531 char_u *err = e_no_more_items; | 2532 char_u *err = e_no_more_items; |
2532 | 2533 |
2533 while (errornr--) | 2534 while (errornr--) |
2534 { | 2535 { |
2535 prev_qf_ptr = qf_ptr; | 2536 prev_qf_ptr = qf_ptr; |
2536 prev_index = *qf_index; | 2537 prev_index = qf_idx; |
2537 | 2538 |
2538 if (dir == FORWARD || dir == FORWARD_FILE) | 2539 if (dir == FORWARD || dir == FORWARD_FILE) |
2539 qf_ptr = get_next_valid_entry(qfl, qf_ptr, qf_index, dir); | 2540 qf_ptr = get_next_valid_entry(qfl, qf_ptr, &qf_idx, dir); |
2540 else | 2541 else |
2541 qf_ptr = get_prev_valid_entry(qfl, qf_ptr, qf_index, dir); | 2542 qf_ptr = get_prev_valid_entry(qfl, qf_ptr, &qf_idx, dir); |
2542 if (qf_ptr == NULL) | 2543 if (qf_ptr == NULL) |
2543 { | 2544 { |
2544 qf_ptr = prev_qf_ptr; | 2545 qf_ptr = prev_qf_ptr; |
2545 *qf_index = prev_index; | 2546 qf_idx = prev_index; |
2546 if (err != NULL) | 2547 if (err != NULL) |
2547 { | 2548 { |
2548 EMSG(_(err)); | 2549 EMSG(_(err)); |
2549 return NULL; | 2550 return NULL; |
2550 } | 2551 } |
2552 } | 2553 } |
2553 | 2554 |
2554 err = NULL; | 2555 err = NULL; |
2555 } | 2556 } |
2556 | 2557 |
2558 *new_qfidx = qf_idx; | |
2557 return qf_ptr; | 2559 return qf_ptr; |
2558 } | 2560 } |
2559 | 2561 |
2560 /* | 2562 /* |
2561 * Get n'th (errornr) quickfix entry | 2563 * Get n'th (errornr) quickfix entry from the current entry in the quickfix |
2564 * list 'qfl'. Returns a pointer to the new entry and the index in 'new_qfidx' | |
2562 */ | 2565 */ |
2563 static qfline_T * | 2566 static qfline_T * |
2564 get_nth_entry( | 2567 get_nth_entry(qf_list_T *qfl, int errornr, int *new_qfidx) |
2568 { | |
2569 qfline_T *qf_ptr = qfl->qf_ptr; | |
2570 int qf_idx = qfl->qf_index; | |
2571 | |
2572 // New error number is less than the current error number | |
2573 while (errornr < qf_idx && qf_idx > 1 && qf_ptr->qf_prev != NULL) | |
2574 { | |
2575 --qf_idx; | |
2576 qf_ptr = qf_ptr->qf_prev; | |
2577 } | |
2578 // New error number is greater than the current error number | |
2579 while (errornr > qf_idx && qf_idx < qfl->qf_count && | |
2580 qf_ptr->qf_next != NULL) | |
2581 { | |
2582 ++qf_idx; | |
2583 qf_ptr = qf_ptr->qf_next; | |
2584 } | |
2585 | |
2586 *new_qfidx = qf_idx; | |
2587 return qf_ptr; | |
2588 } | |
2589 | |
2590 /* | |
2591 * Get a entry specied by 'errornr' and 'dir' from the current | |
2592 * quickfix/location list. 'errornr' specifies the index of the entry and 'dir' | |
2593 * specifies the direction (FORWARD/BACKWARD/FORWARD_FILE/BACKWARD_FILE). | |
2594 * Returns a pointer to the entry and the index of the new entry is stored in | |
2595 * 'new_qfidx'. | |
2596 */ | |
2597 static qfline_T * | |
2598 qf_get_entry( | |
2565 qf_list_T *qfl, | 2599 qf_list_T *qfl, |
2566 int errornr, | 2600 int errornr, |
2567 qfline_T *qf_ptr, | 2601 int dir, |
2568 int *cur_qfidx) | 2602 int *new_qfidx) |
2569 { | 2603 { |
2570 int qf_idx = *cur_qfidx; | 2604 qfline_T *qf_ptr = qfl->qf_ptr; |
2571 | 2605 int qfidx = qfl->qf_index; |
2572 /* New error number is less than the current error number */ | 2606 |
2573 while (errornr < qf_idx && qf_idx > 1 && qf_ptr->qf_prev != NULL) | 2607 if (dir != 0) // next/prev valid entry |
2574 { | 2608 qf_ptr = get_nth_valid_entry(qfl, errornr, dir, &qfidx); |
2575 --qf_idx; | 2609 else if (errornr != 0) // go to specified number |
2576 qf_ptr = qf_ptr->qf_prev; | 2610 qf_ptr = get_nth_entry(qfl, errornr, &qfidx); |
2577 } | 2611 |
2578 /* New error number is greater than the current error number */ | 2612 *new_qfidx = qfidx; |
2579 while (errornr > qf_idx && qf_idx < qfl->qf_count && | |
2580 qf_ptr->qf_next != NULL) | |
2581 { | |
2582 ++qf_idx; | |
2583 qf_ptr = qf_ptr->qf_next; | |
2584 } | |
2585 | |
2586 *cur_qfidx = qf_idx; | |
2587 return qf_ptr; | 2613 return qf_ptr; |
2588 } | 2614 } |
2589 | 2615 |
2590 /* | 2616 /* |
2591 * Find a window displaying a Vim help file. | 2617 * Find a window displaying a Vim help file. |
2879 return OK; | 2905 return OK; |
2880 } | 2906 } |
2881 | 2907 |
2882 /* | 2908 /* |
2883 * Edit the selected file or help file. | 2909 * Edit the selected file or help file. |
2910 * Returns OK if successfully edited the file, FAIL on failing to open the | |
2911 * buffer and NOTDONE if the quickfix/location list was freed by an autocmd | |
2912 * when opening the buffer. | |
2884 */ | 2913 */ |
2885 static int | 2914 static int |
2886 qf_jump_edit_buffer( | 2915 qf_jump_edit_buffer( |
2887 qf_info_T *qi, | 2916 qf_info_T *qi, |
2888 qfline_T *qf_ptr, | 2917 qfline_T *qf_ptr, |
2889 int forceit, | 2918 int forceit, |
2890 win_T *oldwin, | 2919 win_T *oldwin, |
2891 int *opened_window, | 2920 int *opened_window) |
2892 int *abort) | |
2893 { | 2921 { |
2894 qf_list_T *qfl = &qi->qf_lists[qi->qf_curlist]; | 2922 qf_list_T *qfl = &qi->qf_lists[qi->qf_curlist]; |
2895 int retval = OK; | 2923 int retval = OK; |
2896 | 2924 |
2897 if (qf_ptr->qf_type == 1) | 2925 if (qf_ptr->qf_type == 1) |
2923 * present and the list is still valid. | 2951 * present and the list is still valid. |
2924 */ | 2952 */ |
2925 if (!win_valid_any_tab(oldwin)) | 2953 if (!win_valid_any_tab(oldwin)) |
2926 { | 2954 { |
2927 EMSG(_("E924: Current window was closed")); | 2955 EMSG(_("E924: Current window was closed")); |
2928 *abort = TRUE; | |
2929 *opened_window = FALSE; | 2956 *opened_window = FALSE; |
2957 return NOTDONE; | |
2930 } | 2958 } |
2931 else if (!qflist_valid(oldwin, save_qfid)) | 2959 else if (!qflist_valid(oldwin, save_qfid)) |
2932 { | 2960 { |
2933 EMSG(_(e_loc_list_changed)); | 2961 EMSG(_(e_loc_list_changed)); |
2934 *abort = TRUE; | 2962 return NOTDONE; |
2935 } | 2963 } |
2936 } | 2964 } |
2937 else if (old_qf_curlist != qi->qf_curlist | 2965 else if (old_qf_curlist != qi->qf_curlist |
2938 || !is_qf_entry_present(qfl, qf_ptr)) | 2966 || !is_qf_entry_present(qfl, qf_ptr)) |
2939 { | 2967 { |
2940 if (IS_QF_STACK(qi)) | 2968 if (IS_QF_STACK(qi)) |
2941 EMSG(_("E925: Current quickfix was changed")); | 2969 EMSG(_("E925: Current quickfix was changed")); |
2942 else | 2970 else |
2943 EMSG(_(e_loc_list_changed)); | 2971 EMSG(_(e_loc_list_changed)); |
2944 *abort = TRUE; | 2972 return NOTDONE; |
2945 } | 2973 } |
2946 | |
2947 if (*abort) | |
2948 retval = FAIL; | |
2949 } | 2974 } |
2950 | 2975 |
2951 return retval; | 2976 return retval; |
2952 } | 2977 } |
2953 | 2978 |
3064 msg_attr_keep(IObuff, 0, TRUE); | 3089 msg_attr_keep(IObuff, 0, TRUE); |
3065 msg_scroll = i; | 3090 msg_scroll = i; |
3066 } | 3091 } |
3067 | 3092 |
3068 /* | 3093 /* |
3094 * Find a usable window for opening a file from the quickfix/location list. If | |
3095 * a window is not found then open a new window. | |
3096 * Returns OK if successfully jumped or opened a window. Returns FAIL if not | |
3097 * able to jump/open a window. Returns NOTDONE if a file is not associated | |
3098 * with the entry. | |
3099 */ | |
3100 static int | |
3101 qf_jump_open_window(qf_info_T *qi, qfline_T *qf_ptr, int *opened_window) | |
3102 { | |
3103 // For ":helpgrep" find a help window or open one. | |
3104 if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) | |
3105 if (jump_to_help_window(qi, opened_window) == FAIL) | |
3106 return FAIL; | |
3107 | |
3108 // If currently in the quickfix window, find another window to show the | |
3109 // file in. | |
3110 if (bt_quickfix(curbuf) && !*opened_window) | |
3111 { | |
3112 // If there is no file specified, we don't know where to go. | |
3113 // But do advance, otherwise ":cn" gets stuck. | |
3114 if (qf_ptr->qf_fnum == 0) | |
3115 return NOTDONE; | |
3116 | |
3117 if (qf_jump_to_usable_window(qf_ptr->qf_fnum, opened_window) == FAIL) | |
3118 return FAIL; | |
3119 } | |
3120 | |
3121 return OK; | |
3122 } | |
3123 | |
3124 /* | |
3125 * Edit a selected file from the quickfix/location list and jump to a | |
3126 * particular line/column, adjust the folds and display a message about the | |
3127 * jump. | |
3128 * Returns OK on success and FAIL on failing to open the file/buffer. Returns | |
3129 * NOTDONE if the quickfix/location list is freed by an autocmd when opening | |
3130 * the file. | |
3131 */ | |
3132 static int | |
3133 qf_jump_to_buffer( | |
3134 qf_info_T *qi, | |
3135 int qf_index, | |
3136 qfline_T *qf_ptr, | |
3137 int forceit, | |
3138 win_T *oldwin, | |
3139 int *opened_window, | |
3140 int openfold, | |
3141 int print_message) | |
3142 { | |
3143 buf_T *old_curbuf; | |
3144 linenr_T old_lnum; | |
3145 int retval = OK; | |
3146 | |
3147 // If there is a file name, read the wanted file if needed, and check | |
3148 // autowrite etc. | |
3149 old_curbuf = curbuf; | |
3150 old_lnum = curwin->w_cursor.lnum; | |
3151 | |
3152 if (qf_ptr->qf_fnum != 0) | |
3153 { | |
3154 retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, oldwin, | |
3155 opened_window); | |
3156 if (retval != OK) | |
3157 return retval; | |
3158 } | |
3159 | |
3160 // When not switched to another buffer, still need to set pc mark | |
3161 if (curbuf == old_curbuf) | |
3162 setpcmark(); | |
3163 | |
3164 qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, qf_ptr->qf_viscol, | |
3165 qf_ptr->qf_pattern); | |
3166 | |
3167 #ifdef FEAT_FOLDING | |
3168 if ((fdo_flags & FDO_QUICKFIX) && openfold) | |
3169 foldOpenCursor(); | |
3170 #endif | |
3171 if (print_message) | |
3172 qf_jump_print_msg(qi, qf_index, qf_ptr, old_curbuf, old_lnum); | |
3173 | |
3174 return retval; | |
3175 } | |
3176 | |
3177 /* | |
3069 * jump to a quickfix line | 3178 * jump to a quickfix line |
3070 * if dir == FORWARD go "errornr" valid entries forward | 3179 * if dir == FORWARD go "errornr" valid entries forward |
3071 * if dir == BACKWARD go "errornr" valid entries backward | 3180 * if dir == BACKWARD go "errornr" valid entries backward |
3072 * if dir == FORWARD_FILE go "errornr" valid entries files backward | 3181 * if dir == FORWARD_FILE go "errornr" valid entries files backward |
3073 * if dir == BACKWARD_FILE go "errornr" valid entries files backward | 3182 * if dir == BACKWARD_FILE go "errornr" valid entries files backward |
3083 qf_list_T *qfl; | 3192 qf_list_T *qfl; |
3084 qfline_T *qf_ptr; | 3193 qfline_T *qf_ptr; |
3085 qfline_T *old_qf_ptr; | 3194 qfline_T *old_qf_ptr; |
3086 int qf_index; | 3195 int qf_index; |
3087 int old_qf_index; | 3196 int old_qf_index; |
3088 buf_T *old_curbuf; | |
3089 linenr_T old_lnum; | |
3090 char_u *old_swb = p_swb; | 3197 char_u *old_swb = p_swb; |
3091 unsigned old_swb_flags = swb_flags; | 3198 unsigned old_swb_flags = swb_flags; |
3092 int opened_window = FALSE; | 3199 int opened_window = FALSE; |
3093 win_T *oldwin = curwin; | 3200 win_T *oldwin = curwin; |
3094 int print_message = TRUE; | 3201 int print_message = TRUE; |
3095 #ifdef FEAT_FOLDING | 3202 #ifdef FEAT_FOLDING |
3096 int old_KeyTyped = KeyTyped; /* getting file may reset it */ | 3203 int old_KeyTyped = KeyTyped; // getting file may reset it |
3097 #endif | 3204 #endif |
3098 int retval = OK; | 3205 int retval = OK; |
3099 | 3206 |
3100 if (qi == NULL) | 3207 if (qi == NULL) |
3101 qi = &ql_info; | 3208 qi = &ql_info; |
3111 | 3218 |
3112 qf_ptr = qfl->qf_ptr; | 3219 qf_ptr = qfl->qf_ptr; |
3113 old_qf_ptr = qf_ptr; | 3220 old_qf_ptr = qf_ptr; |
3114 qf_index = qfl->qf_index; | 3221 qf_index = qfl->qf_index; |
3115 old_qf_index = qf_index; | 3222 old_qf_index = qf_index; |
3116 if (dir != 0) /* next/prev valid entry */ | 3223 |
3117 { | 3224 qf_ptr = qf_get_entry(qfl, errornr, dir, &qf_index); |
3118 qf_ptr = get_nth_valid_entry(qfl, errornr, qf_ptr, &qf_index, dir); | 3225 if (qf_ptr == NULL) |
3119 if (qf_ptr == NULL) | 3226 { |
3120 { | 3227 qf_ptr = old_qf_ptr; |
3121 qf_ptr = old_qf_ptr; | 3228 qf_index = old_qf_index; |
3122 qf_index = old_qf_index; | 3229 goto theend; |
3123 goto theend; | 3230 } |
3124 } | |
3125 } | |
3126 else if (errornr != 0) /* go to specified number */ | |
3127 qf_ptr = get_nth_entry(qfl, errornr, qf_ptr, &qf_index); | |
3128 | 3231 |
3129 qfl->qf_index = qf_index; | 3232 qfl->qf_index = qf_index; |
3130 if (qf_win_pos_update(qi, old_qf_index)) | 3233 if (qf_win_pos_update(qi, old_qf_index)) |
3131 /* No need to print the error message if it's visible in the error | 3234 // No need to print the error message if it's visible in the error |
3132 * window */ | 3235 // window |
3133 print_message = FALSE; | 3236 print_message = FALSE; |
3134 | 3237 |
3135 /* | 3238 retval = qf_jump_open_window(qi, qf_ptr, &opened_window); |
3136 * For ":helpgrep" find a help window or open one. | 3239 if (retval == FAIL) |
3137 */ | 3240 goto failed; |
3138 if (qf_ptr->qf_type == 1 && (!bt_help(curwin->w_buffer) || cmdmod.tab != 0)) | 3241 if (retval == NOTDONE) |
3139 if (jump_to_help_window(qi, &opened_window) == FAIL) | 3242 goto theend; |
3140 goto theend; | 3243 |
3141 | 3244 retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, oldwin, |
3142 /* | 3245 &opened_window, old_KeyTyped, print_message); |
3143 * If currently in the quickfix window, find another window to show the | 3246 if (retval == NOTDONE) |
3144 * file in. | 3247 { |
3145 */ | 3248 // Quickfix/location list is freed by an autocmd |
3146 if (bt_quickfix(curbuf) && !opened_window) | 3249 qi = NULL; |
3147 { | 3250 qf_ptr = NULL; |
3148 /* | 3251 } |
3149 * If there is no file specified, we don't know where to go. | 3252 |
3150 * But do advance, otherwise ":cn" gets stuck. | 3253 if (retval != OK) |
3151 */ | |
3152 if (qf_ptr->qf_fnum == 0) | |
3153 goto theend; | |
3154 | |
3155 if (qf_jump_to_usable_window(qf_ptr->qf_fnum, &opened_window) == FAIL) | |
3156 goto failed; | |
3157 } | |
3158 | |
3159 /* | |
3160 * If there is a file name, | |
3161 * read the wanted file if needed, and check autowrite etc. | |
3162 */ | |
3163 old_curbuf = curbuf; | |
3164 old_lnum = curwin->w_cursor.lnum; | |
3165 | |
3166 if (qf_ptr->qf_fnum != 0) | |
3167 { | |
3168 int abort = FALSE; | |
3169 | |
3170 retval = qf_jump_edit_buffer(qi, qf_ptr, forceit, oldwin, | |
3171 &opened_window, &abort); | |
3172 if (abort) | |
3173 { | |
3174 qi = NULL; | |
3175 qf_ptr = NULL; | |
3176 } | |
3177 } | |
3178 | |
3179 if (retval == OK) | |
3180 { | |
3181 /* When not switched to another buffer, still need to set pc mark */ | |
3182 if (curbuf == old_curbuf) | |
3183 setpcmark(); | |
3184 | |
3185 if (qf_ptr != NULL) | |
3186 qf_jump_goto_line(qf_ptr->qf_lnum, qf_ptr->qf_col, | |
3187 qf_ptr->qf_viscol, qf_ptr->qf_pattern); | |
3188 | |
3189 #ifdef FEAT_FOLDING | |
3190 if ((fdo_flags & FDO_QUICKFIX) && old_KeyTyped) | |
3191 foldOpenCursor(); | |
3192 #endif | |
3193 if (print_message) | |
3194 qf_jump_print_msg(qi, qf_index, qf_ptr, old_curbuf, old_lnum); | |
3195 } | |
3196 else | |
3197 { | 3254 { |
3198 if (opened_window) | 3255 if (opened_window) |
3199 win_close(curwin, TRUE); /* Close opened window */ | 3256 win_close(curwin, TRUE); // Close opened window |
3200 if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) | 3257 if (qf_ptr != NULL && qf_ptr->qf_fnum != 0) |
3201 { | 3258 { |
3202 /* | 3259 // Couldn't open file, so put index back where it was. This could |
3203 * Couldn't open file, so put index back where it was. This could | 3260 // happen if the file was readonly and we changed something. |
3204 * happen if the file was readonly and we changed something. | |
3205 */ | |
3206 failed: | 3261 failed: |
3207 qf_ptr = old_qf_ptr; | 3262 qf_ptr = old_qf_ptr; |
3208 qf_index = old_qf_index; | 3263 qf_index = old_qf_index; |
3209 } | 3264 } |
3210 } | 3265 } |
3214 qfl->qf_ptr = qf_ptr; | 3269 qfl->qf_ptr = qf_ptr; |
3215 qfl->qf_index = qf_index; | 3270 qfl->qf_index = qf_index; |
3216 } | 3271 } |
3217 if (p_swb != old_swb && opened_window) | 3272 if (p_swb != old_swb && opened_window) |
3218 { | 3273 { |
3219 /* Restore old 'switchbuf' value, but not when an autocommand or | 3274 // Restore old 'switchbuf' value, but not when an autocommand or |
3220 * modeline has changed the value. */ | 3275 // modeline has changed the value. |
3221 if (p_swb == empty_option) | 3276 if (p_swb == empty_option) |
3222 { | 3277 { |
3223 p_swb = old_swb; | 3278 p_swb = old_swb; |
3224 swb_flags = old_swb_flags; | 3279 swb_flags = old_swb_flags; |
3225 } | 3280 } |