commit cb8b5f860cc11f8738796ced20e16763a6ff4123 (HEAD, refs/remotes/origin/master) Author: Michael R. Mauger Date: Sat Jun 2 19:21:31 2018 -0400 Improve buffer naming in sql.el (Bug#31446) diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 0700c228c3..63428610a5 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@ -344,7 +344,8 @@ file. Since that is a plaintext file, this could be dangerous." (const :format "" :completion) (sexp :tag ":completion") (const :format "" :must-match) - (symbol :tag ":must-match"))) + (restricted-sexp + :match-alternatives (listp stringp)))) (const port))) ;; SQL Product support @@ -760,16 +761,20 @@ Globally should be set to nil; it will be non-nil in `sql-mode', (defvar sql-login-delay 7.5 ;; Secs "Maximum number of seconds you are willing to wait for a login connection.") -(defcustom sql-pop-to-buffer-after-send-region nil - "When non-nil, pop to the buffer SQL statements are sent to. +(defvaralias 'sql-pop-to-buffer-after-send-region 'sql-display-sqli-buffer-function) -After a call to `sql-sent-string', `sql-send-region', -`sql-send-paragraph' or `sql-send-buffer', the window is split -and the SQLi buffer is shown. If this variable is not nil, that -buffer's window will be selected by calling `pop-to-buffer'. If -this variable is nil, that buffer is shown using -`display-buffer'." - :type 'boolean +(defcustom sql-display-sqli-buffer-function 'display-buffer + "Function to be called to display a SQLi buffer after `sql-send-*'. + +When set to a function, it will be called to display the buffer. +When set to t, the default function `pop-to-buffer' will be +called. If not set, no attempt will be made to display the +buffer." + + :type '(choice (const :tag "Default" t) + (const :tag "No display" nil) + (function :tag "Display Buffer function")) + :version "27.1" :group 'SQL) ;; imenu support for sql-mode. @@ -789,7 +794,7 @@ this variable is nil, that buffer is shown using This is used to set `imenu-generic-expression' when SQL mode is entered. Subsequent changes to `sql-imenu-generic-expression' will -not affect existing SQL buffers because imenu-generic-expression is +not affect existing SQL buffers because `imenu-generic-expression' is a local variable.") ;; history file @@ -1104,8 +1109,11 @@ add your name with a \"-U\" prefix (such as \"-Umark\") to the list." (when (executable-find sql-postgres-program) (let ((res '())) (ignore-errors - (dolist (row (process-lines sql-postgres-program "-ltX")) - (when (string-match "^ \\([[:alnum:]-_]+\\) +|.*" row) + (dolist (row (process-lines sql-postgres-program + "--list" + "--no-psqlrc" + "--tuples-only")) + (when (string-match "^ \\([^ |]+\\) +|.*" row) (push (match-string 1 row) res)))) (nreverse res)))) @@ -1237,8 +1245,8 @@ specified, it's `sql-product' or `sql-connection' must match." (and (derived-mode-p 'sql-interactive-mode) (or (not product) (eq product sql-product)) - (or (not connection) - (eq connection sql-connection))))))) + (or (stringp connection) + (string= connection sql-connection))))))) ;; Keymap for sql-interactive-mode. @@ -2713,7 +2721,52 @@ adds a fontification pattern to fontify identifiers ending in ;; Save product setting and fontify. (setq sql-product product) (sql-highlight-product)) +(defalias 'sql-set-dialect 'sql-set-product) +(defun sql-buffer-hidden-p (buf) + "Is the buffer hidden?" + (string-prefix-p " " + (cond + ((stringp buf) + (when (get-buffer buf) + buf)) + ((bufferp buf) + (buffer-name buf)) + (t nil)))) + +(defun sql-display-buffer (buf) + "Display a SQLi buffer based on `sql-display-sqli-buffer-function'. + +If BUF is hidden or `sql-display-sqli-buffer-function' is nil, +then the buffer will not be displayed. Otherwise the BUF is +displayed." + (unless (sql-buffer-hidden-p buf) + (cond + ((eq sql-display-sqli-buffer-function t) + (pop-to-buffer buf)) + ((not sql-display-sqli-buffer-function) + nil) + ((functionp sql-display-sqli-buffer-function) + (funcall sql-display-sqli-buffer-function buf)) + (t + (message "Invalid setting of `sql-display-sqli-buffer-function'") + (pop-to-buffer buf))))) + +(defun sql-make-progress-reporter (buf message &optional min-value max-value current-value min-change min-time) + "Make a progress reporter if BUF is not hidden." + (unless (or (sql-buffer-hidden-p buf) + (not sql-display-sqli-buffer-function)) + (make-progress-reporter message min-value max-value current-value min-change min-time))) + +(defun sql-progress-reporter-update (reporter &optional value) + "Report progress of an operation in the echo area." + (when reporter + (progress-reporter-update reporter value))) + +(defun sql-progress-reporter-done (reporter) + "Print reporter’s message followed by word \"done\" in echo area." + (when reporter + (progress-reporter-done reporter))) ;;; SMIE support @@ -2750,8 +2803,8 @@ adds a fontification pattern to fontify identifiers ending in (prod-stmt (sql-get-product-feature prod :statement))) (concat "^\\<" (if prod-stmt - ansi-stmt - (concat "\\(" ansi-stmt "\\|" prod-stmt "\\)")) + (concat "\\(" ansi-stmt "\\|" prod-stmt "\\)") + ansi-stmt) "\\>"))) (defun sql-beginning-of-statement (arg) @@ -2942,7 +2995,12 @@ regexp pattern specified in its value. The `:completion' property prompts for a string specified by its value. (The property value is used as the PREDICATE argument to -`completing-read'.)" +`completing-read'.) + +For both `:file' and `:completion', there can also be a +`:must-match' property that controls REQUIRE-MATCH parameter to +`completing-read'." + (set-default symbol (let* ((default (plist-get plist :default)) @@ -2962,7 +3020,9 @@ value. (The property value is used as the PREDICATE argument to (read-file-name prompt (file-name-directory last-value) default - (plist-get plist :must-match) + (if (plist-member plist :must-match) + (plist-get plist :must-match) + t) (file-name-nondirectory last-value) (when (plist-get plist :file) `(lambda (f) @@ -2979,7 +3039,9 @@ value. (The property value is used as the PREDICATE argument to (completing-read prompt-def (plist-get plist :completion) nil - (plist-get plist :must-match) + (if (plist-member plist :must-match) + (plist-get plist :must-match) + t) last-value history-var default)) @@ -3119,7 +3181,7 @@ See also `sql-help' on how to create such a buffer." (sql-set-sqli-buffer)) (display-buffer sql-buffer)) -(defun sql-make-alternate-buffer-name () +(defun sql-make-alternate-buffer-name (&optional product) "Return a string that can be used to rename a SQLi buffer. This is used to set `sql-alternate-buffer-name' within `sql-interactive-mode'. @@ -3141,7 +3203,7 @@ server/database name." (cdr (apply #'append nil (sql-for-each-login - (sql-get-product-feature sql-product :sqli-login) + (sql-get-product-feature (or product sql-product) :sqli-login) (lambda (token plist) (pcase token (`user @@ -3188,6 +3250,34 @@ server/database name." ;; Use the name we've got name)))) +(defun sql-generate-unique-sqli-buffer-name (product base) + "Generate a new, unique buffer name for a SQLi buffer. + +Append a sequence number until a unique name is found." + (let ((base-name (when (stringp base) + (substring-no-properties + (or base + (sql-get-product-feature product :name) + (symbol-name product))))) + buf-fmt-1st buf-fmt-rest) + + ;; Calculate buffer format + (if base-name + (setq buf-fmt-1st (format "*SQL: %s*" base-name) + buf-fmt-rest (format "*SQL: %s-%%d*" base-name)) + (setq buf-fmt-1st "*SQL*" + buf-fmt-rest "*SQL-%d*")) + + ;; See if we can find an unused buffer + (let ((buf-name buf-fmt-1st) + (i 1)) + (while (sql-buffer-live-p buf-name) + ;; Check a sequence number on the BASE + (setq buf-name (format buf-fmt-rest i) + i (1+ i))) + + buf-name))) + (defun sql-rename-buffer (&optional new-name) "Rename a SQL interactive buffer. @@ -3203,18 +3293,20 @@ NEW-NAME is empty, then the buffer name will be \"*SQL*\"." (user-error "Current buffer is not a SQL interactive buffer") (setq sql-alternate-buffer-name - (cond - ((stringp new-name) new-name) - ((consp new-name) - (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): " - sql-alternate-buffer-name)) - (t sql-alternate-buffer-name))) - - (setq sql-alternate-buffer-name (substring-no-properties sql-alternate-buffer-name)) - (rename-buffer (if (string= "" sql-alternate-buffer-name) - "*SQL*" - (format "*SQL: %s*" sql-alternate-buffer-name)) - t))) + (substring-no-properties + (cond + ((stringp new-name) + new-name) + ((consp new-name) + (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): " + sql-alternate-buffer-name)) + (t + sql-alternate-buffer-name)))) + + (rename-buffer + (sql-generate-unique-sqli-buffer-name sql-product + sql-alternate-buffer-name) + t))) (defun sql-copy-column () "Copy current column to the end of buffer. @@ -3429,15 +3521,14 @@ to avoid deleting non-prompt output." (sql-input-sender (get-buffer-process sql-buffer) s) ;; Send a command terminator if we must - (if sql-send-terminator - (sql-send-magic-terminator sql-buffer s sql-send-terminator)) + (when sql-send-terminator + (sql-send-magic-terminator sql-buffer s sql-send-terminator)) - (message "Sent string to buffer %s" sql-buffer))) + (when sql-pop-to-buffer-after-send-region + (message "Sent string to buffer %s" sql-buffer)))) ;; Display the sql buffer - (if sql-pop-to-buffer-after-send-region - (pop-to-buffer sql-buffer) - (display-buffer sql-buffer))) + (sql-display-buffer sql-buffer)) ;; We don't have no stinkin' sql (user-error "No SQL process started")))) @@ -3536,15 +3627,22 @@ of commands accepted by the SQLi program. COMMAND may also be a list of SQLi command strings." (let* ((visible (and outbuf - (not (string= " " (substring outbuf 0 1)))))) + (not (sql-buffer-hidden-p outbuf)))) + (this-save save-prior) + (next-save t)) + (when visible (message "Executing SQL command...")) + (if (consp command) - (mapc (lambda (c) (sql-redirect-one sqlbuf c outbuf save-prior)) - command) + (dolist (onecmd command) + (sql-redirect-one sqlbuf onecmd outbuf this-save) + (setq this-save next-save)) (sql-redirect-one sqlbuf command outbuf save-prior)) + (when visible - (message "Executing SQL command...done")))) + (message "Executing SQL command...done")) + nil)) (defun sql-redirect-one (sqlbuf command outbuf save-prior) (when command @@ -3593,7 +3691,7 @@ list of SQLi command strings." (replace-match "" t t)) (goto-char start)))))))) -(defun sql-redirect-value (sqlbuf command regexp &optional regexp-groups) +(defun sql-redirect-value (sqlbuf command &optional regexp regexp-groups) "Execute the SQL command and return part of result. SQLBUF must be an active SQL interactive buffer. COMMAND should @@ -3608,7 +3706,7 @@ for each match." (results nil)) (sql-redirect sqlbuf command outbuf nil) (with-current-buffer outbuf - (while (re-search-forward regexp nil t) + (while (re-search-forward (or regexp "^.+$") nil t) (push (cond ;; no groups-return all of them @@ -4206,31 +4304,30 @@ the call to \\[sql-product-interactive] with ;; Handle universal arguments if specified (when (not (or executing-kbd-macro noninteractive)) - (when (and (consp product) - (not (cdr product)) - (numberp (car product))) - (when (>= (prefix-numeric-value product) 16) - (when (not new-name) - (setq new-name '(4))) - (setq product '(4))))) + (when (>= (prefix-numeric-value product) 16) + (when (not new-name) + (setq new-name '(4))) + (setq product '(4)))) ;; Get the value of product that we need (setq product (cond ((= (prefix-numeric-value product) 4) ; C-u, prompt for product (sql-read-product "SQL product: " sql-product)) - ((and product ; Product specified - (symbolp product)) product) + ((assoc product sql-product-alist) ; Product specified + product) (t sql-product))) ; Default to sql-product ;; If we have a product and it has an interactive mode (if product (when (sql-get-product-feature product :sqli-comint-func) - ;; If no new name specified, try to pop to an active SQL - ;; interactive for the same product + ;; If no new name specified or new name in buffer name, + ;; try to pop to an active SQL interactive for the same product (let ((buf (sql-find-sqli-buffer product sql-connection))) - (if (and (not new-name) buf) - (pop-to-buffer buf) + (if (and buf (or (not new-name) + (and (stringp new-name) + (string-match-p (regexp-quote new-name) buf)))) + (sql-display-buffer buf) ;; We have a new name or sql-buffer doesn't exist or match ;; Start by remembering where we start @@ -4242,34 +4339,37 @@ the call to \\[sql-product-interactive] with (sql-get-product-feature product :sqli-login)) ;; Connect to database. - (setq rpt (make-progress-reporter "Login")) + (setq rpt (sql-make-progress-reporter nil "Login")) (let ((sql-user (default-value 'sql-user)) (sql-password (default-value 'sql-password)) (sql-server (default-value 'sql-server)) (sql-database (default-value 'sql-database)) (sql-port (default-value 'sql-port)) - (default-directory (or sql-default-directory - default-directory))) + (default-directory + (or sql-default-directory + default-directory))) + + ;; Call the COMINT service (funcall (sql-get-product-feature product :sqli-comint-func) product (sql-get-product-feature product :sqli-options) + ;; generate a buffer name (cond - ((null new-name) - "*SQL*") - ((stringp new-name) - (if (string-prefix-p "*SQL: " new-name t) - new-name - (concat "*SQL: " new-name "*"))) - ((equal new-name '(4)) - (concat - "*SQL: " + ((not new-name) + (sql-generate-unique-sqli-buffer-name product nil)) + ((consp new-name) + (sql-generate-unique-sqli-buffer-name product (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): " - sql-alternate-buffer-name) - "*")) + (sql-make-alternate-buffer-name product)))) + ((or (string-prefix-p " " new-name) + (string-match-p "\\`[*].*[*]\\'" new-name)) + new-name) + ((stringp new-name) + (sql-generate-unique-sqli-buffer-name product new-name)) (t - (format "*SQL: %s*" new-name))))) + (sql-generate-unique-sqli-buffer-name product nil))))) ;; Set SQLi mode. (let ((sql-interactive-product product)) @@ -4297,25 +4397,26 @@ the call to \\[sql-product-interactive] with (<= 0.0 (setq secs (- secs step)))) (progn (goto-char (point-max)) (not (re-search-backward sql-prompt-regexp 0 t)))) - (progress-reporter-update rpt))) + (sql-progress-reporter-update rpt))) (goto-char (point-max)) (when (re-search-backward sql-prompt-regexp nil t) (run-hooks 'sql-login-hook)) ;; All done. - (progress-reporter-done rpt) - (pop-to-buffer new-sqli-buffer) + (sql-progress-reporter-done rpt) (goto-char (point-max)) - (current-buffer))))) - (user-error "No default SQL product defined. Set `sql-product'."))) + (let ((sql-display-sqli-buffer-function t)) + (sql-display-buffer new-sqli-buffer)) + (get-buffer new-sqli-buffer))))) + (user-error "No default SQL product defined: set `sql-product'"))) (defun sql-comint (product params &optional buf-name) "Set up a comint buffer to run the SQL processor. PRODUCT is the SQL product. PARAMS is a list of strings which are passed as command line arguments. BUF-NAME is the name of the new -buffer. If nil, a name is chosen for it." +buffer. If nil, a name is chosen for it." (let ((program (sql-get-product-feature product :sqli-program))) ;; Make sure we can find the program. `executable-find' does not @@ -4328,15 +4429,10 @@ buffer. If nil, a name is chosen for it." ;; if not specified, try *SQL* then *SQL-product*, then *SQL-product1*, ... ;; otherwise, use *buf-name* (if buf-name - (unless (string-match-p "\\`[*].*[*]\\'" buf-name) + (unless (or (string-prefix-p " " buf-name) + (string-match-p "\\`[*].*[*]\\'" buf-name)) (setq buf-name (concat "*" buf-name "*"))) - (setq buf-name "*SQL*") - (when (sql-buffer-live-p buf-name) - (setq buf-name (format "*SQL-%s*" product))) - (let ((i 1)) - (while (sql-buffer-live-p buf-name) - (setq buf-name (format "*SQL-%s%d*" product i) - i (1+ i))))) + (setq buf-name (sql-generate-unique-sqli-buffer-name product nil))) (set-text-properties 0 (length buf-name) nil buf-name) ;; Start the command interpreter in the buffer commit 84f992d42e3a4c21db9994b8c6585c336cb05163 Merge: d3f94d2869 4cfe5312c8 Author: Glenn Morris Date: Sat Jun 2 10:29:38 2018 -0700 Merge from origin/emacs-26 4cfe531 (origin/emacs-26) Improve ELisp documentation of 'clone-indir... 9089b02 Improve documentation of 'inhibit-message' 6107e12 Improve documentation of comment styles fb45125 Documentation improvements in newcomment.el 641c94c Imp[rove documentation of 'with-silent-modifications' commit d3f94d2869af87e7fb8f18f9f9cdc6e0b9bdd20b Merge: 0b0076c860 6e0ff4cc1f Author: Glenn Morris Date: Sat Jun 2 10:29:38 2018 -0700 ; Merge from origin/emacs-26 The following commits were skipped: 6e0ff4c Fix decoding of directories when "~" includes non-ASCII chars 35c1ab1 Don't remove highlight of misspelled word on pdict save aac541e Fix some problems in the Cairo build e96245a Avoid infloops in font_open_entity 3a06e72 Fix encoding of characters when using GB18030 fonts 7782550 Fix C-p and C-n when wrap-prefix is too wide 9804482 Avoid redisplay problems with too wide wrap-prefix 5ee9ccf Fix 'posn-at-point' when line numbers are displayed c4db766 Another followup to fixing 'window-text-pixel-width' a6cf7be Fix mouse-set-point when line numbers are displayed ae78b14 * src/xdisp.c (Fwindow_text_pixel_size): Fix last change. f1f12d8 Fix 'window-text-pixel-size' when display properties are around 8b2b4b5 Fix display of TABs in hscrolled windows with line numbers de69d28 Fix wait_reading_process_output wait_proc hang commit 0b0076c860799c01c4cefb08d1ee0922a30cbf21 Merge: dfe9cadf75 76f692e82f Author: Glenn Morris Date: Sat Jun 2 10:29:38 2018 -0700 Merge from origin/emacs-26 76f692e Merge branch 'emacs-26' of git.savannah.gnu.org:/srv/git/emac... commit dfe9cadf7523451931a4eb1c7927a71f9ee3837e Merge: 02c7d45d49 ddd1b957e9 Author: Glenn Morris Date: Sat Jun 2 10:29:37 2018 -0700 ; Merge from origin/emacs-26 The following commit was skipped: ddd1b95 Fix posn-at-point in Flycheck buffers commit 02c7d45d490dd28a1c4effa928f9a8b9373149b0 Merge: 0aaf14a441 90bea37d46 Author: Glenn Morris Date: Sat Jun 2 10:29:37 2018 -0700 Merge from origin/emacs-26 90bea37 ; * etc/PROBLEMS: Fix fvwm version number in last commit af82d1f * etc/PROBLEMS: Document stickyness problem with FVWM (Bug#31... 4a3aed2 Update Emacs Lisp Intro to match current behavior 21f2247 Merge branch 'emacs-26' of git.savannah.gnu.org:/srv/git/emac... 3257085 Fix previous commit 6d23525 Fix typos in several manuals (Bug#31610) 9188291 Add detailed documentation about lock files e5471b2 Add commentary for subtle aspect of frame.el Conflicts: doc/lispintro/emacs-lisp-intro.texi commit 0aaf14a441041fa8b5810ae0eec624011b53bb4c Merge: 42a851c634 61c8434fec Author: Glenn Morris Date: Sat Jun 2 10:25:50 2018 -0700 ; Merge from origin/emacs-26 The following commit was skipped: 61c8434 ; Auto-commit of loaddefs files. commit 42a851c6347bb45a2fb8acdb0d2a1ca468ecefd3 Merge: 4a7e74fea6 ca3f0a8343 Author: Glenn Morris Date: Sat Jun 2 10:25:50 2018 -0700 Merge from origin/emacs-26 ca3f0a8 ; * etc/NEWS: Belated announcement of 2 changes made in Emacs... 99f92da Improve documentation of 'directory-files-and-attributes' df8649a * lisp/gnus/message.el (message-remove-header): Don't remove ... b682a7e ; * etc/NEWS: Add headings for Emacs 26.2 aa175a4 Adapt hexl-mode to native line-number display b8e7749 Fix example in Tramp manual f212fe5 Handle case where Xft is found but not XRender 186280f * doc/misc/tramp.texi (Frequently Asked Questions): Adapt zsh... 24ba633 Improve read-multiple-choice docstring (Bug#31628) Conflicts: etc/NEWS src/dired.c commit 4cfe5312c85130ea9ea0b379923c0ef6b190df77 (refs/remotes/origin/emacs-26) Author: Eli Zaretskii Date: Sat Jun 2 14:15:10 2018 +0300 Improve ELisp documentation of 'clone-indirect-buffer' * doc/lispref/buffers.texi (Indirect Buffers): Be more explicit about the value of DISPLAY-FLAG in interactive usage. (Bug#31648) diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 686b6162a5..b030d2e63a 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -1181,10 +1181,10 @@ the current buffer's base buffer and copies the rest of the current buffer's attributes. (If the current buffer is not indirect, it is used as the base buffer.) -If @var{display-flag} is non-@code{nil}, that means to display the new -buffer by calling @code{pop-to-buffer}. If @var{norecord} is -non-@code{nil}, that means not to put the new buffer to the front of -the buffer list. +If @var{display-flag} is non-@code{nil}, as it always is in +interactive calls, that means to display the new buffer by calling +@code{pop-to-buffer}. If @var{norecord} is non-@code{nil}, that means +not to put the new buffer to the front of the buffer list. @end deffn @defun buffer-base-buffer &optional buffer commit 9089b0239fbb4d658cc26523685f58e15a4d429a Author: Eli Zaretskii Date: Sat Jun 2 14:09:11 2018 +0300 Improve documentation of 'inhibit-message' * src/xdisp.c (syms_of_xdisp) : Warn against setting it non-nil globally. (Bug#31627) diff --git a/src/xdisp.c b/src/xdisp.c index d28c114067..5bce05c219 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -32424,7 +32424,12 @@ syms_of_xdisp (void) DEFVAR_BOOL("inhibit-message", inhibit_message, doc: /* Non-nil means calls to `message' are not displayed. -They are still logged to the *Messages* buffer. */); +They are still logged to the *Messages* buffer. + +Do NOT set this globally to a non-nil value, as doing that will +disable messages everywhere, including in I-search and other +places where they are necessary. This variable is intended to +be let-bound around code that needs to disable messages temporarily. */); inhibit_message = 0; message_dolog_marker1 = Fmake_marker (); commit 6107e12f76d3f7ea3136b04d8856b3f9ebc97e1d Author: Eli Zaretskii Date: Sat Jun 2 14:01:18 2018 +0300 Improve documentation of comment styles * doc/lispref/syntax.texi (Syntax Flags): Define the "a" style. (Bug#31624) diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index 44a7730c7a..71c97fdae8 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -339,11 +339,13 @@ same style will be recognized. For a two-character comment delimiter, @cindex comment style Emacs supports several comment styles simultaneously in any one syntax table. A comment style is a set of flags @samp{b}, @samp{c}, and -@samp{n}, so there can be up to 8 different comment styles. -Each comment delimiter has a style and only matches comment delimiters -of the same style. Thus if a comment starts with the comment-start -sequence of style ``bn'', it will extend until the next matching -comment-end sequence of style ``bn''. +@samp{n}, so there can be up to 8 different comment styles, each one +named by the set of its flags. Each comment delimiter has a style and +only matches comment delimiters of the same style. Thus if a comment +starts with the comment-start sequence of style ``bn'', it will extend +until the next matching comment-end sequence of style ``bn''. When +the set of flags has neither flag @samp{b} nor flag @samp{c} set, the +resulting style is called the ``a'' style. The appropriate comment syntax settings for C++ can be as follows: commit fb45125c80313b85a7ee56417e746eeac5eecb05 Author: Eli Zaretskii Date: Sat Jun 2 13:43:43 2018 +0300 Documentation improvements in newcomment.el * lisp/newcomment.el (uncomment-region) (uncomment-region-default): Doc fixes. (Bug#31615) diff --git a/lisp/newcomment.el b/lisp/newcomment.el index f5615d93df..9827a5d1d9 100644 --- a/lisp/newcomment.el +++ b/lisp/newcomment.el @@ -887,7 +887,7 @@ If N is `re', a regexp is returned instead, that would match (defun uncomment-region (beg end &optional arg) "Uncomment each line in the BEG .. END region. The numeric prefix ARG can specify a number of chars to remove from the -comment markers." +comment delimiters." (interactive "*r\nP") (comment-normalize-vars) (when (> beg end) (setq beg (prog1 end (setq end beg)))) @@ -901,7 +901,8 @@ comment markers." (defun uncomment-region-default (beg end &optional arg) "Uncomment each line in the BEG .. END region. The numeric prefix ARG can specify a number of chars to remove from the -comment markers." +comment delimiters. +This function is the default value of `uncomment-region-function'." (goto-char beg) (setq end (copy-marker end)) (let* ((numarg (prefix-numeric-value arg)) commit 641c94ce68399e89a35769cb8727c59412767faa Author: Eli Zaretskii Date: Sat Jun 2 13:27:22 2018 +0300 Imp[rove documentation of 'with-silent-modifications' * doc/lispref/buffers.texi (Buffer Modification): Document 'with-silent-modifications'. (Bug#31613) * doc/lispref/text.texi (Changing Properties): Add a cross-reference to "Buffer Modification". Improve wording. diff --git a/doc/lispref/buffers.texi b/doc/lispref/buffers.texi index 45e90669b7..686b6162a5 100644 --- a/doc/lispref/buffers.texi +++ b/doc/lispref/buffers.texi @@ -587,6 +587,20 @@ in between the calls. If @var{buffer} is @code{nil} (or omitted), the current buffer is used. @end defun +Sometimes there's a need for modifying buffer in a way that doesn't +really change its text, like if only its text properties are changed. +If your program needs to modify a buffer without triggering any hooks +and features that react to buffer modifications, use the +@code{with-silent-modifications} macro. + +@defmac with-silent-modifications body@dots{} +Execute @var{body} pretending it does not modify the buffer. This +includes checking whether the buffer's file is locked (@pxref{File +Locks}), running buffer modification hooks (@pxref{Change Hooks}), +etc. Note that if @var{body} actually modifies the buffer text, its +undo data may become corrupted. +@end defmac + @node Modification Time @section Buffer Modification Time @cindex comparing file modification time diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 6dde4c00f8..477b8fce71 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -3037,9 +3037,10 @@ construct each part with @code{propertize} and then combine them with buffer but does not copy its properties. @findex with-silent-modifications - If you wish to add or remove text properties to a buffer without -marking the buffer as modified, you can wrap the calls above in the -@code{with-silent-modifications} macro. + If you wish to add text properties to a buffer or remove them +without marking the buffer as modified, you can wrap the calls above +in the @code{with-silent-modifications} macro. @xref{Buffer +Modification}. @node Property Search @subsection Text Property Search Functions commit 4a7e74fea687011ee81dcbb02294bccd99b3a05f Author: Eli Zaretskii Date: Sat Jun 2 13:04:15 2018 +0300 Un-obsolete 'string-to-unibyte' * lisp/subr.el (string-to-unibyte): No longer obsolete. See the emacs-devel discussion around this message: http://lists.gnu.org/archive/html/emacs-devel/2018-05/msg00656.html. * etc/NEWS: Announce the change. diff --git a/etc/NEWS b/etc/NEWS index bd25f43ad0..1b324986d9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -670,6 +670,13 @@ loading messages if requested, and protects against recursive loads. The history of variable names read by 'read-variable' is recorded in the new variable 'custom-variable-history'. +--- +** The function 'string-to-unibyte' is no longer declared obsolete. +We have found that there are legitimate use cases for this function, +where there's no better alternative. We believe that the incorrect +uses of this function all but disappeared by now, so we are +un-obsoleting it. + * Changes in Emacs 27.1 on Non-Free Operating Systems diff --git a/lisp/subr.el b/lisp/subr.el index 35e220a10e..914112ccef 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1438,8 +1438,13 @@ be a list of the form returned by `event-start' and `event-end'." "27.1") (make-obsolete 'invocation-name "use the variable of the same name." "27.1") +;; We used to declare string-to-unibyte obsolete, but it is a valid +;; way of getting a unibyte string that can be indexed by bytes, when +;; the original string has raw bytes in their internal multibyte +;; representation. This can be useful when one needs to examine +;; individual bytes at known offsets from the string beginning. +;; (make-obsolete 'string-to-unibyte "use `encode-coding-string'." "26.1") ;; bug#23850 -(make-obsolete 'string-to-unibyte "use `encode-coding-string'." "26.1") (make-obsolete 'string-as-unibyte "use `encode-coding-string'." "26.1") (make-obsolete 'string-make-unibyte "use `encode-coding-string'." "26.1") (make-obsolete 'string-to-multibyte "use `decode-coding-string'." "26.1") commit 6e0ff4cc1f261def00f9f9dd581ba6ef72703f0c Author: Eli Zaretskii Date: Fri May 18 16:34:19 2018 +0300 Fix decoding of directories when "~" includes non-ASCII chars * src/fileio.c (Fexpand_file_name): Don't build multibyte strings from unibyte non-ASCII strings when NAME and DEFAULT_DIRECTORY have different multibyteness, as this adds bytes to the byte sequence, and in some situations, e.g., when the home directory includes non-ASCII characters, can fail file APIs. (Bug#30755) * lisp/startup.el (normal-top-level): Make sure default-directory is set to a multibyte string when decoded on MS-Windows. (cherry picked from commit 3aab8626ba5080bb04d0fdae52d99c850a842a52) diff --git a/lisp/startup.el b/lisp/startup.el index 9d16b59def..33f8ca63f8 100644 --- a/lisp/startup.el +++ b/lisp/startup.el @@ -552,9 +552,17 @@ It is the default value of the variable `top-level'." (if default-directory (setq default-directory (if (eq system-type 'windows-nt) - ;; Convert backslashes to forward slashes. - (expand-file-name - (decode-coding-string default-directory coding t)) + ;; We pass the decoded default-directory as + ;; the 2nd arg to expand-file-name to make + ;; sure it sees a multibyte string as the + ;; default directory; this avoids the side + ;; effect of returning a unibyte string from + ;; expand-file-name because it still sees + ;; the undecoded value of default-directory. + (let ((defdir (decode-coding-string default-directory + coding t))) + ;; Convert backslashes to forward slashes. + (expand-file-name defdir defdir)) (decode-coding-string default-directory coding t)))))) ;; Decode all the important variables and directory lists, now diff --git a/src/fileio.c b/src/fileio.c index c4a10000bc..9dbe3ad788 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -864,33 +864,78 @@ the root directory. */) } } multibyte = STRING_MULTIBYTE (name); - if (multibyte != STRING_MULTIBYTE (default_directory)) + bool defdir_multibyte = STRING_MULTIBYTE (default_directory); + if (multibyte != defdir_multibyte) { + /* We want to make both NAME and DEFAULT_DIRECTORY have the same + multibyteness. Strategy: + . If either NAME or DEFAULT_DIRECTORY is pure-ASCII, they + can be converted to the multibyteness of the other one + while keeping the same byte sequence. + . If both are non-ASCII, the only safe conversion is to + convert the multibyte one to be unibyte, because the + reverse conversion potentially adds bytes while raw bytes + are converted to their multibyte forms, which we will be + unable to account for, since the information about the + original multibyteness is lost. If those additional bytes + later leak to system APIs because they are not encoded or + because they are converted to unibyte strings by keeping + the data, file APIs will fail. + + Note: One could argue that if we see a multibyte string, it + is evidence that file-name decoding was already set up, and + we could convert unibyte strings to multibyte using + DECODE_FILE. However, this is risky, because the likes of + string_to_multibyte are able of creating multibyte strings + without any decoding. */ if (multibyte) { - unsigned char *p = SDATA (name); + bool name_ascii_p = SCHARS (name) == SBYTES (name); + unsigned char *p = SDATA (default_directory); - while (*p && ASCII_CHAR_P (*p)) - p++; - if (*p == '\0') + if (!name_ascii_p) + while (*p && ASCII_CHAR_P (*p)) + p++; + if (name_ascii_p || *p != '\0') { - /* NAME is a pure ASCII string, and DEFAULT_DIRECTORY is - unibyte. Do not convert DEFAULT_DIRECTORY to - multibyte; instead, convert NAME to a unibyte string, - so that the result of this function is also a unibyte - string. This is needed during bootstrapping and - dumping, when Emacs cannot decode file names, because - the locale environment is not set up. */ + /* DEFAULT_DIRECTORY is unibyte and possibly non-ASCII. + Make a unibyte string out of NAME, and arrange for + the result of this function to be a unibyte string. + This is needed during bootstrapping and dumping, when + Emacs cannot decode file names, because the locale + environment is not set up. */ name = make_unibyte_string (SSDATA (name), SBYTES (name)); multibyte = 0; } else - default_directory = string_to_multibyte (default_directory); + { + /* NAME is non-ASCII and multibyte, and + DEFAULT_DIRECTORY is unibyte and pure-ASCII: make a + multibyte string out of DEFAULT_DIRECTORY's data. */ + default_directory = + make_multibyte_string (SSDATA (default_directory), + SCHARS (default_directory), + SCHARS (default_directory)); + } } else { - name = string_to_multibyte (name); - multibyte = 1; + unsigned char *p = SDATA (name); + + while (*p && ASCII_CHAR_P (*p)) + p++; + if (*p == '\0') + { + /* DEFAULT_DIRECTORY is multibyte and NAME is unibyte + and pure-ASCII. Make a multibyte string out of + NAME's data. */ + name = make_multibyte_string (SSDATA (name), + SCHARS (name), SCHARS (name)); + multibyte = 1; + } + else + default_directory = make_unibyte_string (SSDATA (default_directory), + SBYTES (default_directory)); } } commit 35c1ab1419174f72010c745d963a55b6c183443c Author: Eli Zaretskii Date: Sun May 6 21:20:31 2018 +0300 Don't remove highlight of misspelled word on pdict save * lisp/textmodes/ispell.el (ispell-pdict-save): Don't restart flyspell-mode, as bug#11963, which this was supposed to fix, is fixed better by ispell-command-loop, when the user types 'i' or 'a'. Restarting Flyspell mode when the personal dictionary is saved caused bug#31372 as side effect. (ispell-command-loop): Test 'flyspell-mode', not whether flyspell-unhighlight-at is fboundp, to determine whether Flyspell mode is turned on in the current buffer. (flyspell-unhighlight-at): Add declare-function form for it. (cherry picked from commit 91e582a31ada28fab5ae55bdbf959a9d30796587) diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el index 3674a7080b..2b88057dc4 100644 --- a/lisp/textmodes/ispell.el +++ b/lisp/textmodes/ispell.el @@ -117,6 +117,8 @@ (defalias 'check-ispell-version 'ispell-check-version) +(declare-function flyspell-unhighlight-at "flyspell" (pos)) + ;;; ********************************************************************** ;;; The following variables should be set according to personal preference ;;; and location of binaries: @@ -2090,10 +2092,7 @@ If so, ask if it needs to be saved." (or no-query (y-or-n-p "Personal dictionary modified. Save? "))) (ispell-send-string "#\n") ; save dictionary - (message "Personal dictionary saved.") - (when flyspell-mode - (flyspell-mode 0) - (flyspell-mode 1))) + (message "Personal dictionary saved.")) ;; unassert variable, even if not saved to avoid questioning. (setq ispell-pdict-modified-p nil)) @@ -2221,15 +2220,16 @@ Global `ispell-quit' set to start location to continue spell session." ((= char ?i) ; accept and insert word into pers dict (ispell-send-string (concat "*" word "\n")) (setq ispell-pdict-modified-p '(t)) ; dictionary modified! - (when (fboundp 'flyspell-unhighlight-at) - (flyspell-unhighlight-at start)) + + (when flyspell-mode + (flyspell-unhighlight-at start)) nil) ((or (= char ?a) (= char ?A)) ; accept word without insert (ispell-send-string (concat "@" word "\n")) (cl-pushnew word ispell-buffer-session-localwords :test #'equal) - (when (fboundp 'flyspell-unhighlight-at) - (flyspell-unhighlight-at start)) + (when flyspell-mode + (flyspell-unhighlight-at start)) (or ispell-buffer-local-name ; session localwords might conflict (setq ispell-buffer-local-name (buffer-name))) (if (null ispell-pdict-modified-p) commit aac541e75e2c22d05752025c2087ae2eea4cb525 Author: Ari Roponen Date: Fri Apr 27 15:13:12 2018 +0300 Fix some problems in the Cairo build * src/xterm.c (x_begin_cr_clip): Create image surface. (x_update_end) [USE_CAIRO]: Remove GTK3-specific code. (x_scroll_run) [USE_CAIRO]: Implement scrolling. * src/image.c (lookup_rgb_color) [USE_CAIRO]: Support Cairo. (jpeg_load_body) [USE_CAIRO]: Support Cairo. Use USE_CAIRO instead of CAIRO for #ifdef's. (imagemagick_load_image) [USE_CAIRO]: Support Cairo. (Bug#31288) (cherry picked from commit 2d0eff42b8f1122e00f948759ed01a3be1a8c3fc) diff --git a/src/image.c b/src/image.c index 37416c1616..4d5a1bf5e6 100644 --- a/src/image.c +++ b/src/image.c @@ -4629,6 +4629,8 @@ lookup_rgb_color (struct frame *f, int r, int g, int b) return PALETTERGB (r >> 8, g >> 8, b >> 8); #elif defined HAVE_NS return RGB_TO_ULONG (r >> 8, g >> 8, b >> 8); +#elif defined USE_CAIRO + return (0xffu << 24) | (r << 16) | (g << 8) | b; #else xsignal1 (Qfile_error, build_string ("This Emacs mishandles this image file type")); @@ -6702,10 +6704,10 @@ jpeg_load_body (struct frame *f, struct image *img, FILE *volatile fp = NULL; JSAMPARRAY buffer; int row_stride, x, y; - unsigned long *colors; int width, height; int i, ir, ig, ib; #ifndef USE_CAIRO + unsigned long *colors; XImagePtr ximg = NULL; #endif @@ -6823,7 +6825,7 @@ jpeg_load_body (struct frame *f, struct image *img, else ir = 0, ig = 0, ib = 0; -#ifndef CAIRO +#ifndef USE_CAIRO /* Use the color table mechanism because it handles colors that cannot be allocated nicely. Such colors will be replaced with a default color, and we don't have to care about which colors @@ -8537,7 +8539,9 @@ imagemagick_load_image (struct frame *f, struct image *img, int width, height; size_t image_width, image_height; MagickBooleanType status; +#ifndef USE_CAIRO XImagePtr ximg; +#endif int x, y; MagickWand *image_wand; PixelIterator *iterator; @@ -8551,6 +8555,9 @@ imagemagick_load_image (struct frame *f, struct image *img, double rotation; char hint_buffer[MaxTextExtent]; char *filename_hint = NULL; +#ifdef USE_CAIRO + void *data = NULL; +#endif /* Initialize the ImageMagick environment. */ static bool imagemagick_initialized; @@ -8759,6 +8766,12 @@ imagemagick_load_image (struct frame *f, struct image *img, /* Magicexportimage is normally faster than pixelpushing. This method is also well tested. Some aspects of this method are ad-hoc and needs to be more researched. */ + void *dataptr; +#ifdef USE_CAIRO + data = xmalloc (width * height * 4); + const char *exportdepth = "BGRA"; + dataptr = data; +#else int imagedepth = 24; /*MagickGetImageDepth(image_wand);*/ const char *exportdepth = imagedepth <= 8 ? "I" : "BGRP"; /*"RGBP";*/ /* Try to create a x pixmap to hold the imagemagick pixmap. */ @@ -8771,6 +8784,8 @@ imagemagick_load_image (struct frame *f, struct image *img, image_error ("Imagemagick X bitmap allocation failure"); goto imagemagick_error; } + dataptr = ximg->data; +#endif /* not USE_CAIRO */ /* Oddly, the below code doesn't seem to work:*/ /* switch(ximg->bitmap_unit){ */ @@ -8793,14 +8808,17 @@ imagemagick_load_image (struct frame *f, struct image *img, */ int pixelwidth = CharPixel; /*??? TODO figure out*/ MagickExportImagePixels (image_wand, 0, 0, width, height, - exportdepth, pixelwidth, ximg->data); + exportdepth, pixelwidth, dataptr); } else #endif /* HAVE_MAGICKEXPORTIMAGEPIXELS */ { size_t image_height; MagickRealType color_scale = 65535.0 / QuantumRange; - +#ifdef USE_CAIRO + data = xmalloc (width * height * 4); + color_scale /= 256; +#else /* Try to create a x pixmap to hold the imagemagick pixmap. */ if (!image_create_x_image_and_pixmap (f, img, width, height, 0, &ximg, 0)) @@ -8811,6 +8829,7 @@ imagemagick_load_image (struct frame *f, struct image *img, image_error ("Imagemagick X bitmap allocation failure"); goto imagemagick_error; } +#endif /* Copy imagemagick image to x with primitive yet robust pixel pusher loop. This has been tested a lot with many different @@ -8823,7 +8842,9 @@ imagemagick_load_image (struct frame *f, struct image *img, #ifdef COLOR_TABLE_SUPPORT free_color_table (); #endif +#ifndef USE_CAIRO x_destroy_x_image (ximg); +#endif image_error ("Imagemagick pixel iterator creation failed"); goto imagemagick_error; } @@ -8839,16 +8860,27 @@ imagemagick_load_image (struct frame *f, struct image *img, for (x = 0; x < xlim; x++) { PixelGetMagickColor (pixels[x], &pixel); +#ifdef USE_CAIRO + ((uint32_t *)data)[width * y + x] = + lookup_rgb_color (f, + color_scale * pixel.red, + color_scale * pixel.green, + color_scale * pixel.blue); +#else XPutPixel (ximg, x, y, lookup_rgb_color (f, color_scale * pixel.red, color_scale * pixel.green, color_scale * pixel.blue)); +#endif } } DestroyPixelIterator (iterator); } +#ifdef USE_CAIRO + create_cairo_image_surface (img, data, width, height); +#else #ifdef COLOR_TABLE_SUPPORT /* Remember colors allocated for this image. */ img->colors = colors_in_color_table (&img->ncolors); @@ -8860,6 +8892,7 @@ imagemagick_load_image (struct frame *f, struct image *img, /* Put ximg into the image. */ image_put_x_image (f, img, ximg, 0); +#endif /* Final cleanup. image_wand should be the only resource left. */ DestroyMagickWand (image_wand); diff --git a/src/xterm.c b/src/xterm.c index 7b445e5f46..f6f2079ec6 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -360,17 +360,12 @@ x_begin_cr_clip (struct frame *f, GC gc) if (! FRAME_CR_SURFACE (f)) { - cairo_surface_t *surface; - surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), - FRAME_X_DRAWABLE (f), - FRAME_DISPLAY_INFO (f)->visual, - FRAME_PIXEL_WIDTH (f), - FRAME_PIXEL_HEIGHT (f)); - cr = cairo_create (surface); - cairo_surface_destroy (surface); - } - else - cr = cairo_create (FRAME_CR_SURFACE (f)); + FRAME_CR_SURFACE (f) = + cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + FRAME_PIXEL_WIDTH (f), + FRAME_PIXEL_HEIGHT (f)); + } + cr = cairo_create (FRAME_CR_SURFACE (f)); FRAME_CR_CONTEXT (f) = cr; } cairo_save (cr); @@ -1239,32 +1234,24 @@ x_update_end (struct frame *f) #ifdef USE_CAIRO if (FRAME_CR_SURFACE (f)) { - cairo_t *cr = 0; - block_input(); -#if defined (USE_GTK) && defined (HAVE_GTK3) - if (FRAME_GTK_WIDGET (f)) - { - GdkWindow *w = gtk_widget_get_window (FRAME_GTK_WIDGET (f)); - cr = gdk_cairo_create (w); - } - else -#endif - { - cairo_surface_t *surface; - int width = FRAME_PIXEL_WIDTH (f); - int height = FRAME_PIXEL_HEIGHT (f); - if (! FRAME_EXTERNAL_TOOL_BAR (f)) - height += FRAME_TOOL_BAR_HEIGHT (f); - if (! FRAME_EXTERNAL_MENU_BAR (f)) - height += FRAME_MENU_BAR_HEIGHT (f); - surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), - FRAME_X_DRAWABLE (f), - FRAME_DISPLAY_INFO (f)->visual, - width, - height); - cr = cairo_create (surface); - cairo_surface_destroy (surface); - } + cairo_t *cr; + cairo_surface_t *surface; + int width, height; + + block_input (); + width = FRAME_PIXEL_WIDTH (f); + height = FRAME_PIXEL_HEIGHT (f); + if (! FRAME_EXTERNAL_TOOL_BAR (f)) + height += FRAME_TOOL_BAR_HEIGHT (f); + if (! FRAME_EXTERNAL_MENU_BAR (f)) + height += FRAME_MENU_BAR_HEIGHT (f); + surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f), + FRAME_X_DRAWABLE (f), + FRAME_DISPLAY_INFO (f)->visual, + width, + height); + cr = cairo_create (surface); + cairo_surface_destroy (surface); cairo_set_source_surface (cr, FRAME_CR_SURFACE (f), 0, 0); cairo_paint (cr); @@ -4256,7 +4243,28 @@ x_scroll_run (struct window *w, struct run *run) x_clear_cursor (w); #ifdef USE_CAIRO - SET_FRAME_GARBAGED (f); + if (FRAME_CR_CONTEXT (f)) + { + cairo_surface_t *s = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + width, height); + cairo_t *cr = cairo_create (s); + cairo_set_source_surface (cr, cairo_get_target (FRAME_CR_CONTEXT (f)), + -x, -from_y); + cairo_paint (cr); + cairo_destroy (cr); + + cr = FRAME_CR_CONTEXT (f); + cairo_save (cr); + cairo_set_source_surface (cr, s, 0, to_y); + cairo_rectangle (cr, x, to_y, width, height); + cairo_fill (cr); + cairo_restore (cr); + cairo_surface_destroy (s); + } + else + { + SET_FRAME_GARBAGED (f); + } #else XCopyArea (FRAME_X_DISPLAY (f), FRAME_X_DRAWABLE (f), FRAME_X_DRAWABLE (f), commit e96245a5497ecbc6c58740a6b6bd1f848a44b26c Author: Eli Zaretskii Date: Sat May 5 11:52:29 2018 +0300 Avoid infloops in font_open_entity * src/font.c (font_open_entity): Fail after 15 iterations through the loop that looks for a font whose average_width and height are both positive. This avoids infinite loops for fonts that, e.g., report average_width of zero for any possible size we try. (Bug#31316) (cherry picked from commit e2879c1f837059335af89022b2a9ac9bc861e96d) diff --git a/src/font.c b/src/font.c index a6d3f5d479..e53935a15c 100644 --- a/src/font.c +++ b/src/font.c @@ -2906,6 +2906,9 @@ font_open_entity (struct frame *f, Lisp_Object entity, int pixel_size) font = XFONT_OBJECT (font_object); if (font->average_width > 0 && font->height > 0) break; + /* Avoid an infinite loop. */ + if (psize > pixel_size + 15) + return Qnil; } ASET (font_object, FONT_SIZE_INDEX, make_number (pixel_size)); FONT_ADD_LOG ("open", entity, font_object); commit 3a06e7245703f58aaee5c50cfaa410458614efa0 Author: Eli Zaretskii Date: Sat May 5 11:45:37 2018 +0300 Fix encoding of characters when using GB18030 fonts * lisp/international/fontset.el (font-encoding-alist): Fix the GB18030 entry to encode characters correctly when passing them to the xfont back-end. (Bug#31315) See also http://lists.gnu.org/archive/html/emacs-devel/2008-01/msg00754.html. (cherry picked from commit bbe2cadc544e63e9378350621887f8fb9bbcc236) diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el index 6f91207451..5c0189b015 100644 --- a/lisp/international/fontset.el +++ b/lisp/international/fontset.el @@ -53,7 +53,10 @@ ("ascii-0$" . ascii) ("gb2312.1980" . chinese-gb2312) ("gbk" . chinese-gbk) - ("gb18030" . (unicode . nil)) + ;; GB18030 needs the characters encoded by gb18030, but a + ;; gb18030 font doesn't necessarily support all of the GB18030 + ;; characters. + ("gb18030" . (gb18030 . unicode)) ("jisx0208.1978" . japanese-jisx0208-1978) ("jisx0208" . japanese-jisx0208) ("jisx0201" . jisx0201) commit 7782550b3f1ae359c241f02e6b2edc4fe50cab72 Author: Eli Zaretskii Date: Fri Mar 30 15:57:57 2018 +0300 Fix C-p and C-n when wrap-prefix is too wide * src/xdisp.c (move_it_in_display_line_to): Avoid looping in previous/next-line when wrap-prefix is set to a too-wide stretch of whitespace. (Bug#30432) (cherry picked from commit 842b3d7412eaed6b2c9f90c3361abb4932ec0b1d) diff --git a/src/xdisp.c b/src/xdisp.c index 2142d771e2..d28c114067 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9211,9 +9211,25 @@ move_it_in_display_line_to (struct it *it, prev_method = it->method; if (it->method == GET_FROM_BUFFER) prev_pos = IT_CHARPOS (*it); + + /* Detect overly-wide wrap-prefixes made of (space ...) display + properties. When such a wrap prefix reaches past the right + margin of the window, we need to avoid the call to + set_iterator_to_next below, so that it->line_wrap is left at + its TRUNCATE value wisely set by handle_line_prefix. + Otherwise, set_iterator_to_next will pop the iterator stack, + restore it->line_wrap, and we might miss the opportunity to + exit the loop and return. */ + bool overwide_wrap_prefix = + CONSP (it->object) && EQ (XCAR (it->object), Qspace) + && it->sp > 0 && it->method == GET_FROM_STRETCH + && it->current_x >= it->last_visible_x + && it->continuation_lines_width > 0 + && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE; /* The current display element has been consumed. Advance to the next. */ - set_iterator_to_next (it, true); + if (!overwide_wrap_prefix) + set_iterator_to_next (it, true); if (IT_CHARPOS (*it) < CHARPOS (this_line_min_pos)) SET_TEXT_POS (this_line_min_pos, IT_CHARPOS (*it), IT_BYTEPOS (*it)); if (IT_CHARPOS (*it) < to_charpos) commit 9804482b026144237f10ae2fdd8a35e3fecb6d12 Author: Eli Zaretskii Date: Tue Mar 20 19:05:21 2018 +0200 Avoid redisplay problems with too wide wrap-prefix * src/xdisp.c (display_line): Avoid looping in redisplay when wrap-prefix is set to a too-wide stretch of whitespace. (Bug#30432) (cherry picked from commit 2a1fe08307402d6217d073f8ab7737750d253dd4) diff --git a/src/xdisp.c b/src/xdisp.c index 6ca115087c..2142d771e2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21957,9 +21957,24 @@ display_line (struct it *it, int cursor_vpos) break; } + /* Detect overly-wide wrap-prefixes made of (space ...) display + properties. When such a wrap prefix reaches past the right + margin of the window, we need to avoid the call to + set_iterator_to_next below, so that it->line_wrap is left at + its TRUNCATE value wisely set by handle_line_prefix. + Otherwise, set_iterator_to_next will pop the iterator stack, + restore it->line_wrap, and redisplay might infloop. */ + bool overwide_wrap_prefix = + CONSP (it->object) && EQ (XCAR (it->object), Qspace) + && it->sp > 0 && it->method == GET_FROM_STRETCH + && it->current_x >= it->last_visible_x + && it->continuation_lines_width > 0 + && it->line_wrap == TRUNCATE && it->stack[0].line_wrap != TRUNCATE; + /* Proceed with next display element. Note that this skips over lines invisible because of selective display. */ - set_iterator_to_next (it, true); + if (!overwide_wrap_prefix) + set_iterator_to_next (it, true); /* If we truncate lines, we are done when the last displayed glyphs reach past the right margin of the window. */ commit 5ee9ccf5c9d3f0b863439ac815c03c7b3e33a288 Author: Eli Zaretskii Date: Fri Mar 16 19:15:33 2018 +0200 Fix 'posn-at-point' when line numbers are displayed * src/xdisp.c (pos_visible_p): For the leftmost glyph, adjust the X coordinate due to line-number display. (Bug#30834) (cherry picked from commit 4a20174d7949028f66b18a92a75d6b74194242a8) diff --git a/src/xdisp.c b/src/xdisp.c index 21fb6bca1d..6ca115087c 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -1383,6 +1383,29 @@ pos_visible_p (struct window *w, ptrdiff_t charpos, int *x, int *y, move_it_to (&it, charpos, -1, it.last_visible_y - 1, -1, (charpos >= 0 ? MOVE_TO_POS : 0) | MOVE_TO_Y); + /* Adjust for line numbers, if CHARPOS is at or beyond first_visible_x, + but we didn't yet produce the line-number glyphs. */ + if (!NILP (Vdisplay_line_numbers) + && it.current_x >= it.first_visible_x + && IT_CHARPOS (it) == charpos + && !it.line_number_produced_p) + { + /* If the pixel width of line numbers was not yet known, compute + it now. This usually happens in the first display line of a + window. */ + if (!it.lnum_pixel_width) + { + struct it it2; + void *it2data = NULL; + + SAVE_IT (it2, it, it2data); + move_it_by_lines (&it, 1); + it2.lnum_pixel_width = it.lnum_pixel_width; + RESTORE_IT (&it, &it2, it2data); + } + it.current_x += it.lnum_pixel_width; + } + if (charpos >= 0 && (((!it.bidi_p || it.bidi_it.scan_dir != -1) && IT_CHARPOS (it) >= charpos) commit c4db7662bb4740f069e494cfe632c76a0d21d6d7 Author: Eli Zaretskii Date: Fri Mar 16 18:11:07 2018 +0200 Another followup to fixing 'window-text-pixel-width' * src/xdisp.c (Fwindow_text_pixel_size): Adjust the return value when we stop one buffer position short of TO. (Bug#30746) (cherry picked from commit 33cba5405c724566673cf023513bfb1faa963bea) diff --git a/src/xdisp.c b/src/xdisp.c index 4e3955ea61..21fb6bca1d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10175,9 +10175,14 @@ include the height of both, if present, in the return value. */) RESTORE_IT (&it, &it2, it2data); x = move_it_to (&it, end, to_x, max_y, -1, move_op); /* Add the width of the thing at TO, but only if we didn't - overshoot it; if we did, it is already accounted for. */ + overshoot it; if we did, it is already accounted for. Also, + account for the height of the thing at TO. */ if (IT_CHARPOS (it) == end) - x += it.pixel_width; + { + x += it.pixel_width; + it.max_ascent = max (it.max_ascent, it.ascent); + it.max_descent = max (it.max_descent, it.descent); + } } if (!NILP (x_limit)) { commit a6cf7be3f05418200453113c9bc99e057270aad3 Author: Eli Zaretskii Date: Thu Mar 15 15:13:50 2018 +0200 Fix mouse-set-point when line numbers are displayed * src/xdisp.c (move_it_to): Initialize the line_number_produced_p flag before iterating on a new line. (Bug#30818) (cherry picked from commit 5c585b8b994aad4e6844f8eed80bdfbb396e91bf) diff --git a/src/xdisp.c b/src/xdisp.c index f637dec64d..4e3955ea61 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -9600,6 +9600,7 @@ move_it_to (struct it *it, ptrdiff_t to_charpos, int to_x, int to_y, int to_vpos it->current_x = line_start_x; line_start_x = 0; it->hpos = 0; + it->line_number_produced_p = false; it->current_y += it->max_ascent + it->max_descent; ++it->vpos; last_height = it->max_ascent + it->max_descent; commit ae78b142901c954d16a35eaf97b312438f751bdb Author: Eli Zaretskii Date: Tue Mar 13 20:00:54 2018 +0200 * src/xdisp.c (Fwindow_text_pixel_size): Fix last change. (cherry picked from commit 06911714ef66ea81380b1eda75a9f7cfbc9e0b65) diff --git a/src/xdisp.c b/src/xdisp.c index 419187376f..f637dec64d 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10145,14 +10145,12 @@ include the height of both, if present, in the return value. */) directionality, and regions that begin and end in text of the same directionality. */ it.bidi_p = false; - void *it2data = NULL; - struct it it2; - SAVE_IT (it2, it, it2data); int move_op = MOVE_TO_POS | MOVE_TO_Y; int to_x = -1; if (!NILP (x_limit)) { + it.last_visible_x = max_x; /* Actually, we never want move_it_to stop at to_x. But to make sure that move_it_in_display_line_to always moves far enough, we set to_x to INT_MAX and specify MOVE_TO_X. */ @@ -10160,6 +10158,10 @@ include the height of both, if present, in the return value. */) to_x = INT_MAX; } + void *it2data = NULL; + struct it it2; + SAVE_IT (it2, it, it2data); + x = move_it_to (&it, end, to_x, max_y, -1, move_op); /* We could have a display property at END, in which case asking commit f1f12d8be3ddc5aa0a79658f5b339c78742321fa Author: Eli Zaretskii Date: Thu Mar 8 15:32:23 2018 +0200 Fix 'window-text-pixel-size' when display properties are around * src/xdisp.c (Fwindow_text_pixel_size): Correct the result when there's a display property at the TO position, and the call to move_it_to overshoots. (Bug#30746) (cherry picked from commit 50e2c0fb5180a757d8d533518f68837ffe5909be) diff --git a/src/xdisp.c b/src/xdisp.c index 5a301e4090..419187376f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -10138,17 +10138,46 @@ include the height of both, if present, in the return value. */) itdata = bidi_shelve_cache (); SET_TEXT_POS (startp, start, CHAR_TO_BYTE (start)); start_display (&it, w, startp); - - if (NILP (x_limit)) - x = move_it_to (&it, end, -1, max_y, -1, MOVE_TO_POS | MOVE_TO_Y); - else + /* It makes no sense to measure dimensions of region of text that + crosses the point where bidi reordering changes scan direction. + By using unidirectional movement here we at least support the use + case of measuring regions of text that have a uniformly R2L + directionality, and regions that begin and end in text of the + same directionality. */ + it.bidi_p = false; + void *it2data = NULL; + struct it it2; + SAVE_IT (it2, it, it2data); + + int move_op = MOVE_TO_POS | MOVE_TO_Y; + int to_x = -1; + if (!NILP (x_limit)) { - it.last_visible_x = max_x; /* Actually, we never want move_it_to stop at to_x. But to make sure that move_it_in_display_line_to always moves far enough, - we set it to INT_MAX and specify MOVE_TO_X. */ - x = move_it_to (&it, end, INT_MAX, max_y, -1, - MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); + we set to_x to INT_MAX and specify MOVE_TO_X. */ + move_op |= MOVE_TO_X; + to_x = INT_MAX; + } + + x = move_it_to (&it, end, to_x, max_y, -1, move_op); + + /* We could have a display property at END, in which case asking + move_it_to to stop at END will overshoot and stop at position + after END. So we try again, stopping before END, and account for + the width of the last buffer position manually. */ + if (IT_CHARPOS (it) > end) + { + end--; + RESTORE_IT (&it, &it2, it2data); + x = move_it_to (&it, end, to_x, max_y, -1, move_op); + /* Add the width of the thing at TO, but only if we didn't + overshoot it; if we did, it is already accounted for. */ + if (IT_CHARPOS (it) == end) + x += it.pixel_width; + } + if (!NILP (x_limit)) + { /* Don't return more than X-LIMIT. */ if (x > max_x) x = max_x; commit 8b2b4b580c38d7f1d95f8b2bf1f7c6ad8b9207b9 Author: Eli Zaretskii Date: Wed Mar 7 20:40:44 2018 +0200 Fix display of TABs in hscrolled windows with line numbers * src/dispextern.h (struct it): New members tab_offset and line_number_produced_p. * src/xdisp.c (display_line): Don't set row->x to a negative value if line numbers are being displayed. (Bug#30582) Reset the line_number_produced_p flag before laying out the glyph row. (x_produce_glyphs): Use the line_number_produced_p flag to decide whether to offset the X coordinate due to line-number display. Use the tab_offset member to restore the original TAB width for alignment purposes. (move_it_in_display_line_to): Don't produce line numbers when moving in hscrolled window to the left of first_visible_x. (maybe_produce_line_number): Set the line_number_produced_p flag. (Bug#30584) * src/term.c (produce_glyphs): Correct TAB width only when line_number_produced_p flag is set. (cherry picked from commit 1ac190553886ff20817d3dd218464e2fc6f9e42a) diff --git a/src/dispextern.h b/src/dispextern.h index d3e068677f..29c401c61e 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -2462,6 +2462,10 @@ struct it descent/ascent (line-height property). Reset after this glyph. */ bool_bf constrain_row_ascent_descent_p : 1; + /* If true, glyphs for line number display were already produced for + the current row. */ + bool_bf line_number_produced_p : 1; + enum line_wrap_method line_wrap; /* The ID of the default face to use. One of DEFAULT_FACE_ID, @@ -2641,6 +2645,12 @@ struct it /* The line number of point's line, or zero if not computed yet. */ ptrdiff_t pt_lnum; + /* Number of pixels to offset tab stops due to width fixup of the + first glyph that crosses first_visible_x. This is only needed on + GUI frames, only when display-line-numbers is in effect, and only + in hscrolled windows. */ + int tab_offset; + /* Left fringe bitmap number (enum fringe_bitmap_type). */ unsigned left_user_fringe_bitmap : FRINGE_ID_BITS; diff --git a/src/term.c b/src/term.c index b3707da70a..f542fc527c 100644 --- a/src/term.c +++ b/src/term.c @@ -1591,13 +1591,13 @@ produce_glyphs (struct it *it) + it->continuation_lines_width); int x0 = absolute_x; /* Adjust for line numbers. */ - if (!NILP (Vdisplay_line_numbers)) + if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) absolute_x -= it->lnum_pixel_width; int next_tab_x = (((1 + absolute_x + it->tab_width - 1) / it->tab_width) * it->tab_width); - if (!NILP (Vdisplay_line_numbers)) + if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) next_tab_x += it->lnum_pixel_width; int nspaces; diff --git a/src/xdisp.c b/src/xdisp.c index 479a4c5a31..5a301e4090 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -8718,8 +8718,12 @@ move_it_in_display_line_to (struct it *it, if (it->hpos == 0) { - /* If line numbers are being displayed, produce a line number. */ - if (should_produce_line_number (it)) + /* If line numbers are being displayed, produce a line number. + But don't do that if we are to reach first_visible_x, because + line numbers are not relevant to stuff that is not visible on + display. */ + if (!((op && MOVE_TO_X) && to_x == it->first_visible_x) + && should_produce_line_number (it)) { if (it->current_x == it->first_visible_x) maybe_produce_line_number (it); @@ -21169,6 +21173,8 @@ maybe_produce_line_number (struct it *it) it->max_phys_descent = max (it->max_phys_descent, tem_it.max_phys_descent); } + it->line_number_produced_p = true; + bidi_unshelve_cache (itdata, false); } @@ -21292,6 +21298,8 @@ display_line (struct it *it, int cursor_vpos) row->displays_text_p = true; row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p; it->starts_in_middle_of_char_p = false; + it->tab_offset = 0; + it->line_number_produced_p = false; /* Arrange the overlays nicely for our purposes. Usually, we call display_line on only one line at a time, in which case this @@ -21336,6 +21344,10 @@ display_line (struct it *it, int cursor_vpos) || move_result == MOVE_POS_MATCH_OR_ZV)) it->current_x = it->first_visible_x; + /* In case move_it_in_display_line_to above "produced" the line + number. */ + it->line_number_produced_p = false; + /* Record the smallest positions seen while we moved over display elements that are not visible. This is needed by redisplay_internal for optimizing the case where the cursor @@ -21555,6 +21567,10 @@ display_line (struct it *it, int cursor_vpos) row->extra_line_spacing = max (row->extra_line_spacing, it->max_extra_line_spacing); if (it->current_x - it->pixel_width < it->first_visible_x + /* When line numbers are displayed, row->x should not be + offset, as the first glyph after the line number can + never be partially visible. */ + && !line_number_needed /* In R2L rows, we arrange in extend_face_to_end_of_line to add a right offset to the line, by a suitable change to the stretch glyph that is the leftmost @@ -21796,7 +21812,8 @@ display_line (struct it *it, int cursor_vpos) if (it->bidi_p) RECORD_MAX_MIN_POS (it); - if (x < it->first_visible_x && !row->reversed_p) + if (x < it->first_visible_x && !row->reversed_p + && !line_number_needed) /* Glyph is partially visible, i.e. row starts at negative X position. Don't do that in R2L rows, where we arrange to add a right offset to @@ -21812,6 +21829,7 @@ display_line (struct it *it, int cursor_vpos) be taken care of in produce_special_glyphs. */ if (row->reversed_p && new_x > it->last_visible_x + && !line_number_needed && !(it->line_wrap == TRUNCATE && WINDOW_LEFT_FRINGE_WIDTH (it->w) == 0)) { @@ -28264,8 +28282,14 @@ x_produce_glyphs (struct it *it) int x = it->current_x + it->continuation_lines_width; int x0 = x; /* Adjust for line numbers, if needed. */ - if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) - x -= it->lnum_pixel_width; + if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) + { + x -= it->lnum_pixel_width; + /* Restore the original TAB width, if required. */ + if (x + it->tab_offset >= it->first_visible_x) + x += it->tab_offset; + } + int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width; /* If the distance from the current position to the next tab @@ -28273,10 +28297,19 @@ x_produce_glyphs (struct it *it) tab stop after that. */ if (next_tab_x - x < font->space_width) next_tab_x += tab_width; - if (!NILP (Vdisplay_line_numbers) && x0 >= it->lnum_pixel_width) - next_tab_x += (it->lnum_pixel_width - - ((it->w->hscroll * font->space_width) - % tab_width)); + if (!NILP (Vdisplay_line_numbers) && it->line_number_produced_p) + { + next_tab_x += it->lnum_pixel_width; + /* If the line is hscrolled, and the TAB starts before + the first visible pixel, simulate negative row->x. */ + if (x < it->first_visible_x) + { + next_tab_x -= it->first_visible_x - x; + it->tab_offset = it->first_visible_x - x; + } + else + next_tab_x -= it->tab_offset; + } it->pixel_width = next_tab_x - x0; it->nglyphs = 1; commit de69d28458e52487ebb9db47b100c23a16ab6093 Author: Matthias Dahl Date: Fri Feb 16 17:57:40 2018 +0200 Fix wait_reading_process_output wait_proc hang * src/process.c (read_process_output): Track bytes read from a process. (wait_reading_process_output): If called recursively through timers and/or process filters via accept-process-output, it is possible that the output of wait_proc has already been read by one of those recursive calls, leaving the original call hanging forever if no further output arrives through that fd and no timeout has been set. Fix that by using the process read accounting to keep track of how many bytes have been read and use that as a condition to break out of the infinite loop and return to the caller as well as to calculate the proper return value (if a wait_proc is given that is). * src/process.h (struct Lisp_Process): Add nbytes_read to track bytes read from a process. (cherry picked from commit 4ba32858d61eee16f17b51aca01c15211a0912f8) diff --git a/src/process.c b/src/process.c index 45ab1fd724..7f6ea1261e 100644 --- a/src/process.c +++ b/src/process.c @@ -5009,6 +5009,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, struct timespec got_output_end_time = invalid_timespec (); enum { MINIMUM = -1, TIMEOUT, INFINITY } wait; int got_some_output = -1; + uintmax_t prev_wait_proc_nbytes_read = wait_proc ? wait_proc->nbytes_read : 0; #if defined HAVE_GETADDRINFO_A || defined HAVE_GNUTLS bool retry_for_async; #endif @@ -5463,6 +5464,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, if (nfds == 0) { /* Exit the main loop if we've passed the requested timeout, + or have read some bytes from our wait_proc (either directly + in this call or indirectly through timers / process filters), or aren't skipping processes and got some output and haven't lowered our timeout due to timers or SIGIO and have waited a long amount of time due to repeated @@ -5470,7 +5473,9 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, struct timespec huge_timespec = make_timespec (TYPE_MAXIMUM (time_t), 2 * TIMESPEC_RESOLUTION); struct timespec cmp_time = huge_timespec; - if (wait < TIMEOUT) + if (wait < TIMEOUT + || (wait_proc + && wait_proc->nbytes_read != prev_wait_proc_nbytes_read)) break; if (wait == TIMEOUT) cmp_time = end_time; @@ -5785,6 +5790,15 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd, maybe_quit (); } + /* Timers and/or process filters that we have run could have themselves called + `accept-process-output' (and by that indirectly this function), thus + possibly reading some (or all) output of wait_proc without us noticing it. + This could potentially lead to an endless wait (dealt with earlier in the + function) and/or a wrong return value (dealt with here). */ + if (wait_proc && wait_proc->nbytes_read != prev_wait_proc_nbytes_read) + got_some_output = min (INT_MAX, (wait_proc->nbytes_read + - prev_wait_proc_nbytes_read)); + return got_some_output; } @@ -5903,6 +5917,9 @@ read_process_output (Lisp_Object proc, int channel) coding->mode |= CODING_MODE_LAST_BLOCK; } + /* Ignore carryover, it's been added by a previous iteration already. */ + p->nbytes_read += nbytes; + /* Now set NBYTES how many bytes we must decode. */ nbytes += carryover; diff --git a/src/process.h b/src/process.h index ab468b18c5..6464a8cc61 100644 --- a/src/process.h +++ b/src/process.h @@ -129,6 +129,8 @@ struct Lisp_Process pid_t pid; /* Descriptor by which we read from this process. */ int infd; + /* Byte-count modulo (UINTMAX_MAX + 1) for process output read from `infd'. */ + uintmax_t nbytes_read; /* Descriptor by which we write to this process. */ int outfd; /* Descriptors that were created for this process and that need commit 76f692e82f13dc2d36e3636932f3998023a66289 Merge: ddd1b957e9 90bea37d46 Author: Eli Zaretskii Date: Sat Jun 2 12:10:51 2018 +0300 Merge branch 'emacs-26' of git.savannah.gnu.org:/srv/git/emacs into emacs-26 commit ddd1b957e9406a4185e5a43ad3933b4e734d58f1 Author: Eli Zaretskii Date: Fri Jan 19 16:18:41 2018 +0200 Fix posn-at-point in Flycheck buffers * src/dispnew.c (buffer_posn_from_coords): Improve commentary. * src/xdisp.c (move_it_in_display_line_to): Don't exit the loop under truncate-lines if the glyph at TO_CHARPOS was not yet produced. This avoids bailing out too early when we are at TO_CHARPOS, but didn't yet produce glyphs for that buffer position, because the last call to PRODUCE_GLYPHS at this position was for an object other than the buffer. For further details, see http://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00537.html. (cherry picked from commit c0154ac7c3423f68d8f3a2e85a756c9759219039) diff --git a/src/dispnew.c b/src/dispnew.c index ae6799bb85..a81d6f64d1 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5208,6 +5208,11 @@ buffer_posn_from_coords (struct window *w, int *x, int *y, struct display_pos *p #ifdef HAVE_WINDOW_SYSTEM if (it.what == IT_IMAGE) { + /* Note that this ignores images that are fringe bitmaps, + because their image ID is zero, and so IMAGE_OPT_FROM_ID will + return NULL. This is okay, since fringe bitmaps are not + displayed in the text area, and so are never the object we + are interested in. */ img = IMAGE_OPT_FROM_ID (it.f, it.image_id); if (img && !NILP (img->spec)) *object = img->spec; diff --git a/src/xdisp.c b/src/xdisp.c index d6aabd0618..479a4c5a31 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -8790,7 +8790,16 @@ move_it_in_display_line_to (struct it *it, if (it->line_wrap == TRUNCATE) { - if (BUFFER_POS_REACHED_P ()) + /* If it->pixel_width is zero, the last PRODUCE_GLYPHS call + produced something that doesn't consume any screen estate + in the text area, so we don't want to exit the loop at + TO_CHARPOS, before we produce the glyph for that buffer + position. This happens, e.g., when there's an overlay at + TO_CHARPOS that draws a fringe bitmap. */ + if (BUFFER_POS_REACHED_P () + && (it->pixel_width > 0 + || IT_CHARPOS (*it) > to_charpos + || it->area != TEXT_AREA)) { result = MOVE_POS_MATCH_OR_ZV; break; commit 90bea37d466f47a65f3790b4bc46b11af9a4a27a Author: Martin Rudalics Date: Sat Jun 2 11:05:52 2018 +0200 ; * etc/PROBLEMS: Fix fvwm version number in last commit diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 6b15ee9eca..1e103e9af0 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1293,7 +1293,7 @@ the resource prevents the problem. Version 2.6.4 of the FVWM can make a frame sticky (appear on all user desktops) when setting the 'sticky' frame parameter to nil. This may happen without any special user interaction, for example, when Emacs -restores a saved desktop. A fix is to install version 2.6.7 of FVWM, +restores a saved desktop. A fix is to install version 2.6.8 of FVWM, see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31650. ** General X problems commit af82d1f4bd3c01786516c0d32cec4dc77a235778 Author: Martin Rudalics Date: Sat Jun 2 09:49:13 2018 +0200 * etc/PROBLEMS: Document stickyness problem with FVWM (Bug#31650) diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 09027332d8..6b15ee9eca 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -1288,6 +1288,14 @@ do not know what. If it is an Emacs bug, we hope someone can explain what the bug is so we can fix it. In the mean time, removing the resource prevents the problem. +*** FVWM: Some versions of FVWM incorrectly set the 'sticky' frame parameter. + +Version 2.6.4 of the FVWM can make a frame sticky (appear on all user +desktops) when setting the 'sticky' frame parameter to nil. This may +happen without any special user interaction, for example, when Emacs +restores a saved desktop. A fix is to install version 2.6.7 of FVWM, +see https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31650. + ** General X problems *** Redisplay using X is much slower than previous Emacs versions. commit 4a3aed2507a3e347fc0488c21cbc0a898efef6b7 Author: Eli Zaretskii Date: Fri Jun 1 17:11:36 2018 +0300 Update Emacs Lisp Intro to match current behavior * doc/lispintro/emacs-lisp-intro.texi (Wrong Type of Argument) (debug, debug-on-entry, Void Function, Void Variable): Update the *Backtrace* buffer display to current Emacs. (Bug#31654) diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index a256873ab1..aad572623a 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -1818,10 +1818,12 @@ You will create a @file{*Backtrace*} buffer that says: ---------- Buffer: *Backtrace* ---------- Debugger entered--Lisp error: (void-function fill-column) (fill-column) - eval((fill-column)) - eval-last-sexp-1(nil) + eval((fill-column) nil) + elisp--eval-last-sexp(nil) eval-last-sexp(nil) - call-interactively(eval-last-sexp) + funcall-interactively(eval-last-sexp nil) + call-interactively(eval-last-sexp nil nil) + command-execute(eval-last-sexp) ---------- Buffer: *Backtrace* ---------- @end group @end smallexample @@ -1868,9 +1870,11 @@ says: ---------- Buffer: *Backtrace* ---------- Debugger entered--Lisp error: (void-variable +) eval(+) - eval-last-sexp-1(nil) + elisp--eval-last-sexp(nil) eval-last-sexp(nil) - call-interactively(eval-last-sexp) + funcall-interactively(eval-last-sexp nil) + call-interactively(eval-last-sexp nil nil) + command-execute(eval-last-sexp) ---------- Buffer: *Backtrace* ---------- @end group @end smallexample @@ -2137,10 +2141,12 @@ You will create and enter a @file{*Backtrace*} buffer that says: Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p hello) +(2 hello) - eval((+ 2 (quote hello))) - eval-last-sexp-1(nil) + eval((+ 2 'hello) nil) + elisp--eval-last-sexp(t) eval-last-sexp(nil) - call-interactively(eval-last-sexp) + funcall-interactively(eval-print-last-sexp nil) + call-interactively(eval-print-last-sexp nil nil) + command-execute(eval-print-last-sexp) ---------- Buffer: *Backtrace* ---------- @end group @end smallexample @@ -18103,10 +18109,11 @@ Debugger entered--Lisp error: (void-function 1=) triangle-bugged(4) @end group @group - eval((triangle-bugged 4)) - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) + eval((triangle-bugged 4) nil) + eval-expression((triangle-bugged 4) nil nil 127) + funcall-interactively(eval-expression (triangle-bugged 4) nil nil 127) + call-interactively(eval-expression nil nil) + command-execute(eval-expression) ---------- Buffer: *Backtrace* ---------- @end group @end smallexample @@ -18220,12 +18227,13 @@ function: ---------- Buffer: *Backtrace* ---------- Debugger entered--entering a function: * triangle-bugged(5) - eval((triangle-bugged 5)) + eval((triangle-bugged 5) nil) @end group @group - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) + eval-expression((triangle-bugged 5) nil nil 127) + funcall-interactively(eval-expression (triangle-bugged 5) nil nil 127) + call-interactively(eval-expression nil nil) + command-execute(eval-expression) ---------- Buffer: *Backtrace* ---------- @end group @end smallexample @@ -18244,9 +18252,11 @@ Debugger entered--beginning evaluation of function call form: eval((triangle-bugged 5)) @end group @group - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) + eval((triangle-bugged 5) nil) + eval-expression((triangle-bugged 5) nil nil 127) + funcall-interactively(eval-expression (triangle-bugged 5) nil nil 127) + call-interactively(eval-expression nil nil) + command-execute(eval-expression) ---------- Buffer: *Backtrace* ---------- @end group @end smallexample @@ -18271,12 +18281,13 @@ Debugger entered--beginning evaluation of function call form: * (let ((total 0)) (while (> number 0) (setq total ...) (setq number ...)) total) * triangle-bugged(5) - eval((triangle-bugged 5)) + eval((triangle-bugged 5) nil) @group @end group - eval-last-sexp-1(nil) - eval-last-sexp(nil) - call-interactively(eval-last-sexp) + eval-expression((triangle-bugged 5) nil nil 127) + funcall-interactively(eval-expression (triangle-bugged 5) nil nil 127) + call-interactively(eval-expression nil nil) + command-execute(eval-expression) ---------- Buffer: *Backtrace* ---------- @end group @end smallexample commit 21f2247cf49d2332dd3f6d696318c9c65fd26c83 Merge: 6d2352594f 3257085443 Author: Eli Zaretskii Date: Fri Jun 1 17:10:46 2018 +0300 Merge branch 'emacs-26' of git.savannah.gnu.org:/srv/git/emacs into emacs-26 commit 325708544323c7434c62c0ae3773de2cc09692a5 Author: Robert Pluim Date: Fri Jun 1 15:34:33 2018 +0200 Fix previous commit * doc/emacs/files.texi (Interlocking): Two spaces at end of sentence diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 406e7d980c..821d8c1ead 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -772,7 +772,7 @@ file. visiting a file, Emacs records that the file is @dfn{locked} by you. (It does this by creating a specially-named symbolic link@footnote{If your file system does not support symbolic links, a regular file is -used.} with special contents in the same directory. @xref{File +used.} with special contents in the same directory. @xref{File Locks,,, elisp} for more details.) Emacs removes the lock when you save the changes. The idea is that the file is locked whenever an Emacs buffer visiting it has unsaved changes. commit 6d2352594f4e4e17965834851547df3adaa6cd6f Author: Ville Skyttä Date: Sun May 27 19:03:10 2018 +0200 Fix typos in several manuals (Bug#31610) Copyright-paperwork-exempt: yes diff --git a/doc/lispintro/emacs-lisp-intro.texi b/doc/lispintro/emacs-lisp-intro.texi index 67df6f208f..a256873ab1 100644 --- a/doc/lispintro/emacs-lisp-intro.texi +++ b/doc/lispintro/emacs-lisp-intro.texi @@ -484,7 +484,7 @@ Narrowing and Widening @code{car}, @code{cdr}, @code{cons}: Fundamental Functions -* Strange Names:: An historical aside: why the strange names? +* Strange Names:: A historical aside: why the strange names? * car & cdr:: Functions for extracting part of a list. * cons:: Constructing a list. * nthcdr:: Calling @code{cdr} repeatedly. @@ -6797,7 +6797,7 @@ will see @code{cons} as well as two variants on @code{cdr}, namely, @code{setcdr} and @code{nthcdr}. (@xref{copy-region-as-kill}.) @menu -* Strange Names:: An historical aside: why the strange names? +* Strange Names:: A historical aside: why the strange names? * car & cdr:: Functions for extracting part of a list. * cons:: Constructing a list. * nthcdr:: Calling @code{cdr} repeatedly. @@ -7678,7 +7678,7 @@ The first part of the code looks like this: @end smallexample @noindent -@code{char-table-p} is an hitherto unseen function. It determines +@code{char-table-p} is a hitherto unseen function. It determines whether its argument is a character table. When it is, it sets the character passed to @code{zap-to-char} to one of them, if that character exists, or to the character itself. (This becomes important diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 13a25af02c..ce7ec3ac10 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -1048,7 +1048,7 @@ commands operate as if that portion did not exist, allowing a single @code{next-line} command to skip any number of hidden lines. However, character movement commands (such as @code{forward-char}) do not skip the hidden portion, and it is possible (if tricky) to insert -or delete text in an hidden portion. +or delete text in a hidden portion. In the examples below, we show the @emph{display appearance} of the buffer @code{foo}, which changes with the value of diff --git a/doc/lispref/errors.texi b/doc/lispref/errors.texi index 5054172ff3..a0e32c5631 100644 --- a/doc/lispref/errors.texi +++ b/doc/lispref/errors.texi @@ -11,7 +11,7 @@ by concept. The list includes each symbol's message and a cross reference to a description of how the error can occur. - Each error symbol has an set of parent error conditions that is a + Each error symbol has a set of parent error conditions that is a list of symbols. Normally this list includes the error symbol itself and the symbol @code{error}. Occasionally it includes additional symbols, which are intermediate classifications, narrower than diff --git a/doc/misc/autotype.texi b/doc/misc/autotype.texi index 3d61d24fa9..7e2476c225 100644 --- a/doc/misc/autotype.texi +++ b/doc/misc/autotype.texi @@ -214,7 +214,7 @@ have been omitted.) @cindex skeleton language @findex skeleton-insert - Skeletons are an shorthand extension to the Lisp language, where various + Skeletons are a shorthand extension to the Lisp language, where various atoms directly perform either actions on the current buffer or rudimentary flow control mechanisms. Skeletons are interpreted by the function @code{skeleton-insert}. diff --git a/doc/misc/org.texi b/doc/misc/org.texi index 08ba33605e..88cdb5f951 100644 --- a/doc/misc/org.texi +++ b/doc/misc/org.texi @@ -5136,7 +5136,7 @@ that Org can parse this line correctly: In this example, @samp{GTD} is the @emph{group tag} and it is related to two other tags: @samp{Control}, @samp{Persp}. Defining @samp{Control} and -@samp{Persp} as group tags creates an hierarchy of tags: +@samp{Persp} as group tags creates a hierarchy of tags: @example #+TAGS: [ Control : Context Task ] @@ -11180,7 +11180,7 @@ Org exports text in this block only when using ASCII back-end. @cindex horizontal rules, in ASCII export ASCII back-end recognizes only one attribute, @code{:width}, which specifies -the width of an horizontal rule in number of characters. The keyword and +the width of a horizontal rule in number of characters. The keyword and syntax for specifying widths is: @example diff --git a/doc/misc/viper.texi b/doc/misc/viper.texi index 19d592f3e8..e67734bc01 100644 --- a/doc/misc/viper.texi +++ b/doc/misc/viper.texi @@ -4330,7 +4330,7 @@ Same as @code{tabstop}, but affects all buffers. @cindex auto fill @cindex word wrap wrapmargin: In append mode Vi automatically -puts a whenever there is a or +puts an whenever there is an or within columns from the right margin. @item wrapscan @itemx ws diff --git a/doc/misc/wisent.texi b/doc/misc/wisent.texi index 2dffa089da..12bb09c7b2 100644 --- a/doc/misc/wisent.texi +++ b/doc/misc/wisent.texi @@ -1937,7 +1937,7 @@ rule: @end example Set the @code{reparse-symbol} property of the expanded tag to -@samp{rule}. A important consequence is that: +@samp{rule}. An important consequence is that: @strong{Every nonterminal having any rule that calls @code{EXPANDTAG} in a semantic action, should be declared as a start symbol!} commit 9188291f7a3a2536ef0b694e4c75f3094cf46fcf Author: Robert Pluim Date: Fri Jun 1 15:05:23 2018 +0200 Add detailed documentation about lock files * doc/emacs/files.texi (Interlocking): Point user at detailed file locking description in lisp reference manual. Add index entry for '.#' to improve disoverability of information about locking. * doc/lispref/files.texi (File Locks): Describe in detail what the form of the lock file is. Add index entry for '.#' to improve disoverability of information about locking. * src/filelock.c (create-lockfiles): Add cross reference to file locking in user manual and to 'lock-buffer'. Add string '.#' to help users find the doc string. diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 1ced7ca07c..406e7d980c 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi @@ -766,13 +766,16 @@ file. @findex ask-user-about-lock @cindex locking files +@cindex .#, lock file names +@cindex file locking When you make the first modification in an Emacs buffer that is visiting a file, Emacs records that the file is @dfn{locked} by you. (It does this by creating a specially-named symbolic link@footnote{If your file system does not support symbolic links, a regular file is -used.} with special contents in the same directory.) Emacs removes the lock -when you save the changes. The idea is that the file is locked -whenever an Emacs buffer visiting it has unsaved changes. +used.} with special contents in the same directory. @xref{File +Locks,,, elisp} for more details.) Emacs removes the lock when you +save the changes. The idea is that the file is locked whenever an +Emacs buffer visiting it has unsaved changes. @vindex create-lockfiles You can prevent the creation of lock files by setting the variable diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 5137f3a9ab..6dfca0f212 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -712,6 +712,7 @@ with-temp-buffer,, The Current Buffer}. @section File Locks @cindex file locks @cindex lock file +@cindex .#, lock file names When two users edit the same file at the same time, they are likely to interfere with each other. Emacs tries to prevent this situation @@ -720,8 +721,17 @@ modified. Emacs can then detect the first attempt to modify a buffer visiting a file that is locked by another Emacs job, and ask the user what to do. The file lock is really a file, a symbolic link with a special name, -stored in the same directory as the file you are editing. (On file -systems that do not support symbolic links, a regular file is used.) +stored in the same directory as the file you are editing. The name is +constructed by prepending @file{.#} to the filename of the buffer. +The target of the symbolic link will be of the form +@code{@var{user}@@@var{host}.@var{pid}:@var{boot}}, where @var{user} +is replaced with the current username (from @code{user-login-name}), +@var{host} with the name of the host where Emacs is running (from +@code{system-name}), @var{pid} with Emacs's process id, and @var{boot} +with the time since the last reboot. @code{:@var{boot}} is omitted if +the boot time is unavailable. (On file systems that do not support +symbolic links, a regular file is used instead, with contents of the +form @code{@var{user}@@@var{host}.@var{pid}:@var{boot}}.) When you access files using NFS, there may be a small probability that you and another user will both lock the same file simultaneously. diff --git a/src/filelock.c b/src/filelock.c index f2dc723407..d33063c879 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -849,7 +849,10 @@ syms_of_filelock (void) Vtemporary_file_directory = Qnil; DEFVAR_BOOL ("create-lockfiles", create_lockfiles, - doc: /* Non-nil means use lockfiles to avoid editing collisions. */); + doc: /* Non-nil means use lockfiles to avoid editing collisions. +The name of the (per-buffer) lockfile is constructed by prepending a +'.#' to the name of the file being locked. See also `lock-buffer' and +Info node `(emacs)Interlocking'. */); create_lockfiles = 1; defsubr (&Sunlock_buffer); commit e5471b2381e885d5d214bfa09ab0c35275fc6048 Author: Eli Zaretskii Date: Fri Jun 1 15:34:30 2018 +0300 Add commentary for subtle aspect of frame.el * lisp/frame.el: Explain why we use symbol-function when adding watchers for certain variables that need to trigger redisplay. diff --git a/lisp/frame.el b/lisp/frame.el index 447413b325..29c31f41cb 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2475,6 +2475,9 @@ See also `toggle-frame-maximized'." ;; F5 then produces the correct effect, the variable doesn't need ;; to be in this list; otherwise, it does. (mapc (lambda (var) + ;; Using symbol-function here tells the watcher machinery to + ;; call the C function set-buffer-redisplay directly, thus + ;; avoiding a potential GC. (add-variable-watcher var (symbol-function 'set-buffer-redisplay))) '(line-spacing overline-margin commit 61c8434fec7aa45b939137f8ab90c5d5b8cfa4b4 Author: Glenn Morris Date: Fri Jun 1 06:30:31 2018 -0400 ; Auto-commit of loaddefs files. diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el index 165e1f13b6..738ad9e6ea 100644 --- a/lisp/ldefs-boot.el +++ b/lisp/ldefs-boot.el @@ -24870,58 +24870,43 @@ Check if KEY is in the cache. ;;; Generated autoloads from emacs-lisp/pcase.el (autoload 'pcase "pcase" "\ -Evaluate EXP and attempt to match it against structural patterns. +Evaluate EXP to get EXPVAL; try passing control to one of CASES. CASES is a list of elements of the form (PATTERN CODE...). - -A structural PATTERN describes a template that identifies a class -of values. For example, the pattern \\=`(,foo ,bar) matches any -two element list, binding its elements to symbols named `foo' and -`bar' -- in much the same way that `cl-destructuring-bind' would. - -A significant difference from `cl-destructuring-bind' is that, if -a pattern match fails, the next case is tried until either a -successful match is found or there are no more cases. The CODE -expression corresponding to the matching pattern determines the -return value. If there is no match the returned value is nil. - -Another difference is that pattern elements may be quoted, -meaning they must match exactly: The pattern \\='(foo bar) -matches only against two element lists containing the symbols -`foo' and `bar' in that order. (As a short-hand, atoms always -match themselves, such as numbers or strings, and need not be -quoted.) - -Lastly, a pattern can be logical, such as (pred numberp), that -matches any number-like element; or the symbol `_', that matches -anything. Also, when patterns are backquoted, a comma may be -used to introduce logical patterns inside backquoted patterns. - -The complete list of standard patterns is as follows: - - _ matches anything. - SYMBOL matches anything and binds it to SYMBOL. - If a SYMBOL is used twice in the same pattern - the second occurrence becomes an `eq'uality test. - (or PAT...) matches if any of the patterns matches. - (and PAT...) matches if all the patterns match. - \\='VAL matches if the object is `equal' to VAL. - ATOM is a shorthand for \\='ATOM. - ATOM can be a keyword, an integer, or a string. - (pred FUN) matches if FUN applied to the object returns non-nil. - (guard BOOLEXP) matches if BOOLEXP evaluates to non-nil. - (let PAT EXP) matches if EXP matches PAT. - (app FUN PAT) matches if FUN applied to the object matches PAT. +For the first CASE whose PATTERN \"matches\" EXPVAL, +evaluate its CODE..., and return the value of the last form. +If no CASE has a PATTERN that matches, return nil. + +Each PATTERN expands, in essence, to a predicate to call +on EXPVAL. When the return value of that call is non-nil, +PATTERN matches. PATTERN can take one of the forms: + + _ matches anything. + \\='VAL matches if EXPVAL is `equal' to VAL. + KEYWORD shorthand for \\='KEYWORD + INTEGER shorthand for \\='INTEGER + STRING shorthand for \\='STRING + SYMBOL matches anything and binds it to SYMBOL. + If a SYMBOL is used twice in the same pattern + the second occurrence becomes an `eq'uality test. + (pred FUN) matches if FUN called on EXPVAL returns non-nil. + (app FUN PAT) matches if FUN called on EXPVAL matches PAT. + (guard BOOLEXP) matches if BOOLEXP evaluates to non-nil. + (let PAT EXPR) matches if EXPR matches PAT. + (and PAT...) matches if all the patterns match. + (or PAT...) matches if any of the patterns matches. + +FUN in `pred' and `app' can take one of the forms: + SYMBOL or (lambda ARGS BODY) + call it with one argument + (F ARG1 .. ARGn) + call F with ARG1..ARGn and EXPVAL as n+1'th argument + +FUN, BOOLEXP, EXPR, and subsequent PAT can refer to variables +bound earlier in the pattern by a SYMBOL pattern. Additional patterns can be defined using `pcase-defmacro'. -The FUN argument in the `app' pattern may have the following forms: - SYMBOL or (lambda ARGS BODY) in which case it's called with one argument. - (F ARG1 .. ARGn) in which case F gets called with an n+1'th argument - which is the value being matched. -So a FUN of the form SYMBOL is equivalent to (FUN). -FUN can refer to variables bound earlier in the pattern. - -See Info node `(elisp) Pattern matching case statement' in the +See Info node `(elisp) Pattern-Matching Conditional' in the Emacs Lisp manual for more information and examples. \(fn EXP &rest CASES)" nil t) @@ -24981,7 +24966,10 @@ Define a new kind of pcase PATTERN, by macro expansion. Patterns of the form (NAME ...) will be expanded according to this macro. -\(fn NAME ARGS &rest BODY)" nil t) +By convention, DOC should use \"EXPVAL\" to stand +for the result of evaluating EXP (first arg to `pcase'). + +\(fn NAME ARGS [DOC] &rest BODY...)" nil t) (function-put 'pcase-defmacro 'lisp-indent-function '2) @@ -28216,12 +28204,12 @@ than appending to it. Deletes the message after writing if Ask user a multiple choice question. PROMPT should be a string that will be displayed as the prompt. -CHOICES is an alist where the first element in each entry is a -character to be entered, the second element is a short name for -the entry to be displayed while prompting (if there's room, it -might be shortened), and the third, optional entry is a longer -explanation that will be displayed in a help buffer if the user -requests more help. +CHOICES is a list of (KEY NAME [DESCRIPTION]). KEY is a +character to be entered. NAME is a short name for the entry to +be displayed while prompting (if there's room, it might be +shortened). DESCRIPTION is an optional longer explanation that +will be displayed in a help buffer if the user requests more +help. This function translates user input into responses by consulting the bindings in `query-replace-map'; see the documentation of @@ -28232,9 +28220,9 @@ perform the requested window recentering or scrolling and ask again. When `use-dialog-box' is t (the default), this function can pop -up a dialog window to collect the user input. That functionality -requires `display-popup-menus-p' to return t. Otherwise, a text -dialog will be used. +up a dialog window to collect the user input. That functionality +requires `display-popup-menus-p' to return t. Otherwise, a +text dialog will be used. The return value is the matching entry from the CHOICES list. @@ -34594,7 +34582,7 @@ Reenable Ange-FTP, when Tramp is unloaded. ;;;### (autoloads nil "trampver" "net/trampver.el" (0 0 0 0)) ;;; Generated autoloads from net/trampver.el -(push (purecopy '(tramp 2 3 3 26 1)) package--builtin-versions) +(push (purecopy '(tramp 2 3 4 -1)) package--builtin-versions) (if (fboundp 'register-definition-prefixes) (register-definition-prefixes "trampver" '("tramp-"))) commit ca3f0a8343c125a44845d21808ab0e35b87533db Author: Eli Zaretskii Date: Fri Jun 1 11:37:56 2018 +0300 ; * etc/NEWS: Belated announcement of 2 changes made in Emacs 26.1. diff --git a/etc/NEWS b/etc/NEWS index 217c4405ce..873e2dfd1d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -18,6 +18,13 @@ with a prefix argument or by typing C-u C-h C-n. * Installation Changes in Emacs 26.2 +--- +** Building Emacs with the '--with-xwidgets' option now requires WebKit2 +To build Emacs with xwidgets support, you will need to install the +webkit2gtk-4.0 package; version 2.12 or later is required. +(This change was actually made in Emacs 26.1, but was not called out +in its NEWS.) + * Startup Changes in Emacs 26.2 @@ -30,6 +37,17 @@ with a prefix argument or by typing C-u C-h C-n. * Changes in Specialized Modes and Packages in Emacs 26.2 +** Shell mode + +--- +*** Shell mode buffers now have 'scroll-conservatively' set to 101. +This is so as to better emulate the scrolling behavior of a text +terminal when new output is added to the screen buffer. To get back +the previous behavior, reset 'scroll-conservatively' to zero (or any +other value you like) in a function and add it to 'shell-mode-hook'. +(This change was actually made in Emacs 26.1, but was not called out +in its NEWS.) + * New Modes and Packages in Emacs 26.2 commit 99f92dab3d64c4ef0a38fa2f0ea5fd48b8bb2e1a Author: Eli Zaretskii Date: Fri Jun 1 11:27:29 2018 +0300 Improve documentation of 'directory-files-and-attributes' * doc/lispref/files.texi (Contents of Directories): Fix inaccurate description of the return value of directory-files-and-attributes. * src/dired.c (Fdirectory_files_and_attributes): Describe the function's value in more detail. diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index f62b670f47..5137f3a9ab 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -2917,8 +2917,8 @@ are included. This is similar to @code{directory-files} in deciding which files to report on and how to report their names. However, instead of returning a list of file names, it returns for each file a -list @code{(@var{filename} . @var{attributes})}, where @var{attributes} -is what @code{file-attributes} would return for that file. +list @code{(@var{filename} @var{attributes})}, where @var{attributes} +is what @code{file-attributes} returns for that file. The optional argument @var{id-format} has the same meaning as the corresponding argument to @code{file-attributes} (@pxref{Definition of file-attributes}). diff --git a/src/dired.c b/src/dired.c index c446223a0b..a753b1930e 100644 --- a/src/dired.c +++ b/src/dired.c @@ -358,7 +358,14 @@ If NOSORT is non-nil, the list is not sorted--its order is unpredictable. DEFUN ("directory-files-and-attributes", Fdirectory_files_and_attributes, Sdirectory_files_and_attributes, 1, 5, 0, doc: /* Return a list of names of files and their attributes in DIRECTORY. -There are four optional arguments: +Value is a list of the form: + + ((FILE1 FILE1-ATTRS) (FILE2 FILE2-ATTRS) ...) + +where each FILEn-ATTRS is the attributes of FILEn as returned +by `file-attributes'. + +This function accepts four optional arguments: If FULL is non-nil, return absolute file names. Otherwise return names that are relative to the specified directory. If MATCH is non-nil, mention only file names that match the regexp MATCH. commit df8649ac40be54cc3007241c4c1d5b1cb81c54dd Author: Katsumi Yamaoka Date: Wed May 30 23:30:11 2018 +0000 * lisp/gnus/message.el (message-remove-header): Don't remove things not looking like header (bug#31651). diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index 0eebbe299d..461f61f144 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -2431,7 +2431,9 @@ Return the number of headers removed." (while (and (not (eobp)) (not last)) (if (if reverse - (not (looking-at regexp)) + (and (not (looking-at regexp)) + ;; Don't remove things not looking like header. + (looking-at "[!-9;-~]+:")) (looking-at regexp)) (progn (incf number) commit b682a7e5bc644d88ca4e08a9b69e82ac799527c5 Author: Eli Zaretskii Date: Wed May 30 22:31:52 2018 +0300 ; * etc/NEWS: Add headings for Emacs 26.2 diff --git a/etc/NEWS b/etc/NEWS index 10afb7b420..217c4405ce 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -16,6 +16,33 @@ You can narrow news to a specific version by calling 'view-emacs-news' with a prefix argument or by typing C-u C-h C-n. +* Installation Changes in Emacs 26.2 + + +* Startup Changes in Emacs 26.2 + + +* Changes in Emacs 26.2 + + +* Editing Changes in Emacs 26.2 + + +* Changes in Specialized Modes and Packages in Emacs 26.2 + + +* New Modes and Packages in Emacs 26.2 + + +* Incompatible Lisp Changes in Emacs 26.2 + + +* Lisp Changes in Emacs 26.2 + + +* Changes in Emacs 26.2 on Non-Free Operating Systems + + * Installation Changes in Emacs 26.1 ** By default libgnutls is now required when building Emacs. commit aa175a40586c1021549e775b30fb03b4ffb09ac0 Author: Eli Zaretskii Date: Wed May 30 20:30:07 2018 +0300 Adapt hexl-mode to native line-number display * lisp/hexl.el (hexl-mode-ruler): When display-line-numbers is in effect, adjust offsets and columns to account for the line-number display. (Bug#31595) diff --git a/lisp/hexl.el b/lisp/hexl.el index d716405f97..2c1a7de48a 100644 --- a/lisp/hexl.el +++ b/lisp/hexl.el @@ -1104,8 +1104,15 @@ This function is assumed to be used as callback function for `hl-line-mode'." "Return a string ruler for Hexl mode." (let* ((highlight (mod (hexl-current-address) 16)) (s (cdr (assq hexl-bits hexl-rulers))) - (pos 0)) + (pos 0) + (lnum-width + (if display-line-numbers + (round (line-number-display-width 'columns)) + 0))) (set-text-properties 0 (length s) nil s) + (when (> lnum-width 0) + (setq s (concat (make-string lnum-width ? ) s)) + (setq pos (+ pos lnum-width))) ;; Turn spaces in the header into stretch specs so they work ;; regardless of the header-line face. (while (string-match "[ \t]+" s pos) @@ -1116,10 +1123,11 @@ This function is assumed to be used as callback function for `hl-line-mode'." s)) ;; Highlight the current column. (let ( (offset (+ (* 2 highlight) (/ (* 8 highlight) hexl-bits))) ) + (if (> lnum-width 0) (setq offset (+ offset lnum-width))) (put-text-property (+ 11 offset) (+ 13 offset) 'face 'highlight s)) ;; Highlight the current ascii column - (put-text-property (+ (hexl-ascii-start-column) highlight 1) - (+ (hexl-ascii-start-column) highlight 2) + (put-text-property (+ (hexl-ascii-start-column) lnum-width highlight 1) + (+ (hexl-ascii-start-column) lnum-width highlight 2) 'face 'highlight s) s)) commit b8e7749b3384ea14ca22be4d3adb8659f462ea06 Author: Michael Albinus Date: Wed May 30 09:00:04 2018 +0200 Fix example in Tramp manual * doc/misc/tramp.texi (Frequently Asked Questions): Fix wording for the zsh example. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 5fc77cd48c..a00f2f249b 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3162,7 +3162,7 @@ following line to @file{~/.zshrc}: This uses the default value of @code{tramp-terminal-type}, @samp{"dumb"}, as value of the @env{TERM} environment variable. If you want to use another value for @env{TERM}, change -@code{tramp-terminal-type} accordingly. +@code{tramp-terminal-type} and this line accordingly. When using fish shell on remote hosts, disable fancy formatting by adding the following to @file{~/.config/fish/config.fish}: commit f212fe512c3b1757310e875882e3d76b7e8fba23 Author: Robert Pluim Date: Tue May 29 20:32:08 2018 +0200 Handle case where Xft is found but not XRender * configure.ac (XFT_LIBS): Ensure that HAVE_XFT is no if XRender is not found. (Bug#31634) diff --git a/configure.ac b/configure.ac index c66c80adbb..c6101d6353 100644 --- a/configure.ac +++ b/configure.ac @@ -3210,8 +3210,8 @@ if test "${HAVE_X11}" = "yes"; then if test "x${with_xft}" != "xno"; then EMACS_CHECK_MODULES([XFT], [xft >= 0.13.0], [], [HAVE_XFT=no]) - ## Because xftfont.c uses XRenderQueryExtension, we also - ## need to link to -lXrender. + ## Because xterm.c uses XRenderQueryExtension when XFT is + ## enabled, we also need to link to -lXrender. HAVE_XRENDER=no AC_CHECK_LIB(Xrender, XRenderQueryExtension, HAVE_XRENDER=yes) if test "$HAVE_XFT" != no && test "$HAVE_XRENDER" != no; then @@ -3234,6 +3234,9 @@ if test "${HAVE_X11}" = "yes"; then CPPFLAGS=$OLD_CPPFLAGS CFLAGS=$OLD_CFLAGS LIBS=$OLD_LIBS + else + # Make sure XFT is disabled if we found XFT but not XRender + HAVE_XFT=no fi # "$HAVE_XFT" != no fi # "x${with_xft}" != "xno" commit 186280fbbc48d3dc2bfa022d11c1c000a1881bd4 Author: Michael Albinus Date: Tue May 29 19:45:23 2018 +0200 * doc/misc/tramp.texi (Frequently Asked Questions): Adapt zsh example. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 4e75b9a8f0..5fc77cd48c 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3159,6 +3159,11 @@ following line to @file{~/.zshrc}: [[ $TERM == "dumb" ]] && unsetopt zle && PS1='$ ' && return @end example +This uses the default value of @code{tramp-terminal-type}, +@samp{"dumb"}, as value of the @env{TERM} environment variable. If +you want to use another value for @env{TERM}, change +@code{tramp-terminal-type} accordingly. + When using fish shell on remote hosts, disable fancy formatting by adding the following to @file{~/.config/fish/config.fish}: commit 24ba63314f29fdffa9cfe012927e5efd744c138d Author: Damien Cassou Date: Mon May 28 17:12:34 2018 +0200 Improve read-multiple-choice docstring (Bug#31628) * lisp/emacs-lisp/rmc.el (read-multiple-choice): Improve docstring. diff --git a/lisp/emacs-lisp/rmc.el b/lisp/emacs-lisp/rmc.el index 3dd3508903..31974782b5 100644 --- a/lisp/emacs-lisp/rmc.el +++ b/lisp/emacs-lisp/rmc.el @@ -30,12 +30,12 @@ "Ask user a multiple choice question. PROMPT should be a string that will be displayed as the prompt. -CHOICES is an alist where the first element in each entry is a -character to be entered, the second element is a short name for -the entry to be displayed while prompting (if there's room, it -might be shortened), and the third, optional entry is a longer -explanation that will be displayed in a help buffer if the user -requests more help. +CHOICES is a list of (KEY NAME [DESCRIPTION]). KEY is a +character to be entered. NAME is a short name for the entry to +be displayed while prompting (if there's room, it might be +shortened). DESCRIPTION is an optional longer explanation that +will be displayed in a help buffer if the user requests more +help. This function translates user input into responses by consulting the bindings in `query-replace-map'; see the documentation of @@ -46,9 +46,9 @@ perform the requested window recentering or scrolling and ask again. When `use-dialog-box' is t (the default), this function can pop -up a dialog window to collect the user input. That functionality -requires `display-popup-menus-p' to return t. Otherwise, a text -dialog will be used. +up a dialog window to collect the user input. That functionality +requires `display-popup-menus-p' to return t. Otherwise, a +text dialog will be used. The return value is the matching entry from the CHOICES list.