Ticket #4206: StableWindowList_v2.patch

File StableWindowList_v2.patch, 22.7 KB (added by psprint, 4 years ago)

generic clustering

  • lib/widget.h

    From bd9955a7064677f99e181596ec63b997e457c6fe Mon Sep 17 00:00:00 2001
    From: Sebastian Gniazdowski <sgniazdowski@gmail.com>
    Date: Thu, 18 Feb 2021 02:12:39 -0600
    Subject: Stable, unchanged order of files in WindowList action.
    
    ---
     lib/widget.h                   |   1 +
     lib/widget/Makefile.am         |   1 +
     lib/widget/dialog.c            |  49 ++++--
     lib/widget/dialog.h            |   6 +
     lib/widget/order_kept_dialog.c | 262 +++++++++++++++++++++++++++++++++
     lib/widget/order_kept_dialog.h |  50 +++++++
     src/editor/edit.c              |   3 +-
     src/editor/edit.h              |   2 +
     src/editor/editwidget.c        |  63 +++++---
     src/setup.c                    |   2 +
     10 files changed, 401 insertions(+), 38 deletions(-)
     create mode 100644 lib/widget/order_kept_dialog.c
     create mode 100644 lib/widget/order_kept_dialog.h
    
    diff --git a/lib/widget.h b/lib/widget.h
    index e3bb5cac2..2bbbd2cfb 100644
    a b typedef struct WGroup WGroup; 
    2121#include "lib/widget/background.h" 
    2222#include "lib/widget/frame.h" 
    2323#include "lib/widget/dialog.h" 
     24#include "lib/widget/order_kept_dialog.h" 
    2425#include "lib/widget/history.h" 
    2526#include "lib/widget/button.h" 
    2627#include "lib/widget/buttonbar.h" 
  • lib/widget/Makefile.am

    diff --git a/lib/widget/Makefile.am b/lib/widget/Makefile.am
    index 90f023bbc..b7276c47b 100644
    a b libmcwidget_la_SOURCES = \ 
    77        buttonbar.c buttonbar.h \ 
    88        check.c check.h \ 
    99        dialog.c dialog.h \ 
     10        order_kept_dialog.c order_kept_dialog.h \ 
    1011        dialog-switch.c dialog-switch.h \ 
    1112        frame.c frame.h \ 
    1213        gauge.c gauge.h \ 
  • lib/widget/dialog.c

    diff --git a/lib/widget/dialog.c b/lib/widget/dialog.c
    index b8a08f029..c400cd0c0 100644
    a b dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flag 
    373373            gboolean compact, const int *colors, widget_cb_fn callback, 
    374374            widget_mouse_cb_fn mouse_callback, const char *help_ctx, const char *title) 
    375375{ 
    376     WDialog *new_d; 
     376    WDialog *new_h; 
     377    new_h = g_new0 (WDialog, 1); 
     378    if (new_h != NULL) 
     379    { 
     380        gboolean ret; 
     381        ret = dlg_init_object (new_h, modal, y1, x1, lines, cols, pos_flags, compact, colors, 
     382                               callback, mouse_callback, help_ctx, title); 
     383        if (!ret) 
     384        { 
     385            g_free (new_h); 
     386            return NULL; 
     387        } 
     388    } 
     389    return new_h; 
     390} 
     391 
     392/* --------------------------------------------------------------------------------------------- */ 
     393 
     394gboolean 
     395dlg_init_object (WDialog * new_h, gboolean modal, int y1, int x1, int lines, int cols, 
     396                 widget_pos_flags_t pos_flags, gboolean compact, const int *colors, 
     397                 widget_cb_fn callback, widget_mouse_cb_fn mouse_callback, const char *help_ctx, 
     398                 const char *title) 
     399{ 
    377400    Widget *w; 
    378401    WGroup *g; 
    379402 
    380     new_d = g_new0 (WDialog, 1); 
    381     w = WIDGET (new_d); 
    382     g = GROUP (new_d); 
     403    w = WIDGET (new_h); 
     404    g = GROUP (new_h); 
     405 
    383406    widget_adjust_position (pos_flags, &y1, &x1, &lines, &cols); 
    384407    group_init (g, y1, x1, lines, cols, callback != NULL ? callback : dlg_default_callback, 
    385408                mouse_callback != NULL ? mouse_callback : dlg_default_mouse_callback); 
    dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flag 
    397420 
    398421    w->get_colors = dlg_default_get_colors; 
    399422 
    400     new_d->colors = colors; 
    401     new_d->help_ctx = help_ctx; 
    402     new_d->compact = compact; 
    403     new_d->data = NULL; 
     423    new_h->colors = colors; 
     424    new_h->help_ctx = help_ctx; 
     425    new_h->compact = compact; 
     426    new_h->data = NULL; 
    404427 
    405428    if (modal) 
    406429    { 
    407430        w->state |= WST_MODAL; 
    408431 
    409         new_d->bg = WIDGET (frame_new (0, 0, w->lines, w->cols, title, FALSE, new_d->compact)); 
    410         group_add_widget (g, new_d->bg); 
    411         frame_set_title (FRAME (new_d->bg), title); 
     432        new_h->bg = WIDGET (frame_new (0, 0, w->lines, w->cols, title, FALSE, new_h->compact)); 
     433        group_add_widget (g, new_h->bg); 
     434        frame_set_title (FRAME (new_h->bg), title); 
    412435    } 
    413436 
    414437    /* unique name of event group for this dialog */ 
    415     new_d->event_group = g_strdup_printf ("%s_%p", MCEVENT_GROUP_DIALOG, (void *) new_d); 
     438    new_h->event_group = g_strdup_printf ("%s_%p", MCEVENT_GROUP_DIALOG, (void *) new_h); 
    416439 
    417     return new_d; 
     440    return TRUE; 
    418441} 
    419442 
    420443/* --------------------------------------------------------------------------------------------- */ 
  • lib/widget/dialog.h

    diff --git a/lib/widget/dialog.h b/lib/widget/dialog.h
    index 1d08b8e1a..ed90118b4 100644
    a b WDialog *dlg_create (gboolean modal, int y1, int x1, int lines, int cols, 
    102102                     const int *colors, widget_cb_fn callback, widget_mouse_cb_fn mouse_callback, 
    103103                     const char *help_ctx, const char *title); 
    104104 
     105gboolean dlg_init_object (WDialog * new_h, gboolean modal, int y1, int x1, int lines, int cols, 
     106                          widget_pos_flags_t pos_flags, gboolean compact, 
     107                          const int *colors, widget_cb_fn callback, 
     108                          widget_mouse_cb_fn mouse_callback, const char *help_ctx, 
     109                          const char *title); 
     110 
    105111void dlg_set_default_colors (void); 
    106112 
    107113void dlg_init (WDialog * h); 
  • new file lib/widget/order_kept_dialog.c

    diff --git a/lib/widget/order_kept_dialog.c b/lib/widget/order_kept_dialog.c
    new file mode 100644
    index 000000000..99521ba60
    - +  
     1/* 
     2   This dialog keeps a fixed order list of the widgets in its group (no Z-depth reordering). 
     3 
     4   Copyright (C) 2021 
     5   Free Software Foundation, Inc. 
     6 
     7   Written by: 
     8   Sebastian Gniazdowski <sgniazdowski@gmail.com>, 2021 
     9 
     10   This file is part of the Midnight Commander. 
     11 
     12   The Midnight Commander is free software: you can redistribute it 
     13   and/or modify it under the terms of the GNU General Public License as 
     14   published by the Free Software Foundation, either version 3 of the License, 
     15   or (at your option) any later version. 
     16 
     17   The Midnight Commander is distributed in the hope that it will be useful, 
     18   but WITHOUT ANY WARRANTY; without even the implied warranty of 
     19   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     20   GNU General Public License for more details. 
     21 
     22   You should have received a copy of the GNU General Public License 
     23   along with this program.  If not, see <http://www.gnu.org/licenses/>. 
     24 */ 
     25 
     26/** \file order_kept_dlg 
     27 *  \brief This extension of Dialog is to have a stable, fixed list of files in MCEdit. 
     28 *  \author Sebastian Gniazdowski 
     29 *  \date 2021 
     30 * 
     31 *  Before this class the files were fluctuating when they have been selected, as they 
     32 *  were brought to the front of the Z axis, which has been moving them in the `widgets` 
     33 *  list of the Group widget. 
     34 */ 
     35 
     36#include <config.h> 
     37 
     38#include "lib/global.h" 
     39#include "lib/util.h" 
     40#include "lib/widget.h" 
     41 
     42#include "src/editor/editwidget.h" 
     43 
     44/*** global variables ****************************************************************************/ 
     45 
     46/*** file scope macro definitions ****************************************************************/ 
     47 
     48/*** file scope type declarations ****************************************************************/ 
     49 
     50/*** file scope variables ************************************************************************/ 
     51 
     52/*** file scope functions ************************************************************************/ 
     53/* --------------------------------------------------------------------------------------------- */ 
     54 
     55/* To search WEdit by file name till extension, if any - extensions and case can differ */ 
     56static gboolean 
     57similar_filename_edit_widgets (gconstpointer a, gconstpointer b) 
     58{ 
     59    WEdit *wa = (WEdit *) a; 
     60    const char *fname_a = NULL, *fname_b = (const char *) b, *ext_a, *ext_b; 
     61    int len_a = 0, len_b = 0; 
     62 
     63    if (wa != NULL && wa->filename_vpath != NULL) 
     64        fname_a = vfs_path_as_str (wa->filename_vpath); 
     65 
     66    /* Reject identical */ 
     67    if ((fname_a == NULL || fname_b == NULL) || g_strcmp0 (fname_a, fname_b) == 0) 
     68        return FALSE; 
     69 
     70    ext_a = g_strrstr (fname_a, "."); 
     71    len_a = ext_a != NULL ? ext_a - fname_a : (int) strlen (fname_a); 
     72    ext_b = g_strrstr (fname_b, "."); 
     73    len_b = ext_b != NULL ? ext_b - fname_b : (int) strlen (fname_b); 
     74    return (len_a == len_b) && (g_ascii_strncasecmp (fname_a, fname_b, len_a) == 0); 
     75} 
     76 
     77/* --------------------------------------------------------------------------------------------- */ 
     78/* Sorts widgets by clustering headers and sources adjacent */ 
     79 
     80static gboolean 
     81sort_edit_widgets (GPtrArray * array, order_kept_dialog_sort_flags_t sort_flags) 
     82{ 
     83    WEdit *we, *we_con; 
     84    const char *fname, *fname_con; 
     85    guint con_idx = 0, idx; 
     86    gboolean ret = FALSE, ret_con; 
     87    int sort; 
     88 
     89    /* No need to sort? */ 
     90    if ((sort_flags & (ORDER_DLG_GLUE_DIFFERENT_EXTS | 
     91                       ORDER_DLG_GLUE_DIFFERENT_EXTS_REVERSED)) == 0) 
     92        return ret; 
     93 
     94    /* Iterate over array inserting headers before/after its sources */ 
     95    for (idx = 0; idx < array->len; idx++) 
     96    { 
     97        we = (WEdit *) g_ptr_array_index (array, idx); 
     98        if (we->filename_vpath == NULL) 
     99            continue; 
     100        fname = vfs_path_as_str (we->filename_vpath); 
     101 
     102        if (fname == NULL) 
     103            continue; 
     104 
     105        /* Search for a similar file */ 
     106        ret_con = g_ptr_array_find_with_equal_func (array, fname, 
     107                                                    similar_filename_edit_widgets, &con_idx); 
     108 
     109        /* There's no contary file? */ 
     110        if (!ret_con || con_idx == idx || array->pdata[idx] == array->pdata[con_idx]) 
     111            continue; 
     112 
     113        /* Fetch filename of found, similar file */ 
     114        we_con = (WEdit *) g_ptr_array_index (array, con_idx); 
     115        if (we_con->filename_vpath == NULL) 
     116            continue; 
     117        fname_con = vfs_path_as_str (we_con->filename_vpath); 
     118 
     119        ret = TRUE; 
     120 
     121        /* E.g.: if fname has no extension, it'll be sorted first «» -1 */ 
     122        sort = g_strcmp0 (extension (fname), extension (fname_con)); 
     123        if (sort == 0) 
     124            sort = g_strcmp0 (fname, fname_con); 
     125 
     126        /* Move headers and their sources at adjacent positions */ 
     127        if (con_idx < idx && (sort_flags & ORDER_DLG_GLUE_DIFFERENT_EXTS) != 0) 
     128        { 
     129            gpointer file = g_ptr_array_steal_index (array, idx); 
     130            g_ptr_array_insert (array, (sort < 0) ? con_idx : con_idx + 1, file); 
     131        } 
     132        else if (idx < con_idx && (sort_flags & ORDER_DLG_GLUE_DIFFERENT_EXTS) != 0) 
     133        { 
     134            gpointer con_file = g_ptr_array_steal_index (array, con_idx); 
     135            g_ptr_array_insert (array, (sort < 0) ? idx + 1 : idx, con_file); 
     136            idx++; 
     137        } 
     138        else if (con_idx < idx && (sort_flags & ORDER_DLG_GLUE_DIFFERENT_EXTS_REVERSED) != 0) 
     139        { 
     140            gpointer file = g_ptr_array_steal_index (array, idx); 
     141            g_ptr_array_insert (array, (sort < 0) ? con_idx + 1 : con_idx, file); 
     142        } 
     143        else if (idx < con_idx && (sort_flags & ORDER_DLG_GLUE_DIFFERENT_EXTS_REVERSED) != 0) 
     144        { 
     145            gpointer con_file = g_ptr_array_steal_index (array, con_idx); 
     146            g_ptr_array_insert (array, (sort < 0) ? idx : idx + 1, con_file); 
     147            idx++; 
     148        } 
     149    }; 
     150    return ret; 
     151} 
     152 
     153/* --------------------------------------------------------------------------------------------- */ 
     154/* Called after any action properly handled by front WDialog */ 
     155 
     156static gboolean 
     157order_dlg_update_widgets_array (WOrderKeptDialog * h) 
     158{ 
     159    GList *w; 
     160    gboolean ret = FALSE; 
     161    guint idx; 
     162 
     163    /* Initialize pointer array */ 
     164    if (h->ordered_widgets == NULL) 
     165        h->ordered_widgets = g_ptr_array_new (); 
     166 
     167    /* Copy newly opened files */ 
     168    for (w = GROUP (h)->widgets; w != NULL; w = g_list_next (w)) 
     169    { 
     170        if (edit_widget_is_editor (CONST_WIDGET (w->data)) && 
     171            !g_ptr_array_find (h->ordered_widgets, w->data, NULL)) 
     172        { 
     173            g_ptr_array_add (h->ordered_widgets, w->data); 
     174            ret = TRUE; 
     175        } 
     176    } 
     177 
     178    /* Pop closed files */ 
     179    for (idx = 0; idx < h->ordered_widgets->len; idx++) 
     180        if (g_list_find (GROUP (h)->widgets, g_ptr_array_index (h->ordered_widgets, idx)) == NULL) 
     181            g_ptr_array_remove_index (h->ordered_widgets, idx); 
     182 
     183    /* Sort if needed */ 
     184    if (ret) 
     185        order_dlg_sort_widgets (h); 
     186 
     187    return ret; 
     188} 
     189 
     190/* --------------------------------------------------------------------------------------------- */ 
     191/*** public functions ****************************************************************************/ 
     192/* --------------------------------------------------------------------------------------------- */ 
     193 
     194WOrderKeptDialog * 
     195order_dlg_create (gboolean modal, int y1, int x1, int lines, int cols, 
     196                  widget_pos_flags_t pos_flags, gboolean compact, 
     197                  const int *colors, widget_cb_fn callback, 
     198                  widget_cb_fn base_callback, 
     199                  widget_mouse_cb_fn mouse_callback, 
     200                  const char *help_ctx, const char *title, order_kept_dialog_sort_flags_t sort) 
     201{ 
     202    WOrderKeptDialog *new_oh; 
     203    gboolean ret; 
     204 
     205    new_oh = g_new0 (WOrderKeptDialog, 1); 
     206    new_oh->sort_flags = sort; 
     207    ret = dlg_init_object (DIALOG (new_oh), modal, y1, x1, lines, cols, pos_flags, compact, colors, 
     208                           callback, mouse_callback, help_ctx, title); 
     209    if (!ret) 
     210    { 
     211        g_free (new_oh); 
     212        return NULL; 
     213    } 
     214 
     215    new_oh->base_callback = base_callback; 
     216    return new_oh; 
     217} 
     218 
     219/* --------------------------------------------------------------------------------------------- */ 
     220 
     221cb_ret_t 
     222order_dlg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data) 
     223{ 
     224    WOrderKeptDialog *h = ORDER_DIALOG (w); 
     225    cb_ret_t ret = MSG_NOT_HANDLED; 
     226 
     227    switch (msg) 
     228    { 
     229    case MSG_INIT: 
     230        /* Initial copy of WEdit pointers kept in WGroup::widgets */ 
     231        order_dlg_update_widgets_array (h); 
     232        break; 
     233    case MSG_DESTROY: 
     234        /* Only a shallow release, as WEdit objects are owned by WGroup base object */ 
     235        g_ptr_array_free (h->ordered_widgets, TRUE); 
     236        h->ordered_widgets = NULL; 
     237        break; 
     238    default: 
     239        break; 
     240    } 
     241 
     242    if (ret != MSG_HANDLED) 
     243    { 
     244        ret = h->base_callback (w, sender, msg, parm, data); 
     245        if (ret == MSG_HANDLED) 
     246            /* Add and pop new or closed files */ 
     247            order_dlg_update_widgets_array (h); 
     248    } 
     249 
     250    return ret; 
     251} 
     252 
     253/* --------------------------------------------------------------------------------------------- */ 
     254/* Sorts main widget list (adjacent headers/sources) */ 
     255 
     256void 
     257order_dlg_sort_widgets (WOrderKeptDialog * h) 
     258{ 
     259    sort_edit_widgets (h->ordered_widgets, h->sort_flags); 
     260} 
     261 
     262/* --------------------------------------------------------------------------------------------- */ 
  • new file lib/widget/order_kept_dialog.h

    diff --git a/lib/widget/order_kept_dialog.h b/lib/widget/order_kept_dialog.h
    new file mode 100644
    index 000000000..8cbb51486
    - +  
     1#ifndef MC__TEMPLATE_H 
     2#define MC__TEMPLATE_H 
     3 
     4/*** typedefs(not structures) and defined constants **********************************************/ 
     5 
     6#define ORDER_DIALOG(x) ((WOrderKeptDialog *)(x)) 
     7#define CONST_ORDER_DIALOG(x) ((const WOrderKeptDialog *)(x)) 
     8 
     9/*** enums ***************************************************************************************/ 
     10 
     11/* Default is: (1<<0) | (1<<7) */ 
     12typedef enum 
     13{ 
     14    ORDER_DLG_DEFAULT_SORT = 0, 
     15    ORDER_DLG_GLUE_DIFFERENT_EXTS = (1 << 0), 
     16    ORDER_DLG_GLUE_DIFFERENT_EXTS_REVERSED = (1 << 1), 
     17    ORDER_DLG_ALLOW_STANDARD_REORDERING = (1 << 2), 
     18    ORDER_DLG_SORT_REVERSE = (1 << 3), 
     19    ORDER_DLG_SORT_BACKUP_FILES_LAST = (1 << 5) 
     20} order_kept_dialog_sort_flags_t; 
     21 
     22/*** structures declarations (and typedefs of structures)*****************************************/ 
     23 
     24typedef struct WOrderKeptDialog 
     25{ 
     26    WDialog base; 
     27    GPtrArray *ordered_widgets; 
     28    widget_cb_fn base_callback; 
     29    order_kept_dialog_sort_flags_t sort_flags; 
     30} WOrderKeptDialog; 
     31 
     32/*** global variables defined in .c file *********************************************************/ 
     33 
     34/*** declarations of public functions ************************************************************/ 
     35 
     36WOrderKeptDialog *order_dlg_create (gboolean modal, int y1, int x1, int lines, int cols, 
     37                                    widget_pos_flags_t pos_flags, gboolean compact, 
     38                                    const int *colors, widget_cb_fn callback, 
     39                                    widget_cb_fn base_callback, 
     40                                    widget_mouse_cb_fn mouse_callback, 
     41                                    const char *help_ctx, const char *title, 
     42                                    order_kept_dialog_sort_flags_t sort); 
     43 
     44cb_ret_t order_dlg_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data); 
     45 
     46void order_dlg_sort_widgets (WOrderKeptDialog * h); 
     47 
     48/*** inline functions ****************************************************************************/ 
     49 
     50#endif /* MC__ORDER_DIALOG_H */ 
  • src/editor/edit.c

    diff --git a/src/editor/edit.c b/src/editor/edit.c
    index edda1f832..48b7a05b5 100644
    a b gboolean option_line_state = FALSE; 
    9090int option_line_state_width = 0; 
    9191gboolean option_cursor_after_inserted_block = FALSE; 
    9292gboolean option_state_full_filename = FALSE; 
    93  
     93gboolean option_cluster_similar_filenames = TRUE; 
     94gboolean option_cluster_similar_filenames_reversed = TRUE; 
    9495gboolean enable_show_tabs_tws = TRUE; 
    9596gboolean option_check_nl_at_eof = FALSE; 
    9697gboolean option_group_undo = FALSE; 
  • src/editor/edit.h

    diff --git a/src/editor/edit.h b/src/editor/edit.h
    index 6c519e9d3..199394187 100644
    a b extern gboolean option_persistent_selections; 
    4141extern gboolean option_drop_selection_on_copy; 
    4242extern gboolean option_cursor_beyond_eol; 
    4343extern gboolean option_cursor_after_inserted_block; 
     44extern gboolean option_cluster_similar_filenames; 
     45extern gboolean option_cluster_similar_filenames_reversed; 
    4446extern gboolean option_state_full_filename; 
    4547extern gboolean option_line_state; 
    4648extern int option_save_mode; 
  • src/editor/editwidget.c

    diff --git a/src/editor/editwidget.c b/src/editor/editwidget.c
    index 18ac00e66..72f76d3c7 100644
    a b get_hotkey (int n) 
    295295static void 
    296296edit_window_list (const WDialog * h) 
    297297{ 
    298     const WGroup *g = CONST_GROUP (h); 
    299     const size_t offset = 2;    /* skip menu and buttonbar */ 
    300     const size_t dlg_num = g_list_length (g->widgets) - offset; 
     298    const WOrderKeptDialog *od = ORDER_DIALOG (h); 
     299    const size_t dlg_num = od->ordered_widgets->len; 
    301300    int lines, cols; 
    302301    Listbox *listbox; 
    303     GList *w; 
    304302    WEdit *selected; 
    305     int i = 0; 
     303    WListbox *lw; 
     304    uint idx; 
    306305 
    307306    lines = MIN ((size_t) (LINES * 2 / 3), dlg_num); 
    308307    cols = COLS * 2 / 3; 
    309308 
    310309    listbox = create_listbox_window (lines, cols, _("Open files"), "[Open files]"); 
    311310 
    312     for (w = g->widgets; w != NULL; w = g_list_next (w)) 
    313         if (edit_widget_is_editor (CONST_WIDGET (w->data))) 
    314         { 
    315             WEdit *e = (WEdit *) w->data; 
    316             char *fname; 
     311    /* Convenience variable. */ 
     312    lw = LISTBOX (listbox->list); 
    317313 
    318             if (e->filename_vpath == NULL) 
    319                 fname = g_strdup_printf ("%c [%s]", e->modified ? '*' : ' ', _("NoName")); 
    320             else 
    321                 fname = 
    322                     g_strdup_printf ("%c%s", e->modified ? '*' : ' ', 
    323                                      vfs_path_as_str (e->filename_vpath)); 
     314    /* Iterate over designated ptr array */ 
     315    for (idx = 0; idx < od->ordered_widgets->len; idx++) 
     316    { 
     317        WEdit *e = (WEdit *) g_ptr_array_index (od->ordered_widgets, idx); 
     318        char *fname; 
    324319 
    325             listbox_add_item (listbox->list, LISTBOX_APPEND_AT_END, get_hotkey (i++), 
    326                               str_term_trim (fname, WIDGET (listbox->list)->cols - 2), e, FALSE); 
    327             g_free (fname); 
    328         } 
     320        if (e->filename_vpath == NULL) 
     321            fname = g_strdup_printf ("%c [%s]", e->modified ? '*' : ' ', _("NoName")); 
     322        else 
     323            fname = 
     324                g_strdup_printf ("%c%s", e->modified ? '*' : ' ', 
     325                                 vfs_path_as_str (e->filename_vpath)); 
    329326 
    330     selected = run_listbox_with_data (listbox, g->current->data); 
     327        listbox_add_item (lw, LISTBOX_APPEND_AT_END, get_hotkey (idx), 
     328                          str_term_trim (fname, WIDGET (lw)->cols - 2), e, FALSE); 
     329        g_free (fname); 
     330    } 
     331 
     332    selected = run_listbox_with_data (listbox, GROUP (od)->current->data); 
    331333    if (selected != NULL) 
    332334        widget_select (WIDGET (selected)); 
    333335} 
    gboolean 
    12061208edit_files (const GList * files) 
    12071209{ 
    12081210    static gboolean made_directory = FALSE; 
     1211    WOrderKeptDialog *order_edit_dlg; 
    12091212    WDialog *edit_dlg; 
    12101213    WGroup *g; 
    12111214    WMenuBar *menubar; 
    12121215    Widget *w, *wd; 
     1216    order_kept_dialog_sort_flags_t sort_flags = ORDER_DLG_DEFAULT_SORT; 
    12131217    const GList *file; 
    12141218    gboolean ok = FALSE; 
    12151219 
    edit_files (const GList * files) 
    12301234        g_free (dir); 
    12311235    } 
    12321236 
     1237    if (option_cluster_similar_filenames) 
     1238    { 
     1239        if (!option_cluster_similar_filenames_reversed) 
     1240            sort_flags |= ORDER_DLG_GLUE_DIFFERENT_EXTS; 
     1241        else 
     1242            sort_flags |= ORDER_DLG_GLUE_DIFFERENT_EXTS_REVERSED; 
     1243    } 
    12331244    /* Create a new dialog and add it widgets to it */ 
    1234     edit_dlg = 
    1235         dlg_create (FALSE, 0, 0, 1, 1, WPOS_FULLSCREEN, FALSE, NULL, edit_dialog_callback, 
    1236                     edit_dialog_mouse_callback, "[Internal File Editor]", NULL); 
     1245    order_edit_dlg = 
     1246        order_dlg_create (FALSE, 0, 0, 1, 1, WPOS_FULLSCREEN, FALSE, NULL, 
     1247                          order_dlg_callback, edit_dialog_callback, 
     1248                          edit_dialog_mouse_callback, "[Internal File Editor]", NULL, sort_flags); 
     1249 
     1250    edit_dlg = DIALOG (order_edit_dlg); 
    12371251    wd = WIDGET (edit_dlg); 
     1252 
    12381253    widget_want_tab (wd, TRUE); 
    12391254    wd->keymap = editor_map; 
    12401255    wd->ext_keymap = editor_x_map; 
  • src/setup.c

    diff --git a/src/setup.c b/src/setup.c
    index 77c07649d..5e4d156b5 100644
    a b static const struct 
    356356    { "editor_check_new_line", &option_check_nl_at_eof }, 
    357357    { "editor_show_right_margin", &show_right_margin }, 
    358358    { "editor_group_undo", &option_group_undo }, 
     359    { "editor_cluster_similar_filenames", &option_cluster_similar_filenames }, 
     360    { "editor_cluster_similar_filenames_reversed", &option_cluster_similar_filenames_reversed }, 
    359361    { "editor_state_full_filename", &option_state_full_filename }, 
    360362#endif /* USE_INTERNAL_EDIT */ 
    361363    { "editor_ask_filename_before_edit", &editor_ask_filename_before_edit },