[vte/wip/fedora-0-64: 6/10] Support preexec notifications from an interactive shell




commit f4256cc3fa02ccc3d711c2915b4b14dee5b2cdfd
Author: Debarshi Ray <debarshir gnome org>
Date:   Mon Mar 22 19:02:31 2021 +0100

    Support preexec notifications from an interactive shell
    
    Add sequences
      OSC 777 ; preexec BEL
      OSC 777 ; preexec ST
    
    that can be used from an interactive shell's preexec hook to notify
    the terminal emulator that a new command is about to be executed.
    Examples of such hooks are Bash's PS0 and Zsh's preexec.
    
    The OSC 777 escape sequence is taken from Enlightenment's Terminology:
    https://phab.enlightenment.org/T1765
    
    https://bugzilla.gnome.org/show_bug.cgi?id=711059
    https://bugzilla.gnome.org/show_bug.cgi?id=711060

 src/vte.cc            |  6 ++++++
 src/vte.sh.in         |  2 +-
 src/vte/vteterminal.h |  3 ++-
 src/vtegtk.cc         | 18 ++++++++++++++++++
 src/vtegtk.hh         |  1 +
 src/vteinternal.hh    |  1 +
 src/vteseq.cc         |  4 ++++
 7 files changed, 33 insertions(+), 2 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index c3046ddc..a950bd87 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -10164,6 +10164,12 @@ Terminal::emit_pending_signals()
                               m_notification_body.c_str());
         }
 
+       if (m_pending_changes & vte::to_integral(PendingChanges::SHELL_PREEXEC)) {
+                _vte_debug_print (VTE_DEBUG_SIGNALS,
+                                  "Emitting `shell-preexec'.\n");
+                g_signal_emit(freezer.get(), signals[SIGNAL_SHELL_PREEXEC], 0);
+        }
+
         m_pending_changes = 0;
 
        /* Flush any pending "inserted" signals. */
diff --git a/src/vte.sh.in b/src/vte.sh.in
index 2c6f6681..fc33a63f 100644
--- a/src/vte.sh.in
+++ b/src/vte.sh.in
@@ -38,7 +38,7 @@ __vte_prompt_command() {
 
 case "$TERM" in
   xterm*|vte*)
-    [ -n "${BASH_VERSION:-}" ] && PROMPT_COMMAND="__vte_prompt_command"
+    [ -n "${BASH_VERSION:-}" ] && PROMPT_COMMAND="__vte_prompt_command" && PS0=$(printf 
"\033]777;preexec\033\\")
     [ -n "${ZSH_VERSION:-}"  ] && precmd_functions+=(__vte_osc7)
     ;;
 esac
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index ea4fba19..1fb8b061 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -103,9 +103,10 @@ struct _VteTerminalClass {
        void (*bell)(VteTerminal* terminal);
 
        void (*notification_received)(VteTerminal* terminal, const gchar *summary, const gchar *body);
+       void (*shell_preexec)(VteTerminal* terminal);
 
         /* Padding for future expansion. */
-        gpointer padding[15];
+        gpointer padding[14];
 
         VteTerminalClassPrivate *priv;
 };
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index c5c8eb2f..e2a6462f 100644
--- a/src/vtegtk.cc
+++ b/src/vtegtk.cc
@@ -990,6 +990,7 @@ vte_terminal_class_init(VteTerminalClass *klass)
        klass->encoding_changed = NULL;
        klass->char_size_changed = NULL;
        klass->notification_received = NULL;
+       klass->shell_preexec = NULL;
        klass->window_title_changed = NULL;
        klass->icon_title_changed = NULL;
        klass->selection_changed = NULL;
@@ -1091,6 +1092,23 @@ vte_terminal_class_init(VteTerminalClass *klass)
                              G_TYPE_NONE,
                              2, G_TYPE_STRING, G_TYPE_STRING);
 
+        /**
+         * VteTerminal::shell-preexec:
+         * @vteterminal: the object which received the signal
+         *
+         * Emitted when the interactive shell has read in a complete
+         * command and is about to execute it.
+         */
+        signals[SIGNAL_SHELL_PREEXEC] =
+                g_signal_new(I_("shell-preexec"),
+                             G_OBJECT_CLASS_TYPE(klass),
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET(VteTerminalClass, shell_preexec),
+                             NULL,
+                             NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
+
         /**
          * VteTerminal::window-title-changed:
          * @vteterminal: the object which received the signal
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index 24063c30..e90e183e 100644
--- a/src/vtegtk.hh
+++ b/src/vtegtk.hh
@@ -52,6 +52,7 @@ enum {
         SIGNAL_RESIZE_WINDOW,
         SIGNAL_RESTORE_WINDOW,
         SIGNAL_SELECTION_CHANGED,
+        SIGNAL_SHELL_PREEXEC,
         SIGNAL_TEXT_DELETED,
         SIGNAL_TEXT_INSERTED,
         SIGNAL_TEXT_MODIFIED,
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index fd1a8b90..bb98f8bc 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -640,6 +640,7 @@ public:
                 CWD   = 1u << 1,
                 CWF   = 1u << 2,
                 NOTIFICATION = 1u << 3,
+                SHELL_PREEXEC = 1u << 4,
         };
         unsigned m_pending_changes{0};
 
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 7ab65b6d..51ca37bd 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -1402,6 +1402,10 @@ Terminal::handle_urxvt_extension(vte::parser::Sequence const& seq,
                 m_notification_body = *token;
                 return;
         }
+
+        if (*token == "preexec") {
+                m_pending_changes |= vte::to_integral(PendingChanges::SHELL_PREEXEC);
+        }
 }
 
 bool


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