qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs dired.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs dired.c
Date: Wed, 19 Aug 2015 16:49:04 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        15/08/19 16:49:04

Modified files:
        .              : dired.c 

Log message:
        dired: fixed bugs, simplified code
        - use mode structure as signature
        - pass DiredState to internal functions
        - no longer refuse to descend into symlink directories
        - improve navigation when focus goes to a dired buffer in preview mode
        - no longer make dired buffers system buffers to fix bufed behaviour
        - make dired-time-format a global variable

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/dired.c?cvsroot=qemacs&r1=1.55&r2=1.56

Patches:
Index: dired.c
===================================================================
RCS file: /sources/qemacs/qemacs/dired.c,v
retrieving revision 1.55
retrieving revision 1.56
diff -u -b -r1.55 -r1.56
--- dired.c     11 Aug 2015 17:45:30 -0000      1.55
+++ dired.c     19 Aug 2015 16:49:04 -0000      1.56
@@ -51,20 +51,22 @@
     TF_TOUCH_LONG,
     TF_FULL,
     TF_SECONDS,
+    TF_MAX = TF_SECONDS,
 };
 
-static time_t curtime;
-static enum time_format time_format;
+static ModeDef dired_mode;
 
-static int dired_signature;
+static time_t curtime;
 
+/* XXX: need a function to set these variables and trigger refresh */
+static enum time_format dired_time_format;
 static int dired_show_dot_files = 1;
 #ifdef CONFIG_DARWIN
 static int dired_show_ds_store = 0;
 #endif
 
 typedef struct DiredState {
-    void *signature;
+    ModeDef *signature;
     StringArray items;
     int sort_mode; /* DIRED_SORT_GROUP | DIRED_SORT_NAME */
     int last_index;
@@ -93,6 +95,19 @@
     char    name[1];
 } DiredItem;
 
+static DiredState *dired_get_state(EditState *s, int status)
+{
+    DiredState *ds = s->b->priv_data;
+
+    if (ds && ds->signature == &dired_mode)
+        return ds;
+
+    if (status)
+        put_status(s, "Not a dired buffer");
+
+    return NULL;
+}
+
 static inline int dired_get_index(EditState *s) {
     return list_get_pos(s) - DIRED_HEADER;
 }
@@ -112,35 +127,15 @@
     }
 }
 
-static DiredState *dired_get_state(EditState *s, int status)
-{
-    DiredState *ds = s->b->priv_data;
-
-    if (ds && ds->signature == &dired_signature)
-        return ds;
-
-    if (status)
-        put_status(s, "Not a dired buffer");
-
-    return NULL;
-}
-
-static char *dired_get_filename(EditState *s,
-                                char *buf, int buf_size, int index)
+static char *dired_get_filename(DiredState *ds, int index,
+                                char *buf, int buf_size)
 {
-    DiredState *ds;
     const StringItem *item;
     const DiredItem *dip;
 
-    if (!(ds = dired_get_state(s, 1)))
-        return NULL;
-
     if (buf_size > 0)
         buf[0] = '\0';
 
-    if (index < 0)
-        index = dired_get_index(s);
-
     if (index < 0 || index >= ds->items.nb_items)
         return NULL;
 
@@ -152,18 +147,14 @@
     return makepath(buf, buf_size, ds->path, dip->name);
 }
 
-static int dired_find_target(EditState *s, const char *target)
+static int dired_find_target(DiredState *ds, const char *target)
 {
-    DiredState *ds;
     char filename[MAX_FILENAME_SIZE];
     int i;
 
     if (target) {
-        if (!(ds = dired_get_state(s, 1)))
-            return -1;
-
         for (i = 0; i < ds->items.nb_items; i++) {
-            if (dired_get_filename(s, filename, sizeof(filename), i)
+            if (dired_get_filename(ds, i, filename, sizeof(filename))
             &&  strequal(filename, target)) {
                 return i;
             }
@@ -482,23 +473,24 @@
     return atts;
 }
 
-/* select current item */
-static void dired_sort_list(EditState *s)
+/* `ds` and `b` are valid, `s` may be NULL */
+static void dired_sort_list(DiredState *ds, EditBuffer *b, EditState *s)
 {
     char buf[MAX_FILENAME_SIZE];
-    DiredState *ds;
     StringItem *item, *cur_item;
     DiredItem *dip;
-    EditBuffer *b;
     int index, i, col, width, top_line;
 
-    if (!(ds = dired_get_state(s, 1)))
-        return;
-
     /* Try and preserve scroll position */
+    if (s) {
     eb_get_pos(s->b, &top_line, &col, s->offset_top);
-
     index = dired_get_index(s);
+        width = s->width;
+    } else {
+        index = col = top_line = 0;
+        width = 80;
+    }
+
     cur_item = NULL;
     if (index >= 0 && index < ds->items.nb_items)
         cur_item = ds->items.items[index];
@@ -507,7 +499,6 @@
           sizeof(StringItem *), dired_sort_func);
 
     /* construct list buffer */
-    b = s->b;
     /* deleting buffer contents resets s->offset and s->offset_top */
     eb_clear(b);
 
@@ -519,8 +510,9 @@
                   (long long)ds->total_bytes, &"s"[ds->total_bytes == 1]);
     }
 
-    ds->last_width = s->width;
-    width = s->width - clamp(ds->namelen, 16, 40);
+    /* XXX: should use screen specific space_width, separator_width or 
em_width */
+    ds->last_width = width;
+    width -= clamp(ds->namelen, 16, 40);
     ds->no_size = ((width -= ds->sizelen + 2) < 0);
     ds->no_date = ((width -= ds->datelen + 2) < 0);
     ds->no_mode = ((width -= ds->modelen + 1) < 0);
@@ -537,6 +529,7 @@
         if (item == cur_item) {
             if (ds->last_index == index)
                 ds->last_index = i;
+            if (s)
             s->offset = b->total_size;
         }
         col = eb_printf(b, "%c ", dip->mark);
@@ -565,7 +558,7 @@
             col += eb_printf(b, " %*s  ", ds->sizelen, buf);
         }
         if (!ds->no_date) {
-            format_date(buf, sizeof(buf), dip->mtime, time_format);
+            format_date(buf, sizeof(buf), dip->mtime, dired_time_format);
             col += eb_printf(b, "%s  ", buf);
         }
         ds->fnamecol = col - 1;
@@ -586,9 +579,13 @@
     }
     b->modified = 0;
     b->flags |= BF_READONLY;
-    s->offset_top = eb_goto_pos(s->b, top_line, 0);
+    if (s) {
+        s->offset_top = eb_goto_pos(b, top_line, 0);
+    }
 }
 
+/* dired-mode commands */
+
 static void dired_up_down(EditState *s, int dir)
 {
     DiredState *ds;
@@ -685,7 +682,7 @@
             break;
         }
     }
-    dired_sort_list(s);
+    dired_sort_list(ds, s->b, s);
 }
 
 static void dired_set_time_format(EditState *s, int format)
@@ -697,24 +694,27 @@
     if (!(ds = dired_get_state(s, 1)))
         return;
 
-    time_format = format;
+    if (format < 0 || format > TF_MAX)
+        return;
+
+    dired_time_format = format;
 
     ds->datelen = 0;
     for (i = 0; i < ds->items.nb_items; i++) {
         const StringItem *item = ds->items.items[i];
         const DiredItem *dip = item->opaque;
 
-        len = format_date(buf, sizeof(buf), dip->mtime, time_format);
+        len = format_date(buf, sizeof(buf), dip->mtime, format);
         if (ds->datelen < len)
             ds->datelen = len;
     }
-    dired_sort_list(s);
+    dired_sort_list(ds, s->b, s);
 }
 
-static void dired_build_list(EditState *s, const char *path,
-                             const char *target)
+/* `ds` and `b` are valid, `s` and `target` may be NULL */
+static void dired_build_list(DiredState *ds, const char *path,
+                             const char *target, EditBuffer *b, EditState *s)
 {
-    DiredState *ds;
     FindFileState *ffst;
     char filename[MAX_FILENAME_SIZE];
     char line[1024], buf[1024];
@@ -723,9 +723,6 @@
     int len, index;
     StringItem *item;
 
-    if (!(ds = dired_get_state(s, 1)))
-        return;
-
     /* free previous list, if any */
     dired_free(ds);
 
@@ -740,10 +737,10 @@
 
     /* CG: should make absolute ? */
     canonicalize_path(ds->path, sizeof(ds->path), path);
-    eb_set_filename(s->b, ds->path);
-    s->b->flags |= BF_DIRED;
+    eb_set_filename(b, ds->path);
+    b->flags |= BF_DIRED;
 
-    eb_clear(s->b);
+    eb_clear(b);
 
     ffst = find_file_open(ds->path, "*");
     /* Should scan directory/filespec before computing lines to adjust
@@ -818,35 +815,44 @@
             if (ds->sizelen < len)
                 ds->sizelen = len;
 
-            len = format_date(buf, sizeof(buf), dip->mtime, time_format);
+            len = format_date(buf, sizeof(buf), dip->mtime, dired_time_format);
             if (ds->datelen < len)
                 ds->datelen = len;
         }
     }
     find_file_close(&ffst);
     
-    dired_sort_list(s);
-
-    index = dired_find_target(s, target);
-    s->offset = eb_goto_pos(s->b, max(index, 0) + DIRED_HEADER, ds->fnamecol);
+    dired_sort_list(ds, b, s);
+    if (s) {
+        index = dired_find_target(ds, target);
+        s->offset = eb_goto_pos(b, max(index, 0) + DIRED_HEADER, ds->fnamecol);
+    }
 }
 
 /* select current item */
 static void dired_select(EditState *s)
 {
+    DiredState *ds;
     struct stat st;
     char filename[MAX_FILENAME_SIZE];
     EditState *e;
 
-    if (!dired_get_filename(s, filename, sizeof(filename), -1))
+    if (!(ds = dired_get_state(s, 1)))
         return;
 
-    /* now we can act */
-    if (lstat(filename, &st) >= 0 && S_ISDIR(st.st_mode)) {
-        /* do not descend into directories pointed to by symlinks */
-        dired_build_list(s, filename, NULL);
+    if (!dired_get_filename(ds, dired_get_index(s), filename, 
sizeof(filename)))
+        return;
+
+    /* Check if path leads somewhere */
+    if (stat(filename, &st) < 0)
+        return;
+
+    if (S_ISDIR(st.st_mode)) {
+        /* DO descend into directories pointed to by symlinks */
+        /* XXX: should expand directory below current position */
+        dired_build_list(ds, filename, NULL, s->b, s);
     } else
-    if (stat(filename, &st) >= 0 && S_ISREG(st.st_mode)) {
+    if (S_ISREG(st.st_mode)) {
         /* do explore files pointed to by symlinks */
         e = find_window(s, KEY_RIGHT);
         if (e) {
@@ -872,28 +878,33 @@
     e = find_window(s, KEY_RIGHT);
     if (!e)
         return;
+
     /* close previous temporary buffers, if any */
-    /* CG: Should use the do_find_alternate to replace buffer */
     b = e->b;
     if (b && (b->flags & BF_PREVIEW) && !b->modified) {
-        /* free the buffer if no longer viewed */
+        /* will free the buffer if no longer viewed */
         b->flags |= BF_TRANSIENT;
-        //switch_to_buffer(e, NULL);
     }
 
-    if (e) {
-        /* If buffer is not present already, mark it as preview, so
-         * that it will get recycled if needed */
+    /* Load file and attach to window. If file not loaded already, mark
+     * new buffer as BF_PREVIEW, to trigger paging mode and so that it
+     * will get freed if closed.
+     */
+#if 1
+    /* XXX: need a way to verify that file was correctly loaded */
         do_find_file(e, filename, BF_PREVIEW);
+#else
+    rc = qe_load_file(e, filename, 0, 0, BF_PREVIEW);
+    if (rc >= 0) {
         /* disable wrapping to get nicer display */
         /* XXX: should wrap lines unless window is narrow */
         //e->wrap = WRAP_TRUNCATE;
-        b = e->b;
-        if (!b) {
-            b = eb_new("*scratch*", BF_SAVELOG | BF_UTF8);
-            e->b = b;
         }
+    if (rc < 0) {
+        /* if file failed to load, show a scratch buffer */
+        switch_to_buffer(e, eb_new("*scratch*", BF_SAVELOG | BF_UTF8 | 
BF_PREVIEW));
     }
+#endif
 }
 
 static void dired_execute(EditState *s)
@@ -908,13 +919,21 @@
     char target[MAX_FILENAME_SIZE];
     char filename[MAX_FILENAME_SIZE];
 
+    if (s->b->flags & BF_PREVIEW) {
+        EditState *e = find_window(s, KEY_LEFT);
+        if (e && (e->b->flags & BF_DIRED)) {
+            s->qe_state->active_window = e;
+            return;
+        }        
+    }
+
     if (!(ds = dired_get_state(s, 1)))
         return;
 
     pstrcpy(target, sizeof(target), ds->path);
     makepath(filename, sizeof(filename), ds->path, "..");
 
-    dired_build_list(s, filename, target);
+    dired_build_list(ds, filename, target, s->b, s);
 }
 
 static void dired_refresh(EditState *s)
@@ -926,15 +945,16 @@
     if (!(ds = dired_get_state(s, 1)))
         return;
 
-    dired_get_filename(s, target, sizeof(target), -1);
+    dired_get_filename(ds, dired_get_index(s), target, sizeof(target));
     pstrcpy(dirname, sizeof(dirname), ds->path);
-    dired_build_list(s, dirname, target);
+    dired_build_list(ds, dirname, target, s->b, s);
 }
 
 static void dired_toggle_dot_files(EditState *s, int val)
 {
     if (val == -1)
         val = !dired_show_dot_files;
+
     if (dired_show_dot_files != val) {
         dired_show_dot_files = val;
         dired_refresh(s);
@@ -961,7 +981,7 @@
             /* XXX: this may cause problems if buffer is displayed in
              * multiple windows, hence the test on s->y1.
              * Should test for current window */
-            dired_sort_list(s);
+            dired_sort_list(ds, s->b, s);
         }
         /* open file so that user can see it before it is selected */
         /* XXX: find a better solution (callback) */
@@ -971,7 +991,7 @@
         /* Should not rely on last_index! */
         if (index != ds->last_index) {
             ds->last_index = index;
-            if (dired_get_filename(s, filename, sizeof(filename), index)) {
+            if (dired_get_filename(ds, index, filename, sizeof(filename))) {
                 dired_view_file(s, filename);
             }
         }
@@ -982,7 +1002,7 @@
 {
     DiredState *ds = b->priv_data;
 
-    if (ds && ds->signature == &dired_signature) {
+    if (ds && ds->signature == &dired_mode) {
         dired_free(ds);
     }
 
@@ -1000,7 +1020,7 @@
     if (s) {
         if (s->b->priv_data) {
             ds = s->b->priv_data;
-            if (ds->signature != &dired_signature)
+            if (ds->signature != &dired_mode)
                 return -1;
         } else {
             /* XXX: should be allocated by buffer_load API */
@@ -1008,7 +1028,8 @@
             if (!ds)
                 return -1;
 
-            ds->signature = &dired_signature;
+            ds->signature = &dired_mode;
+            /* XXX: Should use last sort mode, a global variable */
             ds->sort_mode = DIRED_SORT_GROUP | DIRED_SORT_NAME;
             ds->last_index = -1;
 
@@ -1016,14 +1037,12 @@
             s->b->close = dired_close;
 
             /* XXX: should be built by buffer_load API */
-            dired_build_list(s, s->b->filename, NULL);
-        }
-
+            dired_build_list(ds, s->b->filename, NULL, s->b, s);
         /* XXX: File system charset should be detected automatically */
         /* XXX: If file system charset is not utf8, eb_printf will fail */
         eb_set_charset(s->b, &charset_utf8, s->b->eol_type);
     }
-
+    }
     return 0;
 }
 
@@ -1032,7 +1051,7 @@
 {
     if (p->b->priv_data) {
         DiredState *ds = p->b->priv_data;
-        if (ds->signature != &dired_signature)
+        if (ds->signature != &dired_mode)
             return 0;
         else
             return 100;
@@ -1076,8 +1095,6 @@
     }
 }
 
-static ModeDef dired_mode;
-
 /* open dired window on the left. The directory of the current file is
    used */
 void do_dired(EditState *s)
@@ -1097,7 +1114,7 @@
      */
 
     /* Should reuse previous dired buffer for same filespec */
-    b = eb_scratch("*dired*", BF_READONLY | BF_SYSTEM | BF_UTF8);
+    b = eb_scratch("*dired*", BF_READONLY | BF_UTF8);
 
     /* Remember target as current current buffer filename */
     pstrcpy(target, sizeof(target), s->b->filename);
@@ -1113,11 +1130,12 @@
 
     width = qs->width / 5;
     e = insert_window_left(b, width, WF_MODELINE);
+    /* set dired mode: dired_mode_init() will load buffer content */
     edit_set_mode(e, &dired_mode);
 
     ds = dired_get_state(e, 0);
     if (ds) {
-        index = dired_find_target(e, target);
+        index = dired_find_target(ds, target);
         e->offset = eb_goto_pos(e->b, max(index, 0) + DIRED_HEADER,
                                 ds->fnamecol);
     }
@@ -1185,9 +1203,10 @@
 };
 
 static VarDef dired_variables[] = {
-    G_VAR( "dired-show-dot-files", dired_show_dot_files, VAR_NUMBER, VAR_RW )
+    G_VAR( "dired-time-format", dired_time_format, VAR_NUMBER, VAR_RW_SAVE )
+    G_VAR( "dired-show-dot-files", dired_show_dot_files, VAR_NUMBER, 
VAR_RW_SAVE )
 #ifdef CONFIG_DARWIN
-    G_VAR( "dired-show-ds-store", dired_show_ds_store, VAR_NUMBER, VAR_RW )
+    G_VAR( "dired-show-ds-store", dired_show_ds_store, VAR_NUMBER, VAR_RW_SAVE 
)
 #endif
 };
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]