Ticket #4193: OtherFileConcept_v3.5.patch

File OtherFileConcept_v3.5.patch, 20.2 KB (added by psprint, 3 years ago)

revisited

  • doc/man/mcedit.1.in

    From 770d3d9f530e93b6795e97a7cce8cab500225aa2 Mon Sep 17 00:00:00 2001
    From: Sebastian Gniazdowski <sgniazdowski@gmail.com>
    Date: Tue, 2 Feb 2021 12:50:19 -0600
    Subject: Other File concept: jumping between headers and sources.
    
    ---
     doc/man/mcedit.1.in     |  25 +++++-
     lib/keybind.c           |   1 +
     lib/keybind.h           |   1 +
     lib/vfs/path.c          |  43 ++++++++++
     lib/vfs/path.h          |   2 +
     misc/mc.default.keymap  |   1 +
     misc/mc.emacs.keymap    |   1 +
     src/editor/edit-impl.h  |  13 ++-
     src/editor/edit.c       |  30 +++++++
     src/editor/edit.h       |   5 ++
     src/editor/editcmd.c    |  11 ++-
     src/editor/editwidget.c | 185 +++++++++++++++++++++++++++++++++++++++-
     src/editor/editwidget.h |   1 +
     src/keybind-defaults.c  |   1 +
     src/setup.c             |   5 ++
     15 files changed, 317 insertions(+), 8 deletions(-)
    
    diff --git a/doc/man/mcedit.1.in b/doc/man/mcedit.1.in
    index 33e5f34b7..acd46ca8a 100644
    a b supports are: block copy, move, delete, cut, paste; key for key undo; 
    6262pull\-down menus; file insertion; macro commands; regular expression 
    6363search and replace; shift\-arrow text highlighting (if supported by 
    6464the terminal); insert\-overwrite toggle; autoindent; tunable tab size; 
    65 syntax highlighting for various file types; and an option to pipe text 
     65syntax highlighting for various file types; switching between headers 
     66and sources (Alt-a by default), and an option to pipe text 
    6667blocks through shell commands like indent and ispell. 
    6768.PP 
    6869Each file is opened in its own window in full\-screen mode. Window control 
    The macro is executed when you press the assigned key. 
    111112.PP 
    112113The macro commands are stored in section 
    113114.B [editor] 
    114 it the file 
     115in the file 
    115116.BR ~/.local/share/mc/mc.macros . 
    116117.PP 
    117118External scripts (filters) can be assigned into the any hotkey by edit 
    will be untouched. Default value is 
    603604.I editor_state_full_filename 
    604605Show full path name in the status line. If disabled (default), only base name of the 
    605606file is shown. 
     607.TP 
     608.I editor_other_file_1_exts 
     609MCEdit can quickly switch between 
     610.BR source " and " interface 
     611files – in case of the latter, being typically e.g.: the header files of 
     612C/C++. An example pair of such files is, e.g.: 
     613.BR main.c " and " main.h 
     614and pressing Alt-a (the default binding of the feature's action) would switch 
     615between them back and forth, first loading the file into the editor, if 
     616needed. This option allows to configure the feature by specifying a comma 
     617separated list of the name extensions of the files (including dots) to be 
     618recognized as the interface-kind files. Its default value supports C/C++ 
     619headers 
     620.RB ( .h ", " .hpp ", etc.)." 
     621.TP 
     622.I editor_other_file_2_exts 
     623This option allows to configure the other-file feature (called also: alternate 
     624file) by specifying the file name extensions for the source-kind files. Its 
     625default value supports typical sources written in C/C++ languages 
     626.RB ( .c ", " .cpp ", " .cxx ", etc.)." 
    606627.SH MISCELLANEOUS 
    607628The editor also displays non\-us characters (160+).  When editing 
    608629binary files, you should set 
  • lib/keybind.c

    diff --git a/lib/keybind.c b/lib/keybind.c
    index abd44d3e2..2ec715bfa 100644
    a b static name_keymap_t command_names[] = { 
    277277    ADD_KEYMAP_NAME (ParagraphUp), 
    278278    ADD_KEYMAP_NAME (ParagraphDown), 
    279279    ADD_KEYMAP_NAME (EditFile), 
     280    ADD_KEYMAP_NAME (OtherFile), 
    280281    ADD_KEYMAP_NAME (MarkWord), 
    281282    ADD_KEYMAP_NAME (MarkLine), 
    282283    ADD_KEYMAP_NAME (MarkAll), 
  • lib/keybind.h

    diff --git a/lib/keybind.h b/lib/keybind.h
    index af019df09..cd7192d06 100644
    a b enum 
    246246    CK_ParagraphDown, 
    247247    /* file commands */ 
    248248    CK_EditFile, 
     249    CK_OtherFile, 
    249250    CK_InsertFile, 
    250251    CK_EditSyntaxFile, 
    251252    CK_Close, 
  • lib/vfs/path.c

    diff --git a/lib/vfs/path.c b/lib/vfs/path.c
    index 49553198f..22d4a81e6 100644
    a b vfs_path_strip_home (const char *dir) 
    593593/*** public functions ****************************************************************************/ 
    594594/* --------------------------------------------------------------------------------------------- */ 
    595595 
     596/** 
     597 * Returns TRUE if path has one of the given extensions (in a NULL terminated array). 
     598 * The extension strings should include the dot. 
     599 */ 
     600gboolean 
     601vfs_path_has_extension (const vfs_path_t * fs_path, const char **exts, gboolean ignore_case) 
     602{ 
     603    const char *path, **cur_ext; 
     604    char *upcase_path, *upcase_ext; 
     605    gboolean ret = TRUE; 
     606 
     607    path = vfs_path_as_str (fs_path); 
     608 
     609    /* 
     610     * The extensions should be only ASCII, so use g_ascii_strup() which also 
     611     * safely leaves non-ASCII chars unchanged. 
     612     */ 
     613    upcase_path = g_ascii_strup (path, -1); 
     614 
     615    for (cur_ext = exts; cur_ext != NULL && *cur_ext != NULL; cur_ext++) 
     616    { 
     617        if (ignore_case) 
     618        { 
     619            upcase_ext = g_ascii_strup (*cur_ext, -1); 
     620            if (g_str_has_suffix (upcase_path, upcase_ext)) 
     621                goto ret_true; 
     622            g_free (upcase_ext); 
     623            upcase_ext = NULL; 
     624        } 
     625        else if (g_str_has_suffix (path, *cur_ext)) 
     626            goto ret_true; 
     627    } 
     628 
     629    ret = FALSE; 
     630  ret_true: 
     631    if (upcase_ext != NULL) 
     632        g_free (upcase_ext); 
     633    g_free (upcase_path); 
     634    return ret; 
     635} 
     636 
     637/* --------------------------------------------------------------------------------------------- */ 
     638 
    596639#define vfs_append_from_path(appendfrom, is_relative) \ 
    597640{ \ 
    598641    if ((flags & VPF_STRIP_HOME) && element_index == 0 && \ 
  • lib/vfs/path.h

    diff --git a/lib/vfs/path.h b/lib/vfs/path.h
    index c5dc4f5a4..802d0b17f 100644
    a b char *vfs_path_to_str_elements_count (const vfs_path_t * path, int elements_coun 
    6767char *vfs_path_to_str_flags (const vfs_path_t * vpath, int elements_count, vfs_path_flag_t flags); 
    6868vfs_path_t *vfs_path_from_str (const char *path_str); 
    6969vfs_path_t *vfs_path_from_str_flags (const char *path_str, vfs_path_flag_t flags); 
     70gboolean vfs_path_has_extension (const vfs_path_t * fs_path, const char **exts, 
     71                                 gboolean ignore_case); 
    7072vfs_path_t *vfs_path_build_filename (const char *first_element, ...); 
    7173vfs_path_t *vfs_path_append_new (const vfs_path_t * vpath, const char *first_element, ...); 
    7274vfs_path_t *vfs_path_append_vpath_new (const vfs_path_t * first_vpath, ...); 
  • misc/mc.default.keymap

    diff --git a/misc/mc.default.keymap b/misc/mc.default.keymap
    index 2931ddd0a..075c8e4ce 100644
    a b DeleteToEnd = ctrl-k 
    291291Save = f2 
    292292# EditFile = 
    293293EditNew = ctrl-n 
     294OtherFile = alt-a 
    294295SaveAs = f12; ctrl-f2 
    295296# Close = 
    296297History = alt-shift-e 
  • misc/mc.emacs.keymap

    diff --git a/misc/mc.emacs.keymap b/misc/mc.emacs.keymap
    index 7cc305db7..bff42b0a0 100644
    a b DeleteToEnd = ctrl-k 
    290290# ParagraphDown = 
    291291Save = f2 
    292292# EditFile = 
     293OtherFile = alt-a 
    293294SaveAs = f12; ctrl-f2 
    294295# Close = 
    295296History = alt-shift-e 
  • src/editor/edit-impl.h

    diff --git a/src/editor/edit-impl.h b/src/editor/edit-impl.h
    index 3ad04dbea..90dc5dedb 100644
    a b typedef enum 
    9494    EDIT_DO_BACKUP 
    9595} edit_save_mode_t; 
    9696 
     97 
     98/* Describes how well a file suits for editing. Symlinks and empty files get average grade. */ 
     99typedef enum 
     100{ 
     101    FILE_RANK_INVALID = -1, 
     102    FILE_RANK_NOT_SUITABLE = 0, 
     103    FILE_RANK_AVERAGE_SUITABLE, 
     104    FILE_RANK_SUITABLE 
     105} file_suitable_rank_t; 
     106 
    97107/*** structures declarations (and typedefs of structures)*****************************************/ 
    98108 
    99109/* search/replace options */ 
    WEdit *edit_init (WEdit * edit, int y, int x, int lines, int cols, 
    185195                  const vfs_path_t * filename_vpath, long line); 
    186196gboolean edit_clean (WEdit * edit); 
    187197gboolean edit_ok_to_exit (WEdit * edit); 
    188 gboolean edit_load_cmd (WDialog * h); 
     198file_suitable_rank_t edit_check_file_suitable (const vfs_path_t * fs_path); 
     199gboolean edit_load_cmd (WDialog * h, const void *data); 
    189200gboolean edit_load_file_from_history (WDialog * h); 
    190201gboolean edit_load_syntax_file (WDialog * h); 
    191202gboolean edit_load_menu_file (WDialog * h); 
  • src/editor/edit.c

    diff --git a/src/editor/edit.c b/src/editor/edit.c
    index edda1f832..98882b241 100644
    a b int option_line_state_width = 0; 
    9191gboolean option_cursor_after_inserted_block = FALSE; 
    9292gboolean option_state_full_filename = FALSE; 
    9393 
     94char *option_other_file_1_exts; 
     95char *option_other_file_2_exts; 
     96 
    9497gboolean enable_show_tabs_tws = TRUE; 
    9598gboolean option_check_nl_at_eof = FALSE; 
    9699gboolean option_group_undo = FALSE; 
    edit_insert_stream (WEdit * edit, FILE * f) 
    277280    return i; 
    278281} 
    279282 
     283/* --------------------------------------------------------------------------------------------- */ 
     284/** 
     285 * Gives a 3-level evaluation of how well given file is looking as a suitable input to the editor. 
     286 */ 
     287file_suitable_rank_t 
     288edit_check_file_suitable (const vfs_path_t * fs_path) 
     289{ 
     290    struct stat lst, st; 
     291 
     292    if (fs_path == NULL) 
     293        return FILE_RANK_INVALID; 
     294 
     295    if (exist_file (vfs_path_as_str (fs_path))) 
     296    { 
     297        if (mc_lstat (fs_path, &lst) == 0 && mc_stat (fs_path, &st) == 0) 
     298        { 
     299            if (st.st_size != 0 && S_ISREG (st.st_mode) && !S_ISLNK (lst.st_mode)) 
     300                return FILE_RANK_SUITABLE; 
     301            else 
     302                return FILE_RANK_AVERAGE_SUITABLE; 
     303        } 
     304    } 
     305    return FILE_RANK_NOT_SUITABLE; 
     306} 
     307 
    280308/* --------------------------------------------------------------------------------------------- */ 
    281309/** 
    282310  * Open file and create it if necessary. 
    edit_init (WEdit * edit, int y, int x, int lines, int cols, const vfs_path_t * f 
    21082136        w->options |= WOP_SELECTABLE | WOP_TOP_SELECT | WOP_WANT_CURSOR; 
    21092137        w->keymap = editor_map; 
    21102138        w->ext_keymap = editor_x_map; 
     2139        edit->otherfile_vpath = NULL; 
    21112140        edit->fullscreen = TRUE; 
    21122141        edit_save_size (edit); 
    21132142    } 
    edit_clean (WEdit * edit) 
    22042233    g_free (edit->redo_stack); 
    22052234    vfs_path_free (edit->filename_vpath); 
    22062235    vfs_path_free (edit->dir_vpath); 
     2236    vfs_path_free (edit->otherfile_vpath); 
    22072237    mc_search_free (edit->search); 
    22082238    g_free (edit->last_search_string); 
    22092239 
  • src/editor/edit.h

    diff --git a/src/editor/edit.h b/src/editor/edit.h
    index 6c519e9d3..e3b9b7fd8 100644
    a b extern char *option_stop_format_chars; 
    5353 
    5454extern gboolean edit_confirm_save; 
    5555 
     56extern char *option_other_file_1_exts; 
     57extern char *option_other_file_2_exts; 
     58 
    5659extern gboolean visible_tabs; 
    5760extern gboolean visible_tws; 
    5861 
    extern gboolean show_right_margin; 
    6669void edit_stack_init (void); 
    6770void edit_stack_free (void); 
    6871 
     72/* If file is open, switch to it, otherwise it is loaded */ 
     73gboolean edit_switch_to_file (WDialog * h, const vfs_path_t * file); 
    6974gboolean edit_file (const vfs_path_t * file_vpath, long line); 
    7075gboolean edit_files (const GList * files); 
    7176 
  • src/editor/editcmd.c

    diff --git a/src/editor/editcmd.c b/src/editor/editcmd.c
    index 0d2caa923..661655d58 100644
    a b edit_save_confirm_cmd (WEdit * edit) 
    20632063  */ 
    20642064 
    20652065gboolean 
    2066 edit_load_cmd (WDialog * h) 
     2066edit_load_cmd (WDialog * h, const void *data) 
    20672067{ 
    20682068    char *exp; 
    20692069    gboolean ret = TRUE;        /* possible cancel */ 
    20702070 
    2071     exp = input_expand_dialog (_("Load"), _("Enter file name:"), 
    2072                                MC_HISTORY_EDIT_LOAD, INPUT_LAST_TEXT, 
    2073                                INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD); 
     2071    if (data != NULL) 
     2072        exp = g_strdup ((char *) data); 
     2073    else 
     2074        exp = input_expand_dialog (_("Load"), _("Enter file name:"), 
     2075                                   MC_HISTORY_EDIT_LOAD, INPUT_LAST_TEXT, 
     2076                                   INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD); 
    20742077 
    20752078    if (exp != NULL && *exp != '\0') 
    20762079    { 
  • src/editor/editwidget.c

    diff --git a/src/editor/editwidget.c b/src/editor/editwidget.c
    index 18ac00e66..8547a44de 100644
    a b static unsigned int edit_dlg_init_refcounter = 0; 
    8888static cb_ret_t edit_dialog_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, 
    8989                                      void *data); 
    9090 
     91/* --------------------------------------------------------------------------------------------- */ 
     92 
     93static char * 
     94replace_suffix_with (const char *src_str, const char *old_suffix, const char *new_suffix) 
     95{ 
     96    char *new_str, *sufx_ptr; 
     97    new_str = g_strndup (src_str, strlen (src_str) + strlen (new_suffix)); 
     98    sufx_ptr = g_strrstr (new_str, old_suffix); 
     99    if (sufx_ptr != NULL) 
     100    { 
     101        g_stpcpy (sufx_ptr, new_suffix); 
     102        return new_str; 
     103    } 
     104    else 
     105    { 
     106        g_free (new_str); 
     107        return NULL; 
     108    } 
     109} 
     110 
     111/* --------------------------------------------------------------------------------------------- */ 
     112/** 
     113 * Fills otherfile_vpath field with a detected and verified alternate (also called `other`) 
     114 * file path. In short, the other file is a header main.h when editing main.c and vice versa. 
     115 */ 
     116static gboolean 
     117edit_compute_other_file_vfs_path (WEdit * edit) 
     118{ 
     119    /* Default values, inspired by output of: ctags --list-map-extensions */ 
     120    char **headers; 
     121    char **sources; 
     122    char **exts[2] = { 0 }; 
     123    vfs_path_t *fs_path, *avg_path; 
     124    int idx, oth_type = -1, ext_index; 
     125    file_suitable_rank_t existing_rank; 
     126    gboolean ret = FALSE; 
     127 
     128    headers = g_strsplit (option_other_file_1_exts, ",", 0); 
     129    sources = g_strsplit (option_other_file_2_exts, ",", 0); 
     130 
     131    if ((headers == NULL || headers[0] == NULL) && (sources == NULL || sources[0] == NULL)) 
     132        goto other_ret; 
     133 
     134    exts[0] = headers; 
     135    exts[1] = sources; 
     136 
     137    /* Try the already computed one if it exists in otherfile_vpath field */ 
     138    fs_path = edit->otherfile_vpath; 
     139    avg_path = fs_path; 
     140    edit->otherfile_vpath = NULL; 
     141 
     142    /* Is it only an average match or no match? If yes, try to find a better one */ 
     143    existing_rank = edit_check_file_suitable (fs_path); 
     144    if (existing_rank <= FILE_RANK_AVERAGE_SUITABLE && edit->filename_vpath != NULL) 
     145    { 
     146        for (idx = 0; idx <= 1; idx++) 
     147        { 
     148            if (vfs_path_has_extension (edit->filename_vpath, (const char **) exts[idx], TRUE)) 
     149            { 
     150                oth_type = 1 - idx; 
     151                break; 
     152            } 
     153        } 
     154        if (oth_type >= 0) 
     155            fs_path = edit->filename_vpath; 
     156    } 
     157    /* No extension matched, or using the previously, highly suited file */ 
     158    if (oth_type == -1) 
     159    { 
     160        edit->otherfile_vpath = avg_path; 
     161        ret = (existing_rank >= FILE_RANK_AVERAGE_SUITABLE); 
     162        goto other_ret; 
     163    } 
     164 
     165    for (ext_index = 0; exts[oth_type][ext_index] != NULL; ext_index++) 
     166    { 
     167        char *try_path; 
     168        vfs_path_t *cand_fs_path = NULL; 
     169        file_suitable_rank_t rank; 
     170 
     171        try_path = replace_suffix_with (vfs_path_as_str (fs_path), ".", exts[oth_type][ext_index]); 
     172 
     173        if (try_path == NULL) 
     174            continue; 
     175 
     176        cand_fs_path = vfs_path_from_str (try_path); 
     177        g_free (try_path); 
     178 
     179        if (cand_fs_path == NULL) 
     180            continue; 
     181 
     182        rank = edit_check_file_suitable (cand_fs_path); 
     183        if (rank < FILE_RANK_AVERAGE_SUITABLE) 
     184        { 
     185            vfs_path_free (cand_fs_path); 
     186            cand_fs_path = NULL; 
     187            continue; 
     188        } 
     189        else if (rank == FILE_RANK_AVERAGE_SUITABLE) 
     190        { 
     191            if (existing_rank < rank) 
     192            { 
     193                existing_rank = rank; 
     194                if (avg_path != NULL) 
     195                    vfs_path_free (avg_path); 
     196                avg_path = cand_fs_path; 
     197                cand_fs_path = NULL; 
     198            } 
     199            else 
     200            { 
     201                vfs_path_free (cand_fs_path); 
     202                cand_fs_path = NULL; 
     203            } 
     204        } 
     205        else if (rank >= FILE_RANK_SUITABLE) 
     206        { 
     207            if (avg_path != NULL) 
     208                vfs_path_free (avg_path); 
     209            edit->otherfile_vpath = cand_fs_path; 
     210            ret = TRUE; 
     211            goto other_ret; 
     212        } 
     213    } 
     214 
     215    /* Any side-saved average candidate? */ 
     216    if (avg_path != NULL) 
     217    { 
     218        edit->otherfile_vpath = avg_path; 
     219        ret = (existing_rank >= FILE_RANK_AVERAGE_SUITABLE); 
     220    } 
     221 
     222  other_ret: 
     223    if (sources != NULL) 
     224        g_strfreev (sources); 
     225    if (headers != NULL) 
     226        g_strfreev (headers); 
     227    return ret; 
     228} 
     229 
    91230/* --------------------------------------------------------------------------------------------- */ 
    92231/** 
    93232 * Init the 'edit' subsystem 
    edit_dialog_command_execute (WDialog * h, long command) 
    391530        edit_add_window (h, wh->y + 1, wh->x, wh->lines - 2, wh->cols, NULL, 0); 
    392531        break; 
    393532    case CK_EditFile: 
    394         edit_load_cmd (h); 
     533        edit_load_cmd (h, NULL); 
     534        break; 
     535    case CK_OtherFile: 
     536        { 
     537            WEdit *e = (WEdit *) g->current->data; 
     538            gboolean retflag = FALSE; 
     539 
     540            if (e != NULL && edit_widget_is_editor (CONST_WIDGET (e))) 
     541            { 
     542                retflag = edit_compute_other_file_vfs_path (e); 
     543                if (retflag) 
     544                    retflag = edit_switch_to_file (h, e->otherfile_vpath); 
     545            } 
     546            if (!retflag) 
     547                ret = MSG_NOT_HANDLED; 
     548        } 
    395549        break; 
    396550    case CK_History: 
    397551        edit_load_file_from_history (h); 
    edit_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event) 
    11781332/* --------------------------------------------------------------------------------------------- */ 
    11791333/*** public functions ****************************************************************************/ 
    11801334/* --------------------------------------------------------------------------------------------- */ 
     1335 
     1336gboolean 
     1337edit_switch_to_file (WDialog * h, const vfs_path_t * file) 
     1338{ 
     1339    const WGroup *g = CONST_GROUP (h); 
     1340    GList *el; 
     1341    gboolean ret = FALSE; 
     1342 
     1343    for (el = g->widgets; el != NULL; el = g_list_next (el)) 
     1344    { 
     1345        if (edit_widget_is_editor (CONST_WIDGET (el->data))) 
     1346        { 
     1347            WEdit *e = (WEdit *) el->data; 
     1348            if (g_strcmp0 (edit_get_file_name (e), vfs_path_as_str (file)) == 0) 
     1349            { 
     1350                widget_select (WIDGET (e)); 
     1351                ret = TRUE; 
     1352                break; 
     1353            } 
     1354        } 
     1355    } 
     1356    /* File not loaded? -> If it is so, then open it. */ 
     1357    if (!ret) 
     1358        ret = edit_load_cmd (h, vfs_path_as_str (file)); 
     1359    return ret; 
     1360} 
     1361 
     1362/* --------------------------------------------------------------------------------------------- */ 
     1363 
    11811364/** 
    11821365 * Edit one file. 
    11831366 * 
  • src/editor/editwidget.h

    diff --git a/src/editor/editwidget.h b/src/editor/editwidget.h
    index 446ef07ac..b4b10692e 100644
    a b struct WEdit 
    7272 
    7373    vfs_path_t *filename_vpath; /* Name of the file */ 
    7474    vfs_path_t *dir_vpath;      /* NULL if filename is absolute */ 
     75    vfs_path_t *otherfile_vpath;        /* Name of the `other` file (e.g.: header, with .h extension) */ 
    7576 
    7677    /* dynamic buffers and cursor position for editor: */ 
    7778    edit_buffer_t buffer; 
  • src/keybind-defaults.c

    diff --git a/src/keybind-defaults.c b/src/keybind-defaults.c
    index 7b87c2f5a..aa4eb5ec0 100644
    a b static const global_keymap_ini_t default_editor_keymap[] = { 
    393393    {"InsertOverwrite", "insert"}, 
    394394    {"Help", "f1"}, 
    395395    {"Save", "f2"}, 
     396    {"OtherFile", "alt-a"}, 
    396397    {"Mark", "f3"}, 
    397398    {"Replace", "f4"}, 
    398399    {"Copy", "f5"}, 
  • src/setup.c

    diff --git a/src/setup.c b/src/setup.c
    index 77c07649d..c8fde7230 100644
    a b static const struct 
    404404    const char *opt_defval; 
    405405} str_options[] = { 
    406406#ifdef USE_INTERNAL_EDIT 
     407    { "editor_other_file_1_exts", &option_other_file_1_exts, 
     408                                   ".h,.hpp,.h++,.hh,.hp," 
     409                                     ".hxx,.inl,.inc,.def" }, 
     410    { "editor_other_file_2_exts", &option_other_file_2_exts, 
     411                                   ".c,.cpp,.c++,.cc,.cp,.cxx,.c+"}, 
    407412    { "editor_backup_extension", &option_backup_ext, "~" }, 
    408413    { "editor_filesize_threshold", &option_filesize_threshold, "64M" }, 
    409414    { "editor_stop_format_chars", &option_stop_format_chars, "-+*\\,.;:&>" },