all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* clone buffer that is visiting a file
@ 2008-09-04 12:55 xraysmalevich
  2008-09-05  1:45 ` Kevin Rodgers
       [not found] ` <mailman.18481.1220579126.18990.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 3+ messages in thread
From: xraysmalevich @ 2008-09-04 12:55 UTC (permalink / raw)
  To: help-gnu-emacs

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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2008-09-05 13:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-04 12:55 clone buffer that is visiting a file xraysmalevich
2008-09-05  1:45 ` Kevin Rodgers
     [not found] ` <mailman.18481.1220579126.18990.help-gnu-emacs@gnu.org>
2008-09-05 13:44   ` xraysmalevich

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.