commit 5c414441ed73f1a302a2953dc493e83b98589262 (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Mon Feb 5 16:27:24 2018 -0800 Work around macOS faccessat bug * src/fileio.c (file_accessible_directory_p): Append an extra "/" to work around macOS bug in faccessat (Bug#30350). diff --git a/src/fileio.c b/src/fileio.c index be29e60fc0..b0ef3d4e91 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2811,12 +2811,15 @@ file_accessible_directory_p (Lisp_Object file) dir = data; else { - /* Just check for trailing '/' when deciding whether to append '/'. - That's simpler than testing the two special cases "/" and "//", - and it's a safe optimization here. */ - char *buf = SAFE_ALLOCA (len + 3); + /* Just check for trailing '/' when deciding whether append '/' + before appending '.'. That's simpler than testing the two + special cases "/" and "//", and it's a safe optimization + here. After appending '.', append another '/' to work around + a macOS bug (Bug#30350). */ + static char const appended[] = "/./"; + char *buf = SAFE_ALLOCA (len + sizeof appended); memcpy (buf, data, len); - strcpy (buf + len, &"/."[data[len - 1] == '/']); + strcpy (buf + len, &appended[data[len - 1] == '/']); dir = buf; } commit 8e42b1bd3c8ba1757c150149f0d21eabd9245dcc Author: Juri Linkov Date: Mon Feb 5 23:54:27 2018 +0200 Support list-matching-lines-jump-to-current-line for context lines. * lisp/replace.el (occur--orig-line-str): Remove. (occur): Remove occur--orig-line-str. (occur-engine): Use add-face-text-property to add the face list-matching-lines-current-line-face to the current line. Use previous-single-property-change to find occur--final-pos. (occur-context-lines): New args orig-line and multi-occur-p. Find the current line in context lines and add face to it. (Bug#30281) diff --git a/lisp/replace.el b/lisp/replace.el index 0db74114b1..0efd082096 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -1389,7 +1389,6 @@ invoke `occur'." (defvar occur--region-end nil) (defvar occur--matches-threshold nil) (defvar occur--orig-line nil) -(defvar occur--orig-line-str nil) (defvar occur--final-pos nil) (defun occur (regexp &optional nlines region) @@ -1446,11 +1445,7 @@ is not modified." (and in-region-p (line-number-at-pos (min start end)))) (occur--orig-line - (line-number-at-pos (point))) - (occur--orig-line-str - (buffer-substring-no-properties - (line-beginning-position) - (line-end-position)))) + (line-number-at-pos (point)))) (save-excursion ; If no matches `occur-1' doesn't restore the point. (and in-region-p (narrow-to-region start end)) (occur-1 regexp nlines (list (current-buffer))) @@ -1550,7 +1545,7 @@ See also `multi-occur'." (let ((inhibit-read-only t) ;; Don't generate undo entries for creation of the initial contents. (buffer-undo-list t) - (occur--final-pos nil)) + (occur--final-pos nil)) (erase-buffer) (let ((count (if (stringp nlines) @@ -1618,8 +1613,8 @@ See also `multi-occur'." (global-matches 0) ;; total count of matches (coding nil) (case-fold-search case-fold) - (in-region-p (and occur--region-start occur--region-end)) - (multi-occur-p (cdr buffers))) + (in-region-p (and occur--region-start occur--region-end)) + (multi-occur-p (cdr buffers))) ;; Map over all the buffers (dolist (buf buffers) (when (buffer-live-p buf) @@ -1627,16 +1622,14 @@ See also `multi-occur'." (matches 0) ;; count of matches (curr-line ;; line count (or occur--matches-threshold 1)) - (orig-line occur--orig-line) - (orig-line-str occur--orig-line-str) - (orig-line-shown-p) + (orig-line occur--orig-line) + (orig-line-shown-p) (prev-line nil) ;; line number of prev match endpt (prev-after-lines nil) ;; context lines of prev match (matchbeg 0) (origpt nil) (begpt nil) (endpt nil) - (finalpt nil) (marker nil) (curstring "") (ret nil) @@ -1677,6 +1670,16 @@ See also `multi-occur'." ;; Count empty lines that don't use next loop (Bug#22062). (when (zerop len) (setq matches (1+ matches))) + (when (and list-matching-lines-jump-to-current-line + (not multi-occur-p)) + (when (= curr-line orig-line) + (add-face-text-property + 0 len list-matching-lines-current-line-face nil curstring) + (add-text-properties 0 len '(current-line t) curstring)) + (when (and (>= orig-line (- curr-line nlines)) + (<= orig-line (+ curr-line nlines))) + ;; Shown either here or will be shown by occur-context-lines + (setq orig-line-shown-p t))) (while (and (< start len) (string-match regexp curstring start)) (setq matches (1+ matches)) @@ -1737,26 +1740,33 @@ See also `multi-occur'." ;; The complex multi-line display style. (setq ret (occur-context-lines out-line nlines keep-props begpt - endpt curr-line prev-line - prev-after-lines prefix-face)) + endpt curr-line prev-line + prev-after-lines prefix-face + orig-line multi-occur-p)) ;; Set first elem of the returned list to `data', ;; and the second elem to `prev-after-lines'. (setq prev-after-lines (nth 1 ret)) - (nth 0 ret)))) + (nth 0 ret))) + (orig-line-str + (when (and list-matching-lines-jump-to-current-line + (null orig-line-shown-p) + (> curr-line orig-line)) + (setq orig-line-shown-p t) + (save-excursion + (goto-char (point-min)) + (forward-line (1- orig-line)) + (occur-engine-line (line-beginning-position) + (line-end-position) keep-props))))) ;; Actually insert the match display data (with-current-buffer out-buf - (when (and list-matching-lines-jump-to-current-line - (not multi-occur-p) - (not orig-line-shown-p) - (>= curr-line orig-line)) - (insert - (concat - (propertize - (format "%7d:%s" orig-line orig-line-str) - 'face list-matching-lines-current-line-face - 'mouse-face 'mode-line-highlight - 'help-echo "Current line") "\n")) - (setq orig-line-shown-p t finalpt (point))) + (when orig-line-str + (add-face-text-property + 0 (length orig-line-str) + list-matching-lines-current-line-face nil orig-line-str) + (add-text-properties 0 (length orig-line-str) + '(current-line t) orig-line-str) + (insert (car (occur-engine-add-prefix + (list orig-line-str) prefix-face)))) (insert data))) (goto-char endpt)) (if endpt @@ -1771,23 +1781,28 @@ See also `multi-occur'." (forward-line 1)) (goto-char (point-max))) (setq prev-line (1- curr-line))) - ;; Insert original line if haven't done yet. - (when (and list-matching-lines-jump-to-current-line - (not multi-occur-p) - (not orig-line-shown-p)) - (with-current-buffer out-buf - (insert - (concat - (propertize - (format "%7d:%s" orig-line orig-line-str) - 'face list-matching-lines-current-line-face - 'mouse-face 'mode-line-highlight - 'help-echo "Current line") "\n")))) ;; Flush remaining context after-lines. (when prev-after-lines (with-current-buffer out-buf (insert (apply #'concat (occur-engine-add-prefix - prev-after-lines prefix-face))))))) + prev-after-lines prefix-face))))) + (when (and list-matching-lines-jump-to-current-line + (null orig-line-shown-p)) + (setq orig-line-shown-p t) + (let ((orig-line-str + (save-excursion + (goto-char (point-min)) + (forward-line (1- orig-line)) + (occur-engine-line (line-beginning-position) + (line-end-position) keep-props)))) + (add-face-text-property + 0 (length orig-line-str) + list-matching-lines-current-line-face nil orig-line-str) + (add-text-properties 0 (length orig-line-str) + '(current-line t) orig-line-str) + (with-current-buffer out-buf + (insert (car (occur-engine-add-prefix + (list orig-line-str) prefix-face)))))))) (when (not (zerop lines)) ;; is the count zero? (setq global-lines (+ global-lines lines) global-matches (+ global-matches matches)) @@ -1818,10 +1833,13 @@ See also `multi-occur'." (add-text-properties beg end `(occur-title ,buf)) (when title-face (add-face-text-property beg end title-face)) - (goto-char (if finalpt - (setq occur--final-pos - (cl-incf finalpt (- end beg))) - (point-min)))))))))) + (goto-char (if (and list-matching-lines-jump-to-current-line + (not multi-occur-p)) + (setq occur--final-pos + (and (goto-char (point-max)) + (or (previous-single-property-change (point) 'current-line) + (point-max)))) + (point-min)))))))))) ;; Display total match count and regexp for multi-buffer. (when (and (not (zerop global-lines)) (> (length buffers) 1)) (goto-char (point-min)) @@ -1895,7 +1913,8 @@ See also `multi-occur'." ;; then concatenate them all together. (defun occur-context-lines (out-line nlines keep-props begpt endpt curr-line prev-line prev-after-lines - &optional prefix-face) + &optional prefix-face + orig-line multi-occur-p) ;; Find after- and before-context lines of the current match. (let ((before-lines (nreverse (cdr (occur-accumulate-lines @@ -1905,13 +1924,32 @@ See also `multi-occur'." (1+ nlines) keep-props endpt))) separator) + (when (and list-matching-lines-jump-to-current-line + (not multi-occur-p)) + (when (and (>= orig-line (- curr-line nlines)) + (< orig-line curr-line)) + (let ((curstring (nth (- (length before-lines) (- curr-line orig-line)) before-lines))) + (add-face-text-property + 0 (length curstring) + list-matching-lines-current-line-face nil curstring) + (add-text-properties 0 (length curstring) + '(current-line t) curstring))) + (when (and (<= orig-line (+ curr-line nlines)) + (> orig-line curr-line)) + (let ((curstring (nth (- orig-line curr-line 1) after-lines))) + (add-face-text-property + 0 (length curstring) + list-matching-lines-current-line-face nil curstring) + (add-text-properties 0 (length curstring) + '(current-line t) curstring)))) + ;; Combine after-lines of the previous match ;; with before-lines of the current match. (when prev-after-lines ;; Don't overlap prev after-lines with current before-lines. (if (>= (+ prev-line (length prev-after-lines)) - (- curr-line (length before-lines))) + (- curr-line (length before-lines))) (setq prev-after-lines (butlast prev-after-lines (- (length prev-after-lines) commit a0c7157a16481b0523ad20cda9115f9435188f73 Merge: c24c5dc4a4 c787a49682 Author: Glenn Morris Date: Mon Feb 5 07:50:22 2018 -0800 Merge from origin/emacs-26 c787a49 (origin/emacs-26) * lisp/vc/vc-git.el (vc-git-print-log): Res... b654791 * doc/emacs/misc.texi (Interactive Shell): Refer to node "Min... f1102d2 Yet another round of fixing the Emacs manual 76b5a68 * etc/NEWS: Expunge the solecism "allow(s)" + infinitive b4ff8cc Two minor fixes in Antinews aafcd12 * etc/NEWS: Rename image-dired-thumb-job-limit a893924 * lisp/simple.el (async-shell-command, shell-command): Fix gr... 699081f Fix deferred display of async shell-command buffers d2d5e54 Mention remote file name completion in Emacs manual f589f5a Yest another round of manual copyedits 1ed4089 Update xdisp.c commentary e23de39 Fix Bug#30324 e1a9dc0 Recognize Org as builtin package (bug#30310) Conflicts: etc/NEWS commit c24c5dc4a4cc18e7f1ec949efcfe1d4bae541d02 Author: Michael Albinus Date: Mon Feb 5 14:02:49 2018 +0100 Fix inconsistency expanding "//" in Tramp * doc/misc/tramp.texi (File name completion): Adapt example expanding "//". * lisp/net/tramp.el (tramp-handle-substitute-in-file-name): "//" shall expand the localname only, even when on top of the local part. * test/lisp/net/tramp-tests.el (tramp-test04-substitute-in-file-name): Adapt test. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 235627cc0f..ae544b0871 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2509,7 +2509,7 @@ Example: @print{} @trampfn{ssh,melancholia,/etc} @kbd{C-x C-f @trampfn{ssh,melancholia,//etc} @key{TAB}} - @print{} /etc + @print{} @trampfn{ssh,melancholia,/etc} @kbd{C-x C-f @trampfn{ssh,melancholia,/usr/local/bin///etc} @key{TAB}} @print{} /etc diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 09abd48226..b2e20000d3 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3554,17 +3554,19 @@ support symbolic links." ;; First, we must replace environment variables. (setq filename (tramp-replace-environment-variables filename)) (with-parsed-tramp-file-name filename nil - ;; Ignore in LOCALNAME everything before "//" or "/~". - (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname)) - (setq filename - (concat (file-remote-p filename) - (replace-match "\\1" nil nil localname))) - ;; "/m:h:~" does not work for completion. We use "/m:h:~/". - (when (string-match "~$" filename) - (setq filename (concat filename "/")))) ;; We do not want to replace environment variables, again. (let (process-environment) - (tramp-run-real-handler 'substitute-in-file-name (list filename)))))) + ;; Ignore in LOCALNAME everything before "//" or "/~". + (when (stringp localname) + (if (string-match "//\\(/\\|~\\)" localname) + (setq filename (substitute-in-file-name localname)) + (setq filename + (concat (file-remote-p filename) + (substitute-in-file-name localname)))))) + ;; "/m:h:~" does not work for completion. We use "/m:h:~/". + (if (string-match "~$" filename) + (concat filename "/") + filename)))) (defun tramp-handle-set-visited-file-modtime (&optional time-list) "Like `set-visited-file-modtime' for Tramp files." diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 7a12d1468b..422e71df7c 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -1712,39 +1712,59 @@ handled properly. BODY shall not contain a timeout." (ert-deftest tramp-test04-substitute-in-file-name () "Check `substitute-in-file-name'." - (should (string-equal (substitute-in-file-name "/method:host://foo") "/foo")) + (should (string-equal (substitute-in-file-name "/method:host:///foo") "/foo")) (should (string-equal - (substitute-in-file-name "/method:host:/path//foo") "/method:host:/foo")) + (substitute-in-file-name "/method:host://foo") "/method:host:/foo")) (should (string-equal (substitute-in-file-name "/method:host:/path///foo") "/foo")) + (should + (string-equal + (substitute-in-file-name "/method:host:/path//foo") "/method:host:/foo")) ;; Quoting local part. (should (string-equal - (substitute-in-file-name "/method:host:/://foo") "/method:host:/://foo")) + (substitute-in-file-name "/method:host:/:///foo") "/method:host:/:///foo")) (should (string-equal - (substitute-in-file-name "/method:host:/:/path//foo") - "/method:host:/:/path//foo")) + (substitute-in-file-name "/method:host:/://foo") "/method:host:/://foo")) (should (string-equal (substitute-in-file-name "/method:host:/:/path///foo") "/method:host:/:/path///foo")) + (should + (string-equal + (substitute-in-file-name "/method:host:/:/path//foo") + "/method:host:/:/path//foo")) + (should + (string-equal (substitute-in-file-name "/method:host://~foo") "/~foo")) (should (string-equal - (substitute-in-file-name "/method:host:/path/~/foo") "/method:host:~/foo")) + (substitute-in-file-name "/method:host:/~foo") "/method:host:/~foo")) (should - (string-equal (substitute-in-file-name "/method:host:/path//~/foo") "~/foo")) + (string-equal (substitute-in-file-name "/method:host:/path//~foo") "/~foo")) + ;; (substitute-in-file-name "/path/~foo") expands only to "/~foo"", + ;; if $LOGNAME or $USER is "foo". Otherwise, it doesn't expand. + (should + (string-equal + (substitute-in-file-name + "/method:host:/path/~foo") "/method:host:/path/~foo")) ;; Quoting local part. (should (string-equal - (substitute-in-file-name "/method:host:/:/path/~/foo") - "/method:host:/:/path/~/foo")) + (substitute-in-file-name "/method:host:/://~foo") "/method:host:/://~foo")) + (should + (string-equal + (substitute-in-file-name "/method:host:/:/~foo") "/method:host:/:/~foo")) + (should + (string-equal + (substitute-in-file-name + "/method:host:/:/path//~foo") "/method:host:/:/path//~foo")) (should (string-equal - (substitute-in-file-name "/method:host:/:/path//~/foo") - "/method:host:/:/path//~/foo")) + (substitute-in-file-name + "/method:host:/:/path/~foo") "/method:host:/:/path/~foo")) (let (process-environment) (should commit c787a4968273027960a20ced6d63bae0d1ffa87e (refs/remotes/origin/emacs-26) Author: Juri Linkov Date: Sun Feb 4 23:58:37 2018 +0200 * lisp/vc/vc-git.el (vc-git-print-log): Restrict file scope to a single file when vc-git-print-log-follow is non-nil (bug#19045). (vc-git-print-log-follow): Doc fix. * etc/NEWS: Mention 'vc-git-print-log-follow'. diff --git a/etc/NEWS b/etc/NEWS index 02385d2b70..00ff9cda8e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1169,6 +1169,9 @@ branch-related commands on a keymap bound to 'B'. *** 'vc-region-history' is now bound to 'C-x v h', replacing the older 'vc-insert-headers' binding. +*** New user option 'vc-git-print-log-follow' to follow renames in Git logs +for a single file. + ** CC mode --- diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 3bf837caaa..40aa0b2601 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -994,7 +994,7 @@ This prompts for a branch to merge from." (autoload 'vc-setup-buffer "vc-dispatcher") (defcustom vc-git-print-log-follow nil - "If true, follow renames in Git logs for files." + "If true, follow renames in Git logs for a single file." :type 'boolean :version "26.1") @@ -1019,8 +1019,10 @@ If LIMIT is non-nil, show no more than this many entries." (append '("log" "--no-color") (when (and vc-git-print-log-follow - (not (cl-some #'file-directory-p files))) - ;; "--follow" on directories is broken + (null (cdr files)) + (car files) + (not (file-directory-p (car files)))) + ;; "--follow" on directories or multiple files is broken ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=8756 ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=16422 (list "--follow")) commit b654791064b43a94150ed6c56053162a6b2ea037 Author: Michael Albinus Date: Sun Feb 4 22:56:34 2018 +0100 * doc/emacs/misc.texi (Interactive Shell): Refer to node "Minibuffer File" for hints how to type remote file names effectively. diff --git a/doc/emacs/misc.texi b/doc/emacs/misc.texi index 3300ed67c6..1fb47c3c68 100644 --- a/doc/emacs/misc.texi +++ b/doc/emacs/misc.texi @@ -791,7 +791,8 @@ the variable @code{explicit-shell-file-name}. If this is @code{nil} exists. Otherwise, it usually uses the variable @code{shell-file-name} (@pxref{Single Shell}); but if the default directory is remote (@pxref{Remote Files}), it prompts you for the -shell file name. +shell file name. @xref{Minibuffer File}, for hints how to type remote +file names effectively. Emacs sends the new shell the contents of the file @file{~/.emacs_@var{shellname}} as input, if it exists, where commit f1102d2de483eac412430279ede23872d575ddf6 Author: Eli Zaretskii Date: Sun Feb 4 22:15:05 2018 +0200 Yet another round of fixing the Emacs manual * doc/emacs/cmdargs.texi (Action Arguments): Rearrange text describing what happens when Emacs is invoked with several file arguments. Suggested by Grant Rettke in emacs-manual-bugs@gnu.org. * doc/emacs/xresources.texi (GTK styles): * doc/emacs/mini.texi (Passwords): * doc/emacs/frames.texi (Scroll Bars): Use "cannot" instead of "can not". * doc/emacs/macos.texi (Mac / GNUstep Basics): Clarify the effect of ns-right-alternate-modifier when its value is 'none'. Suggested by Wanderson Ferreira in emacs-manual-bugs@gnu.org. * doc/emacs/calendar.texi (Importing Diary, Appointments): Now sub-sections of Diary. * doc/emacs/emacs.texi (Top): * doc/emacs/calendar.texi (Diary): Adjust menus to the above change. Suggested by Isaac Carter in emacs-manual-bugs@gnu.org. * doc/emacs/anti.texi (Antinews): Fix grammar. diff --git a/doc/emacs/anti.texi b/doc/emacs/anti.texi index 8cef1be4e1..d4b68a2fac 100644 --- a/doc/emacs/anti.texi +++ b/doc/emacs/anti.texi @@ -95,7 +95,7 @@ happen. The variables @code{attempt-stack-overflow-recovery} and @item The @code{list-timers} command was removed, as we decided timers are -no user-level feature, and therefore users should not be allowed to +not a user-level feature, and therefore users should not be allowed to mess with them. Ask an Emacs Lisp guru near you for help if you have a runaway timer in your session. (Of course, as you move back in time, such runaway timers will become less and less frequent, and diff --git a/doc/emacs/calendar.texi b/doc/emacs/calendar.texi index 9145a725e1..ed1f53fa70 100644 --- a/doc/emacs/calendar.texi +++ b/doc/emacs/calendar.texi @@ -41,8 +41,6 @@ For more advanced topics, * Lunar Phases:: Displaying phases of the moon. * Other Calendars:: Converting dates to other calendar systems. * Diary:: Displaying events from your diary. -* Appointments:: Reminders when it's time to do something. -* Importing Diary:: Converting diary events to/from other formats. * Daylight Saving:: How to specify when daylight saving time is active. * Time Intervals:: Keeping track of time intervals. @ifnottex @@ -936,6 +934,8 @@ entries. * Date Formats:: Various ways you can specify dates. * Adding to Diary:: Commands to create diary entries. * Special Diary Entries:: Anniversaries, blocks of dates, cyclic entries, etc. +* Appointments:: Reminders when it's time to do something. +* Importing Diary:: Converting diary events to/from other formats. @end menu @node Format of Diary File @@ -1363,7 +1363,7 @@ can perform arbitrary computations to determine when they apply. @end ifnottex @node Appointments -@section Appointments +@subsection Appointments @cindex appointment notification @vindex appt-display-format @@ -1450,7 +1450,7 @@ list without affecting your diary file. You delete entries from the appointment list with @kbd{M-x appt-delete}. @node Importing Diary -@section Importing and Exporting Diary Entries +@subsection Importing and Exporting Diary Entries You can transfer diary entries between Emacs diary files and a variety of other formats. diff --git a/doc/emacs/cmdargs.texi b/doc/emacs/cmdargs.texi index 1dbc1dc735..63db2ac765 100644 --- a/doc/emacs/cmdargs.texi +++ b/doc/emacs/cmdargs.texi @@ -101,13 +101,13 @@ displayed file is the last one specified on the command line; the other files are visited but their buffers are not shown. If the startup buffer is disabled (@pxref{Entering Emacs}), then -@var{file} is visited in a single window if one file argument was -supplied; with two file arguments, Emacs displays the files in two -different windows; with more than two file argument, Emacs displays -the last file specified in one window, plus a Buffer Menu in a -different window (@pxref{Several Buffers}). To inhibit using the -Buffer Menu for this, change the variable -@code{inhibit-startup-buffer-menu} to @code{t}. +starting Emacs with one file argument displays the buffer visiting +@var{file} in a single window. With two file arguments, Emacs +displays the files in two different windows. With more than two file +argument, Emacs displays the last file specified in one window, plus +another window with a Buffer Menu showing all the other files +(@pxref{Several Buffers}). To inhibit using the Buffer Menu for this, +change the variable @code{inhibit-startup-buffer-menu} to @code{t}. @item +@var{linenum} @var{file} @opindex +@var{linenum} diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi index 0051868fee..474c4e96e2 100644 --- a/doc/emacs/emacs.texi +++ b/doc/emacs/emacs.texi @@ -954,8 +954,6 @@ The Calendar and the Diary * Lunar Phases:: Displaying phases of the moon. * Other Calendars:: Converting dates to other calendar systems. * Diary:: Displaying events from your diary. -* Appointments:: Reminders when it's time to do something. -* Importing Diary:: Converting diary events to/from other formats. * Daylight Saving:: How to specify when daylight saving time is active. * Time Intervals:: Keeping track of time intervals. @ifnottex @@ -983,6 +981,8 @@ The Diary * Date Formats:: Various ways you can specify dates. * Adding to Diary:: Commands to create diary entries. * Special Diary Entries:: Anniversaries, blocks of dates, cyclic entries, etc. +* Appointments:: Reminders when it's time to do something. +* Importing Diary:: Converting diary events to/from other formats. @ifnottex More advanced features of the Calendar and Diary diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi index 7c1d36c720..afdfa6c39c 100644 --- a/doc/emacs/frames.texi +++ b/doc/emacs/frames.texi @@ -994,7 +994,7 @@ variable @code{scroll-bar-adjust-thumb-portion} to control when the end of the buffer is visible. If its value is non-@code{nil}, the scroll bar can be dragged downwards even if the end of the buffer is shown; if @code{nil}, the thumb will be at the -bottom when the end of the buffer is shown. You can not over-scroll +bottom when the end of the buffer is shown. You cannot over-scroll when the entire buffer is visible. @cindex scroll-bar face diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi index cf4e48bacb..dbde2c8f82 100644 --- a/doc/emacs/macos.texi +++ b/doc/emacs/macos.texi @@ -49,7 +49,8 @@ default). A value of @code{control}, @code{meta}, @code{alt}, @code{super}, or @code{hyper} makes them behave like the corresponding modifier keys; a value to @code{left} means be the same key as @code{ns-alternate-modifier}; a value of @code{none} tells Emacs to -ignore them. +ignore them, in which case you get the default behavior of macOS +accentuation system from the right option key. @kbd{S-mouse-1} adjusts the region to the click position, just like @kbd{mouse-3} (@code{mouse-save-then-kill}); it does not pop diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index 35cffc1db9..de16c44720 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -773,10 +773,10 @@ you type the required password, press @key{RET} to submit it. To prevent others from seeing your password, every character you type is displayed as a dot (@samp{.}) instead of its usual form. - Most of the features and commands associated with the minibuffer can -@emph{not} be used when entering a password. There is no history or -completion, and you cannot change windows or perform any other action -with Emacs until you have submitted the password. + Most of the features and commands associated with the minibuffer +@emph{cannot} be used when entering a password. There is no history +or completion, and you cannot change windows or perform any other +action with Emacs until you have submitted the password. While you are typing the password, you may press @key{DEL} to delete backwards, removing the last character entered. @kbd{C-u} deletes diff --git a/doc/emacs/xresources.texi b/doc/emacs/xresources.texi index f192c0d4c9..d58c6b905e 100644 --- a/doc/emacs/xresources.texi +++ b/doc/emacs/xresources.texi @@ -764,7 +764,7 @@ This is the state for data that has been selected by the user. It can be selected text or items selected in a list. This state is not used in Emacs. @item INSENSITIVE -This is the state for widgets that are visible, but they can not be +This is the state for widgets that are visible, but they cannot be manipulated in the usual way---for example, buttons that can't be pressed, and disabled menu items. To display disabled menu items in yellow, use @code{fg[INSENSITIVE] = "yellow"}. commit 8fbf28536ee1169f59206523e2af050916befbf6 Author: Philipp Stephani Date: Wed Mar 30 19:22:56 2016 +0200 Fix handling of modifier keys on macOS * src/nsterm.m (keyDown:): Distinguish between shift-like and control-like modifier keys. Allow treating ⌘ as shift-like modifier (e.g. for the Gujarati – QUERTY input method, where ⌘ switches to QUERTY.) * lisp/cus-start.el (standard): Change nil to none for ns-command-modifier; update description. * etc/NEWS: Add NEWS entry. diff --git a/etc/NEWS b/etc/NEWS index afd0fba5a1..8fed15af5b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -286,6 +286,9 @@ loading messages if requested, and protects against recursive loads. ** Battery status is now supported in all Cygwin builds. Previously it was supported only in the Cygwin-w32 build. +** Emacs now handles key combinations involving the macOS "command" +and "option" modifier keys more correctly. + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/lisp/cus-start.el b/lisp/cus-start.el index 4529fa1ac9..9ba1e105a1 100644 --- a/lisp/cus-start.el +++ b/lisp/cus-start.el @@ -413,6 +413,10 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of ;; msdos.c (dos-unsupported-char-glyph display integer) ;; nsterm.m + ;; + ;; FIXME: Why does ⌃ use nil instead of none? Also the + ;; description is confusing; setting it to nil disables ⌃ + ;; entirely. (ns-control-modifier ns (choice (const :tag "No modifier" nil) @@ -429,13 +433,13 @@ Leaving \"Default\" unchecked is equivalent with specifying a default of (const super)) "24.1") (ns-command-modifier ns - (choice (const :tag "No modifier" nil) + (choice (const :tag "No modifier (work as layout switch)" none) (const control) (const meta) (const alt) (const hyper) (const super)) "23.1") (ns-right-command-modifier ns - (choice (const :tag "No modifier (work as command)" none) + (choice (const :tag "No modifier (work as layout switch)" none) (const :tag "Use the value of ns-command-modifier" left) (const control) (const meta) diff --git a/src/nsterm.m b/src/nsterm.m index 4b81ad2a6c..b7f5a32c09 100644 --- a/src/nsterm.m +++ b/src/nsterm.m @@ -37,6 +37,7 @@ Updated by Christian Limpach (chris@nice.ch) #include #include #include +#include #include #include @@ -5944,7 +5945,6 @@ - (BOOL)fulfillService: (NSString *)name withArg: (NSString *)arg @end /* EmacsApp */ - /* ========================================================================== EmacsView implementation @@ -6050,7 +6050,6 @@ - (void)keyDown: (NSEvent *)theEvent int code; unsigned fnKeysym = 0; static NSMutableArray *nsEvArray; - int left_is_none; unsigned int flags = [theEvent modifierFlags]; NSTRACE ("[EmacsView keyDown:]"); @@ -6092,10 +6091,8 @@ most recently updated (I guess), which is not the correct one. */ if (!processingCompose) { - /* When using screen sharing, no left or right information is sent, - so use Left key in those cases. */ - int is_left_key, is_right_key; - + /* FIXME: What should happen for key sequences with more than + one character? */ code = ([[theEvent charactersIgnoringModifiers] length] == 0) ? 0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0]; @@ -6142,131 +6139,47 @@ flag set (this is probably a bug in the OS). if (flags & NSEventModifierFlagShift) emacs_event->modifiers |= shift_modifier; - is_right_key = (flags & NSRightCommandKeyMask) == NSRightCommandKeyMask; - is_left_key = (flags & NSLeftCommandKeyMask) == NSLeftCommandKeyMask - || (! is_right_key && (flags & NSEventModifierFlagCommand) == NSEventModifierFlagCommand); - - if (is_right_key) - emacs_event->modifiers |= parse_solitary_modifier - (EQ (ns_right_command_modifier, Qleft) - ? ns_command_modifier - : ns_right_command_modifier); - - if (is_left_key) - { - emacs_event->modifiers |= parse_solitary_modifier - (ns_command_modifier); - - /* if super (default), take input manager's word so things like - dvorak / qwerty layout work */ - if (EQ (ns_command_modifier, Qsuper) - && !fnKeysym - && [[theEvent characters] length] != 0) - { - /* XXX: the code we get will be unshifted, so if we have - a shift modifier, must convert ourselves */ - if (!(flags & NSEventModifierFlagShift)) - code = [[theEvent characters] characterAtIndex: 0]; -#if 0 - /* this is ugly and also requires linking w/Carbon framework - (for LMGetKbdType) so for now leave this rare (?) case - undealt with.. in future look into CGEvent methods */ - else - { - long smv = GetScriptManagerVariable (smKeyScript); - Handle uchrHandle = GetResource - ('uchr', GetScriptVariable (smv, smScriptKeys)); - UInt32 dummy = 0; - UCKeyTranslate ((UCKeyboardLayout *) *uchrHandle, - [[theEvent characters] characterAtIndex: 0], - kUCKeyActionDisplay, - (flags & ~NSEventModifierFlagCommand) >> 8, - LMGetKbdType (), kUCKeyTranslateNoDeadKeysMask, - &dummy, 1, &dummy, &code); - code &= 0xFF; - } -#endif - } - } - - is_right_key = (flags & NSRightControlKeyMask) == NSRightControlKeyMask; - is_left_key = (flags & NSLeftControlKeyMask) == NSLeftControlKeyMask - || (! is_right_key && (flags & NSEventModifierFlagControl) == NSEventModifierFlagControl); - - if (is_right_key) - emacs_event->modifiers |= parse_solitary_modifier - (EQ (ns_right_control_modifier, Qleft) - ? ns_control_modifier - : ns_right_control_modifier); - - if (is_left_key) - emacs_event->modifiers |= parse_solitary_modifier - (ns_control_modifier); - - if (flags & NS_FUNCTION_KEY_MASK && !fnKeysym) - emacs_event->modifiers |= - parse_solitary_modifier (ns_function_modifier); - - left_is_none = NILP (ns_alternate_modifier) - || EQ (ns_alternate_modifier, Qnone); - - is_right_key = (flags & NSRightAlternateKeyMask) - == NSRightAlternateKeyMask; - is_left_key = (flags & NSLeftAlternateKeyMask) == NSLeftAlternateKeyMask - || (! is_right_key - && (flags & NSEventModifierFlagOption) == NSEventModifierFlagOption); - - if (is_right_key) - { - if ((NILP (ns_right_alternate_modifier) - || EQ (ns_right_alternate_modifier, Qnone) - || (EQ (ns_right_alternate_modifier, Qleft) && left_is_none)) - && !fnKeysym) - { /* accept pre-interp alt comb */ - if ([[theEvent characters] length] > 0) - code = [[theEvent characters] characterAtIndex: 0]; - /*HACK: clear lone shift modifier to stop next if from firing */ - if (emacs_event->modifiers == shift_modifier) - emacs_event->modifiers = 0; - } - else - emacs_event->modifiers |= parse_solitary_modifier - (EQ (ns_right_alternate_modifier, Qleft) - ? ns_alternate_modifier - : ns_right_alternate_modifier); - } - - if (is_left_key) /* default = meta */ - { - if (left_is_none && !fnKeysym) - { /* accept pre-interp alt comb */ - if ([[theEvent characters] length] > 0) - code = [[theEvent characters] characterAtIndex: 0]; - /*HACK: clear lone shift modifier to stop next if from firing */ - if (emacs_event->modifiers == shift_modifier) - emacs_event->modifiers = 0; - } - else - emacs_event->modifiers |= - parse_solitary_modifier (ns_alternate_modifier); - } - - if (NS_KEYLOG) - fprintf (stderr, "keyDown: code =%x\tfnKey =%x\tflags = %x\tmods = %x\n", - (unsigned) code, fnKeysym, flags, emacs_event->modifiers); - - /* if it was a function key or had modifiers, pass it directly to emacs */ + /* The ⌘ and ⌥ modifiers can be either shift-like (for alternate + character input) or control-like (as command prefix). If we + have only shift-like modifiers, then we should use the + translated characters (returned by the characters method); if + we have only control-like modifiers, then we should use the + untranslated characters (returned by the + charactersIgnoringModifiers method). An annoyance happens if + we have both shift-like and control-like modifiers because + the NSEvent API doesn’t let us ignore only some modifiers. + Therefore we ignore all shift-like modifiers in that + case. */ + + /* EV_MODIFIERS2 uses parse_solitary_modifier on all known + modifier keys, which returns 0 for shift-like modifiers. + Therefore its return value is the set of control-like + modifiers. */ + unsigned int control_modifiers = EV_MODIFIERS2 (flags); + emacs_event->modifiers |= control_modifiers; + + if (NS_KEYLOG) + fprintf (stderr, "keyDown: code =%x\tfnKey =%x\tflags = %x\tmods = %x\n", + code, fnKeysym, flags, emacs_event->modifiers); + + /* If it was a function key or had control-like modifiers, pass + it directly to Emacs. */ if (fnKeysym || (emacs_event->modifiers && (emacs_event->modifiers != shift_modifier) && [[theEvent charactersIgnoringModifiers] length] > 0)) /*[[theEvent characters] length] */ { emacs_event->kind = NON_ASCII_KEYSTROKE_EVENT; + /* FIXME: What are the next four lines supposed to do? */ if (code < 0x20) code |= (1<<28)|(3<<16); else if (code == 0x7f) code |= (1<<28)|(3<<16); else if (!fnKeysym) + /* FIXME: This seems wrong, characters in the range + [0x80, 0xFF] are not ASCII characters. Can’t we just + use MULTIBYTE_CHAR_KEYSTROKE_EVENT here for all kinds + of characters? */ emacs_event->kind = code > 0xFF ? MULTIBYTE_CHAR_KEYSTROKE_EVENT : ASCII_KEYSTROKE_EVENT; @@ -6277,11 +6190,32 @@ flag set (this is probably a bug in the OS). } } + /* If we get here, a non-function key without control-like modifiers + was hit. Use interpretKeyEvents, which in turn will call + insertText; see + https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/HandlingKeyEvents/HandlingKeyEvents.html. */ if (NS_KEYLOG && !processingCompose) fprintf (stderr, "keyDown: Begin compose sequence.\n"); + /* FIXME: interpretKeyEvents doesn’t seem to send insertText if ⌘ is + used as shift-like modifier, at least on El Capitan. Mask it + out. This shouldn’t be needed though; we should figure out what + the correct way of handling ⌘ is. */ + if ([theEvent modifierFlags] & NSEventModifierFlagCommand) + theEvent = [NSEvent keyEventWithType:[theEvent type] + location:[theEvent locationInWindow] + modifierFlags:[theEvent modifierFlags] & ~NSEventModifierFlagCommand + timestamp:[theEvent timestamp] + windowNumber:[theEvent windowNumber] + context:nil + characters:[theEvent characters] + charactersIgnoringModifiers:[theEvent charactersIgnoringModifiers] + isARepeat:[theEvent isARepeat] + keyCode:[theEvent keyCode]]; + processingCompose = YES; + /* FIXME: Use [NSArray arrayWithObject:theEvent]? */ [nsEvArray addObject: theEvent]; [self interpretKeyEvents: nsEvArray]; [nsEvArray removeObject: theEvent]; commit 76b5a687d07b93dc7e292b72da6ad82001ff1fe3 Author: Alan Mackenzie Date: Sun Feb 4 17:18:39 2018 +0000 * etc/NEWS: Expunge the solecism "allow(s)" + infinitive diff --git a/etc/NEWS b/etc/NEWS index 5b3e445476..02385d2b70 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -264,9 +264,9 @@ to non-nil moves point to the beginning of the region. +++ ** New user option 'mouse-drag-and-drop-region'. -This option allows to drag the entire region of text to another place -or another buffer. Its behavior is customizable via the new options -'mouse-drag-and-drop-region-cut-when-buffers-differ', +This option allows you to drag the entire region of text to another +place or another buffer. Its behavior is customizable via the new +options 'mouse-drag-and-drop-region-cut-when-buffers-differ', 'mouse-drag-and-drop-region-show-tooltip', and 'mouse-drag-and-drop-region-show-cursor'. @@ -481,8 +481,8 @@ commands. libraries: 'find-library-other-window' and 'find-library-other-frame'. +++ -** The new variable 'display-raw-bytes-as-hex' allows to change the -display of raw bytes from octal to hex. +** The new variable 'display-raw-bytes-as-hex' allows you to change +the display of raw bytes from octal to hex. +++ ** You can now provide explicit field numbers in format specifiers. @@ -855,8 +855,8 @@ breakpoint (e.g. with "f" and "o") by customizing the new option +++ *** New customizable option 'edebug-max-depth'. -This allows to enlarge the maximum recursion depth when instrumenting -code. +This allows you to enlarge the maximum recursion depth when +instrumenting code. ** Eshell @@ -1056,8 +1056,8 @@ A valid remote file name starts with "/method:host:" or "/-::" is the shortest remote file name then. +++ -*** The command 'tramp-change-syntax' allows to choose an alternative -remote file name syntax. +*** The command 'tramp-change-syntax' allows you to choose an +alternative remote file name syntax. +++ *** New connection method "sg", which supports editing files under a @@ -1067,7 +1067,7 @@ different group ID. *** New connection method "doas" for OpenBSD hosts. +++ -*** New connection method "gdrive", which allows to access Google +*** New connection method "gdrive", which allows access to Google Drive onsite repositories. +++ @@ -1868,10 +1868,11 @@ focus via the mouse. frame. +++ -**** 'width' and 'height' allow to specify pixel values and ratios now. +**** 'width' and 'height' now allow the specification of pixel values +and ratios. +++ -**** 'left' and 'top' allow to specify ratios now. +**** 'left' and 'top' now allow the specification of ratios. +++ **** 'keep-ratio' preserves size and position of child frames when their @@ -1892,7 +1893,7 @@ handle fitting a frame to its buffer individually. +++ **** 'drag-internal-border', 'drag-with-header-line', 'drag-with-mode-line', 'snap-width', 'top-visible' and 'bottom-visible' -allow to drag and resize frames with the mouse. +allow dragging and resizing frames with the mouse. +++ **** 'minibuffer' is now set to the default minibuffer window when @@ -1939,8 +1940,9 @@ like a single live window - is now official. For details consult the section "(elisp) Atomic Windows" in the ELisp manual. +++ -*** New 'display-buffer' alist entry 'window-parameters' allows to -assign window parameters to the window used for displaying the buffer. +*** New 'display-buffer' alist entry 'window-parameters' allows the +assignment of window parameters to the window used for displaying the +buffer. +++ *** New function 'display-buffer-reuse-mode-window' is an action function @@ -1960,7 +1962,7 @@ its window gets deleted by 'delete-other-windows'. +++ *** New window parameters 'mode-line-format' and 'header-line-format' -allow to override the buffer-local formats for this window. +allow the buffer-local formats for this window to be overridden. +++ *** New command 'window-swap-states' swaps the states of two live commit d2630e456923d2bd70fdd59267fe6e3d8eeb69ca Author: Michael Albinus Date: Sun Feb 4 13:25:10 2018 +0100 Make tramp-archive fit for older Emacsen * lisp/net/tramp-archive.el (tramp-archive-enabled) (tramp-archive-file-name-handler-alist) (tramp-archive-file-name-handler): Adapt docstring. (tramp-register-archive-file-name-handler): Remove it from `after-init-hook' when unloading. (tramp-archive-gvfs-host): New defsubst. (tramp-archive-dissect-file-name): Use it. * lisp/net/tramp-cmds.el (tramp-cleanup-all-connections): Check that `tramp-archive-enabled' is bound. * test/lisp/net/tramp-archive-tests.el (tramp-archive-test42-auto-load): Check also that tramp-archive is not loaded when Tramp is loaded. (tramp-archive-test42-delay-load): Adapt test messages. diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el index ac1c4e1448..5f28756d75 100644 --- a/lisp/net/tramp-archive.el +++ b/lisp/net/tramp-archive.el @@ -116,8 +116,9 @@ ;; would load Tramp. So we make a cheaper check. ;;;###autoload (defvar tramp-archive-enabled (featurep 'dbusbind) - "Non-nil when GVFS is available.") + "Non-nil when file archive support is available.") +;; After loading tramp-gvfs.el, we know it better. (setq tramp-archive-enabled tramp-gvfs-enabled) ;; @@ -175,6 +176,9 @@ It must be supported by libarchive(3).") "\\)" ;; \1 "\\(" "/" ".*" "\\)" "\\'"))) ;; \2 +;; In older Emacsen (prior 27.1), `tramp-archive-autoload-file-name-regexp' +;; is not autoloaded. So we cannot expect it to be known in +;; tramp-loaddefs.el. But it exists, when tramp-archive.el is loaded. ;;;###tramp-autoload (defconst tramp-archive-file-name-regexp (ignore-errors (tramp-archive-autoload-file-name-regexp)) @@ -266,7 +270,7 @@ It must be supported by libarchive(3).") (vc-registered . ignore) (verify-visited-file-modtime . tramp-handle-verify-visited-file-modtime) (write-region . tramp-archive-handle-not-implemented)) - "Alist of handler functions for GVFS archive method. + "Alist of handler functions for file archive method. Operations not mentioned here will be handled by the default Emacs primitives.") (defsubst tramp-archive-file-name-for-operation (operation &rest args) @@ -288,7 +292,7 @@ pass to the OPERATION." ;;;###tramp-autoload (defun tramp-archive-file-name-handler (operation &rest args) - "Invoke the GVFS archive related OPERATION. + "Invoke the file archive related OPERATION. First arg specifies the OPERATION, second arg is a list of arguments to pass to the OPERATION." (let* ((filename (apply 'tramp-archive-file-name-for-operation @@ -323,8 +327,16 @@ pass to the OPERATION." (put 'tramp-archive-file-name-handler 'safe-magic t)))) ;;;###autoload -(add-hook 'after-init-hook 'tramp-register-archive-file-name-handler) - +(progn + (add-hook 'after-init-hook 'tramp-register-archive-file-name-handler) + (add-hook + 'tramp-archive-unload-hook + (lambda () + (remove-hook + 'after-init-hook 'tramp-register-archive-file-name-handler)))) + +;; In older Emacsen (prior 27.1), the autoload above does not exist. +;; So we call it again; it doesn't hurt. (tramp-register-archive-file-name-handler) ;; Mark `operations' the handler is responsible for. @@ -343,12 +355,6 @@ pass to the OPERATION." (remove-hook 'url-handler-mode-hook 'tramp-register-file-name-handlers))))) -;; Debug. -;(trace-function-background 'tramp-archive-file-name-handler) -;(trace-function-background 'tramp-gvfs-file-name-handler) -;(trace-function-background 'tramp-file-name-archive) -;(trace-function-background 'tramp-archive-dissect-file-name) - ;; File name conversions. @@ -374,6 +380,10 @@ The hash key is the archive name. The value is a cons of the used `tramp-file-name' structure for tramp-gvfs, and the file name of a local copy, if any.") +(defsubst tramp-archive-gvfs-host (archive) + "Return host name of ARCHIVE as used in GVFS for mounting" + (url-hexify-string (tramp-gvfs-url-file-name archive))) + (defun tramp-archive-dissect-file-name (name) "Return a `tramp-file-name' structure. The structure consists of the `tramp-archive-method' method, the @@ -397,8 +407,7 @@ name is kept in slot `hop'" (let ((archive (tramp-make-tramp-file-name (tramp-archive-dissect-file-name archive) nil 'noarchive))) - (setf (tramp-file-name-host vec) - (url-hexify-string (tramp-gvfs-url-file-name archive)))) + (setf (tramp-file-name-host vec) (tramp-archive-gvfs-host archive))) (puthash archive (list vec) tramp-archive-hash)) ;; http://... @@ -411,15 +420,13 @@ name is kept in slot `hop'" (url-type (url-generic-parse-url archive)) url-tramp-protocols)) (archive (url-tramp-convert-url-to-tramp archive))) - (setf (tramp-file-name-host vec) - (url-hexify-string (tramp-gvfs-url-file-name archive)))) + (setf (tramp-file-name-host vec) (tramp-archive-gvfs-host archive))) (puthash archive (list vec) tramp-archive-hash)) ;; GVFS supported schemes. ((or (tramp-gvfs-file-name-p archive) (not (file-remote-p archive))) - (setf (tramp-file-name-host vec) - (url-hexify-string (tramp-gvfs-url-file-name archive))) + (setf (tramp-file-name-host vec) (tramp-archive-gvfs-host archive)) (puthash archive (list vec) tramp-archive-hash)) ;; Anything else. Here we call `file-local-copy', which we @@ -428,8 +435,7 @@ name is kept in slot `hop'" (inhibit-file-name-handlers (cons 'jka-compr-handler inhibit-file-name-handlers)) (copy (file-local-copy archive))) - (setf (tramp-file-name-host vec) - (url-hexify-string (tramp-gvfs-url-file-name copy))) + (setf (tramp-file-name-host vec) (tramp-archive-gvfs-host copy)) (puthash archive (cons vec copy) tramp-archive-hash)))) ;; So far, `vec' handles just the mount point. Add `localname', diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index ab3768a91f..cbb9cd3700 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -144,7 +144,8 @@ This includes password cache, file cache, connection cache, buffers." (clrhash tramp-cache-data) ;; Cleanup local copies of archives. - (tramp-archive-cleanup-hash) + (when (bound-and-true-p tramp-archive-enabled) + (tramp-archive-cleanup-hash)) ;; Remove buffers. (dolist (name (tramp-list-tramp-buffers)) diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el index e4ae121700..33916f82da 100644 --- a/test/lisp/net/tramp-archive-tests.el +++ b/test/lisp/net/tramp-archive-tests.el @@ -808,21 +808,29 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." ;; Autoloading tramp-archive works since Emacs 27.1. (skip-unless (tramp-archive--test-emacs27-p)) + ;; tramp-archive is neither loaded at Emacs startup, nor when + ;; loading a file like "/ssh::" (which loads Tramp). (let ((default-directory (expand-file-name temporary-file-directory)) (code + "(progn \ + (message \"tramp-archive loaded: %%s %%s\" \ + (featurep 'tramp) (featurep 'tramp-archive)) \ + (file-attributes %S \"/\") \ + (message \"tramp-archive loaded: %%s %%s\" \ + (featurep 'tramp) (featurep 'tramp-archive)))")) + (dolist (file `("/ssh::foo" ,(concat tramp-archive-test-archive "foo"))) + (should + (string-match + (format + "tramp-archive loaded: nil nil[[:ascii:]]+tramp-archive loaded: t %s" + (tramp-archive-file-name-p file)) + (shell-command-to-string (format - "(message \"Tramp loaded: %%s\" (and (file-exists-p %S) t))" - tramp-archive-test-archive))) - (should - (string-match - "Tramp loaded: t[\n\r]+" - (shell-command-to-string - (format - "%s -batch -Q -L %s --eval %s" - (shell-quote-argument - (expand-file-name invocation-name invocation-directory)) - (mapconcat 'shell-quote-argument load-path " -L ") - (shell-quote-argument code))))))) + "%s -batch -Q -L %s --eval %s" + (shell-quote-argument + (expand-file-name invocation-name invocation-directory)) + (mapconcat 'shell-quote-argument load-path " -L ") + (shell-quote-argument (format code file))))))))) (ert-deftest tramp-archive-test42-delay-load () "Check that `tramp-archive' is loaded lazily, only when needed." @@ -836,18 +844,21 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (let ((default-directory (expand-file-name temporary-file-directory)) (code "(progn \ - (setq tramp-archive-enabled %s) \ - (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ - (find-file %S \"/\") \ - (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ - (file-attributes %S \"/\") \ - (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)))")) + (setq tramp-archive-enabled %s) \ + (message \"tramp-archive loaded: %%s\" \ + (featurep 'tramp-archive)) \ + (file-attributes %S \"/\") \ + (message \"tramp-archive loaded: %%s\" \ + (featurep 'tramp-archive)) \ + (file-attributes %S \"/\") \ + (message \"tramp-archive loaded: %%s\" \ + (featurep 'tramp-archive)))")) ;; tramp-archive doesn't load when `tramp-archive-enabled' is nil. (dolist (tae '(t nil)) (should (string-match (format - "Tramp loaded: nil[[:ascii:]]+Tramp loaded: nil[[:ascii:]]+Tramp loaded: %s" + "tramp-archive loaded: nil[[:ascii:]]+tramp-archive loaded: nil[[:ascii:]]+tramp-archive loaded: %s" tae) (shell-command-to-string (format commit b4ff8cc591250823d726d59340d32cd72f1103f0 Author: Martin Rudalics Date: Sun Feb 4 11:47:30 2018 +0100 Two minor fixes in Antinews * doc/emacs/anti.texi (Antinews): Two minor fixes. diff --git a/doc/emacs/anti.texi b/doc/emacs/anti.texi index 9c63e04dcb..8cef1be4e1 100644 --- a/doc/emacs/anti.texi +++ b/doc/emacs/anti.texi @@ -90,12 +90,12 @@ You can no longer disable attempts of recovery from fatal exceptions such as C stack overflows and fatal signals. Since the recovery included in Emacs is reliable enough, we decided there was no reason to put your edits in danger of becoming lost when these situations -happen. The variables @code{'attempt-stack-overflow-recovery} and +happen. The variables @code{attempt-stack-overflow-recovery} and @code{attempt-orderly-shutdown-on-fatal-signal} are therefore removed. @item The @code{list-timers} command was removed, as we decided timers are -not user-level feature, and therefore users should not be allowed to +no user-level feature, and therefore users should not be allowed to mess with them. Ask an Emacs Lisp guru near you for help if you have a runaway timer in your session. (Of course, as you move back in time, such runaway timers will become less and less frequent, and commit aafcd12eebff1549b3d4b4f8f8d0f24498c1aedf Author: Juri Linkov Date: Sat Feb 3 23:42:55 2018 +0200 * etc/NEWS: Rename image-dired-thumb-job-limit to image-dired-queue-active-limit (bug#30279) diff --git a/etc/NEWS b/etc/NEWS index 76e6316ca2..5b3e445476 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -958,7 +958,7 @@ the function 'image-dired-setup-dired-keybindings'. --- *** Thumbnail generation is now asynchronous. The number of concurrent processes is limited by the variable -'image-dired-thumb-job-limit'. +'image-dired-queue-active-limit'. --- *** 'image-dired-thumbnail-storage' has a new option 'standard-large' commit a893924fd17c8d0422fccfcb5f373df49a6a1511 Author: Basil L. Contovounesios Date: Sat Feb 3 23:27:13 2018 +0200 * lisp/simple.el (async-shell-command, shell-command): Fix grammar diff --git a/lisp/simple.el b/lisp/simple.el index e2deceb4c2..b7ad6ebd79 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3351,15 +3351,15 @@ to execute it asynchronously. The output appears in the buffer `*Async Shell Command*'. That buffer is in shell mode. -You can configure `async-shell-command-buffer' to specify what to do in -case when `*Async Shell Command*' buffer is already taken by another +You can configure `async-shell-command-buffer' to specify what to do +when the `*Async Shell Command*' buffer is already taken by another running shell command. To run COMMAND without displaying the output in a window you can configure `display-buffer-alist' to use the action `display-buffer-no-window' for the buffer `*Async Shell Command*'. In Elisp, you will often be better served by calling `start-process' -directly, since it offers more control and does not impose the use of a -shell (with its need to quote arguments)." +directly, since it offers more control and does not impose the use of +a shell (with its need to quote arguments)." (interactive (list (read-shell-command "Async shell command: " nil nil @@ -3428,8 +3428,8 @@ In an interactive call, the variable `shell-command-default-error-buffer' specifies the value of ERROR-BUFFER. In Elisp, you will often be better served by calling `call-process' or -`start-process' directly, since it offers more control and does not impose -the use of a shell (with its need to quote arguments)." +`start-process' directly, since they offer more control and do not +impose the use of a shell (with its need to quote arguments)." (interactive (list commit 699081f0516b057ce9319383b244a8e1e8e88516 Author: Basil L. Contovounesios Date: Sat Feb 3 23:22:51 2018 +0200 Fix deferred display of async shell-command buffers * lisp/simple.el (shell-command): Display async shell buffer on process output for every, not just first, command invocation. Check buffer liveness, not name, before displaying. (bug#30213, bug#30280) diff --git a/lisp/simple.el b/lisp/simple.el index 3ac6b86381..e2deceb4c2 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3547,14 +3547,20 @@ the use of a shell (with its need to quote arguments)." ;; carriage motion (see comint-inhibit-carriage-motion). (set-process-filter proc 'comint-output-filter) (if async-shell-command-display-buffer + ;; Display buffer immediately. (display-buffer buffer '(nil (allow-no-window . t))) - (add-function :before (process-filter proc) - (lambda (process _string) - (let ((buf (process-buffer process))) - (when (and (zerop (buffer-size buf)) - (string= (buffer-name buf) - bname)) - (display-buffer buf)))))))) + ;; Defer displaying buffer until first process output. + ;; Use disposable named advice so that the buffer is + ;; displayed at most once per process lifetime. + (let ((nonce (make-symbol "nonce"))) + (add-function :before (process-filter proc) + (lambda (proc _string) + (let ((buf (process-buffer proc))) + (when (buffer-live-p buf) + (remove-function (process-filter proc) + nonce) + (display-buffer buf)))) + `((name . ,nonce))))))) ;; Otherwise, command is executed synchronously. (shell-command-on-region (point) (point) command output-buffer nil error-buffer))))))) commit d2d5e548244b598d5908ad24640aa7c676ece044 Author: Eli Zaretskii Date: Sat Feb 3 22:30:03 2018 +0200 Mention remote file name completion in Emacs manual * doc/emacs/mini.texi (Minibuffer File): Describe the behavior of "//" with remote file names. (Bug#29149) diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index fcd229d817..35cffc1db9 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -119,6 +119,12 @@ second slash in the pair. In the example above, the terminal allows it. (To disable this dimming, turn off File Name Shadow mode with the command @kbd{M-x file-name-shadow-mode}.) + When completing remote file names (@pxref{Remote Files}), a double +slash behaves slightly differently: it causes Emacs to ignore only the +file-name part, leaving the rest (method, host and username, etc.) +intact. Typing three slashes in a row ignores everything in remote +file names. @xref{File name completion,,, tramp, The Tramp Manual}. + @cindex home directory shorthand Emacs interprets @file{~/} as your home directory. Thus, @file{~/foo/bar.txt} specifies a file named @file{bar.txt}, inside a commit 327d251f8a857350a78029c31c7ab3f9797cc727 Author: Paul Eggert Date: Sat Feb 3 12:10:19 2018 -0800 Avoid EOVERFLOW problems with file-directory-p This fixes a bug where (file-directory-p FOO) would fail if FOO had an inode number out of range for ‘stat’. * src/fileio.c (file_directory_p): Accept a Lisp string instead of a C string. All callers changed. On non-MS-Windows hosts, use openat with O_PATH|O_DIRECTORY if available, otherwise file_accessible_directory_p unless it fails due to EACCESS, otherwise stat. diff --git a/src/fileio.c b/src/fileio.c index 62f641fdea..be29e60fc0 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -139,7 +139,7 @@ static bool e_write (int, Lisp_Object, ptrdiff_t, ptrdiff_t, struct coding_system *); -/* Return true if FILENAME exists. */ +/* Return true if FILENAME exists, otherwise return false and set errno. */ static bool check_existing (const char *filename) @@ -2595,7 +2595,7 @@ DEFUN ("file-writable-p", Ffile_writable_p, Sfile_writable_p, 1, 1, 0, /* The read-only attribute of the parent directory doesn't affect whether a file or directory can be created within it. Some day we should check ACLs though, which do affect this. */ - return file_directory_p (SSDATA (dir)) ? Qt : Qnil; + return file_directory_p (dir) ? Qt : Qnil; #else return check_writable (SSDATA (dir), W_OK | X_OK) ? Qt : Qnil; #endif @@ -2689,19 +2689,47 @@ See `file-symlink-p' to distinguish symlinks. */) absname = ENCODE_FILE (absname); - return file_directory_p (SSDATA (absname)) ? Qt : Qnil; + return file_directory_p (absname) ? Qt : Qnil; } -/* Return true if FILE is a directory or a symlink to a directory. */ +/* Return true if FILE is a directory or a symlink to a directory. + Otherwise return false and set errno. */ bool -file_directory_p (char const *file) +file_directory_p (Lisp_Object file) { #ifdef WINDOWSNT /* This is cheaper than 'stat'. */ - return faccessat (AT_FDCWD, file, D_OK, AT_EACCESS) == 0; + return faccessat (AT_FDCWD, SSDATA (file), D_OK, AT_EACCESS) == 0; #else +# ifdef O_PATH + /* Use O_PATH if available, as it avoids races and EOVERFLOW issues. */ + int fd = openat (AT_FDCWD, SSDATA (file), O_PATH | O_CLOEXEC | O_DIRECTORY); + if (0 <= fd) + { + emacs_close (fd); + return true; + } + if (errno != EINVAL) + return false; + /* O_PATH is defined but evidently this Linux kernel predates 2.6.39. + Fall back on generic POSIX code. */ +# endif + /* Use file_accessible_directory, as it avoids stat EOVERFLOW + problems and could be cheaper. However, if it fails because FILE + is inaccessible, fall back on stat; if the latter fails with + EOVERFLOW then FILE must have been a directory unless a race + condition occurred (a problem hard to work around portably). */ + if (file_accessible_directory_p (file)) + return true; + if (errno != EACCES) + return false; struct stat st; - return stat (file, &st) == 0 && S_ISDIR (st.st_mode); + if (stat (SSDATA (file), &st) != 0) + return errno == EOVERFLOW; + if (S_ISDIR (st.st_mode)) + return true; + errno = ENOTDIR; + return false; #endif } @@ -2762,7 +2790,7 @@ file_accessible_directory_p (Lisp_Object file) return (SBYTES (file) == 0 || w32_accessible_directory_p (SSDATA (file), SBYTES (file))); # else /* MSDOS */ - return file_directory_p (SSDATA (file)); + return file_directory_p (file); # endif /* MSDOS */ #else /* !DOS_NT */ /* On POSIXish platforms, use just one system call; this avoids a @@ -3192,7 +3220,7 @@ Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of { #ifdef MSDOS /* Setting times on a directory always fails. */ - if (file_directory_p (SSDATA (encoded_absname))) + if (file_directory_p (encoded_absname)) return Qnil; #endif report_file_error ("Setting file times", absname); diff --git a/src/lisp.h b/src/lisp.h index d547c0c443..a7f0a1d78f 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4130,7 +4130,7 @@ extern _Noreturn void report_file_error (const char *, Lisp_Object); extern _Noreturn void report_file_notify_error (const char *, Lisp_Object); extern bool internal_delete_file (Lisp_Object); extern Lisp_Object emacs_readlinkat (int, const char *); -extern bool file_directory_p (const char *); +extern bool file_directory_p (Lisp_Object); extern bool file_accessible_directory_p (Lisp_Object); extern void init_fileio (void); extern void syms_of_fileio (void); diff --git a/src/lread.c b/src/lread.c index 1221dc9a05..7cacd47d51 100644 --- a/src/lread.c +++ b/src/lread.c @@ -1702,7 +1702,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, AT_EACCESS) == 0) { - if (file_directory_p (pfn)) + if (file_directory_p (encoded_fn)) last_errno = EISDIR; else fd = 1; commit a34c7d7470d5f749659658943bd4084942d873e3 Author: Philipp Stephani Date: Sat Feb 3 21:14:59 2018 +0100 Add tests to verify error propagation in 'json-insert'. * test/src/json-tests.el (json-tests--error): New error symbol. (json-insert/signal, json-insert/throw): New tests. diff --git a/test/src/json-tests.el b/test/src/json-tests.el index 47bccbe6f3..3bbf9eb96b 100644 --- a/test/src/json-tests.el +++ b/test/src/json-tests.el @@ -26,6 +26,8 @@ (require 'cl-lib) (require 'map) +(define-error 'json-tests--error "JSON test error") + (ert-deftest json-serialize/roundtrip () (skip-unless (fboundp 'json-serialize)) ;; The noncharacter U+FFFF should be passed through, @@ -176,5 +178,35 @@ Test with both unibyte and multibyte strings." (should-not (bobp)) (should (looking-at-p (rx " [456]" eos))))) +(ert-deftest json-insert/signal () + (skip-unless (fboundp 'json-insert)) + (with-temp-buffer + (let ((calls 0)) + (add-hook 'after-change-functions + (lambda (_begin _end _length) + (cl-incf calls) + (signal 'json-tests--error + '("Error in `after-change-functions'"))) + :local) + (should-error + (json-insert '((a . "b") (c . 123) (d . [1 2 t :false]))) + :type 'json-tests--error) + (should (equal calls 1))))) + +(ert-deftest json-insert/throw () + (skip-unless (fboundp 'json-insert)) + (with-temp-buffer + (let ((calls 0)) + (add-hook 'after-change-functions + (lambda (_begin _end _length) + (cl-incf calls) + (throw 'test-tag 'throw-value)) + :local) + (should-error + (catch 'test-tag + (json-insert '((a . "b") (c . 123) (d . [1 2 t :false])))) + :type 'no-catch) + (should (equal calls 1))))) + (provide 'json-tests) ;;; json-tests.el ends here commit 9da8da2c4105a28064b1b7d3880ae3fc831c7e8a Author: Noam Postavsky Date: Sat Feb 3 00:44:45 2018 -0500 Don't require all file-attributes to be equal (Bug#30327) * test/lisp/files-tests.el (files-tests-file-attributes-equal): New function. (files-tests-file-name-non-special-directory-files-and-attributes) (files-tests-file-name-non-special-file-attributes): Use it instead of `equal'. diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index 4e1d20edf0..d07df02877 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el @@ -417,10 +417,23 @@ be invoked with the right arguments." (should (equal (directory-files nospecial-dir) (directory-files tmpdir))))) +(defun files-tests-file-attributes-equal (attr1 attr2) + ;; Element 4 is access time, which may be changed by the act of + ;; checking the attributes. + (setf (nth 4 attr1) nil) + (setf (nth 4 attr2) nil) + ;; Element 9 is unspecified. + (setf (nth 9 attr1) nil) + (setf (nth 9 attr2) nil) + (equal attr1 attr2)) + (ert-deftest files-tests-file-name-non-special-directory-files-and-attributes () (files-tests--with-temp-non-special (tmpdir nospecial-dir t) - (should (equal (directory-files-and-attributes nospecial-dir) - (directory-files-and-attributes tmpdir))))) + (cl-loop for (file1 . attr1) in (directory-files-and-attributes nospecial-dir) + for (file2 . attr2) in (directory-files-and-attributes tmpdir) + do + (should (equal file1 file2)) + (should (files-tests-file-attributes-equal attr1 attr2))))) (ert-deftest files-tests-file-name-non-special-dired-compress-handler () ;; `dired-compress-file' can get confused by filenames with ":" in @@ -451,7 +464,8 @@ be invoked with the right arguments." (ert-deftest files-tests-file-name-non-special-file-attributes () (files-tests--with-temp-non-special (tmpfile nospecial) - (should (equal (file-attributes nospecial) (file-attributes tmpfile))))) + (should (files-tests-file-attributes-equal + (file-attributes nospecial) (file-attributes tmpfile))))) (ert-deftest files-tests-file-name-non-special-file-directory-p () (files-tests--with-temp-non-special (tmpdir nospecial-dir t) commit a057771a5af5c9f33ab08a1a55676f3b0ddbee74 Author: Michael Albinus Date: Sat Feb 3 20:08:29 2018 +0100 * test/lisp/files-tests.el (files-tests--with-temp-non-special): Expand `temporary-file-directory' by `file-truename', in case it is located on a symlinked directory. (Bug#30327) diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index 5f42b904cc..4e1d20edf0 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el @@ -351,7 +351,8 @@ be invoked with the right arguments." (declare (indent 1) (debug ((symbolp symbolp &optional form) body))) (cl-check-type name symbol) (cl-check-type non-special-name symbol) - `(let* ((,name (make-temp-file "files-tests" ,dir-flag)) + `(let* ((temporary-file-directory (file-truename temporary-file-directory)) + (,name (make-temp-file "files-tests" ,dir-flag)) (,non-special-name (file-name-quote ,name))) (unwind-protect (progn ,@body) commit a2cb52cd2e7c497df51d751b91b331f59f9637e7 Author: Michael Albinus Date: Sat Feb 3 18:49:56 2018 +0100 Prevent loading tramp-archive when it cannot be used * lisp/files.el (locate-dominating-file): Check, that FILE is a directory when traversing the tree. * lisp/net/tramp-archive.el (tramp-archive-enabled): New defvar. (tramp-archive-file-name-regexp): Protect against errors. (tramp-archive-file-name-handler) (tramp-register-archive-file-name-handler): Use it. (all) Call `tramp-register-archive-file-name-handler'. * lisp/net/tramp.el (tramp-register-file-name-handlers): Use `tramp-archive-enabled'. * test/lisp/net/tramp-archive-tests.el (all): Use `tramp-archive-enabled' instead of `tramp-gvfs-enabled'. (tramp-archive--test-emacs27-p): New defun. (tramp-archive-test42-auto-load): Skip for older Emacsen. (tramp-archive-test42-delay-load): Skip for older Emacsen. Test also behavior when `tramp-archive-enabled' is nil. diff --git a/lisp/files.el b/lisp/files.el index e884a3acc1..414eb3f93a 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -963,7 +963,8 @@ the function needs to examine, starting with FILE." (null file) (string-match locate-dominating-stop-dir-regexp file))) (setq try (if (stringp name) - (file-exists-p (expand-file-name name file)) + (and (file-directory-p file) + (file-exists-p (expand-file-name name file))) (funcall name file))) (cond (try (setq root file)) ((equal file (setq file (file-name-directory diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el index 23191f11f3..ac1c4e1448 100644 --- a/lisp/net/tramp-archive.el +++ b/lisp/net/tramp-archive.el @@ -112,6 +112,14 @@ (defvar url-handler-regexp) (defvar url-tramp-protocols) +;; We cannot check `tramp-gvfs-enabled' in loaddefs.el, because this +;; would load Tramp. So we make a cheaper check. +;;;###autoload +(defvar tramp-archive-enabled (featurep 'dbusbind) + "Non-nil when GVFS is available.") + +(setq tramp-archive-enabled tramp-gvfs-enabled) + ;; ;;;###autoload (defconst tramp-archive-suffixes @@ -169,7 +177,7 @@ It must be supported by libarchive(3).") ;;;###tramp-autoload (defconst tramp-archive-file-name-regexp - (tramp-archive-autoload-file-name-regexp) + (ignore-errors (tramp-archive-autoload-file-name-regexp)) "Regular expression matching archive file names.") ;;;###tramp-autoload @@ -291,7 +299,7 @@ pass to the OPERATION." (tramp-archive-run-real-handler 'file-directory-p (list archive))) (tramp-archive-run-real-handler operation args) ;; Now run the handler. - (unless tramp-gvfs-enabled + (unless tramp-archive-enabled (tramp-compat-user-error nil "Package `tramp-archive' not supported")) (let ((tramp-methods (cons `(,tramp-archive-method) tramp-methods)) (tramp-gvfs-methods tramp-archive-all-gvfs-methods) @@ -308,14 +316,17 @@ pass to the OPERATION." ;;;###autoload (progn (defun tramp-register-archive-file-name-handler () "Add archive file name handler to `file-name-handler-alist'." - (add-to-list 'file-name-handler-alist - (cons (tramp-archive-autoload-file-name-regexp) - 'tramp-autoload-file-name-handler)) - (put 'tramp-archive-file-name-handler 'safe-magic t))) + (when tramp-archive-enabled + (add-to-list 'file-name-handler-alist + (cons (tramp-archive-autoload-file-name-regexp) + 'tramp-autoload-file-name-handler)) + (put 'tramp-archive-file-name-handler 'safe-magic t)))) ;;;###autoload (add-hook 'after-init-hook 'tramp-register-archive-file-name-handler) +(tramp-register-archive-file-name-handler) + ;; Mark `operations' the handler is responsible for. (put 'tramp-archive-file-name-handler 'operations (mapcar 'car tramp-archive-file-name-handler-alist)) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 5a2e358daa..09abd48226 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -2401,10 +2401,11 @@ remote file names." (put 'tramp-completion-file-name-handler 'operations (mapcar 'car tramp-completion-file-name-handler-alist)) - (add-to-list 'file-name-handler-alist - (cons tramp-archive-file-name-regexp - 'tramp-archive-file-name-handler)) - (put 'tramp-archive-file-name-handler 'safe-magic t) + (when (bound-and-true-p tramp-archive-enabled) + (add-to-list 'file-name-handler-alist + (cons tramp-archive-file-name-regexp + 'tramp-archive-file-name-handler)) + (put 'tramp-archive-file-name-handler 'safe-magic t)) ;; If jka-compr or epa-file are already loaded, move them to the ;; front of `file-name-handler-alist'. diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el index bebdf108c6..e4ae121700 100644 --- a/test/lisp/net/tramp-archive-tests.el +++ b/test/lisp/net/tramp-archive-tests.el @@ -86,12 +86,18 @@ Some semantics has been changed for there, w/o new functions or variables, so we check the Emacs version directly." (>= emacs-major-version 26)) +(defun tramp-archive--test-emacs27-p () + "Check for Emacs version >= 27.1. +Some semantics has been changed for there, w/o new functions or +variables, so we check the Emacs version directly." + (>= emacs-major-version 27)) + (ert-deftest tramp-archive-test00-availability () - "Test availability of Tramp functions." - :expected-result (if tramp-gvfs-enabled :passed :failed) + "Test availability of archive file name functions." + :expected-result (if tramp-archive-enabled :passed :failed) (should (and - tramp-gvfs-enabled + tramp-archive-enabled (file-exists-p tramp-archive-test-file-archive) (tramp-archive-file-name-p tramp-archive-test-archive)))) @@ -147,7 +153,7 @@ variables, so we check the Emacs version directly." (ert-deftest tramp-archive-test02-file-name-dissect () "Check archive file name components." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (with-parsed-tramp-archive-file-name tramp-archive-test-archive nil (should (string-equal method tramp-archive-method)) @@ -266,7 +272,7 @@ They shall still be supported" "Check `directory-file-name'. This checks also `file-name-as-directory', `file-name-directory', `file-name-nondirectory' and `unhandled-file-name-directory'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (should (string-equal @@ -305,7 +311,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test07-file-exists-p () "Check `file-exist-p', `write-region' and `delete-file'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (unwind-protect (let ((default-directory tramp-archive-test-archive)) @@ -327,7 +333,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test08-file-local-copy () "Check `file-local-copy'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let (tmp-name) (unwind-protect @@ -353,7 +359,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test09-insert-file-contents () "Check `insert-file-contents'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let ((tmp-name (expand-file-name "bar/bar" tramp-archive-test-archive))) (unwind-protect @@ -379,7 +385,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test11-copy-file () "Check `copy-file'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) ;; Copy simple file. (let ((tmp-name1 (expand-file-name "bar/bar" tramp-archive-test-archive)) @@ -444,7 +450,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test15-copy-directory () "Check `copy-directory'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let* ((tmp-name1 (expand-file-name "bar" tramp-archive-test-archive)) (tmp-name2 (tramp-archive--test-make-temp-name)) @@ -498,7 +504,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test16-directory-files () "Check `directory-files'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let ((tmp-name tramp-archive-test-archive) (files '("." ".." "bar" "baz.tar" "foo.hrd" "foo.lnk" "foo.txt"))) @@ -521,7 +527,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test17-insert-directory () "Check `insert-directory'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let (;; We test for the summary line. Keyword "total" could be localized. (process-environment @@ -563,7 +569,7 @@ This checks also `file-name-as-directory', `file-name-directory', (ert-deftest tramp-archive-test18-file-attributes () "Check `file-attributes'. This tests also `file-readable-p' and `file-regular-p'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let ((tmp-name1 (expand-file-name "foo.txt" tramp-archive-test-archive)) (tmp-name2 (expand-file-name "foo.lnk" tramp-archive-test-archive)) @@ -613,7 +619,7 @@ This tests also `file-readable-p' and `file-regular-p'." (ert-deftest tramp-archive-test19-directory-files-and-attributes () "Check `directory-files-and-attributes'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let ((tmp-name (expand-file-name "bar" tramp-archive-test-archive)) attr) @@ -638,7 +644,7 @@ This tests also `file-readable-p' and `file-regular-p'." (ert-deftest tramp-archive-test20-file-modes () "Check `file-modes'. This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let ((tmp-name1 (expand-file-name "foo.txt" tramp-archive-test-archive)) (tmp-name2 (expand-file-name "bar" tramp-archive-test-archive))) @@ -667,7 +673,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (ert-deftest tramp-archive-test21-file-links () "Check `file-symlink-p' and `file-truename'" - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) ;; We must use `file-truename' for the file archive, because it ;; could be located on a symlinked directory. This would let the @@ -705,7 +711,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (ert-deftest tramp-archive-test26-file-name-completion () "Check `file-name-completion' and `file-name-all-completions'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) (let ((tmp-name tramp-archive-test-archive)) (unwind-protect @@ -744,7 +750,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." ;; The functions were introduced in Emacs 26.1. (ert-deftest tramp-archive-test37-make-nearby-temp-file () "Check `make-nearby-temp-file' and `temporary-file-directory'." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) ;; Since Emacs 26.1. (skip-unless (and (fboundp 'make-nearby-temp-file) (fboundp 'temporary-file-directory))) @@ -781,7 +787,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (ert-deftest tramp-archive-test40-file-system-info () "Check that `file-system-info' returns proper values." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) ;; Since Emacs 27.1. (skip-unless (fboundp 'file-system-info)) @@ -798,7 +804,9 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (ert-deftest tramp-archive-test42-auto-load () "Check that `tramp-archive' autoloads properly." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) + ;; Autoloading tramp-archive works since Emacs 27.1. + (skip-unless (tramp-archive--test-emacs27-p)) (let ((default-directory (expand-file-name temporary-file-directory)) (code @@ -818,38 +826,44 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (ert-deftest tramp-archive-test42-delay-load () "Check that `tramp-archive' is loaded lazily, only when needed." - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) + ;; Autoloading tramp-archive works since Emacs 27.1. + (skip-unless (tramp-archive--test-emacs27-p)) - ;; Tramp is neither loaded at Emacs startup, nor when completing a - ;; non archive file name like "/foo". Completing an archive file - ;; name like "/foo.tar/" autoloads Tramp, when `tramp-mode' is t. + ;; tramp-archive is neither loaded at Emacs startup, nor when + ;; loading a file like "/foo.tar". It is loaded only when + ;; `tramp-archive-enabled' is t. (let ((default-directory (expand-file-name temporary-file-directory)) (code + "(progn \ + (setq tramp-archive-enabled %s) \ + (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ + (find-file %S \"/\") \ + (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ + (file-attributes %S \"/\") \ + (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)))")) + ;; tramp-archive doesn't load when `tramp-archive-enabled' is nil. + (dolist (tae '(t nil)) + (should + (string-match + (format + "Tramp loaded: nil[[:ascii:]]+Tramp loaded: nil[[:ascii:]]+Tramp loaded: %s" + tae) + (shell-command-to-string (format - "(progn \ - (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ - (file-name-all-completions %S \"/\") \ - (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ - (file-name-all-completions %S \"/\") \ - (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)))" - tramp-archive-test-file-archive - tramp-archive-test-archive))) - ;; Tramp doesn't load when `tramp-mode' is nil. - (should - (string-match - "Tramp loaded: nil[\n\r]+Tramp loaded: nil[\n\r]+Tramp loaded: t[\n\r]+" - (shell-command-to-string - (format - "%s -batch -Q -L %s --eval %s" - (shell-quote-argument - (expand-file-name invocation-name invocation-directory)) - (mapconcat 'shell-quote-argument load-path " -L ") - (shell-quote-argument code))))))) + "%s -batch -Q -L %s --eval %s" + (shell-quote-argument + (expand-file-name invocation-name invocation-directory)) + (mapconcat 'shell-quote-argument load-path " -L ") + (shell-quote-argument + (format + code tae tramp-archive-test-file-archive + (concat tramp-archive-test-archive "foo")))))))))) (ert-deftest tramp-archive-test99-libarchive-tests () "Run tests of libarchive test files." :tags '(:expensive-test) - (skip-unless tramp-gvfs-enabled) + (skip-unless tramp-archive-enabled) ;; We do not want to run unless chosen explicitly. This test makes ;; sense only in my local environment. Michael Albinus. (skip-unless commit f7c8a12b12f5344100d3da192c0ec80f69ed55a9 Author: Basil L. Contovounesios Date: Tue Jan 30 11:10:14 2018 +0000 ; Fix arglist doc of json parse functions * src/json.c (Fjson_parse_string, Fjson_parse_buffer): Fix "usage:" arglist doc. diff --git a/src/json.c b/src/json.c index 12ba7afa6a..b046d34f66 100644 --- a/src/json.c +++ b/src/json.c @@ -740,7 +740,7 @@ object, all but the last one are ignored. If STRING doesn't contain a valid JSON object, an error of type `json-parse-error' is signaled. The keyword argument `:object-type' specifies which Lisp type is used to represent objects; it can be `hash-table' or `alist'. -usage: (string &key (OBJECT-TYPE \\='hash-table)) */) +usage: (json-parse-string STRING &key (OBJECT-TYPE \\='hash-table)) */) (ptrdiff_t nargs, Lisp_Object *args) { ptrdiff_t count = SPECPDL_INDEX (); @@ -813,7 +813,7 @@ DEFUN ("json-parse-buffer", Fjson_parse_buffer, Sjson_parse_buffer, This is similar to `json-parse-string', which see. Move point after the end of the object if parsing was successful. On error, point is not moved. -usage: (&key (OBJECT-TYPE \\='hash-table)) */) +usage: (json-parse-buffer &key (OBJECT-TYPE \\='hash-table)) */) (ptrdiff_t nargs, Lisp_Object *args) { ptrdiff_t count = SPECPDL_INDEX (); commit 84c9dba4cee052b68b194c3a2e5c297a94d8c8af Author: Michael Albinus Date: Sat Feb 3 13:22:56 2018 +0100 Autoload tramp-archive * doc/misc/tramp.texi (Archive file names): Do not require to load Tramp explicitly, this is autoloaded now also for file archives. * lisp/net/tramp-archive.el (tramp-archive-suffixes) (tramp-archive-compression-suffixes): Autoload them. (tramp-archive-autoload-file-name-regexp): New defmacro. (tramp-archive-file-name-regexp): Use it. (tramp-register-archive-file-name-handler): New defun. Call it in `after-init-hook'. * test/lisp/net/tramp-archive-tests.el (tramp-archive-test40-file-system-info): Rename from `tramp-archive-test40-archive-file-system-info. (tramp-archive-test42-auto-load) (tramp-archive-test42-delay-load): New tests. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index f5dfef261f..235627cc0f 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3117,15 +3117,14 @@ similar @samp{/scp:user@@host:...}. See the constant @code{tramp-archive-all-gvfs-methods} for a complete list of @code{tramp-gvfs} supported method names. -If @value{tramp} is loaded and @code{url-handler-mode} is enabled, -archives could be visited via URLs, like +If @code{url-handler-mode} is enabled, archives could be visited via +URLs, like @file{https://ftp.gnu.org/gnu/tramp/tramp-2.3.2.tar.gz/INSTALL}. This allows complex file operations like @lisp @group (progn - (require 'tramp) (url-handler-mode 1) (ediff-directories "https://ftp.gnu.org/gnu/tramp/tramp-2.3.1.tar.gz/tramp-2.3.1" @@ -3137,8 +3136,10 @@ It is even possible to access file archives in file archives, as @lisp @group -(find-file - "http://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control") +(progn + (url-handler-mode 1) + (find-file + "http://ftp.debian.org/debian/pool/main/c/coreutils/coreutils_8.28-1_amd64.deb/control.tar.gz/control")) @end group @end lisp diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el index e012ac3a19..23191f11f3 100644 --- a/lisp/net/tramp-archive.el +++ b/lisp/net/tramp-archive.el @@ -113,7 +113,7 @@ (defvar url-tramp-protocols) ;; -;;;###tramp-autoload +;;;###autoload (defconst tramp-archive-suffixes ;; "cab", "lzh" and "zip" are included with lower and upper letters, ;; because Microsoft Windows provides them often with capital @@ -143,25 +143,33 @@ It must be supported by libarchive(3).") ;; -;; read and write: tar, cpio, pax , gzip , zip, bzip2, xz, lzip, lzma, ar, mtree, iso9660, compress, -;; read only: 7-Zip, mtree, xar, lha/lzh, rar, microsoft cab, +;; read and write: tar, cpio, pax , gzip , zip, bzip2, xz, lzip, lzma, ar, mtree, iso9660, compress. +;; read only: 7-Zip, mtree, xar, lha/lzh, rar, microsoft cab. -;;;###tramp-autoload +;;;###autoload (defconst tramp-archive-compression-suffixes '("bz2" "gz" "lrz" "lz" "lz4" "lzma" "lzo" "uu" "xz" "Z") "List of suffixes which indicate a compressed file. It must be supported by libarchive(3).") -;;;###tramp-autoload -(defconst tramp-archive-file-name-regexp - (concat +;; The definition of `tramp-archive-file-name-regexp' contains calls +;; to `regexp-opt', which cannot be autoloaded while loading +;; loaddefs.el. So we use a macro, which is evaluated only when needed. +;;;###autoload +(progn (defmacro tramp-archive-autoload-file-name-regexp () + "Regular expression matching archive file names." + `(concat "\\`" "\\(" ".+" "\\." ;; Default suffixes ... (regexp-opt tramp-archive-suffixes) ;; ... with compression. "\\(?:" "\\." (regexp-opt tramp-archive-compression-suffixes) "\\)*" "\\)" ;; \1 - "\\(" "/" ".*" "\\)" "\\'") ;; \2 + "\\(" "/" ".*" "\\)" "\\'"))) ;; \2 + +;;;###tramp-autoload +(defconst tramp-archive-file-name-regexp + (tramp-archive-autoload-file-name-regexp) "Regular expression matching archive file names.") ;;;###tramp-autoload @@ -297,6 +305,17 @@ pass to the OPERATION." (save-match-data (apply (cdr fn) args)) (tramp-archive-run-real-handler operation args)))))) +;;;###autoload +(progn (defun tramp-register-archive-file-name-handler () + "Add archive file name handler to `file-name-handler-alist'." + (add-to-list 'file-name-handler-alist + (cons (tramp-archive-autoload-file-name-regexp) + 'tramp-autoload-file-name-handler)) + (put 'tramp-archive-file-name-handler 'safe-magic t))) + +;;;###autoload +(add-hook 'after-init-hook 'tramp-register-archive-file-name-handler) + ;; Mark `operations' the handler is responsible for. (put 'tramp-archive-file-name-handler 'operations (mapcar 'car tramp-archive-file-name-handler-alist)) diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el index 96c6a71097..bebdf108c6 100644 --- a/test/lisp/net/tramp-archive-tests.el +++ b/test/lisp/net/tramp-archive-tests.el @@ -779,7 +779,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (delete-directory tmp-file) (should-not (file-exists-p tmp-file)))) -(ert-deftest tramp-archive-test40-archive-file-system-info () +(ert-deftest tramp-archive-test40-file-system-info () "Check that `file-system-info' returns proper values." (skip-unless tramp-gvfs-enabled) ;; Since Emacs 27.1. @@ -796,6 +796,56 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'." (zerop (nth 1 fsi)) (zerop (nth 2 fsi)))))) +(ert-deftest tramp-archive-test42-auto-load () + "Check that `tramp-archive' autoloads properly." + (skip-unless tramp-gvfs-enabled) + + (let ((default-directory (expand-file-name temporary-file-directory)) + (code + (format + "(message \"Tramp loaded: %%s\" (and (file-exists-p %S) t))" + tramp-archive-test-archive))) + (should + (string-match + "Tramp loaded: t[\n\r]+" + (shell-command-to-string + (format + "%s -batch -Q -L %s --eval %s" + (shell-quote-argument + (expand-file-name invocation-name invocation-directory)) + (mapconcat 'shell-quote-argument load-path " -L ") + (shell-quote-argument code))))))) + +(ert-deftest tramp-archive-test42-delay-load () + "Check that `tramp-archive' is loaded lazily, only when needed." + (skip-unless tramp-gvfs-enabled) + + ;; Tramp is neither loaded at Emacs startup, nor when completing a + ;; non archive file name like "/foo". Completing an archive file + ;; name like "/foo.tar/" autoloads Tramp, when `tramp-mode' is t. + (let ((default-directory (expand-file-name temporary-file-directory)) + (code + (format + "(progn \ + (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ + (file-name-all-completions %S \"/\") \ + (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)) \ + (file-name-all-completions %S \"/\") \ + (message \"Tramp loaded: %%s\" (featurep 'tramp-archive)))" + tramp-archive-test-file-archive + tramp-archive-test-archive))) + ;; Tramp doesn't load when `tramp-mode' is nil. + (should + (string-match + "Tramp loaded: nil[\n\r]+Tramp loaded: nil[\n\r]+Tramp loaded: t[\n\r]+" + (shell-command-to-string + (format + "%s -batch -Q -L %s --eval %s" + (shell-quote-argument + (expand-file-name invocation-name invocation-directory)) + (mapconcat 'shell-quote-argument load-path " -L ") + (shell-quote-argument code))))))) + (ert-deftest tramp-archive-test99-libarchive-tests () "Run tests of libarchive test files." :tags '(:expensive-test) commit f589f5ae6e19210b8520526fa3111243ca446b02 Author: Eli Zaretskii Date: Sat Feb 3 13:50:38 2018 +0200 Yest another round of manual copyedits * doc/emacs/fixit.texi (Transpose, Spelling): Minor stylistic changes. Suggested by myq larson in emacs-manual-bugs@gnu.org. * doc/emacs/calendar.texi (Appointments, Time Intervals): Mention relevant Org features. Suggested by Alex Branham in emacs-manual-bugs@gnu.org. * doc/emacs/dired.texi (Operating on Files) (Shell Commands in Dired, Image-Dired): Minor stylistic edits. Suggested by Francis Wright in emacs-manual-bugs@gnu.org. * doc/emacs/commands.texi (User Input): Explain "C-M-a". Suggested by Martin Luethi in emacs-manual-bugs@gnu.org. diff --git a/doc/emacs/calendar.texi b/doc/emacs/calendar.texi index 7ce73a662b..9145a725e1 100644 --- a/doc/emacs/calendar.texi +++ b/doc/emacs/calendar.texi @@ -1435,7 +1435,11 @@ also updated whenever the diary file (or a file it includes; see @ifnottex @ref{Fancy Diary Display}) @end ifnottex -is saved. +is saved. If you use the Org Mode and keep appointments in your Org +agenda files, you can add those appointments to the list using the +@code{org-agenda-to-appt} command. @xref{Weekly/daily agenda, +Appointment reminders,,org, The Org Manual}, for more about that +command. @findex appt-add @findex appt-delete @@ -1581,10 +1585,13 @@ variables' values are 120. @cindex time intervals, summing @cindex summing time intervals @cindex timeclock +@cindex clocking time The timeclock package adds up time intervals, so you can (for instance) keep track of how much time you spend working on particular -projects. +projects. (A more advanced alternative is to use the Org Mode's +facilities for clocking time, @pxref{Clocking work time,,,org, The Org +Manual}). @findex timeclock-in @findex timeclock-out diff --git a/doc/emacs/commands.texi b/doc/emacs/commands.texi index 2e65bfd385..8b8b0c7aad 100644 --- a/doc/emacs/commands.texi +++ b/doc/emacs/commands.texi @@ -56,11 +56,12 @@ characters, e.g., @kbd{C-@key{F1}} or @kbd{M-@key{LEFT}}. @cindex @key{ESC} replacing @key{META} key You can also type Meta characters using two-character sequences starting with @key{ESC}. Thus, you can enter @kbd{M-a} by typing -@kbd{@key{ESC} a}. You can enter @kbd{C-M-a} by typing @kbd{@key{ESC} -C-a}. Unlike @key{META}, @key{ESC} is entered as a separate -character. You don't hold down @key{ESC} while typing the next -character; instead, press @key{ESC} and release it, then enter the -next character. This feature is useful on certain text terminals +@kbd{@key{ESC} a}. You can enter @kbd{C-M-a} (holding down both +@key{Ctrl} and @key{Alt}, then pressing @kbd{a}) by typing +@kbd{@key{ESC} C-a}. Unlike @key{META}, @key{ESC} is entered as a +separate character. You don't hold down @key{ESC} while typing the +next character; instead, press @key{ESC} and release it, then enter +the next character. This feature is useful on certain text terminals where the @key{META} key does not function reliably. @cindex keys stolen by window manager diff --git a/doc/emacs/dired.texi b/doc/emacs/dired.texi index 805f580086..6b6ab3a039 100644 --- a/doc/emacs/dired.texi +++ b/doc/emacs/dired.texi @@ -727,8 +727,8 @@ this.) @vindex dired-chown-program The variable @code{dired-chown-program} specifies the name of the -program to use to do the work (different systems put @command{chown} -in different places). +program to use to do the work. (This variable is necessary because +different systems put @command{chown} in different places). @findex dired-do-touch @kindex T @r{(Dired)} @@ -898,7 +898,7 @@ treat it specially. Otherwise, if the command string contains @samp{?} surrounded by whitespace or @samp{`?`}, Emacs runs the shell command once @emph{for each file}, substituting the current file name for @samp{?} -and @samp{`?`} each time. You can use both @samp{?} or @samp{`?`} more +and @samp{`?`} each time. You can use both @samp{?} and @samp{`?`} more than once in the command; the same file name replaces each occurrence. If you mix them with @samp{*} the command signals an error. @@ -1391,7 +1391,7 @@ display the next image. Typing @key{DEL} the previous thumbnail and displays that instead. @vindex image-dired-external-viewer - To view and the image in its original size, either provide a prefix + To view the image in its original size, either provide a prefix argument (@kbd{C-u}) before pressing @key{RET}, or type @kbd{C-@key{RET}} (@code{image-dired-thumbnail-display-external}) to display the image in an external viewer. You must first configure @@ -1426,7 +1426,8 @@ a comment from Dired (@code{image-dired-dired-comment-files}). Image-Dired also provides simple image manipulation. In the thumbnail buffer, type @kbd{L} to rotate the original image 90 degrees anti clockwise, and @kbd{R} to rotate it 90 degrees clockwise. This -rotation is lossless, and uses an external utility called JpegTRAN. +rotation is lossless, and uses an external utility called +@command{jpegtran}, which you need to install first. @node Misc Dired Features @section Other Dired Features diff --git a/doc/emacs/fixit.texi b/doc/emacs/fixit.texi index ced1ef9dbf..aca85f3de0 100644 --- a/doc/emacs/fixit.texi +++ b/doc/emacs/fixit.texi @@ -159,9 +159,10 @@ last two characters on the line. So, if you catch your transposition error right away, you can fix it with just a @kbd{C-t}. If you don't catch it so fast, you must move the cursor back between the two transposed characters before you type @kbd{C-t}. If you transposed a space with -the last character of the word before it, the word motion commands are -a good way of getting there. Otherwise, a reverse search (@kbd{C-r}) -is often the best way. @xref{Search}. +the last character of the word before it, the word motion commands +(@kbd{M-f}, @kbd{M-b}, etc.) are a good way of getting there. +Otherwise, a reverse search (@kbd{C-r}) is often the best way. +@xref{Search}. @kindex C-x C-t @findex transpose-lines @@ -181,22 +182,23 @@ punctuation characters between the words do not move. For example, @kbd{C-M-t} (@code{transpose-sexps}) is a similar command for transposing two expressions (@pxref{Expressions}), and @kbd{C-x C-t} (@code{transpose-lines}) exchanges lines. They work like @kbd{M-t} -except as regards what units of text they transpose. +except as regards the units of text they transpose. A numeric argument to a transpose command serves as a repeat count: it -tells the transpose command to move the character (word, expression, line) -before or containing point across several other characters (words, -expressions, lines). For example, @kbd{C-u 3 C-t} moves the character before -point forward across three other characters. It would change -@samp{f@point{}oobar} into @samp{oobf@point{}ar}. This is equivalent to -repeating @kbd{C-t} three times. @kbd{C-u - 4 M-t} moves the word -before point backward across four words. @kbd{C-u - C-M-t} would cancel -the effect of plain @kbd{C-M-t}. +tells the transpose command to move the character (or word or +expression or line) before or containing point across several other +characters (or words or expressions or lines). For example, @kbd{C-u +3 C-t} moves the character before point forward across three other +characters. It would change @samp{f@point{}oobar} into +@samp{oobf@point{}ar}. This is equivalent to repeating @kbd{C-t} +three times. @kbd{C-u - 4 M-t} moves the word before point backward +across four words. @kbd{C-u - C-M-t} would cancel the effect of plain +@kbd{C-M-t}. A numeric argument of zero is assigned a special meaning (because otherwise a command with a repeat count of zero would do nothing): to -transpose the character (word, expression, line) ending after point -with the one ending after the mark. +transpose the character (or word or expression or line) ending after +point with the one ending after the mark. @node Fixing Case @section Case Conversion @@ -227,9 +229,10 @@ case-convert it and go on typing. @xref{Case}. This section describes the commands to check the spelling of a single word or of a portion of a buffer. These commands only work if -the spelling checker program Hunspell, Aspell, Ispell or Enchant is installed. -These programs are not part of Emacs, but one of them is usually -installed in GNU/Linux and other free operating systems. +a spelling checker program, one of Hunspell, Aspell, Ispell or +Enchant, is installed. These programs are not part of Emacs, but one +of them is usually installed in GNU/Linux and other free operating +systems. @ifnottex @xref{Top, Aspell,, aspell, The Aspell Manual}. @end ifnottex commit 1ed408995a622a4c0cd7176f9bd0d81ebfbb5e43 Author: Eli Zaretskii Date: Sat Feb 3 12:19:41 2018 +0200 Update xdisp.c commentary * src/xdisp.c: Update commentary regarding "asynchronous" entry into redisplay. (Bug#30182) diff --git a/src/xdisp.c b/src/xdisp.c index 7511e54ab1..bf1737b9cf 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -34,26 +34,41 @@ along with GNU Emacs. If not, see . */ in xdisp.c is the only entry into the inner redisplay code. The following diagram shows how redisplay code is invoked. As you - can see, Lisp calls redisplay and vice versa. Under window systems - like X, some portions of the redisplay code are also called - asynchronously during mouse movement or expose events. It is very - important that these code parts do NOT use the C library (malloc, - free) because many C libraries under Unix are not reentrant. They - may also NOT call functions of the Lisp interpreter which could - change the interpreter's state. If you don't follow these rules, - you will encounter bugs which are very hard to explain. + can see, Lisp calls redisplay and vice versa. + + Under window systems like X, some portions of the redisplay code + are also called asynchronously, due to mouse movement or expose + events. "Asynchronously" in this context means that any C function + which calls maybe_quit or process_pending_signals could enter + redisplay via expose_frame and/or note_mouse_highlight, if X events + were recently reported to Emacs about mouse movements or frame(s) + that were exposed. And such redisplay could invoke the Lisp + interpreter, e.g. via the :eval forms in mode-line-format, and as + result the global state could change. It is therefore very + important that C functions which might cause such "asynchronous" + redisplay, but cannot tolerate the results, use + block_input/unblock_input around code fragments which assume that + global Lisp state doesn't change. If you don't follow this rule, + you will encounter bugs which are very hard to explain. One place + that needs to take such precautions is timer_check, some of whose + code cannot tolerate changes in timer alists while it processes + timers. +--------------+ redisplay +----------------+ | Lisp machine |---------------->| Redisplay code |<--+ +--------------+ (xdisp.c) +----------------+ | ^ | | +----------------------------------+ | - Don't use this path when called | - asynchronously! | - | - expose_window (asynchronous) | - | - X expose events -----+ + Block input to prevent this when | + called asynchronously! | + | + note_mouse_highlight (asynchronous) | + | + X mouse events -----+ + | + expose_frame (asynchronous) | + | + X expose events -----+ What does redisplay do? Obviously, it has to figure out somehow what has been changed since the last time the display has been updated, commit e23de39e22ccdf594b0ee84959f6df9d01af25a2 Author: Michael Albinus Date: Sat Feb 3 11:08:33 2018 +0100 Fix Bug#30324 * lisp/net/rlogin.el (rlogin, rlogin-directory-tracking-mode): Adapt to changed remote file name syntax. (Bug#30324) diff --git a/lisp/net/rlogin.el b/lisp/net/rlogin.el index 646adef2f0..3bfc4d7f35 100644 --- a/lisp/net/rlogin.el +++ b/lisp/net/rlogin.el @@ -219,7 +219,7 @@ variable." ;; function, to avoid a gratuitous resync check; the default ;; should be the user's home directory, be it local or remote. (setq comint-file-name-prefix - (concat "/" rlogin-remote-user "@" rlogin-host ":")) + (concat "/-:" rlogin-remote-user "@" rlogin-host ":")) (cd-absolute comint-file-name-prefix)) ((null rlogin-directory-tracking-mode)) (t @@ -253,7 +253,7 @@ local one share the same directories (e.g. through NFS)." (setq rlogin-directory-tracking-mode t) (setq shell-dirtrackp t) (setq comint-file-name-prefix - (concat "/" rlogin-remote-user "@" rlogin-host ":"))) + (concat "/-:" rlogin-remote-user "@" rlogin-host ":"))) ((< prefix 0) (setq rlogin-directory-tracking-mode nil) (setq shell-dirtrackp nil)) commit e1a9dc0af6ffb202ce1393b376d14d3c3897a243 Author: Glenn Morris Date: Fri Feb 2 21:08:22 2018 -0500 Recognize Org as builtin package (bug#30310) * lisp/org/org.el: Add Version header so detected as builtin package. * test/lisp/org/org-tests.el: New file. diff --git a/lisp/org/org.el b/lisp/org/org.el index 5272061ccc..4e4620549c 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -7,6 +7,7 @@ ;; Maintainer: Carsten Dominik ;; Keywords: outlines, hypermedia, calendar, wp ;; Homepage: http://orgmode.org +;; Version: 9.1.6 ;; ;; This file is part of GNU Emacs. ;; diff --git a/test/lisp/org/org-tests.el b/test/lisp/org/org-tests.el new file mode 100644 index 0000000000..a220188856 --- /dev/null +++ b/test/lisp/org/org-tests.el @@ -0,0 +1,31 @@ +;;; org-tests.el --- tests for org/org.el + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; Maintainer: emacs-devel@gnu.org + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(ert-deftest org-package-version () + "Test Version: header is present and correct. +Ref ." + (should (require 'org-version nil t)) + (should (equal (version-to-list (org-release)) + (cdr (assq 'org package--builtin-versions)))))