Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

10.4: Edit binary .plist files with emacs UNIX
Tiger only hintAdding this code to your ~/.emacs file makes editing .plist files much less annoying.

(push '(".plist'" . simple-plist-hack) auto-mode-alist)

(defun simple-plist-hack ()
  (when (string-match "`bplist" (buffer-string))
    (shell-command-on-region 
     (point-min) (point-max)
     ;; yes, the temp file is necessary :-(
     (format "plutil -convert xml1 -o /tmp/temp.plist %s; cat /tmp/temp.plist"
       (shell-quote-argument (buffer-file-name)))
     t t))
  (set-buffer-modified-p nil)
  (sgml-mode)) ;; replace this if you have xml-mode installed
[robg adds: I don't use emacs regularly, but tested this one and it worked very nicely -- I created the ~/.emacs file, added the above code, then tried to edit the Safari plist file. It opened in pure text mode, I made a simple change, saved it, then used the Dev Tools' Property List Editor to verify that the change I made was there (which it was, of course).]
    •    
  • Currently 3.20 / 5
  You rated: 3 / 5 (5 votes cast)
 
[11,326 views]  

10.4: Edit binary .plist files with emacs | 15 comments | Create New Account
Click here to return to the '10.4: Edit binary .plist files with emacs' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
vim?
Authored by: mithras on Jun 13, '05 10:08:26AM

Cool. Can anyone cook up a vim equivalent? I'll try to post back with a solution in a day or two if no one else can manage.

---
--
Listen To My iTunes Library (6500+ songs, iTunes 4 required)



[ Reply to This | # ]
vim?
Authored by: Brock Lee on Jun 13, '05 10:40:56AM

Well how about a shell script like this:

#!/bin/sh

if [ $# -ne 1 ] ;then
    echo Usage: $0 file.plist
    exit 1
fi

temp=/tmp/$0.$$
plutil -convert xml1 $1 > $temp
vim $temp
plutil -convert binary1 $temp > $1
rm -f $temp
Please note that I have not tested this.

[ Reply to This | # ]
10.4: Edit binary .plist files with emacs
Authored by: rflo on Jun 13, '05 11:20:13AM
I think the first line of the code should read

(push '("\\.plist\\'" . simple-plist-hack) auto-mode-alist)
and the second line of the function should read

  (when (string-match "^bplist" (buffer-string))

---
Ronald Florence

[ Reply to This | # ]

You Are Right... the Carat "^" is the Correct Character.
Authored by: EatingPie on Jun 13, '05 01:04:03PM

^^


---
-Pie
<http://www.storybytes.com>



[ Reply to This | # ]
Temp File Unnecessary
Authored by: EatingPie on Jun 13, '05 12:58:45PM

Good hint. A nice starting point for a mode... only thing needed is a re-convert to binary for the save function.

That said, my addition: No need for the /tmp/temp.plist file.

Change the "format" command to read like so:


     (format "/usr/bin/plutil -convert xml1 -o /dev/stdout %s"
             (shell-quote-argument (buffer-file-name)))

There you have it.

-Pie

---
-Pie


[ Reply to This | # ]

reconverting (was: Temp File Unnecessary)
Authored by: rflo on Jun 13, '05 01:24:23PM

Eating Pie wrote:

> A nice starting point for a mode... only thing needed is a re-convert
> to binary for the save function.

Actually, reconverting really isn't needed. An application that uses binary .plist files, like Safari, will convert the .plist to binary form the next time it is saved at program exit or when the perferences are changed.

---
Ronald Florence



[ Reply to This | # ]
reconverting (was: Temp File Unnecessary)
Authored by: klktrk on Jun 13, '05 02:25:15PM

That does not always seem to be the case. My sequence:
Closed Safari. Edited binary .plist file in emacs as per hint.
saved the changes in emacs.
opened the com.apple.Safari.plist file in BBEdit, noticed it was in XML text format
opened Safari. Closed Safari
opened the com.apple.Safari.plist file in BBEdit, noticed it was STILL in XML text format.



[ Reply to This | # ]
reconverting (was: Temp File Unnecessary)
Authored by: rflo on Jun 13, '05 02:55:51PM

klktrk writes:

> That does not always seem to be the case. My sequence:
> Closed Safari. Edited binary .plist file in emacs as per hint.
> saved the changes in emacs.
> opened the com.apple.Safari.plist file in BBEdit, noticed it was in XML > text format
> opened Safari. Closed Safari
> opened the com.apple.Safari.plist file in BBEdit, noticed it was STILL > in XML text format.

Look at the modified times on the preferences file. If you changed nothing in Safari, Safari would have no reason to resave the preferences file. When you do change something in Safari, it will save its preferences as a binary XML file.

---
Ronald Florence



[ Reply to This | # ]
reconverting (was: Temp File Unnecessary)
Authored by: GaelicWizard on Jun 13, '05 06:29:19PM

There is no need to convert back to binary, it is an identical representation of the XML. Personally, I would like to change the preference so that ALL plists are back in XML like they were pre-Tiger.

---
Pell



[ Reply to This | # ]
That doesn't work
Authored by: steike on Jun 14, '05 01:10:53PM

It seems to work, but you get a "/dev/stdout: Operation not supported" at the end of the file... notice the comment :-)



[ Reply to This | # ]
Crap!
Authored by: EatingPie on Jun 14, '05 02:13:03PM

Tested my change, and didn't see that.

I'll see if I can come up with a workaround inside emacs.


---
-Pie
<http://www.storybytes.com>



[ Reply to This | # ]
YES! It DOES WORK... Now!
Authored by: EatingPie on Jun 14, '05 04:17:24PM

Take my original...


     (format "/usr/bin/plutil -convert xml1 -o /dev/stdout %s"
             (shell-quote-argument (buffer-file-name)))

And after the close of the "when" statement, add:


  (save-excursion
    (goto-char (point-max))
    (previous-line 1)
    (if (looking-at "/dev/stdout: Operation not supported")
        (kill-line 1)))

Like I said, the temp file is not necessary! :)

---
-Pie


[ Reply to This | # ]

Temp File Unnecessary -- summary
Authored by: chris2 on Oct 30, '05 07:08:02AM
a great tip! as a summary of the other suggestions, and extra code to resave in binary foramt where appropriate: (note 'write-file advise is commented out as an easy way to save as xml instead.

(add-to-list 'auto-mode-alist '(".plist'" . visit-bplist))
(defvar plist-converted-binary nil
  "Buffer local variable indicating if file came from binary-plist.")
(make-variable-buffer-local 'plist-converted-binary)

(defun visit-bplist ()
  (when (string-match "^bplist" (buffer-string))
    (message "Reading in binary plist")
    (shell-command-on-region 
     (point-min) (point-max)
     (format "/usr/bin/plutil -convert xml1 -o /dev/stdout %s"
	     (shell-quote-argument (buffer-file-name))) t t)
    (save-excursion
      (goto-char (point-max)) (previous-line 1)
      (if (looking-at "/dev/stdout: Operation not supported") (kill-line 1)))
    (xml-mode)
    (set-buffer-modified-p nil)
    (setq buffer-undo-list nil)
    (setq plist-converted-binary t)))

(defadvice save-buffer (after convert-plist (&optional args))
  (when plist-converted-binary
    (shell-command
     (format "/usr/bin/plutil -convert binary1 %s"
	     (shell-quote-argument (buffer-file-name))) nil nil)
    (message "Wrote bplist %s" (buffer-file-name))))
(ad-activate 'save-buffer)

;; (defadvice write-file (after convert-plist (filename &optional confirm))
;;   (if plist-converted-binary
;;       (shell-command
;;        (format "/usr/bin/plutil -convert binary1 %s"
;; 	       (shell-quote-argument filename))
;;        nil nil)))
;; (ad-activate 'write-file)


[ Reply to This | # ]
permanently converts binary to xml
Authored by: klktrk on Jun 13, '05 02:20:57PM

Using this modification in emacs will permanently convert your original binary format .plist file to xml format.

Wouldn't it be better to set up e-macs so it would convert the temp file back to binary format again upon finishing your edits?



[ Reply to This | # ]
permanently converts binary to xml
Authored by: GaelicWizard on Jun 13, '05 06:23:22PM

So? Why does it need to be in binary? To save a few k? There's no point to the binary format for preference files (but using CoreData with plists can get big, so binary is faster and smaller in that case).

---
Pell



[ Reply to This | # ]