From a18ce8dcba77fe4b4ffca8528be06b57200faed8 Mon Sep 17 00:00:00 2001 From: Charlie Gordon Date: Sun, 8 May 2005 15:08:07 +0000 Subject: [PATCH] improved bufed mode: added BUFED_ALL_VISIBLE flag to include system buffers in list display buffer size added bufed_clear_modified, bufed_toggle_modified. added bufed_toggle_all_visible, navigation keys. improved dired mode: store file details in separate structure added sorting options, marking options --- bufed.c | 149 ++++++++++++++++++---- dired.c | 383 ++++++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 429 insertions(+), 103 deletions(-) diff --git a/bufed.c b/bufed.c index 013e22f..c4826f1 100644 --- a/bufed.c +++ b/bufed.c @@ -18,8 +18,14 @@ */ #include "qe.h" +enum { + BUFED_ALL_VISIBLE = 1 +}; + typedef struct BufedState { StringArray items; + int flags; + int last_index; } BufedState; ModeDef bufed_mode; @@ -27,29 +33,47 @@ ModeDef bufed_mode; static void build_bufed_list(EditState *s) { QEmacsState *qs = s->qe_state; - EditBuffer *b; + EditBuffer *b, *b1; BufedState *hs; + int last_index = list_get_pos(s); int i; hs = s->mode_data; free_strings(&hs->items); - for(b = qs->first_buffer; b != NULL; b = b->next) { - if (!(b->flags & BF_SYSTEM)) + for (b = qs->first_buffer; b != NULL; b = b->next) { + if (!(b->flags & BF_SYSTEM) || (hs->flags & BUFED_ALL_VISIBLE)) add_string(&hs->items, b->name); } /* build buffer */ b = s->b; eb_delete(b, 0, b->total_size); - for(i=0;iitems.nb_items;i++) { - eb_printf(b, " %s", hs->items.items[i]->str); - if (i != hs->items.nb_items - 1) - eb_printf(b, "\n"); + for (i = 0; i < hs->items.nb_items; i++) { + eb_printf(b, " %-20s", hs->items.items[i]->str); + b1 = eb_find(hs->items.items[i]->str); + if (b1) { + /* CG: should also display mode */ + eb_printf(b, " %10d %s", b1->total_size, b1->filename); + } + eb_printf(b, "\n"); } + s->offset = eb_goto_pos(s->b, last_index, 0); } -static void bufed_select(EditState *s) +static EditBuffer *bufed_get_buffer(EditState *s) +{ + BufedState *bs = s->mode_data; + int index; + + index = list_get_pos(s); + if (index < 0 || index >= bs->items.nb_items) + return NULL; + + return eb_find(bs->items.items[index]->str); +} + +static void bufed_select(EditState *s, int temp) { BufedState *bs = s->mode_data; StringItem *item; @@ -60,16 +84,29 @@ static void bufed_select(EditState *s) index = list_get_pos(s); if (index < 0 || index >= bs->items.nb_items) return; + + if (temp && index == bs->last_index) + return; + item = bs->items.items[index]; b = eb_find(item->str); if (!b) return; e = find_window_right(s); - if (!e) - return; - /* delete dired window */ - do_delete_window(s, 1); - switch_to_buffer(e, b); + if (temp) { + if (e) { + bs->last_index = index; + switch_to_buffer(e, b); + } + return; + } + if (e) { + /* delete dired window */ + do_delete_window(s, 1); + switch_to_buffer(e, b); + } else { + switch_to_buffer(s, b); + } } /* iterate 'func_item' to selected items. If no selected items, then @@ -118,10 +155,16 @@ static void do_list_buffers(EditState *s) { QEmacsState *qs = s->qe_state; BufedState *bs; - EditBuffer *b; - EditState *e; + EditBuffer *b, *b0; + EditState *e, *e1; int width, i; + /* remember current buffer for target positioning, because + * s may be destroyed by insert_window_left + * CG: remove this kludge once we have delayed EditState free + */ + b0 = s->b; + /* XXX: must close this buffer when destroying window: add a special buffer flag to tell this */ b = eb_new("*bufed*", BF_READONLY | BF_SYSTEM); @@ -130,12 +173,16 @@ static void do_list_buffers(EditState *s) e = insert_window_left(b, width, WF_MODELINE); do_set_mode(e, &bufed_mode, NULL); + e1 = find_window_right(e); + if (e1) + b0 = e1->b; + bs = e->mode_data; /* if active buffer is found, go directly on it */ - for(i=0;iitems.nb_items;i++) { - if (!strcmp(bs->items.items[i]->str, s->b->name)) { - e->offset = eb_goto_pos(e->b, i, 0); + for (i = 0; i < bs->items.nb_items; i++) { + if (!strcmp(bs->items.items[i]->str, b0->name)) { + e->offset = eb_goto_pos(e->b, i, 0); break; } } @@ -144,6 +191,49 @@ static void do_list_buffers(EditState *s) qs->active_window = e; } +static void bufed_clear_modified(EditState *s) +{ + EditBuffer *b; + + b = bufed_get_buffer(s); + if (!b) + return; + + b->modified = 0; + build_bufed_list(s); +} + +static void bufed_toggle_read_only(EditState *s) +{ + EditBuffer *b; + + b = bufed_get_buffer(s); + if (!b) + return; + + b->flags ^= BF_READONLY; + build_bufed_list(s); +} + +static void bufed_refresh(EditState *s, int toggle) +{ + BufedState *bs = s->mode_data; + + if (toggle) + bs->flags ^= BUFED_ALL_VISIBLE; + + build_bufed_list(s); +} + +static void bufed_display_hook(EditState *s) +{ + /* Prevent point from going beyond list */ + if (s->offset && s->offset == s->b->total_size) + do_up_down(s, -1); + + bufed_select(s, 1); +} + static int bufed_mode_init(EditState *s, ModeSavedData *saved_data) { list_mode.mode_init(s, saved_data); @@ -155,19 +245,28 @@ static int bufed_mode_init(EditState *s, ModeSavedData *saved_data) static void bufed_mode_close(EditState *s) { - BufedState *hs; - hs = s->mode_data; - free_strings(&hs->items); + BufedState *bs = s->mode_data; + + free_strings(&bs->items); list_mode.mode_close(s); } /* specific bufed commands */ static CmdDef bufed_commands[] = { - CMD0( KEY_RET, KEY_RIGHT, "bufed-select", bufed_select) - CMD1( KEY_CTRL('g'), KEY_NONE, "delete-window", do_delete_window, 0) + CMD1( KEY_RET, KEY_RIGHT, "bufed-select", bufed_select, 0) + /* bufed-abort should restore previous buffer in right-window */ + CMD1( KEY_CTRL('g'), KEY_NONE, "bufed-abort", do_delete_window, 0) CMD0( ' ', KEY_CTRL('t'), "bufed-toggle_selection", list_toggle_selection) - CMD0( KEY_F8, KEY_NONE, "bufed-kill-buffer", bufed_kill_buffer) + /* BS should go back to previous item and unmark it */ + //CMD1( 'u', KEY_NONE, "bufed-unmark", bufed_mark, ' ') + CMD0( '~', KEY_NONE, "bufed-clear-modified", bufed_clear_modified) + CMD0( '%', KEY_NONE, "bufed-toggle-read-only", bufed_toggle_read_only) + CMD1( 'a', KEY_NONE, "bufed-toggle-all-visible", bufed_refresh, 1) + CMD1( 'n', KEY_NONE, "next-line", do_up_down, 1 ) + CMD1( 'p', KEY_NONE, "previous-line", do_up_down, -1 ) + CMD1( 'r', 'g', "bufed-refresh", bufed_refresh, 0) + CMD0( 'k', KEY_F8, "bufed-kill-buffer", bufed_kill_buffer) CMD_DEF_END, }; @@ -179,11 +278,13 @@ static CmdDef bufed_global_commands[] = { static int bufed_init(void) { /* inherit from list mode */ + /* CG: assuming list_mode already initialized ? */ memcpy(&bufed_mode, &list_mode, sizeof(ModeDef)); bufed_mode.name = "bufed"; bufed_mode.instance_size = sizeof(BufedState); bufed_mode.mode_init = bufed_mode_init; bufed_mode.mode_close = bufed_mode_close; + bufed_mode.display_hook = bufed_display_hook; /* first register mode */ qe_register_mode(&bufed_mode); diff --git a/dired.c b/dired.c index d2a7583..5e5d875 100644 --- a/dired.c +++ b/dired.c @@ -18,28 +18,40 @@ */ #include "qe.h" +enum { DIRED_HEADER = 0 }; + +enum { + DIRED_SORT_NAME = 1, + DIRED_SORT_EXTENSION = 2, + DIRED_SORT_SIZE = 4, + DIRED_SORT_DATE = 8, + DIRED_SORT_MASK = 1+2+4+8, + DIRED_SORT_GROUP = 16, + DIRED_SORT_DESCENDING = 32, +}; + typedef struct DiredState { StringArray items; - int last_pos; + int sort_mode; /* DIRED_SORT_GROUP | DIRED_SORT_NAME */ + int last_index; char path[1024]; /* current path */ } DiredState; -static void open_new_file(EditState *s); +/* opaque structure for sorting DiredState.items StringArray */ +typedef struct DiredItem { + DiredState *state; + mode_t mode; + off_t size; + time_t mtime; + int offset; + char mark; + char name[1]; +} DiredItem; -static void dired_display(EditState *s) -{ - DiredState *ds = s->mode_data; - int pos; +static void dired_view_file(EditState *s, const char *filename); - list_mode.display(s); - - /* open file so that user can see it before it is selected */ - /* XXX: find a better solution (callback) */ - pos = list_get_pos(s); - if (pos != ds->last_pos) { - ds->last_pos = pos; - open_new_file(s); - } +extern inline int dired_get_index(EditState *s) { + return list_get_pos(s) - DIRED_HEADER; } void dired_free(EditState *s) @@ -48,12 +60,14 @@ void dired_free(EditState *s) int i; /* free opaques */ - for(i=0;iitems.nb_items;i++) { + for (i = 0; i < ds->items.nb_items; i++) { free(ds->items.items[i]->opaque); } free_strings(&ds->items); + ds->last_index = -1; + /* reset cursor position */ s->offset = 0; } @@ -61,19 +75,141 @@ void dired_free(EditState *s) /* sort alphabetically with directories first */ static int dired_sort_func(const void *p1, const void *p2) { - StringItem *item1 = *(StringItem **)p1; - StringItem *item2 = *(StringItem **)p2; - int len1, len2, is_dir1, is_dir2; + const StringItem *item1 = *(const StringItem **)p1; + const StringItem *item2 = *(const StringItem **)p2; + const DiredItem *dip1 = item1->opaque; + const DiredItem *dip2 = item2->opaque; + int mode = dip1->state->sort_mode, res; + int is_dir1, is_dir2; - len1 = strlen(item1->str); - len2 = strlen(item2->str); - is_dir1 = (strchr(item1->str, '/') != NULL); - is_dir2 = (strchr(item2->str, '/') != NULL); + if (mode & DIRED_SORT_GROUP) { + is_dir1 = !!S_ISDIR(dip1->mode); + is_dir2 = !!S_ISDIR(dip2->mode); + if (is_dir1 != is_dir2) + return is_dir2 - is_dir1; + } + for (;;) { + if (mode & DIRED_SORT_DATE) { + if (dip1->mtime != dip2->mtime) { + res = (dip1->mtime < dip2->mtime) ? -1 : 1; + break; + } + } + if (mode & DIRED_SORT_SIZE) { + if (dip1->size != dip2->size) { + res = (dip1->size < dip2->size) ? -1 : 1; + break; + } + } + if (mode & DIRED_SORT_EXTENSION) { + res = strcmp(extension(dip1->name), extension(dip2->name)); + if (res) + break; + } + res = strcmp(dip1->name, dip2->name); + break; + } + return (mode & DIRED_SORT_DESCENDING) ? -res : res; +} + +/* select current item */ +static void do_dired_sort(EditState *s) +{ + DiredState *hs = s->mode_data; + StringItem *item, *cur_item; + DiredItem *dip; + EditBuffer *b; + int index, i; + + index = dired_get_index(s); + cur_item = NULL; + if (index >= 0 && index < hs->items.nb_items) + cur_item = hs->items.items[index]; + + qsort(hs->items.items, hs->items.nb_items, + sizeof(StringItem *), dired_sort_func); + + /* construct list buffer */ + b = s->b; + b->flags &= ~BF_READONLY; + eb_delete(b, 0, b->total_size); + s->offset = 0; + if (DIRED_HEADER) + eb_printf(b, " %s:\n", hs->path); + for (i = 0; i < hs->items.nb_items; i++) { + item = hs->items.items[i]; + dip = item->opaque; + dip->offset = b->total_size; + if (item == cur_item) + s->offset = b->total_size; + eb_printf(b, "%c %s\n", dip->mark, item->str); + } + b->modified = 0; + b->flags |= BF_READONLY; +} + +static void dired_mark(EditState *s, int mark) +{ + DiredState *hs = s->mode_data; + const StringItem *item; + DiredItem *dip; + unsigned char ch; + int index; + + index = dired_get_index(s); + + if (index < 0 || index >= hs->items.nb_items) + return; + item = hs->items.items[index]; + dip = item->opaque; + + ch = dip->mark = mark; + eb_write(s->b, dip->offset, &ch, 1); + + text_move_up_down(s, 1); +} + +static void dired_sort(EditState *s, const char *sort_order) +{ + DiredState *hs = s->mode_data; + const char *p; - if (is_dir1 != is_dir2) - return is_dir2 - is_dir1; - else - return strcmp(item1->str, item2->str); + for (p = sort_order; *p; p++) { + switch (tolower(*p)) { + case 'n': /* name */ + hs->sort_mode &= ~DIRED_SORT_MASK; + hs->sort_mode |= DIRED_SORT_NAME; + break; + case 'e': /* extension */ + hs->sort_mode &= ~DIRED_SORT_MASK; + hs->sort_mode |= DIRED_SORT_EXTENSION; + break; + case 's': /* size */ + hs->sort_mode &= ~DIRED_SORT_MASK; + hs->sort_mode |= DIRED_SORT_SIZE; + break; + case 'd': /* direct */ + hs->sort_mode &= ~DIRED_SORT_MASK; + hs->sort_mode |= DIRED_SORT_DATE; + break; + case 'u': /* ungroup */ + hs->sort_mode &= ~DIRED_SORT_GROUP; + break; + case 'g': /* group */ + hs->sort_mode |= DIRED_SORT_GROUP; + break; + case '+': /* ascending */ + hs->sort_mode &= ~DIRED_SORT_DESCENDING; + break; + case '-': /* descending */ + hs->sort_mode |= DIRED_SORT_DESCENDING; + break; + case 'r': /* reverse */ + hs->sort_mode ^= DIRED_SORT_DESCENDING; + break; + } + } + do_dired_sort(s); } #define MAX_COL_FILE_SIZE 32 @@ -86,15 +222,16 @@ void build_dired_list(EditState *s, const char *path) char line[1024], buf[1024]; const char *p; struct stat st; - int ct, len, i; + int ct, len; StringItem *item; - EditBuffer *b; /* free previous list, if any */ dired_free(s); - hs->last_pos = -1; + /* CG: should make absolute ? */ canonize_path(hs->path, sizeof(hs->path), path); + set_filename(s->b, hs->path); + s->b->flags |= BF_DIRED; ffs = find_file_open(hs->path, "*"); while (!find_file_next(ffs, filename, sizeof(filename))) { @@ -102,12 +239,12 @@ void build_dired_list(EditState *s, const char *path) continue; p = basename(filename); +#if 1 /* CG: bad idea, but causes spurious bugs */ /* exclude redundant '.' and '..' */ if (!strcmp(p, ".") || !strcmp(p, "..")) continue; - - strcpy(line, " "); - pstrcat(line, sizeof(line), p); +#endif + pstrcpy(line, sizeof(line), p); ct = 0; if (S_ISDIR(st.st_mode)) { ct = '/'; @@ -115,6 +252,8 @@ void build_dired_list(EditState *s, const char *path) ct = '|'; } else if (S_ISSOCK(st.st_mode)) { ct = '='; + } else if (S_ISLNK(st.st_mode)) { + ct = '@'; } else if ((st.st_mode & 0111) != 0) { ct = '*'; } @@ -152,43 +291,44 @@ void build_dired_list(EditState *s, const char *path) pstrcat(line, sizeof(line), buf); item = add_string(&hs->items, line); - if (item) - item->opaque = strdup(p); + if (item) { + DiredItem *dip; + + dip = malloc(sizeof(DiredItem) + strlen(p)); + dip->state = hs; + dip->mode = st.st_mode; + dip->size = st.st_size; + dip->mtime = st.st_mtime; + dip->mark = ' '; + strcpy(dip->name, p); + item->opaque = dip; + } } find_file_close(ffs); - qsort(hs->items.items, hs->items.nb_items, - sizeof(StringItem *), dired_sort_func); - - /* construct list buffer */ - b = s->b; - eb_delete(b, 0, b->total_size); - for(i=0;iitems.nb_items;i++) { - eb_printf(b, "%s", hs->items.items[i]->str); - if (i != hs->items.nb_items - 1) - eb_printf(b, "\n"); - } - b->modified = 0; + do_dired_sort(s); } -static void get_dired_filename(EditState *s, - char *buf, int buf_size, int index) +static char *get_dired_filename(EditState *s, + char *buf, int buf_size, int index) { DiredState *hs = s->mode_data; - StringItem *item; + const StringItem *item; + const DiredItem *dip; + /* CG: assuming buf_size > 0 */ buf[0] = '\0'; if (index < 0 || index >= hs->items.nb_items) - return; + return NULL; + item = hs->items.items[index]; + dip = item->opaque; /* build filename */ - pstrcpy(buf, buf_size, hs->path); - pstrcat(buf, buf_size, "/"); - pstrcat(buf, buf_size, (const char *)item->opaque); + /* CG: Should canonize path */ + return makepath(buf, buf_size, hs->path, dip->name); } - /* select current item */ static void dired_select(EditState *s) { @@ -196,8 +336,10 @@ static void dired_select(EditState *s) char filename[1024]; EditState *e; - get_dired_filename(s, filename, sizeof(filename), - list_get_pos(s)); + if (!get_dired_filename(s, filename, sizeof(filename), + dired_get_index(s))) { + return; + } /* now we can act */ if (lstat(filename, &st) < 0) @@ -217,22 +359,22 @@ static void dired_select(EditState *s) } } -static void open_new_file(EditState *s) +static void dired_view_file(EditState *s, const char *filename) { EditBuffer *b; EditState *e, *e1; - char filename[1024]; e = find_window_right(s); if (!e) return; /* close previous temporary buffers, if any */ + /* CG: Should use the do_find_alternate to replace buffer */ b = e->b; if ((b->flags & BF_PREVIEW) && !b->modified) { switch_to_buffer(e, NULL); /* Before freeing buffer, make sure it isn't used by another window. * This could happen if we split the view window and continue browsing. */ - for(e1 = qe_state.first_window; e1 != NULL; e1 = e1->next_window) { + for (e1 = s->qe_state->first_window; e1 != NULL; e1 = e1->next_window) { if (e1 != s && e1->b == b) break; } @@ -240,8 +382,6 @@ static void open_new_file(EditState *s) eb_free(b); } - get_dired_filename(s, filename, sizeof(filename), - list_get_pos(s)); if (e) { do_load(e, filename); /* disable wrapping to get nicer display */ @@ -252,26 +392,70 @@ static void open_new_file(EditState *s) e->b = b; } /* mark buffer as preview, so that it will get recycled if needed */ + /* CG: this is wrong if buffer existed already */ b->flags |= BF_PREVIEW; } } +static void dired_execute(EditState *s) +{ + /* Actually delete, copy, or move the marked items */ + put_status(s, "Not yet implemented"); +} static void dired_parent(EditState *s) { DiredState *hs = s->mode_data; char filename[1024]; - pstrcpy(filename, sizeof(filename), hs->path); - pstrcat(filename, sizeof(filename), "/.."); + makepath(filename, sizeof(filename), hs->path, ".."); + /* CG: Should make current directory current item in parent */ build_dired_list(s, filename); } +static void dired_refresh(EditState *s) +{ + DiredState *hs = s->mode_data; + + /* CG: Should try and keep current entry */ + build_dired_list(s, hs->path); +} + +static void dired_display_hook(EditState *s) +{ + DiredState *ds = s->mode_data; + char filename[1024]; + int index; + + /* Prevent point from going beyond list */ + if (s->offset && s->offset == s->b->total_size) + do_up_down(s, -1); + + /* open file so that user can see it before it is selected */ + /* XXX: find a better solution (callback) */ + index = dired_get_index(s); + if (index < 0 || index >= ds->items.nb_items) + return; + /* Should not rely on last_index! */ + if (index != ds->last_index) { + ds->last_index = index; + if (get_dired_filename(s, filename, sizeof(filename), + dired_get_index(s))) { + dired_view_file(s, filename); + } + } +} + static int dired_mode_init(EditState *s, ModeSavedData *saved_data) { + DiredState *hs; + list_mode.mode_init(s, saved_data); + hs = s->mode_data; + hs->sort_mode = DIRED_SORT_GROUP | DIRED_SORT_NAME; + build_dired_list(s, s->b->filename); return 0; @@ -300,11 +484,22 @@ void do_dired(EditState *s) { DiredState *hs; QEmacsState *qs = s->qe_state; - EditBuffer *b; - EditState *e; - int width, i; + EditBuffer *b, *b0; + EditState *e, *e1; + int width, index, i; char filename[1024], *p; + /* Should take directory argument with optional switches, + * find dired window if exists, + * else create one and do this. + * recursive listing and multi directory patterns. + */ + + /* remember current buffer for target positioning, because + * s may be destroyed by insert_window_left + */ + b0 = s->b; + b = eb_new("*dired*", BF_READONLY | BF_SYSTEM); /* set the filename to the directory of the current file */ @@ -312,6 +507,7 @@ void do_dired(EditState *s) p = strrchr(filename, '/'); if (p) *p = '\0'; + canonize_absolute_path(filename, sizeof(filename), filename); set_filename(b, filename); width = qs->width / 4; @@ -319,14 +515,20 @@ void do_dired(EditState *s) do_set_mode(e, &dired_mode, NULL); hs = e->mode_data; - /* if active file is found, go directly on it */ - for(i=0;iitems.nb_items;i++) { - get_dired_filename(e, filename, sizeof(filename), i); - if (!strcmp(filename, s->b->filename)) { - e->offset = eb_goto_pos(e->b, i, 0); - break; - } + e1 = find_window_right(e); + if (e1) + b0 = e1->b; + + index = 0; + /* CG: target file should be an argument to this command */ + for (i = 0; i < hs->items.nb_items; i++) { + if (get_dired_filename(e, filename, sizeof(filename), i) + && !strcmp(filename, b0->filename)) { + index = i; + break; + } } + e->offset = eb_goto_pos(e->b, index + DIRED_HEADER, 0); /* modify active window */ qs->active_window = e; @@ -334,10 +536,32 @@ void do_dired(EditState *s) /* specific dired commands */ static CmdDef dired_commands[] = { - CMD0( ' ', KEY_CTRL('t'), "dired-toggle_selection", list_toggle_selection) CMD0( KEY_RET, KEY_RIGHT, "dired-select", dired_select) - CMD0( KEY_LEFT, KEY_NONE, "dired-parent", dired_parent) - CMD1( KEY_CTRL('g'), KEY_NONE, "delete-window", do_delete_window, 0) + CMD0( KEY_TAB, KEY_NONE, "dired-tab", do_other_window) + /* dired-abort should restore previous buffer in right-window */ + CMD1( KEY_CTRL('g'), KEY_NONE, "dired-abort", do_delete_window, 0) + CMD0( ' ', KEY_CTRL('t'), "dired-toggle_selection", list_toggle_selection) + /* BS should go back to previous item and unmark it */ + CMD ( 's', KEY_NONE, "dired-sort\0s{Sort order: }", dired_sort) + /* s -> should also change switches */ + CMD1( 'd', KEY_NONE, "dired-delete", dired_mark, 'D') + CMD1( 'c', KEY_NONE, "dired-copy", dired_mark, 'C') + CMD1( 'm', KEY_NONE, "dired-move", dired_mark, 'M') + CMD1( 'u', KEY_NONE, "dired-unmark", dired_mark, ' ') + CMD0( 'x', KEY_NONE, "dired-execute", dired_execute) + CMD1( 'n', KEY_NONE, "next-line", do_up_down, 1 ) + CMD1( 'p', KEY_NONE, "previous-line", do_up_down, -1 ) + CMD0( 'r', KEY_NONE, "dired-refresh", dired_refresh) + /* g -> refresh all expanded dirs ? */ + /* l -> relist single directory or marked files ? */ + CMD0( '^', KEY_LEFT, "dired-parent", dired_parent) + /* need commands for splitting, unsplitting, zooming, making subdirs */ + /* h -> info */ + /* i, + -> create subdirectory */ + /* o -> explore in other window */ + /* R -> rename a file or move selection to another directory */ + /* C -> copy files */ + /* mark files globally */ CMD_DEF_END, }; @@ -349,13 +573,14 @@ static CmdDef dired_global_commands[] = { static int dired_init(void) { /* inherit from list mode */ + /* CG: assuming list_mode already initialized ? */ memcpy(&dired_mode, &list_mode, sizeof(ModeDef)); dired_mode.name = "dired"; dired_mode.instance_size = sizeof(DiredState); - dired_mode.display = dired_display; - dired_mode.mode_probe = dired_mode_probe; + dired_mode.mode_probe = dired_mode_probe; dired_mode.mode_init = dired_mode_init; dired_mode.mode_close = dired_mode_close; + dired_mode.display_hook = dired_display_hook; /* first register mode */ qe_register_mode(&dired_mode);