From f3c77d11af65f3b319b1784b4c3cf08c51aa7997 Mon Sep 17 00:00:00 2001
From: Dima Kogan <dima@secretsauce.net>
Date: Mon, 5 Dec 2016 21:42:20 -0800
Subject: [PATCH] stash

---
 lisp/comint.el           |  6 ++++-
 lisp/emacs-lisp/debug.el | 54 ++++++++++++++++++++++++++++++++++++++++
 lisp/shell.el            |  2 ++
 src/data.c               | 50 +++++++++++++++++++++++++++++++++++++
 src/fns.c                |  4 +++
 5 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/lisp/comint.el b/lisp/comint.el
index b23f72ed618..c82c3d09df3 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -1879,6 +1879,7 @@ Similarly for Soar, Scheme, etc."
           (let ((echo-len (- comint-last-input-end
                              comint-last-input-start)))
             ;; Wait for all input to be echoed:
+            
             (while (and (> (+ comint-last-input-end echo-len)
                            (point-max))
                         (accept-process-output proc)
@@ -1890,6 +1891,7 @@ Similarly for Soar, Scheme, etc."
                           ;; (+ comint-last-input-start
                           ;;    (- (point-max) comint-last-input-end))
                           nil comint-last-input-end (point-max)))))
+            
             (if (and
                  (<= (+ comint-last-input-end echo-len)
                      (point-max))
@@ -1901,6 +1903,7 @@ Similarly for Soar, Scheme, etc."
                 ;; Certain parts of the text to be deleted may have
                 ;; been mistaken for prompts.  We have to prevent
                 ;; problems when `comint-prompt-read-only' is non-nil.
+                
                 (let ((inhibit-read-only t))
                   (delete-region comint-last-input-end
                                  (+ comint-last-input-end echo-len))
@@ -1909,6 +1912,7 @@ Similarly for Soar, Scheme, etc."
                       (goto-char comint-last-input-end)
                       (comint-update-fence)))))))
 
+        
         ;; This used to call comint-output-filter-functions,
         ;; but that scrolled the buffer in undesirable ways.
         (run-hook-with-args 'comint-output-filter-functions "")))))
@@ -2666,7 +2670,7 @@ This command is like `M-.' in bash."
   (set-marker comint-insert-previous-argument-last-start-pos (point))
   ;; Insert the argument.
   (let ((input-string (comint-previous-input-string 0)))
-    (when (string-match "[ \t\n]*&" input-string)
+    (when (string-match "[ \t\n]*&[ \t\n]*$" input-string)
       ;; strip terminating '&'
       (setq input-string (substring input-string 0 (match-beginning 0))))
     (insert (comint-arguments input-string index index)))
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el
index cb77148c285..faa323f733a 100644
--- a/lisp/emacs-lisp/debug.el
+++ b/lisp/emacs-lisp/debug.el
@@ -816,6 +816,60 @@ Redefining FUNCTION also cancels it."
               '((depth . -100)))
   function)
 
+;;;###autoload
+;; (defun debug-on-set (symbol)
+;;   "Request FUNCTION to invoke debugger each time it is called.
+
+;; When called interactively, prompt for FUNCTION in the minibuffer.
+
+;; This works by modifying the definition of FUNCTION.  If you tell the
+;; debugger to continue, FUNCTION's execution proceeds.  If FUNCTION is a
+;; normal function or a macro written in Lisp, you can also step through
+;; its execution.  FUNCTION can also be a primitive that is not a special
+;; form, in which case stepping is not possible.  Break-on-entry for
+;; primitive functions only works when that function is called from Lisp.
+
+;; Use \\[cancel-debug-on-entry] to cancel the effect of this command.
+;; Redefining FUNCTION also cancels it."
+;;   (interactive
+;;    (let ((v (variable-at-point))
+;; 	 (enable-recursive-minibuffers t)
+;;          (orig-buffer (current-buffer))
+;; 	 val)
+;;      (setq val (completing-read
+;;                 (if (symbolp v)
+;;                     (format
+;;                      "Debug on set to symbol (default %s): " v)
+;;                   "Debug on set to symbol: ")
+;;                 #'help--symbol-completion-table
+;;                 (lambda (vv)
+;;                   ;; In case the variable only exists in the buffer
+;;                   ;; the command we switch back to that buffer before
+;;                   ;; we examine the variable.
+;;                   (with-current-buffer orig-buffer
+;;                     (or (get vv 'variable-documentation)
+;;                         (and (boundp vv) (not (keywordp vv))))))
+;;                 t nil nil
+;;                 (if (symbolp v) (symbol-name v))))
+;;      (list (if (equal val "")
+;; 	       v (intern val)))))
+
+
+
+;;   (interactive
+;;    (let* ((var-default (variable-at-point))
+;;           (var (completing-read
+;; 		(if var-default
+;; 		    (format "Debug on set to symbol (default %s): " var-default)
+;; 		  "Debug on set to symbol: ")
+;; 		nil
+;; 		#'boundp
+;; 		t nil nil (symbol-name var-default))))
+;;      (list (if (equal var "") var-default (intern var)))))
+;;   (advice-add function :before #'debug--implement-debug-on-entry
+;;               '((depth . -100)))
+;;   function)
+
 (defun debug--function-list ()
   "List of functions currently set for debug on entry."
   (let ((funs '()))
diff --git a/lisp/shell.el b/lisp/shell.el
index c8a8555d632..c7ba64ecf4e 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -1000,6 +1000,8 @@ command again."
       (let ((pt (point))
 	    (regexp
 	     (concat
+              ;; comint-process-echoes is the thing that breaks the
+              ;; throbber
 	      (if comint-process-echoes
 		  ;; Skip command echo if the process echoes
 		  (concat "\\(" (regexp-quote shell-dirstack-query) "\n\\)")
diff --git a/src/data.c b/src/data.c
index 8e07bf01b44..26ff9948828 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1304,6 +1304,56 @@ set_internal (Lisp_Object symbol, Lisp_Object newval, Lisp_Object where,
     default: emacs_abort ();
     }
 
+
+  const char* symname = SDATA(sym->name);
+
+  if( EQ(Vwatch_object, symbol) )
+  {
+      static int nest_level = 0;
+      if(nest_level++ == 0)
+      {
+          switch(sym->redirect)
+          {
+          case SYMBOL_PLAINVAL:
+              {
+                  AUTO_STRING (format, "Setting symbol '%s'; redirect: SYMBOL_PLAINVAL");
+                  CALLN (Fmessage, format, SYMBOL_NAME (symbol));
+                  break;
+              }
+          case SYMBOL_VARALIAS:
+              {
+                  AUTO_STRING (format, "Setting symbol '%s'; redirect: SYMBOL_VARALIAS");
+                  CALLN (Fmessage, format, SYMBOL_NAME (symbol));
+                  break;
+              }
+          case SYMBOL_LOCALIZED:
+              {
+                  AUTO_STRING (format, "Setting symbol '%s'; redirect: SYMBOL_LOCALIZED");
+                  CALLN (Fmessage, format, SYMBOL_NAME (symbol));
+                  break;
+              }
+          case SYMBOL_FORWARDED:
+              {
+                  AUTO_STRING (format, "Setting symbol '%s'; redirect: SYMBOL_FORWARDED");
+                  CALLN (Fmessage, format, SYMBOL_NAME (symbol));
+                  break;
+              }
+
+          default:
+              {
+                  AUTO_STRING (format, "Setting symbol '%s'; redirect: UNKNOWN");
+                  CALLN (Fmessage, format, SYMBOL_NAME (symbol));
+                  break;
+              }
+          }
+      }
+      nest_level--;
+  }
+
+
+
+
+
  start:
   switch (sym->redirect)
     {
diff --git a/src/fns.c b/src/fns.c
index 136a2198c2c..9eabc1414f4 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -5120,6 +5120,10 @@ On some platforms, file selection dialogs are also enabled if this is
 non-nil.  */);
   use_dialog_box = 1;
 
+  DEFVAR_LISP("watch-object", Vwatch_object,
+	       doc: /* Symbol to watch.  */);
+  Vwatch_object = Qnil;
+
   DEFVAR_BOOL ("use-file-dialog", use_file_dialog,
     doc: /* Non-nil means mouse commands use a file dialog to ask for files.
 This applies to commands from menus and tool bar buttons even when
-- 
2.39.5