qemacs-commit
[Top][All Lists]
Advanced

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

[Qemacs-commit] qemacs buffer.c parser.c qe.h variables.c dired...


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs buffer.c parser.c qe.h variables.c dired...
Date: Thu, 10 Sep 2015 00:25:24 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        15/09/10 00:25:24

Modified files:
        .              : buffer.c parser.c qe.h variables.c dired.c qe.c 
                         qeconfig.h variables.h 

Log message:
        sessions: implement session saving/restoring
        - add qe_save_variables(s, b)
        - add use_session_file global variable
        - add VarDef::modified flag to detect customized variables
        - set modified flag upon variable modifications
        - dired: set modified flag when changing in dired variables
        - fix BUG in qe_register_variables, did not set set_value handler 
          on last VarDef element
        - make qe_save_variables() public
        - remove do_save_variables(), move save_session() to parser.c
        - add eb_puts() and eb_putc() for consistency
        - add WF_HIDDEN window flag to temporarily flag windows to be deleted
        - add do_hide_window(), do_delete_all_windows() and 
do_delete_hidden_windows()
        - add qe_save_window_layout() to save window layout to session file
        - add do_create_window(s, filename, layout) to restore window layout
        - add qe_save_macros() to save keyboard macros to session file
        - detect keyboard macro redefinitions and avoid duplicates
        - add qe_save_open_files() to save list of open files and directories
        - pass `all` flag to do_delete_other_windows() to force complete 
deletion
        - add qe_load_session() and do_save_session():
          * qe_load_session() is invoked before parsing the command line if 
            use_session_file is set, via the config file or command line option 
(-s)
          * do_save_session() is invoked just before closing qemacs.  It can 
also
            be invoked as a command and shows a popup window with the contents 
of
            the session file produced instead of saving it.
        - fix CRASH BUG in command definitions, missing argument specifier 
caused
          spurious crashes when invoking commands from script files. This 
affected:
          find-file(), find-file-other-window(), find-alternate-file(), 
kill-buffer()
          load-file-from-path().
        - insert newly created windows in list in top-down left-right order
        - update WF_RSEPARATOR flag upon deletion of vertically split window

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.97&r2=1.98
http://cvs.savannah.gnu.org/viewcvs/qemacs/parser.c?cvsroot=qemacs&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.207&r2=1.208
http://cvs.savannah.gnu.org/viewcvs/qemacs/variables.c?cvsroot=qemacs&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/qemacs/dired.c?cvsroot=qemacs&r1=1.62&r2=1.63
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.212&r2=1.213
http://cvs.savannah.gnu.org/viewcvs/qemacs/qeconfig.h?cvsroot=qemacs&r1=1.54&r2=1.55
http://cvs.savannah.gnu.org/viewcvs/qemacs/variables.h?cvsroot=qemacs&r1=1.7&r2=1.8

Patches:
Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -b -r1.97 -r1.98
--- buffer.c    27 Aug 2015 23:03:40 -0000      1.97
+++ buffer.c    10 Sep 2015 00:25:23 -0000      1.98
@@ -1891,10 +1891,10 @@
 int eb_raw_buffer_load1(EditBuffer *b, FILE *f, int offset)
 {
     unsigned char buf[IOBUF_SIZE];
-    int len, size;
+    int len, size, inserted;
 
     //put_status(NULL, "loading %s", filename);
-    size = 0;
+    size = inserted = 0;
     for (;;) {
         len = fread(buf, 1, IOBUF_SIZE, f);
         if (len <= 0) {
@@ -1902,7 +1902,7 @@
                 return -1;
             break;
         }
-        eb_insert(b, offset, buf, len);
+        inserted += eb_insert(b, offset, buf, len);
         offset += len;
         size += len;
     }
@@ -2190,6 +2190,19 @@
     return 1;
 }
 
+int eb_putc(EditBuffer *b, int c)
+{
+    char buf[8];
+    int len = eb_encode_uchar(b, buf, c);
+
+    return eb_insert(b, b->total_size, buf, len);
+}
+
+int eb_puts(EditBuffer *b, const char *s)
+{
+    return eb_insert_utf8_buf(b, b->total_size, s, strlen(s));
+}
+
 int eb_printf(EditBuffer *b, const char *fmt, ...)
 {
     char buf0[1024];

Index: parser.c
===================================================================
RCS file: /sources/qemacs/qemacs/parser.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- parser.c    11 Aug 2015 22:15:38 -0000      1.3
+++ parser.c    10 Sep 2015 00:25:23 -0000      1.4
@@ -224,9 +224,6 @@
         }
         nb_args = 0;
 
-        /* first argument is always the window */
-        args_type[nb_args++] = CMD_ARG_WINDOW;
-
         /* construct argument type list */
         r = d->name + strlen(d->name) + 1;
         if (*r == '*') {
@@ -237,6 +234,9 @@
             }
         }
 
+        /* first argument is always the window */
+        args_type[nb_args++] = CMD_ARG_WINDOW;
+
         for (;;) {
             unsigned char arg_type;
             int ret;
@@ -324,6 +324,7 @@
         qs->last_cmd_func = qs->this_cmd_func;
         if (qs->active_window)
             s = qs->active_window;
+        check_window(&s);
         continue;
 
     fail:
@@ -391,6 +392,39 @@
     do_eval_buffer_region(s, 0, -1);
 }
 
+#ifndef CONFIG_TINY
+int qe_load_session(EditState *s)
+{
+    return parse_config_file(s, ".qesession");
+}
+
+void do_save_session(EditState *s, int popup)
+{
+    EditBuffer *b = eb_scratch("*session*", BF_UTF8);
+    time_t now;
+
+    eb_printf(b, "// qemacs version: %s\n", QE_VERSION);
+    now = time(NULL);
+    eb_printf(b, "// session saved: %s\n", ctime(&now));
+
+    qe_save_variables(s, b);
+    qe_save_macros(s, b);
+    qe_save_open_files(s, b);
+    qe_save_window_layout(s, b);
+
+    if (popup) {
+        b->offset = 0;
+        b->flags |= BF_READONLY;
+
+        /* Should show window caption "qemacs session" */
+        show_popup(b);
+    } else {
+        eb_write_buffer(b, 0, b->total_size, ".qesession");
+        eb_free(&b);
+    }
+}
+#endif
+
 static CmdDef parser_commands[] = {
 
     CMD2( KEY_META(':'), KEY_NONE,
@@ -400,7 +434,10 @@
           "eval-region", do_eval_region)
     CMD0( KEY_NONE, KEY_NONE,
           "eval-buffer", do_eval_buffer)
-
+#ifndef CONFIG_TINY
+    CMD1( KEY_NONE, KEY_NONE,
+          "save-session", do_save_session, 1)
+#endif
     CMD_DEF_END,
 };
 

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.207
retrieving revision 1.208
diff -u -b -r1.207 -r1.208
--- qe.h        27 Aug 2015 15:32:28 -0000      1.207
+++ qe.h        10 Sep 2015 00:25:23 -0000      1.208
@@ -1036,6 +1036,8 @@
 int eb_match_str(EditBuffer *b, int offset, const char *str, int *offsetp);
 int eb_match_istr(EditBuffer *b, int offset, const char *str, int *offsetp);
 int eb_printf(EditBuffer *b, const char *fmt, ...) __attr_printf(2,3);
+int eb_puts(EditBuffer *b, const char *s);
+int eb_putc(EditBuffer *b, int c);
 void eb_line_pad(EditBuffer *b, int n);
 int eb_get_region_content_size(EditBuffer *b, int start, int stop);
 static inline int eb_get_content_size(EditBuffer *b) {
@@ -1215,8 +1217,9 @@
 #define WF_MODELINE   0x0002 /* mode line must be displayed */
 #define WF_RSEPARATOR 0x0004 /* right window separator */
 #define WF_POPLEFT    0x0008 /* left side window */
+#define WF_HIDDEN     0x0010 /* hidden window, used for temporary changes */
 
-    OWNED char *prompt;  /* optional window prompt, utf8, owned by the window 
*/
+    OWNED char *prompt;  /* optional window prompt, utf8 */
     //const char *mode_line;
     //const char *title;
     struct QEmacsState *qe_state;
@@ -1804,6 +1807,9 @@
 void do_delete_window(EditState *s, int force);
 // should take argval
 void do_split_window(EditState *s, int horiz);
+void do_create_window(EditState *s, const char *filename, const char *layout);
+void qe_save_window_layout(EditState *s, EditBuffer *b);
+
 void edit_display(QEmacsState *qs);
 void edit_invalidate(EditState *s);
 void display_mode_line(EditState *s);
@@ -1967,6 +1973,8 @@
 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 qe_save_macros(EditState *s, EditBuffer *b);
+
 void edit_attach(EditState *s, EditState *e);
 void do_completion(EditState *s);
 void do_completion_space(EditState *s);
@@ -1982,8 +1990,12 @@
 void do_load_file_from_path(EditState *s, const char *filename, int bflags);
 void do_set_visited_file_name(EditState *s, const char *filename,
                               const char *renamefile);
+void qe_save_open_files(EditState *s, EditBuffer *b);
+
 void do_doctor(EditState *s);
-void do_delete_other_windows(EditState *s);
+void do_delete_other_windows(EditState *s, int all);
+void do_hide_window(EditState *s, int set);
+void do_delete_hidden_windows(EditState *s);
 void do_describe_key_briefly(EditState *s);
 void do_show_bindings(EditState *s, const char *cmd_name);
 void do_apropos(EditState *s, const char *str);
@@ -2004,6 +2016,9 @@
 void do_eval_expression(EditState *s, const char *expression);
 void do_eval_region(EditState *s); /* should pass actual offsets */
 void do_eval_buffer(EditState *s);
+extern int use_session_file;
+int qe_load_session(EditState *s);
+void do_save_session(EditState *s, int popup);
 
 /* extras.c */
 

Index: variables.c
===================================================================
RCS file: /sources/qemacs/qemacs/variables.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- variables.c 30 Aug 2015 12:03:46 -0000      1.19
+++ variables.c 10 Sep 2015 00:25:24 -0000      1.20
@@ -75,7 +75,10 @@
     M_VAR( "mode-name", name, VAR_STRING, VAR_RO )
     M_VAR( "auto-indent", auto_indent, VAR_NUMBER, VAR_RW )
 
+    G_VAR( "use-session-file", use_session_file, VAR_NUMBER, VAR_RW )
+
     /* more buffer fields: modified, readonly, binary, charset */
+
     /* more window fields: mode_line, color, input_method...
      */
 
@@ -215,23 +218,32 @@
             snprintf(buf, sizeof(buf), "%d", num);
             value = buf;
         }
+        if (!strequal(ptr, value)) {
         pstr = (char **)ptr;
         if ((u8 *)*pstr > end)
             qe_free(pstr);
         *pstr = qe_strdup(value);
+            vp->modified = 1;
+        }
         break;
     case VAR_CHARS:
         if (!value) {
             snprintf(buf, sizeof(buf), "%d", num);
             value = buf;
         }
+        if (!strequal(ptr, value)) {
         pstrcpy(ptr, vp->size, value);
+            vp->modified = 1;
+        }
         break;
     case VAR_NUMBER:
         if (!value) {
-            /* XXX: should have default, min and max values */
+            if (*(int*)ptr != num) {
             *(int*)ptr = num;
+                vp->modified = 1;
+            }
         } else {
+            /* XXX: should have default, min and max values */
             return VAR_INVALID;
         }
         break;
@@ -252,6 +264,7 @@
         /* Create user variable (global/buffer/window/mode?) */
         vp = qe_mallocz(VarDef);
         vp->name = qe_strdup(name);
+        vp->modified = 1;
         vp->domain = VAR_SELF;
         vp->rw = VAR_RW_SAVE;
         if (value) {
@@ -332,12 +345,12 @@
     QEmacsState *qs = &qe_state;
     VarDef *vp;
 
-    for (vp = vars; vp < vars + count - 1; vp++) {
+    for (vp = vars; vp < vars + count; vp++) {
         if (!vp->set_value)
             vp->set_value = qe_generic_set_variable;
         vp->next = vp + 1;
     }
-    vp->next = qs->first_variable;
+    vp[-1].next = qs->first_variable;
     qs->first_variable = vars;
 }
 
@@ -350,7 +363,7 @@
     const char *type;
     const VarDef *vp;
 
-    eb_printf(b, "\n  variables:\n\n");
+    eb_puts(b, "\n  variables:\n\n");
     for (vp = qs->first_variable; vp; vp = vp->next) {
         switch (vp->type) {
         case VAR_NUMBER:
@@ -375,19 +388,17 @@
     }
 }
 
-static void qe_save_variables(EditState *s, EditBuffer *b)
+void qe_save_variables(EditState *s, EditBuffer *b)
 {
     QEmacsState *qs = s->qe_state;
     char buf[MAX_FILENAME_SIZE];
     char varname[32], *p;
     const VarDef *vp;
 
-    eb_printf(b, "// variables:\n");
-    eb_printf(b, "// version: %s\n", QE_VERSION);
-    eb_printf(b, "\n");
-
+    eb_puts(b, "// variables:\n");
+    /* Only save customized variables */
     for (vp = qs->first_variable; vp; vp = vp->next) {
-        if (vp->rw != VAR_RW_SAVE)
+        if (vp->rw != VAR_RW_SAVE || !vp->modified)
             continue;
         pstrcpy(varname, countof(varname), vp->name);
         for (p = varname; *p; p++) {
@@ -397,18 +408,7 @@
         qe_get_variable(s, vp->name, buf, sizeof(buf), NULL, 1);
         eb_printf(b, "%s = %s;\n", varname, buf);
     }
-    eb_printf(b, "\n");
-}
-
-static void do_save_variables(EditState *s)
-{
-    EditBuffer *b = eb_scratch("*session*", BF_UTF8);
-    qe_save_variables(s, b);
-    b->offset = 0;
-    b->flags |= BF_READONLY;
-
-    /* Should show window caption "qemacs session" */
-    show_popup(b);
+    eb_putc(b, '\n');
 }
 
 /*---------------- commands ----------------*/
@@ -420,8 +420,6 @@
     CMD2( KEY_F8, KEY_NONE,
           "set-variable", do_set_variable, ESss,
           "s{Set variable: }[var]|var|s{to value: }|value|")
-    CMD0( KEY_F8, KEY_NONE,
-          "save-variables", do_save_variables)
 
     CMD_DEF_END,
 };

Index: dired.c
===================================================================
RCS file: /sources/qemacs/qemacs/dired.c,v
retrieving revision 1.62
retrieving revision 1.63
diff -u -b -r1.62 -r1.63
--- dired.c     30 Aug 2015 21:51:49 -0000      1.62
+++ dired.c     10 Sep 2015 00:25:24 -0000      1.63
@@ -112,6 +112,20 @@
 static int dired_hflag = 0; /* 0=exact, 1=human-decimal, 2=human-binary */
 static int dired_sort_mode = DIRED_SORT_GROUP | DIRED_SORT_NAME;
 
+static QVarType dired_sort_mode_set_value(EditState *s, VarDef *vp,
+    void *ptr, const char *str, int sort_mode);
+static QVarType dired_time_format_set_value(EditState *s, VarDef *vp,
+    void *ptr, const char *str, int format);
+
+static VarDef dired_variables[] = {
+    G_VAR_F( "dired-sort-mode", dired_sort_mode, VAR_NUMBER, VAR_RW_SAVE,
+            dired_sort_mode_set_value )
+    G_VAR_F( "dired-time-format", dired_time_format, VAR_NUMBER, VAR_RW_SAVE,
+            dired_time_format_set_value )
+    G_VAR( "dired-show-dot-files", dired_show_dot_files, VAR_NUMBER, 
VAR_RW_SAVE )
+    G_VAR( "dired-show-ds-store", dired_show_ds_store, VAR_NUMBER, VAR_RW_SAVE 
)
+};
+
 static inline DiredState *dired_get_state(EditState *e, int status)
 {
     return qe_get_buffer_mode_data(e->b, &dired_mode, status ? e : NULL);
@@ -854,7 +868,10 @@
             break;
         }
     }
+    if (dired_sort_mode != sort_mode) {
     dired_sort_mode = sort_mode;
+        vp->modified = 1;
+    }
     return VAR_NUMBER;
 }
 
@@ -862,7 +879,8 @@
 {
     int sort_mode = dired_sort_mode;
 
-    dired_sort_mode_set_value(s, NULL, &dired_sort_mode, sort_order, 
sort_mode);
+    dired_sort_mode_set_value(s, &dired_variables[0], &dired_sort_mode,
+                              sort_order, sort_mode);
 
     if (sort_mode != dired_sort_mode)
         dired_update_buffer(dired_get_state(s, 0), s->b, s, DIRED_UPDATE_SORT);
@@ -885,14 +903,17 @@
     if (format < 0 || format > TF_MAX)
        return VAR_UNKNOWN;
 
+    if (dired_time_format != format) {
     dired_time_format = format;
-
+        vp->modified = 1;
+    }
     return VAR_NUMBER;
 }
 
 static void dired_set_time_format(EditState *s, int format)
 {
-    dired_time_format_set_value(s, NULL, &dired_time_format, NULL, format);
+    dired_time_format_set_value(s, &dired_variables[1], &dired_time_format,
+                                NULL, format);
 }
 
 /* `ds` and `b` are valid, `s` and `target` may be NULL */
@@ -1030,7 +1051,7 @@
     if (rc >= 0) {
         /* disable wrapping to get nicer display */
         /* XXX: should wrap lines unless window is narrow */
-        //e->wrap = WRAP_TRUNCATE;
+        e->wrap = WRAP_TRUNCATE;
     }
     if (rc < 0) {
         /* if file failed to load, show a scratch buffer */
@@ -1293,15 +1314,6 @@
     CMD_DEF_END,
 };
 
-static VarDef dired_variables[] = {
-    G_VAR_F( "dired-time-format", dired_time_format, VAR_NUMBER, VAR_RW_SAVE,
-            dired_time_format_set_value )
-    G_VAR( "dired-show-dot-files", dired_show_dot_files, VAR_NUMBER, 
VAR_RW_SAVE )
-    G_VAR( "dired-show-ds-store", dired_show_ds_store, VAR_NUMBER, VAR_RW_SAVE 
)
-    G_VAR_F( "dired-sort-mode", dired_sort_mode, VAR_NUMBER, VAR_RW_SAVE,
-            dired_sort_mode_set_value )
-};
-
 static int dired_init(void)
 {
     /* inherit from list mode */

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.212
retrieving revision 1.213
diff -u -b -r1.212 -r1.213
--- qe.c        27 Aug 2015 23:03:41 -0000      1.212
+++ qe.c        10 Sep 2015 00:25:24 -0000      1.213
@@ -74,6 +74,7 @@
 static int screen_width = 0;
 static int screen_height = 0;
 static int no_init_file;
+int use_session_file;
 #ifndef CONFIG_TINY
 static int free_everything;
 #endif
@@ -1870,6 +1871,7 @@
         ret = b->data_type->buffer_load(b, f);
     else
         ret = -1;
+
     b->modified = 0;
     b->save_log = saved;
 
@@ -4636,17 +4638,29 @@
                          const char *key_bind)
 {
     CmdDef *def;
-    int size;
+    int namelen, size;
     char *buf;
 
-    size = strlen(name) + 1 + 2 + strlen(keys) + 2;
+    namelen = strlen(name);
+    size = namelen + 1 + 2 + strlen(keys) + 2;
     buf = qe_malloc_array(char, size);
 
+    // XXX: should special case "last-kbd-macro"
+
     /* CG: should parse macro keys to an array and pass index
      * to do_execute_macro.
      */
     snprintf(buf, size, "%s%cS{%s}", name, 0, keys);
 
+    def = qe_find_cmd(name);
+    if (def && def->action.ESs == do_execute_macro_keys) {
+        /* redefininig a macro */
+        /* XXX: freeing the current macro definition may cause a crash if it
+         * is currently executing.
+         */
+        qe_free((char **)&def->name);
+        def->name = buf;
+    } else {
     def = qe_mallocz_array(CmdDef, 2);
     def->key = def->alt_key = KEY_NONE;
     def->name = buf;
@@ -4655,7 +4669,57 @@
     def->action.ESs = do_execute_macro_keys;
     def[1].val = 1;  /* flag as allocated for free-all */
     qe_register_cmd_table(def, NULL);
+    }
+    if (key_bind && *key_bind) {
     do_set_key(s, key_bind, name, 0);
+    }
+}
+
+static void qe_save_macro(EditState *s, CmdDef *def, EditBuffer *b)
+{
+    QEmacsState *qs = s->qe_state;
+    char buf[32];
+    buf_t outbuf, *out;
+    int i;
+    const char *name = "last-kbd-macro";
+
+    if (def)
+        name = def->name;
+
+    eb_printf(b, "define_kbd_macro(\"%s\", \"", name);
+
+    if (def) {
+        const char *keys = def->name;
+        keys += strlen(keys) + 1 + 2;
+        while (keys[1]) {
+            eb_putc(b, utf8_decode(&keys));
+        }
+    } else {
+        for (i = 0; i < qs->nb_macro_keys; i++) {
+            out = buf_init(&outbuf, buf, sizeof(buf));
+            buf_put_key(out, qs->macro_keys[i]);
+            eb_puts(b, out->buf);
+        }
+    }
+    eb_puts(b, "\", \"\");\n");
+}
+
+void qe_save_macros(EditState *s, EditBuffer *b)
+{
+    QEmacsState *qs = &qe_state;
+    CmdDef *d;
+
+    eb_puts(b, "// macros:\n");
+    qe_save_macro(s, NULL, b);
+
+    /* Enumerate defined macros */
+    for (d = qs->first_cmd; d != NULL; d = d->action.next) {
+        for (; d->name != NULL; d++) {
+            if (d->action.ESs == do_execute_macro_keys)
+                qe_save_macro(s, d, b);
+        }
+    }
+    eb_putc(b, '\n');
 }
 
 #define MACRO_KEY_INCR 64
@@ -5131,7 +5195,7 @@
 {
     /* b may be NULL ??? */
     QEmacsState *qs = &qe_state;
-    EditState *s;
+    EditState *s, *e;
 
     s = qe_mallocz(EditState);
     if (!s)
@@ -5147,7 +5211,11 @@
     compute_client_area(s);
 
     /* link window in window list */
-    edit_attach(s, qs->first_window);
+    for (e = qs->first_window; e != NULL; e = e->next_window) {
+        if (e->y1 > s->y1 || (e->y1 == s->y1 && e->x1 > s->x1))
+            break;
+    }
+    edit_attach(s, e);
 
     /* restore saved window settings, set mode */
     switch_to_buffer(s, b);
@@ -6290,7 +6358,6 @@
             f = NULL;
             goto fail;
         }
-
         bdt = selected_mode->data_type;
         if (bdt == &raw_data_type)
             eb_set_charset(b, charset, eol_type);
@@ -6329,6 +6396,19 @@
     return -1;
 }
 
+void qe_save_open_files(EditState *s, EditBuffer *b)
+{
+    QEmacsState *qs = &qe_state;
+    EditBuffer *b1;
+
+    eb_puts(b, "// open files:\n");
+    for (b1 = qs->first_buffer; b1 != NULL; b1 = b1->next) {
+        if (!(b1->flags & BF_SYSTEM) && *b1->filename)
+            eb_printf(b, "find_file(\"%s\");\n", b1->filename);
+    }
+    eb_putc(b, '\n');
+}
+
 #if 0
 static void load_progress_cb(void *opaque, int size)
 {
@@ -6540,6 +6620,10 @@
         edit_display(&qe_state);
         dpy_flush(&global_screen);
     } else {
+#ifndef CONFIG_TINY
+        if (use_session_file)
+            do_save_session(qe_state.active_window, 0);
+#endif
         qe_free(&is);
         url_exit();
     }
@@ -6781,6 +6865,8 @@
                 if (x1 == e->x2 && y1 == e->y1 && y2 >= e->y2) {
                     /* partial vertical split along the left border */
                     e->x2 = x2;
+                    e->flags &= ~WF_RSEPARATOR;
+                    e->flags |= s->flags & WF_RSEPARATOR;
                     y1 = e->y2;
                 } else
                 if (x2 == e->x1 && y1 == e->y1 && y2 >= e->y2) {
@@ -6816,7 +6902,7 @@
         do_refresh(qs->first_window);
 }
 
-void do_delete_other_windows(EditState *s)
+void do_delete_other_windows(EditState *s, int all)
 {
     QEmacsState *qs = s->qe_state;
     EditState *e, *e1;
@@ -6829,6 +6915,9 @@
         if (!e->minibuf && e != s)
             edit_close(&e);
     }
+    if (all) {
+        edit_close(&s);
+    } else {
     /* resize to whole screen */
     s->y1 = 0;
     s->x1 = 0;
@@ -6837,6 +6926,27 @@
     s->flags &= ~WF_RSEPARATOR;
     compute_client_area(s);
     do_refresh(s);
+    }
+}
+
+void do_hide_window(EditState *s, int set)
+{
+    if (set)
+        s->flags |= WF_HIDDEN;
+    else
+        s->flags &= ~WF_HIDDEN;
+}
+
+void do_delete_hidden_windows(EditState *s)
+{
+    QEmacsState *qs = s->qe_state;
+    EditState *e, *e1;
+
+    for (e = qs->first_window; e != NULL; e = e1) {
+        e1 = e->next_window;
+        if (e->flags & WF_HIDDEN)
+            edit_close(&e);
+    }
 }
 
 /* XXX: add minimum size test and refuse to split if reached */
@@ -6880,6 +6990,110 @@
     do_refresh(s);
 }
 
+void do_create_window(EditState *s, const char *filename, const char *layout)
+{
+    QEmacsState *qs = s->qe_state;
+    static const char * const names[] = {
+        "x1:", "y1:", "x2:", "y2:", "flags:", "wrap:",
+        "offset:", "offset.col:", "mark:", "mark.col:", "top:", "top.col:",
+        "active:",
+    };
+    int args[] = { 0, 0, 0, 0, WF_MODELINE, WRAP_LINE, 0, 0, 0, 0, 0, 0, 0  };
+    ModeDef *m = NULL;
+    int i, n, x1, y1, x2, y2, flags, wrap;
+    const char *p = layout;
+    EditBuffer *b1;
+
+    b1 = eb_find_file(filename);
+    if (!b1) {
+        put_status(s, "create_window: no such file loaded: %s", filename);
+        return;
+    }
+
+    for (n = 0; *p; n++) {
+        while (qe_isblank(*p))
+            p++;
+        for (i = 0; i < countof(names); i++) {
+            if (strstart(p, names[i], &p)) {
+                n = i;
+                break;
+            }
+        }
+        if (strstart(p, "mode:", &p)) {
+            m = qe_find_mode(p, 0);
+            break;
+        }
+        if (n >= countof(args))
+            break;
+
+        args[n] = strtol(p, (char **)&p, 0);
+        while (qe_isblank(*p))
+            p++;
+        if (*p == ',')
+            p++;
+    }
+    x1 = scale(args[0], qs->width, 1000);
+    y1 = scale(args[1], qs->height - qs->status_height, 1000);
+    x2 = scale(args[2], qs->width, 1000);
+    y2 = scale(args[3], qs->height - qs->status_height, 1000);
+    flags = args[4];
+    wrap = args[5];
+
+    s = edit_new(b1, x1, y1, x2 - x1, y2 - y1, flags);
+    if (m)
+        edit_set_mode(s, m);
+    s->wrap = wrap;
+    s->offset = clamp(eb_goto_pos(b1, args[6], args[7]), 0, b1->total_size);
+    s->b->mark = clamp(eb_goto_pos(b1, args[8], args[9]), 0, b1->total_size);
+    s->offset_top = clamp(eb_goto_pos(b1, args[10], args[11]), 0, 
b1->total_size);
+    if (args[12])
+        qs->active_window = s;
+
+    do_refresh(s);
+}
+
+void qe_save_window_layout(EditState *s, EditBuffer *b)
+{
+    QEmacsState *qs = s->qe_state;
+    const EditState *e;
+    int offset_row, offset_col;
+    int mark_row, mark_col;
+    int top_row, top_col;
+
+    eb_puts(b, "// window layout:\n");
+    /* Get rid of default window */
+    // XXX: should simplify layout management
+    // XXX: should save mark, offset, offset_top
+    eb_puts(b, "delete_other_windows();\n");
+    eb_puts(b, "hide_window();\n");
+    for (e = qs->first_window; e != NULL; e = e->next_window) {
+        if (*e->b->filename) {
+            eb_get_pos(e->b, &offset_row, &offset_col, e->offset);
+            eb_get_pos(e->b, &mark_row, &mark_col, e->b->mark);
+            eb_get_pos(e->b, &top_row, &top_col, e->offset_top);
+            eb_printf(b, "create_window(\"%s\", "
+                      "\"%d,%d,%d,%d flags:%d wrap:%d",
+                      e->b->filename,
+                      scale(e->x1, 1000, qs->width),
+                      scale(e->y1, 1000, qs->height - qs->status_height),
+                      scale(e->x2, 1000, qs->width),
+                      scale(e->y2, 1000, qs->height - qs->status_height),
+                      e->flags, e->wrap);
+            if (e->offset)
+                eb_printf(b, " offset:%d,%d", offset_row, offset_col);
+            if (e->b->mark)
+                eb_printf(b, " mark:%d,%d", mark_row, mark_col);
+            if (e->offset_top)
+                eb_printf(b, " top:%d,%d", top_row, top_col);
+            if (e == qs->active_window)
+                eb_printf(b, " active:1");
+            eb_printf(b, " mode:%s\");\n", e->mode->name);
+        }
+    }
+    eb_puts(b, "delete_hidden_windows();\n");
+    eb_putc(b, '\n');
+}
+
 /* help */
 
 void do_describe_key_briefly(EditState *s)
@@ -7627,6 +7841,8 @@
       { .func_noarg = show_usage }},
     { "no-init-file", "q", NULL, CMD_OPT_BOOL, "do not load config files",
       { .int_ptr = &no_init_file }},
+    { "use-session", "s", NULL, CMD_OPT_BOOL, "load and save session files",
+      { .int_ptr = &use_session_file }},
     { "ttycharset", "c", "CHARSET", CMD_OPT_ARG, "specify tty charset",
       { .func_arg = set_tty_charset }},
     { "user", "u", "USER", CMD_OPT_ARG, "load ~USER/.qe/config instead of your 
own",
@@ -7787,7 +8003,7 @@
     QEDisplay *dpy;
     int i, _optind;
 #if !defined(CONFIG_TINY) && !defined(CONFIG_WIN32)
-    int is_player;
+    int is_player, session_loaded = 0;
 #endif
 
     qs->ec.function = "qe-init";
@@ -7905,6 +8121,10 @@
 
     qe_event_init();
 
+#ifndef CONFIG_TINY
+    if (use_session_file)
+        session_loaded = !qe_load_session(s);
+#endif
     do_refresh(s);
 
     /* load file(s) */
@@ -7936,7 +8156,7 @@
     }
 
 #if !defined(CONFIG_TINY) && !defined(CONFIG_WIN32)
-    if (is_player && (_optind >= argc || S_ISDIR(s->b->st_mode))) {
+    if (is_player && !session_loaded && (_optind >= argc || 
S_ISDIR(s->b->st_mode))) {
         /* if player, go to directory mode by default if no file selected */
         do_dired(s);
     }

Index: qeconfig.h
===================================================================
RCS file: /sources/qemacs/qemacs/qeconfig.h,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -b -r1.54 -r1.55
--- qeconfig.h  27 Aug 2015 23:03:39 -0000      1.54
+++ qeconfig.h  10 Sep 2015 00:25:24 -0000      1.55
@@ -132,13 +132,16 @@
 
     CMD3( KEY_CTRLX(KEY_CTRL('f')), KEY_NONE,
           "find-file", do_find_file, ESsi, 0,
-          "s{Find file: }[file]|file|") /* u? */
+          "s{Find file: }[file]|file|"
+          "v") /* u? */
     CMD3( KEY_CTRL('x'), KEY_META('f'),
           "find-file-other-window", do_find_file_other_window, ESsi, 0,
-          "s{Find file: }[file]|file|") /* u? */
+          "s{Find file: }[file]|file|"
+          "v") /* u? */
     CMD3( KEY_CTRLX(KEY_CTRL('v')), KEY_NONE,
           "find-alternate-file", do_find_alternate_file, ESsi, 0,
-          "s{Find alternate file: }[file]|file|") /* u? */
+          "s{Find alternate file: }[file]|file|"
+          "v") /* u? */
     CMD2( KEY_CTRLX('i'), KEY_NONE,
           "insert-file", do_insert_file, ESs,
           "*s{Insert file: }[file]|file|") /* u? */
@@ -155,7 +158,8 @@
           "s{Switch to buffer: }[buffer]|buffer|")
     CMD3( KEY_CTRLX('k'), KEY_NONE,
           "kill-buffer", do_kill_buffer, ESsi, 0,
-          "s{Kill buffer: }[buffer]|buffer|")
+          "s{Kill buffer: }[buffer]|buffer|"
+          "v")
     CMD0( KEY_CTRLX(KEY_CTRL('q')), KEY_NONE,
           "toggle-read-only", do_toggle_read_only)
     CMD2( KEY_META('~'), KEY_NONE,
@@ -285,8 +289,14 @@
 #endif
     CMD1( KEY_CTRLX('0'), KEY_NONE,
           "delete-window", do_delete_window, 0)
-    CMD0( KEY_CTRLX('1'), KEY_NONE,
-          "delete-other-windows", do_delete_other_windows)
+    CMD1( KEY_CTRLX('1'), KEY_NONE,
+          "delete-other-windows", do_delete_other_windows, 0)
+    CMD1( KEY_NONE, KEY_NONE,
+          "delete-all-windows", do_delete_other_windows, 1)
+    CMD1( KEY_NONE, KEY_NONE,
+          "hide-window", do_hide_window, 1)
+    CMD0( KEY_NONE, KEY_NONE,
+          "delete-hidden-windows", do_delete_hidden_windows)
     CMD1( KEY_CTRLX('2'), KEY_NONE,
           "split-window-vertically", do_split_window, 0) /* u? */
     CMD1( KEY_CTRLX('3'), KEY_NONE,
@@ -295,6 +305,10 @@
           "toggle-full-screen", do_toggle_full_screen)
     CMD0( KEY_NONE, KEY_NONE,
           "toggle-mode-line", do_toggle_mode_line)
+    CMD2( KEY_NONE, KEY_NONE,
+          "create-window", do_create_window, ESss,
+          "s{Filename: }[file]|file|"
+          "s{Layout: }|layout|")
 
     /*---------------- Help ----------------*/
 
@@ -409,7 +423,8 @@
     /* other stuff */
     CMD3( KEY_NONE, KEY_NONE,
           "load-file-from-path", do_load_file_from_path, ESsi, 0,
-          "s{Load file from path: }|file|")
+          "s{Load file from path: }|file|"
+          "v")
     CMD2( KEY_NONE, KEY_NONE,
           "load-config-file", do_load_config_file, ESs,
           "s{Configuration file: }[file]|file|")

Index: variables.h
===================================================================
RCS file: /sources/qemacs/qemacs/variables.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- variables.h 30 Aug 2015 12:03:47 -0000      1.7
+++ variables.h 10 Sep 2015 00:25:24 -0000      1.8
@@ -47,6 +47,7 @@
 typedef struct VarDef VarDef;
 struct VarDef {
     const char *name;
+    unsigned int modified : 1;
     enum QVarDomain domain : 4;
     enum QVarType type : 4;
     enum QVarAccess rw : 2;
@@ -65,28 +66,29 @@
 };
 
 #define U_VAR_F(name, type, fun) \
-    { (name), VAR_SELF, type, VAR_RW, 0, { .num = 0 }, fun, NULL },
+    { (name), 0, VAR_SELF, type, VAR_RW, 0, { .num = 0 }, fun, NULL },
 #define G_VAR_F(name, var, type, rw, fun) \
-    { (name), VAR_GLOBAL, type, rw, 0, { .ptr = (void*)&(var) }, fun, NULL },
+    { (name), 0, VAR_GLOBAL, type, rw, 0, \
+      { .ptr = (void*)&(var) }, fun, NULL },
 #define S_VAR_F(name, fld, type, rw, fun) \
-    { (name), VAR_STATE, type, rw, sizeof(((QEmacsState*)0)->fld), \
+    { (name), 0, VAR_STATE, type, rw, sizeof(((QEmacsState*)0)->fld), \
       { .offset = offsetof(QEmacsState, fld) }, fun, NULL },
 #define B_VAR_F(name, fld, type, rw, fun) \
-    { (name), VAR_BUFFER, type, rw, sizeof(((EditBuffer*)0)->fld), \
+    { (name), 0, VAR_BUFFER, type, rw, sizeof(((EditBuffer*)0)->fld), \
       { .offset = offsetof(EditBuffer, fld) }, fun, NULL },
 #define W_VAR_F(name, fld, type, rw, fun) \
-    { (name), VAR_WINDOW, type, rw, sizeof(((EditState*)0)->fld), \
+    { (name), 0, VAR_WINDOW, type, rw, sizeof(((EditState*)0)->fld), \
       { .offset = offsetof(EditState, fld) }, fun, NULL },
 #define M_VAR_F(name, fld, type, rw, fun) \
-    { (name), VAR_MODE, type, rw, sizeof(((ModeDef*)0)->fld), \
+    { (name), 0, VAR_MODE, type, rw, sizeof(((ModeDef*)0)->fld), \
       { .offset = offsetof(ModeDef, fld) }, fun, NULL },
 
-#define U_VAR(name, type)        U_VAR_F(name, type, NULL)
-#define G_VAR(name,var,type,rw)  G_VAR_F(name,var,type,rw, NULL)
-#define S_VAR(name,fld,type,rw)  S_VAR_F(name,fld,type,rw, NULL)
-#define B_VAR(name,fld,type,rw)  B_VAR_F(name,fld,type,rw, NULL)
-#define W_VAR(name,fld,type,rw)  W_VAR_F(name,fld,type,rw, NULL)
-#define M_VAR(name,fld,type,rw)  M_VAR_F(name,fld,type,rw, NULL)
+#define U_VAR(name,type)         U_VAR_F(name, type, NULL)
+#define G_VAR(name,var,type,rw)  G_VAR_F(name, var, type, rw, NULL)
+#define S_VAR(name,fld,type,rw)  S_VAR_F(name, fld, type, rw, NULL)
+#define B_VAR(name,fld,type,rw)  B_VAR_F(name, fld, type, rw, NULL)
+#define W_VAR(name,fld,type,rw)  W_VAR_F(name, fld, type, rw, NULL)
+#define M_VAR(name,fld,type,rw)  M_VAR_F(name, fld, type, rw, NULL)
 
 void qe_register_variables(VarDef *vars, int count);
 VarDef *qe_find_variable(const char *name);
@@ -101,3 +103,4 @@
 
 void do_set_variable(EditState *s, const char *name, const char *value);
 void do_show_variable(EditState *s, const char *name);
+void qe_save_variables(EditState *s, EditBuffer *b);



reply via email to

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