commit 4a9d8bdca3e502c1e87c4c50df3926c629475d39 (HEAD, refs/remotes/origin/master) Author: Robert Pluim Date: Tue Oct 22 09:31:15 2019 +0200 Show stash counts in button in vc-dir Based on suggestions from Mattias Engdegård. * lisp/vc/vc-git.el (vc-git--make-button-text): New function to generate text for stash button. (vc-git-make-stash-button): Show stash counts. Delete and recreate button when toggling. (vc-git-dir-extra-headers): Pass counts to vc-git-make-stash-button. Treat stash count <= vc-git-show-stash as equivalent to showing entire list. diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 70f5399073..ce8e57df76 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -650,17 +650,34 @@ or an empty string if none." (define-key map "S" 'vc-git-stash-snapshot) map)) -(defun vc-git-make-stash-button () - (make-text-button "Show/hide stashes" nil - 'action - (lambda (&rest _ignore) - (let* ((inhibit-read-only t) - (start (next-single-property-change (point-min) 'vc-git-hideable)) - (end (next-single-property-change start 'vc-git-hideable))) - (add-text-properties - start end - `(invisible ,(not (get-text-property start 'invisible)))))) - 'help-echo "mouse-2, RET: Show/hide stashes")) +(defun vc-git--make-button-text (show count1 count2) + (if show + (format "Show all stashes (%s)" count2) + (if (= count1 count2) + (format "Hide all stashes (%s)" count2) + (format "Show %s stash%s (of %s)" count1 (if (= count1 1) "" "es") count2)))) + +(defun vc-git-make-stash-button (show count1 count2) + (let ((orig-text (vc-git--make-button-text show count1 count2))) + (make-text-button + orig-text nil + 'action + (lambda (counts) + (let* ((inhibit-read-only t) + (start (next-single-property-change + (point-min) 'vc-git-hideable)) + (end (next-single-property-change + start 'vc-git-hideable)) + (state (get-text-property start 'invisible))) + (add-text-properties + start end + `(invisible ,(not state))) + (save-excursion + (delete-region (button-start (point)) (button-end (point))) + (insert (vc-git-make-stash-button + (not state) (car counts) (cdr counts)))))) + 'button-data (cons count1 count2) + 'help-echo "mouse-2, RET: Show/hide stashes"))) (defvar vc-git-stash-menu-map (let ((map (make-sparse-keymap "Git Stash"))) @@ -707,14 +724,18 @@ or an empty string if none." (setq remote-url (match-string 1 remote-url)))) (setq branch "not (detached HEAD)")) (when stash-list - (let* ((limit + (let* ((len (length stash-list)) + (limit (if (integerp vc-git-show-stash) - (min vc-git-show-stash (length stash-list)) - (length stash-list))) + (min vc-git-show-stash len) + len)) (shown-stashes (cl-subseq stash-list 0 limit)) (hidden-stashes (cl-subseq stash-list limit)) - (all-hideable (eq vc-git-show-stash t))) - (setq stash-button (vc-git-make-stash-button) + (all-hideable (or (eq vc-git-show-stash t) + (<= len vc-git-show-stash)))) + (setq stash-button (if all-hideable + (vc-git-make-stash-button nil limit limit) + (vc-git-make-stash-button t vc-git-show-stash len)) stash-string (concat (when shown-stashes commit d45740cd9f4f9f2cc132fb81626236789a97b2c9 Author: Arash Esbati Date: Sun Oct 20 20:27:00 2019 +0200 Move entry for \Ref into LaTeX core * lisp/textmodes/reftex-vars.el (reftex-ref-style-alist): Move entry for \Ref from "Varioref" into "Default" as this macro is part of LaTeX 2019-10-01 kernel. Rearrange entries for "Varioref". diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index a9d5819f4b..74cedfaa94 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el @@ -1059,9 +1059,9 @@ This is used to string together whole reference sets, like (defcustom reftex-ref-style-alist '(("Default" t - (("\\ref" ?\C-m) ("\\pageref" ?p))) + (("\\ref" ?\C-m) ("\\Ref" ?R) ("\\pageref" ?p))) ("Varioref" "varioref" - (("\\vref" ?v) ("\\vpageref" ?g) ("\\Vref" ?V) ("\\Ref" ?R))) + (("\\vref" ?v) ("\\Vref" ?V) ("\\vpageref" ?g))) ("Fancyref" "fancyref" (("\\fref" ?f) ("\\Fref" ?F))) ("Hyperref" "hyperref" commit 444930104e09b92ac27092aea44985637a39c26d Author: Stefan Kangas Date: Tue Oct 22 04:05:35 2019 +0200 * etc/NEWS: Improve documentation of 'package-initialize'. diff --git a/etc/NEWS b/etc/NEWS index 50213227fb..d44c853cef 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -171,11 +171,16 @@ make some customization fail to work. +++ ** Installed packages are now activated *before* loading the init file. -This is part of a change intended to eliminate the behavior of -package.el inserting a call to 'package-initialize' into the init -file, which was previously done when Emacs was started. As a result -of this change, it is no longer necessary to call 'package-initialize' -in your init file. +As a result of this change, it is no longer necessary to call +'package-initialize' in your init file. + +Previously, a call to 'package-initialize' was automatically inserted +into the init file when Emacs was started. This call can now safely +be removed. Alternatively, if you want to ensure that your init file +is still compatible with earlier versions of Emacs, change it to: + +(when (version< emacs-version "27.1") + (package-initialize)) However, if your init file changes the values of 'package-load-list' or 'package-user-dir', or sets 'package-enable-at-startup' to nil then commit 3716921c012d7b21a9b0d593a7ea0ddd1e860cfd Author: Paul Eggert Date: Mon Oct 21 17:28:02 2019 -0700 Portcheck only if --enable-gcc-warnings Problem reported by Richard Copley (Bug#37852). This patch causes the problem to not occur if one uses plain ‘configure’. The problem can still occur if with ‘configure --enable-gcc-warnings’, so a further fix may be needed. * configure.ac (GNULIB_PORTCHECK, _FORTIFY_SOURCE): Define these only with an explicit --enable-gcc-warnings. diff --git a/configure.ac b/configure.ac index 33d725c804..3b6a2a6d16 100644 --- a/configure.ac +++ b/configure.ac @@ -1114,15 +1114,16 @@ AS_IF([test $gl_gcc_warnings = no], fi AC_DEFINE([GCC_LINT], [1], [Define to 1 if --enable-gcc-warnings.]) - AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) - AH_VERBATIM([GNULIB_PORTCHECK_FORTIFY_SOURCE], - [/* Enable compile-time and run-time bounds-checking, and some warnings, - without upsetting glibc 2.15+. */ - #if (defined GNULIB_PORTCHECK && !defined _FORTIFY_SOURCE \ - && defined __OPTIMIZE__ && __OPTIMIZE__) - # define _FORTIFY_SOURCE 2 - #endif - ]) + AS_IF([test $gl_gcc_warnings = yes], + [AC_DEFINE([GNULIB_PORTCHECK], [1], [enable some gnulib portability checks]) + AH_VERBATIM([GNULIB_PORTCHECK_FORTIFY_SOURCE], + [/* Enable compile-time and run-time bounds-checking, and some warnings, + without upsetting glibc 2.15+. */ + #if (defined GNULIB_PORTCHECK && !defined _FORTIFY_SOURCE \ + && defined __OPTIMIZE__ && __OPTIMIZE__) + # define _FORTIFY_SOURCE 2 + #endif + ])]) ]) # clang is picky about these regardless of whether commit b087a5f3e4a7fff586245c117f153ae50a35537c Author: Stefan Kangas Date: Tue Oct 22 00:38:21 2019 +0200 Remove XEmacs compat code from speedbar.el * lisp/speedbar.el (speedbar-frame-plist, speedbar-frame-mode) (speedbar-make-overlay, speedbar-overlay-put, speedbar-delete-overlay) (speedbar-mode-line-update, speedbar-frame-reposition-smartly) (speedbar-set-mode-line-format, speedbar-reconfigure-keymaps) (speedbar-add-localized-speedbar-support, speedbar-check-vc) (speedbar-highlight-one-tag-line) (speedbar-unhighlight-one-tag-line): Remove XEmacs compat code. * doc/misc/speedbar.texi (Frames and Faces): Remove documentation for XEmacs. diff --git a/doc/misc/speedbar.texi b/doc/misc/speedbar.texi index 503f9cd646..1e0a34ef9d 100644 --- a/doc/misc/speedbar.texi +++ b/doc/misc/speedbar.texi @@ -695,18 +695,11 @@ file being edited. Face used when the mouse passes over a button. @end table -You can also customize speedbar's initial frame parameters. How this is -accomplished is dependent on your platform being Emacs or XEmacs. - -@cindex @code{speedbar-frame-parameters}, Emacs -In Emacs, change the alist @code{speedbar-frame-parameters}. This -variable is used to set up initial details. Height is also -automatically added when speedbar is created, though you can override -it. - -@cindex @code{speedbar-frame-plist}, XEmacs -In XEmacs, change the plist @code{speedbar-frame-plist}. This is the -XEmacs way of doing the same thing. +@cindex @code{speedbar-frame-parameters} +You can also customize speedbar's initial frame parameters by changing +the alist @code{speedbar-frame-parameters}. This variable is used to +set up initial details. Height is also automatically added when +speedbar is created, though you can override it. @node Tag Hierarchy Methods @section Tag Hierarchy Methods diff --git a/lisp/speedbar.el b/lisp/speedbar.el index df9e932be9..c489d18ce1 100644 --- a/lisp/speedbar.el +++ b/lisp/speedbar.el @@ -341,23 +341,6 @@ attached to and added to this list before the new frame is initialized." (symbol :tag "Parameter") (sexp :tag "Value")))) -;; These values by Hrvoje Nikšić -(defcustom speedbar-frame-plist - '(minibuffer nil width 20 border-width 0 - internal-border-width 0 unsplittable t - default-toolbar-visible-p nil has-modeline-p nil - menubar-visible-p nil - default-gutter-visible-p nil - ) - "Parameters to use when creating the speedbar frame in XEmacs. -Parameters not listed here which will be added automatically are -`height' which will be initialized to the height of the frame speedbar -is attached to." - :group 'speedbar - :type '(repeat (group :inline t - (symbol :tag "Property") - (sexp :tag "Value")))) - (defcustom speedbar-use-imenu-flag (fboundp 'imenu) "Non-nil means use imenu for file parsing, nil to use etags. XEmacs prior to 20.4 doesn't support imenu, therefore the default is to @@ -941,20 +924,15 @@ directories.") (defvar speedbar-power-click nil "Never set this by hand. Value is t when S-mouse activity occurs.") - -;;; Compatibility -;; -(defalias 'speedbar-make-overlay - (if (featurep 'xemacs) 'make-extent 'make-overlay)) - -(defalias 'speedbar-overlay-put - (if (featurep 'xemacs) 'set-extent-property 'overlay-put)) +(define-obsolete-function-alias 'speedbar-make-overlay + 'make-overlay "27.1") +(define-obsolete-function-alias 'speedbar-overlay-put + 'overlay-put "27.1") +(define-obsolete-function-alias 'speedbar-delete-overlay + 'delete-overlay "27.1") +(define-obsolete-function-alias 'speedbar-mode-line-update + 'force-mode-line-update "27.1") -(defalias 'speedbar-delete-overlay - (if (featurep 'xemacs) 'delete-extent 'delete-overlay)) - -(defalias 'speedbar-mode-line-update - (if (featurep 'xemacs) 'redraw-modeline 'force-mode-line-update)) ;;; Mode definitions/ user commands ;; @@ -982,12 +960,7 @@ supported at a time. 'speedbar-buffer "Speedbar" #'speedbar-frame-mode - (if (featurep 'xemacs) - (append speedbar-frame-plist - ;; This is a hack to get speedbar to iconify - ;; with the selected frame. - (list 'parent (selected-frame))) - speedbar-frame-parameters) + speedbar-frame-parameters 'speedbar-before-delete-hook 'speedbar-before-popup-hook 'speedbar-after-create-hook) @@ -1008,18 +981,8 @@ supported at a time. (defun speedbar-frame-reposition-smartly () "Reposition the speedbar frame to be next to the attached frame." - (cond ((and (featurep 'xemacs) - (or (member 'left speedbar-frame-plist) - (member 'top speedbar-frame-plist))) - (dframe-reposition-frame - speedbar-frame - (dframe-attached-frame speedbar-frame) - (cons (car (cdr (member 'left speedbar-frame-plist))) - (car (cdr (member 'top speedbar-frame-plist))))) - ) - ((and (not (featurep 'xemacs)) - (or (assoc 'left speedbar-frame-parameters) - (assoc 'top speedbar-frame-parameters))) + (cond ((or (assoc 'left speedbar-frame-parameters) + (assoc 'top speedbar-frame-parameters)) ;; if left/top were specified in the parameters, pass them ;; down to the reposition function (dframe-reposition-frame @@ -1147,9 +1110,6 @@ return true without a query." This gives visual indications of what is up. It EXPECTS the speedbar frame and window to be the currently active frame and window." (if (and (frame-live-p (speedbar-current-frame)) - (or (not (featurep 'xemacs)) - (with-no-warnings - (specifier-instance has-modeline-p))) speedbar-buffer) (with-current-buffer speedbar-buffer (let* ((w (or (speedbar-frame-width) 20)) @@ -1173,7 +1133,7 @@ frame and window to be the currently active frame and window." (if (not (equal mode-line-format tf)) (progn (setq mode-line-format tf) - (speedbar-mode-line-update))))))) + (force-mode-line-update))))))) (defvar speedbar-previous-menu nil "The menu before the last `speedbar-reconfigure-keymaps' was called.") @@ -1233,13 +1193,8 @@ and the existence of packages." (if speedbar-previous-menu (easy-menu-remove speedbar-previous-menu)) (setq speedbar-previous-menu md) ;; Now add the new menu - (if (not (featurep 'xemacs)) - (easy-menu-define speedbar-menu-map (current-local-map) - "Speedbar menu" md) - (easy-menu-add md (current-local-map)) - ;; XEmacs-specific: - (if (fboundp 'set-buffer-menubar) - (set-buffer-menubar (list md))))) + (easy-menu-define speedbar-menu-map (current-local-map) + "Speedbar menu" md)) (run-hooks 'speedbar-reconfigure-keymaps-hook))) @@ -1848,7 +1803,6 @@ of the special mode functions." (setq speedbar-special-mode-expansion-list t) ;; If it is autoloaded, we need to load it now so that ;; we have access to the variable -speedbar-menu-items. - ;; Is this XEmacs safe? (autoload-do-load (symbol-function v) v) (setq speedbar-special-mode-expansion-list (list v)) (setq v (intern-soft (concat ms "-speedbar-key-map"))) @@ -2884,10 +2838,7 @@ to add more types of version control systems." (speedbar-vc-check-dir-p default-directory) (not (or (and (featurep 'ange-ftp) (string-match - (car (symbol-value - (if (featurep 'xemacs) - 'ange-ftp-directory-format - 'ange-ftp-name-format))) + (car (symbol-value 'ange-ftp-name-format)) (expand-file-name default-directory))) ;; efs support: Bob Weiner (and (featurep 'efs) @@ -3966,17 +3917,17 @@ TEXT is the buffer's name, TOKEN and INDENT are unused." "Highlight the current line, unhighlighting a previously jumped to line." (speedbar-unhighlight-one-tag-line) (setq speedbar-highlight-one-tag-line - (speedbar-make-overlay (line-beginning-position) - (line-beginning-position 2))) - (speedbar-overlay-put speedbar-highlight-one-tag-line 'face - 'speedbar-highlight-face) + (make-overlay (line-beginning-position) + (line-beginning-position 2))) + (overlay-put speedbar-highlight-one-tag-line 'face + 'speedbar-highlight-face) (add-hook 'pre-command-hook 'speedbar-unhighlight-one-tag-line)) (defun speedbar-unhighlight-one-tag-line () "Unhighlight the currently highlighted line." (when (and speedbar-highlight-one-tag-line (not (eq this-command 'handle-switch-frame))) - (speedbar-delete-overlay speedbar-highlight-one-tag-line) + (delete-overlay speedbar-highlight-one-tag-line) (setq speedbar-highlight-one-tag-line nil) (remove-hook 'pre-command-hook 'speedbar-unhighlight-one-tag-line))) commit 950264ff1e92a7f437ef3b4df70bd8a22d65a488 Author: Juri Linkov Date: Tue Oct 22 00:29:21 2019 +0300 * lisp/vc/vc-annotate.el (vc-annotate-lines): Use set-face-extend (bug#37774) diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el index 2cc0f3c40a..35b69b53eb 100644 --- a/lisp/vc/vc-annotate.el +++ b/lisp/vc/vc-annotate.el @@ -725,6 +725,7 @@ The annotations are relative to the current time, unless overridden by OFFSET." ;; Make the face if not done. (face (or (intern-soft face-name) (let ((tmp-face (make-face (intern face-name)))) + (set-face-extend tmp-face t) (cond (vc-annotate-background-mode (set-face-background tmp-face (cdr color))) commit d5fdde42d2c662628f83fdbf3e11f6567f151236 Author: Lars Ingebrigtsen Date: Mon Oct 21 22:38:34 2019 +0200 Try to not put SMTP passwords in the *Messages* buffer * lisp/mail/smtpmail.el (smtpmail--sanitize-error-message): New function. (smtpmail-send-it): Use it. (smtpmail-send-queued-mail): Ditto. diff --git a/lisp/mail/smtpmail.el b/lisp/mail/smtpmail.el index 802c9ba788..9cf28fbe8a 100644 --- a/lisp/mail/smtpmail.el +++ b/lisp/mail/smtpmail.el @@ -354,7 +354,8 @@ for `smtpmail-try-auth-method'.") (when (setq result (smtpmail-via-smtp smtpmail-recipient-address-list tembuf)) - (error "Sending failed: %s" result)) + (error "Sending failed: %s" + (smtpmail--sanitize-error-message result))) (error "Sending failed; no recipients")) (let* ((file-data (expand-file-name @@ -437,13 +438,18 @@ for `smtpmail-try-auth-method'.") (when (setq result (smtpmail-via-smtp smtpmail-recipient-address-list (current-buffer))) - (error "Sending failed: %s" result)) + (error "Sending failed: %s" + (smtpmail--sanitize-error-message result))) (error "Sending failed; no recipients")))) (delete-file file-data) (delete-file file-elisp) (delete-region (point-at-bol) (point-at-bol 2))) (write-region (point-min) (point-max) qfile)))) +(defun smtpmail--sanitize-error-message (string) + "Try to remove passwords and the like from SMTP error messages." + (replace-regexp-in-string "\\bAUTH\\b.*" "AUTH" string)) + (defun smtpmail-fqdn () (if smtpmail-local-domain (concat (system-name) "." smtpmail-local-domain) commit 7f5db3f40caa3050135dae85294849f8375d97b8 Author: Stefan Monnier Date: Mon Oct 21 16:35:38 2019 -0400 * lisp/emacs-lisp/cursor-sensor.el: Make it possible to reveal invisible text (cursor-sensor-mode): Hook into post-command-hook as well. (cursor-sensor--detect): Make argument optional. diff --git a/lisp/emacs-lisp/cursor-sensor.el b/lisp/emacs-lisp/cursor-sensor.el index 66b940f7fb..21d22bbac9 100644 --- a/lisp/emacs-lisp/cursor-sensor.el +++ b/lisp/emacs-lisp/cursor-sensor.el @@ -132,7 +132,7 @@ By convention, this is a list of symbols where each symbol stands for the ;;;###autoload (define-minor-mode cursor-intangible-mode "Keep cursor outside of any `cursor-intangible' text property." - nil nil nil + :global nil (if cursor-intangible-mode (add-hook 'pre-redisplay-functions #'cursor-sensor--move-to-tangible nil t) @@ -140,7 +140,7 @@ By convention, this is a list of symbols where each symbol stands for the ;;; Detect cursor movement. -(defun cursor-sensor--detect (window) +(defun cursor-sensor--detect (&optional window) (unless cursor-sensor-inhibit (let* ((point (window-point window)) ;; It's often desirable to make the cursor-sensor-functions property @@ -178,7 +178,8 @@ By convention, this is a list of symbols where each symbol stands for the (unless (memq f (get-char-property pos 'cursor-sensor-functions)) (setq missing t))) - missing)))) + missing))) + (window (selected-window))) (dolist (f (cdr old)) (unless (and (memq f new) (not (funcall missing-p f))) (funcall f window oldpos 'left))) @@ -203,12 +204,21 @@ of the cursor. They're called with three arguments (WINDOW OLDPOS DIR) where WINDOW is the affected window, OLDPOS is the last known position of the cursor and DIR can be `entered' or `left' depending on whether the cursor is entering the area covered by the text-property property or leaving it." - nil nil nil - (if cursor-sensor-mode - (add-hook 'pre-redisplay-functions #'cursor-sensor--detect - nil t) + :global nil + (cond + (cursor-sensor-mode + ;; Also add ourselves to `post-command-hook' because + ;; `pre-redisplay-functions' are sometimes called too late (after + ;; adjust_point_for_property has moved point, which makes it + ;; "impossible" for cursor-sensor-functions to do things like + ;; revealing invisible text). + (add-hook 'post-command-hook #'cursor-sensor--detect nil t) + (add-hook 'pre-redisplay-functions #'cursor-sensor--detect + nil t)) + (t + (remove-hook 'post-command-hook #'cursor-sensor--detect t) (remove-hook 'pre-redisplay-functions #'cursor-sensor--detect - t))) + t)))) (provide 'cursor-sensor) ;;; cursor-sensor.el ends here commit cf294d78a1d25c5c5178ce3fc7fdddc0de58b904 Author: Lars Ingebrigtsen Date: Mon Oct 21 22:28:49 2019 +0200 Tiny clean-up of previous edebug patch * lisp/emacs-lisp/edebug.el (edebug--overlay-breakpoints): Clean up code slightly. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 9c85ae3dd3..7a40ca36b8 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -3258,7 +3258,7 @@ the breakpoint." (overlay-put overlay 'help-echo "Breakpoint") (overlay-put overlay 'face 'edebug-enabled-breakpoint)))) (overlay-put overlay 'edebug t) - (let ((fringe (make-overlay pos pos (current-buffer)))) + (let ((fringe (make-overlay pos pos))) (overlay-put fringe 'edebug t) (overlay-put fringe 'before-string (propertize commit 7e5f3a809109fc9643739bea2113563805618df2 Author: Lars Ingebrigtsen Date: Mon Oct 21 22:22:06 2019 +0200 Ensure we always remove the breakpoint overlays * lisp/emacs-lisp/edebug.el (edebug--display-1): Remove the overlays here -- this cleans up after exiting no matter how we exited. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 0c3164b5cb..9c85ae3dd3 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -2845,6 +2845,7 @@ See `edebug-behavior-alist' for implementations.") (goto-char edebug-buffer-outside-point)) ;; ... nothing more. ) + (edebug--overlay-breakpoints-remove (point-min) (point-max)) ;; Could be an option to keep eval display up. (if edebug-eval-buffer (kill-buffer edebug-eval-buffer)) (with-timeout-unsuspend edebug-with-timeout-suspend) @@ -2944,7 +2945,6 @@ See `edebug-behavior-alist' for implementations.") (setq signal-hook-function #'edebug-signal) (if edebug-backtrace-buffer (kill-buffer edebug-backtrace-buffer)) - (edebug--overlay-breakpoints-remove (point-min) (point-max)) ;; Remember selected-window after recursive-edit. ;; (setq edebug-inside-window (selected-window)) commit 73cea54064828197f9db256fb4b925ef6be85861 Author: Lars Ingebrigtsen Date: Mon Oct 21 22:17:12 2019 +0200 Add fringe markers to edebug breakpoints * lisp/emacs-lisp/edebug.el (edebug--overlay-breakpoints): Set a fringe element to mark the breakpoint. (edebug-breakpoint): Fringe marker. diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index a646ce6feb..0c3164b5cb 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el @@ -3232,6 +3232,9 @@ the breakpoint." (goto-char position) (edebug--overlay-breakpoints edebug-def-name))))) +(define-fringe-bitmap 'edebug-breakpoint + "\x3c\x7e\xff\xff\xff\xff\x7e\x3c") + (defun edebug--overlay-breakpoints (function) (let* ((data (get function 'edebug)) (start (nth 0 data)) @@ -3245,12 +3248,22 @@ the breakpoint." (when edebug-active (dolist (breakpoint breakpoints) (let* ((pos (+ start (aref offsets (car breakpoint)))) - (overlay (make-overlay pos (1+ pos)))) + (overlay (make-overlay pos (1+ pos))) + (face (if (nth 4 breakpoint) + (progn + (overlay-put overlay + 'help-echo "Disabled breakpoint") + (overlay-put overlay + 'face 'edebug-disabled-breakpoint)) + (overlay-put overlay 'help-echo "Breakpoint") + (overlay-put overlay 'face 'edebug-enabled-breakpoint)))) (overlay-put overlay 'edebug t) - (overlay-put overlay 'face - (if (nth 4 breakpoint) - 'edebug-disabled-breakpoint - 'edebug-enabled-breakpoint))))))) + (let ((fringe (make-overlay pos pos (current-buffer)))) + (overlay-put fringe 'edebug t) + (overlay-put fringe 'before-string + (propertize + "x" 'display + `(left-fringe edebug-breakpoint ,face))))))))) (defun edebug--overlay-breakpoints-remove (start end) (dolist (overlay (overlays-in start end)) commit ce94c43c155f86bbbd9d3196ff84f334738ced75 Author: Stefan Kangas Date: Mon Oct 21 21:21:50 2019 +0200 Clean up previous icalendar.el change * lisp/calendar/icalendar.el (icalendar--rris): Redefine as obsolete function alias. diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index 63d09dc4c2..1186ced3fb 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -344,12 +344,8 @@ mix of different line endings." (while (re-search-forward "\r\n\\|\n\r" nil t) (replace-match "\n" nil nil)))) -(defsubst icalendar--rris (regexp rep string &optional fixedcase literal) - "Replace regular expression in string. -Pass arguments REGEXP REP STRING FIXEDCASE LITERAL to -`replace-regexp-in-string'." - (declare (obsolete replace-regexp-in-string "27.1")) - (replace-regexp-in-string regexp rep string fixedcase literal)) +(define-obsolete-function-alias 'icalendar--rris + 'replace-regexp-in-string "27.1") (defun icalendar--read-element (invalue inparams) "Recursively read the next iCalendar element in the current buffer. commit 969f84b694a830272f1a05ae3a75f0c3885c8479 Author: Stefan Kangas Date: Mon Oct 21 21:19:25 2019 +0200 Remove more XEmacs compat code from viper-*.el * lisp/emulation/viper-cmd.el (viper-submit-report): * lisp/emulation/viper-init.el (viper-set-insert-cursor-type) (viper-restore-cursor-type, viper-use-replace-region-delimiters) (viper-has-face-support-p, viper-window-display-p) (viper-color-display-p, viper-device-type): * lisp/emulation/viper-mous.el (viper-mouse-click-search-word) (viper-mouse-click-insert-word, viper-mouse-click-get-word) (viper-mouse-click-posn, viper-mouse-click-window): * lisp/emulation/viper-util.el (viper-abbreviate-file-name) (viper-set-replace-overlay, viper-maybe-checkout): Remove XEmacs compat code. diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el index f193c4273b..5f90963ac4 100644 --- a/lisp/emulation/viper-cmd.el +++ b/lisp/emulation/viper-cmd.el @@ -4756,14 +4756,12 @@ Please, specify your level now: ")) (defun viper-submit-report () "Submit bug report on Viper." (interactive) - (defvar viper-device-type) (defvar viper-color-display-p) (defvar viper-frame-parameters) (defvar viper-minibuffer-emacs-face) (defvar viper-minibuffer-vi-face) (defvar viper-minibuffer-insert-face) (let ((reporter-prompt-for-summary-p t) - (viper-device-type (viper-device-type)) (viper-color-display-p (if (viper-window-display-p) (viper-color-display-p) 'non-x)) @@ -4824,7 +4822,7 @@ Please, specify your level now: ")) 'ex-cycle-through-non-files 'viper-expert-level 'major-mode - 'viper-device-type + 'window-system 'viper-color-display-p 'viper-frame-parameters 'viper-minibuffer-vi-face diff --git a/lisp/emulation/viper-init.el b/lisp/emulation/viper-init.el index ea041564cc..98fd9e9f89 100644 --- a/lisp/emulation/viper-init.el +++ b/lisp/emulation/viper-init.el @@ -46,21 +46,16 @@ ;; Tell whether we are running as a window application or on a TTY -(defsubst viper-device-type () - (if (featurep 'xemacs) - (device-type (selected-device)) - window-system)) +(define-obsolete-function-alias 'viper-device-type 'window-system "27.1") (defun viper-color-display-p () (condition-case nil - (if (featurep 'xemacs) - (eq (device-class (selected-device)) 'color) - (display-color-p)) + (display-color-p) (error nil))) ;; in XEmacs: device-type is tty on tty and stream in batch. (defun viper-window-display-p () - (and (viper-device-type) (not (memq (viper-device-type) '(tty stream pc))))) + (and window-system (not (memq window-system '(tty stream pc))))) (defcustom viper-ms-style-os-p (memq system-type '(ms-dos windows-nt)) "Non-nil if Emacs is running under an MS-style OS: MS-DOS, or MS-Windows." @@ -87,7 +82,7 @@ In all likelihood, you don't need to bother with this setting." (cond ((viper-window-display-p)) (viper-force-faces) ((viper-color-display-p)) - (t (memq (viper-device-type) '(pc))))) + (t (memq window-system '(pc))))) ;;; Macros @@ -403,15 +398,6 @@ delete the text being replaced, as in standard Vi." ;; internal var, used to remember the default cursor color of emacs frames (defvar viper-vi-state-cursor-color nil) -;; Frame-local variables are obsolete from Emacs 22.2 onwards, so we -;; do it by hand with viper-frame-value (qv). -(when (and (featurep 'xemacs) - (fboundp 'make-variable-frame-local)) - (make-variable-frame-local 'viper-replace-overlay-cursor-color) - (make-variable-frame-local 'viper-insert-state-cursor-color) - (make-variable-frame-local 'viper-emacs-state-cursor-color) - (make-variable-frame-local 'viper-vi-state-cursor-color)) - (viper-deflocalvar viper-replace-overlay nil "") (put 'viper-replace-overlay 'permanent-local t) @@ -428,8 +414,7 @@ is non-nil." :type 'string :group 'viper) (defcustom viper-use-replace-region-delimiters - (or (not (viper-has-face-support-p)) - (and (featurep 'xemacs) (eq (viper-device-type) 'tty))) + (not (viper-has-face-support-p)) "If non-nil, Viper will always use `viper-replace-region-end-delimiter' and `viper-replace-region-start-delimiter' to delimit replacement regions, even on color displays. By default, the delimiters are used only on TTYs." @@ -441,15 +426,6 @@ color displays. By default, the delimiters are used only on TTYs." :type 'symbol :group 'viper) -;; XEmacs requires glyphs -(when (featurep 'xemacs) - (or (glyphp viper-replace-region-end-delimiter) - (setq viper-replace-region-end-delimiter - (make-glyph viper-replace-region-end-delimiter))) - (or (glyphp viper-replace-region-start-delimiter) - (setq viper-replace-region-start-delimiter - (make-glyph viper-replace-region-start-delimiter)))) - ;; These are local marker that must be initialized to nil and moved with ;; `viper-move-marker-locally' ;; @@ -949,15 +925,11 @@ Should be set in `viper-custom-file-name'." (defun viper-restore-cursor-type () (condition-case nil - (if (featurep 'xemacs) - (set (make-local-variable 'bar-cursor) nil) - (setq cursor-type (default-value 'cursor-type))) + (setq cursor-type (default-value 'cursor-type)) (error nil))) (defun viper-set-insert-cursor-type () - (if (featurep 'xemacs) - (set (make-local-variable 'bar-cursor) 2) - (setq cursor-type '(bar . 2)))) + (setq cursor-type '(bar . 2))) (defun viper-ESC-keyseq-timeout () "Key sequence beginning with ESC and separated by no more than this many milliseconds is considered to be generated by a keyboard function key. diff --git a/lisp/emulation/viper-mous.el b/lisp/emulation/viper-mous.el index 5451f33d47..1e2c0e3dd8 100644 --- a/lisp/emulation/viper-mous.el +++ b/lisp/emulation/viper-mous.el @@ -109,8 +109,7 @@ considered related." ;; Returns window where click occurs (defun viper-mouse-click-window (click) - (let ((win (if (featurep 'xemacs) (event-window click) - (posn-window (event-start click))))) + (let ((win (posn-window (event-start click)))) (if (window-live-p win) win (error "Click was not over a live window")))) @@ -127,10 +126,10 @@ considered related." (defsubst viper-mouse-click-window-buffer-name (click) (buffer-name (viper-mouse-click-window-buffer click))) -;; Returns position of a click (defsubst viper-mouse-click-posn (click) - (if (featurep 'xemacs) (event-point click) - (posn-point (event-start click)))) + "Returns position of a click." + (declare (obsolete nil "27.1")) + (posn-point (event-start click))) @@ -225,7 +224,7 @@ On single or double click, returns the word as determined by `viper-surrounding-word-function'." (let ((click-word "") - (click-pos (viper-mouse-click-posn click)) + (click-pos (posn-point (event-start click))) (click-buf (viper-mouse-click-window-buffer click))) (or (natnump count) (setq count 1)) (or (natnump click-count) (setq click-count 1)) @@ -257,8 +256,7 @@ See `viper-surrounding-word' for the definition of a word in this case." (or (not (eq (key-binding viper-mouse-down-insert-key-parsed) 'viper-mouse-catch-frame-switch)) (not (eq (key-binding viper-mouse-up-insert-key-parsed) - 'viper-mouse-click-insert-word)) - (and (featurep 'xemacs) (not (event-over-text-area-p click))))) + 'viper-mouse-click-insert-word)))) () ; do nothing, if binding isn't right or not over text ;; turn arg into a number (cond ((integerp arg) nil) @@ -348,8 +346,7 @@ this command. (or (not (eq (key-binding viper-mouse-down-search-key-parsed) 'viper-mouse-catch-frame-switch)) (not (eq (key-binding viper-mouse-up-search-key-parsed) - 'viper-mouse-click-search-word)) - (and (featurep 'xemacs) (not (event-over-text-area-p click))))) + 'viper-mouse-click-search-word)))) () ; do nothing, if binding isn't right or not over text (let ((previous-search-string viper-s-string) click-word click-count) diff --git a/lisp/emulation/viper-util.el b/lisp/emulation/viper-util.el index 046cee9912..c7073d06ac 100644 --- a/lisp/emulation/viper-util.el +++ b/lisp/emulation/viper-util.el @@ -685,7 +685,7 @@ Otherwise return the normal value." (y-or-n-p (format "File %s is checked in. Check it out? " - (viper-abbreviate-file-name file)))) + (abbreviate-file-name file)))) (with-current-buffer buf (command-execute checkout-function))))) @@ -737,7 +737,7 @@ Otherwise return the normal value." ;; just have keymap attached to replace overlay. ;;(overlay-put ;; viper-replace-overlay - ;; (if (featurep 'xemacs) 'keymap 'local-map) + ;; 'local-map ;; viper-replace-map) ) (if (viper-has-face-support-p) @@ -804,8 +804,8 @@ Otherwise return the normal value." ;;; XEmacs compatibility -(defun viper-abbreviate-file-name (file) - (abbreviate-file-name file)) +(define-obsolete-function-alias 'viper-abbreviate-file-name + 'abbreviate-file-name "27.1") ;; Sit for VAL milliseconds. XEmacs doesn't support the millisecond arg ;; in sit-for, so this function smooths out the differences. commit 8f9ed4c71d22288c38331199fd556acf65752d0d Author: Stefan Kangas Date: Mon Oct 21 18:49:04 2019 +0200 Remove XEmacs compat code from icalendar.el (Bug#37816) * lisp/calendar/icalendar.el (icalendar--convert-string-for-export) (icalendar--convert-string-for-import) (icalendar--parse-summary-and-rest) (icalendar--convert-ordinary-to-ical) (icalendar--convert-weekly-to-ical) (icalendar--convert-yearly-to-ical) (icalendar--convert-block-to-ical) (icalendar--convert-cyclic-to-ical) (icalendar--convert-anniversary-to-ical) (icalendar--format-ical-event) (icalendar--convert-recurring-to-diary): Remove XEmacs compat code. (icalendar--rris): Declare obsolete. diff --git a/lisp/calendar/icalendar.el b/lisp/calendar/icalendar.el index 3ae0fcbe97..63d09dc4c2 100644 --- a/lisp/calendar/icalendar.el +++ b/lisp/calendar/icalendar.el @@ -347,14 +347,9 @@ mix of different line endings." (defsubst icalendar--rris (regexp rep string &optional fixedcase literal) "Replace regular expression in string. Pass arguments REGEXP REP STRING FIXEDCASE LITERAL to -`replace-regexp-in-string' (Emacs) or to `replace-in-string' (XEmacs)." - (cond ((fboundp 'replace-regexp-in-string) - ;; Emacs: - (replace-regexp-in-string regexp rep string fixedcase literal)) - ((fboundp 'replace-in-string) - ;; XEmacs: - (save-match-data ;; apparently XEmacs needs save-match-data - (replace-in-string string regexp rep literal))))) +`replace-regexp-in-string'." + (declare (obsolete replace-regexp-in-string "27.1")) + (replace-regexp-in-string regexp rep string fixedcase literal)) (defun icalendar--read-element (invalue inparams) "Recursively read the next iCalendar element in the current buffer. @@ -978,14 +973,14 @@ TIMESTRING and has the same result as \"9:00\"." (defun icalendar--convert-string-for-export (string) "Escape comma and other critical characters in STRING." - (icalendar--rris "," "\\\\," string)) + (replace-regexp-in-string "," "\\\\," string)) (defun icalendar--convert-string-for-import (string) "Remove escape chars for comma, semicolon etc. from STRING." - (icalendar--rris - "\\\\n" "\n " (icalendar--rris - "\\\\\"" "\"" (icalendar--rris - "\\\\;" ";" (icalendar--rris + (replace-regexp-in-string + "\\\\n" "\n " (replace-regexp-in-string + "\\\\\"" "\"" (replace-regexp-in-string + "\\\\;" ";" (replace-regexp-in-string "\\\\," "," string))))) ;; ====================================================================== @@ -1232,7 +1227,7 @@ Returns an alist." (setq ct (+ ct 1)) (setq pos-uid (* 2 ct)))) ) (mapc (lambda (ij) - (setq s (icalendar--rris (car ij) (cadr ij) s t t))) + (setq s (replace-regexp-in-string (car ij) (cadr ij) s t t))) (list ;; summary must be first! because of %s (list "%s" @@ -1253,7 +1248,7 @@ Returns an alist." (concat "\\(" icalendar-import-format-uid "\\)??")))) ;; Need the \' regexp in order to detect multi-line items (setq s (concat "\\`" - (icalendar--rris "%s" "\\(.*?\\)" s nil t) + (replace-regexp-in-string "%s" "\\(.*?\\)" s nil t) "\\'")) (if (string-match s summary-and-rest) (let (cla des loc org sta url uid) ;; sum @@ -1395,7 +1390,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." (when starttimestring (unless endtimestring (let ((time - (read (icalendar--rris "^T0?" "" + (read (replace-regexp-in-string "^T0?" "" starttimestring)))) (if (< time 230000) ;; Case: ends on same day @@ -1483,7 +1478,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." (when starttimestring (unless endtimestring (let ((time (read - (icalendar--rris "^T0?" "" + (replace-regexp-in-string "^T0?" "" starttimestring)))) (setq endtimestring (format "T%06d" (+ 10000 time)))))) @@ -1570,7 +1565,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." (when starttimestring (unless endtimestring (let ((time (read - (icalendar--rris "^T0?" "" + (replace-regexp-in-string "^T0?" "" starttimestring)))) (setq endtimestring (format "T%06d" (+ 10000 time)))))) @@ -1704,7 +1699,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." (when starttimestring (unless endtimestring (let ((time - (read (icalendar--rris "^T0?" "" + (read (replace-regexp-in-string "^T0?" "" starttimestring)))) (setq endtimestring (format "T%06d" (+ 10000 time)))))) @@ -1747,7 +1742,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." (n (nth 3 sexp)) (day (nth 4 sexp)) (summary - (replace-regexp-in-string + (replace-regexp-in-string "\\(^\s+\\|\s+$\\)" "" (buffer-substring (point) (point-max))))) @@ -1857,7 +1852,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." (when starttimestring (unless endtimestring (let ((time - (read (icalendar--rris "^T0?" "" + (read (replace-regexp-in-string "^T0?" "" starttimestring)))) (setq endtimestring (format "T%06d" (+ 10000 time)))))) @@ -1926,7 +1921,7 @@ entries. ENTRY-MAIN is the first line of the diary entry." (when starttimestring (unless endtimestring (let ((time - (read (icalendar--rris "^T0?" "" + (read (replace-regexp-in-string "^T0?" "" starttimestring)))) (setq endtimestring (format "T%06d" (+ 10000 time)))))) @@ -2051,12 +2046,12 @@ buffer `*icalendar-errors*'." (formatted-contents "")) (when (and contents (> (length contents) 0)) (setq formatted-contents - (icalendar--rris "%s" + (replace-regexp-in-string "%s" (icalendar--convert-string-for-import contents) (symbol-value format) t t))) - (setq string (icalendar--rris spec + (setq string (replace-regexp-in-string spec formatted-contents string t t)))) @@ -2450,7 +2445,7 @@ END-T is the event's end time in diary format." (ex-d (icalendar--datetime-to-diary-date ex-start))) (setq result - (icalendar--rris "^%%(\\(and \\)?" + (replace-regexp-in-string "^%%(\\(and \\)?" (format "%%%%(and (not (diary-date %s)) " ex-d) commit 61fb5214816ef3d57e676d900e499ffcd079a1f9 Author: Eli Zaretskii Date: Mon Oct 21 14:29:13 2019 +0300 Avoid false indications from Flymake in .dir-locals.el files * lisp/progmodes/elisp-mode.el (emacs-lisp-mode): Don't install 'elisp-flymake-checkdoc' and 'elisp-flymake-byte-compile' hooks for .dir-locals.el files. Reported by Clément Pit-Claudel . diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 516e4f9cd6..7705761365 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -256,8 +256,20 @@ Blank lines separate paragraphs. Semicolons start comments. (setq-local project-vc-external-roots-function #'elisp-load-path-roots) (add-hook 'completion-at-point-functions #'elisp-completion-at-point nil 'local) - (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t) - (add-hook 'flymake-diagnostic-functions #'elisp-flymake-byte-compile nil t)) + ;; .dir-locals.el and lock files will cause the byte-compiler and + ;; checkdoc emit spurious warnings, because they don't follow the + ;; conventions of Emacs Lisp sources. Until we have a better fix, + ;; like teaching elisp-mode about files that only hold data + ;; structures, we disable the ELisp Flymake backend for these files. + (unless + (let* ((bfname (buffer-file-name)) + (fname (and (stringp bfname) (file-name-nondirectory bfname)))) + (or (not (stringp fname)) + (string-match "\\`\\.#" fname) + (string-equal dir-locals-file fname))) + (add-hook 'flymake-diagnostic-functions #'elisp-flymake-checkdoc nil t) + (add-hook 'flymake-diagnostic-functions + #'elisp-flymake-byte-compile nil t))) ;; Font-locking support. commit 03921902b2a07909e7f36e6c8fb259eff4bad982 Author: Eli Zaretskii Date: Mon Oct 21 13:32:40 2019 +0300 ; Add commentary to w32inevt.c * src/w32inevt.c (do_mouse_event): Comment on mouse coordinates in console mouse-wheel events. diff --git a/src/w32inevt.c b/src/w32inevt.c index 1a901d4e0a..4312e52b6b 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -534,6 +534,12 @@ do_mouse_event (MOUSE_EVENT_RECORD *event, case MOUSE_HWHEELED: { struct frame *f = get_frame (); + /* Mouse positions in console wheel events are reported to + ReadConsoleInput relative to the display's top-left + corner(!), not relative to the origin of the console screen + buffer. This makes these coordinates unusable; e.g., + scrolling the tab-line in general doesn't work. + FIXME (but how?). */ int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y; bool down_p = (event->dwButtonState & 0x10000000) != 0; commit a5ca89d35c9762b1ff850235e0df5fdb4e77079d Author: Robert Pluim Date: Thu Oct 17 15:55:06 2019 +0200 Add button to vc-dir to toggle visibility of stash list * lisp/vc/vc-git.el: Move cl-lib require outside 'eval-when-compile'. * lisp/vc/vc-git.el (vc-git-show-stash):New user option. (vc-git-make-stash-button): Create button that allows hiding the stash list. (vc-git-dir-extra-headers): Split stash list into hideable and non-hideable parts depending on value of vc-git-show-stash. Add button to toggle visibility of hideable part. * etc/NEWS: Announce it. diff --git a/etc/NEWS b/etc/NEWS index cf6b066b44..50213227fb 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -815,6 +815,11 @@ The default value is 'find-dired-sort-by-filename'. *** New command 'log-edit-generate-changelog-from-diff', bound to 'C-c C-w'. This generates ChangeLog entries from the VC fileset diff. +*** 'vc-dir' now shows a button allowing you to hide the stash list. +Controlled by user option 'vc-git-show-stash'. Default t means show +the entire list as before. An integer value limits the list length +(but still allows you to show the entire list via the button). + *** Recording ChangeLog entries doesn't require an actual file. If a ChangeLog file doesn't exist, and if the new user option 'add-log-dont-create-changelog-file' is non-nil (which is the diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 9715aea1fd..70f5399073 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -102,8 +102,8 @@ ;;; Code: +(require 'cl-lib) (eval-when-compile - (require 'cl-lib) (require 'subr-x) ; for string-trim-right (require 'vc) (require 'vc-dir)) @@ -192,6 +192,21 @@ The following place holders should be present in the string: :type 'string :version "27.1") +(defcustom vc-git-show-stash t + "How much of the git stash list to show by default. +Default t means all, otherwise an integer specifying the maximum +number to show. A text button is always shown allowing you to +toggle display of the entire list." + :type '(choice (const :tag "All" t) + (integer :tag "Limit" + :validate + (lambda (widget) + (unless (>= (widget-value widget) 0) + (widget-put widget :error + "Invalid value: must be a non-negative integer") + widget)))) + :version "27.1") + ;; History of Git commands. (defvar vc-git-history nil) @@ -635,6 +650,18 @@ or an empty string if none." (define-key map "S" 'vc-git-stash-snapshot) map)) +(defun vc-git-make-stash-button () + (make-text-button "Show/hide stashes" nil + 'action + (lambda (&rest _ignore) + (let* ((inhibit-read-only t) + (start (next-single-property-change (point-min) 'vc-git-hideable)) + (end (next-single-property-change start 'vc-git-hideable))) + (add-text-properties + start end + `(invisible ,(not (get-text-property start 'invisible)))))) + 'help-echo "mouse-2, RET: Show/hide stashes")) + (defvar vc-git-stash-menu-map (let ((map (make-sparse-keymap "Git Stash"))) (define-key map [de] @@ -655,9 +682,11 @@ or an empty string if none." (let ((str (with-output-to-string (with-current-buffer standard-output (vc-git--out-ok "symbolic-ref" "HEAD")))) - (stash (vc-git-stash-list)) + (stash-list (vc-git-stash-list)) (stash-help-echo "Use M-x vc-git-stash to create stashes.") - branch remote remote-url) + (stash-list-help-echo "mouse-3: Show stash menu\nRET: Show stash\nA: Apply stash\nP: Apply and remove stash (pop)\nC-k: Delete stash") + + branch remote remote-url stash-button stash-string) (if (string-match "^\\(refs/heads/\\)?\\(.+\\)$" str) (progn (setq branch (match-string 2 str)) @@ -677,6 +706,50 @@ or an empty string if none." (when (string-match "\\([^\n]+\\)" remote-url) (setq remote-url (match-string 1 remote-url)))) (setq branch "not (detached HEAD)")) + (when stash-list + (let* ((limit + (if (integerp vc-git-show-stash) + (min vc-git-show-stash (length stash-list)) + (length stash-list))) + (shown-stashes (cl-subseq stash-list 0 limit)) + (hidden-stashes (cl-subseq stash-list limit)) + (all-hideable (eq vc-git-show-stash t))) + (setq stash-button (vc-git-make-stash-button) + stash-string + (concat + (when shown-stashes + (concat + (propertize "\n" + 'vc-git-hideable all-hideable) + (mapconcat + (lambda (x) + (propertize x + 'face 'font-lock-variable-name-face + 'mouse-face 'highlight + 'vc-git-hideable all-hideable + 'help-echo stash-list-help-echo + 'keymap vc-git-stash-map)) + shown-stashes + (propertize "\n" + 'vc-git-hideable all-hideable)))) + (when hidden-stashes + (concat + (propertize "\n" + 'invisible t + 'vc-git-hideable t) + (mapconcat + (lambda (x) + (propertize x + 'face 'font-lock-variable-name-face + 'mouse-face 'highlight + 'invisible t + 'vc-git-hideable t + 'help-echo stash-list-help-echo + 'keymap vc-git-stash-map)) + hidden-stashes + (propertize "\n" + 'invisible t + 'vc-git-hideable t)))))))) ;; FIXME: maybe use a different face when nothing is stashed. (concat (propertize "Branch : " 'face 'font-lock-type-face) @@ -688,26 +761,19 @@ or an empty string if none." (propertize "Remote : " 'face 'font-lock-type-face) (propertize remote-url 'face 'font-lock-variable-name-face))) - "\n" ;; For now just a heading, key bindings can be added later for various bisect actions (when (file-exists-p (expand-file-name ".git/BISECT_START" (vc-git-root dir))) - (propertize "Bisect : in progress\n" 'face 'font-lock-warning-face)) + (propertize "\nBisect : in progress" 'face 'font-lock-warning-face)) (when (file-exists-p (expand-file-name ".git/rebase-apply" (vc-git-root dir))) - (propertize "Rebase : in progress\n" 'face 'font-lock-warning-face)) - (if stash + (propertize "\nRebase : in progress" 'face 'font-lock-warning-face)) + (if stash-list (concat - (propertize "Stash :\n" 'face 'font-lock-type-face - 'help-echo stash-help-echo) - (mapconcat - (lambda (x) - (propertize x - 'face 'font-lock-variable-name-face - 'mouse-face 'highlight - 'help-echo "mouse-3: Show stash menu\nRET: Show stash\nA: Apply stash\nP: Apply and remove stash (pop)\nC-k: Delete stash" - 'keymap vc-git-stash-map)) - stash "\n")) + (propertize "\nStash : " 'face 'font-lock-type-face + 'help-echo stash-help-echo) + stash-button + stash-string) (concat - (propertize "Stash : " 'face 'font-lock-type-face + (propertize "\nStash : " 'face 'font-lock-type-face 'help-echo stash-help-echo) (propertize "Nothing stashed" 'help-echo stash-help-echo