qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs bufed.c buffer.c dired.c qe.c qe.h shell.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs bufed.c buffer.c dired.c qe.c qe.h shell.c
Date: Wed, 19 Aug 2015 19:20:58 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        15/08/19 19:20:58

Modified files:
        .              : bufed.c buffer.c dired.c qe.c qe.h shell.c 

Log message:
        window handling, bufed/dired: fixed bugs, simplified code
        - make show_popup(b) return the window
        - pass an extra window argument to find_window() as a default return 
value
        - add check_buffer(EditBuffer **sp) to validate a buffer pointer
        - changed eb_find_window(): find a different window attached to a given 
buffer
        - removed edit_find(), use eb_find_window() instead
        - change edit_attach(): 
          take window before which to move arg window, use NULL to append at 
the end.
          If qs->active_window is NULL, set it to the first window
        - add buffer flags BF_IS_LOG and BF_IS_STYLE
        - create style buffers with a meaningful name
        - create log buffers with a meaningful name
        - add window flag WF_POPLEFT for dired interactive buffers
        - no longer create process buffer and find files in dired pop left pane
        - remember last buffer upon switch_to_buffer for 
predict_switch_to_buffer()
        - rename do_file1() as extern qe_load_file() and make it return success 
status
        - prevent do_find_file_other_window() from splitting window if too 
shallow
        - fix window fusion algorithm when deleting left pane with split right 
pane
        - prevent delete-other-windows() from minibuf and poups
        - use mode structure as signature for bufed-mode, shell-mode
        - make list-buffers open an interactive popup window
        - toggle full buffer list with '.'

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/bufed.c?cvsroot=qemacs&r1=1.35&r2=1.36
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.86&r2=1.87
http://cvs.savannah.gnu.org/viewcvs/qemacs/dired.c?cvsroot=qemacs&r1=1.56&r2=1.57
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.202&r2=1.203
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.200&r2=1.201
http://cvs.savannah.gnu.org/viewcvs/qemacs/shell.c?cvsroot=qemacs&r1=1.96&r2=1.97

Patches:
Index: bufed.c
===================================================================
RCS file: /sources/qemacs/qemacs/bufed.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -b -r1.35 -r1.36
--- bufed.c     11 Aug 2015 17:45:30 -0000      1.35
+++ bufed.c     19 Aug 2015 19:20:57 -0000      1.36
@@ -22,16 +22,17 @@
 #include "qe.h"
 
 enum {
-    BUFED_ALL_VISIBLE = 1
+    BUFED_HIDE_SYSTEM = 0,
+    BUFED_ALL_VISIBLE = 1,
 };
 
-static int bufed_signature;
-
 typedef struct BufedState {
-    void *signature;
-    StringArray items;
+    ModeDef *signature;
     int flags;
-    int last_index;
+    EditState *cur_window;
+    EditBuffer *cur_buffer;
+    EditBuffer *last_buffer;
+    StringArray items;
 } BufedState;
 
 static ModeDef bufed_mode;
@@ -40,7 +41,7 @@
 {
     BufedState *bs = s->b->priv_data;
 
-    if (bs && bs->signature == &bufed_signature)
+    if (bs && bs->signature == &bufed_mode)
         return bs;
 
     if (status)
@@ -90,6 +91,12 @@
             char path[MAX_FILENAME_SIZE];
             const char *mode_name;
 
+            if (b1->flags & BF_IS_LOG) {
+                mode_name = "log";
+            } else
+            if (b1->flags & BF_IS_STYLE) {
+                mode_name = "style";
+            } else
             if (b1->saved_mode) {
                 mode_name = b1->saved_mode->name;
             } else
@@ -102,8 +109,8 @@
                 mode_name = "none";
             }
 
-            eb_printf(b, " %10d %c %-8s %-8s %s",
-                      b1->total_size, " 1234567"[b1->style_bytes & 7],
+            eb_printf(b, " %10d %1.0d %-8s %-8s %s",
+                      b1->total_size, b1->style_bytes & 7,
                       b1->charset->name, mode_name,
                       make_user_path(path, sizeof(path), b1->filename));
         }
@@ -131,39 +138,36 @@
 static void bufed_select(EditState *s, int temp)
 {
     BufedState *bs;
-    StringItem *item;
-    EditBuffer *b;
+    EditBuffer *b, *last_buffer;
     EditState *e;
     int index;
 
     if (!(bs = bufed_get_state(s, 1)))
         return;
 
+    if (temp < 0) {
+        b = check_buffer(&bs->cur_buffer);
+        last_buffer = check_buffer(&bs->last_buffer);
+    } else {
     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(s, KEY_RIGHT);
-    if (temp) {
-        if (e) {
-            bs->last_index = index;
-            switch_to_buffer(e, b);
+        b = eb_find(bs->items.items[index]->str);
+        last_buffer = bs->cur_buffer;
         }
-        return;
+    e = check_window(&bs->cur_window);
+    if (e && b) {
+        switch_to_buffer(e, b);
+        e->last_buffer = last_buffer;
     }
-    if (e) {
+    if (temp <= 0) {
         /* delete bufed window */
         do_delete_window(s, 1);
-        switch_to_buffer(e, b);
+        if (e)
+            e->qe_state->active_window = e;
     } else {
-        switch_to_buffer(s, b);
+        do_refresh_complete(s);
     }
 }
 
@@ -218,31 +222,38 @@
 /* show a list of buffers */
 static void do_list_buffers(EditState *s, int argval)
 {
-    QEmacsState *qs = s->qe_state;
     BufedState *bs;
-    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
-     */
-    b = b0 = s->b;
-
-    if ((bs = bufed_get_state(s, 0)) == NULL) {
-        /* XXX: must close this buffer when destroying window: add a
-        special buffer flag to tell this */
-        b = eb_scratch("*bufed*", BF_READONLY | BF_SYSTEM | BF_UTF8);
+    EditBuffer *b;
+    EditState *e;
+    int i;
+
+    /* ignore command from the minibuffer and popups */
+    if (s->minibuf || (s->flags & WF_POPUP))
+        return;
+
+    if (s->flags & WF_POPLEFT) {
+        /* avoid messing with the dired pane */
+        s = find_window(s, KEY_RIGHT, s);
+        s->qe_state->active_window = s;
     }
 
-    width = qs->width / 5;
-    e = insert_window_left(b, width, WF_MODELINE);
+    b = eb_scratch("*bufed*", BF_READONLY | BF_SYSTEM | BF_UTF8);
+    if (!b)
+        return;
+
+    e = show_popup(b);
+    if (!e)
+        return;
+
     edit_set_mode(e, &bufed_mode);
 
     if (!(bs = bufed_get_state(e, 1)))
         return;
 
+    bs->cur_window = s;
+    bs->cur_buffer = s->b;
+    bs->last_buffer = s->last_buffer;
+
     if (argval == NO_ARG) {
         bs->flags &= ~BUFED_ALL_VISIBLE;
     } else {
@@ -250,20 +261,13 @@
     }
     build_bufed_list(e);
 
-    e1 = find_window(e, KEY_RIGHT);
-    if (e1)
-        b0 = e1->b;
-
     /* if active buffer is found, go directly on it */
     for (i = 0; i < bs->items.nb_items; i++) {
-        if (strequal(bs->items.items[i]->str, b0->name)) {
+        if (strequal(bs->items.items[i]->str, s->b->name)) {
             e->offset = eb_goto_pos(e->b, i, 0);
             break;
         }
     }
-
-    /* modify active window */
-    qs->active_window = e;
 }
 
 static void bufed_clear_modified(EditState *s)
@@ -309,6 +313,7 @@
     if (s->offset && s->offset == s->b->total_size)
         do_up_down(s, -1);
 
+    if (s->flags & WF_POPUP)
     bufed_select(s, 1);
 }
 
@@ -316,7 +321,7 @@
 {
     if (p->b->priv_data) {
         BufedState *bs = p->b->priv_data;
-        if (bs->signature == &bufed_signature)
+        if (bs->signature == &bufed_mode)
             return 95;
         else
             return 0;
@@ -328,7 +333,7 @@
 {
     BufedState *bs = b->priv_data;
 
-    if (bs && bs->signature == &bufed_signature) {
+    if (bs && bs->signature == &bufed_mode) {
         free_strings(&bs->items);
     }
 
@@ -346,7 +351,7 @@
     if (s) {
         if (s->b->priv_data) {
             bs = s->b->priv_data;
-            if (bs->signature != &bufed_signature)
+            if (bs->signature != &bufed_mode)
                 return -1;
         } else {
             /* XXX: should be allocated by buffer_load API */
@@ -354,8 +359,7 @@
             if (!bs)
                 return -1;
 
-            bs->signature = &bufed_signature;
-            bs->last_index = -1;
+            bs->signature = &bufed_mode;
             s->b->priv_data = bs;
             s->b->close = bufed_close;
         }
@@ -365,11 +369,11 @@
 
 /* specific bufed commands */
 static CmdDef bufed_commands[] = {
-    CMD1( KEY_RET, KEY_RIGHT,
+    CMD1( KEY_RET, KEY_NONE,
           "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)
+    CMD1( KEY_CTRL('g'), KEY_CTRLX(KEY_CTRL('g')),
+          "bufed-abort", bufed_select, -1)
     CMD1( ' ', KEY_CTRL('t'),
           "bufed-toggle-selection", list_toggle_selection, 1)
     CMD1( KEY_DEL, KEY_NONE,
@@ -379,7 +383,7 @@
           "bufed-clear-modified", bufed_clear_modified)
     CMD0( '%', KEY_NONE,
           "bufed-toggle-read-only", bufed_toggle_read_only)
-    CMD1( 'a', KEY_NONE,
+    CMD1( 'a', '.',
           "bufed-toggle-all-visible", bufed_refresh, 1)
     CMD1( 'n', KEY_CTRL('n'), /* KEY_DOWN */
           "bufed-next-line", do_up_down, 1)
@@ -406,7 +410,6 @@
     bufed_mode.name = "bufed";
     bufed_mode.mode_probe = bufed_mode_probe;
     bufed_mode.mode_init = bufed_mode_init;
-    /* CG: not a good idea, display hook has side effect on layout */
     bufed_mode.display_hook = bufed_display_hook;
 
     /* first register mode */

Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -b -r1.86 -r1.87
--- buffer.c    16 Aug 2015 23:15:01 -0000      1.86
+++ buffer.c    19 Aug 2015 19:20:57 -0000      1.87
@@ -395,6 +395,21 @@
     return size;
 }
 
+/* Verify that window still exists, return argument or NULL,
+ * update handle if window is invalid.
+ */
+EditBuffer *check_buffer(EditBuffer **sp)
+{
+    QEmacsState *qs = &qe_state;
+    EditBuffer *b;
+
+    for (b = qs->first_buffer; b != NULL; b = b->next) {
+        if (b == *sp)
+            return b;
+    }
+    return *sp = NULL;
+}
+
 /* We must have : 0 <= offset <= b->total_size,
  * return actual number of bytes removed.
  */
@@ -663,19 +678,17 @@
     return NULL;
 }
 
-/* Find the next window showing a given buffer */
-EditState *eb_find_window(EditBuffer *b, EditState *e)
+/* Find a window attached to a given buffer, different from s */
+EditState *eb_find_window(EditBuffer *b, EditState *s)
 {
     QEmacsState *qs = &qe_state;
+    EditState *e;
 
-    for (e = e ? e->next_window : qs->first_window;
-         e != NULL;
-         e = e->next_window)
-    {
-            if (e->b == b)
-                return e;
+    for (e = qs->first_window; e != NULL; e = e->next_window) {
+        if (e != s && e->b == b)
+            break;
     }
-    return NULL;
+    return e;
 }
 
 void eb_trace_bytes(const void *buf, int size, int state)
@@ -800,7 +813,9 @@
     if (b->b_styles) {
         return 0;
     } else {
-        b->b_styles = eb_new("*", BF_SYSTEM | BF_RAW);
+        char name[MAX_BUFFERNAME_SIZE];
+        snprintf(name, sizeof(name), "*S<%s>", b->name);
+        b->b_styles = eb_new(name, BF_SYSTEM | BF_IS_STYLE | BF_RAW);
         b->flags |= flags & BF_STYLES;
         b->style_shift = ((flags & BF_STYLES) / BF_STYLE1) - 1;
         b->style_bytes = 1 << b->style_shift;
@@ -904,8 +919,8 @@
          * should not be a problem since this log buffer is never
          * referenced by name.
          */
-        snprintf(buf, sizeof(buf), "*log <%s>*", b->name);
-        b->log_buffer = eb_new(buf, BF_SYSTEM | BF_RAW);
+        snprintf(buf, sizeof(buf), "*L<%s>", b->name);
+        b->log_buffer = eb_new(buf, BF_SYSTEM | BF_IS_LOG | BF_RAW);
         if (!b->log_buffer)
             return;
     }

Index: dired.c
===================================================================
RCS file: /sources/qemacs/qemacs/dired.c,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -b -r1.56 -r1.57
--- dired.c     19 Aug 2015 16:49:04 -0000      1.56
+++ dired.c     19 Aug 2015 19:20:57 -0000      1.57
@@ -854,7 +854,7 @@
     } else
     if (S_ISREG(st.st_mode)) {
         /* do explore files pointed to by symlinks */
-        e = find_window(s, KEY_RIGHT);
+        e = find_window(s, KEY_RIGHT, NULL);
         if (e) {
 #if 1
             s->qe_state->active_window = e;
@@ -874,8 +874,9 @@
 {
     EditBuffer *b;
     EditState *e;
+    int rc;
 
-    e = find_window(s, KEY_RIGHT);
+    e = find_window(s, KEY_RIGHT, NULL);
     if (!e)
         return;
 
@@ -890,10 +891,6 @@
      * 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 */
@@ -904,7 +901,6 @@
         /* 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)
@@ -920,7 +916,7 @@
     char filename[MAX_FILENAME_SIZE];
 
     if (s->b->flags & BF_PREVIEW) {
-        EditState *e = find_window(s, KEY_LEFT);
+        EditState *e = find_window(s, KEY_LEFT, NULL);
         if (e && (e->b->flags & BF_DIRED)) {
             s->qe_state->active_window = e;
             return;

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.202
retrieving revision 1.203
diff -u -b -r1.202 -r1.203
--- qe.c        17 Aug 2015 16:56:49 -0000      1.202
+++ qe.c        19 Aug 2015 19:20:57 -0000      1.203
@@ -958,7 +958,7 @@
 {
 #ifndef CONFIG_TINY
     if (s->b->flags & BF_PREVIEW) {
-        EditState *e = find_window(s, KEY_LEFT);
+        EditState *e = find_window(s, KEY_LEFT, NULL);
         if (e && (e->b->flags & BF_DIRED)
         &&  dir < 0 && eb_at_bol(s->b, s->offset)) {
             s->qe_state->active_window = e;
@@ -4900,7 +4900,6 @@
 
 void switch_to_buffer(EditState *s, EditBuffer *b)
 {
-    QEmacsState *qs = s->qe_state;
     EditBuffer *b1;
     EditState *e;
     ModeSavedData *saved_data;
@@ -4916,10 +4915,7 @@
     b1 = s->b;
     if (b1) {
         /* save mode data if no other window uses the buffer */
-        for (e = qs->first_window; e != NULL; e = e->next_window) {
-            if (e != s && e->b == b1)
-                break;
-        }
+        e = eb_find_window(b1, s);
         if (e) {
             /* no need to save mode data */
             /* CG: bogus! e and s might have different modes */
@@ -4940,6 +4936,9 @@
         edit_set_mode(s, NULL);
         if (b1->flags & BF_TRANSIENT) {
             eb_free(&b1);
+        } else {
+            /* save buffer for predict_switch_to_buffer */
+            s->last_buffer = s->b;
         }
     }
 
@@ -4947,12 +4946,8 @@
     s->b = b;
 
     if (b) {
-        /* try to restore saved data from another window or from the
-           buffer saved data */
-        for (e = qs->first_window; e != NULL; e = e->next_window) {
-            if (e != s && e->b == b)
-                break;
-        }
+        /* Try to get window mode and data from another window */
+        e = eb_find_window(b, s);
         if (e) {
             mode = e->mode;
             saved_data = generic_mode_save_data(e);
@@ -5016,6 +5011,7 @@
     s = qe_mallocz(EditState);
     if (!s)
         return NULL;
+
     s->qe_state = qs;
     s->screen = qs->screen;
     s->x1 = x1;
@@ -5024,30 +5020,15 @@
     s->y2 = y1 + height;
     s->flags = flags;
     compute_client_area(s);
+
     /* link window in window list */
-    s->next_window = qs->first_window;
-    /* CG: should append window to end of list, esp. for popups */
-    qs->first_window = s;
-    if (!qs->active_window)
-        qs->active_window = s;
+    edit_attach(s, qs->first_window);
+
     /* restore saved window settings, set mode */
     switch_to_buffer(s, b);
     return s;
 }
 
-/* find a window with a given buffer if any. */
-EditState *edit_find(EditBuffer *b)
-{
-    QEmacsState *qs = &qe_state;
-    EditState *e;
-
-    for (e = qs->first_window; e != NULL; e = e->next_window) {
-        if (e->b == b)
-            break;
-    }
-    return e;
-}
-
 /* detach the window from the window tree. */
 void edit_detach(EditState *s)
 {
@@ -5065,11 +5046,24 @@
         qs->active_window = qs->first_window;
 }
 
-/* attach the window to the window list. */
-void edit_attach(EditState *s, EditState **ep)
+/* move a window before another one */
+void edit_attach(EditState *s, EditState *e)
 {
-    s->next_window = *ep;
+    QEmacsState *qs = s->qe_state;
+    EditState *active_window = qs->active_window;
+    EditState **ep;
+
+    if (s != e) {
+        edit_detach(s);
+
+        for (ep = &qs->first_window; *ep; ep = &(*ep)->next_window) {
+            if (*ep == e)
+                break;
+        }
+        s->next_window = e;
     *ep = s;
+        qs->active_window = active_window ? active_window : s;
+    }
 }
 
 /* close the edit window. If it is active, find another active
@@ -5079,26 +5073,10 @@
 {
     if (*sp) {
         EditState *s = *sp;
-        QEmacsState *qs = s->qe_state;
-        EditState **ps;
 
         /* save current state for later window reattachment */
         switch_to_buffer(s, NULL);
-
-        /* detach from window list */
-        ps = &qs->first_window;
-        while (*ps != NULL) {
-            if (*ps == s) {
-                *ps = s->next_window;
-                break;
-            }
-            ps = &(*ps)->next_window;
-        }
-
-        /* if active window, select another active window */
-        if (qs->active_window == s)
-            qs->active_window = qs->first_window;
-
+        edit_detach(s);
         qe_free(&s->mode_data);
         qe_free(&s->prompt);
         qe_free(&s->line_shadow);
@@ -5671,15 +5649,15 @@
 }
 
 /* show a popup on a readonly buffer */
-void show_popup(EditBuffer *b)
+EditState *show_popup(EditBuffer *b)
 {
-    EditState *s;
     QEmacsState *qs = &qe_state;
+    EditState *s = qs->active_window;
     int w, h, w1, h1;
 
     /* Prevent recursion */
-    if (qs->active_window && qs->active_window->b == b)
-        return;
+    if (s && s->b == b)
+        return s;
 
     /* XXX: generic function to open popup ? */
     w1 = qs->screen->width;
@@ -5694,6 +5672,7 @@
     popup_saved_active = qs->active_window;
     qs->active_window = s;
     do_refresh(s);
+    return s;
 }
 
 static void less_init(void)
@@ -5728,13 +5707,13 @@
     }
 
     e_new = edit_new(b, 0, 0, width, qs->height - qs->status_height,
-                     flags | WF_RSEPARATOR);
-    do_refresh(qs->first_window);
+                     flags | WF_POPLEFT | WF_RSEPARATOR);
+    do_refresh(e_new);
     return e_new;
 }
 
 /* return a window on the side of window 's' */
-EditState *find_window(EditState *s, int key)
+EditState *find_window(EditState *s, int key, EditState *def)
 {
     QEmacsState *qs = s->qe_state;
     EditState *e;
@@ -5760,41 +5739,35 @@
                 return e;
         }
     }
-    return NULL;
+    return def;
 }
 
 void do_find_window(EditState *s, int key)
 {
-    QEmacsState *qs = s->qe_state;
-    EditState *e;
-
-    e = find_window(s, key);
-    if (e)
-        qs->active_window = e;
+    s->qe_state->active_window = find_window(s, key, s);
 }
 #endif
 
-/* give a good guess to the user for the next buffer */
+/* Give a good guess to the user for the next buffer */
 static EditBuffer *predict_switch_to_buffer(EditState *s)
 {
     QEmacsState *qs = s->qe_state;
-    EditState *e;
     EditBuffer *b;
 
+    /* try and switch to the last buffer attached to the window */
+    b = check_buffer(&s->last_buffer);
+    if (b)
+        return b;
+
+    /* else try and switch to a buffer not shown in any window */
     for (b = qs->first_buffer; b != NULL; b = b->next) {
         if (!(b->flags & BF_SYSTEM)) {
-            for (e = qs->first_window; e != NULL; e = e->next_window) {
-                if (e->b == b)
-                    break;
-            }
-            if (!e)
-                goto found;
+            if (!eb_find_window(b, NULL))
+                return b;
         }
     }
-    /* select current buffer if none found */
-    b = s->b;
- found:
-    return b;
+    /* otherwise select current buffer. */
+    return s->b;
 }
 
 void do_switch_to_buffer(EditState *s, const char *bufname)
@@ -5857,7 +5830,10 @@
     EditState *e;
     EditBuffer *b1;
 
-    // FIXME: used to delete windows containing the buffer ???
+    /* Emacs makes any window showing the killed buffer switch to
+     * another buffer.
+     * An alternative is to delete windows showing the buffer.
+     */
 
     /* find a new buffer to switch to */
     for (b1 = qs->first_buffer; b1 != NULL; b1 = b1->next) {
@@ -6045,15 +6021,20 @@
                modes[found]->name, scores[found]);
 }
 
-/* Should take bits from enumeration instead of booleans */
-static void do_load1(EditState *s, const char *filename1,
+/* Load a file and attach buffer to window `s`.
+ * Return -1 if loading failed.
+ * Return 0 if file or resource was already loaded,
+ * Return 1 if file or resource was newly loaded,
+ * Return 2 if buffer was created for a new file.
+ * Should take bits from enumeration instead of booleans.
+ */
+int qe_load_file(EditState *s, const char *filename1,
                      int kill_buffer, int load_resource, int bflags)
 {
     u8 buf[4097];
     char filename[MAX_FILENAME_SIZE];
-    int st_mode, buf_size;
+    int st_mode, buf_size, mode_score;
     ModeDef *selected_mode;
-    int mode_score;
     EditBuffer *b;
     EditBufferDataType *bdt;
     FILE *f;
@@ -6061,46 +6042,47 @@
     EOLType eol_type = EOL_UNIX;
     QECharset *charset = &charset_utf8;
 
+#ifndef CONFIG_TINY
+    /* avoid messing with the dired pane */
+    if ((s->flags & WF_POPLEFT) && s->x1 == 0) {
+        EditState *e = find_window(s, KEY_RIGHT, NULL);
+        if (e) {
+            if (s->qe_state->active_window == s)
+                s->qe_state->active_window = e;
+            s = e;
+        }
+    }
+#endif
+
     if (load_resource) {
         if (find_resource_file(filename, sizeof(filename), filename1)) {
             /* XXX: issue error message? */
-            return;
+            return -1;
         }
     } else {
         /* compute full name */
         canonicalize_absolute_path(filename, sizeof(filename), filename1);
     }
 
-    ///* If file already shown in window, switch to that */
-    //s1 = find_file_window(filename);
-    //if (s1 != NULL) {
-    //    qs->active_window = s1;
-    //    return;
-    //}
-
-    ///* Split window if window large enough and not empty */
-    //if (other_window && s->height > 10 && s->b->total_size > 0) {
-    //    do_split_window(s, 0, 0);
-    //    s = qs->active_window;
-    //}
-
-    if (kill_buffer && s->b) {
-        /* CG: this behaviour is not correct */
-        /* CG: should have a direct primitive */
-        do_kill_buffer(s, s->b->name);
-    }
-
     /* If file already loaded in existing buffer, switch to that */
     b = eb_find_file(filename);
     if (b != NULL) {
         switch_to_buffer(s, b);
-        return;
+        return 0;
+    }
+
+    /* We are going to try and load a new file: potentially delete the
+     * current buffer if requested.
+     */
+    if (kill_buffer && s->b && !s->b->modified) {
+        s->b->flags |= BF_TRANSIENT;
     }
 
     /* Create new buffer with unique name from filename */
     b = eb_new("", BF_SAVELOG | bflags);
     eb_set_filename(b, filename);
 
+    /* XXX: should actually initialize SAVED_DATA area in new buffer */
     s->offset = 0;
     /* XXX: Should test for full width and WRAP_TRUNCATE if not */
     s->wrap = WRAP_LINE;        /* default mode may override this */
@@ -6128,7 +6110,7 @@
         if (b->data_type == &raw_data_type)
             put_status(s, "(New file)");
         do_load_qerc(s, s->b->filename);
-        return;
+        return 2;
     } else {
         b->st_mode = st_mode = st.st_mode;
         buf_size = 0;
@@ -6179,7 +6161,7 @@
 
         /* XXX: invalid place */
         edit_invalidate(s);
-        return;
+        return 1;
     }
 
  fail:
@@ -6187,6 +6169,7 @@
 
     put_status(s, "Could not open '%s': %s",
                filename, strerror(errno));
+    return -1;
 }
 
 #if 0
@@ -6224,25 +6207,28 @@
 
 void do_find_file(EditState *s, const char *filename, int bflags)
 {
-    do_load1(s, filename, 0, 0, bflags);
+    qe_load_file(s, filename, 0, 0, bflags);
 }
 
 void do_find_file_other_window(EditState *s, const char *filename, int bflags)
 {
-    QEmacsState *qs = s->qe_state;
-
+    /* Split window if window large enough and not empty */
+    /* XXX: should check s->height units */
+    if (s->height > 10 && s->b->total_size > 0) {
     do_split_window(s, 0);
-    do_load1(qs->active_window, filename, 0, 0, bflags);
+        s = s->qe_state->active_window;
+    }
+    qe_load_file(s, filename, 0, 0, bflags);
 }
 
 void do_find_alternate_file(EditState *s, const char *filename, int bflags)
 {
-    do_load1(s, filename, 1, 0, bflags);
+    qe_load_file(s, filename, 1, 0, bflags);
 }
 
 void do_load_file_from_path(EditState *s, const char *filename, int bflags)
 {
-    do_load1(s, filename, 0, 1, bflags);
+    qe_load_file(s, filename, 0, 1, bflags);
 }
 
 void do_insert_file(EditState *s, const char *filename)
@@ -6608,9 +6594,8 @@
 void do_delete_window(EditState *s, int force)
 {
     QEmacsState *qs = s->qe_state;
-    EditState *e;
-    int count, x1, y1, x2, y2;
-    int ex1, ey1, ex2, ey2;
+    EditState *e, *e1 = NULL;
+    int count, pass, x1, y1, x2, y2;
 
     count = 0;
     for (e = qs->first_window; e != NULL; e = e->next_window) {
@@ -6622,47 +6607,53 @@
         return;
 
     if (!(s->flags & WF_POPUP)) {
-        /* try to merge the window with one adjacent window. If none
-           found, just leave a hole */
+        /* Try to merge the window with adjacent windows.
+         * If this cannot be done, just leave a hole and force full
+         * redisplay.
+         */
         x1 = s->x1;
         x2 = s->x2;
         y1 = s->y1;
         y2 = s->y2;
 
+        for (pass = 0; pass < 2; pass++) {
         for (e = qs->first_window; e != NULL; e = e->next_window) {
-            if (e->minibuf || e == s)
+                if (e->minibuf || e == s || (e->flags & WF_POPUP))
                 continue;
-            ex1 = e->x1;
-            ex2 = e->x2;
-            ey1 = e->y1;
-            ey2 = e->y2;
 
-            if (x1 == ex2 && y1 == ey1 && y2 == ey2) {
-                /* left border */
+                if (x1 == e->x2 && y1 == e->y1 && y2 >= e->y2) {
+                    /* partial vertical split along the left border */
                 e->x2 = x2;
-                break;
+                    y1 = e->y2;
             } else
-            if (x2 == ex1 && y1 == ey1 && y2 == ey2) {
-                /* right border */
+                if (x2 == e->x1 && y1 == e->y1 && y2 >= e->y2) {
+                    /* partial vertical split along the right border */
                 e->x1 = x1;
-                break;
+                    y1 = e->y2;
             } else
-            if (y1 == ey2 && x1 == ex1 && x2 == ex2) {
-                /* top border */
+                if (y1 == e->y2 && x1 == e->x1 && x2 >= e->x2) {
+                    /* partial horizontal split along the top border */
                 e->y2 = y2;
-                break;
+                    x1 = e->x2;
             } else
-            if (y2 == ey1 && x1 == ex1 && x2 == ex2) {
-                /* bottom border */
+                if (y2 == e->y1 && x1 == e->x1 && x2 >= e->x2) {
+                    /* partial horizontal split along bottom border */
                 e->y1 = y1;
-                break;
+                    x1 = e->x2;
+                } else {
+                    continue;
             }
+                compute_client_area(e1 = e);
         }
-        if (e)
-            compute_client_area(e);
+            if (x1 == x2 || y1 == y2)
+                break;
+        }
+        if (x1 != x2 && y1 != y2)
+            qs->complete_refresh = 1;
     }
     if (qs->active_window == s)
-        qs->active_window = e ? e : qs->first_window;
+        qs->active_window = e1 ? e1 : qs->first_window;
+
     edit_close(&s);
     if (qs->first_window)
         do_refresh(qs->first_window);
@@ -6673,6 +6664,9 @@
     QEmacsState *qs = s->qe_state;
     EditState *e, *e1;
 
+    if (s->minibuf || (s->flags & WF_POPUP))
+        return;
+
     for (e = qs->first_window; e != NULL; e = e1) {
         e1 = e->next_window;
         if (!e->minibuf && e != s)
@@ -6718,8 +6712,7 @@
         s->y2 = y;
     }
     /* insert in the window list after current window */
-    edit_detach(e);
-    edit_attach(e, &s->next_window);
+    edit_attach(e, s->next_window);
 
     if (qs->flag_split_window_change_focus)
         qs->active_window = e;

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.200
retrieving revision 1.201
diff -u -b -r1.200 -r1.201
--- qe.h        19 Aug 2015 16:22:30 -0000      1.200
+++ qe.h        19 Aug 2015 19:20:58 -0000      1.201
@@ -859,6 +859,8 @@
 #define BF_STYLE1    0x1000  /* buffer has 1 byte styles */
 #define BF_STYLE2    0x2000  /* buffer has 2 byte styles */
 #define BF_STYLE4    0x3000  /* buffer has 4 byte styles */
+#define BF_IS_STYLE  0x4000  /* buffer is a styles buffer */
+#define BF_IS_LOG    0x8000  /* buffer is a log buffer */
 
 struct EditBuffer {
     OWNED Page *page_table;
@@ -927,9 +929,9 @@
     /* CG: should instead keep a pointer to last window using this
      * buffer, even if no longer on screen
      */
-    struct ModeDef *default_mode;
-    struct ModeDef *saved_mode;
-    OWNED struct ModeSavedData *saved_data;
+    ModeDef *default_mode;
+    ModeDef *saved_mode;
+    OWNED ModeSavedData *saved_data;
 
     /* default mode stuff when buffer is detached from window */
     int offset;
@@ -1171,6 +1173,8 @@
 
     EditBuffer *b;
 
+    EditBuffer *last_buffer;    /* for predict_switch_to_buffer */
+
     /* mode specific info */
     ModeDef *mode;
     void *mode_data; /* mode private data */
@@ -1205,6 +1209,7 @@
 #define WF_POPUP      0x0001 /* popup window (with borders) */
 #define WF_MODELINE   0x0002 /* mode line must be displayed */
 #define WF_RSEPARATOR 0x0004 /* right window separator */
+#define WF_POPLEFT    0x0008 /* left side window */
 
     OWNED char *prompt;  /* optional window prompt, utf8, owned by the window 
*/
     //const char *mode_line;
@@ -1751,15 +1756,19 @@
 }
 #endif
 
+/* file loading */
+int qe_load_file(EditState *s, const char *filename1,
+                 int kill_buffer, int load_resource, int bflags);
+
 /* config file support */
 void do_load_config_file(EditState *e, const char *file);
 void do_load_qerc(EditState *e, const char *file);
 
 /* popup / low level window handling */
-void show_popup(EditBuffer *b);
+EditState *show_popup(EditBuffer *b);
 int check_read_only(EditState *s);
 EditState *insert_window_left(EditBuffer *b, int width, int flags);
-EditState *find_window(EditState *s, int key);
+EditState *find_window(EditState *s, int key, EditState *def);
 void do_find_window(EditState *s, int key);
 
 /* window handling */
@@ -1767,8 +1776,8 @@
 EditState *edit_new(EditBuffer *b,
                     int x1, int y1, int width, int height, int flags);
 void edit_detach(EditState *s);
+EditBuffer *check_buffer(EditBuffer **sp);
 EditState *check_window(EditState **sp);
-EditState *edit_find(EditBuffer *b);
 void do_refresh(EditState *s);
 // should take direction argument
 void do_other_window(EditState *s);
@@ -1939,7 +1948,7 @@
 void do_execute_macro_keys(EditState *s, const char *keys);
 void do_define_kbd_macro(EditState *s, const char *name, const char *keys,
                          const char *key_bind);
-void edit_attach(EditState *s, EditState **ep);
+void edit_attach(EditState *s, EditState *e);
 void do_completion(EditState *s);
 void do_completion_space(EditState *s);
 void do_electric_filename(EditState *s, int key);

Index: shell.c
===================================================================
RCS file: /sources/qemacs/qemacs/shell.c,v
retrieving revision 1.96
retrieving revision 1.97
diff -u -b -r1.96 -r1.97
--- shell.c     10 Aug 2015 19:44:20 -0000      1.96
+++ shell.c     19 Aug 2015 19:20:58 -0000      1.97
@@ -52,10 +52,8 @@
     TTY_STATE_STRING,
 };
 
-static int shell_signature;
-
 typedef struct ShellState {
-    void *signature;
+    ModeDef *signature;
     /* buffer state */
     int pty_fd;
     int pid; /* -1 if not launched */
@@ -659,7 +657,7 @@
 {
     ShellState *s = e->b->priv_data;
 
-    if (s && s->signature == &shell_signature)
+    if (s && s->signature == &shell_mode)
         return s;
 
     if (status)
@@ -687,7 +685,7 @@
     const char *p;
     int len;
 
-    if (!s || s->signature != &shell_signature)
+    if (!s || s->signature != &shell_mode)
         return;
 
     if (key == KEY_CTRL('o')) {
@@ -1244,7 +1242,7 @@
     unsigned char buf[16 * 1024];
     int len, i;
 
-    if (!s || s->signature != &shell_signature)
+    if (!s || s->signature != &shell_mode)
         return;
 
     qs = s->qe_state;
@@ -1279,7 +1277,7 @@
     ShellState *s = b->priv_data;
     int status;
 
-    if (!s || s->signature != &shell_signature)
+    if (!s || s->signature != &shell_mode)
         return;
 
     eb_free_callback(b, eb_offset_callback, &s->cur_offset);
@@ -1317,7 +1315,7 @@
     EditState *e;
     char buf[1024];
 
-    if (!s || s->signature != &shell_signature)
+    if (!s || s->signature != &shell_mode)
         return;
 
     b = s->b;
@@ -1395,7 +1393,7 @@
     b = b0;
     if (b) {
         s = b->priv_data;
-        if (s && s->signature != &shell_signature)
+        if (s && s->signature != &shell_mode)
             return NULL;
         if (shell_flags & SF_COLOR)
             eb_create_style_buffer(b, BF_STYLE2);
@@ -1426,7 +1424,7 @@
                 eb_free(&b);
             return NULL;
         }
-        s->signature = &shell_signature;
+        s->signature = &shell_mode;
         b->priv_data = s;
         b->close = shell_close;
         /* Track cursor with edge effect */
@@ -1466,7 +1464,7 @@
 
     b = eb_find(bufname);
     if (b) {
-        e = edit_find(b);
+        e = eb_find_window(b, NULL);
         if (e)
             qs->active_window = e;
         else
@@ -1480,26 +1478,33 @@
     ShellState *shs;
     EditBuffer *b = NULL;
 
+    if (s->flags & WF_POPLEFT) {
+        /* avoid messing with the dired pane */
+        s = find_window(s, KEY_RIGHT, s);
+        s->qe_state->active_window = s;
+    }
+
     /* CG: Should prompt for buffer name if arg:
      * find a syntax for optional string argument w/ prompt
      */
     /* find shell buffer if any */
     if (!force || force == NO_ARG) {
         /* XXX: if current buffer is a shell buffer without a process,
-         * restart shell process.
+         * restart shell process in it.
          */
         b = s->b;
         shs = b->priv_data;
         if (strstart(b->name, "*shell*", NULL)
-        &&  shs && shs->signature == &shell_signature) {
+        &&  shs && shs->signature == &shell_mode) {
             if (shs->pid >= 0)
                 return;
         } else {
+            /* XXX: should find the last used shell buffer */
             b = try_show_buffer(s, "*shell*");
             if (b) {
                 shs = b->priv_data;
                 if (shs) {
-                    if (shs->signature != &shell_signature) {
+                    if (shs->signature != &shell_mode) {
                         b = NULL;
                     } else
                     if (shs->pid >= 0)
@@ -1960,7 +1965,7 @@
 {
     if (p->b && p->b->priv_data) {
         ShellState *s = p->b->priv_data;
-        if (s->signature == &shell_signature) {
+        if (s->signature == &shell_mode) {
             if (s->shell_flags & SF_INTERACTIVE)
                 return 100;
         }



reply via email to

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