[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
clone buffer that is visiting a file
From: |
xraysmalevich |
Subject: |
clone buffer that is visiting a file |
Date: |
Thu, 4 Sep 2008 05:55:49 -0700 (PDT) |
User-agent: |
G2/1.0 |
If you try to run clone-buffer on a file-visiting buffer, it won't
happen, and you get the error message "Cannot clone a file-visiting
buffer."
I think I understand why -- if you clone a file-visiting buffer, both
buffers are visiting the same file -- and this is more a situation for
an indirect buffer. Is this correct?
But what about situations where you want the entire text of the file-
visiting buffer, the same major mode, but not have it be visiting a
file? Is there any easier way to do this other than copying the entire
buffer and starting from scratch?
I poked around in the the internals of clone-buffer, and it seems to
be happy with copying file-visiting buffers if I turn off the file-
visiting checks AND disable copying local variables. Is this safe? Are
there any reason why I might NOT want to do this?
below is my modified clone-buffer code, with mooning internal
commentary on my suspicious changes:
(defun clone-this-buffer (&optional newname display-flag)
"Create and return a twin copy of the current buffer.
Unlike an indirect buffer, the new buffer can be edited
independently of the old one (if it is not read-only).
NEWNAME is the name of the new buffer. It may be modified by
adding or incrementing <N> at the end as necessary to create a
unique buffer name. If nil, it defaults to the name of the
current buffer, with the proper suffix. If DISPLAY-FLAG is
non-nil, the new buffer is shown with `pop-to-buffer'. Trying to
clone a file-visiting buffer, results in a buffer not tied to a file.
hopefully.
Interactively, DISPLAY-FLAG is t and NEWNAME is the name of the
current buffer with appropriate suffix. However, if a prefix
argument is given, then the command prompts for NEWNAME in the
minibuffer.
This runs the normal hook `clone-buffer-hook' in the new buffer
after it has been set up properly in other respects."
(interactive
(progn
(if (get major-mode 'no-clone)
(error "Cannot clone a buffer in %s mode" mode-name))
(list (if current-prefix-arg
(read-buffer "Name of new cloned buffer: " (current-buffer)))
t)))
(if (get major-mode 'no-clone)
(error "Cannot 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 ((buf (current-buffer))
(ptmin (point-min))
(ptmax (point-max))
(pt (point))
(mk (if mark-active (mark t)))
(modified (buffer-modified-p))
(mode major-mode)
(lvars (buffer-local-variables))
(process (get-buffer-process (current-buffer)))
(new (generate-new-buffer (or newname (buffer-name)))))
(save-restriction
(widen)
(with-current-buffer new
(insert-buffer-substring buf)))
(with-current-buffer new
(narrow-to-region ptmin ptmax)
(goto-char pt)
(if mk (set-mark mk))
(set-buffer-modified-p modified)
;; Clone the old buffer's process, if any.
;; commented-out to avoid file-visiting issues
;; may not be related
;;(when process (clone-process process))
;; Now set up the major mode.
(funcall mode)
;; Set up other local variables.
;;; NOT copying local-vars seems to kill the associations to a
visited file.
;; I think
;; (mapc (lambda (v)
;; (condition-case () ;in case var is read-only
;; (if (symbolp v)
;; (makunbound v)
;; (set (make-local-variable (car v)) (cdr v)))
;; (error nil)))
;; lvars)
;; Run any hooks (typically set up by the major mode
;; for cloning to work properly).
(run-hooks 'clone-buffer-hook))
(if display-flag
;; Presumably the current buffer is shown in the selected
frame, so
;; we want to display the clone elsewhere.
(let ((same-window-regexps nil)
(same-window-buffer-names))
(pop-to-buffer new)))
new))
--the Other michael
- clone buffer that is visiting a file,
xraysmalevich <=