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




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

    Support precmd notifications from an interactive shell
    
    Add sequences
      OSC 777 ; precmd BEL
      OSC 777 ; precmd ST
    
    that can be used from an interactive shell's precmd hook to notify the
    terminal emulator that a first level prompt is about to be shown.
    Examples of such hooks are Bash's PROMPT_COMMAND and Zsh's precmd.
    
    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, 32 insertions(+), 3 deletions(-)
---
diff --git a/src/vte.cc b/src/vte.cc
index a950bd87..90488beb 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -10170,6 +10170,12 @@ Terminal::emit_pending_signals()
                 g_signal_emit(freezer.get(), signals[SIGNAL_SHELL_PREEXEC], 0);
         }
 
+       if (m_pending_changes & vte::to_integral(PendingChanges::SHELL_PRECMD)) {
+                _vte_debug_print (VTE_DEBUG_SIGNALS,
+                                  "Emitting `shell-precmd'.\n");
+                g_signal_emit(freezer.get(), signals[SIGNAL_SHELL_PRECMD], 0);
+        }
+
         m_pending_changes = 0;
 
        /* Flush any pending "inserted" signals. */
diff --git a/src/vte.sh.in b/src/vte.sh.in
index fc33a63f..359afbc4 100644
--- a/src/vte.sh.in
+++ b/src/vte.sh.in
@@ -32,7 +32,7 @@ __vte_prompt_command() {
   local pwd='~'
   [ "$PWD" != "$HOME" ] && pwd=${PWD/#$HOME\//\~\/}
   pwd="${pwd//[[:cntrl:]]}"
-  printf '\033]777;notify;Command completed;%s\033\\\033]0;%s@%s:%s\033\\' "${command}" "${USER}" 
"${HOSTNAME%%.*}" "${pwd}"
+  printf '\033]777;notify;Command completed;%s\033\\\033]777;precmd\033\\\033]0;%s@%s:%s\033\\' "${command}" 
"${USER}" "${HOSTNAME%%.*}" "${pwd}"
   __vte_osc7
 }
 
diff --git a/src/vte/vteterminal.h b/src/vte/vteterminal.h
index 1fb8b061..0b77566a 100644
--- a/src/vte/vteterminal.h
+++ b/src/vte/vteterminal.h
@@ -103,10 +103,11 @@ struct _VteTerminalClass {
        void (*bell)(VteTerminal* terminal);
 
        void (*notification_received)(VteTerminal* terminal, const gchar *summary, const gchar *body);
+       void (*shell_precmd)(VteTerminal* terminal);
        void (*shell_preexec)(VteTerminal* terminal);
 
         /* Padding for future expansion. */
-        gpointer padding[14];
+        gpointer padding[13];
 
         VteTerminalClassPrivate *priv;
 };
diff --git a/src/vtegtk.cc b/src/vtegtk.cc
index e2a6462f..4b71437d 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_precmd = NULL;
        klass->shell_preexec = NULL;
        klass->window_title_changed = NULL;
        klass->icon_title_changed = NULL;
@@ -1092,6 +1093,23 @@ vte_terminal_class_init(VteTerminalClass *klass)
                              G_TYPE_NONE,
                              2, G_TYPE_STRING, G_TYPE_STRING);
 
+        /**
+         * VteTerminal::shell-precmd:
+         * @vteterminal: the object which received the signal
+         *
+         * Emitted right before an interactive shell shows a
+         * first-level prompt.
+         */
+        signals[SIGNAL_SHELL_PRECMD] =
+                g_signal_new(I_("shell-precmd"),
+                             G_OBJECT_CLASS_TYPE(klass),
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET(VteTerminalClass, shell_precmd),
+                             NULL,
+                             NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 0);
+
         /**
          * VteTerminal::shell-preexec:
          * @vteterminal: the object which received the signal
diff --git a/src/vtegtk.hh b/src/vtegtk.hh
index e90e183e..93a6dde3 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_PRECMD,
         SIGNAL_SHELL_PREEXEC,
         SIGNAL_TEXT_DELETED,
         SIGNAL_TEXT_INSERTED,
diff --git a/src/vteinternal.hh b/src/vteinternal.hh
index bb98f8bc..25253c0a 100644
--- a/src/vteinternal.hh
+++ b/src/vteinternal.hh
@@ -641,6 +641,7 @@ public:
                 CWF   = 1u << 2,
                 NOTIFICATION = 1u << 3,
                 SHELL_PREEXEC = 1u << 4,
+                SHELL_PRECMD = 1u << 5,
         };
         unsigned m_pending_changes{0};
 
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 51ca37bd..10b494bd 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -1403,7 +1403,9 @@ Terminal::handle_urxvt_extension(vte::parser::Sequence const& seq,
                 return;
         }
 
-        if (*token == "preexec") {
+        if (*token == "precmd") {
+                m_pending_changes |= vte::to_integral(PendingChanges::SHELL_PRECMD);
+        } else if (*token == "preexec") {
                 m_pending_changes |= vte::to_integral(PendingChanges::SHELL_PREEXEC);
         }
 }


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