commit edb4af7a1d1e8e0ab67b2dedad0ca0380e6866d4 (HEAD, refs/remotes/origin/master) Author: Puneeth Chaganti Date: Sat May 21 10:02:46 2016 +0300 * lisp/svg.el (svg-create): Fix a typo: xmlsn -> xmlns. (Bug#23589) diff --git a/lisp/svg.el b/lisp/svg.el index 0b45c5c..c4f3270 100644 --- a/lisp/svg.el +++ b/lisp/svg.el @@ -36,7 +36,7 @@ any further elements added." `((width . ,width) (height . ,height) (version . "1.1") - (xmlsn . "http://www.w3.org/2000/svg") + (xmlns . "http://www.w3.org/2000/svg") ,@(svg--arguments nil args)))) (defun svg-gradient (svg id type stops) commit 44d743c20fa84fe041581dd3e0e2c5b9d86189e7 Author: Andrew Hyatt Date: Sat May 21 00:08:27 2016 -0400 Added tests for dos unibyte decoding. The underlying bug was previously fixed by Eli Zaretskii in commit c8109d9c4057d8cac79e2c139758cadd410e7446. diff --git a/test/lisp/legacy/coding-tests.el b/test/lisp/legacy/coding-tests.el index cba8c7b..772c873 100644 --- a/test/lisp/legacy/coding-tests.el +++ b/test/lisp/legacy/coding-tests.el @@ -48,3 +48,11 @@ (let ((coding-system-for-write (intern "\"us-ascii\""))) (write-region "some text" nil test-file)))) (coding-tests-remove-files))) + +;; See issue #5251. +(ert-deftest ert-test-unibyte-buffer-dos-eol-decode () + (with-temp-buffer + (set-buffer-multibyte nil) + (insert (encode-coding-string "あ" 'euc-jp) "\xd" "\n") + (decode-coding-region (point-min) (point-max) 'euc-jp-dos) + (should-not (string-match-p "\^M" (buffer-string))))) commit f2b7a432687d6d561162774b8f3dc558903c796f Author: Philipp Stephani Date: Tue May 10 23:23:26 2016 +0200 Fix handling of ‘mouse-on-link-p’. If ‘mouse-on-link-p’ returns a string or vector, the first element is to be used as new event. Translation to ‘mouse-2’ should only happen if the return value is not a string or vector. See docstring of ‘mouse-on-link-p’ and Bug#23288. * lisp/mouse.el (mouse--down-1-maybe-follows-link): Process return value of ‘mouse-on-link-p’ according to documentation. * test/lisp/mouse-tests.el (bug23288-use-return-value) (bug23288-translate-to-mouse-2): Tests for Bug#23288. diff --git a/lisp/mouse.el b/lisp/mouse.el index e5e1110..3e3708a 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -97,35 +97,44 @@ Expects to be bound to `down-mouse-1' in `key-translation-map'." (when (and mouse-1-click-follows-link (eq (if (eq mouse-1-click-follows-link 'double) 'double-down-mouse-1 'down-mouse-1) - (car-safe last-input-event)) - (mouse-on-link-p (event-start last-input-event)) - (or mouse-1-click-in-non-selected-windows - (eq (selected-window) - (posn-window (event-start last-input-event))))) - (let ((timedout - (sit-for (if (numberp mouse-1-click-follows-link) - (/ (abs mouse-1-click-follows-link) 1000.0) - 0)))) - (if (if (and (numberp mouse-1-click-follows-link) - (>= mouse-1-click-follows-link 0)) - timedout (not timedout)) - nil - - (let ((event (read-key))) ;Use read-key so it works for xterm-mouse-mode! - (if (eq (car-safe event) (if (eq mouse-1-click-follows-link 'double) - 'double-mouse-1 'mouse-1)) - ;; Turn the mouse-1 into a mouse-2 to follow links. - (let ((newup (if (eq mouse-1-click-follows-link 'double) - 'double-mouse-2 'mouse-2))) - ;; If mouse-2 has never been done by the user, it doesn't have - ;; the necessary property to be interpreted correctly. - (unless (get newup 'event-kind) - (put newup 'event-kind (get (car event) 'event-kind))) - (push (cons newup (cdr event)) unread-command-events) - ;; Don't change the down event, only the up-event (bug#18212). - nil) - (push event unread-command-events) - nil)))))) + (car-safe last-input-event))) + (let ((action (mouse-on-link-p (event-start last-input-event)))) + (when (and action + (or mouse-1-click-in-non-selected-windows + (eq (selected-window) + (posn-window (event-start last-input-event))))) + (let ((timedout + (sit-for (if (numberp mouse-1-click-follows-link) + (/ (abs mouse-1-click-follows-link) 1000.0) + 0)))) + (if (if (and (numberp mouse-1-click-follows-link) + (>= mouse-1-click-follows-link 0)) + timedout (not timedout)) + nil + ;; Use read-key so it works for xterm-mouse-mode! + (let ((event (read-key))) + (if (eq (car-safe event) + (if (eq mouse-1-click-follows-link 'double) + 'double-mouse-1 'mouse-1)) + (progn + ;; Turn the mouse-1 into a mouse-2 to follow links, + ;; but only if ‘mouse-on-link-p’ hasn’t returned a + ;; string or vector (see its docstring). + (if (or (stringp action) (vectorp action)) + (push (aref action 0) unread-command-events) + (let ((newup (if (eq mouse-1-click-follows-link 'double) + 'double-mouse-2 'mouse-2))) + ;; If mouse-2 has never been done by the user, it + ;; doesn't have the necessary property to be + ;; interpreted correctly. + (unless (get newup 'event-kind) + (put newup 'event-kind (get (car event) 'event-kind))) + (push (cons newup (cdr event)) unread-command-events))) + ;; Don't change the down event, only the up-event + ;; (bug#18212). + nil) + (push event unread-command-events) + nil)))))))) (define-key key-translation-map [down-mouse-1] #'mouse--down-1-maybe-follows-link) diff --git a/test/lisp/mouse-tests.el b/test/lisp/mouse-tests.el new file mode 100644 index 0000000..21abf38 --- /dev/null +++ b/test/lisp/mouse-tests.el @@ -0,0 +1,48 @@ +;;; mouse-tests.el --- unit tests for mouse.el -*- lexical-binding: t; -*- + +;; Copyright (C) 2016 Free Software Foundation, Inc. + +;; Author: Philipp Stephani + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Unit tests for lisp/mouse.el. + +;;; Code: + +(ert-deftest bug23288-use-return-value () + "If ‘mouse-on-link-p’ returns a string, its first character is +used." + (cl-letf ((last-input-event '(down-mouse-1 nil 1)) + (unread-command-events '((mouse-1 nil 1))) + (mouse-1-click-follows-link t) + (mouse-1-click-in-non-selected-windows t) + ((symbol-function 'mouse-on-link-p) (lambda (_pos) "abc"))) + (should-not (mouse--down-1-maybe-follows-link)) + (should (equal unread-command-events '(?a))))) + +(ert-deftest bug23288-translate-to-mouse-2 () + "If ‘mouse-on-link-p’ doesn’t return a string or vector, +translate ‘mouse-1’ events into ‘mouse-2’ events." + (cl-letf ((last-input-event '(down-mouse-1 nil 1)) + (unread-command-events '((mouse-1 nil 1))) + (mouse-1-click-follows-link t) + (mouse-1-click-in-non-selected-windows t) + ((symbol-function 'mouse-on-link-p) (lambda (_pos) t))) + (should-not (mouse--down-1-maybe-follows-link)) + (should (equal unread-command-events '((mouse-2 nil 1)))))) + +;;; mouse-tests.el ends here commit 65e38569e5eca8e4e8a0e38391c07e3862e78cb7 Author: Daiki Ueno Date: Thu May 19 18:05:19 2016 +0900 epg: Add a way to detect gpg1 executable for tests Fixes bug#23561. * test/automated/epg-tests.el (epg-tests-program-alist-for-passphrase-callback): New constant. (epg-tests-find-usable-gpg-configuration): New function, renamed from `epg-tests-gpg-usable'. All callers changed. (epg-tests-gpg-usable): Remove. * lisp/epg-config.el (epg-config--program-alist): Factor out constructor element to... (epg-config--configuration-constructor-alist): ...here. (epg-find-configuration): Rename FORCE argument to NO-CACHE, and add PROGRAM-ALIST argument. diff --git a/lisp/epg-config.el b/lisp/epg-config.el index 8a20804..9179e04 100644 --- a/lisp/epg-config.el +++ b/lisp/epg-config.el @@ -81,57 +81,69 @@ Note that the buffer name starts with a space." (defconst epg-config--program-alist '((OpenPGP epg-gpg-program - epg-config--make-gpg-configuration ("gpg2" . "2.1.6") ("gpg" . "1.4.3")) (CMS epg-gpgsm-program - epg-config--make-gpgsm-configuration ("gpgsm" . "2.0.4"))) "Alist used to obtain the usable configuration of executables. The first element of each entry is protocol symbol, which is either `OpenPGP' or `CMS'. The second element is a symbol where -the executable name is remembered. The third element is a -function which constructs a configuration object (actually a -plist). The rest of the entry is an alist mapping executable -names to the minimum required version suitable for the use with -Emacs.") +the executable name is remembered. The rest of the entry is an +alist mapping executable names to the minimum required version +suitable for the use with Emacs.") + +(defconst epg-config--configuration-constructor-alist + '((OpenPGP . epg-config--make-gpg-configuration) + (CMS . epg-config--make-gpgsm-configuration)) + "Alist used to obtain the usable configuration of executables. +The first element of each entry is protocol symbol, which is +either `OpenPGP' or `CMS'. The second element is a function +which constructs a configuration object (actually a plist).") (defvar epg--configurations nil) ;;;###autoload -(defun epg-find-configuration (protocol &optional force) +(defun epg-find-configuration (protocol &optional no-cache program-alist) "Find or create a usable configuration to handle PROTOCOL. This function first looks at the existing configuration found by -the previous invocation of this function, unless FORCE is non-nil. - -Then it walks through `epg-config--program-alist'. If -`epg-gpg-program' or `epg-gpgsm-program' is already set with -custom, use it. Otherwise, it tries the programs listed in the -entry until the version requirement is met." - (let ((entry (assq protocol epg-config--program-alist))) +the previous invocation of this function, unless NO-CACHE is non-nil. + +Then it walks through PROGRAM-ALIST or +`epg-config--program-alist'. If `epg-gpg-program' or +`epg-gpgsm-program' is already set with custom, use it. +Otherwise, it tries the programs listed in the entry until the +version requirement is met." + (unless program-alist + (setq program-alist epg-config--program-alist)) + (let ((entry (assq protocol program-alist))) (unless entry (error "Unknown protocol %S" protocol)) - (cl-destructuring-bind (symbol constructor . alist) + (cl-destructuring-bind (symbol . alist) (cdr entry) - (or (and (not force) (alist-get protocol epg--configurations)) - ;; If the executable value is already set with M-x - ;; customize, use it without checking. - (if (get symbol 'saved-value) - (let ((configuration (funcall constructor (symbol-value symbol)))) - (push (cons protocol configuration) epg--configurations) - configuration) - (catch 'found - (dolist (program-version alist) - (let ((executable (executable-find (car program-version)))) - (when executable - (let ((configuration - (funcall constructor executable))) - (when (ignore-errors - (epg-check-configuration configuration - (cdr program-version)) - t) - (push (cons protocol configuration) epg--configurations) - (throw 'found configuration)))))))))))) + (let ((constructor + (alist-get protocol epg-config--configuration-constructor-alist))) + (or (and (not no-cache) (alist-get protocol epg--configurations)) + ;; If the executable value is already set with M-x + ;; customize, use it without checking. + (if (and symbol (get symbol 'saved-value)) + (let ((configuration + (funcall constructor (symbol-value symbol)))) + (push (cons protocol configuration) epg--configurations) + configuration) + (catch 'found + (dolist (program-version alist) + (let ((executable (executable-find (car program-version)))) + (when executable + (let ((configuration + (funcall constructor executable))) + (when (ignore-errors + (epg-check-configuration configuration + (cdr program-version)) + t) + (unless no-cache + (push (cons protocol configuration) + epg--configurations)) + (throw 'found configuration))))))))))))) ;; Create an `epg-configuration' object for `gpg', using PROGRAM. (defun epg-config--make-gpg-configuration (program) diff --git a/test/lisp/epg-tests.el b/test/lisp/epg-tests.el index 4a31797..d51ab23 100644 --- a/test/lisp/epg-tests.el +++ b/test/lisp/epg-tests.el @@ -30,16 +30,17 @@ (expand-file-name "data/epg" (getenv "EMACS_TEST_DIRECTORY")) "Directory containing epg test data.") -(defun epg-tests-gpg-usable (&optional require-passphrase) - (and (executable-find epg-gpg-program) - (condition-case nil - (progn - (epg-check-configuration (epg-configuration)) - (if require-passphrase - (string-match "\\`1\\." - (cdr (assq 'version (epg-configuration)))) - t)) - (error nil)))) +(defconst epg-tests-program-alist-for-passphrase-callback + '((OpenPGP + nil + ("gpg" . "1.4.3")))) + +(defun epg-tests-find-usable-gpg-configuration (&optional require-passphrase) + (epg-find-configuration + 'OpenPGP + 'no-cache + (if require-passphrase + epg-tests-program-alist-for-passphrase-callback))) (defun epg-tests-passphrase-callback (_c _k _d) ;; Need to create a copy here, since the string will be wiped out @@ -52,9 +53,14 @@ &rest body) "Set up temporary locations and variables for testing." (declare (indent 1)) - `(let* ((epg-tests-home-directory (make-temp-file "epg-tests-homedir" t))) + `(let ((epg-tests-home-directory (make-temp-file "epg-tests-homedir" t))) (unwind-protect (let ((context (epg-make-context 'OpenPGP))) + (setf (epg-context-program context) + (alist-get 'program + (epg-tests-find-usable-gpg-configuration + ,(if require-passphrase + `'require-passphrase)))) (setf (epg-context-home-directory context) epg-tests-home-directory) (setenv "GPG_AGENT_INFO") @@ -78,7 +84,7 @@ (delete-directory epg-tests-home-directory t))))) (ert-deftest epg-decrypt-1 () - (skip-unless (epg-tests-gpg-usable 'require-passphrase)) + (skip-unless (epg-tests-find-usable-gpg-configuration 'require-passphrase)) (with-epg-tests (:require-passphrase t) (should (equal "test" (epg-decrypt-string epg-tests-context "\ @@ -90,14 +96,14 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA== -----END PGP MESSAGE-----"))))) (ert-deftest epg-roundtrip-1 () - (skip-unless (epg-tests-gpg-usable 'require-passphrase)) + (skip-unless (epg-tests-find-usable-gpg-configuration 'require-passphrase)) (with-epg-tests (:require-passphrase t) (let ((cipher (epg-encrypt-string epg-tests-context "symmetric" nil))) (should (equal "symmetric" (epg-decrypt-string epg-tests-context cipher)))))) (ert-deftest epg-roundtrip-2 () - (skip-unless (epg-tests-gpg-usable 'require-passphrase)) + (skip-unless (epg-tests-find-usable-gpg-configuration 'require-passphrase)) (with-epg-tests (:require-passphrase t :require-public-key t :require-secret-key t) @@ -108,7 +114,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA== (epg-decrypt-string epg-tests-context cipher)))))) (ert-deftest epg-sign-verify-1 () - (skip-unless (epg-tests-gpg-usable 'require-passphrase)) + (skip-unless (epg-tests-find-usable-gpg-configuration 'require-passphrase)) (with-epg-tests (:require-passphrase t :require-public-key t :require-secret-key t) @@ -122,7 +128,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA== (should (eq 'good (epg-signature-status (car verify-result))))))) (ert-deftest epg-sign-verify-2 () - (skip-unless (epg-tests-gpg-usable 'require-passphrase)) + (skip-unless (epg-tests-find-usable-gpg-configuration 'require-passphrase)) (with-epg-tests (:require-passphrase t :require-public-key t :require-secret-key t) @@ -138,7 +144,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA== (should (eq 'good (epg-signature-status (car verify-result))))))) (ert-deftest epg-sign-verify-3 () - (skip-unless (epg-tests-gpg-usable 'require-passphrase)) + (skip-unless (epg-tests-find-usable-gpg-configuration 'require-passphrase)) (with-epg-tests (:require-passphrase t :require-public-key t :require-secret-key t) @@ -153,7 +159,7 @@ jA0EAwMCE19JBLTvvmhgyRrGGglRbnKkK9PJG8fDwO5ccjysrR7IcdNcnA== (should (eq 'good (epg-signature-status (car verify-result))))))) (ert-deftest epg-import-1 () - (skip-unless (epg-tests-gpg-usable 'require-passphrase)) + (skip-unless (epg-tests-find-usable-gpg-configuration 'require-passphrase)) (with-epg-tests (:require-passphrase nil) (should (= 0 (length (epg-list-keys epg-tests-context)))) (should (= 0 (length (epg-list-keys epg-tests-context nil t))))) commit 970074470d7bc332fc36fd30feee93e1d6130177 Author: Mark Oteiza Date: Thu May 19 19:01:08 2016 -0400 Put point at beginning of display-time-world buffer. If display-time-world decides to popup vertically from the bottom of the frame and scroll-margin is nonzero, the top of the buffer contents are hidden due to scroll. * lisp/time.el (display-time-world-display): Move point to point-min after inserting contents. diff --git a/lisp/time.el b/lisp/time.el index ba57924..651dd56 100644 --- a/lisp/time.el +++ b/lisp/time.el @@ -535,7 +535,8 @@ See `display-time-world'." (setq fmt (concat "%-" (int-to-string max-width) "s %s\n")) (dolist (timedata (nreverse result)) (insert (format fmt (car timedata) (cdr timedata)))) - (delete-char -1))) + (delete-char -1)) + (goto-char (point-min))) ;;;###autoload (defun display-time-world () commit e8a28b295fabbc249c5123b58fcf2beb82f08da2 Author: Paul Eggert Date: Thu May 19 08:38:55 2016 -0700 Allow null entries in face and image cache Problem reported by Tino Calancha (Bug#23580). * src/dispextern.h (FACE_FROM_ID, IMAGE_FROM_ID): Don’t assume that the result is non-null. * src/xdisp.c (fill_image_glyph_string): Restore check that image pointer is non-null. diff --git a/src/dispextern.h b/src/dispextern.h index 4deebc1..e83b7c7 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -1815,7 +1815,6 @@ struct face_cache #define FACE_FROM_ID(F, ID) \ (eassert (UNSIGNED_CMP (ID, <, FRAME_FACE_CACHE (F)->used)), \ - eassume (FRAME_FACE_CACHE (F)->faces_by_id[ID]), \ FRAME_FACE_CACHE (F)->faces_by_id[ID]) /* Return a pointer to the face with ID on frame F, or null if such a @@ -3093,7 +3092,6 @@ struct image_cache #define IMAGE_FROM_ID(F, ID) \ (eassert (UNSIGNED_CMP (ID, <, FRAME_IMAGE_CACHE (F)->used)), \ - eassume (FRAME_IMAGE_CACHE (F)->images[ID]), \ FRAME_IMAGE_CACHE (F)->images[ID]) /* Value is a pointer to the image with id ID on frame F, or null if diff --git a/src/xdisp.c b/src/xdisp.c index e18af2f..10a0cf2 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -24870,6 +24870,7 @@ fill_image_glyph_string (struct glyph_string *s) { eassert (s->first_glyph->type == IMAGE_GLYPH); s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id); + eassert (s->img); s->slice = s->first_glyph->slice.img; s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id); s->font = s->face->font; commit 40108979821637104d2ece39af8a27068544d3bd Author: Paul Eggert Date: Thu May 19 08:02:13 2016 -0700 Fix flyspell highlighting Problem reported by Jim Meyering (Bug#23575). * src/xdisp.c (extend_face_to_end_of_line): Fix typo in previous change. diff --git a/src/xdisp.c b/src/xdisp.c index bec7339..e18af2f 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -19635,8 +19635,8 @@ extend_face_to_end_of_line (struct it *it) to the end of the line. If the background equals the background of the frame, we don't have to do anything. */ face = FACE_OPT_FROM_ID (f, (it->face_before_selective_p - ? it->face_id - : it->saved_face_id)); + ? it->saved_face_id + : it->face_id)); if (FRAME_WINDOW_P (f) && MATRIX_ROW_DISPLAYS_TEXT_P (it->glyph_row)