help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: safe way to add contents to a file ?


From: Jean-Christophe Helary
Subject: Re: safe way to add contents to a file ?
Date: Sun, 22 Dec 2019 12:14:04 +0900


> On Dec 21, 2019, at 1:00, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> 
>> (setq myText "<item>bla</item>")
>> (setq myMarker "<!-- place new items before this comment -->")
>> (setq myFile "/path/to/test.xml")
> 
> Being at top-level these aren't just setting the vars but defining them,
> so should use `defvar` or `defconst`.
> 
>> (defun myInsert (myText myMarker myFile)
>>  (save-current-buffer
>>    (set-buffer (find-file-noselect myFile))
> 
> `with-current-buffer` does the same, but shorter ;-)

How is it supposed to be shorter ?

(defun myInsert (myText myMarker myFile)
  (save-current-buffer
    (set-buffer (find-file-noselect myFile))
    (goto-char (point-min))
    (goto-char (- (search-forward myMarker) (length myMarker)))
    (insert myText)
    (indent-region (point-min) (point-max))
    (save-buffer)
    (kill-buffer)))

(defun myInsert2 (myText myMarker myFile)
  (with-current-buffer
      (set-buffer (find-file-noselect myFile))
    (goto-char (point-min))
    (goto-char (- (search-forward myMarker) (length myMarker)))
    (insert myText)
    (indent-region (point-min) (point-max))
    (save-buffer)
    (kill-buffer)))


Honestly, as I read the respective doc strings and reference parts again, I'm 
not even sure why I chose save-current-buffer here anymore, but *because* there 
is no explanatory document on how to do proper file i/o in the Elisp Reference 
it is hard to make informed decisions, or even progress without a lot of 
searching outside the reference.

>>    (goto-char (point-min))
>>    (goto-char (- (search-forward myMarker) (length myMarker)))
> 
> If the search fails, this will signal a "low-level" error, and it's
> often useful to replace it with some other behavior (e.g. an error
> message which the user is more likely to understand, or some other
> behavior), so it's more idiomatic to do something like:
> 
>    (goto-char (point-min))
>    (if (not (search-forward myMarker nil t))
>        (user-error "Can't find foo bar in your fine file")
>      (goto-char (match-beginning 0))

But here, the code would go on inserting the text in a position that's not 
correct, right ?

Isn't it possible to catch the error around the search ? The only language I 
know, AppleScript, has a

try
  body
on error
  do something
end try

block which seems equivalent to "condition-case" but it seems that I'd have to 
use a progn to have the equivalent:

(defun myInsert3 (myText myMarker myFile)
  (save-current-buffer
    (set-buffer (find-file-noselect myFile))
    (goto-char (point-min))
    (condition-case nil
        (progn
          (goto-char (- (search-forward myMarker) (length myMarker)))
          (insert myText)
          (indent-region (point-min) (point-max))
          (save-buffer))
      (error (format "%s was not found" myMarker)))
    (kill-buffer)))

And then the message is not displayed. I just get a "t" which I guess 
corresponds to the successful (kill-buffer)...

And if I put the kill-buffer inside the progn, then I'm left with an open 
buffer that's not relevant anymore...


Jean-Christophe Helary
-----------------------------------------------
http://mac4translators.blogspot.com @brandelune





reply via email to

[Prev in Thread] Current Thread [Next in Thread]