Ticket #1823: 1823-one-digit-press-ReGoto-lines-version5.patch

File 1823-one-digit-press-ReGoto-lines-version5.patch, 9.4 KB (added by vit_r, 10 years ago)

one digit press ReGoto? visited lines

  • src/editor/editcmd.c

    From 66c0f06e9c196e26637ad0a2998adfe1756bf94b Mon Sep 17 00:00:00 2001
    From: Vit Rosin <vit_r@list.ru>
    Date: Thu, 11 Feb 2010 13:22:38 +0000
    Subject: [PATCH]  one digit press ReGoto lines version5
     !
     ! 1.
     !    'edit->curs_line's are stored and then displayed as numbered prompt.
     !    Pressing corressponding digit is designed to revisit that line
     ! 2.
     !    Typed in dialog string can have chars (chars will be ignored)
     ! 3.
     !    Last typed string can be edited in next dialog
     !
    
    ---
     src/editor/editcmd.c |  317 +++++++++++++++++++++++++++++++++++++++++++-------
     1 files changed, 277 insertions(+), 40 deletions(-)
    
    diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c
    index eb11f91..8d04191 100644
    a b void edit_paste_from_X_buf_cmd (WEdit * edit) 
    19791979} 
    19801980 
    19811981 
    1982 /* 
    1983  * Ask user for the line and go to that line. 
    1984  * Negative numbers mean line from the end (i.e. -1 is the last line). 
    1985  */ 
    1986 void 
    1987 edit_goto_cmd (WEdit *edit) 
    1988 { 
    1989     char *f; 
    1990     static long line = 0;       /* line as typed, saved as default */ 
    1991     long l; 
    1992     char *error; 
    1993     char s[32]; 
    1994  
    1995     g_snprintf (s, sizeof (s), "%ld", line); 
    1996     f = input_dialog (_(" Goto line "), _(" Enter line: "), MC_HISTORY_EDIT_GOTO_LINE, 
    1997                       line ? s : ""); 
    1998     if (!f) 
    1999         return; 
    2000  
    2001     if (!*f) { 
    2002         g_free (f); 
    2003         return; 
    2004     } 
    2005  
    2006     l = strtol (f, &error, 0); 
    2007     if (*error) { 
    2008         g_free (f); 
    2009         return; 
    2010     } 
    2011  
    2012     line = l; 
    2013     if (l < 0) 
    2014         l = edit->total_lines + l + 2; 
    2015     edit_move_display (edit, l - edit->num_widget_lines / 2 - 1); 
    2016     edit_move_to_line (edit, l - 1); 
    2017     edit->force |= REDRAW_COMPLETELY; 
    2018     g_free (f); 
    2019 } 
    2020  
    2021  
    20221982/* Return 1 on success */ 
    20231983int 
    20241984edit_save_block_cmd (WEdit *edit) 
    edit_move_block_to_left (WEdit * edit) 
    28352795    } while (cur_bol >= start_bol) ; 
    28362796    edit->force |= REDRAW_PAGE; 
    28372797} 
     2798 
     2799 
     2800#define GOTO_MAXSHOW 4 
     2801#define GOTO_MAXTYPED 12 
     2802#define GOTO_LONG_MAX ((long long) LONG_MAX) 
     2803 
     2804static void 
     2805gtl_mem_fail (const char *msg) 
     2806{ 
     2807    message (D_ERROR, _(" Internal error: "), _("\n\n   \"%s\"\n\n"), msg); 
     2808} 
     2809 
     2810 
     2811static char * 
     2812get_prompt (const long *nbrs_stored, unsigned int n_last) 
     2813{ 
     2814    static int once_showed = 0; 
     2815    char *stored_nstr = NULL; 
     2816    char *sline_n = NULL; 
     2817    unsigned int n; 
     2818 
     2819    if (n_last > (GOTO_MAXSHOW + 1)) 
     2820        n_last = GOTO_MAXSHOW + 1; 
     2821 
     2822    if (once_showed == 0) { 
     2823        stored_nstr = 
     2824            g_strdup (_("'\n    To clear `file-history' type key-char\n" 
     2825                        "    `c' or `C' then <Enter>\n\n")); 
     2826        once_showed = 1; 
     2827    } else { 
     2828        stored_nstr = g_strdup (_("'\n")); 
     2829    } 
     2830 
     2831    if (stored_nstr == NULL) { 
     2832        gtl_mem_fail (_(" #1: if (stored_nstr == NULL) ")); 
     2833        return NULL; 
     2834    } 
     2835 
     2836    for (n = 1; n <= n_last; n++) { 
     2837        if (nbrs_stored[n] != 0) { 
     2838            sline_n = g_strdup_printf (_("  %10li   %2i\n"), nbrs_stored[n], n); 
     2839            if (sline_n == NULL) { 
     2840                g_free (stored_nstr); 
     2841                gtl_mem_fail (_(" if (sline_n == NULL) ")); 
     2842                return NULL; 
     2843            } else { 
     2844                stored_nstr = g_strconcat (stored_nstr, sline_n, (char *) NULL); 
     2845                g_free (sline_n); 
     2846                if (stored_nstr == NULL) { 
     2847                    gtl_mem_fail (_(" #2: if (stored_nstr == NULL) ")); 
     2848                    return NULL; 
     2849                } 
     2850            } 
     2851        } 
     2852    } 
     2853 
     2854    return stored_nstr; 
     2855} 
     2856 
     2857 
     2858static void 
     2859gothis_nbr (WEdit * edit, long realgo_n) 
     2860{ 
     2861    /* when last line is new line (`\n') go to previous line */ 
     2862    if (realgo_n < 0) { 
     2863        if (edit_get_byte (edit, edit->last_byte - 1) != '\n') 
     2864            realgo_n++; 
     2865 
     2866        realgo_n = edit->total_lines + realgo_n + 1; 
     2867    } 
     2868 
     2869    edit_move_display (edit, realgo_n - (edit->num_widget_lines / 3)); 
     2870    edit_move_to_line (edit, realgo_n - 1); 
     2871    edit->force |= REDRAW_COMPLETELY; 
     2872} 
     2873 
     2874 
     2875static long 
     2876get_nbr (const char *usertyped) 
     2877{ 
     2878    char indigits[GOTO_MAXTYPED] = { '\0' }; 
     2879    int ch = 0; 
     2880    int i = 0, n = 0; 
     2881    long long a_nbr = 0; 
     2882 
     2883    for (n = 0; n < GOTO_MAXTYPED; n++) 
     2884        indigits[n] = ' '; 
     2885 
     2886    indigits[--n] = '\0'; 
     2887 
     2888    for (i = (strlen (usertyped) - 1); i >= 0; i--) { 
     2889        ch = usertyped[i]; 
     2890        if (ch >= '0' && ch <= '9') { 
     2891            indigits[--n] = ch; 
     2892        } else if (ch == '+' || ch == '-') { 
     2893            indigits[--n] = ch; 
     2894            break; 
     2895        } 
     2896    } 
     2897 
     2898    if (n < (GOTO_MAXTYPED - 1)) { 
     2899        a_nbr = strtoll (indigits, NULL, 10); 
     2900        if (llabs (a_nbr) > GOTO_LONG_MAX) { 
     2901            message (D_NORMAL, _(" too big number "), _("\n seems typed string is:   `%s'" 
     2902                                                        "\n and got abs number is:   `%lli'\n" 
     2903                                                        "\n MAX abs line nbr can be: `%lli'\n"), 
     2904                     usertyped, llabs (a_nbr), GOTO_LONG_MAX); 
     2905            return 0; 
     2906        } 
     2907    } 
     2908 
     2909    return ((long) a_nbr); 
     2910} 
     2911 
     2912 
     2913static long 
     2914proceed_line_nbr (WEdit * edit, long *nbrs_stored, unsigned int *n_last, const long line_n) 
     2915{ 
     2916    int n, n0, k; 
     2917    long ln, lk, realgo_n; 
     2918 
     2919    if (line_n == nbrs_stored[*n_last]) 
     2920        return line_n; 
     2921 
     2922    realgo_n = line_n; 
     2923    if (line_n == 0) { 
     2924        return 0; 
     2925    } else if (line_n > 0) { 
     2926        if (line_n <= *n_last) { 
     2927            realgo_n = nbrs_stored[line_n]; 
     2928        } else if (line_n >= edit->total_lines) { 
     2929            realgo_n = -1; 
     2930        } 
     2931    } else if (line_n <= -edit->total_lines) { 
     2932        realgo_n = 1; 
     2933    } 
     2934 
     2935    if (*n_last < 1) { 
     2936        nbrs_stored[++(*n_last)] = realgo_n; 
     2937        return realgo_n; 
     2938    } 
     2939 
     2940    if (realgo_n == nbrs_stored[*n_last]) 
     2941        return realgo_n; 
     2942 
     2943    if (realgo_n == nbrs_stored[*n_last]) 
     2944        return realgo_n; 
     2945 
     2946    for (n = 1; n <= GOTO_MAXSHOW; n++) { 
     2947        if (realgo_n == nbrs_stored[n]) 
     2948            nbrs_stored[n] = 0; 
     2949    } 
     2950 
     2951    /* get rid of duplicates then store */ 
     2952    n0 = 0; 
     2953    for (n = GOTO_MAXSHOW; n > 1; n--) { 
     2954        ln = nbrs_stored[n]; 
     2955        if (ln == 0) { 
     2956            n0 = 1; 
     2957        } else { 
     2958            for (k = 1; k < n; k++) { 
     2959                lk = nbrs_stored[k]; 
     2960                if (lk == 0) { 
     2961                    n0 = 1; 
     2962                } else if (lk == ln) { 
     2963                    nbrs_stored[k] = 0; 
     2964                    n0 = 1; 
     2965                } 
     2966            } 
     2967        } 
     2968    } 
     2969 
     2970    if (n0 != 0) { 
     2971        *n_last = 0; 
     2972        for (n = 1; n <= GOTO_MAXSHOW; n++) { 
     2973            if (nbrs_stored[n] != 0) { 
     2974                nbrs_stored[++(*n_last)] = nbrs_stored[n]; 
     2975                if (*n_last < n) 
     2976                    nbrs_stored[n] = 0; 
     2977 
     2978                if (n == GOTO_MAXSHOW) 
     2979                    nbrs_stored[GOTO_MAXSHOW] = 0; 
     2980            } 
     2981        } 
     2982    } 
     2983 
     2984    if (*n_last >= GOTO_MAXSHOW) { 
     2985        for (n = 1; n < GOTO_MAXSHOW; n++) 
     2986            nbrs_stored[n] = nbrs_stored[n + 1]; 
     2987 
     2988        *n_last = GOTO_MAXSHOW - 1; 
     2989    } 
     2990 
     2991    nbrs_stored[++(*n_last)] = realgo_n; 
     2992    return realgo_n; 
     2993} 
     2994 
     2995 
     2996void 
     2997edit_goto_cmd (WEdit * edit) 
     2998{ 
     2999    char *prompt = NULL; 
     3000    char *title = NULL; 
     3001    char *utyped = NULL; 
     3002    static char dlg_nbr[GOTO_MAXTYPED + 1] = { '\0' }; 
     3003    static long nbrs_stored[GOTO_MAXSHOW + 2] = { -1 }; 
     3004    static long realgo_n = 0; 
     3005    static unsigned int n_last = 0; 
     3006 
     3007    if (edit->total_lines > GOTO_LONG_MAX) 
     3008        return; 
     3009 
     3010    if (edit->total_lines <= GOTO_MAXSHOW) 
     3011        return; 
     3012 
     3013    do { 
     3014        proceed_line_nbr (edit, nbrs_stored, &n_last, edit->curs_line + 1); 
     3015        if (n_last == 1) 
     3016            title = g_strdup (_(" Goto line ")); 
     3017        else 
     3018            title = g_strdup (_(" Type right clmn or new line ")); 
     3019 
     3020        if (title == NULL) { 
     3021            gtl_mem_fail (_(" if (title == NULL) ")); 
     3022            return; 
     3023        } 
     3024 
     3025        if (n_last == 1) 
     3026            prompt = g_strdup (_(" Enter line: ")); 
     3027        else 
     3028            prompt = get_prompt (nbrs_stored, n_last); 
     3029 
     3030        if (prompt == NULL) { 
     3031            gtl_mem_fail (_(" if (prompt == NULL) ")); 
     3032            return; 
     3033        } 
     3034 
     3035        utyped = input_dialog (title, prompt, MC_HISTORY_EDIT_GOTO_LINE, dlg_nbr); 
     3036        g_free (title); 
     3037        g_free (prompt); 
     3038        if (utyped == NULL) 
     3039            return; 
     3040 
     3041        if (*utyped == '\0') { 
     3042            g_free (utyped); 
     3043            return; 
     3044        } 
     3045 
     3046        g_snprintf (dlg_nbr, sizeof (dlg_nbr), "%s", utyped); 
     3047        if ('0' == utyped[0] && '\0' == utyped[1]) { 
     3048            dlg_nbr[0] = '\0'; 
     3049            n_last--; 
     3050            return; 
     3051        } else if (('c' == utyped[0] || 'C' == utyped[0]) 
     3052                   && '\0' == utyped[1]) { 
     3053            dlg_nbr[0] = '\0'; 
     3054            for (n_last = GOTO_MAXSHOW; n_last > 0;) 
     3055                nbrs_stored[n_last--] = 0; 
     3056 
     3057            realgo_n = 0; 
     3058        } else if (strlen (utyped) > GOTO_MAXTYPED) { 
     3059            message (D_NORMAL, _(" too long typed string "), _("\n seems strlen = : `%i' " 
     3060                                                               "\n\n MAX strlen can be: `%i' " 
     3061                                                               "\n\n MAX abs line number: `%li' \n"), 
     3062                     strlen (utyped), GOTO_MAXTYPED, labs (LONG_MAX)); 
     3063            n_last--; 
     3064            realgo_n = 0; 
     3065        } else { 
     3066            realgo_n = proceed_line_nbr (edit, nbrs_stored, &n_last, get_nbr (utyped)); 
     3067        } 
     3068 
     3069        g_free (utyped); 
     3070 
     3071    } while (realgo_n == 0); 
     3072 
     3073    gothis_nbr (edit, realgo_n); 
     3074}