Ticket #267: 0001-Add-stack-navigation-structure.-Add-hotkeys-A-ba.patch

File 0001-Add-stack-navigation-structure.-Add-hotkeys-A-ba.patch, 16.7 KB (added by angel_il, 16 years ago)
  • edit/Makefile.am

    From 20c769b06373ebb0956643478fb8f33dea6ae190 Mon Sep 17 00:00:00 2001
    From: Ilia Maslakov <il.smind@gmail.com>
    Date: Wed, 25 Feb 2009 21:53:52 +0000
    Subject: [PATCH] Add stack navigation structure. Add hotkeys A-'-' backward A-'=' forward navigation to files.
     add edit/etags.c edit/etags.h
    
    ---
     edit/Makefile.am  |    2 +-
     edit/edit.c       |   35 ++++++++++
     edit/edit.h       |   10 +++
     edit/editcmd.c    |  185 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
     edit/editcmddef.h |    5 +-
     edit/editkeys.c   |    4 +-
     edit/etags.c      |   88 +++++++++++++++++++++++++
     edit/etags.h      |    9 +++
     src/main.c        |   18 +++++
     src/main.h        |    9 +++
     10 files changed, 360 insertions(+), 5 deletions(-)
     create mode 100644 edit/etags.c
     create mode 100644 edit/etags.h
    
    diff --git a/edit/Makefile.am b/edit/Makefile.am
    index 2fd8a4a..ce82871 100644
    a b libedit_a_SOURCES = \ 
    1010        bookmark.c edit.c editcmd.c editwidget.c editdraw.c editkeys.c \ 
    1111        editmenu.c editoptions.c editcmddef.h edit.h edit-widget.h \ 
    1212        editlock.c editlock.h syntax.c usermap.h usermap.c wordproc.c \ 
    13         choosesyntax.c 
     13        choosesyntax.c etags.c etats.h 
    1414 
    1515EXTRA_DIST = ChangeLog 
  • edit/edit.c

    diff --git a/edit/edit.c b/edit/edit.c
    index 51810f7..2b88204 100644
    a b edit_reload (WEdit *edit, const char *filename) 
    646646    return 1; 
    647647} 
    648648 
     649/* 
     650 * Load a new file into the editor and set line.  If it fails, preserve the old file. 
     651 * To do it, allocate a new widget, initialize it and, if the new file 
     652 * was loaded, copy the data to the old widget. 
     653 * Return 1 on success, 0 on failure. 
     654 */ 
     655int 
     656edit_reload_line (WEdit *edit, const char *filename, long line) 
     657{ 
     658    WEdit *e; 
     659    int lines = edit->num_widget_lines; 
     660    int columns = edit->num_widget_columns; 
     661 
     662    e = g_malloc0 (sizeof (WEdit)); 
     663    e->widget = edit->widget; 
     664    if (!edit_init (e, lines, columns, filename, line)) { 
     665        g_free (e); 
     666        return 0; 
     667    } 
     668    edit_clean (edit); 
     669    memcpy (edit, e, sizeof (WEdit)); 
     670    g_free (e); 
     671    return 1; 
     672} 
     673 
    649674 
    650675/* 
    651676   Recording stack for undo: 
    edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) 
    24802505        edit_insert_file_cmd (edit); 
    24812506        break; 
    24822507 
     2508    case CK_Load_Prev_File: 
     2509        edit_load_back_cmd (edit); 
     2510        break; 
     2511    case CK_Load_Next_File: 
     2512        edit_load_forward_cmd (edit); 
     2513        break; 
     2514 
    24832515    case CK_Toggle_Syntax: 
    24842516        if ((option_syntax_highlighting ^= 1) == 1) 
    24852517            edit_load_syntax (edit, NULL, option_syntax_type); 
    edit_execute_cmd (WEdit *edit, int command, int char_for_insertion) 
    25012533    case CK_Complete_Word: 
    25022534        edit_complete_word_cmd (edit); 
    25032535        break; 
     2536    case CK_Find_Definition: 
     2537        edit_get_match_keyword_cmd (edit); 
     2538        break; 
    25042539 
    25052540    case CK_Exit: 
    25062541        dlg_stop (edit->widget.parent); 
  • edit/edit.h

    diff --git a/edit/edit.h b/edit/edit.h
    index 3e5f563..85fd07a 100644
    a b  
    103103#define TAB_SIZE                option_tab_spacing 
    104104#define HALF_TAB_SIZE           ((int) option_tab_spacing / 2) 
    105105 
     106/* max count stack files */ 
     107#define MAX_HISTORY_MOVETO     50 
     108 
     109typedef struct edit_stack_type { 
     110    long line; 
     111    char *filename; 
     112}edit_stack_type; 
     113 
    106114struct macro { 
    107115    short command; 
    108116    short ch; 
    int edit_save_block (WEdit * edit, const char *filename, long start, long finish 
    175183int edit_save_block_cmd (WEdit * edit); 
    176184int edit_insert_file_cmd (WEdit * edit); 
    177185int edit_insert_file (WEdit * edit, const char *filename); 
     186int edit_load_back_cmd (WEdit * edit); 
     187int edit_load_forward_cmd (WEdit * edit); 
    178188void edit_block_process_cmd (WEdit * edit, const char *shell_cmd, int block); 
    179189void freestrs (void); 
    180190void edit_refresh_cmd (WEdit * edit); 
  • edit/editcmd.c

    diff --git a/edit/editcmd.c b/edit/editcmd.c
    index 257ab6e..a69cb89 100644
    a b  
    1 /* editor high level editing commands. 
     1/* editor high level editing commands 
    22 
    33   Copyright (C) 1996, 1997, 1998, 2001, 2002, 2003, 2004, 2005, 2006, 
    44   2007 Free Software Foundation, Inc. 
     
    4545#include "editlock.h" 
    4646#include "editcmddef.h" 
    4747#include "edit-widget.h" 
     48#include "etags.h" 
    4849 
    4950#include "../src/color.h"       /* dialog_colors */ 
    5051#include "../src/tty.h"         /* LINES */ 
    static void 
    27952796edit_completion_dialog (WEdit * edit, int max_len, int word_len, 
    27962797                        struct selection *compl, int num_compl) 
    27972798{ 
     2799 
    27982800    int start_x, start_y, offset, i; 
    27992801    char *curr = NULL; 
    28002802    Dlg_head *compl_dlg; 
    edit_complete_word_cmd (WEdit *edit) 
    28832885    /* prepare match expression */ 
    28842886    bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] 
    28852887        [word_start & M_EDIT_BUF_SIZE]; 
    2886     match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); 
    28872888 
     2889    match_expr = g_strdup_printf ("%.*s[a-zA-Z_0-9]+", word_len, bufpos); 
    28882890    /* init search: backward, regexp, whole word, case sensitive */ 
    28892891    edit_set_search_parameters (0, 1, 1, 1, 1); 
    28902892 
    edit_begin_end_macro_cmd(WEdit *edit) 
    29692971            edit_execute_key_command (edit, command, -1); 
    29702972    } 
    29712973} 
     2974 
     2975int 
     2976edit_load_forward_cmd (WEdit *edit) 
     2977{ 
     2978    if (edit->modified) { 
     2979        if (edit_query_dialog2 
     2980            (_("Warning"), 
     2981             _(" Current text was modified without a file save. \n" 
     2982               " Continue discards these changes. "), _("C&ontinue"), 
     2983             _("&Cancel"))) { 
     2984            edit->force |= REDRAW_COMPLETELY; 
     2985            return 0; 
     2986        } 
     2987    } 
     2988    if ( edit_stack_iterator + 1 < MAX_HISTORY_MOVETO ) { 
     2989        if ( edit_history_moveto[edit_stack_iterator + 1].line < 1 ) { 
     2990            return 1; 
     2991        } 
     2992        edit_stack_iterator++; 
     2993        if ( edit_history_moveto[edit_stack_iterator].filename ) { 
     2994            edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, 
     2995                              edit_history_moveto[edit_stack_iterator].line); 
     2996            return 0; 
     2997        } else { 
     2998            return 1; 
     2999        } 
     3000    } else { 
     3001        return 1; 
     3002    } 
     3003} 
     3004 
     3005int 
     3006edit_load_back_cmd (WEdit *edit) 
     3007{ 
     3008    if (edit->modified) { 
     3009        if (edit_query_dialog2 
     3010            (_("Warning"), 
     3011             _(" Current text was modified without a file save. \n" 
     3012               " Continue discards these changes. "), _("C&ontinue"), 
     3013             _("&Cancel"))) { 
     3014            edit->force |= REDRAW_COMPLETELY; 
     3015            return 0; 
     3016        } 
     3017    } 
     3018    if ( edit_stack_iterator > 0 ) { 
     3019        edit_stack_iterator--; 
     3020        if ( edit_history_moveto[edit_stack_iterator].filename ) { 
     3021            edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, 
     3022                              edit_history_moveto[edit_stack_iterator].line); 
     3023            return 0; 
     3024        } else { 
     3025            return 1; 
     3026        } 
     3027    } else { 
     3028        return 1; 
     3029    } 
     3030} 
     3031 
     3032 
     3033/* let the user select where function definition */ 
     3034static void 
     3035edit_select_definition_dialog (WEdit * edit, int max_len, int word_len, 
     3036                               struct def_hash_type *def_hash, int num_lines) 
     3037{ 
     3038 
     3039    int start_x, start_y, offset, i; 
     3040    char *curr = NULL; 
     3041    struct def_hash_type *curr_def; 
     3042    Dlg_head *def_dlg; 
     3043    WListbox *def_list; 
     3044    int def_dlg_h;      /* dialog height */ 
     3045    int def_dlg_w;      /* dialog width */ 
     3046 
     3047    /* calculate the dialog metrics */ 
     3048    def_dlg_h = num_lines + 2; 
     3049    def_dlg_w = max_len + 4; 
     3050    start_x = edit->curs_col + edit->start_col - (def_dlg_w / 2); 
     3051    start_y = edit->curs_row + EDIT_TEXT_VERTICAL_OFFSET + 1; 
     3052 
     3053    if (start_x < 0) 
     3054        start_x = 0; 
     3055    if (def_dlg_w > COLS) 
     3056        def_dlg_w = COLS; 
     3057    if (def_dlg_h > LINES - 2) 
     3058        def_dlg_h = LINES - 2; 
     3059 
     3060    offset = start_x + def_dlg_w - COLS; 
     3061    if (offset > 0) 
     3062        start_x -= offset; 
     3063    offset = start_y + def_dlg_h - LINES; 
     3064    if (offset > 0) 
     3065        start_y -= (offset + 1); 
     3066 
     3067    /* create the dialog */ 
     3068    def_dlg = create_dlg (start_y, start_x, def_dlg_h, def_dlg_w, 
     3069                          dialog_colors, NULL, "[Definitions]", NULL, 
     3070                          DLG_COMPACT); 
     3071 
     3072    /* create the listbox */ 
     3073    def_list = listbox_new (1, 1, def_dlg_w - 2, def_dlg_h - 2, NULL); 
     3074 
     3075    /* add the dialog */ 
     3076    add_widget (def_dlg, def_list); 
     3077 
     3078    char *label_def = NULL; 
     3079 
     3080    /* fill the listbox with the completions */ 
     3081    for (i = 0; i < num_lines; i++) { 
     3082        label_def = g_strdup_printf ("%s:%i", def_hash[i].filename, def_hash[i].line); 
     3083        listbox_add_item (def_list, LISTBOX_APPEND_AT_END, 0, label_def, &def_hash[i]); 
     3084        g_free(label_def); 
     3085    } 
     3086    /* pop up the dialog */ 
     3087    run_dlg (def_dlg); 
     3088 
     3089    /* apply the choosen completion */ 
     3090    if (def_dlg->ret_value == B_ENTER) { 
     3091        listbox_get_current (def_list, &curr, &curr_def); 
     3092        if ( curr ) { 
     3093            if ( edit_stack_iterator+1 < MAX_HISTORY_MOVETO ) { 
     3094                g_free( edit_history_moveto[edit_stack_iterator].filename ); 
     3095                edit_history_moveto[edit_stack_iterator].filename = g_strdup(edit->filename); 
     3096                edit_history_moveto[edit_stack_iterator].line = edit->start_line + edit->curs_row + 1; 
     3097                edit_stack_iterator++; 
     3098                mc_log("%s:%i iterator=%i\n", curr_def->filename, curr_def->line, edit_stack_iterator); 
     3099                g_free( edit_history_moveto[edit_stack_iterator].filename ); 
     3100                edit_history_moveto[edit_stack_iterator].filename = g_strdup(curr_def->filename); 
     3101                edit_history_moveto[edit_stack_iterator].line = curr_def->line; 
     3102                edit_reload_line (edit, edit_history_moveto[edit_stack_iterator].filename, 
     3103                                              edit_history_moveto[edit_stack_iterator].line); 
     3104            } 
     3105        } 
     3106    } 
     3107 
     3108    /* clear definition hash */ 
     3109    for ( int i = 0; i < MAX_DEFINITIONS; i++) { 
     3110        g_free(def_hash[i].filename); 
     3111    } 
     3112 
     3113    /* destroy dialog before return */ 
     3114    destroy_dlg (def_dlg); 
     3115} 
     3116 
     3117 
     3118void 
     3119edit_get_match_keyword_cmd (WEdit *edit) 
     3120{ 
     3121    int word_len = 0, num_def = 0, max_len; 
     3122    long word_start = 0; 
     3123    unsigned char *bufpos; 
     3124    char *match_expr; 
     3125    struct def_hash_type def_hash[MAX_DEFINITIONS]; 
     3126 
     3127    for ( int i = 0; i < MAX_DEFINITIONS; i++) { 
     3128        def_hash[i].filename = NULL; 
     3129    } 
     3130 
     3131    /* search start of word to be completed */ 
     3132    if (!edit_find_word_start (edit, &word_start, &word_len)) 
     3133        return; 
     3134 
     3135    /* prepare match expression */ 
     3136    mc_log("edit_get_match_keyword_cmd\n"); 
     3137    bufpos = &edit->buffers1[word_start >> S_EDIT_BUF_SIZE] 
     3138                            [word_start & M_EDIT_BUF_SIZE]; 
     3139    match_expr = g_strdup_printf ("%.*s", word_len, bufpos); 
     3140 
     3141    mc_log("%s \n", match_expr); 
     3142 
     3143    set_def_hash("TAGS", match_expr, (struct def_hash_type *) &def_hash, &num_def); 
     3144    max_len = 50; 
     3145    word_len = 0; 
     3146    if ( num_def > 0 ) { 
     3147        edit_select_definition_dialog (edit, max_len, word_len, 
     3148                                       (struct def_hash_type *) &def_hash, 
     3149                                       num_def); 
     3150    } 
     3151    g_free (match_expr); 
     3152} 
  • edit/editcmddef.h

    diff --git a/edit/editcmddef.h b/edit/editcmddef.h
    index 2135376..3521d8b 100644
    a b  
    4242#define CK_Load                 102 
    4343#define CK_New                  103 
    4444#define CK_Save_As              104 
     45#define CK_Load_Prev_File       111 
     46#define CK_Load_Next_File       112 
    4547 
    4648/* block commands */ 
    4749#define CK_Mark                 201 
     
    9698#define CK_Terminal             422 
    9799#define CK_Terminal_App         423 
    98100#define CK_ExtCmd               424 
    99  
    100101#define CK_User_Menu            425 
     102#define CK_Find_Definition      426 
     103 
    101104/* application control */ 
    102105#define CK_Save_Desktop         451 
    103106#define CK_New_Window           452 
  • edit/editkeys.c

    diff --git a/edit/editkeys.c b/edit/editkeys.c
    index 2cc6add..91306ca 100644
    a b static const edit_key_map_type common_key_map[] = { 
    9999    { KEY_RIGHT, CK_Right }, 
    100100    { KEY_UP, CK_Up }, 
    101101 
    102     { ALT ('\n'), CK_Return }, 
     102    { ALT ('\n'), CK_Find_Definition }, 
    103103    { ALT ('\t'), CK_Complete_Word }, 
    104104    { ALT ('l'), CK_Goto }, 
    105105    { ALT ('L'), CK_Goto }, 
    static const edit_key_map_type common_key_map[] = { 
    108108    { ALT ('u'), CK_ExtCmd }, 
    109109    { ALT ('<'), CK_Beginning_Of_Text }, 
    110110    { ALT ('>'), CK_End_Of_Text }, 
     111    { ALT ('-'), CK_Load_Prev_File }, 
     112    { ALT ('='), CK_Load_Next_File }, 
    111113    { ALT (KEY_BACKSPACE), CK_Delete_Word_Left }, 
    112114 
    113115    { XCTRL ('k'), CK_Delete_To_Line_End }, 
  • new file edit/etags.c

    diff --git a/edit/etags.c b/edit/etags.c
    new file mode 100644
    index 0000000..f0dac2b
    - +  
     1/*find . -type f -name "*.[ch]" | etags -l c --declarations - */ 
     2#include <stdlib.h> 
     3#include <stdio.h> 
     4#include <inttypes.h> 
     5#include <string.h> 
     6#include <glib.h> 
     7#include <ctype.h> 
     8#include "etags.h" 
     9 
     10long get_pos_from(char *str) 
     11{ 
     12    static char buf[16]; 
     13    int i, j; 
     14    j = 0; 
     15    int len = strlen( str ); 
     16    for ( i = 0; i < len && i < 16; i++ ) { 
     17        char c = (char) str[i]; 
     18        if ( isdigit (c) ) { 
     19            buf[j++] = c; 
     20            buf[j] = '\0'; 
     21        } else { 
     22            return atol((char *)buf); 
     23        } 
     24    } 
     25    return 0; 
     26} 
     27 
     28int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash, int *num) 
     29{ 
     30    FILE *f; 
     31    static char buf[4048]; 
     32    int len; 
     33 
     34    f = fopen (tagfile, "r"); 
     35    int i; 
     36    if (!f) 
     37        return 1; 
     38 
     39    len = strlen( match_func ); 
     40    int pos; 
     41    char *filename = NULL; 
     42    long line; 
     43    enum {start, in_filename, in_define} state=start; 
     44 
     45    while (fgets (buf, sizeof (buf), f)) { 
     46 
     47        switch ( state ) { 
     48        case start: 
     49            if ( buf[0] == 0x0C ) { 
     50                state = in_filename; 
     51            } 
     52            break; 
     53        case in_filename: 
     54            pos = strcspn(buf, ","); 
     55            if ( filename ) { 
     56                g_free(filename); 
     57            } 
     58            filename = malloc(pos + 2); 
     59            g_strlcpy ( filename, (char *)buf, pos + 1 ); 
     60            state = in_define; 
     61            break; 
     62        case in_define: 
     63            if ( buf[0] == 0x0C ) { 
     64                state = in_filename; 
     65                break; 
     66            } 
     67            /* check if the filename matches the define pos */ 
     68            if ( strstr ( buf, match_func ) ) { 
     69                int l = (int)strlen( buf ); 
     70                for ( i = 0; i < l; i++) { 
     71                    if ( ( buf[i] == 0x7F || buf[i] == 0x01 ) && isdigit(buf[i+1]) ) { 
     72                        line = get_pos_from(&buf[i+1]); 
     73                        state = start; 
     74                        if ( *num < MAX_DEFINITIONS ) { 
     75                            def_hash[*num].filename_len = strlen(filename); 
     76                            def_hash[*num].filename = g_strdup(filename); 
     77                            def_hash[*num].line = line; 
     78                            (*num)++; 
     79                        } 
     80                    } 
     81                } 
     82            } 
     83            break; 
     84        } 
     85    } 
     86    g_free(filename); 
     87    return 0; 
     88} 
  • new file edit/etags.h

    diff --git a/edit/etags.h b/edit/etags.h
    new file mode 100644
    index 0000000..f2f8403
    - +  
     1#define MAX_DEFINITIONS 50 
     2 
     3struct def_hash_type { 
     4   int filename_len; 
     5   unsigned char *filename; 
     6   long line; 
     7}; 
     8long get_pos_from(char *str); 
     9int set_def_hash(char *tagfile, char *match_func, struct def_hash_type *def_hash, int *num); 
  • src/main.c

    diff --git a/src/main.c b/src/main.c
    index 4dcee7c..66a8d81 100644
    a b char *mc_home = NULL; 
    279279 
    280280char cmd_buf[512]; 
    281281 
     282#ifdef USE_INTERNAL_EDIT 
     283int edit_stack_iterator = 0; 
     284struct edit_stack_type edit_history_moveto[MAX_HISTORY_MOVETO]; 
     285#endif 
     286 
    282287static void 
    283288reload_panelized (WPanel *panel) 
    284289{ 
    main (int argc, char *argv[]) 
    21352140 
    21362141    vfs_init (); 
    21372142 
     2143#ifdef USE_INTERNAL_EDIT 
     2144    for ( int i = 0; i < MAX_HISTORY_MOVETO; i++ ) { 
     2145        edit_history_moveto[i].filename = NULL; 
     2146        edit_history_moveto[i].line = -1; 
     2147    } 
     2148#endif 
     2149 
    21382150#ifdef HAVE_SLANG 
    21392151    SLtt_Ignore_Beep = 1; 
    21402152#endif 
    main (int argc, char *argv[]) 
    22552267    g_free (this_dir); 
    22562268    g_free (other_dir); 
    22572269 
     2270#ifdef USE_INTERNAL_EDIT 
     2271    for ( int i = 0; i < MAX_HISTORY_MOVETO; i++ ) { 
     2272        g_free(edit_history_moveto[i].filename); 
     2273    } 
     2274#endif 
     2275 
    22582276    return 0; 
    22592277} 
  • src/main.h

    diff --git a/src/main.h b/src/main.h
    index 1500548..d858cb2 100644
    a b  
    55#include "panel.h" 
    66#include "widget.h" 
    77 
     8#ifdef USE_INTERNAL_EDIT 
     9#include "../edit/edit.h" 
     10#endif 
     11 
    812/* Toggling functions */ 
    913void toggle_fast_reload (void); 
    1014void toggle_mix_all_files (void); 
    extern int mou_auto_repeat; 
    3842extern char *other_dir; 
    3943extern int mouse_move_pages; 
    4044 
     45#ifdef USE_INTERNAL_EDIT 
     46extern int edit_stack_iterator; 
     47struct edit_stack_type edit_history_moveto[MAX_HISTORY_MOVETO]; 
     48#endif 
     49 
    4150#ifdef HAVE_CHARSET 
    4251extern int source_codepage; 
    4352extern int display_codepage;