diff options
Diffstat (limited to 'lisp/dired.el')
-rw-r--r-- | lisp/dired.el | 151 |
1 files changed, 132 insertions, 19 deletions
diff --git a/lisp/dired.el b/lisp/dired.el index e4bc4decf84..08b19a02250 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1504,7 +1504,7 @@ see `dired-use-ls-dired' for more details.") ;; "--dired", so we cannot add it to the `process-file' ;; call for wildcards. (when (file-remote-p dir) - (setq switches (dired-replace-in-string "--dired" "" switches))) + (setq switches (string-replace "--dired" "" switches))) (let* ((default-directory (car dir-wildcard)) (script (format "ls %s %s" switches (cdr dir-wildcard))) (remotep (file-remote-p dir)) @@ -2585,6 +2585,21 @@ Otherwise, display it in another buffer." ;;; Functions for extracting and manipulating file names in Dired buffers. +(defun dired-unhide-subdir () + (with-silent-modifications + (dired--unhide (dired-subdir-min) (dired-subdir-max)))) + +(defun dired-subdir-hidden-p (dir) + (save-excursion + (dired-goto-subdir dir) + (dired--hidden-p))) + +(defun dired-subdir-min () + (save-excursion + (if (not (dired-prev-subdir 0 t t)) + (error "Not in a subdir!") + (point)))) + (defun dired-get-filename (&optional localp no-error-if-not-filep) "In Dired, return name of file mentioned on this line. Value returned normally includes the directory name. @@ -2595,10 +2610,17 @@ it occurs in the buffer, and a value of t means construct name relative to Optional arg NO-ERROR-IF-NOT-FILEP means treat `.' and `..' as regular filenames and return nil if no filename on this line. Otherwise, an error occurs in these cases." - (let (case-fold-search file p1 p2 already-absolute) + (let ((hidden (and dired-subdir-alist + (dired-subdir-hidden-p + (dired-current-directory)))) + case-fold-search file p1 p2 already-absolute) + (when hidden + (dired-unhide-subdir)) (save-excursion (if (setq p1 (dired-move-to-filename (not no-error-if-not-filep))) (setq p2 (dired-move-to-end-of-filename no-error-if-not-filep)))) + (when hidden + (dired-hide-subdir 1)) ;; nil if no file on this line, but no-error-if-not-filep is t: (if (setq file (and p1 p2 (buffer-substring p1 p2))) (progn @@ -4040,10 +4062,10 @@ only in the active region if `dired-mark-region' is non-nil." (if fn (backup-file-name-p fn)))) "backup file"))) -(defun dired-change-marks (old new) +(defun dired-change-marks (&optional old new) "Change all OLD marks to NEW marks. OLD and NEW are both characters used to mark files." - (declare (advertised-calling-convention '(old new) "28.1")) + (declare (advertised-calling-convention (old new) "28.1")) (interactive (let* ((cursor-in-echo-area t) (old (progn (message "Change (old mark): ") (read-char))) @@ -4205,22 +4227,50 @@ format, use `\\[universal-argument] \\[dired]'.") "Non-nil means the Dired sort command is disabled. The idea is to set this buffer-locally in special Dired buffers.") +(defcustom dired-switches-in-mode-line nil + "How to indicate `dired-actual-switches' in mode-line. +Possible values: + * `nil': Indicate name-or-date sort order, if possible. + Else show full switches. + * `as-is': Show full switches. + * Integer: Show only the first N chars of full switches. + * Function: Pass `dired-actual-switches' as arg and show result." + :group 'Dired-Plus + :type '(choice + (const :tag "Indicate by name or date, else full" nil) + (const :tag "Show full switches" as-is) + (integer :tag "Show first N chars of switches" :value 10) + (function :tag "Format with function" :value identity))) + (defun dired-sort-set-mode-line () - ;; Set mode line display according to dired-actual-switches. - ;; Mode line display of "by name" or "by date" guarantees the user a - ;; match with the corresponding regexps. Non-matching switches are - ;; shown literally. + "Set mode-line according to option `dired-switches-in-mode-line'." (when (eq major-mode 'dired-mode) (setq mode-name - (let (case-fold-search) - (cond ((string-match-p - dired-sort-by-name-regexp dired-actual-switches) - "Dired by name") - ((string-match-p - dired-sort-by-date-regexp dired-actual-switches) - "Dired by date") - (t - (concat "Dired " dired-actual-switches))))) + (let ((case-fold-search nil)) + (if dired-switches-in-mode-line + (concat + "Dired" + (cond ((integerp dired-switches-in-mode-line) + (let* ((l1 (length dired-actual-switches)) + (xs (substring + dired-actual-switches + 0 (min l1 dired-switches-in-mode-line))) + (l2 (length xs))) + (if (zerop l2) + xs + (concat " " xs (and (< l2 l1) "…"))))) + ((functionp dired-switches-in-mode-line) + (format " %s" (funcall + dired-switches-in-mode-line + dired-actual-switches))) + (t (concat " " dired-actual-switches)))) + (cond ((string-match-p dired-sort-by-name-regexp + dired-actual-switches) + "Dired by name") + ((string-match-p dired-sort-by-date-regexp + dired-actual-switches) + "Dired by date") + (t (concat "Dired " dired-actual-switches)))))) (force-mode-line-update))) (define-obsolete-function-alias 'dired-sort-set-modeline @@ -4268,11 +4318,10 @@ With a prefix argument, edit the current listing switches instead." (dired-sort-set-mode-line) (revert-buffer)) -;; Some user code loads dired especially for this. -;; Don't do that--use replace-regexp-in-string instead. (defun dired-replace-in-string (regexp newtext string) ;; Replace REGEXP with NEWTEXT everywhere in STRING and return result. ;; NEWTEXT is taken literally---no \\DIGIT escapes will be recognized. + (declare (obsolete replace-regexp-in-string "28.1")) (let ((result "") (start 0) mb me) (while (string-match regexp string start) (setq mb (match-beginning 0) @@ -4475,6 +4524,70 @@ Ask means pop up a menu for the user to select one of copy, move or link." (add-to-list 'desktop-buffer-mode-handlers '(dired-mode . dired-restore-desktop-buffer)) + +;;;; Jump to Dired + +(defvar archive-superior-buffer) +(defvar tar-superior-buffer) + +;;;###autoload +(defun dired-jump (&optional other-window file-name) + "Jump to Dired buffer corresponding to current buffer. +If in a file, Dired the current directory and move to file's line. +If in Dired already, pop up a level and goto old directory's line. +In case the proper Dired file line cannot be found, refresh the dired +buffer and try again. +When OTHER-WINDOW is non-nil, jump to Dired buffer in other window. +When FILE-NAME is non-nil, jump to its line in Dired. +Interactively with prefix argument, read FILE-NAME." + (interactive + (list nil (and current-prefix-arg + (read-file-name "Jump to Dired file: ")))) + (cond + ((and (bound-and-true-p archive-subfile-mode) + (buffer-live-p archive-superior-buffer)) + (switch-to-buffer archive-superior-buffer)) + ((and (bound-and-true-p tar-subfile-mode) + (buffer-live-p tar-superior-buffer)) + (switch-to-buffer tar-superior-buffer)) + (t + ;; Expand file-name before `dired-goto-file' call: + ;; `dired-goto-file' requires its argument to be an absolute + ;; file name; the result of `read-file-name' could be + ;; an abbreviated file name (Bug#24409). + (let* ((file (or (and file-name (expand-file-name file-name)) + buffer-file-name)) + (dir (if file (file-name-directory file) default-directory))) + (if (and (eq major-mode 'dired-mode) (null file-name)) + (progn + (setq dir (dired-current-directory)) + (dired-up-directory other-window) + (unless (dired-goto-file dir) + ;; refresh and try again + (dired-insert-subdir (file-name-directory dir)) + (dired-goto-file dir))) + (if other-window + (dired-other-window dir) + (dired dir)) + (if file + (or (dired-goto-file file) + ;; refresh and try again + (progn + (dired-insert-subdir (file-name-directory file)) + (dired-goto-file file)) + ;; Toggle omitting, if it is on, and try again. + (when (bound-and-true-p dired-omit-mode) + (dired-omit-mode) + (dired-goto-file file))))))))) + +;;;###autoload +(defun dired-jump-other-window (&optional file-name) + "Like \\[dired-jump] (`dired-jump') but in other window." + (interactive + (list (and current-prefix-arg + (read-file-name "Jump to Dired file: ")))) + (dired-jump t file-name)) + (provide 'dired) (run-hooks 'dired-load-hook) ; for your customizations |