commit 2b347905feae0753c9e037082c7b5fdbc2b85fd0 (HEAD, refs/remotes/origin/master) Author: Eli Zaretskii Date: Tue Oct 15 11:20:22 2019 +0300 ; Minor copyedits in recently installed documentation changes * lisp/files.el (require-final-newline): * etc/NEWS: Improve wording in recent documentation changes. diff --git a/etc/NEWS b/etc/NEWS index ab3bbd1099..d06f0a5952 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2400,7 +2400,7 @@ scrolling. * Lisp Changes in Emacs 27.1 +++ -** New macro 'benchmark-progn' +** New macro 'benchmark-progn'. This macro works like 'progn', but messages how long it takes to evaluate the body forms. The value of the last form is the return value. diff --git a/lisp/files.el b/lisp/files.el index 1078b0c4c9..40807617fa 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -339,8 +339,8 @@ Certain major modes set this locally to the value obtained from `mode-require-final-newline'. This variable is only heeded when visiting files (or saving -visited files). Writing data to the file system with -`write-region' and the like is not influenced by this variable." +buffers into files they visit). Writing data to the file system +with `write-region' and the like is not influenced by this variable." :safe #'symbolp :type '(choice (const :tag "When visiting" visit) (const :tag "When saving" t) commit dcc710916e29777192630c8f225f4b17aa9cd3c2 Author: Lars Ingebrigtsen Date: Tue Oct 15 08:42:28 2019 +0200 Make auth-source work with non-ASCII passwords again * lisp/auth-source.el (auth-source--obfuscate): Convert the string to bytes before obfuscating. (auth-source--deobfuscate): Convert back into a string (bug#37758). diff --git a/lisp/auth-source.el b/lisp/auth-source.el index 9061d41556..1d3d8dba40 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -1184,7 +1184,8 @@ FILE is the file from which we obtained this token." (auth-source--pad auth-source--session-nonce (plist-get cdata :cipher-keysize)) (list 'iv-auto (plist-get cdata :cipher-ivsize)) - (auth-source--pad string (plist-get cdata :cipher-blocksize))) + (auth-source--pad (encode-coding-string string 'utf-8) + (plist-get cdata :cipher-blocksize))) "-")) (mapcar #'1- string))) @@ -1203,14 +1204,16 @@ FILE is the file from which we obtained this token." (gnutls-available-p)) (let ((cdata (car (last (gnutls-ciphers)))) (bits (split-string data "-"))) - (auth-source--unpad - (car - (gnutls-symmetric-decrypt - (pop cdata) - (auth-source--pad auth-source--session-nonce - (plist-get cdata :cipher-keysize)) - (base64-decode-string (cadr bits)) - (base64-decode-string (car bits)))))) + (decode-coding-string + (auth-source--unpad + (car + (gnutls-symmetric-decrypt + (pop cdata) + (auth-source--pad auth-source--session-nonce + (plist-get cdata :cipher-keysize)) + (base64-decode-string (cadr bits)) + (base64-decode-string (car bits))))) + 'utf-8)) (apply #'string (mapcar #'1+ data)))) (cl-defun auth-source-netrc-search (&rest spec commit ddc9837bf48c99c31df397438175afc2f9d3819c Author: Lars Ingebrigtsen Date: Tue Oct 15 08:19:08 2019 +0200 Add new macro `benchmark-progn' * doc/lispref/debugging.texi (Profiling): Mention it. * lisp/emacs-lisp/benchmark.el (benchmark-progn): New macro. diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi index 71e767d0a6..b7eca1e50f 100644 --- a/doc/lispref/debugging.texi +++ b/doc/lispref/debugging.texi @@ -1041,9 +1041,9 @@ functions written in Lisp, it cannot profile Emacs primitives. @cindex benchmarking You can measure the time it takes to evaluate individual Emacs Lisp forms using the @file{benchmark} library. See the macros -@code{benchmark-run} and @code{benchmark-run-compiled} in -@file{benchmark.el}. You can also use the @code{benchmark} command -for timing forms interactively. +@code{benchmark-run}, @code{benchmark-run-compiled} and +@code{benchmark-progn} in @file{benchmark.el}. You can also use the +@code{benchmark} command for timing forms interactively. @c Not worth putting in the printed manual. @ifnottex diff --git a/etc/NEWS b/etc/NEWS index ff613ecd41..ab3bbd1099 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2399,6 +2399,12 @@ scrolling. * Lisp Changes in Emacs 27.1 ++++ +** New macro 'benchmark-progn' +This macro works like 'progn', but messages how long it takes to +evaluate the body forms. The value of the last form is the return +value. + ** New function 'read-char-with-history'. This function works like 'read-char', but maintains a history that can be navigated via the 'M-p'/'M-n' keystrokes. diff --git a/lisp/emacs-lisp/benchmark.el b/lisp/emacs-lisp/benchmark.el index 8f12858b03..278fb807fd 100644 --- a/lisp/emacs-lisp/benchmark.el +++ b/lisp/emacs-lisp/benchmark.el @@ -107,6 +107,30 @@ For non-interactive use see also `benchmark-run' and (message "Elapsed time: %fs (%fs in %d GCs)" (car result) (nth 2 result) (nth 1 result))))) +;;;###autoload +(defmacro benchmark-progn (&rest body) + "Evaluate BODY and message the time taken. +The return value is the value of the final form in BODY." + (declare (debug body) (indent 0)) + (let ((value (make-symbol "value")) + (start (make-symbol "start")) + (gcs (make-symbol "gcs")) + (gc (make-symbol "gc"))) + `(let ((,gc gc-elapsed) + (,gcs gcs-done) + (,start (current-time)) + (,value (progn + ,@body))) + (message "Elapsed time: %fs%s" + (float-time (time-since ,start)) + (if (> (- gcs-done ,gcs) 0) + (format " (%fs in %d GCs)" + (- gc-elapsed ,gc) + (- gcs-done ,gcs)) + "")) + ;; Return the value of the body. + ,value))) + (provide 'benchmark) ;;; benchmark.el ends here commit 7acc621e373ba1371495e15e5e78aa6ce948a9a6 Author: Carlos Pita Date: Tue Dec 4 19:35:09 2018 -0300 Fix python-shell font-lock cleanup for unclosed quotes (Bug#32390) The problem originating this report was: ------------- In [15]: " File "", line 1 " ^ SyntaxError: EOL while scanning string literal In [16]: string face still here" ------------- This happens because python-shell-font-lock-comint-output-filter-function is called twice, first for the error output and then for the "In [16]: " part. The first time python-shell-comint-end-of-output-p returns nil since we're *not* at the end of an input prompt. The second time it returns 0 since we're at the end of *just* an input prompt. So we don't call python-shell-font-lock-cleanup-buffer either time. The current code is relying in a very weak rule: it considers "just an input prompt" to be a continuation prompt. Another unreliable aspect of the current rule is that sometimes (python-shell-comint-end-of-output-p (ansi-color-filter-apply output)) returns 1 and not 0 for continuation prompts. In short, the rule does a very poor job identifying continuations. * lisp/progmodes/python.el (python-shell-font-lock-cleanup-buffer): Don't check for empty OUTPUT since python-shell-comint-end-of-output-p returns nil for that anyway. Don't check for python-shell-comint-end-of-output-p returning a specific number because it's unreliable, just check for any non-nil. Identify continuation prompts by looking for "...". diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index ae5aff351c..b168b62c29 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -2600,14 +2600,12 @@ goes wrong and syntax highlighting in the shell gets messed up." (defun python-shell-font-lock-comint-output-filter-function (output) "Clean up the font-lock buffer after any OUTPUT." - (if (and (not (string= "" output)) - ;; Is end of output and is not just a prompt. - (not (member - (python-shell-comint-end-of-output-p - (ansi-color-filter-apply output)) - '(nil 0)))) - ;; If output is other than an input prompt then "real" output has - ;; been received and the font-lock buffer must be cleaned up. + (if (let ((output (ansi-color-filter-apply output))) + (and (python-shell-comint-end-of-output-p output) + ;; Assume "..." represents a continuation prompt. + (not (string-match "\\.\\.\\." output)))) + ;; If output ends with an initial (not continuation) input prompt + ;; then the font-lock buffer must be cleaned up. (python-shell-font-lock-cleanup-buffer) ;; Otherwise just add a newline. (python-shell-font-lock-with-font-lock-buffer commit 8a089a95d8dc5a3b579a349785793dd52ecdb7cd Author: Juri Linkov Date: Tue Oct 15 01:43:45 2019 +0300 Add images on tab-bar buttons the first time the tab bar is activated * lisp/tab-bar.el (tab-bar-mode): Set display property with image files on tab-bar-new-button and tab-bar-close-button when tab-bar-mode is enabled the first time. (tab-bar-new-button, tab-bar-close-button): Use default values without display image properties. (Bug#37685) diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 23ac243f53..3fe750908b 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -99,6 +99,29 @@ (cons (cons 'tab-bar-lines val) (assq-delete-all 'tab-bar-lines default-frame-alist))))) + + (when (and tab-bar-mode (not (get-text-property 0 'display tab-bar-new-button))) + ;; This file is pre-loaded so only here we can use the right data-directory: + (let ((file (expand-file-name "images/tabs/new.xpm" data-directory))) + (when (file-exists-p file) + (add-text-properties 0 (length tab-bar-new-button) + `(display (image :type xpm + :file ,file + :margin (2 . 0) + :ascent center)) + tab-bar-new-button)))) + + (when (and tab-bar-mode (not (get-text-property 0 'display tab-bar-close-button))) + ;; This file is pre-loaded so only here we can use the right data-directory: + (let ((file (expand-file-name "images/tabs/close.xpm" data-directory))) + (when (file-exists-p file) + (add-text-properties 0 (length tab-bar-close-button) + `(display (image :type xpm + :file ,file + :margin (2 . 0) + :ascent center)) + tab-bar-close-button)))) + (when tab-bar-mode (global-set-key [(control shift iso-lefttab)] 'tab-previous) (global-set-key [(control shift tab)] 'tab-previous) @@ -198,14 +221,7 @@ before calling the command that adds a new tab." :group 'tab-bar :version "27.1") -(defvar tab-bar-new-button - (propertize " + " - 'display `(image :type xpm - :file ,(expand-file-name - "images/tabs/new.xpm" - data-directory) - :margin (2 . 0) - :ascent center)) +(defvar tab-bar-new-button " + " "Button for creating a new tab.") (defcustom tab-bar-close-button-show t @@ -227,12 +243,6 @@ If nil, don't show it at all." (defvar tab-bar-close-button (propertize " x" - 'display `(image :type xpm - :file ,(expand-file-name - "images/tabs/close.xpm" - data-directory) - :margin (2 . 0) - :ascent center) 'close-tab t :help "Click to close tab") "Button for closing the clicked tab.") commit d4cfe67e8ae4392fc1f01879f6d3a9a8b6947ac1 Author: Juanma Barranquero Date: Mon Oct 14 23:52:21 2019 +0200 lisp/*.el: Force non-nil result to t, to match docstring * lisp/ido.el (ido-ignore-item-p): * lisp/simple.el (use-region-p): * lisp/whitespace.el (whitespace-style-face-p) (whitespace-style-mark-p): * lisp/calendar/cal-islam.el (calendar-islamic-leap-year-p): * lisp/mail/rmail.el (rmail-is-text-p): * lisp/mh-e/mh-alias.el (mh-alias-for-from-p): * lisp/net/imap.el (imap-message-flag-permanent-p): * lisp/progmodes/tcl.el (tcl-real-comment-p): * lisp/textmodes/table.el (table--point-in-cell-p): Normalize boolean result. diff --git a/lisp/calendar/cal-islam.el b/lisp/calendar/cal-islam.el index 81ac4d0332..c31e3c480a 100644 --- a/lisp/calendar/cal-islam.el +++ b/lisp/calendar/cal-islam.el @@ -45,8 +45,9 @@ (defun calendar-islamic-leap-year-p (year) "Return t if YEAR is a leap year on the Islamic calendar." - (memq (% year 30) - (list 2 5 7 10 13 16 18 21 24 26 29))) + (and (memq (% year 30) + (list 2 5 7 10 13 16 18 21 24 26 29)) + t)) (defun calendar-islamic-last-day-of-month (month year) "The last day in MONTH during YEAR on the Islamic calendar." diff --git a/lisp/ido.el b/lisp/ido.el index 1cfcb0f535..2a660e6b0c 100644 --- a/lisp/ido.el +++ b/lisp/ido.el @@ -3890,7 +3890,7 @@ frame, rather than all frames, regardless of value of `ido-all-frames'." (defun ido-ignore-item-p (name re-list &optional ignore-ext) "Return t if the buffer or file NAME should be ignored." - (or (member name ido-ignore-item-temp-list) + (or (and (member name ido-ignore-item-temp-list) t) (and ido-process-ignore-lists re-list (save-match-data diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el index 93e7cb0133..34f8a46761 100644 --- a/lisp/mail/rmail.el +++ b/lisp/mail/rmail.el @@ -2738,7 +2738,7 @@ N defaults to the current message." ;; (a default of "text/plain; charset=US-ASCII" is assumed) or ;; the base content type is either text or message. (or (not content-type-header) - (string-match text-regexp content-type-header))))) + (and (string-match text-regexp content-type-header) t))))) (defcustom rmail-show-message-verbose-min 200000 "Message size at which to show progress messages for displaying it." diff --git a/lisp/mh-e/mh-alias.el b/lisp/mh-e/mh-alias.el index 5573f22072..632280e74d 100644 --- a/lisp/mh-e/mh-alias.el +++ b/lisp/mh-e/mh-alias.el @@ -485,7 +485,8 @@ set `mh-alias-insert-file' or the \"Aliasfile:\" profile component")) (set-buffer mh-show-buffer)) (let ((from-header (mh-extract-from-header-value))) (and from-header - (mh-alias-address-to-alias from-header)))))) + (mh-alias-address-to-alias from-header) + t))))) (defun mh-alias-add-alias-to-file (alias address &optional file) "Add ALIAS for ADDRESS in alias FILE without alias check or prompts. diff --git a/lisp/net/imap.el b/lisp/net/imap.el index 9f43c57ffd..eb96309421 100644 --- a/lisp/net/imap.el +++ b/lisp/net/imap.el @@ -1672,8 +1672,9 @@ non-nil, return these properties." "Return t if FLAG can be permanently saved on articles. MAILBOX specifies a mailbox on the server in BUFFER." (with-current-buffer (or buffer (current-buffer)) - (or (member "\\*" (imap-mailbox-get 'permanentflags mailbox)) - (member flag (imap-mailbox-get 'permanentflags mailbox))))) + (and (or (member "\\*" (imap-mailbox-get 'permanentflags mailbox)) + (member flag (imap-mailbox-get 'permanentflags mailbox))) + t))) (defun imap-message-flags-set (articles flags &optional silent buffer) (when (and articles flags) diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el index 0788725055..e5fdd27243 100644 --- a/lisp/progmodes/tcl.el +++ b/lisp/progmodes/tcl.el @@ -1221,7 +1221,6 @@ first word following a semicolon, opening brace, or opening bracket." (t (memq (preceding-char) '(?\; ?{ ?\[)))))) -;; FIXME doesn't actually return t. See last case. (defun tcl-real-comment-p () "Return t if point is just after the `#' beginning a real comment. Does not check to see if previous char is actually `#'. @@ -1230,7 +1229,7 @@ preceded only by whitespace on the line, or has a preceding semicolon, opening brace, or opening bracket on the same line." (save-excursion (backward-char) - (tcl-real-command-p))) + (and (tcl-real-command-p) t))) (defun tcl-hairy-scan-for-comment (state end always-stop) "Determine if point is in a comment. diff --git a/lisp/simple.el b/lisp/simple.el index 2add266960..b733f76ac7 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -5681,7 +5681,8 @@ the region must not be empty. Otherwise, the return value is nil. For some commands, it may be appropriate to ignore the value of `use-empty-active-region'; in that case, use `region-active-p'." (and (region-active-p) - (or use-empty-active-region (> (region-end) (region-beginning))))) + (or use-empty-active-region (> (region-end) (region-beginning))) + t)) (defun region-active-p () "Return non-nil if Transient Mark mode is enabled and the mark is active. diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index f684f4e4ca..94dcaea0ba 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -4938,7 +4938,8 @@ When optional LOCATION is provided the test is performed at that location." (save-excursion (goto-char location) (table--probe-cell)) - (table--probe-cell)))) + (table--probe-cell)) + t)) (defun table--region-in-cell-p (beg end) "Return t when location BEG and END are in a valid table cell in the current buffer." diff --git a/lisp/whitespace.el b/lisp/whitespace.el index d0368b54a8..243e750246 100644 --- a/lisp/whitespace.el +++ b/lisp/whitespace.el @@ -2025,7 +2025,8 @@ resultant list will be returned." (memq 'space-after-tab::space whitespace-active-style) (memq 'space-before-tab whitespace-active-style) (memq 'space-before-tab::tab whitespace-active-style) - (memq 'space-before-tab::space whitespace-active-style)))) + (memq 'space-before-tab::space whitespace-active-style)) + t)) (defun whitespace-color-on () @@ -2326,9 +2327,10 @@ Also refontify when necessary." (defun whitespace-style-mark-p () "Return t if there is some visualization via display table." - (or (memq 'tab-mark whitespace-active-style) - (memq 'space-mark whitespace-active-style) - (memq 'newline-mark whitespace-active-style))) + (and (or (memq 'tab-mark whitespace-active-style) + (memq 'space-mark whitespace-active-style) + (memq 'newline-mark whitespace-active-style)) + t)) (defsubst whitespace-char-valid-p (char) commit cb29a3816489a9bb5472bb3dfe4b64687419cb2e Author: Juri Linkov Date: Tue Oct 15 00:50:24 2019 +0300 Set tab-line face height to 0.9. * lisp/tab-line.el (tab-line): Set :height to 0.9. * lisp/tab-bar.el (tab-bar): Remove :height. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index e96d5d15b2..23ac243f53 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -50,7 +50,6 @@ (defface tab-bar '((((type x w32 ns) (class color)) - :height 1.1 :inherit variable-pitch :background "grey85" :foreground "black") diff --git a/lisp/tab-line.el b/lisp/tab-line.el index 69b510b64c..4397cae255 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -44,6 +44,7 @@ (defface tab-line '((((type x w32 ns) (class color)) :inherit variable-pitch + :height 0.9 :background "grey85" :foreground "black") (((type x) (class mono)) commit 75939b84e4d15cddd9d847ac9b340f9dffb01426 Author: Lars Ingebrigtsen Date: Mon Oct 14 23:36:51 2019 +0200 Remove the find-file-visit-truename safe-local-variable * lisp/files.el (find-file-visit-truename): Remove the safe-local-variable put, because the variable is checked too late to actually make a difference (bug#36830). diff --git a/lisp/files.el b/lisp/files.el index 9f22210e2a..1078b0c4c9 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -180,7 +180,6 @@ chasing all links both at the file level and at the levels of the containing directories." :type 'boolean :group 'find-file) -(put 'find-file-visit-truename 'safe-local-variable 'booleanp) (defcustom revert-without-query nil "Specify which files should be reverted without query. commit ad6ea982e44424865864a4a5ea997e5f4e0cf9f9 Author: Štěpán Němec Date: Mon Oct 14 23:12:00 2019 +0200 quail/py-b5: Use U+3007 for ideographic zero (bug#3179) * leim/leim-ext.el ("quail/PY-b5"): Use U+3007 instead of U+25CB for ideographic zero. U+25CB (used previously) is only one of the several lookalikes (bug#3179). diff --git a/leim/leim-ext.el b/leim/leim-ext.el index de30a70f2a..8ad7e85caf 100644 --- a/leim/leim-ext.el +++ b/leim/leim-ext.el @@ -29,7 +29,7 @@ ;;; Code: (eval-after-load "quail/PY-b5" - '(quail-defrule "ling2" ?○ nil t)) + '(quail-defrule "ling2" ?〇 nil t)) ;; Enable inputting full-width space (U+3000). (eval-after-load "quail/Punct" commit 2a41fe2eaf422fbd50c7c663eaa566f3801b97cf Author: Lars Ingebrigtsen Date: Mon Oct 14 22:49:22 2019 +0200 require-final-newline doc string clarification * lisp/files.el (require-final-newline): Mention that the variable applies to visited files (bug#34986). diff --git a/lisp/files.el b/lisp/files.el index 68a1284b38..9f22210e2a 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -337,7 +337,11 @@ Any other non-nil value means ask user whether to add a newline, when saving. A value of nil means don't add newlines. Certain major modes set this locally to the value obtained -from `mode-require-final-newline'." +from `mode-require-final-newline'. + +This variable is only heeded when visiting files (or saving +visited files). Writing data to the file system with +`write-region' and the like is not influenced by this variable." :safe #'symbolp :type '(choice (const :tag "When visiting" visit) (const :tag "When saving" t) commit 674515dd75aea441bc8847a73da18ddd303668e1 Author: Juri Linkov Date: Mon Oct 14 23:07:23 2019 +0300 Use variable-pitch fonts in tab-bar and tab-line faces * lisp/tab-bar.el (tab-bar): * lisp/tab-line.el (tab-line): Inherit face from variable-pitch. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index b7de64d4ae..e96d5d15b2 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -51,6 +51,7 @@ (defface tab-bar '((((type x w32 ns) (class color)) :height 1.1 + :inherit variable-pitch :background "grey85" :foreground "black") (((type x) (class mono)) @@ -62,7 +63,9 @@ :group 'tab-bar-faces) (defface tab-bar-tab - '((((class color) (min-colors 88)) + '((default + :inherit tab-bar) + (((class color) (min-colors 88)) :box (:line-width 1 :style released-button)) (t :inverse-video nil)) diff --git a/lisp/tab-line.el b/lisp/tab-line.el index b552df9ba5..69b510b64c 100644 --- a/lisp/tab-line.el +++ b/lisp/tab-line.el @@ -43,6 +43,7 @@ (defface tab-line '((((type x w32 ns) (class color)) + :inherit variable-pitch :background "grey85" :foreground "black") (((type x) (class mono)) @@ -54,9 +55,10 @@ :group 'tab-line-faces) (defface tab-line-tab - '((((class color) (min-colors 88)) - :box (:line-width 1 :style released-button) - :background "grey85") + '((default + :inherit tab-line) + (((class color) (min-colors 88)) + :box (:line-width 1 :style released-button)) (t :inverse-video nil)) "Tab line face for selected tab." commit 6aa0e0c754553e4beb7b4f2774bf7f0e29cb346b Author: Stefan Kangas Date: Mon Oct 14 21:36:14 2019 +0200 Clarify C void type description in semantic * admin/grammars/c.by: Clarify void type. (Bug#9222) diff --git a/admin/grammars/c.by b/admin/grammars/c.by index bd1b6a528e..10ff860e21 100644 --- a/admin/grammars/c.by +++ b/admin/grammars/c.by @@ -187,7 +187,7 @@ ;; Types %token VOID "void" -%put VOID summary "Built in typeless type: void" +%put VOID summary "Built in type: void" %token CHAR "char" %put CHAR summary "Integral Character Type: (0 to 256)" %token WCHAR "wchar_t" commit dc31f254b622ed145e6f71a432fe306b96b3c7a8 Author: Lars Ingebrigtsen Date: Mon Oct 14 21:29:48 2019 +0200 dired-do-shell-command doc string fix * lisp/dired-aux.el (dired-do-shell-command): Mention the guesser variables (bug#16562). diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index 8bda25e9e3..b3ff244362 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -743,7 +743,11 @@ instead of in a subdir. In a noninteractive call (from Lisp code), you must specify the list of file names explicitly with the FILE-LIST argument, which -can be produced by `dired-get-marked-files', for example." +can be produced by `dired-get-marked-files', for example. + +`dired-guess-shell-alist-default' and +`dired-guess-shell-alist-user' are consulted when the user is +prompted for the shell command to use interactively." ;;Functions dired-run-shell-command and dired-shell-stuff-it do the ;;actual work and can be redefined for customization. (interactive commit 561570475e99e1591df0b200facde22983754cf6 Author: Juri Linkov Date: Mon Oct 14 22:14:15 2019 +0300 Fix initial value of frame-inhibit-implied-resize * src/frame.c (syms_of_frame): Update doc string and default value of frame-inhibit-implied-resize in NS to include 'tab-bar-lines. diff --git a/src/frame.c b/src/frame.c index f7e65be727..cc76cf4f69 100644 --- a/src/frame.c +++ b/src/frame.c @@ -6290,24 +6290,19 @@ width by the width of one scroll bar provided this option is nil and keep it unchanged if this option is either t or a list containing `vertical-scroll-bars'. -In NS that use the external tool bar and no tab bar, the default value -is nil which means that changing any of the parameters listed above -may change the size of the frame. In GTK+ that use the external tool -bar, the default value is \\='(tab-bar-lines) which means that -adding/removing a tab bar does not change the frame height. On all -other types of GUI frames, the default value is \\='(tab-bar-lines -tool-bar-lines) which means that adding/removing a tool bar or tab bar -does not change the frame height. Otherwise it's t which means the -frame size never changes implicitly when there's no window -system support. +In GTK+ and NS that use the external tool bar, the default value is +\\='(tab-bar-lines) which means that adding/removing a tab bar does +not change the frame height. On all other types of GUI frames, the +default value is \\='(tab-bar-lines tool-bar-lines) which means that +adding/removing a tool bar or tab bar does not change the frame +height. Otherwise it's t which means the frame size never changes +implicitly when there's no window system support. Note that when a frame is not large enough to accommodate a change of any of the parameters listed above, Emacs may try to enlarge the frame even if this option is non-nil. */); #if defined (HAVE_WINDOW_SYSTEM) -#if defined (HAVE_NS) - frame_inhibit_implied_resize = Qnil; -#elif defined (USE_GTK) +#if defined (USE_GTK) || defined (HAVE_NS) frame_inhibit_implied_resize = list1 (Qtab_bar_lines); #else frame_inhibit_implied_resize = list2 (Qtab_bar_lines, Qtool_bar_lines); commit ad30f1e5fc955d95ebc09016f3b95afc6f594010 Author: Eli Zaretskii Date: Mon Oct 14 20:23:53 2019 +0300 Minor fixes in Introduction to Emacs Lisp * doc/lispintro/emacs-lisp-intro.texi (if, save-excursion): 'defun' is a macro, not a special form anymore. (Bug#37747) diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 3e43f7f09f..489ba8d6ef 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -3826,12 +3826,11 @@ delimit them from the body of the @code{let}. @findex if @cindex Conditional with @code{if} -A third special form, in addition to @code{defun} and @code{let}, is the -conditional @code{if}. This form is used to instruct the computer to -make decisions. You can write function definitions without using -@code{if}, but it is used often enough, and is important enough, to be -included here. It is used, for example, in the code for the -function @code{beginning-of-buffer}. +Anoter special form is the conditional @code{if}. This form is used +to instruct the computer to make decisions. You can write function +definitions without using @code{if}, but it is used often enough, and +is important enough, to be included here. It is used, for example, in +the code for the function @code{beginning-of-buffer}. The basic idea behind an @code{if}, is that @emph{if} a test is true, @emph{then} an expression is evaluated. If the test is not true, the @@ -4204,8 +4203,8 @@ On the other hand, this function returns @code{nil} if the test is false. @findex point @findex mark -The @code{save-excursion} function is the third and final special form -that we will discuss in this chapter. +The @code{save-excursion} function is the final special form that we +will discuss in this chapter. In Emacs Lisp programs used for editing, the @code{save-excursion} function is very common. It saves the location of point, commit 83010ae0fedf150e590eb38eadab0110946d8206 Author: Juri Linkov Date: Mon Oct 14 19:51:51 2019 +0300 * lisp/tab-bar.el (tab-bar-tab-name-current): Fix with buffer-name. diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 52245dd78f..b7de64d4ae 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -271,7 +271,7 @@ from all windows in the window configuration." (defun tab-bar-tab-name-current () "Generate tab name from the buffer of the selected window." - (window-buffer (minibuffer-selected-window))) + (buffer-name (window-buffer (minibuffer-selected-window)))) (defun tab-bar-tab-name-current-with-count () "Generate tab name from the buffer of the selected window. commit 668137acfbcb71108748195078d11ac3433f1f3f Author: Eli Zaretskii Date: Mon Oct 14 17:35:42 2019 +0300 ; Minor copyedits of recent documentation changes * etc/NEWS: * doc/lispref/display.texi (Face Attributes): Fix documentation of the ':extend' face attribute. diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 1678d32db0..f35b11f849 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2484,14 +2484,16 @@ attributes from faces earlier in the list override those from later faces. @item :extend -Whether or not this face will be extended until the end of the window. -The value should be @code{t} to extend until end of the window using -this face or @code{nil} fill the space between the end of the line and -the end of the window with the default face. When a face is conformed -by merging multiple other faces; only those with @code{:extend t} will -be merged to conform a new face to extend until end of window. By -default only @code{region} and @code{hl-line} have this attribute set -to @code{t}. +Whether or not this face will be extended beyond end of line and will +affect the display of the empty space between the end of line and the +edge of the window. The value should be @code{t} to display the empty +space between end of line and edge of the window using this face, or +@code{nil} to not use this face for the space between the end of the +line and the edge of the window. When Emacs merges several faces for +displaying the empty space beyond end of line, only those faces with +@code{:extend} non-@code{nil} will be merged. By default, only +@code{region} and @code{hl-line} faces have this attribute set to +@code{t}. @end table diff --git a/etc/NEWS b/etc/NEWS index c48184aec2..ff613ecd41 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -389,10 +389,11 @@ to 'completion-styles' or 'completion-category-overrides' to use it. +++ ** New face attribute ':extend' to control face extension at EOL. -There is a new face attribute :extend to use the face attributes to -extend after the end of the line until the end of the window. Such -:extend is set to nil by default in all faces except for 'hl-line' and -'region' because those extend until the end of the window by default. +The new face attribute ':extend' controls whether to use the face for +displaying the empty space beyond end of line (EOL) till the edge of +the window. By default, this attribute is non-nil only for 'region' +and 'hl-line' faces; any other face that crosses end of line will not +affect the display of the empty space at EOL. ** Connection-local variables commit ed29d0239a03b6eee418e438edee6b2df7612606 Author: Stefan Kangas Date: Mon Oct 14 16:00:05 2019 +0200 Improve documentation of dired-do-chmod * lisp/dired-aux.el (dired-do-chmod): Doc fix. The part about MS-Windows was written by Eli Zaretskii. (Bug#24897) diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el index bfc37c5cde..8bda25e9e3 100644 --- a/lisp/dired-aux.el +++ b/lisp/dired-aux.el @@ -365,9 +365,17 @@ List has a form of (file-name full-file-name (attribute-list))." ;;;###autoload (defun dired-do-chmod (&optional arg) "Change the mode of the marked (or next ARG) files. -Symbolic modes like `g+w' are allowed. -Type M-n to pull the file attributes of the file at point -into the minibuffer." +Both octal numeric modes like `644' and symbolic modes like `g+w' +are supported. Type M-n to pull the file attributes of the file +at point into the minibuffer. + +See Info node `(coreutils)File permissions' for more information. +Alternatively, see the man page for \"chmod\", using the command +\\[man] in Emacs. + +Note that on MS-Windows only the `w' (write) bit is meaningful: +resetting it makes the file read-only. Changing any other bit +has no effect on MS-Windows." (interactive "P") (let* ((files (dired-get-marked-files t arg nil nil t)) ;; The source of default file attributes is the file at point. commit 08f6c2a8c972b8c323cd24863fa35fb590689de3 Author: Philipp Stephani Date: Sun Oct 13 17:26:10 2019 +0200 Enable modules by default. The interface has been stable since Emacs 25, and most bugs are fixed by now. * configure.ac: Enable modules by default. diff --git a/configure.ac b/configure.ac index 7435f2e8da..33d725c804 100644 --- a/configure.ac +++ b/configure.ac @@ -461,7 +461,7 @@ OPTION_DEFAULT_ON([gsettings],[don't compile with GSettings support]) OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support]) OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support]) OPTION_DEFAULT_ON([zlib],[don't compile with zlib decompression support]) -OPTION_DEFAULT_OFF([modules],[compile with dynamic modules support]) +OPTION_DEFAULT_ON([modules],[compile with dynamic modules support]) OPTION_DEFAULT_ON([threads],[don't compile with elisp threading support]) AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB], diff --git a/etc/NEWS b/etc/NEWS index 59237267f0..c48184aec2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -131,6 +131,9 @@ builds respectively. ** New make target 'help' shows a summary of common make targets. +** Emacs now builds with dynamic module support by default. Pass +'--without-modules' to 'configure' to disable dynamic module support. + * Startup Changes in Emacs 27.1 commit d2d658320ee91ed4f61becd5ca996bd9033b7327 Author: Michael Albinus Date: Mon Oct 14 14:53:29 2019 +0200 Suppress eager completion on not connected hosts in Tramp * lisp/net/tramp.el (tramp-completion-handle-file-name-completion): Bind `non-essential' to t. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 2a60aff383..e51a1c7f8a 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2597,11 +2597,13 @@ not in completion mode." (defun tramp-completion-handle-file-name-completion (filename directory &optional predicate) "Like `file-name-completion' for Tramp files." - (try-completion - filename - (mapcar #'list (file-name-all-completions filename directory)) - (when (and predicate (tramp-connectable-p directory)) - (lambda (x) (funcall predicate (expand-file-name (car x) directory)))))) + ;; Suppress eager completion on not connected hosts. + (let ((non-essential t)) + (try-completion + filename + (mapcar #'list (file-name-all-completions filename directory)) + (when (and predicate (tramp-connectable-p directory)) + (lambda (x) (funcall predicate (expand-file-name (car x) directory))))))) ;; I misuse a little bit the `tramp-file-name' structure in order to ;; handle completion possibilities for partial methods / user names / commit 3d6075e3ee8c447f8974b37007a1b1ae1af8917c Merge: a122ca6907 7a10082093 Author: Jimmy Aguilar Mena Date: Mon Oct 14 14:29:47 2019 +0200 Merge branch 'feature/extend_face_id' New face attribute :extend to control the face extension after EOL. necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit. commit 7a10082093791f0e035e4f9f95a774a7be1cd586 (refs/remotes/origin/feature/extend_face_id) Author: Jimmy Aguilar Mena Date: Sun Oct 13 23:20:22 2019 +0200 Fix issue calling face_at_pos. *src/xdisp.c (extend_face_to_end_of_line): Add extra condition when producing glyphs from a C string to not call face_at_pos. diff --git a/src/xdisp.c b/src/xdisp.c index d54b717a50..30be492d9b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21578,7 +21578,8 @@ extend_face_to_end_of_line (struct it *it) || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) return; - const int extend_face_id = (it->face_id == DEFAULT_FACE_ID) + const int extend_face_id = (it->face_id == DEFAULT_FACE_ID + || it->s != NULL) ? DEFAULT_FACE_ID : face_at_pos (it, LFACE_EXTEND_INDEX); commit 501846c85932f1c11405f0a1748b884074a76004 Author: Jimmy Aguilar Mena Date: Sun Oct 13 16:56:50 2019 +0200 Modify face_at_pos to not modify change IT. src/xdisp.c (face_at_pos): Removed code to that modified it->start_of_box_run_p and it->face_box_p. This function should not modify it. (handle_face_prop): Added code to update it->start_of_box_run_p and it->face_box_p. (underlying_face_id): Input IT made CONST. diff --git a/src/xdisp.c b/src/xdisp.c index 6c0b1f8848..d54b717a50 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -993,7 +993,7 @@ static int handle_display_spec (struct it *, Lisp_Object, Lisp_Object, static int handle_single_display_spec (struct it *, Lisp_Object, Lisp_Object, Lisp_Object, struct text_pos *, ptrdiff_t, int, bool, bool); -static int underlying_face_id (struct it *); +static int underlying_face_id (const struct it *); #define face_before_it_pos(IT) face_before_or_after_it_pos (IT, true) #define face_after_it_pos(IT) face_before_or_after_it_pos (IT, false) @@ -4158,23 +4158,20 @@ handle_fontified_prop (struct it *it) ***********************************************************************/ static int -face_at_pos (struct it *it, enum lface_attribute_index attr_filter) +face_at_pos (const struct it *it, enum lface_attribute_index attr_filter) { - int new_face_id; ptrdiff_t next_stop; - const bool is_string = STRINGP (it->string); - - if (!is_string) - { - new_face_id - = face_at_buffer_position (it->w, - IT_CHARPOS (*it), - &next_stop, - (IT_CHARPOS (*it) - + TEXT_PROP_DISTANCE_LIMIT), - false, it->base_face_id, - attr_filter); - } + + if (!STRINGP (it->string)) + { + return face_at_buffer_position (it->w, + IT_CHARPOS (*it), + &next_stop, + (IT_CHARPOS (*it) + + TEXT_PROP_DISTANCE_LIMIT), + false, it->base_face_id, + attr_filter); + } else { int base_face_id; @@ -4183,7 +4180,7 @@ face_at_pos (struct it *it, enum lface_attribute_index attr_filter) Lisp_Object from_overlay = (it->current.overlay_string_index >= 0 ? it->string_overlays[it->current.overlay_string_index - % OVERLAY_STRING_CHUNK_SIZE] + % OVERLAY_STRING_CHUNK_SIZE] : Qnil); /* See if we got to this string directly or indirectly from @@ -4198,7 +4195,7 @@ face_at_pos (struct it *it, enum lface_attribute_index attr_filter) if (it->stack[i].current.overlay_string_index >= 0) from_overlay = it->string_overlays[it->stack[i].current.overlay_string_index - % OVERLAY_STRING_CHUNK_SIZE]; + % OVERLAY_STRING_CHUNK_SIZE]; else if (! NILP (it->stack[i].from_overlay)) from_overlay = it->stack[i].from_overlay; @@ -4213,11 +4210,11 @@ face_at_pos (struct it *it, enum lface_attribute_index attr_filter) only on text properties and ignores overlays. */ base_face_id = face_for_overlay_string (it->w, - IT_CHARPOS (*it), - &next_stop, - (IT_CHARPOS (*it) - + TEXT_PROP_DISTANCE_LIMIT), - false, + IT_CHARPOS (*it), + &next_stop, + (IT_CHARPOS (*it) + + TEXT_PROP_DISTANCE_LIMIT), + false, from_overlay); } else @@ -4247,14 +4244,24 @@ face_at_pos (struct it *it, enum lface_attribute_index attr_filter) : underlying_face_id (it); } - new_face_id = face_at_string_position (it->w, - it->string, - IT_STRING_CHARPOS (*it), - bufpos, - &next_stop, - base_face_id, false, - attr_filter); - } /* !is_string. */ + return face_at_string_position (it->w, + it->string, + IT_STRING_CHARPOS (*it), + bufpos, + &next_stop, + base_face_id, false, + attr_filter); + } // !STRINGP (it->string)) +} + + +/* Set up iterator IT from face properties at its current position. + Called from handle_stop. */ +static enum prop_handled +handle_face_prop (struct it *it) +{ + const int new_face_id = face_at_pos (it, 0); + /* Is this a start of a run of characters with box face? Caveat: this can be called for a freshly initialized @@ -4273,11 +4280,11 @@ face_at_pos (struct it *it, enum lface_attribute_index attr_filter) /* If the value of face_id of the iterator is -1, we have to look in front of IT's position and see whether there is a face there that's different from new_face_id. */ - if (!is_string + if (!STRINGP (it->string) && !old_face && IT_CHARPOS (*it) > BEG) { - int prev_face_id = face_before_it_pos (it); + const int prev_face_id = face_before_it_pos (it); old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id); } @@ -4285,21 +4292,12 @@ face_at_pos (struct it *it, enum lface_attribute_index attr_filter) /* If the new face has a box, but the old face does not, this is the start of a run of characters with box face, i.e. this character has a shadow on the left side. */ + it->face_id = new_face_id; it->start_of_box_run_p = (new_face->box != FACE_NO_BOX && (old_face == NULL || !old_face->box)); it->face_box_p = new_face->box != FACE_NO_BOX; } - return new_face_id; -} - - -/* Set up iterator IT from face properties at its current position. - Called from handle_stop. */ -static enum prop_handled -handle_face_prop (struct it *it) -{ - it->face_id = face_at_pos (it, 0); return HANDLED_NORMALLY; } @@ -4310,7 +4308,7 @@ handle_face_prop (struct it *it) Otherwise, use the iterator's base_face_id. */ static int -underlying_face_id (struct it *it) +underlying_face_id (const struct it *it) { int face_id = it->base_face_id, i; commit cc47cd4202aa474cf83d6fc42d959460d3cf823f Author: Jimmy Aguilar Mena Date: Wed Oct 9 16:44:21 2019 +0200 ; extend_face_id and fill_column_indicator corrections *etc/NEWS: Correction for extend face and add some comments in the code. diff --git a/etc/NEWS b/etc/NEWS index 680ac03853..59237267f0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -385,10 +385,11 @@ simply, makes "foo" complete to both "barfoo" and "frodo". Add 'flex' to 'completion-styles' or 'completion-category-overrides' to use it. +++ -** There is a new face attribute :extend to use the face attributes to +** New face attribute ':extend' to control face extension at EOL. +There is a new face attribute :extend to use the face attributes to extend after the end of the line until the end of the window. Such -:extend is set to nil by default in all faces except for `hl-line` and -`region` because those extend until the end of the window by default. +:extend is set to nil by default in all faces except for 'hl-line' and +'region' because those extend until the end of the window by default. ** Connection-local variables diff --git a/src/xdisp.c b/src/xdisp.c index 45462c5ac5..6c0b1f8848 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -442,7 +442,7 @@ fill_column_indicator_column (struct it *it, int char_width) ? BVAR (current_buffer, fill_column) : Vdisplay_fill_column_indicator_column); - /* The stretch width needs to considet the latter + /* The stretch width needs to consider the latter added glyph in append_space_for_newline. */ if (RANGED_FIXNUMP (0, col, INT_MAX)) { @@ -21691,6 +21691,9 @@ extend_face_to_end_of_line (struct it *it) && indicator_column < it->last_visible_x) { + /* Here we substract char_width because we want the + column indicator in the column INDICATOR_COLUMN, not + after it. */ const int stretch_width = indicator_column - it->current_x - char_width; @@ -21851,6 +21854,11 @@ extend_face_to_end_of_line (struct it *it) default_face->id : face->id); /* Display fill-column indicator if needed. */ + /* We need to subtract 1 to the indicator_column here because we + will add the indicator IN the column indicator number, not + after it. We compare the variable it->current_x before + producing the glyph. When FRAME_WINDOW_P we substract + CHAR_WIDTH calculating STRETCH_WIDTH for the same reason. */ const int indicator_column = fill_column_indicator_column (it, 1) - 1; do diff --git a/src/xfaces.c b/src/xfaces.c index cc65527fe6..5a741ae8cc 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -2284,7 +2284,7 @@ filter_face_ref (Lisp_Object face_ref, ATTR_FILTER is the index of a parameter that conditions the merging for named faces (case 1) to only the face_ref where - lface[merge_face_ref] is non-nil. To merge unconditionally set this + lface[merge_face_ref] is non-nil. To merge unconditionally set this value to 0. FACE_REF may be a single face specification or a list of such commit 0cf11eb2e80ec1e038654780c4833bea05ead05e Author: Jimmy Aguilar Mena Date: Sun Sep 29 21:41:00 2019 +0200 *etc/NEWS: Added comment about :extend face attribute in NEWS. diff --git a/etc/NEWS b/etc/NEWS index 34925c1af7..680ac03853 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -384,6 +384,12 @@ matches strings where the pattern appears as a subsequence. Put simply, makes "foo" complete to both "barfoo" and "frodo". Add 'flex' to 'completion-styles' or 'completion-category-overrides' to use it. ++++ +** There is a new face attribute :extend to use the face attributes to +extend after the end of the line until the end of the window. Such +:extend is set to nil by default in all faces except for `hl-line` and +`region` because those extend until the end of the window by default. + ** Connection-local variables +++ commit 424e6f54e5c3592f32016267179171b40dafbb99 Author: Jimmy Aguilar Mena Date: Sat Sep 21 23:34:40 2019 +0200 Document new :extend face attribute in manuals. Some stylistic corrections in src/xdisp.c and src/xfaces.c. diff --git a/doc/emacs/mark.texi b/doc/emacs/mark.texi index bbeb4cb039..f012d72fc2 100644 --- a/doc/emacs/mark.texi +++ b/doc/emacs/mark.texi @@ -23,6 +23,11 @@ When the mark is active, we say also that the region is active; Emacs indicates its extent by highlighting the text within it, using the @code{region} face (@pxref{Face Customization}). +This is one of the few faces that has the @code{:extend t} attribute +by default, which implies that the same face is used to highlight the +text and space between end of line and the window border. To +highlight only the text you could set this attribute to @code{nil}. + @cindex deactivating the mark After certain non-motion commands, including any command that changes the text in the buffer, Emacs automatically @dfn{deactivates} diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 61bd4ce883..1678d32db0 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2482,6 +2482,17 @@ faces (@pxref{Displaying Faces}). If the face to inherit from is never merges @code{:inherit} attributes. If a list of faces is used, attributes from faces earlier in the list override those from later faces. + +@item :extend +Whether or not this face will be extended until the end of the window. +The value should be @code{t} to extend until end of the window using +this face or @code{nil} fill the space between the end of the line and +the end of the window with the default face. When a face is conformed +by merging multiple other faces; only those with @code{:extend t} will +be merged to conform a new face to extend until end of window. By +default only @code{region} and @code{hl-line} have this attribute set +to @code{t}. + @end table @defun font-family-list &optional frame @@ -2840,6 +2851,11 @@ This sets the @code{:inverse-video} attribute of @var{face} to @deffn Command invert-face face &optional frame This swaps the foreground and background colors of face @var{face}. +@end deffn + +@deffn Command set-face-extend face extend &optional frame +This sets the @code{:extend} attribute of @var{face} to +@var{extend}. @end deffn The following functions examine the attributes of a face. They @@ -2900,6 +2916,12 @@ This function returns non-@code{nil} if face @var{face} specifies a non-@code{nil} @code{:inverse-video} attribute. @end defun +@defun face-extend-p face &optional frame +This function returns non-@code{nil} if face @var{face} specifies +a non-@code{nil} @code{:extend} attribute. +@end defun + + @node Displaying Faces @subsection Displaying Faces @cindex displaying faces diff --git a/src/xdisp.c b/src/xdisp.c index 2c69a1f04f..45462c5ac5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21400,7 +21400,7 @@ append_space_for_newline (struct it *it, bool default_face_p) const int local_default_face_id = lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); struct face* default_face = - FACE_FROM_ID (it->f, local_default_face_id); + FACE_FROM_ID_OR_NULL (it->f, local_default_face_id); #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (it->f)) @@ -21534,7 +21534,7 @@ append_space_for_newline (struct it *it, bool default_face_p) g->ascent = it->max_ascent; g->descent = it->max_descent; } -#endif // HAVE_WINDOW_SYSTEM +#endif /* HAVE_WINDOW_SYSTEM */ it->override_ascent = -1; it->constrain_row_ascent_descent_p = false; it->current_x = saved_x; @@ -21722,8 +21722,6 @@ extend_face_to_end_of_line (struct it *it) } } - /* Restore the face after the indicator was generated. */ - /* If there is space after the indicator generate an extra empty glyph to restore the face. Issue was observed in X systems. */ diff --git a/src/xfaces.c b/src/xfaces.c index 5577640325..cc65527fe6 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -2282,7 +2282,7 @@ filter_face_ref (Lisp_Object face_ref, of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face inheritance or list structure; it may be 0 for most callers. - attr_filter is the index of a parameter that conditions the merging + ATTR_FILTER is the index of a parameter that conditions the merging for named faces (case 1) to only the face_ref where lface[merge_face_ref] is non-nil. To merge unconditionally set this value to 0. @@ -6043,7 +6043,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) which a different face is needed, as far as text properties and overlays are concerned. W is a window displaying current_buffer. - attr_filter is passed merge_face_ref. + ATTR_FILTER is passed merge_face_ref. REGION_BEG, REGION_END delimit the region, so it can be highlighted. @@ -6126,7 +6126,8 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, } /* Optimize common cases where we can use the default face. */ - if (noverlays == 0 && NILP (prop)) + if (noverlays == 0 + && NILP (prop)) { SAFE_FREE (); return default_face->id; commit 38ee12d5a2df150e6ba9023d968d1c49c85ca6e1 Author: Jimmy Aguilar Mena Date: Sat Sep 21 20:33:38 2019 +0200 Fixed merge_face_ref recursive calls. * src/xfaces.c (merge_face_ref): Fixed recursive calls to consider filter when CONSP (face_ref). diff --git a/src/xdisp.c b/src/xdisp.c index d99bc4323d..2c69a1f04f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21563,7 +21563,6 @@ append_space_for_newline (struct it *it, bool default_face_p) static void extend_face_to_end_of_line (struct it *it) { - struct face *face; struct frame *f = it->f; /* If line is already filled, do nothing. Non window-system frames @@ -21588,9 +21587,9 @@ extend_face_to_end_of_line (struct it *it) /* Face extension extends the background and box of IT->extend_face_id to the end of the line. If the background equals the background of the frame, we don't have to do anything. */ - face = FACE_FROM_ID (f, (it->face_before_selective_p - ? it->saved_face_id - : extend_face_id)); + struct face *face = FACE_FROM_ID (f, (it->face_before_selective_p + ? it->saved_face_id + : extend_face_id)); if (FRAME_WINDOW_P (f) && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) diff --git a/src/xfaces.c b/src/xfaces.c index 082019d74e..5577640325 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -2529,7 +2529,7 @@ merge_face_ref (struct window *w, normal face reference. */ if (! merge_face_ref (w, f, value, to, err_msgs, named_merge_points, - 0)) + attr_filter)) err = true; } else if (EQ (keyword, QCextend)) @@ -2560,10 +2560,10 @@ merge_face_ref (struct window *w, if (! NILP (next)) ok = merge_face_ref (w, f, next, to, err_msgs, - named_merge_points, 0); + named_merge_points, attr_filter); if (! merge_face_ref (w, f, first, to, err_msgs, - named_merge_points, 0)) + named_merge_points, attr_filter)) ok = false; } } commit 92445de0a41bd138cc5a81cd1038720e20896535 Author: Jimmy Aguilar Mena Date: Sat Sep 21 19:57:17 2019 +0200 Optimization in extend_face * src/xdisp.c (extend_face_to_end_of_line): Optimization to void calls to face_at_pos. diff --git a/src/xdisp.c b/src/xdisp.c index 5f7799e5b6..d99bc4323d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -434,7 +434,7 @@ static int fill_column_indicator_column (struct it *it, int char_width) { if (Vdisplay_fill_column_indicator - && it->w->pseudo_window_p == 0 + && !it->w->pseudo_window_p && it->continuation_lines_width == 0 && CHARACTERP (Vdisplay_fill_column_indicator_character)) { @@ -21581,8 +21581,9 @@ extend_face_to_end_of_line (struct it *it) || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) return; - const int extend_face_id - = face_at_pos (it, LFACE_EXTEND_INDEX); + const int extend_face_id = (it->face_id == DEFAULT_FACE_ID) + ? DEFAULT_FACE_ID + : face_at_pos (it, LFACE_EXTEND_INDEX); /* Face extension extends the background and box of IT->extend_face_id to the end of the line. If the background equals the background commit acc720988446dd047d9496f9fb958b703e29dc8d Author: Jimmy Aguilar Mena Date: Sat Sep 21 17:04:09 2019 +0200 Extend_face simplify. * src/dispextern.h (struct it): Removed extend_face unneeded members. * src/xdisp.c (handle_face_prop_general): renamed to face_at_pos and removed input parameter initial_face_id. Updated all occurrences. diff --git a/src/dispextern.h b/src/dispextern.h index 8bbabbe30d..0615b16d71 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2374,7 +2374,7 @@ struct it /* Face id of the iterator saved in case a glyph from dpvec contains a face. The face is restored when all glyphs from dpvec have been delivered. */ - int saved_face_id, saved_extend_face_id; + int saved_face_id; /* Vector of glyphs for control character translation. The pointer dpvec is set to ctl_chars when a control character is translated. @@ -2436,7 +2436,7 @@ struct it ptrdiff_t prev_stop; ptrdiff_t base_level_stop; struct composition_it cmp_it; - int face_id, extend_face_id; + int face_id; /* Save values specific to a given method. */ union { @@ -2494,9 +2494,6 @@ struct it /* Face to use. */ int face_id; - /* Face to extend at EOL/ */ - int extend_face_id; - /* Setting of buffer-local variable selective-display-ellipses. */ bool_bf selective_display_ellipsis_p : 1; diff --git a/src/xdisp.c b/src/xdisp.c index 5ed6323409..5f7799e5b6 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4158,8 +4158,7 @@ handle_fontified_prop (struct it *it) ***********************************************************************/ static int -handle_face_prop_general (struct it *it, int initial_face_id, - enum lface_attribute_index attr_filter) +face_at_pos (struct it *it, enum lface_attribute_index attr_filter) { int new_face_id; ptrdiff_t next_stop; @@ -4263,13 +4262,13 @@ handle_face_prop_general (struct it *it, int initial_face_id, face will not change until limit, i.e. if the new face has a box, all characters up to limit will have one. But, as usual, we don't know whether limit is really the end. */ - if (new_face_id != initial_face_id) + if (new_face_id != it->face_id) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); /* If it->face_id is -1, old_face below will be NULL, see the definition of FACE_FROM_ID_OR_NULL. This will happen if this is the initial call that gets the face. */ - struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, initial_face_id); + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); /* If the value of face_id of the iterator is -1, we have to look in front of IT's position and see whether there is a @@ -4300,7 +4299,7 @@ handle_face_prop_general (struct it *it, int initial_face_id, static enum prop_handled handle_face_prop (struct it *it) { - it->face_id = handle_face_prop_general (it, it->face_id, 0); + it->face_id = face_at_pos (it, 0); return HANDLED_NORMALLY; } @@ -21582,15 +21581,15 @@ extend_face_to_end_of_line (struct it *it) || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) return; - it->extend_face_id - = handle_face_prop_general (it, it->extend_face_id, LFACE_EXTEND_INDEX); + const int extend_face_id + = face_at_pos (it, LFACE_EXTEND_INDEX); /* Face extension extends the background and box of IT->extend_face_id to the end of the line. If the background equals the background of the frame, we don't have to do anything. */ face = FACE_FROM_ID (f, (it->face_before_selective_p - ? it->saved_face_id - : it->extend_face_id)); + ? it->saved_face_id + : extend_face_id)); if (FRAME_WINDOW_P (f) && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) @@ -21683,7 +21682,7 @@ extend_face_to_end_of_line (struct it *it) Lisp_Object save_object = it->object; const int saved_face_id = it->face_id; - it->face_id = it->extend_face_id; + it->face_id = extend_face_id; it->avoid_cursor_p = true; it->object = Qnil; @@ -21717,7 +21716,7 @@ extend_face_to_end_of_line (struct it *it) = XFIXNAT (Vdisplay_fill_column_indicator_character); it->face_id = merge_faces (it->w, Qfill_column_indicator, - 0, it->extend_face_id); + 0, extend_face_id); PRODUCE_GLYPHS (it); it->face_id = save_face_id; } @@ -21864,7 +21863,7 @@ extend_face_to_end_of_line (struct it *it) { int saved_face_id = it->face_id; it->face_id - = merge_faces (it->w, Qfill_column_indicator, 0, it->extend_face_id); + = merge_faces (it->w, Qfill_column_indicator, 0, extend_face_id); it->c = it->char_to_display = XFIXNAT (Vdisplay_fill_column_indicator_character); commit 2b80b4dc460c29096a39a5f3a6b474203599cfe7 Author: Jimmy Aguilar Mena Date: Sun Sep 15 23:14:48 2019 +0200 Added parameter attr_filter to face_at_string_position. Update all the occurrences in src/xdisp.c and src/xfaces.c diff --git a/src/dispextern.h b/src/dispextern.h index 5db3ae88bf..8bbabbe30d 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3559,7 +3559,8 @@ int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, bool, Lisp_Object); int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, - ptrdiff_t *, enum face_id, bool); + ptrdiff_t *, enum face_id, bool, + enum lface_attribute_index); int merge_faces (struct window *, Lisp_Object, int, int); int compute_char_face (struct frame *, int, Lisp_Object); void free_all_realized_faces (Lisp_Object); diff --git a/src/font.c b/src/font.c index e1e33ab8b2..7fdadb17c1 100644 --- a/src/font.c +++ b/src/font.c @@ -3785,7 +3785,7 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, if (STRINGP (string)) face_id = face_at_string_position (w, string, pos, 0, &endptr, - DEFAULT_FACE_ID, 0); + DEFAULT_FACE_ID, false, 0); else face_id = face_at_buffer_position (w, pos, &endptr, pos + 100, false, -1, 0); @@ -3841,7 +3841,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, : lookup_basic_face (w, f, DEFAULT_FACE_ID); face_id = face_at_string_position (w, string, pos, 0, &ignore, - face_id, false); + face_id, false, 0); } face = FACE_FROM_ID (f, face_id); } diff --git a/src/xdisp.c b/src/xdisp.c index d77fe5d40a..5ed6323409 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4173,7 +4173,8 @@ handle_face_prop_general (struct it *it, int initial_face_id, &next_stop, (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), - false, it->base_face_id, attr_filter); + false, it->base_face_id, + attr_filter); } else { @@ -4218,7 +4219,7 @@ handle_face_prop_general (struct it *it, int initial_face_id, (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), false, - from_overlay); + from_overlay); } else { @@ -4252,7 +4253,8 @@ handle_face_prop_general (struct it *it, int initial_face_id, IT_STRING_CHARPOS (*it), bufpos, &next_stop, - base_face_id, false); + base_face_id, false, + attr_filter); } /* !is_string. */ /* Is this a start of a run of characters with box face? @@ -4422,12 +4424,9 @@ face_before_or_after_it_pos (struct it *it, bool before_p) base_face_id = underlying_face_id (it); /* Get the face for ASCII, or unibyte. */ - face_id = face_at_string_position (it->w, - it->string, - charpos, - bufpos, - &next_check_charpos, - base_face_id, false); + face_id = face_at_string_position (it->w, it->string, charpos, + bufpos, &next_check_charpos, + base_face_id, false, 0); /* Correct the face for charsets different from ASCII. Do it for the multibyte case only. The face returned above is @@ -7637,7 +7636,8 @@ get_next_display_element (struct it *it) next_face_id = face_at_string_position (it->w, base_string, CHARPOS (pos), 0, - &ignore, face_id, false); + &ignore, face_id, + false, 0); it->end_of_box_run_p = (FACE_FROM_ID (it->f, next_face_id)->box == FACE_NO_BOX); @@ -26569,8 +26569,8 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st /* Initialize the iterator IT for iteration over STRING beginning with index START. */ - reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, start, - precision, field_width, multibyte); + reseat_to_string (it, NILP (lisp_string) ? string : NULL, lisp_string, + start, precision, field_width, multibyte); if (string && STRINGP (lisp_string)) /* LISP_STRING is the one returned by decode_mode_spec. We should ignore its text properties. */ @@ -26585,7 +26585,7 @@ display_string (const char *string, Lisp_Object lisp_string, Lisp_Object face_st it->face_id = face_at_string_position (it->w, face_string, face_string_pos, - 0, &endptr, it->base_face_id, false); + 0, &endptr, it->base_face_id, false, 0); face = FACE_FROM_ID (it->f, it->face_id); it->face_box_p = face->box != FACE_NO_BOX; } @@ -32745,11 +32745,10 @@ note_mode_line_or_margin_highlight (Lisp_Object window, int x, int y, hlinfo->mouse_face_past_end = false; hlinfo->mouse_face_window = window; - hlinfo->mouse_face_face_id = face_at_string_position (w, string, - charpos, - 0, &ignore, - glyph->face_id, - true); + hlinfo->mouse_face_face_id = + face_at_string_position (w, string, charpos, 0, &ignore, + glyph->face_id, true, 0); + show_mouse_face (hlinfo, DRAW_MOUSE_FACE); mouse_face_shown = true; @@ -33175,7 +33174,7 @@ note_mouse_highlight (struct frame *f, int x, int y) hlinfo->mouse_face_window = window; hlinfo->mouse_face_face_id = face_at_string_position (w, object, pos, 0, &ignore, - glyph->face_id, true); + glyph->face_id, true, 0); show_mouse_face (hlinfo, DRAW_MOUSE_FACE); cursor = No_Cursor; } diff --git a/src/xfaces.c b/src/xfaces.c index d3851d0334..082019d74e 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6275,9 +6275,10 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos, int face_at_string_position (struct window *w, Lisp_Object string, - ptrdiff_t pos, ptrdiff_t bufpos, - ptrdiff_t *endptr, enum face_id base_face_id, - bool mouse_p) + ptrdiff_t pos, ptrdiff_t bufpos, + ptrdiff_t *endptr, enum face_id base_face_id, + bool mouse_p, + enum lface_attribute_index attr_filter) { Lisp_Object prop, position, end, limit; struct frame *f = XFRAME (WINDOW_FRAME (w)); @@ -6321,7 +6322,7 @@ face_at_string_position (struct window *w, Lisp_Object string, /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, NULL, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); /* Look up a realized face with the given face attributes, or realize a new one for ASCII characters. */ commit e1b5e80aad46bba39831ae4c0aa863e69c915b4c Author: Jimmy Aguilar Mena Date: Sat Sep 14 23:46:10 2019 +0200 Extend face hl-line after end-of-line * lisp/hl-line.el (face hl-line): Added extend attribute to hl-line face. diff --git a/lisp/hl-line.el b/lisp/hl-line.el index 8d929b8bb0..8d92e36214 100644 --- a/lisp/hl-line.el +++ b/lisp/hl-line.el @@ -78,7 +78,7 @@ when `global-hl-line-sticky-flag' is non-nil.") :group 'convenience) (defface hl-line - '((t :inherit highlight)) + '((t :inherit highlight :extend t)) "Default face for highlighting the current line in Hl-Line mode." :version "22.1" :group 'hl-line) commit ab22720651cd792d2ca5c0c3ec20a5249c1ce1f0 Author: Jimmy Aguilar Mena Date: Sat Sep 14 23:43:32 2019 +0200 Fix last change in append_space_for_newline. * src/xdisp.c (append_space_for_newline): Code refactor and simplification. diff --git a/src/xdisp.c b/src/xdisp.c index 8e87e8c0ac..d77fe5d40a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -434,6 +434,7 @@ static int fill_column_indicator_column (struct it *it, int char_width) { if (Vdisplay_fill_column_indicator + && it->w->pseudo_window_p == 0 && it->continuation_lines_width == 0 && CHARACTERP (Vdisplay_fill_column_indicator_character)) { @@ -21378,7 +21379,7 @@ append_space_for_newline (struct it *it, bool default_face_p) int saved_c = it->c, saved_len = it->len; int saved_char_to_display = it->char_to_display; int saved_x = it->current_x; - int saved_face_id = it->face_id; + const int saved_face_id = it->face_id; bool saved_box_end = it->end_of_box_run_p; struct text_pos saved_pos = it->position; Lisp_Object saved_object = it->object; @@ -21389,32 +21390,39 @@ append_space_for_newline (struct it *it, bool default_face_p) it->object = Qnil; it->len = 1; - int local_default_face_id = - lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); - struct face* default_face = - FACE_FROM_ID (it->f, local_default_face_id); - - /* Corner case for when display-fill-column-indicator-mode - is active and the extra character should be added in the - same place than the line. */ - int char_width = 1; + if (default_face_p #ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (it->f)) + || FRAME_WINDOW_P (it->f) +#endif + ) { - struct font *font = (default_face->font - ? default_face->font - : FRAME_FONT (it->f)); - char_width = (font->average_width - ? font->average_width - : font->space_width); - } + const int local_default_face_id = + lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); + struct face* default_face = + FACE_FROM_ID (it->f, local_default_face_id); + +#ifdef HAVE_WINDOW_SYSTEM + if (FRAME_WINDOW_P (it->f)) + { + struct font *font = (default_face->font + ? default_face->font + : FRAME_FONT (it->f)); + char_width = (font->average_width + ? font->average_width + : font->space_width); + } #endif + if (default_face_p) + it->face_id = local_default_face_id; + } + /* Corner case for when display-fill-column-indicator-mode + is active and the extra character should be added in the + same place than the line. */ + const int indicator_column = - (it->w->pseudo_window_p == 0 - ? fill_column_indicator_column (it, char_width) - : -1); + fill_column_indicator_column (it, char_width); if (it->current_x == indicator_column) { @@ -21424,31 +21432,26 @@ append_space_for_newline (struct it *it, bool default_face_p) = merge_faces (it->w, Qfill_column_indicator, 0, saved_face_id); face = FACE_FROM_ID (it->f, it->face_id); - goto produce_glyphs; } + else + { + it->c = it->char_to_display = ' '; + /* If the default face was remapped, be sure to use the + remapped face for the appended newline. */ - it->c = it->char_to_display = ' '; - /* If the default face was remapped, be sure to use the - remapped face for the appended newline. */ - it->face_id = default_face_p - ? local_default_face_id - : it->saved_face_id; - - - face = FACE_FROM_ID (it->f, it->face_id); - it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); - /* In R2L rows, we will prepend a stretch glyph that will - have the end_of_box_run_p flag set for it, so there's no - need for the appended newline glyph to have that flag - set. */ - if (it->glyph_row->reversed_p - /* But if the appended newline glyph goes all the way to - the end of the row, there will be no stretch glyph, - so leave the box flag set. */ - && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) - it->end_of_box_run_p = false; - - produce_glyphs: + face = FACE_FROM_ID (it->f, it->face_id); + it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); + /* In R2L rows, we will prepend a stretch glyph that will + have the end_of_box_run_p flag set for it, so there's no + need for the appended newline glyph to have that flag + set. */ + if (it->glyph_row->reversed_p + /* But if the appended newline glyph goes all the way to + the end of the row, there will be no stretch glyph, + so leave the box flag set. */ + && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) + it->end_of_box_run_p = false; + } PRODUCE_GLYPHS (it); #ifdef HAVE_WINDOW_SYSTEM if (FRAME_WINDOW_P (it->f)) @@ -21671,9 +21674,7 @@ extend_face_to_end_of_line (struct it *it) : font->space_width); const int indicator_column = - (it->w->pseudo_window_p == 0 - ? fill_column_indicator_column (it, char_width) - : -1); + fill_column_indicator_column (it, char_width); const char saved_char = it->char_to_display; const struct text_pos saved_pos = it->position; commit 95d1c3b23e5188f10b7552a0c90613eb66cd2d94 Author: Jimmy Aguilar Mena Date: Sat Sep 14 21:15:17 2019 +0200 Add space for cursor to work also in terminal. * src/xdisp.c (append_space_for_newline): Modified to add the space with the last face also in terminal interface. (fill_column_indicator_column): Modified to group more conditions. (extend_face_to_end_of_line): Simplified code in fill_column_indicator to use the new function. diff --git a/src/xdisp.c b/src/xdisp.c index ad4d69938c..8e87e8c0ac 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -431,7 +431,7 @@ static Lisp_Object list_of_error; met, return the (nonnegative) column number, else return a negative value. */ static int -fill_column_indicator_column (struct it *it) +fill_column_indicator_column (struct it *it, int char_width) { if (Vdisplay_fill_column_indicator && it->continuation_lines_width == 0 @@ -440,8 +440,16 @@ fill_column_indicator_column (struct it *it) Lisp_Object col = (EQ (Vdisplay_fill_column_indicator_column, Qt) ? BVAR (current_buffer, fill_column) : Vdisplay_fill_column_indicator_column); + + /* The stretch width needs to considet the latter + added glyph in append_space_for_newline. */ if (RANGED_FIXNUMP (0, col, INT_MAX)) - return XFIXNUM (col); + { + int icol = XFIXNUM (col); + if (!INT_MULTIPLY_WRAPV (char_width, icol, &icol) + && !INT_ADD_WRAPV (it->lnum_pixel_width, icol, &icol)) + return icol; + } } return -1; } @@ -4244,7 +4252,7 @@ handle_face_prop_general (struct it *it, int initial_face_id, bufpos, &next_stop, base_face_id, false); - } + } /* !is_string. */ /* Is this a start of a run of characters with box face? Caveat: this can be called for a freshly initialized @@ -21357,97 +21365,94 @@ compute_line_metrics (struct it *it) static bool append_space_for_newline (struct it *it, bool default_face_p) { -#ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (it->f)) + int n = it->glyph_row->used[TEXT_AREA]; + + if (it->glyph_row->glyphs[TEXT_AREA] + n + < it->glyph_row->glyphs[1 + TEXT_AREA]) { - int n = it->glyph_row->used[TEXT_AREA]; - - if (it->glyph_row->glyphs[TEXT_AREA] + n - < it->glyph_row->glyphs[1 + TEXT_AREA]) - { - /* Save some values that must not be changed. - Must save IT->c and IT->len because otherwise - ITERATOR_AT_END_P wouldn't work anymore after - append_space_for_newline has been called. */ - enum display_element_type saved_what = it->what; - int saved_c = it->c, saved_len = it->len; - int saved_char_to_display = it->char_to_display; - int saved_x = it->current_x; - int saved_face_id = it->face_id; - bool saved_box_end = it->end_of_box_run_p; - struct text_pos saved_pos; - Lisp_Object saved_object; - struct face *face; + /* Save some values that must not be changed. + Must save IT->c and IT->len because otherwise + ITERATOR_AT_END_P wouldn't work anymore after + append_space_for_newline has been called. */ + enum display_element_type saved_what = it->what; + int saved_c = it->c, saved_len = it->len; + int saved_char_to_display = it->char_to_display; + int saved_x = it->current_x; + int saved_face_id = it->face_id; + bool saved_box_end = it->end_of_box_run_p; + struct text_pos saved_pos = it->position; + Lisp_Object saved_object = it->object; + struct face *face; + + it->what = IT_CHARACTER; + memset (&it->position, 0, sizeof it->position); + it->object = Qnil; + it->len = 1; - saved_object = it->object; - saved_pos = it->position; + int local_default_face_id = + lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); + struct face* default_face = + FACE_FROM_ID (it->f, local_default_face_id); - it->what = IT_CHARACTER; - memset (&it->position, 0, sizeof it->position); - it->object = Qnil; - it->len = 1; + /* Corner case for when display-fill-column-indicator-mode + is active and the extra character should be added in the + same place than the line. */ - int local_default_face_id = - lookup_basic_face (it->w, it->f, DEFAULT_FACE_ID); - struct face* default_face = - FACE_FROM_ID_OR_NULL (it->f, local_default_face_id); - - /* Corner case for when display-fill-column-indicator-mode - is active and the extra character should be added in the - same place than the line. */ - int indicator_column = (it->w->pseudo_window_p == 0 - ? fill_column_indicator_column (it) - : -1); - if (indicator_column >= 0) - { - struct font *font = (default_face->font - ? default_face->font - : FRAME_FONT (it->f)); - const int char_width = (font->average_width - ? font->average_width - : font->space_width); - int column_x; - - if (!INT_MULTIPLY_WRAPV (indicator_column, char_width, - &column_x) - && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, - &column_x) - && it->current_x == column_x) - { - it->c = it->char_to_display - = XFIXNAT (Vdisplay_fill_column_indicator_character); - it->face_id - = merge_faces (it->w, Qfill_column_indicator, - 0, saved_face_id); - face = FACE_FROM_ID (it->f, it->face_id); - goto produce_glyphs; - } - } - - it->c = it->char_to_display = ' '; - /* If the default face was remapped, be sure to use the - remapped face for the appended newline. */ - if (default_face_p) - it->face_id = local_default_face_id; - else if (it->face_before_selective_p) - it->face_id = it->saved_face_id; + int char_width = 1; +#ifdef HAVE_WINDOW_SYSTEM + if (FRAME_WINDOW_P (it->f)) + { + struct font *font = (default_face->font + ? default_face->font + : FRAME_FONT (it->f)); + char_width = (font->average_width + ? font->average_width + : font->space_width); + } +#endif + const int indicator_column = + (it->w->pseudo_window_p == 0 + ? fill_column_indicator_column (it, char_width) + : -1); + + if (it->current_x == indicator_column) + { + it->c = it->char_to_display + = XFIXNAT (Vdisplay_fill_column_indicator_character); + it->face_id + = merge_faces (it->w, Qfill_column_indicator, + 0, saved_face_id); face = FACE_FROM_ID (it->f, it->face_id); - it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); - /* In R2L rows, we will prepend a stretch glyph that will - have the end_of_box_run_p flag set for it, so there's no - need for the appended newline glyph to have that flag - set. */ - if (it->glyph_row->reversed_p - /* But if the appended newline glyph goes all the way to - the end of the row, there will be no stretch glyph, - so leave the box flag set. */ - && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) - it->end_of_box_run_p = false; - - produce_glyphs: - PRODUCE_GLYPHS (it); + goto produce_glyphs; + } + it->c = it->char_to_display = ' '; + /* If the default face was remapped, be sure to use the + remapped face for the appended newline. */ + it->face_id = default_face_p + ? local_default_face_id + : it->saved_face_id; + + + face = FACE_FROM_ID (it->f, it->face_id); + it->face_id = FACE_FOR_CHAR (it->f, face, 0, -1, Qnil); + /* In R2L rows, we will prepend a stretch glyph that will + have the end_of_box_run_p flag set for it, so there's no + need for the appended newline glyph to have that flag + set. */ + if (it->glyph_row->reversed_p + /* But if the appended newline glyph goes all the way to + the end of the row, there will be no stretch glyph, + so leave the box flag set. */ + && saved_x + FRAME_COLUMN_WIDTH (it->f) < it->last_visible_x) + it->end_of_box_run_p = false; + + produce_glyphs: + PRODUCE_GLYPHS (it); +#ifdef HAVE_WINDOW_SYSTEM + if (FRAME_WINDOW_P (it->f)) + { /* Make sure this space glyph has the right ascent and descent values, or else cursor at end of line will look funny, and height of empty lines will be incorrect. */ @@ -21468,8 +21473,8 @@ append_space_for_newline (struct it *it, bool default_face_p) gui_produce_glyph for newline characters. */ height = get_it_property (it, Qline_height); if (CONSP (height) - && CONSP (XCDR (height)) - && NILP (XCDR (XCDR (height)))) + && CONSP (XCDR (height)) + && NILP (XCDR (XCDR (height)))) { total_height = XCAR (XCDR (height)); height = XCAR (height); @@ -21498,12 +21503,12 @@ append_space_for_newline (struct it *it, bool default_face_p) if (!NILP (total_height)) spacing = calc_line_height_property (it, total_height, font, - boff, false); + boff, false); else { spacing = get_it_property (it, Qline_spacing); spacing = calc_line_height_property (it, spacing, font, - boff, false); + boff, false); } if (FIXNUMP (spacing)) { @@ -21526,22 +21531,21 @@ append_space_for_newline (struct it *it, bool default_face_p) g->ascent = it->max_ascent; g->descent = it->max_descent; - - it->override_ascent = -1; - it->constrain_row_ascent_descent_p = false; - it->current_x = saved_x; - it->object = saved_object; - it->position = saved_pos; - it->what = saved_what; - it->face_id = saved_face_id; - it->len = saved_len; - it->c = saved_c; - it->char_to_display = saved_char_to_display; - it->end_of_box_run_p = saved_box_end; - return true; } +#endif // HAVE_WINDOW_SYSTEM + it->override_ascent = -1; + it->constrain_row_ascent_descent_p = false; + it->current_x = saved_x; + it->object = saved_object; + it->position = saved_pos; + it->what = saved_what; + it->face_id = saved_face_id; + it->len = saved_len; + it->c = saved_c; + it->char_to_display = saved_char_to_display; + it->end_of_box_run_p = saved_box_end; + return true; } -#endif return false; } @@ -21657,9 +21661,6 @@ extend_face_to_end_of_line (struct it *it) /* Display fill column indicator if not in modeline or toolbar and display fill column indicator mode is active. */ - const int indicator_column = (it->w->pseudo_window_p == 0 - ? fill_column_indicator_column (it) - : -1); struct font *font = (default_face->font ? default_face->font @@ -21668,7 +21669,11 @@ extend_face_to_end_of_line (struct it *it) const int char_width = (font->average_width ? font->average_width : font->space_width); - int column_x; + + const int indicator_column = + (it->w->pseudo_window_p == 0 + ? fill_column_indicator_column (it, char_width) + : -1); const char saved_char = it->char_to_display; const struct text_pos saved_pos = it->position; @@ -21678,22 +21683,18 @@ extend_face_to_end_of_line (struct it *it) const int saved_face_id = it->face_id; it->face_id = it->extend_face_id; + it->avoid_cursor_p = true; + it->object = Qnil; if (indicator_column >= 0 - && !INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x) - && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x) - && column_x >= it->current_x - && column_x <= it->last_visible_x) + && indicator_column > it->current_x + && indicator_column < it->last_visible_x) { - /* The stretch width needs to considet the latter - added glyph. */ - const int stretch_width - = column_x - it->current_x - char_width; + const int stretch_width = + indicator_column - it->current_x - char_width; memset (&it->position, 0, sizeof it->position); - it->avoid_cursor_p = true; - it->object = Qnil; /* Only generate a stretch glyph if there is distance between current_x and and the indicator position. */ @@ -21708,7 +21709,7 @@ extend_face_to_end_of_line (struct it *it) /* Generate the glyph indicator only if append_space_for_newline didn't already. */ - if (it->current_x < column_x) + if (it->current_x < indicator_column) { const int save_face_id = it->face_id; it->char_to_display @@ -21718,7 +21719,6 @@ extend_face_to_end_of_line (struct it *it) 0, it->extend_face_id); PRODUCE_GLYPHS (it); it->face_id = save_face_id; - } } @@ -21853,14 +21853,13 @@ extend_face_to_end_of_line (struct it *it) default_face->id : face->id); /* Display fill-column indicator if needed. */ - int indicator_column = fill_column_indicator_column (it); - if (indicator_column >= 0 - && INT_ADD_WRAPV (it->lnum_pixel_width, indicator_column, - &indicator_column)) - indicator_column = -1; + const int indicator_column = + fill_column_indicator_column (it, 1) - 1; do { - if (it->current_x == indicator_column) + if (it->current_x != indicator_column) + PRODUCE_GLYPHS (it); + else { int saved_face_id = it->face_id; it->face_id @@ -21873,8 +21872,6 @@ extend_face_to_end_of_line (struct it *it) it->face_id = saved_face_id; it->c = it->char_to_display = ' '; } - else - PRODUCE_GLYPHS (it); } while (it->current_x <= it->last_visible_x); commit eb259473db50e5083296b9dd1468e378c94ce7f1 Author: Jimmy Aguilar Mena Date: Mon Sep 9 16:10:57 2019 +0200 Changed handle_face_prop_general prototype. * src/xdisp.h (handle_face_prop_general): Changed function prototype to receive different arguments. diff --git a/src/xdisp.c b/src/xdisp.c index ee1a089af5..ad4d69938c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4148,14 +4148,15 @@ handle_fontified_prop (struct it *it) Faces ***********************************************************************/ -static enum prop_handled -handle_face_prop_general (struct it *it, int *face_id_ptr, +static int +handle_face_prop_general (struct it *it, int initial_face_id, enum lface_attribute_index attr_filter) { int new_face_id; ptrdiff_t next_stop; + const bool is_string = STRINGP (it->string); - if (!STRINGP (it->string)) + if (!is_string) { new_face_id = face_at_buffer_position (it->w, @@ -4164,39 +4165,7 @@ handle_face_prop_general (struct it *it, int *face_id_ptr, (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), false, it->base_face_id, attr_filter); - - /* Is this a start of a run of characters with box face? - Caveat: this can be called for a freshly initialized - iterator; face_id is -1 in this case. We know that the new - face will not change until limit, i.e. if the new face has a - box, all characters up to limit will have one. But, as - usual, we don't know whether limit is really the end. */ - if (new_face_id != *face_id_ptr) - { - struct face *new_face = FACE_FROM_ID (it->f, new_face_id); - /* If it->face_id is -1, old_face below will be NULL, see - the definition of FACE_FROM_ID_OR_NULL. This will happen - if this is the initial call that gets the face. */ - struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr); - - /* If the value of face_id of the iterator is -1, we have to - look in front of IT's position and see whether there is a - face there that's different from new_face_id. */ - if (!old_face && IT_CHARPOS (*it) > BEG) - { - int prev_face_id = face_before_it_pos (it); - - old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id); - } - - /* If the new face has a box, but the old face does not, - this is the start of a run of characters with box face, - i.e. this character has a shadow on the left side. */ - it->start_of_box_run_p = (new_face->box != FACE_NO_BOX - && (old_face == NULL || !old_face->box)); - it->face_box_p = new_face->box != FACE_NO_BOX; - } - } + } else { int base_face_id; @@ -4275,40 +4244,53 @@ handle_face_prop_general (struct it *it, int *face_id_ptr, bufpos, &next_stop, base_face_id, false); + } + + /* Is this a start of a run of characters with box face? + Caveat: this can be called for a freshly initialized + iterator; face_id is -1 in this case. We know that the new + face will not change until limit, i.e. if the new face has a + box, all characters up to limit will have one. But, as + usual, we don't know whether limit is really the end. */ + if (new_face_id != initial_face_id) + { + struct face *new_face = FACE_FROM_ID (it->f, new_face_id); + /* If it->face_id is -1, old_face below will be NULL, see + the definition of FACE_FROM_ID_OR_NULL. This will happen + if this is the initial call that gets the face. */ + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, initial_face_id); - /* Is this a start of a run of characters with box? Caveat: - this can be called for a freshly allocated iterator; face_id - is -1 is this case. We know that the new face will not - change until the next check pos, i.e. if the new face has a - box, all characters up to that position will have a - box. But, as usual, we don't know whether that position - is really the end. */ - if (new_face_id != *face_id_ptr) + /* If the value of face_id of the iterator is -1, we have to + look in front of IT's position and see whether there is a + face there that's different from new_face_id. */ + if (!is_string + && !old_face + && IT_CHARPOS (*it) > BEG) { - struct face *new_face = FACE_FROM_ID (it->f, new_face_id); - struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr); + int prev_face_id = face_before_it_pos (it); - /* If new face has a box but old face hasn't, this is the - start of a run of characters with box, i.e. it has a - shadow on the left side. */ - it->start_of_box_run_p - = new_face->box && (old_face == NULL || !old_face->box); - it->face_box_p = new_face->box != FACE_NO_BOX; + old_face = FACE_FROM_ID_OR_NULL (it->f, prev_face_id); } + + /* If the new face has a box, but the old face does not, + this is the start of a run of characters with box face, + i.e. this character has a shadow on the left side. */ + it->start_of_box_run_p = (new_face->box != FACE_NO_BOX + && (old_face == NULL || !old_face->box)); + it->face_box_p = new_face->box != FACE_NO_BOX; } - *face_id_ptr = new_face_id; - return HANDLED_NORMALLY; + return new_face_id; } /* Set up iterator IT from face properties at its current position. Called from handle_stop. */ - static enum prop_handled handle_face_prop (struct it *it) { - return handle_face_prop_general (it, &(it->face_id), 0); + it->face_id = handle_face_prop_general (it, it->face_id, 0); + return HANDLED_NORMALLY; } @@ -21593,7 +21575,8 @@ extend_face_to_end_of_line (struct it *it) || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) return; - handle_face_prop_general (it, &(it->extend_face_id), LFACE_EXTEND_INDEX); + it->extend_face_id + = handle_face_prop_general (it, it->extend_face_id, LFACE_EXTEND_INDEX); /* Face extension extends the background and box of IT->extend_face_id to the end of the line. If the background equals the background commit b5cd6871c0b9ba4443793217c2f9a63423a6e58d Author: Jimmy Aguilar Mena Date: Sun Sep 8 14:41:31 2019 +0200 Fixed extend face filtered for prop. * src/xfaces.c (face_at_buffer_position): Pass ATTR_FILTER to merge_face_ref in when !NILP (prop). diff --git a/src/xdisp.c b/src/xdisp.c index 518d823ca9..ee1a089af5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4149,17 +4149,12 @@ handle_fontified_prop (struct it *it) ***********************************************************************/ static enum prop_handled -handle_face_prop_general (struct it *it, +handle_face_prop_general (struct it *it, int *face_id_ptr, enum lface_attribute_index attr_filter) { - int new_face_id, *face_id_ptr; + int new_face_id; ptrdiff_t next_stop; - if (attr_filter == LFACE_EXTEND_INDEX) - face_id_ptr = &(it->extend_face_id); - else - face_id_ptr = &(it->face_id); - if (!STRINGP (it->string)) { new_face_id @@ -4313,7 +4308,7 @@ handle_face_prop_general (struct it *it, static enum prop_handled handle_face_prop (struct it *it) { - return handle_face_prop_general (it, 0); + return handle_face_prop_general (it, &(it->face_id), 0); } @@ -21598,7 +21593,7 @@ extend_face_to_end_of_line (struct it *it) || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) return; - handle_face_prop_general (it, LFACE_EXTEND_INDEX); + handle_face_prop_general (it, &(it->extend_face_id), LFACE_EXTEND_INDEX); /* Face extension extends the background and box of IT->extend_face_id to the end of the line. If the background equals the background diff --git a/src/xfaces.c b/src/xfaces.c index 189ba1e767..d3851d0334 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -6133,11 +6133,11 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, } /* Begin with attributes from the default face. */ - memcpy (attrs, default_face->lface, sizeof attrs); + memcpy (attrs, default_face->lface, sizeof(attrs)); /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, NULL, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); /* Now merge the overlay data. */ noverlays = sort_overlays (overlay_vec, noverlays, w); commit faa9b06b486c2d87c304bc006d20604f9f937a40 Author: Jimmy Aguilar Mena Date: Sat Oct 12 19:51:46 2019 +0200 Call handle_face_prop_general to extend face. * src/xdisp.c (extend_face_to_end_of_line): Added a call to handle_face_prop_general to extend face after EOL according to parameter :extend in the faces. diff --git a/src/xdisp.c b/src/xdisp.c index 1eec08d951..518d823ca9 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21598,12 +21598,14 @@ extend_face_to_end_of_line (struct it *it) || WINDOW_RIGHT_MARGIN_WIDTH (it->w) > 0)) return; - /* Face extension extends the background and box of IT->face_id + handle_face_prop_general (it, LFACE_EXTEND_INDEX); + + /* Face extension extends the background and box of IT->extend_face_id to the end of the line. If the background equals the background of the frame, we don't have to do anything. */ face = FACE_FROM_ID (f, (it->face_before_selective_p ? it->saved_face_id - : it->face_id)); + : it->extend_face_id)); if (FRAME_WINDOW_P (f) && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row) commit 42bbfd29e75686cb33207c753383d9664785f5c8 Author: Jimmy Aguilar Mena Date: Sat Oct 12 19:15:32 2019 +0200 Update dfci code with new extend_face code. * src/xdisp.c (extend_face_to_end_of_line): Updated the column-indicator code to use the new version of the function fill_column_indicator_column. diff --git a/src/xdisp.c b/src/xdisp.c index 07ff4c7da7..1eec08d951 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21626,9 +21626,7 @@ extend_face_to_end_of_line (struct it *it) that the character will always be single byte in unibyte text. */ if (!ASCII_CHAR_P (it->c)) - { it->face_id = FACE_FOR_CHAR (f, face, 0, -1, Qnil); - } /* The default face, possibly remapped. */ struct face *default_face = @@ -21679,79 +21677,86 @@ extend_face_to_end_of_line (struct it *it) /* Display fill column indicator if not in modeline or toolbar and display fill column indicator mode is active. */ - int indicator_column = (it->w->pseudo_window_p == 0 + const int indicator_column = (it->w->pseudo_window_p == 0 ? fill_column_indicator_column (it) : -1); - if (indicator_column >= 0) + + struct font *font = (default_face->font + ? default_face->font + : FRAME_FONT (f)); + + const int char_width = (font->average_width + ? font->average_width + : font->space_width); + int column_x; + + const char saved_char = it->char_to_display; + const struct text_pos saved_pos = it->position; + const bool saved_avoid_cursor = it->avoid_cursor_p; + const bool saved_box_start = it->start_of_box_run_p; + Lisp_Object save_object = it->object; + const int saved_face_id = it->face_id; + + it->face_id = it->extend_face_id; + + if (indicator_column >= 0 + && !INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x) + && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x) + && column_x >= it->current_x + && column_x <= it->last_visible_x) { - struct font *font = (default_face->font - ? default_face->font - : FRAME_FONT (f)); - const int char_width = (font->average_width - ? font->average_width - : font->space_width); - int column_x; - - if (!INT_MULTIPLY_WRAPV (indicator_column, char_width, &column_x) - && !INT_ADD_WRAPV (it->lnum_pixel_width, column_x, &column_x) - && column_x >= it->current_x - && column_x <= it->last_visible_x) - { - const char saved_char = it->char_to_display; - const struct text_pos saved_pos = it->position; - const bool saved_avoid_cursor = it->avoid_cursor_p; - const int saved_face_id = it->face_id; - const bool saved_box_start = it->start_of_box_run_p; - Lisp_Object save_object = it->object; - - /* The stretch width needs to considet the latter - added glyph. */ - const int stretch_width - = column_x - it->current_x - char_width; - - memset (&it->position, 0, sizeof it->position); - it->avoid_cursor_p = true; - it->object = Qnil; - - /* Only generate a stretch glyph if there is distance - between current_x and and the indicator position. */ - if (stretch_width > 0) - { - int stretch_ascent = (((it->ascent + it->descent) - * FONT_BASE (font)) / FONT_HEIGHT (font)); - append_stretch_glyph (it, Qnil, stretch_width, - it->ascent + it->descent, - stretch_ascent); - } - /* Generate the glyph indicator only if - append_space_for_newline didn't already. */ - if (it->current_x < column_x) - { - it->char_to_display - = XFIXNAT (Vdisplay_fill_column_indicator_character); - it->face_id - = merge_faces (it->w, Qfill_column_indicator, - 0, saved_face_id); - PRODUCE_GLYPHS (it); - } - - /* Restore the face after the indicator was generated. */ - it->face_id = saved_face_id; - - /* If there is space after the indicator generate an - extra empty glyph to restore the face. Issue was - observed in X systems. */ - it->char_to_display = ' '; - PRODUCE_GLYPHS (it); - - it->char_to_display = saved_char; - it->position = saved_pos; - it->avoid_cursor_p = saved_avoid_cursor; - it->start_of_box_run_p = saved_box_start; - it->object = save_object; - } + /* The stretch width needs to considet the latter + added glyph. */ + const int stretch_width + = column_x - it->current_x - char_width; + + memset (&it->position, 0, sizeof it->position); + it->avoid_cursor_p = true; + it->object = Qnil; + + /* Only generate a stretch glyph if there is distance + between current_x and and the indicator position. */ + if (stretch_width > 0) + { + int stretch_ascent = (((it->ascent + it->descent) + * FONT_BASE (font)) / FONT_HEIGHT (font)); + append_stretch_glyph (it, Qnil, stretch_width, + it->ascent + it->descent, + stretch_ascent); + } + + /* Generate the glyph indicator only if + append_space_for_newline didn't already. */ + if (it->current_x < column_x) + { + const int save_face_id = it->face_id; + it->char_to_display + = XFIXNAT (Vdisplay_fill_column_indicator_character); + it->face_id + = merge_faces (it->w, Qfill_column_indicator, + 0, it->extend_face_id); + PRODUCE_GLYPHS (it); + it->face_id = save_face_id; + + } } + + /* Restore the face after the indicator was generated. */ + + /* If there is space after the indicator generate an + extra empty glyph to restore the face. Issue was + observed in X systems. */ + it->char_to_display = ' '; + PRODUCE_GLYPHS (it); + + it->char_to_display = saved_char; + it->position = saved_pos; + it->avoid_cursor_p = saved_avoid_cursor; + it->start_of_box_run_p = saved_box_start; + it->object = save_object; + it->face_id = saved_face_id; + } if (it->glyph_row->reversed_p) { @@ -21797,10 +21802,9 @@ extend_face_to_end_of_line (struct it *it) /* The last row's stretch glyph should get the default face, to avoid painting the rest of the window with the region face, if the region ends at ZV. */ - if (it->glyph_row->ends_at_zv_p) - it->face_id = default_face->id; - else - it->face_id = face->id; + it->face_id = (it->glyph_row->ends_at_zv_p ? + default_face->id : face->id); + it->start_of_box_run_p = false; append_stretch_glyph (it, Qnil, stretch_width, it->ascent + it->descent, stretch_ascent); @@ -21822,14 +21826,11 @@ extend_face_to_end_of_line (struct it *it) { /* Save some values that must not be changed. */ int saved_x = it->current_x; - struct text_pos saved_pos; - Lisp_Object saved_object; + struct text_pos saved_pos = it->position; + Lisp_Object saved_object = it->object;; enum display_element_type saved_what = it->what; int saved_face_id = it->face_id; - saved_object = it->object; - saved_pos = it->position; - it->what = IT_CHARACTER; memset (&it->position, 0, sizeof it->position); it->object = Qnil; @@ -21868,10 +21869,8 @@ extend_face_to_end_of_line (struct it *it) /* The last row's blank glyphs should get the default face, to avoid painting the rest of the window with the region face, if the region ends at ZV. */ - if (it->glyph_row->ends_at_zv_p) - it->face_id = default_face->id; - else - it->face_id = face->id; + it->face_id = (it->glyph_row->ends_at_zv_p ? + default_face->id : face->id); /* Display fill-column indicator if needed. */ int indicator_column = fill_column_indicator_column (it); @@ -21881,24 +21880,21 @@ extend_face_to_end_of_line (struct it *it) indicator_column = -1; do { - int saved_face_id; - bool indicate = it->current_x == indicator_column; - if (indicate) + if (it->current_x == indicator_column) { - saved_face_id = it->face_id; + int saved_face_id = it->face_id; it->face_id - = merge_faces (it->w, Qfill_column_indicator, 0, saved_face_id); + = merge_faces (it->w, Qfill_column_indicator, 0, it->extend_face_id); it->c = it->char_to_display = XFIXNAT (Vdisplay_fill_column_indicator_character); - } - PRODUCE_GLYPHS (it); + PRODUCE_GLYPHS (it); - if (indicate) - { it->face_id = saved_face_id; it->c = it->char_to_display = ' '; } + else + PRODUCE_GLYPHS (it); } while (it->current_x <= it->last_visible_x); commit e02fe26c7fcccb4059a7c7baba20bd9cb3b9a313 Author: Jimmy Aguilar Mena Date: Sat Oct 12 18:10:48 2019 +0200 New parameter to control the face extension.. * src/xdisp.c (handle_face_prop_general): New function to specialize handle_face_prop with ATTR_FILTER. * src/dispextern.h (face_at_buffer_position): Added LFACE_ATTRIBUTE_INDEX. * src/xfaces.c (merge_face_ref): Added LFACE_ATTRIBUTE_INDEX to merge conditionally. diff --git a/src/dispextern.h b/src/dispextern.h index 519cc36345..5db3ae88bf 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3554,8 +3554,8 @@ int lookup_derived_face (struct window *, struct frame *, void init_frame_faces (struct frame *); void free_frame_faces (struct frame *); void recompute_basic_faces (struct frame *); -int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, - bool, int); +int face_at_buffer_position (struct window *, ptrdiff_t, ptrdiff_t *, + ptrdiff_t, bool, int, enum lface_attribute_index); int face_for_overlay_string (struct window *, ptrdiff_t, ptrdiff_t *, ptrdiff_t, bool, Lisp_Object); int face_at_string_position (struct window *, Lisp_Object, ptrdiff_t, ptrdiff_t, diff --git a/src/font.c b/src/font.c index 6bc977fd68..e1e33ab8b2 100644 --- a/src/font.c +++ b/src/font.c @@ -3785,10 +3785,10 @@ font_at (int c, ptrdiff_t pos, struct face *face, struct window *w, if (STRINGP (string)) face_id = face_at_string_position (w, string, pos, 0, &endptr, - DEFAULT_FACE_ID, false); + DEFAULT_FACE_ID, 0); else face_id = face_at_buffer_position (w, pos, &endptr, - pos + 100, false, -1); + pos + 100, false, -1, 0); face = FACE_FROM_ID (f, face_id); } if (multibyte) @@ -3832,7 +3832,7 @@ font_range (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t *limit, if (NILP (string)) face_id = face_at_buffer_position (w, pos, &ignore, *limit, - false, -1); + false, -1, 0); else { face_id = @@ -4618,7 +4618,7 @@ DEFUN ("internal-char-font", Finternal_char_font, Sinternal_char_font, 1, 2, 0, w = XWINDOW (window); f = XFRAME (w->frame); face_id = face_at_buffer_position (w, pos, &dummy, - pos + 100, false, -1); + pos + 100, false, -1, 0); } if (! CHAR_VALID_P (c)) return Qnil; diff --git a/src/xdisp.c b/src/xdisp.c index 38a2ff66c5..07ff4c7da7 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -4148,15 +4148,18 @@ handle_fontified_prop (struct it *it) Faces ***********************************************************************/ -/* Set up iterator IT from face properties at its current position. - Called from handle_stop. */ - static enum prop_handled -handle_face_prop (struct it *it) +handle_face_prop_general (struct it *it, + enum lface_attribute_index attr_filter) { - int new_face_id; + int new_face_id, *face_id_ptr; ptrdiff_t next_stop; + if (attr_filter == LFACE_EXTEND_INDEX) + face_id_ptr = &(it->extend_face_id); + else + face_id_ptr = &(it->face_id); + if (!STRINGP (it->string)) { new_face_id @@ -4165,7 +4168,7 @@ handle_face_prop (struct it *it) &next_stop, (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT), - false, it->base_face_id); + false, it->base_face_id, attr_filter); /* Is this a start of a run of characters with box face? Caveat: this can be called for a freshly initialized @@ -4173,13 +4176,13 @@ handle_face_prop (struct it *it) face will not change until limit, i.e. if the new face has a box, all characters up to limit will have one. But, as usual, we don't know whether limit is really the end. */ - if (new_face_id != it->face_id) + if (new_face_id != *face_id_ptr) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); /* If it->face_id is -1, old_face below will be NULL, see the definition of FACE_FROM_ID_OR_NULL. This will happen if this is the initial call that gets the face. */ - struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr); /* If the value of face_id of the iterator is -1, we have to look in front of IT's position and see whether there is a @@ -4285,10 +4288,10 @@ handle_face_prop (struct it *it) box, all characters up to that position will have a box. But, as usual, we don't know whether that position is really the end. */ - if (new_face_id != it->face_id) + if (new_face_id != *face_id_ptr) { struct face *new_face = FACE_FROM_ID (it->f, new_face_id); - struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, it->face_id); + struct face *old_face = FACE_FROM_ID_OR_NULL (it->f, *face_id_ptr); /* If new face has a box but old face hasn't, this is the start of a run of characters with box, i.e. it has a @@ -4299,11 +4302,21 @@ handle_face_prop (struct it *it) } } - it->face_id = new_face_id; + *face_id_ptr = new_face_id; return HANDLED_NORMALLY; } +/* Set up iterator IT from face properties at its current position. + Called from handle_stop. */ + +static enum prop_handled +handle_face_prop (struct it *it) +{ + return handle_face_prop_general (it, 0); +} + + /* Return the ID of the face ``underlying'' IT's current position, which is in a string. If the iterator is associated with a buffer, return the face at IT's current buffer position. @@ -4527,7 +4540,7 @@ face_before_or_after_it_pos (struct it *it, bool before_p) face_id = face_at_buffer_position (it->w, CHARPOS (pos), &next_check_charpos, - limit, false, -1); + limit, false, -1, 0); /* Correct the face for charsets different from ASCII. Do it for the multibyte case only. The face returned above is @@ -7649,10 +7662,11 @@ get_next_display_element (struct it *it) else { next_face_id = - face_at_buffer_position (it->w, CHARPOS (pos), &ignore, + face_at_buffer_position (it->w, CHARPOS (pos), + &ignore, CHARPOS (pos) + TEXT_PROP_DISTANCE_LIMIT, - false, -1); + false, -1, 0); it->end_of_box_run_p = (FACE_FROM_ID (it->f, next_face_id)->box == FACE_NO_BOX); @@ -32068,7 +32082,7 @@ mouse_face_from_buffer_pos (Lisp_Object window, hlinfo->mouse_face_face_id = face_at_buffer_position (w, mouse_charpos, &ignore, mouse_charpos + 1, - !hlinfo->mouse_face_hidden, -1); + !hlinfo->mouse_face_hidden, -1, 0); show_mouse_face (hlinfo, DRAW_MOUSE_FACE); } diff --git a/src/xfaces.c b/src/xfaces.c index 889bf83561..189ba1e767 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -347,7 +347,8 @@ static struct face_cache *make_face_cache (struct frame *); static void free_face_cache (struct face_cache *); static bool merge_face_ref (struct window *w, struct frame *, Lisp_Object, Lisp_Object *, - bool, struct named_merge_point *); + bool, struct named_merge_point *, + enum lface_attribute_index); static int color_distance (Emacs_Color *x, Emacs_Color *y); #ifdef HAVE_WINDOW_SYSTEM @@ -1910,7 +1911,8 @@ get_lface_attributes (struct window *w, attrs[i] = Qunspecified; return merge_face_ref (w, f, XCDR (face_remapping), attrs, - signal_p, named_merge_points); + signal_p, named_merge_points, + 0); } } @@ -2065,7 +2067,8 @@ merge_face_vectors (struct window *w, if (!UNSPECIFIEDP (from[LFACE_INHERIT_INDEX]) && !NILP (from[LFACE_INHERIT_INDEX])) merge_face_ref (w, f, from[LFACE_INHERIT_INDEX], - to, false, named_merge_points); + to, false, named_merge_points, + 0); if (FONT_SPEC_P (from[LFACE_FONT_INDEX])) { @@ -2131,7 +2134,8 @@ merge_face_vectors (struct window *w, static bool merge_named_face (struct window *w, struct frame *f, Lisp_Object face_name, Lisp_Object *to, - struct named_merge_point *named_merge_points) + struct named_merge_point *named_merge_points, + enum lface_attribute_index attr_filter) { struct named_merge_point named_merge_point; @@ -2141,9 +2145,13 @@ merge_named_face (struct window *w, { Lisp_Object from[LFACE_VECTOR_SIZE]; bool ok = get_lface_attributes (w, f, face_name, from, false, - named_merge_points); + named_merge_points); - if (ok) + eassert (attr_filter < LFACE_VECTOR_SIZE); + + if (ok && (attr_filter == 0 + || (!NILP (from[attr_filter]) + && !UNSPECIFIEDP (from[attr_filter])))) merge_face_vectors (w, f, from, to, named_merge_points); return ok; @@ -2274,6 +2282,11 @@ filter_face_ref (Lisp_Object face_ref, of ERR_MSGS). Use NAMED_MERGE_POINTS to detect loops in face inheritance or list structure; it may be 0 for most callers. + attr_filter is the index of a parameter that conditions the merging + for named faces (case 1) to only the face_ref where + lface[merge_face_ref] is non-nil. To merge unconditionally set this + value to 0. + FACE_REF may be a single face specification or a list of such specifications. Each face specification can be: @@ -2302,7 +2315,8 @@ filter_face_ref (Lisp_Object face_ref, static bool merge_face_ref (struct window *w, struct frame *f, Lisp_Object face_ref, Lisp_Object *to, - bool err_msgs, struct named_merge_point *named_merge_points) + bool err_msgs, struct named_merge_point *named_merge_points, + enum lface_attribute_index attr_filter) { bool ok = true; /* Succeed without an error? */ Lisp_Object filtered_face_ref; @@ -2514,7 +2528,8 @@ merge_face_ref (struct window *w, /* This is not really very useful; it's just like a normal face reference. */ if (! merge_face_ref (w, f, value, to, - err_msgs, named_merge_points)) + err_msgs, named_merge_points, + 0)) err = true; } else if (EQ (keyword, QCextend)) @@ -2544,16 +2559,19 @@ merge_face_ref (struct window *w, Lisp_Object next = XCDR (face_ref); if (! NILP (next)) - ok = merge_face_ref (w, f, next, to, err_msgs, named_merge_points); + ok = merge_face_ref (w, f, next, to, err_msgs, + named_merge_points, 0); - if (! merge_face_ref (w, f, first, to, err_msgs, named_merge_points)) + if (! merge_face_ref (w, f, first, to, err_msgs, + named_merge_points, 0)) ok = false; } } else { /* FACE_REF ought to be a face name. */ - ok = merge_named_face (w, f, face_ref, to, named_merge_points); + ok = merge_named_face (w, f, face_ref, to, named_merge_points, + attr_filter); if (!ok && err_msgs) add_to_log ("Invalid face reference: %s", face_ref); } @@ -4534,7 +4552,8 @@ lookup_face (struct frame *f, Lisp_Object *attr) suitable face is found, realize a new one. */ int -face_for_font (struct frame *f, Lisp_Object font_object, struct face *base_face) +face_for_font (struct frame *f, Lisp_Object font_object, + struct face *base_face) { struct face_cache *cache = FRAME_FACE_CACHE (f); unsigned hash; @@ -4769,7 +4788,7 @@ DEFUN ("face-attributes-as-vector", Fface_attributes_as_vector, Lisp_Object lface = make_vector (LFACE_VECTOR_SIZE, Qunspecified); merge_face_ref (NULL, XFRAME (selected_frame), plist, XVECTOR (lface)->contents, - true, 0); + true, NULL, 0); return lface; } @@ -5126,7 +5145,7 @@ face for italic. */) for (i = 0; i < LFACE_VECTOR_SIZE; i++) attrs[i] = Qunspecified; - merge_face_ref (NULL, f, attributes, attrs, true, 0); + merge_face_ref (NULL, f, attributes, attrs, true, NULL, 0); def_face = FACE_FROM_ID_OR_NULL (f, DEFAULT_FACE_ID); if (def_face == NULL) @@ -6012,7 +6031,7 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) Lisp_Object attrs[LFACE_VECTOR_SIZE]; struct face *default_face = FACE_FROM_ID (f, DEFAULT_FACE_ID); memcpy (attrs, default_face->lface, sizeof attrs); - merge_face_ref (NULL, f, prop, attrs, true, 0); + merge_face_ref (NULL, f, prop, attrs, true, NULL, 0); face_id = lookup_face (f, attrs); } @@ -6024,6 +6043,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) which a different face is needed, as far as text properties and overlays are concerned. W is a window displaying current_buffer. + attr_filter is passed merge_face_ref. + REGION_BEG, REGION_END delimit the region, so it can be highlighted. @@ -6043,7 +6064,8 @@ compute_char_face (struct frame *f, int ch, Lisp_Object prop) int face_at_buffer_position (struct window *w, ptrdiff_t pos, ptrdiff_t *endptr, ptrdiff_t limit, - bool mouse, int base_face_id) + bool mouse, int base_face_id, + enum lface_attribute_index attr_filter) { struct frame *f = XFRAME (w->frame); Lisp_Object attrs[LFACE_VECTOR_SIZE]; @@ -6104,8 +6126,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, } /* Optimize common cases where we can use the default face. */ - if (noverlays == 0 - && NILP (prop)) + if (noverlays == 0 && NILP (prop)) { SAFE_FREE (); return default_face->id; @@ -6116,7 +6137,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, 0); /* Now merge the overlay data. */ noverlays = sort_overlays (overlay_vec, noverlays, w); @@ -6136,7 +6157,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, so discard the mouse-face text property, if any, and use the overlay property instead. */ memcpy (attrs, default_face->lface, sizeof attrs); - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); } oend = OVERLAY_END (overlay_vec[i]); @@ -6153,8 +6174,9 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos, ptrdiff_t oendpos; prop = Foverlay_get (overlay_vec[i], propname); + if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, attr_filter); oend = OVERLAY_END (overlay_vec[i]); oendpos = OVERLAY_POSITION (oend); @@ -6220,7 +6242,7 @@ face_for_overlay_string (struct window *w, ptrdiff_t pos, /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, 0); *endptr = endpos; @@ -6255,7 +6277,7 @@ int face_at_string_position (struct window *w, Lisp_Object string, ptrdiff_t pos, ptrdiff_t bufpos, ptrdiff_t *endptr, enum face_id base_face_id, - bool mouse_p) + bool mouse_p) { Lisp_Object prop, position, end, limit; struct frame *f = XFRAME (WINDOW_FRAME (w)); @@ -6299,7 +6321,7 @@ face_at_string_position (struct window *w, Lisp_Object string, /* Merge in attributes specified via text properties. */ if (!NILP (prop)) - merge_face_ref (w, f, prop, attrs, true, 0); + merge_face_ref (w, f, prop, attrs, true, NULL, 0); /* Look up a realized face with the given face attributes, or realize a new one for ASCII characters. */ @@ -6349,7 +6371,7 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id, if (!NILP (face_name)) { - if (!merge_named_face (w, f, face_name, attrs, 0)) + if (!merge_named_face (w, f, face_name, attrs, NULL, 0)) return base_face_id; } else commit bc8db39775eb3af36a45d51130cd4dbd3b3e7210 Author: Jimmy Aguilar Mena Date: Wed Sep 4 17:27:28 2019 +0200 Added face parameter :extend. This is an initial change to add a parameter :extend that will be used in the display engine later. diff --git a/lisp/cus-face.el b/lisp/cus-face.el index d73bce42c3..5a49a81043 100644 --- a/lisp/cus-face.el +++ b/lisp/cus-face.el @@ -233,7 +233,11 @@ (file :tag "File" :help-echo "Name of bitmap file." :must-match t))) - + (:extend + (choice :tag "Extend" + :help-echo "Control whether attributes should be extended after EOL." + (const :tag "Off" nil) + (const :tag "On" t))) (:inherit (repeat :tag "Inherit" :help-echo "List of faces to inherit attributes from." diff --git a/lisp/faces.el b/lisp/faces.el index c789d3729e..36fc69895d 100644 --- a/lisp/faces.el +++ b/lisp/faces.el @@ -342,6 +342,7 @@ is either `foreground-color', `background-color', or a keyword." (:box (".attributeBox" . "Face.AttributeBox")) (:underline (".attributeUnderline" . "Face.AttributeUnderline")) (:inverse-video (".attributeInverse" . "Face.AttributeInverse")) + (:extend (".attributeExtend" . "Face.AttributeExtend")) (:stipple (".attributeStipple" . "Face.AttributeStipple") (".attributeBackgroundPixmap" . "Face.AttributeBackgroundPixmap")) @@ -594,6 +595,13 @@ Use `face-attribute' for finer control." (let ((italic (face-attribute face :slant frame inherit))) (memq italic '(italic oblique)))) +(defun face-extend-p (face &optional frame inherit) + "Return non-nil if FACE specifies a non-nil extend. +If the optional argument FRAME is given, report on face FACE in that frame. +If FRAME is t, report on the defaults for face FACE (for new frames). +If FRAME is omitted or nil, use the selected frame. +Optional argument INHERIT is passed to `face-attribute'." + (eq (face-attribute face :extend frame inherit) t)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -760,6 +768,11 @@ For convenience, attributes `:family', `:foundry', `:width', `:height', `:weight', and `:slant' may also be set in one step from an X font name: +`:extend' + +VALUE specifies whether the FACE should be extended after EOL. +VALUE must be one of t or nil. + `:font' Set font-related face attributes from VALUE. @@ -979,6 +992,18 @@ Use `set-face-attribute' or `modify-face' for finer control." (define-obsolete-function-alias 'set-face-italic-p 'set-face-italic "24.4") +(defun set-face-extend (face extend-p &optional frame) + "Specify whether face FACE should be extended. +EXTEND-P nil means FACE explicitly doesn't extend after EOL. +EXTEND-P t means FACE extends after EOL. + +FRAME nil or not specified means change face on all frames. +Use `set-face-attribute' to \"unspecify\" underlining." + (interactive + (let ((list (read-face-and-attribute :extend))) + (list (car list) (if (cadr list) t)))) + (set-face-attribute face frame :extend extend-p)) + (defalias 'set-face-background-pixmap 'set-face-stipple) @@ -1102,7 +1127,7 @@ an integer value." (:slant (mapcar #'(lambda (x) (cons (symbol-name (aref x 1)) (aref x 1))) font-slant-table)) - (:inverse-video + ((or :inverse-video :extend) (mapcar #'(lambda (x) (cons (symbol-name x) x)) (internal-lisp-face-attribute-values attribute))) ((or :underline :overline :strike-through :box) @@ -1147,6 +1172,7 @@ an integer value." (:slant . "slant") (:underline . "underline") (:overline . "overline") + (:extend . "extend") (:strike-through . "strike-through") (:box . "box") (:inverse-video . "inverse-video display") @@ -1549,7 +1575,8 @@ is given, in which case return its value instead." ;; (see also realize_default_face in xfaces.c). (append '(:underline nil :overline nil :strike-through nil - :box nil :inverse-video nil :stipple nil :inherit nil) + :box nil :inverse-video nil :stipple nil :inherit nil + :extend nil) ;; `display-graphic-p' is unavailable when running ;; temacs, prior to loading frame.el. (when (fboundp 'display-graphic-p) @@ -2314,24 +2341,24 @@ If you set `term-file-prefix' to nil, this function does nothing." ;; if background is light. (defface region '((((class color) (min-colors 88) (background dark)) - :background "blue3") + :background "blue3" :extend t) (((class color) (min-colors 88) (background light) (type gtk)) :distant-foreground "gtk_selection_fg_color" - :background "gtk_selection_bg_color") + :background "gtk_selection_bg_color" :extend t) (((class color) (min-colors 88) (background light) (type ns)) :distant-foreground "ns_selection_fg_color" - :background "ns_selection_bg_color") + :background "ns_selection_bg_color" :extend t) (((class color) (min-colors 88) (background light)) - :background "lightgoldenrod2") + :background "lightgoldenrod2" :extend t) (((class color) (min-colors 16) (background dark)) - :background "blue3") + :background "blue3" :extend t) (((class color) (min-colors 16) (background light)) - :background "lightgoldenrod2") + :background "lightgoldenrod2" :extend t) (((class color) (min-colors 8)) - :background "blue" :foreground "white") + :background "blue" :foreground "white" :extend t) (((type tty) (class mono)) :inverse-video t) - (t :background "gray")) + (t :background "gray" :extend t)) "Basic face for highlighting the region." :version "21.1" :group 'basic-faces) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 5e55240dab..235aa9a6e1 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -1385,6 +1385,7 @@ If FRAME is omitted or nil, use the selected frame." (:stipple . "Stipple") (:font . "Font") (:fontset . "Fontset") + (:extend . "Extend") (:inherit . "Inherit"))) (max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x))) attrs)))) diff --git a/src/dispextern.h b/src/dispextern.h index 57400ae047..519cc36345 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1677,11 +1677,9 @@ struct face /* Pixel value or color index of background color. */ unsigned long background; - /* Pixel value or color index of underline color. */ + /* Pixel value or color index of underline, overlined, + strike-through, or box color. */ unsigned long underline_color; - - /* Pixel value or color index of overlined, strike-through, or box - color. */ unsigned long overline_color; unsigned long strike_through_color; unsigned long box_color; @@ -1864,6 +1862,9 @@ struct face_cache ? FRAME_FACE_CACHE (F)->faces_by_id[ID] \ : NULL) +#define FACE_EXTENSIBLE_P(F) \ + (!NILP (F->lface[LFACE_EXTEND_INDEX])) + /* True if FACE is suitable for displaying ASCII characters. */ INLINE bool FACE_SUITABLE_FOR_ASCII_CHAR_P (struct face *face) @@ -2373,7 +2374,7 @@ struct it /* Face id of the iterator saved in case a glyph from dpvec contains a face. The face is restored when all glyphs from dpvec have been delivered. */ - int saved_face_id; + int saved_face_id, saved_extend_face_id; /* Vector of glyphs for control character translation. The pointer dpvec is set to ctl_chars when a control character is translated. @@ -2435,7 +2436,7 @@ struct it ptrdiff_t prev_stop; ptrdiff_t base_level_stop; struct composition_it cmp_it; - int face_id; + int face_id, extend_face_id; /* Save values specific to a given method. */ union { @@ -2493,6 +2494,9 @@ struct it /* Face to use. */ int face_id; + /* Face to extend at EOL/ */ + int extend_face_id; + /* Setting of buffer-local variable selective-display-ellipses. */ bool_bf selective_display_ellipsis_p : 1; diff --git a/src/xfaces.c b/src/xfaces.c index c7d6990f50..889bf83561 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -1590,6 +1590,7 @@ the WIDTH times as wide as FACE on FRAME. */) #define LFACE_FONT(LFACE) AREF ((LFACE), LFACE_FONT_INDEX) #define LFACE_INHERIT(LFACE) AREF ((LFACE), LFACE_INHERIT_INDEX) #define LFACE_FONTSET(LFACE) AREF ((LFACE), LFACE_FONTSET_INDEX) +#define LFACE_EXTEND(LFACE) AREF ((LFACE), LFACE_EXTEND_INDEX) #define LFACE_DISTANT_FOREGROUND(LFACE) \ AREF ((LFACE), LFACE_DISTANT_FOREGROUND_INDEX) @@ -1633,6 +1634,10 @@ check_lface_attrs (Lisp_Object attrs[LFACE_VECTOR_SIZE]) || SYMBOLP (attrs[LFACE_UNDERLINE_INDEX]) || STRINGP (attrs[LFACE_UNDERLINE_INDEX]) || CONSP (attrs[LFACE_UNDERLINE_INDEX])); + eassert (UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX]) + || IGNORE_DEFFACE_P (attrs[LFACE_EXTEND_INDEX]) + || SYMBOLP (attrs[LFACE_EXTEND_INDEX]) + || STRINGP (attrs[LFACE_EXTEND_INDEX])); eassert (UNSPECIFIEDP (attrs[LFACE_OVERLINE_INDEX]) || IGNORE_DEFFACE_P (attrs[LFACE_OVERLINE_INDEX]) || SYMBOLP (attrs[LFACE_OVERLINE_INDEX]) @@ -2512,6 +2517,13 @@ merge_face_ref (struct window *w, err_msgs, named_merge_points)) err = true; } + else if (EQ (keyword, QCextend)) + { + if (EQ (value, Qt) || NILP (value)) + to[LFACE_EXTEND_INDEX] = value; + else + err = true; + } else err = true; @@ -3030,6 +3042,17 @@ FRAME 0 means change the face on all frames, and change the default old_value = LFACE_INVERSE (lface); ASET (lface, LFACE_INVERSE_INDEX, value); } + else if (EQ (attr, QCextend)) + { + if (!UNSPECIFIEDP (value) && !IGNORE_DEFFACE_P (value)) + { + CHECK_SYMBOL (value); + if (!EQ (value, Qt) && !NILP (value)) + signal_error ("Invalid extend face attribute value", value); + } + old_value = LFACE_EXTEND (lface); + ASET (lface, LFACE_EXTEND_INDEX, value); + } else if (EQ (attr, QCforeground)) { /* Compatibility with 20.x. */ @@ -3503,7 +3526,9 @@ DEFUN ("internal-set-lisp-face-attribute-from-resource", value = face_boolean_x_resource_value (value, true); else if (EQ (attr, QCweight) || EQ (attr, QCslant) || EQ (attr, QCwidth)) value = intern (SSDATA (value)); - else if (EQ (attr, QCreverse_video) || EQ (attr, QCinverse_video)) + else if (EQ (attr, QCreverse_video) + || EQ (attr, QCinverse_video) + || EQ (attr, QCextend)) value = face_boolean_x_resource_value (value, true); else if (EQ (attr, QCunderline) || EQ (attr, QCoverline) @@ -3727,6 +3752,8 @@ frames). If FRAME is omitted or nil, use the selected frame. */) value = LFACE_SWIDTH (lface); else if (EQ (keyword, QCinherit)) value = LFACE_INHERIT (lface); + else if (EQ (keyword, QCextend)) + value = LFACE_EXTEND (lface); else if (EQ (keyword, QCfont)) value = LFACE_FONT (lface); else if (EQ (keyword, QCfontset)) @@ -3754,7 +3781,9 @@ Value is nil if ATTR doesn't have a discrete set of valid values. */) if (EQ (attr, QCunderline) || EQ (attr, QCoverline) || EQ (attr, QCstrike_through) - || EQ (attr, QCinverse_video) || EQ (attr, QCreverse_video)) + || EQ (attr, QCinverse_video) + || EQ (attr, QCreverse_video) + || EQ (attr, QCextend)) result = list2 (Qt, Qnil); return result; @@ -4784,6 +4813,9 @@ gui_supports_face_attributes_p (struct frame *f, || (!UNSPECIFIEDP (attrs[LFACE_INVERSE_INDEX]) && face_attr_equal_p (attrs[LFACE_INVERSE_INDEX], def_attrs[LFACE_INVERSE_INDEX])) + || (!UNSPECIFIEDP (attrs[LFACE_EXTEND_INDEX]) + && face_attr_equal_p (attrs[LFACE_EXTEND_INDEX], + def_attrs[LFACE_EXTEND_INDEX])) || (!UNSPECIFIEDP (attrs[LFACE_FOREGROUND_INDEX]) && face_attr_equal_p (attrs[LFACE_FOREGROUND_INDEX], def_attrs[LFACE_FOREGROUND_INDEX])) @@ -5362,6 +5394,9 @@ realize_default_face (struct frame *f) ASET (lface, LFACE_FONTSET_INDEX, Qnil); } + if (UNSPECIFIEDP (LFACE_EXTEND (lface))) + ASET (lface, LFACE_EXTEND_INDEX, Qnil); + if (UNSPECIFIEDP (LFACE_UNDERLINE (lface))) ASET (lface, LFACE_UNDERLINE_INDEX, Qnil); @@ -6539,6 +6574,7 @@ syms_of_xfaces (void) DEFSYM (QCstrike_through, ":strike-through"); DEFSYM (QCbox, ":box"); DEFSYM (QCinherit, ":inherit"); + DEFSYM (QCextend, ":extend"); /* Symbols used for Lisp face attribute values. */ DEFSYM (QCcolor, ":color"); commit f9206f34d63104c50659a15d3615646a09df87bf Author: Jimmy Aguilar Mena Date: Wed Aug 28 11:47:50 2019 +0200 Simplify struct face to use only underline. * src/dispextern.h (enum face_underline_type): Add FACE_NO_UNDERLINE = 0. (struct face): Merge `underline_type` and `underline_p` into `underline`. Update all the occurrences in src/xdisp.c, src/xfaces.c, and src/xterm.c. diff --git a/src/dispextern.h b/src/dispextern.h index 7a15e2745b..57400ae047 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1607,6 +1607,7 @@ enum lface_attribute_index LFACE_INHERIT_INDEX, LFACE_FONTSET_INDEX, LFACE_DISTANT_FOREGROUND_INDEX, + LFACE_EXTEND_INDEX, LFACE_VECTOR_SIZE }; @@ -1632,6 +1633,7 @@ enum face_box_type enum face_underline_type { + FACE_NO_UNDERLINE = 0, FACE_UNDER_LINE, FACE_UNDER_WAVE }; @@ -1706,7 +1708,7 @@ struct face ENUM_BF (face_box_type) box : 2; /* Style of underlining. */ - ENUM_BF (face_underline_type) underline_type : 1; + ENUM_BF (face_underline_type) underline : 2; /* If `box' above specifies a 3D type, true means use box_color for drawing shadows. */ @@ -1714,7 +1716,6 @@ struct face /* Non-zero if text in this face should be underlined, overlined, strike-through or have a box drawn around it. */ - bool_bf underline_p : 1; bool_bf overline_p : 1; bool_bf strike_through_p : 1; @@ -1724,14 +1725,10 @@ struct face bool_bf foreground_defaulted_p : 1; bool_bf background_defaulted_p : 1; - /* True means that either no color is specified for underlining or that - the specified color couldn't be loaded. Use the foreground - color when drawing in that case. */ - bool_bf underline_defaulted_p : 1; - /* True means that either no color is specified for the corresponding attribute or that the specified color couldn't be loaded. Use the foreground color when drawing in that case. */ + bool_bf underline_defaulted_p : 1; bool_bf overline_color_defaulted_p : 1; bool_bf strike_through_color_defaulted_p : 1; bool_bf box_color_defaulted_p : 1; diff --git a/src/nsterm.m b/src/nsterm.m index c8094d0ee3..5583c6105c 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -3404,9 +3404,9 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. return; /* Do underline. */ - if (face->underline_p) + if (face->underline) { - if (s->face->underline_type == FACE_UNDER_WAVE) + if (s->face->underline == FACE_UNDER_WAVE) { if (face->underline_defaulted_p) [defaultCol set]; @@ -3415,15 +3415,15 @@ Note that CURSOR_WIDTH is meaningful only for (h)bar cursors. ns_draw_underwave (s, width, x); } - else if (s->face->underline_type == FACE_UNDER_LINE) + else if (s->face->underline == FACE_UNDER_LINE) { NSRect r; unsigned long thickness, position; /* If the prev was underlined, match its appearance. */ - if (s->prev && s->prev->face->underline_p - && s->prev->face->underline_type == FACE_UNDER_LINE + if (s->prev + && s->prev->face->underline == FACE_UNDER_LINE && s->prev->underline_thickness > 0) { thickness = s->prev->underline_thickness; diff --git a/src/w32term.c b/src/w32term.c index 82256db172..9da0845836 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -2481,9 +2481,9 @@ w32_draw_glyph_string (struct glyph_string *s) if (!s->for_overlaps) { /* Draw underline. */ - if (s->face->underline_p) + if (s->face->underline) { - if (s->face->underline_type == FACE_UNDER_WAVE) + if (s->face->underline == FACE_UNDER_WAVE) { COLORREF color; @@ -2494,13 +2494,13 @@ w32_draw_glyph_string (struct glyph_string *s) w32_draw_underwave (s, color); } - else if (s->face->underline_type == FACE_UNDER_LINE) + else if (s->face->underline == FACE_UNDER_LINE) { unsigned long thickness, position; int y; - if (s->prev && s->prev->face->underline_p - && s->prev->face->underline_type == FACE_UNDER_LINE) + if (s->prev + && s->prev->face->underline == FACE_UNDER_LINE) { /* We use the same underline style as the previous one. */ thickness = s->prev->underline_thickness; @@ -2514,7 +2514,7 @@ w32_draw_glyph_string (struct glyph_string *s) BOOL use_underline_position_properties; Lisp_Object val = buffer_local_value (Qunderline_minimum_offset, - s->w->contents); + s->w->contents); if (FIXNUMP (val)) minimum_offset = max (0, XFIXNUM (val)); else diff --git a/src/xdisp.c b/src/xdisp.c index 1cfd7ef760..38a2ff66c5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -28502,7 +28502,7 @@ font_for_underline_metrics (struct glyph_string *s) for (g = s->first_glyph - 1; g >= g0; g--) { struct face *prev_face = FACE_FROM_ID (s->f, g->face_id); - if (!(prev_face && prev_face->underline_p)) + if (!(prev_face && prev_face->underline != FACE_NO_UNDERLINE)) break; } diff --git a/src/xfaces.c b/src/xfaces.c index 0c99eea156..c7d6990f50 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -1209,7 +1209,7 @@ free_face_colors (struct frame *f, struct face *face) IF_DEBUG (--ncolors_allocated); } - if (face->underline_p + if (face->underline && !face->underline_defaulted_p) { x_free_colors (f, &face->underline_color, 1); @@ -5698,16 +5698,14 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] if (EQ (underline, Qt)) { /* Use default color (same as foreground color). */ - face->underline_p = true; - face->underline_type = FACE_UNDER_LINE; + face->underline = FACE_UNDER_LINE; face->underline_defaulted_p = true; face->underline_color = 0; } else if (STRINGP (underline)) { /* Use specified color. */ - face->underline_p = true; - face->underline_type = FACE_UNDER_LINE; + face->underline = FACE_UNDER_LINE; face->underline_defaulted_p = false; face->underline_color = load_color (f, face, underline, @@ -5715,7 +5713,7 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] } else if (NILP (underline)) { - face->underline_p = false; + face->underline = FACE_NO_UNDERLINE; face->underline_defaulted_p = false; face->underline_color = 0; } @@ -5723,10 +5721,9 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] { /* `(:color COLOR :style STYLE)'. STYLE being one of `line' or `wave'. */ - face->underline_p = true; + face->underline = FACE_UNDER_LINE; face->underline_color = 0; face->underline_defaulted_p = true; - face->underline_type = FACE_UNDER_LINE; /* FIXME? This is also not robust about checking the precise form. See comments in Finternal_set_lisp_face_attribute. */ @@ -5759,9 +5756,9 @@ realize_gui_face (struct face_cache *cache, Lisp_Object attrs[LFACE_VECTOR_SIZE] else if (EQ (keyword, QCstyle)) { if (EQ (value, Qline)) - face->underline_type = FACE_UNDER_LINE; + face->underline = FACE_UNDER_LINE; else if (EQ (value, Qwave)) - face->underline_type = FACE_UNDER_WAVE; + face->underline = FACE_UNDER_WAVE; } } } @@ -6296,9 +6293,8 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id, { struct frame *f = WINDOW_XFRAME (w); Lisp_Object attrs[LFACE_VECTOR_SIZE]; - struct face *base_face; + struct face *base_face = FACE_FROM_ID_OR_NULL (f, base_face_id); - base_face = FACE_FROM_ID_OR_NULL (f, base_face_id); if (!base_face) return base_face_id; @@ -6323,12 +6319,14 @@ merge_faces (struct window *w, Lisp_Object face_name, int face_id, } else { - struct face *face; if (face_id < 0) return base_face_id; - face = FACE_FROM_ID_OR_NULL (f, face_id); + + struct face *face = FACE_FROM_ID_OR_NULL (f, face_id); + if (!face) return base_face_id; + merge_face_vectors (w, f, face->lface, attrs, 0); } @@ -6416,7 +6414,7 @@ dump_realized_face (struct face *face) #endif fprintf (stderr, "fontset: %d\n", face->fontset); fprintf (stderr, "underline: %d (%s)\n", - face->underline_p, + face->underline, SDATA (Fsymbol_name (face->lface[LFACE_UNDERLINE_INDEX]))); fprintf (stderr, "hash: %" PRIuPTR "\n", face->hash); } diff --git a/src/xterm.c b/src/xterm.c index b49c9d6893..5d8b1482a6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -3813,9 +3813,9 @@ x_draw_glyph_string (struct glyph_string *s) if (!s->for_overlaps) { /* Draw underline. */ - if (s->face->underline_p) + if (s->face->underline) { - if (s->face->underline_type == FACE_UNDER_WAVE) + if (s->face->underline == FACE_UNDER_WAVE) { if (s->face->underline_defaulted_p) x_draw_underwave (s); @@ -3829,13 +3829,13 @@ x_draw_glyph_string (struct glyph_string *s) XSetForeground (display, s->gc, xgcv.foreground); } } - else if (s->face->underline_type == FACE_UNDER_LINE) + else if (s->face->underline == FACE_UNDER_LINE) { unsigned long thickness, position; int y; - if (s->prev && s->prev->face->underline_p - && s->prev->face->underline_type == FACE_UNDER_LINE) + if (s->prev && + s->prev->face->underline == FACE_UNDER_LINE) { /* We use the same underline style as the previous one. */ thickness = s->prev->underline_thickness; commit a122ca690798cf3cd8e2c65d373e45b5e6b30d4f Author: Robert Pluim Date: Mon Oct 14 11:43:12 2019 +0200 Fix directory-files-recursively doc typo * lisp/files.el (directory-files-recursively): Fix doc string. diff --git a/lisp/files.el b/lisp/files.el index 007195d22a..68a1284b38 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -827,7 +827,7 @@ in the output directories whose names match REGEXP. PREDICATE can be either nil (which means that all subdirectories are descended into), t (which means that subdirectories that can't be read are ignored), or a function (which is called with -name name of the subdirectory and should return non-nil if the +the name of the subdirectory and should return non-nil if the subdirectory is to be descended into). If FOLLOW-SYMLINKS, symbolic links that point to directories are commit 1fbce07e66c44c292d7b3ae04d67a7e7f6ed151a Author: Martin Rudalics Date: Mon Oct 14 10:53:07 2019 +0200 Fix bug recently introduced in 'fit-window-to-buffer' (Bug#37743) * lisp/window.el (fit-window-to-buffer): Call 'window-combined-p' with right argument (Bug#37743). diff --git a/lisp/window.el b/lisp/window.el index 80d9d2e072..af35f9abe6 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -8923,7 +8923,7 @@ accessible position." ;; vertically. ((and (not (eq fit-window-to-buffer-horizontally 'only)) (not (window-size-fixed-p window 'preserved)) - (window-combined-p)) + (window-combined-p window)) (let* ((line-height (window-default-line-height window)) (total-height (window-size window nil pixelwise)) (min-height