I'm trying to programmatically define the windows in my frame. I have 4 windows, two with dired buffers in them so that I can select the file I want to visit.
(delete-other-windows)
(split-window-horizontally)
(dired ".")
(split-window-vertically)
(find-file "test.txt")
(other-window -1)
(split-window-vertically)
(dired ".")
(other-window -1)
+-----------+-----------+
| | |
| | |
| test.txt | dired |
| | |
| | |
+-----------+-----------+
| | |
| dired | whatever |
| | |
| | |
+-----------+-----------+
To open a file in the current dired buffer, I set (put 'dired-find-alternate-file 'disabled nil)
to disable the warning and select the file I want with a
(dired-find-alternate-file
). When I do this, however, it kills the other dired buffer I have open. It seems that dired can only have one buffer per directory.
How can I have two dired buffers for the same directory, but kill each of them independently?
edit
Using indirect buffers, I can get what I want, but it ain't pretty. Good gravy, is there a better way?
(defun my-clone-indirect-buffer-same-window (newname display-flag &optional norecord)
"A copy-paste of clone-indirect-buffer, but with pop-to-buffer
changed to pop-to-buffer-same-window."
(interactive
(progn
(if (get major-mode 'no-clone-indirect)
(error "Cannot indirectly clone a buffer in %s mode" mode-name))
(list (if current-prefix-arg
(read-buffer "Name of indirect buffer: " (current-buffer)))
t)))
(if (get major-mode 'no-clone-indirect)
(error "Cannot indirectly clone a buffer in %s mode" mode-name))
(setq newname (or newname (buffer-name)))
(if (string-match "<[0-9]+>\\'" newname)
(setq newname (substring newname 0 (match-beginning 0))))
(let* ((name (generate-new-buffer-name newname))
(buffer (make-indirect-buffer (current-buffer) name t)))
(with-current-buffer buffer
(run-hooks 'clone-indirect-buffer-hook))
(when display-flag
(pop-to-buffer-same-window buffer norecord))
buffer))
(delete-other-windows)
(split-window-horizontally)
(dired ".")
(split-window-vertically)
(find-file "test.txt")
(other-window -1)
(split-window-vertically)
(switch-to-buffer (cdr (car dired-buffers)))
(my-clone-indirect-buffer-same-window nil t)
(other-window -1)
edit2
Based on Drew's answer, the following does what I asked:
(setq my-root ".")
(setq my-main "test.txt")
(delete-other-windows)
(split-window-horizontally)
(dired my-root)
(split-window-vertically)
(find-file my-main)
(other-window -1)
(split-window-vertically)
;; creates a new buffer with same name as my-root containing
;; a snapshot of the file listing
(dired (cons my-root (directory-files my-root)))
(other-window -1)
C-u M-x dired RET RET
asks aboutls
flags, but the buffer it creates is not independent: if I kill it, any other dired buffer for the same directory also disappears. You can create indirect buffers but AFAIK, there is a single buffer for any one file or directory, so when that buffer is killed, it disappears from all windows that display it.C-h i g(elisp)indirect buffers
.*foo*
", "*foo<01>*
", "*foo<02>*
". That way, there would be no need for an indirect buffer. [PS: You can programmatically create new windows above, below, left, right.]