qemacs-commit
[Top][All Lists]
Advanced

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

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


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs buffer.c qe.c qe.h shell.c
Date: Mon, 03 Mar 2014 23:35:47 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/03/03 23:35:47

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

Log message:
        Fix inconsistencies in shell mode
        
        * clear interactive window flag upon mode change
        * enable interactive mode upon vertical cursor movement
        * add more checks for private data consistency
        * free shell data upon process exit in non interactive shell buffers
        * added shell-command command on M-!
        * make kill_buffer_noconfirm() public to remove buffer safely

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/buffer.c?cvsroot=qemacs&r1=1.74&r2=1.75
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.c?cvsroot=qemacs&r1=1.151&r2=1.152
http://cvs.savannah.gnu.org/viewcvs/qemacs/qe.h?cvsroot=qemacs&r1=1.143&r2=1.144
http://cvs.savannah.gnu.org/viewcvs/qemacs/shell.c?cvsroot=qemacs&r1=1.85&r2=1.86

Patches:
Index: buffer.c
===================================================================
RCS file: /sources/qemacs/qemacs/buffer.c,v
retrieving revision 1.74
retrieving revision 1.75
diff -u -b -r1.74 -r1.75
--- buffer.c    10 Feb 2014 21:27:53 -0000      1.74
+++ buffer.c    3 Mar 2014 23:35:46 -0000       1.75
@@ -586,6 +586,7 @@
         eb_free_style_buffer(b);
 
        qe_free(&b->saved_data);
+       qe_free(&b->priv_data);
         qe_free(bp);
     }
 }

Index: qe.c
===================================================================
RCS file: /sources/qemacs/qemacs/qe.c,v
retrieving revision 1.151
retrieving revision 1.152
diff -u -b -r1.151 -r1.152
--- qe.c        1 Mar 2014 19:24:02 -0000       1.151
+++ qe.c        3 Mar 2014 23:35:46 -0000       1.152
@@ -1703,6 +1703,7 @@
     /* if a mode is already defined, try to close it */
     if (s->mode) {
         /* save mode data if necessary */
+        s->interactive = 0;
         if (!saved_data) {
             saved_data = s->mode->mode_save_data(s);
             if (saved_data)
@@ -5494,8 +5495,18 @@
     s->b->modified = (argval != NO_ARG);
 }
 
-static void kill_buffer_confirm_cb(void *opaque, char *reply);
-static void kill_buffer_noconfirm(EditBuffer *b);
+static void kill_buffer_confirm_cb(void *opaque, char *reply)
+{
+    int yes_replied;
+
+    if (!reply)
+        return;
+    yes_replied = strequal(reply, "yes");
+    qe_free(&reply);
+    if (!yes_replied)
+        return;
+    kill_buffer_noconfirm(opaque);
+}
 
 void do_kill_buffer(EditState *s, const char *bufname)
 {
@@ -5518,20 +5529,7 @@
     }
 }
 
-static void kill_buffer_confirm_cb(void *opaque, char *reply)
-{
-    int yes_replied;
-
-    if (!reply)
-        return;
-    yes_replied = strequal(reply, "yes");
-    qe_free(&reply);
-    if (!yes_replied)
-        return;
-    kill_buffer_noconfirm(opaque);
-}
-
-static void kill_buffer_noconfirm(EditBuffer *b)
+void kill_buffer_noconfirm(EditBuffer *b)
 {
     QEmacsState *qs = &qe_state;
     EditState *e;
@@ -6915,7 +6913,7 @@
     *show_ptr = 0;
     b = eb_find("*Help*");
     if (b) {
-        eb_delete(b, 0, b->total_size);
+        eb_clear(b);
     } else {
         b = eb_new("*Help*", BF_UTF8);
         *show_ptr = 1;

Index: qe.h
===================================================================
RCS file: /sources/qemacs/qemacs/qe.h,v
retrieving revision 1.143
retrieving revision 1.144
diff -u -b -r1.143 -r1.144
--- qe.h        1 Mar 2014 22:37:26 -0000       1.143
+++ qe.h        3 Mar 2014 23:35:46 -0000       1.144
@@ -1690,6 +1690,7 @@
 void do_refresh_complete(EditState *s);
 void do_kill_buffer(EditState *s, const char *bufname1);
 void switch_to_buffer(EditState *s, EditBuffer *b);
+void kill_buffer_noconfirm(EditBuffer *b);
 
 /* text mode */
 

Index: shell.c
===================================================================
RCS file: /sources/qemacs/qemacs/shell.c,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -b -r1.85 -r1.86
--- shell.c     10 Feb 2014 21:21:40 -0000      1.85
+++ shell.c     3 Mar 2014 23:35:47 -0000       1.86
@@ -657,14 +657,16 @@
 #endif
 }
 
-static ShellState *shell_get_state(EditState *e)
+static ShellState *shell_get_state(EditState *e, int status)
 {
     ShellState *s = e->b->priv_data;
 
     if (s && s->signature == &shell_signature)
         return s;
 
+    if (status)
     put_status(e, "Not a shell buffer");
+
     return NULL;
 }
 
@@ -674,11 +676,10 @@
 {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
-        return;
-
-    if (e->interactive)
+    if (e->interactive) {
+        if ((s = shell_get_state(e, 0)) != NULL)
         e->offset = s->cur_offset;
+    }
 }
 
 static void shell_key(void *opaque, int key)
@@ -1272,6 +1273,40 @@
     dpy_flush(qs->screen);
 }
 
+static void shell_close(EditBuffer *b)
+{
+    ShellState *s = b->priv_data;
+    int status;
+
+    if (!s || s->signature != &shell_signature)
+        return;
+
+    eb_free_callback(b, eb_offset_callback, &s->cur_offset);
+
+    if (s->pid != -1) {
+        kill(s->pid, SIGINT);
+        /* wait first 100 ms */
+        usleep(100 * 1000);
+        if (waitpid(s->pid, &status, WNOHANG) != s->pid) {
+            /* if still not killed, then try harder (useful for
+               shells) */
+            kill(s->pid, SIGKILL);
+            /* CG: should add timeout facility and error message */
+            while (waitpid(s->pid, &status, 0) != s->pid)
+                continue;
+        }
+       set_pid_handler(s->pid, NULL, NULL);
+        s->pid = -1;
+    }
+    if (s->pty_fd >= 0) {
+        set_read_handler(s->pty_fd, NULL, NULL);
+        s->pty_fd = -1;
+    }
+    qe_free(&b->priv_data);
+    if (b->close == shell_close)
+        b->close = NULL;
+}
+
 static void shell_pid_cb(void *opaque, int status)
 {
     ShellState *s = opaque;
@@ -1286,7 +1321,7 @@
     b = s->b;
     qs = s->qe_state;
 
-    *buf = 0;
+    *buf = '\0';
     if (s->caption) {
         time_t ti;
         char *time_str;
@@ -1334,38 +1369,13 @@
         if (e->b == b)
             e->interactive = 0;
     }
+    if (!(s->shell_flags & SF_INTERACTIVE)) {
+        shell_close(b);
+    }
     edit_display(qs);
     dpy_flush(qs->screen);
 }
 
-static void shell_close(EditBuffer *b)
-{
-    ShellState *s = b->priv_data;
-    int status;
-
-    eb_free_callback(b, eb_offset_callback, &s->cur_offset);
-
-    if (s->pid != -1) {
-        kill(s->pid, SIGINT);
-        /* wait first 100 ms */
-        usleep(100 * 1000);
-        if (waitpid(s->pid, &status, WNOHANG) != s->pid) {
-            /* if still not killed, then try harder (useful for
-               shells) */
-            kill(s->pid, SIGKILL);
-            /* CG: should add timeout facility and error message */
-            while (waitpid(s->pid, &status, 0) != s->pid)
-                continue;
-        }
-       set_pid_handler(s->pid, NULL, NULL);
-        s->pid = -1;
-    }
-    if (s->pty_fd >= 0) {
-        set_read_handler(s->pty_fd, NULL, NULL);
-    }
-    qe_free(&b->priv_data);
-}
-
 EditBuffer *new_shell_buffer(EditBuffer *b0, const char *bufname,
                              const char *caption, const char *cmd,
                              int shell_flags)
@@ -1503,8 +1513,6 @@
 
     b->default_mode = &shell_mode;
     switch_to_buffer(s, b);
-    s->interactive = 1;
-    //edit_set_mode(s, &shell_mode);
 
     put_status(s, "Press C-o to toggle between shell/edit mode");
 }
@@ -1557,12 +1565,12 @@
 
 static void shell_move_left_right(EditState *e, int dir)
 {
+    if (e->interactive) {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
+        if (!(s = shell_get_state(e, 1)))
         return;
 
-    if (e->interactive) {
         tty_write(s, dir > 0 ? s->kcuf1 : s->kcub1, -1);
     } else {
         text_move_left_right_visual(e, dir);
@@ -1571,12 +1579,12 @@
 
 static void shell_move_word_left_right(EditState *e, int dir)
 {
+    if (e->interactive) {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
+        if (!(s = shell_get_state(e, 1)))
         return;
 
-    if (e->interactive) {
         tty_write(s, dir > 0 ? "\033f" : "\033b", -1);
     } else {
         text_move_word_left_right(e, dir);
@@ -1587,13 +1595,15 @@
 {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
+    if (!(s = shell_get_state(e, 1)))
         return;
 
     if (e->interactive) {
         tty_write(s, dir > 0 ? s->kcud1 : s->kcuu1, -1);
     } else {
         text_move_up_down(e, dir);
+        if (s->shell_flags & SF_INTERACTIVE)
+            e->interactive = (e->offset == s->cur_offset);
     }
 }
 
@@ -1601,25 +1611,26 @@
 {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
+    if (!(s = shell_get_state(e, 1)))
         return;
 
     e->interactive = 0;
     text_scroll_up_down(e, dir);
+    if (s->shell_flags & SF_INTERACTIVE)
     e->interactive = (e->offset == s->cur_offset);
 }
 
 static void shell_move_bol(EditState *e)
 {
-    ShellState *s;
-
-    if (!(s = shell_get_state(e)))
-        return;
-
     /* XXX: exit shell interactive mode on home / ^A */
     e->interactive = 0;
 
     if (e->interactive) {
+        ShellState *s;
+
+        if (!(s = shell_get_state(e, 1)))
+            return;
+
         tty_write(s, "\001", 1); /* Control-A */
     } else {
         text_move_bol(e);
@@ -1630,7 +1641,7 @@
 {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
+    if (!(s = shell_get_state(e, 1)))
         return;
 
     if (e->interactive) {
@@ -1638,6 +1649,7 @@
     } else {
         text_move_eol(e);
         /* XXX: restore shell interactive mode on end / ^E */
+        if (s->shell_flags & SF_INTERACTIVE)
         e->interactive = (e->offset == s->cur_offset);
     }
 }
@@ -1646,12 +1658,13 @@
 {
     char buf[10];
     int len;
+
+    if (e->interactive) {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
+        if (!(s = shell_get_state(e, 1)))
         return;
 
-    if (e->interactive) {
         if (c >= KEY_META(0) && c <= KEY_META(0xff)) {
             buf[0] = '\033';
             buf[1] = c - KEY_META(0);
@@ -1705,11 +1718,14 @@
 {
     ShellState *s;
 
-    if (!(s = shell_get_state(e)))
+    if (!(s = shell_get_state(e, 1)))
         return;
 
-    e->interactive = !e->interactive;
     if (e->interactive) {
+        e->interactive = 0;
+    } else
+    if (s->shell_flags & SF_INTERACTIVE) {
+        e->interactive = 1;
         if (s->grab_keys)
             qe_grab_keys(shell_key, s);
     }
@@ -1720,6 +1736,27 @@
 #endif
 }
 
+static void do_shell_command(EditState *e, const char *cmd)
+{
+    EditBuffer *b;
+
+    /* if the buffer already exists, kill it */
+    b = eb_find("*shell command output*");
+    if (b) {
+        kill_buffer_noconfirm(b);
+    }
+
+    /* create new buffer */
+    b = new_shell_buffer(NULL, "*shell command output*", NULL, cmd,
+                         SF_COLOR | SF_INFINITE);
+    if (!b)
+        return;
+
+    /* XXX: try to split window if necessary */
+    switch_to_buffer(e, b);
+    edit_set_mode(e, &pager_mode);
+}
+
 static void do_compile(EditState *e, const char *cmd)
 {
     EditBuffer *b;
@@ -1727,9 +1764,7 @@
     /* if the buffer already exists, kill it */
     b = eb_find("*compilation*");
     if (b) {
-        /* XXX: e should not become invalid */
-        b->modified = 0;
-        do_kill_buffer(e, "*compilation*");
+        kill_buffer_noconfirm(b);
     }
 
     if (!cmd || !*cmd)
@@ -1888,6 +1923,9 @@
 static CmdDef shell_global_commands[] = {
     CMD2( KEY_CTRLXRET('\r'), KEY_NONE,
           "shell", do_shell, ESi, "ui")
+    CMD2( KEY_META('!'), KEY_NONE,
+          "shell-command", do_shell_command, ESs,
+          "s{Shell command: }|shell-command|")
     CMD2( KEY_NONE, KEY_NONE,
           "ssh", do_ssh, ESs,
           "s{Open connection to (host or address@hidden: }|ssh|")
@@ -1917,20 +1955,26 @@
     return 0;
 }
 
-static int shell_mode_init(EditState *s, ModeSavedData *saved_data)
+static int shell_mode_init(EditState *e, ModeSavedData *saved_data)
 {
-    text_mode_init(s, saved_data);
-    s->b->tab_width = 8;
-    s->wrap = WRAP_TRUNCATE;
-    s->interactive = 1;
+    ShellState *s;
+
+    if (!(s = shell_get_state(e, 1)))
+        return -1;
+
+    text_mode_init(e, saved_data);
+    e->b->tab_width = 8;
+    e->wrap = WRAP_TRUNCATE;
+    if (s->shell_flags & SF_INTERACTIVE)
+        e->interactive = 1;
     return 0;
 }
 
-static int pager_mode_init(EditState *s, ModeSavedData *saved_data)
+static int pager_mode_init(EditState *e, ModeSavedData *saved_data)
 {
-    text_mode_init(s, saved_data);
-    s->b->tab_width = 8;
-    s->wrap = WRAP_TRUNCATE;
+    text_mode_init(e, saved_data);
+    e->b->tab_width = 8;
+    e->wrap = WRAP_TRUNCATE;
     return 0;
 }
 



reply via email to

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