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

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

one click choice of visited lines

  • src/editor/editcmd.c

    From 29e6f2079ffc8479567be3a7296296ee7d3f8b82 Mon Sep 17 00:00:00 2001
    From: Vit Rosin <vit_r@list.ru>
    Date: Tue, 9 Feb 2010 13:17:03 +0000
    Subject: [PATCH]  goto prev line version4
    
    ---
     src/editor/editcmd.c |  306 +++++++++++++++++++++++++++++++++++++++++++-------
     1 files changed, 266 insertions(+), 40 deletions(-)
    
    diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c
    index eb11f91..b57bbe8 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 MAXGOTOSHOW 4 
     2801#define MAXGOTOTYPED 12 
     2802 
     2803 
     2804void 
     2805gtl_mem_fail (const char *msg) 
     2806{ 
     2807    message (D_ERROR, _(" Internal error: "), 
     2808             _("\n\n   \"%s\"\n\n"), msg); 
     2809} 
     2810 
     2811 
     2812char * 
     2813gtl_lines_saved_as_str (WEdit * edit, const long *nbrs_stored, int n_last) 
     2814{ 
     2815    static int once_showed = 0; 
     2816    int n, m; 
     2817    char *hist_clear_msg = NULL; 
     2818    char *str_line_N = NULL; 
     2819    char *str_stored_nbrs = NULL; 
     2820 
     2821    if (n_last > MAXGOTOSHOW) 
     2822        n_last = MAXGOTOSHOW; 
     2823 
     2824    if (once_showed == 0) { 
     2825        hist_clear_msg = 
     2826            g_strdup (_("    To clear `file-history' type key-char\n    `c' or `C' then <Enter>\n\n ")); 
     2827        once_showed = 1; 
     2828    } else { 
     2829        hist_clear_msg = g_strdup (_(" ")); 
     2830    } 
     2831 
     2832    if (edit_get_byte (edit, edit->last_byte - 1) == '\n') 
     2833        str_stored_nbrs = 
     2834            g_strdup_printf ("'\n%s %10li <= 0  bottom ('\\n' is next)\n  %10li <= 1  upper line\n", 
     2835                             hist_clear_msg, edit->total_lines, nbrs_stored[1]); 
     2836    else 
     2837        str_stored_nbrs = 
     2838            g_strdup_printf 
     2839            ("'\n%s %10li <= 0  bottom (next is not '\\n')\n  %10li <= 1  upper line\n", 
     2840             hist_clear_msg, (edit->total_lines + 1), nbrs_stored[1]); 
     2841 
     2842    g_free (hist_clear_msg); 
     2843    if (str_stored_nbrs == NULL) { 
     2844        gtl_mem_fail (_(" if ( str_stored_nbrs == NULL ) ")); 
     2845        return NULL; 
     2846    } 
     2847 
     2848    if (n_last > 1) { 
     2849        m = 2; 
     2850        for (n = 2; n <= n_last; n++) { 
     2851            if (nbrs_stored[n] != 0) { 
     2852                str_line_N = g_strdup_printf ("  %10li   %2i\n", nbrs_stored[n], m++); 
     2853                if (str_line_N == NULL) { 
     2854                    g_free (str_stored_nbrs); 
     2855                    gtl_mem_fail (_(" if ( str_line_N == NULL ) ")); 
     2856                    return NULL; 
     2857                } else { 
     2858                    str_stored_nbrs = g_strconcat (str_stored_nbrs, str_line_N, (char *) NULL); 
     2859                    g_free (str_line_N); 
     2860                    if (str_stored_nbrs == NULL) { 
     2861                        gtl_mem_fail (_(" if ( str_stored_nbrs == NULL ) ")); 
     2862                        return NULL; 
     2863                    } 
     2864                } 
     2865            } 
     2866        } 
     2867 
     2868        if (str_stored_nbrs == NULL) 
     2869            gtl_mem_fail (_(" if ( str_stored_nbrs == NULL ) ")); 
     2870    } 
     2871    return str_stored_nbrs; 
     2872} 
     2873 
     2874 
     2875void 
     2876gtl_gothis_nbr (WEdit * edit, long realgo_nbr) 
     2877{ 
     2878    /* when last line is new line (`\n') go to previous line */ 
     2879    if (realgo_nbr == 0) { 
     2880        return; 
     2881    } else if (realgo_nbr < 0) { 
     2882        if (edit_get_byte (edit, edit->last_byte - 1) != '\n') 
     2883            realgo_nbr++; 
     2884 
     2885        realgo_nbr = edit->total_lines + realgo_nbr + 1; 
     2886    } 
     2887    edit_move_display (edit, realgo_nbr - (edit->num_widget_lines / 3)); 
     2888    edit_move_to_line (edit, realgo_nbr - 1); 
     2889    edit->force |= REDRAW_COMPLETELY; 
     2890} 
     2891 
     2892 
     2893long 
     2894gtl_proceed_line_nbr (WEdit * edit, long *nbrs_stored, int *n_last, const long line_n) 
     2895{ 
     2896    int n, n0, ln, k, lk, realgo_nbr; 
     2897 
     2898    if (line_n == 0 || line_n == -1) 
     2899        return (-1); 
     2900 
     2901    if (line_n == 1) 
     2902        return line_n; 
     2903 
     2904    if (line_n == nbrs_stored[*n_last]) 
     2905        return line_n; 
     2906 
     2907    realgo_nbr = line_n; 
     2908    if (line_n > 0) { 
     2909        if (line_n <= *n_last) { 
     2910            realgo_nbr = nbrs_stored[line_n]; 
     2911        } else if (line_n >= edit->total_lines) { 
     2912            return (-1); 
     2913        } 
     2914    } else if (line_n <= -edit->total_lines) { 
     2915        return 1; 
     2916    } 
     2917 
     2918    if (realgo_nbr == nbrs_stored[*n_last]) 
     2919        return realgo_nbr; 
     2920 
     2921    for (n = 2; n < MAXGOTOSHOW; n++) { 
     2922        ln = nbrs_stored[n]; 
     2923        if (ln == edit->total_lines || ln == -edit->total_lines || ln == (edit->total_lines + 1) 
     2924            || ln == -(edit->total_lines + 1) 
     2925            || ln == 1 || ln == -1 || ln == realgo_nbr) 
     2926            nbrs_stored[n] = 0; 
     2927    } 
     2928 
     2929    /* get rid of duplicates then store */ 
     2930    n0 = 0; 
     2931    for (n = MAXGOTOSHOW; n > 2; n--) { 
     2932        ln = nbrs_stored[n]; 
     2933        if (ln == 0) { 
     2934            n0 = 1; 
     2935        } else { 
     2936            for (k = 2; k < n; k++) { 
     2937                lk = nbrs_stored[k]; 
     2938                if (lk == 0) { 
     2939                    n0 = 1; 
     2940                } else if (lk == ln) { 
     2941                    nbrs_stored[k] = 0; 
     2942                    n0 = 1; 
     2943                } 
     2944            } 
     2945        } 
     2946    } 
     2947 
     2948    if (n0 != 0) { 
     2949        *n_last = 1; 
     2950        for (n = 2; n <= MAXGOTOSHOW; n++) { 
     2951            if (nbrs_stored[n] != 0) { 
     2952                nbrs_stored[++(*n_last)] = nbrs_stored[n]; 
     2953                if (*n_last < n) 
     2954                    nbrs_stored[n] = 0; 
     2955 
     2956                if (n == MAXGOTOSHOW) 
     2957                    nbrs_stored[MAXGOTOSHOW] = 0; 
     2958            } 
     2959        } 
     2960    } 
     2961 
     2962    if (*n_last >= MAXGOTOSHOW) { 
     2963        for (n = 2; n < MAXGOTOSHOW; n++) 
     2964            nbrs_stored[n] = nbrs_stored[n + 1]; 
     2965 
     2966        *n_last = MAXGOTOSHOW - 1; 
     2967    } 
     2968 
     2969    nbrs_stored[++(*n_last)] = realgo_nbr; 
     2970    return realgo_nbr; 
     2971} 
     2972 
     2973 
     2974void 
     2975edit_goto_cmd (WEdit * edit) 
     2976{ 
     2977    const long long gtl_LONG_MAX = (long long) LONG_MAX; 
     2978    char *gtprompt = NULL; 
     2979    char str_displayed_nbr[MAXGOTOTYPED] = { '\0' }; 
     2980    char *str_input_type_error = NULL; 
     2981    char *usertyped_str = NULL; 
     2982    int errno_prev = 0; 
     2983    static int n_last = 2; 
     2984    static long realgo_nbr = 0; 
     2985    static long nbrs_stored[MAXGOTOSHOW + 1] = { -1, 1, MAXGOTOSHOW }; 
     2986    static long long typed_nbr = 0; 
     2987 
     2988    if (edit->total_lines > gtl_LONG_MAX) 
     2989        return; 
     2990 
     2991    if (edit->total_lines <= MAXGOTOSHOW) 
     2992        return; 
     2993 
     2994    while (1) { 
     2995        str_displayed_nbr[0] = '\0'; 
     2996        g_snprintf (str_displayed_nbr, sizeof (str_displayed_nbr), "%li", nbrs_stored[n_last - 1]); 
     2997        gtl_proceed_line_nbr (edit, nbrs_stored, &n_last, edit->curs_line + 1); 
     2998        gtprompt = gtl_lines_saved_as_str (edit, nbrs_stored, n_last); 
     2999        usertyped_str = input_dialog (_(" Type right clmn or new line "), 
     3000                                      gtprompt, MC_HISTORY_EDIT_GOTO_LINE, str_displayed_nbr); 
     3001        g_free (gtprompt); 
     3002        if (usertyped_str == NULL) 
     3003            return; 
     3004 
     3005        if (*usertyped_str == '\0') { 
     3006/*         
     3007            message (2, _(" Empty string "), _( 
     3008                    "\n typed:\n\n `%s' \n\n"), 
     3009                     usertyped_str); 
     3010*/ 
     3011            g_free (usertyped_str); 
     3012            return; 
     3013        } 
     3014        if (('c' == usertyped_str[0] 
     3015            || 'C' == usertyped_str[0]) 
     3016            && '\0' == usertyped_str[1]) { 
     3017            g_free (usertyped_str); 
     3018            for (n_last = MAXGOTOSHOW; n_last > 1;) 
     3019                nbrs_stored[n_last--] = 0; 
     3020 
     3021        } else if (strlen (usertyped_str) > MAXGOTOTYPED) { 
     3022            message (2, _(" too long typed string "), 
     3023                    _("\n\n MAX strlen can be: `%i' " 
     3024                    "\n\n MAX abs line number: `%li' \n\n"), 
     3025                    MAXGOTOTYPED, labs (LONG_MAX)); 
     3026            g_free (usertyped_str); 
     3027            return; 
     3028        } else { 
     3029            errno_prev = errno; 
     3030            errno = 0;          /* To distinguish success/failure after call */ 
     3031 
     3032            typed_nbr = strtoll (usertyped_str, &str_input_type_error, 10); 
     3033            /* Check for various possible errors */ 
     3034            if (usertyped_str == str_input_type_error) { 
     3035                message (2, _(" No digits were found "), _("\n seems typed:\n\n `%s' " 
     3036                    "\n\n has no digits\n\n"), usertyped_str); 
     3037                g_free (usertyped_str); 
     3038                return; 
     3039            } 
     3040 
     3041            if (*str_input_type_error != '\0') { 
     3042                gtl_mem_fail (_(" if ( *str_input_type_error != '\0' ) ")); 
     3043                g_free (usertyped_str); 
     3044                return; 
     3045            } 
     3046 
     3047            if (llabs (typed_nbr) > gtl_LONG_MAX) { 
     3048                message (2, _(" too big number "),  
     3049                    _("\n\n MAX abs line number can be: `%lli'" 
     3050                    "\n\n seems typed string is:      `%s'" 
     3051                    "\n\n and abs number is:          `%lli'\n\n"), 
     3052                    gtl_LONG_MAX, usertyped_str, llabs (typed_nbr)); 
     3053                g_free (usertyped_str); 
     3054                return; 
     3055            } 
     3056            errno = errno_prev; 
     3057            g_free (usertyped_str); 
     3058            realgo_nbr = gtl_proceed_line_nbr (edit, nbrs_stored, &n_last, (long) typed_nbr); 
     3059            break; 
     3060        } 
     3061    } 
     3062    gtl_gothis_nbr (edit, realgo_nbr); 
     3063}