Ticket #90 (assigned defect)

Opened 1 year ago

Last modified 1 year ago

Editor silently lets you clobber changed file

Reported by: gz Assigned to: gb (accepted)
Priority: major Milestone:
Component: IDE Version:
Keywords: Cc:

Description

Open a file in the IDE. Open the same file in emacs, make a change, save it. Now make a change in the IDE and save it -- it quietly overwrites the changes you made in emacs. It should notice the change and confirm whether you want to overwrite it

Change History

08/29/07 15:24:08 changed by gb

  • status changed from new to assigned.

When something similar happens and TextEdit? is involved (e.g., open file in TextEdit?, open and modify in Emacs, try to save in TextEdit?), TextEdit? notices that the file's been renamed (to "foo.lisp~" or whatever Emacs renamed the original to while saving).

If the file's externally deleted, trying to save in TextEdit? claims that the document's location can't be determined.

If the file's deleted and then recreated externally, saving in TextEdit? notices that the file's been modified and pops up an alert.

08/31/07 17:07:57 changed by gb

Scarily enough, this seems to work sometimes. (It all should be "free" NSDocument behavior.)

When it works, the document maintains an FSRef to the original pathname. If the file is renamed, the new name is reflected in the window title (and attempts to save the document note this fact and ask for confirmation.)

Whether it works or not may have something to do with how the editor document is created. I've seen it "work" (maintain the FSRef that enables it to detect these kinds of changes) when the document was opened via "Open Recent ..."; I've seen it fail some times as well, and don't yet know what the determining factors are.

08/31/07 17:58:51 changed by gb

Here's a little function that loops over all Hemlock buffers, trying to peek inside the private data structure associated with the buffer's documents that tracks changes to the represented file:

(defun show-tracking-info () 
  (do* ((buffers (cdr hi::*buffer-list*) (cddr buffers)))
     ((null buffers))
  (let* ((doc (hi::buffer-document (car buffers))))
    (when doc
      (format t "~%~%~s~%~s" (car buffers) doc)
      (let* ((info (pref doc :<NSD>ocument._private<D>ata)))
      (loop for i from 2 to 5 do (print (paref info (:* :id) i))))))))

NOTE: I've tried this on PPC32; it may not work on x86-64.

For some buffers, the output looks like:

#<Hemlock Buffer "modeline.lisp /usr/local/src/ccl/cocoa-ide/hemlock/src/">
#<HEMLOCK-EDITOR-DOCUMENT <HemlockEditorDocument: 0x97fa00> (#x97FA00)>
#<NS-OBJECT <NSFileSpecifier: 0x86f440b0> (#x86F440B0)> 
#<NS-OBJECT <NSFileSpecifier: 0x86f44110> (#x86F44110)> 
#<NS-STRING "modeline.lisp" (#x86F44170)> 
#<NS-DATE 2007-08-21 00:07:38 -0600 (#x85AF0670)> 

But for others, it looks like:

#<Hemlock Buffer "lispmode.lisp /usr/local/src/ccl/cocoa-ide/hemlock/src/">
#<HEMLOCK-EDITOR-DOCUMENT <HemlockEditorDocument: 0x91ac00> (#x91AC00)>
#<A Null Foreign Pointer> 
#<A Null Foreign Pointer> 
#<A Null Foreign Pointer> 
#<NS-DATE 2007-08-29 15:30:55 -0600 (#x85AE36F0)> 

The missing NSFileSpecifiers (which I assume are just wrappers around FSSpecs) seem to cause the problem, but I don't know why they're present in some cases but missing in others.