X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/b50a20709f8ec549c18b8dd8665f6f61ee151c82..c87c2cad94ab0570846015dcef91a38e84317be9:/lisp/files.el diff --git a/lisp/files.el b/lisp/files.el index aca7b3593d..4610c0a11e 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -2143,6 +2143,7 @@ Do you want to revisit the file normally now? ") (defun insert-file-contents-literally (filename &optional visit beg end replace) "Like `insert-file-contents', but only reads in the file literally. +See `insert-file-contents' for an explanation of the parameters. A buffer may be modified in several ways after reading into the buffer, due to Emacs features such as format decoding, character code conversion, `find-file-hook', automatic uncompression, etc. @@ -2315,14 +2316,21 @@ not set local variables (though we do notice a mode specified with -*-.) or from Lisp without specifying the optional argument FIND-FILE; in that case, this function acts as if `enable-local-variables' were t." (interactive) - (fundamental-mode) + (kill-all-local-variables) + (unless delay-mode-hooks + (run-hooks 'change-major-mode-after-body-hook + 'after-change-major-mode-hook)) (let ((enable-local-variables (or (not find-file) enable-local-variables))) ;; FIXME this is less efficient than it could be, since both ;; s-a-m and h-l-v may parse the same regions, looking for "mode:". (with-demoted-errors "File mode specification error: %s" (set-auto-mode)) - (with-demoted-errors "File local-variables error: %s" - (hack-local-variables))) + ;; `delay-mode-hooks' being non-nil will have prevented the major + ;; mode's call to `run-mode-hooks' from calling + ;; `hack-local-variables'. In that case, call it now. + (when delay-mode-hooks + (with-demoted-errors "File local-variables error: %s" + (hack-local-variables 'no-mode)))) ;; Turn font lock off and on, to make sure it takes account of ;; whatever file local variables are relevant to it. (when (and font-lock-mode @@ -3296,11 +3304,15 @@ DIR-NAME is the name of the associated directory. Otherwise it is nil." ;; TODO? Warn once per file rather than once per session? (defvar hack-local-variables--warned-lexical nil) -(defun hack-local-variables (&optional mode-only) +(defun hack-local-variables (&optional handle-mode) "Parse and put into effect this buffer's local variables spec. Uses `hack-local-variables-apply' to apply the variables. -If MODE-ONLY is non-nil, all we do is check whether a \"mode:\" +If HANDLE-MODE is nil, we apply all the specified local +variables. If HANDLE-MODE is neither nil nor t, we do the same, +except that any settings of `mode' are ignored. + +If HANDLE-MODE is t, all we do is check whether a \"mode:\" is specified, and return the corresponding mode symbol, or nil. In this case, we try to ignore minor-modes, and only return a major-mode. @@ -3318,7 +3330,7 @@ local variables, but directory-local variables may still be applied." (let ((enable-local-variables (and local-enable-local-variables enable-local-variables)) result) - (unless mode-only + (unless (eq handle-mode t) (setq file-local-variables-alist nil) (with-demoted-errors "Directory-local variables error: %s" ;; Note this is a no-op if enable-local-variables is nil. @@ -3326,18 +3338,19 @@ local variables, but directory-local variables may still be applied." ;; This entire function is basically a no-op if enable-local-variables ;; is nil. All it does is set file-local-variables-alist to nil. (when enable-local-variables - ;; This part used to ignore enable-local-variables when mode-only - ;; was non-nil. That was inappropriate, eg consider the + ;; This part used to ignore enable-local-variables when handle-mode + ;; was t. That was inappropriate, eg consider the ;; (artificial) example of: ;; (setq local-enable-local-variables nil) ;; Open a file foo.txt that contains "mode: sh". ;; It correctly opens in text-mode. ;; M-x set-visited-file name foo.c, and it incorrectly stays in text-mode. (unless (or (inhibit-local-variables-p) - ;; If MODE-ONLY is non-nil, and the prop line specifies a + ;; If HANDLE-MODE is t, and the prop line specifies a ;; mode, then we're done, and have no need to scan further. - (and (setq result (hack-local-variables-prop-line mode-only)) - mode-only)) + (and (setq result (hack-local-variables-prop-line + (eq handle-mode t))) + (eq handle-mode t))) ;; Look for "Local variables:" line in last page. (save-excursion (goto-char (point-max)) @@ -3392,7 +3405,7 @@ local variables, but directory-local variables may still be applied." (goto-char (point-min)) (while (not (or (eobp) - (and mode-only result))) + (and (eq handle-mode t) result))) ;; Find the variable name; (unless (looking-at hack-local-variable-regexp) (error "Malformed local variable line: %S" @@ -3409,7 +3422,7 @@ local variables, but directory-local variables may still be applied." (forward-char 1) (let ((read-circle nil)) (setq val (read (current-buffer)))) - (if mode-only + (if (eq handle-mode t) (and (eq var 'mode) ;; Specifying minor-modes via mode: is ;; deprecated, but try to reject them anyway. @@ -3431,6 +3444,7 @@ local variables, but directory-local variables may still be applied." ;; to use 'thisbuf's name in the ;; warning message. (or (buffer-file-name thisbuf) "")))))) + ((and (eq var 'mode) handle-mode)) (t (ignore-errors (push (cons (if (eq var 'eval) @@ -3439,8 +3453,8 @@ local variables, but directory-local variables may still be applied." val) result)))))) (forward-line 1)))))))) ;; Now we've read all the local variables. - ;; If MODE-ONLY is non-nil, return whether the mode was specified. - (if mode-only result + ;; If HANDLE-MODE is t, return whether the mode was specified. + (if (eq handle-mode t) result ;; Otherwise, set the variables. (hack-local-variables-filter result nil) (hack-local-variables-apply))))) @@ -3803,8 +3817,10 @@ This function returns either: ;; The entry MTIME should match the most recent ;; MTIME among matching files. (and cached-files - (= (time-to-seconds (nth 2 dir-elt)) - (apply #'max (mapcar (lambda (f) (time-to-seconds (nth 5 (file-attributes f)))) + (= (float-time (nth 2 dir-elt)) + (apply #'max (mapcar (lambda (f) + (float-time + (nth 5 (file-attributes f)))) cached-files)))))) ;; This cache entry is OK. dir-elt @@ -3846,7 +3862,7 @@ Return the new class name, which is a symbol named DIR." (seconds-to-time (if success (apply #'max (mapcar (lambda (file) - (time-to-seconds (nth 5 (file-attributes file)))) + (float-time (nth 5 (file-attributes file)))) files)) ;; If there was a problem, use the values we could get but ;; don't let the cache prevent future reads. @@ -4304,8 +4320,8 @@ the group would be preserved too." (defun file-name-sans-extension (filename) "Return FILENAME sans final \"extension\". -The extension, in a file name, is the part that follows the last `.', -except that a leading `.', if any, doesn't count." +The extension, in a file name, is the part that begins with the last `.', +except that a leading `.' of the file name, if there is one, doesn't count." (save-match-data (let ((file (file-name-sans-versions (file-name-nondirectory filename))) directory) @@ -4320,15 +4336,16 @@ except that a leading `.', if any, doesn't count." (defun file-name-extension (filename &optional period) "Return FILENAME's final \"extension\". -The extension, in a file name, is the part that follows the last `.', -excluding version numbers and backup suffixes, -except that a leading `.', if any, doesn't count. +The extension, in a file name, is the part that begins with the last `.', +excluding version numbers and backup suffixes, except that a leading `.' +of the file name, if there is one, doesn't count. Return nil for extensionless file names such as `foo'. Return the empty string for file names such as `foo.'. -If PERIOD is non-nil, then the returned value includes the period -that delimits the extension, and if FILENAME has no extension, -the value is \"\"." +By default, the returned value excludes the period that starts the +extension, but if the optional argument PERIOD is non-nil, the period +is included in the value, and in that case, if FILENAME has no +extension, the value is \"\"." (save-match-data (let ((file (file-name-sans-versions (file-name-nondirectory filename)))) (if (and (string-match "\\.[^.]*\\'" file) @@ -5122,7 +5139,7 @@ change the additional actions you can take on files." (defun clear-visited-file-modtime () "Clear out records of last mod time of visited file. -Next attempt to save will certainly not complain of a discrepancy." +Next attempt to save will not complain of a discrepancy." (set-visited-file-modtime 0)) (defun not-modified (&optional arg) @@ -6193,7 +6210,7 @@ and `list-directory-verbose-switches'." PATTERN is assumed to represent a file-name wildcard suitable for the underlying filesystem. For Unix and GNU/Linux, each character from the -set [ \\t\\n;<>&|()`'\"#$] is quoted with a backslash; for DOS/Windows, all +set [ \\t\\n;<>&|()\\=`\\='\"#$] is quoted with a backslash; for DOS/Windows, all the parts of the pattern which don't include wildcard characters are quoted with double quotes. @@ -6568,7 +6585,7 @@ normally equivalent short `-D' option is just passed on to (setq error-lines (nreverse error-lines)) ;; Now read the numeric positions of file names. (goto-char linebeg) - (forward-word 1) + (forward-word-strictly 1) (forward-char 3) (while (< (point) end) (let ((start (insert-directory-adj-pos @@ -6663,11 +6680,14 @@ message to that effect instead of signaling an error." ;; Simulate the message printed by `ls'. (insert (format "%s: No such file or directory\n" file)))) -(defvar kill-emacs-query-functions nil +(defcustom kill-emacs-query-functions nil "Functions to call with no arguments to query about killing Emacs. If any of these functions returns nil, killing Emacs is canceled. `save-buffers-kill-emacs' calls these functions, but `kill-emacs', -the low level primitive, does not. See also `kill-emacs-hook'.") +the low level primitive, does not. See also `kill-emacs-hook'." + :type 'hook + :version "25.2" + :group 'convenience) (defcustom confirm-kill-emacs nil "How to ask for confirmation when leaving Emacs. @@ -6726,7 +6746,8 @@ if any returns nil. If `confirm-kill-emacs' is non-nil, calls it." (defun save-buffers-kill-terminal (&optional arg) "Offer to save each buffer, then kill the current connection. -If the current frame has no client, kill Emacs itself. +If the current frame has no client, kill Emacs itself using +`save-buffers-kill-emacs'. With prefix ARG, silently save all file-visiting buffers, then kill. @@ -6843,8 +6864,8 @@ If CHAR is in [Xugo], the value is taken from FROM (or 0 if omitted)." (cond ((= char ?r) #o0444) ((= char ?w) #o0222) ((= char ?x) #o0111) - ((= char ?s) #o1000) - ((= char ?t) #o6000) + ((= char ?s) #o6000) + ((= char ?t) #o1000) ;; Rights relative to the previous file modes. ((= char ?X) (if (= (logand from #o111) 0) 0 #o0111)) ((= char ?u) (let ((uright (logand #o4700 from))) @@ -6900,7 +6921,7 @@ as in \"og+rX-w\"." (mapcar 'file-modes-char-to-who (match-string 1 modes))))) (when (= num-who 0) - (setq num-who (default-file-modes))) + (setq num-who (logior #o7000 (default-file-modes)))) (setq num-modes (file-modes-rights-to-number (substring modes (match-end 1)) num-who num-modes) @@ -7083,6 +7104,78 @@ Otherwise, trash FILENAME using the freedesktop.org conventions, (let ((delete-by-moving-to-trash nil)) (rename-file fn new-fn))))))))) +(defsubst file-attribute-type (attributes) + "The type field in ATTRIBUTES returned by `file-attribute'. +The value is either t for directory, string (name linked to) for +symbolic link, or nil." + (nth 0 attributes)) + +(defsubst file-attribute-link-number (attributes) + "Return the number of links in ATTRIBUTES returned by `file-attribute'." + (nth 1 attributes)) + +(defsubst file-attribute-user-id (attributes) + "The UID field in ATTRIBUTES returned by `file-attribute'. +This is either a string or a number. If a string value cannot be +looked up, a numeric value, either an integer or a float, is +returned." + (nth 2 attributes)) + +(defsubst file-attribute-group-id (attributes) + "The GID field in ATTRIBUTES returned by `file-attribute'. +This is either a string or a number. If a string value cannot be +looked up, a numeric value, either an integer or a float, is +returned." + (nth 3 attributes)) + +(defsubst file-attribute-access-time (attributes) + "The last access time in ATTRIBUTES returned by `file-attribute'. +This a list of integers (HIGH LOW USEC PSEC) in the same style +as (current-time)." + (nth 4 attributes)) + +(defsubst file-attribute-modification-time (attributes) + "The modification time in ATTRIBUTES returned by `file-attribute'. +This is the time of the last change to the file's contents, and +is a list of integers (HIGH LOW USEC PSEC) in the same style +as (current-time)." + (nth 5 attributes)) + +(defsubst file-attribute-status-change-time (attributes) + "The status modification time in ATTRIBUTES returned by `file-attribute'. +This is the time of last change to the file's attributes: owner +and group, access mode bits, etc, and is a list of integers (HIGH +LOW USEC PSEC) in the same style as (current-time)." + (nth 6 attributes)) + +(defsubst file-attribute-size (attributes) + "The size (in bytes) in ATTRIBUTES returned by `file-attribute'. +This is a floating point number if the size is too large for an integer." + (nth 7 attributes)) + +(defsubst file-attribute-modes (attributes) + "The file modes in ATTRIBUTES returned by `file-attribute'. +This is a string of ten letters or dashes as in ls -l." + (nth 8 attributes)) + +(defsubst file-attribute-inode-number (attributes) + "The inode number in ATTRIBUTES returned by `file-attribute'. +If it is larger than what an Emacs integer can hold, this is of +the form (HIGH . LOW): first the high bits, then the low 16 bits. +If even HIGH is too large for an Emacs integer, this is instead +of the form (HIGH MIDDLE . LOW): first the high bits, then the +middle 24 bits, and finally the low 16 bits." + (nth 10 attributes)) + +(defsubst file-attribute-device-number (attributes) + "The file system device number in ATTRIBUTES returned by `file-attribute'. +If it is larger than what an Emacs integer can hold, this is of +the form (HIGH . LOW): first the high bits, then the low 16 bits. +If even HIGH is too large for an Emacs integer, this is instead +of the form (HIGH MIDDLE . LOW): first the high bits, then the +middle 24 bits, and finally the low 16 bits." + (nth 11 attributes)) + (define-key ctl-x-map "\C-f" 'find-file) (define-key ctl-x-map "\C-r" 'find-file-read-only)