Function: find-alternate-file

find-alternate-file is an interactive and byte-compiled function defined in files.el.gz.

Signature

(find-alternate-file FILENAME &optional WILDCARDS)

Documentation

Find file FILENAME, select its buffer, kill previous buffer.

If the current buffer now contains an empty file that you just visited
(presumably by mistake), use this command to visit the file you really want.

See C-x C-f (find-file) for the possible forms of the FILENAME argument.

Interactively, or if WILDCARDS is non-nil in a call from Lisp, expand wildcards (if any) and replace the file with multiple files.

If the current buffer is an indirect buffer, or the base buffer for one or more indirect buffers, the other buffer(s) are not killed.

View in manual

Probably introduced at or before Emacs version 1.9.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/files.el.gz
(defun find-alternate-file (filename &optional wildcards)
  "Find file FILENAME, select its buffer, kill previous buffer.
If the current buffer now contains an empty file that you just visited
\(presumably by mistake), use this command to visit the file you really want.

See \\[find-file] for the possible forms of the FILENAME argument.

Interactively, or if WILDCARDS is non-nil in a call from Lisp,
expand wildcards (if any) and replace the file with multiple files.

If the current buffer is an indirect buffer, or the base buffer
for one or more indirect buffers, the other buffer(s) are not
killed."
  (interactive
   (let ((file buffer-file-name)
	 (file-name nil)
	 (file-dir nil))
     (and file
	  (setq file-name (file-name-nondirectory file)
		file-dir (file-name-directory file)))
     (list (read-file-name
	    "Find alternate file: " file-dir nil
            (confirm-nonexistent-file-or-buffer) file-name)
	   t)))
  (unless (run-hook-with-args-until-failure 'kill-buffer-query-functions)
    (user-error "Aborted"))
  (and (buffer-modified-p) buffer-file-name
       (not (yes-or-no-p
             (format-message "Kill and replace buffer `%s' without saving it? "
                             (buffer-name))))
       (user-error "Aborted"))
  (let ((obuf (current-buffer))
	(ofile buffer-file-name)
	(onum buffer-file-number)
	(odir dired-directory)
	(otrue buffer-file-truename)
	(oname (buffer-name)))
    ;; Run `kill-buffer-hook' here.  It needs to happen before
    ;; variables like `buffer-file-name' etc are set to nil below,
    ;; because some of the hooks that could be invoked
    ;; (e.g., `save-place-to-alist') depend on those variables.
    ;;
    ;; Note that `kill-buffer-hook' is not what queries whether to
    ;; save a modified buffer visiting a file.  Rather, `kill-buffer'
    ;; asks that itself.  Thus, there's no need to temporarily do
    ;; `(set-buffer-modified-p nil)' before running this hook.
    (let ((find-alternate-file-dont-kill-client 'dont-kill-client))
      (run-hooks 'kill-buffer-hook))
    ;; Okay, now we can end-of-life the old buffer.
    (if (get-buffer " **lose**")
	(kill-buffer " **lose**"))
    (rename-buffer " **lose**")
    (unwind-protect
	(progn
	  (unlock-buffer)
	  ;; This prevents us from finding the same buffer
	  ;; if we specified the same file again.
	  (setq buffer-file-name nil)
	  (setq buffer-file-number nil)
	  (setq buffer-file-truename nil)
	  ;; Likewise for dired buffers.
	  (setq dired-directory nil)
          ;; Don't use `find-file' because it may end up using another window
          ;; in some corner cases, e.g. when the selected window is
          ;; softly-dedicated.
	  (let ((newbuf (find-file-noselect filename nil nil wildcards)))
            (switch-to-buffer (if (consp newbuf) (car newbuf) newbuf))))
      (when (eq obuf (current-buffer))
	;; This executes if find-file gets an error
	;; and does not really find anything.
	;; We put things back as they were.
	;; If find-file actually finds something, we kill obuf below.
	(setq buffer-file-name ofile)
	(setq buffer-file-number onum)
	(setq buffer-file-truename otrue)
	(setq dired-directory odir)
	(lock-buffer)
        (if (get-buffer oname)
            (kill-buffer oname))
	(rename-buffer oname)))
    (unless (eq (current-buffer) obuf)
      (with-current-buffer obuf
	;; Restore original buffer's file names so they can be still
	;; used when referencing the now defunct buffer (Bug#68235).
	(setq buffer-file-name ofile)
	(setq buffer-file-number onum)
	(setq buffer-file-truename otrue)
	(unless (get-buffer oname)
	  ;; Restore original's buffer name so 'kill-buffer' can use it
	  ;; to assign its last name (Bug#68235).
	  (rename-buffer oname))
	;; We already ran these; don't run them again.
	(let (kill-buffer-query-functions kill-buffer-hook)
	  (kill-buffer obuf))))))