Ticket #1823: 1823-goto-prev-line-version3.patch

File 1823-goto-prev-line-version3.patch, 10.5 KB (added by vit_r, 14 years ago)

one click choice of visited lines

  • src/editor/editcmd.c

    From f534565d75879baf4d84e851ed9f319e0d2ad7af Mon Sep 17 00:00:00 2001
    From: Vit Rosin <vit_r@list.ru>
    Date: Tue, 9 Feb 2010 10:10:25 +0000
    Subject: [PATCH]  goto prev line version3
    
    ---
     src/editor/editcmd.c |  285 +++++++++++++++++++++++++++++++++++++++++++++++++-
     1 files changed, 282 insertions(+), 3 deletions(-)
    
    diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c
    index eb11f91..2979897 100644
    a b void edit_paste_from_X_buf_cmd (WEdit * edit) 
    19821982/* 
    19831983 * Ask user for the line and go to that line. 
    19841984 * Negative numbers mean line from the end (i.e. -1 is the last line). 
    1985  */ 
     1985 * / 
    19861986void 
    19871987edit_goto_cmd (WEdit *edit) 
    19881988{ 
    19891989    char *f; 
    1990     static long line = 0;       /* line as typed, saved as default */ 
     1990    static long line = 0;       / * line as typed, saved as default * / 
    19911991    long l; 
    19921992    char *error; 
    19931993    char s[32]; 
    edit_goto_cmd (WEdit *edit) 
    20172017    edit->force |= REDRAW_COMPLETELY; 
    20182018    g_free (f); 
    20192019} 
    2020  
     2020*/ 
    20212021 
    20222022/* Return 1 on success */ 
    20232023int 
    edit_move_block_to_left (WEdit * edit) 
    28352835    } while (cur_bol >= start_bol) ; 
    28362836    edit->force |= REDRAW_PAGE; 
    28372837} 
     2838 
     2839 
     2840#define MAXGOTOSHOW 3 
     2841#define MAXGOTOTYPED 12 
     2842 
     2843void gtl_mem_fail (const char *msg, const char *funcname, const char *filename, const long line_n); 
     2844char *gtl_lines_saved_as_str (WEdit * edit, const long *nbrs_stored, int n_last); 
     2845void gtl_gothis_nbr (WEdit * edit, long realgo_nbr); 
     2846long gtl_proceed_line_nbr (WEdit * edit, long *nbrs_stored, int *n_last, const long line_n); 
     2847 
     2848 
     2849void 
     2850gtl_mem_fail (const char *msg, const char *funcname, const char *filename, const long line_n) 
     2851{ 
     2852    message (D_ERROR, _(" Internal error: "), 
     2853             _("\n\n    %s:%li:\n\n    in FUNCTION\n\n    %s\n\n    \"%s\"\n\n"),  
     2854             filename, line_n, funcname, msg); 
     2855} 
     2856 
     2857 
     2858char * 
     2859gtl_lines_saved_as_str (WEdit * edit, const long *nbrs_stored, int n_last) 
     2860{ 
     2861    static int once_showed = 0; 
     2862    int n, m; 
     2863    char *hist_clear_msg = NULL; 
     2864    char *str_line_N = NULL; 
     2865    char *str_stored_nbrs = NULL; 
     2866 
     2867    if (n_last > MAXGOTOSHOW) 
     2868        n_last = MAXGOTOSHOW; 
     2869 
     2870    if (once_showed == 0) { 
     2871        hist_clear_msg = 
     2872            g_strdup (_ 
     2873                      ("    To clear `file-history' type key-char\n    `c' or `C' then <Enter>\n\n ")); 
     2874        once_showed = 1; 
     2875    } else { 
     2876        hist_clear_msg = g_strdup (_(" ")); 
     2877    } 
     2878 
     2879    if (edit_get_byte (edit, edit->last_byte - 1) == '\n') 
     2880        str_stored_nbrs = 
     2881            g_strdup_printf ("'\n%s %10li <= 0  bottom ('\\n' is next)\n  %10li <= 1  upper line\n", 
     2882                             hist_clear_msg, edit->total_lines, nbrs_stored[1]); 
     2883    else 
     2884        str_stored_nbrs = 
     2885            g_strdup_printf 
     2886            ("'\n%s %10li <= 0  bottom (next is not '\\n')\n  %10li <= 1  upper line\n", 
     2887             hist_clear_msg, (edit->total_lines + 1), nbrs_stored[1]); 
     2888 
     2889    g_free (hist_clear_msg); 
     2890    if (str_stored_nbrs == NULL) { 
     2891        gtl_mem_fail (_(" if ( str_stored_nbrs == NULL ) "), __FUNCTION__, __FILE__, __LINE__); 
     2892        return NULL; 
     2893    } 
     2894 
     2895    if (n_last > 1) { 
     2896        m = 2; 
     2897        for (n = 2; n <= n_last; n++) { 
     2898            if (nbrs_stored[n] != 0) { 
     2899                str_line_N = g_strdup_printf ("  %10li   %2i\n", nbrs_stored[n], m++); 
     2900                if (str_line_N == NULL) { 
     2901                    g_free (str_stored_nbrs); 
     2902                    gtl_mem_fail (_(" if ( str_line_N == NULL ) "), __FUNCTION__, __FILE__, __LINE__); 
     2903                    return NULL; 
     2904                } else { 
     2905                    str_stored_nbrs = g_strconcat (str_stored_nbrs, str_line_N, (char *) NULL); 
     2906                    g_free (str_line_N); 
     2907                    if (str_stored_nbrs == NULL) { 
     2908                        gtl_mem_fail (_(" if ( str_stored_nbrs == NULL ) "), __FUNCTION__, __FILE__, __LINE__); 
     2909                        return NULL; 
     2910                    } 
     2911                } 
     2912            } 
     2913        } 
     2914 
     2915        if (str_stored_nbrs == NULL) 
     2916            gtl_mem_fail (_(" if ( str_stored_nbrs == NULL ) "), __FUNCTION__, __FILE__, __LINE__); 
     2917    } 
     2918    return str_stored_nbrs; 
     2919} 
     2920 
     2921 
     2922void 
     2923gtl_gothis_nbr (WEdit * edit, long realgo_nbr) 
     2924{ 
     2925    /* when last line is new line (`\n') go to previous line */ 
     2926    if (realgo_nbr == 0) { 
     2927        return; 
     2928    } else if (realgo_nbr < 0) { 
     2929        if (edit_get_byte (edit, edit->last_byte - 1) != '\n') 
     2930            realgo_nbr++; 
     2931 
     2932        realgo_nbr = edit->total_lines + realgo_nbr + 1; 
     2933    } 
     2934    edit_move_display (edit, realgo_nbr - (edit->num_widget_lines / 3)); 
     2935    edit_move_to_line (edit, realgo_nbr - 1); 
     2936    edit->force |= REDRAW_COMPLETELY; 
     2937} 
     2938 
     2939 
     2940long 
     2941gtl_proceed_line_nbr (WEdit * edit, long *nbrs_stored, int *n_last, const long line_n) 
     2942{ 
     2943    int n, n0, ln, k, lk, realgo_nbr; 
     2944 
     2945    if (line_n == 0 || line_n == -1) 
     2946        return (-1); 
     2947 
     2948    if (line_n == 1) 
     2949        return line_n; 
     2950 
     2951    if (line_n == nbrs_stored[*n_last]) 
     2952        return line_n; 
     2953 
     2954    realgo_nbr = line_n; 
     2955    if (line_n > 0) { 
     2956        if (line_n <= *n_last) { 
     2957            realgo_nbr = nbrs_stored[line_n]; 
     2958        } else if (line_n >= edit->total_lines) { 
     2959            return (-1); 
     2960        } 
     2961    } else if (line_n <= -edit->total_lines) { 
     2962        return 1; 
     2963    } 
     2964 
     2965    if (realgo_nbr == nbrs_stored[*n_last]) 
     2966        return realgo_nbr; 
     2967 
     2968    for (n = 2; n < MAXGOTOSHOW; n++) { 
     2969        ln = nbrs_stored[n]; 
     2970        if (ln == edit->total_lines || ln == -edit->total_lines || ln == (edit->total_lines + 1) 
     2971            || ln == -(edit->total_lines + 1) 
     2972            || ln == 1 || ln == -1 || ln == realgo_nbr) 
     2973            nbrs_stored[n] = 0; 
     2974    } 
     2975 
     2976    /* get rid of duplicates then store */ 
     2977    n0 = 0; 
     2978    for (n = MAXGOTOSHOW; n > 2; n--) { 
     2979        ln = nbrs_stored[n]; 
     2980        if (ln == 0) { 
     2981            n0 = 1; 
     2982        } else { 
     2983            for (k = 2; k < n; k++) { 
     2984                lk = nbrs_stored[k]; 
     2985                if (lk == 0) { 
     2986                    n0 = 1; 
     2987                } else if (lk == ln) { 
     2988                    nbrs_stored[k] = 0; 
     2989                    n0 = 1; 
     2990                } 
     2991            } 
     2992        } 
     2993    } 
     2994 
     2995    if (n0 != 0) { 
     2996        *n_last = 1; 
     2997        for (n = 2; n <= MAXGOTOSHOW; n++) { 
     2998            if (nbrs_stored[n] != 0) { 
     2999                nbrs_stored[++(*n_last)] = nbrs_stored[n]; 
     3000                if (*n_last < n) 
     3001                    nbrs_stored[n] = 0; 
     3002 
     3003                if (n == MAXGOTOSHOW) 
     3004                    nbrs_stored[MAXGOTOSHOW] = 0; 
     3005            } 
     3006        } 
     3007    } 
     3008 
     3009    if (*n_last >= MAXGOTOSHOW) { 
     3010        for (n = 2; n < MAXGOTOSHOW; n++) 
     3011            nbrs_stored[n] = nbrs_stored[n + 1]; 
     3012 
     3013        *n_last = MAXGOTOSHOW - 1; 
     3014    } 
     3015 
     3016    nbrs_stored[++(*n_last)] = realgo_nbr; 
     3017    return realgo_nbr; 
     3018} 
     3019 
     3020 
     3021void 
     3022edit_goto_cmd (WEdit * edit) 
     3023{ 
     3024    const long long gtl_LONG_MAX = (long long) LONG_MAX; 
     3025    char *gtprompt = NULL; 
     3026    char str_displayed_nbr[MAXGOTOTYPED] = { '\0' }; 
     3027    char *str_input_type_error = NULL; 
     3028    char *usertyped_str = NULL; 
     3029    int errno_prev = 0; 
     3030    static int n_last = 2; 
     3031    static long realgo_nbr = 0; 
     3032    static long nbrs_stored[MAXGOTOSHOW + 1] = { -1, 1, MAXGOTOSHOW }; 
     3033    static long long typed_nbr = 0; 
     3034 
     3035    if (edit->total_lines > gtl_LONG_MAX) 
     3036        return; 
     3037 
     3038    if (edit->total_lines <= MAXGOTOSHOW) 
     3039        return; 
     3040 
     3041    while (1) { 
     3042        str_displayed_nbr[0] = '\0'; 
     3043        g_snprintf (str_displayed_nbr, sizeof (str_displayed_nbr), "%li", nbrs_stored[n_last - 1]); 
     3044        gtl_proceed_line_nbr (edit, nbrs_stored, &n_last, edit->curs_line + 1); 
     3045        gtprompt = gtl_lines_saved_as_str (edit, nbrs_stored, n_last); 
     3046        usertyped_str = input_dialog (_(" Type right clmn or new line "), 
     3047                                      gtprompt, MC_HISTORY_EDIT_GOTO_LINE, str_displayed_nbr); 
     3048        g_free (gtprompt); 
     3049        if (usertyped_str == NULL) 
     3050            return; 
     3051 
     3052        if (*usertyped_str == '\0') { 
     3053/*         
     3054            message (2, _(" Empty string "), _("\n %s : %s : %d : " 
     3055                    "\n typed:\n\n `%s' \n\n"), 
     3056                    __FUNCTION__, __FILE__, __LINE__, usertyped_str); 
     3057*/ 
     3058            g_free (usertyped_str); 
     3059            return; 
     3060        } 
     3061        if (('c' == usertyped_str[0] 
     3062            || 'C' == usertyped_str[0]) 
     3063            && '\0' == usertyped_str[1]) { 
     3064            g_free (usertyped_str); 
     3065            for (n_last = MAXGOTOSHOW; n_last > 1;) 
     3066                nbrs_stored[n_last--] = 0; 
     3067 
     3068        } else if (strlen (usertyped_str) > MAXGOTOTYPED) { 
     3069            message (2, _(" too long typed string "), 
     3070                     _("\n %s : %s : %d : " 
     3071                       "\n\n MAX strlen can be: `%i' " 
     3072                       "\n\n MAX abs line number: `%li' \n\n"), 
     3073                     __FUNCTION__, __FILE__, __LINE__, MAXGOTOTYPED, labs (LONG_MAX)); 
     3074            g_free (usertyped_str); 
     3075            return; 
     3076        } else { 
     3077            errno_prev = errno; 
     3078            errno = 0;          /* To distinguish success/failure after call */ 
     3079 
     3080            typed_nbr = strtoll (usertyped_str, &str_input_type_error, 10); 
     3081            /* Check for various possible errors */ 
     3082            if (usertyped_str == str_input_type_error) { 
     3083                message (2, _(" No digits were found "), 
     3084                         _("\n %s : %s : %d : " 
     3085                           "\n seems typed:\n\n `%s' " 
     3086                           "\n\n has no digits\n\n"), 
     3087                         __FUNCTION__, __FILE__, __LINE__, usertyped_str); 
     3088                g_free (usertyped_str); 
     3089                return; 
     3090            } 
     3091 
     3092            if (*str_input_type_error != '\0') { 
     3093                gtl_mem_fail (_(" if ( *str_input_type_error != '\0' ) "), __FUNCTION__, __FILE__, __LINE__); 
     3094                g_free (usertyped_str); 
     3095                return; 
     3096            } 
     3097 
     3098            if (llabs (typed_nbr) > gtl_LONG_MAX) { 
     3099                message (2, _(" too big number "),  
     3100                        _("\n %s : %s : %d : " 
     3101                        "\n\n MAX abs line number can be: `%lli'" 
     3102                        "\n\n seems typed string is:      `%s'" 
     3103                        "\n\n and abs number is:          `%lli'\n\n"), 
     3104                        __FUNCTION__, __FILE__, __LINE__,  
     3105                        gtl_LONG_MAX, usertyped_str, llabs (typed_nbr)); 
     3106                g_free (usertyped_str); 
     3107                return; 
     3108            } 
     3109            errno = errno_prev; 
     3110            g_free (usertyped_str); 
     3111            realgo_nbr = gtl_proceed_line_nbr (edit, nbrs_stored, &n_last, (long) typed_nbr); 
     3112            break; 
     3113        } 
     3114    } 
     3115    gtl_gothis_nbr (edit, realgo_nbr); 
     3116}