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

10.4: Edit and save binary plist files in emacs, revisited UNIX
Tiger only hintThis is an alternative method for this hint, which will allow you to edit binary .plist files in Emacs as text. This version will also save them as binary files again, transparently.

First, we need to create a wrapper script for plutil. I put mine in ~/bin, but you can put it wherever you prefer. Here's the contents:
#!/bin/sh

tempfile=/tmp/`basename $0`.$$
touch $tempfile
dd <&0 >$tempfile
plutil $* $tempfile 
dd <$tempfile >&1
All the script does is take data passed to it via standard input and save it to a temporary file, convert the temporary file with the plutil commmand, and write the contents of the file to standard output. This step is necessary because Emacs's auto-compression-mode uses standard output and standard input to pipe data, but plutil only acts on a physical file. (I tried piping to using plutil [arguments] /dev/stdin, but got errors.)

After creating the file, make it executable with this command (replacing /path/to/scriptfile with the actual path to your script):
chmod a+x /path/to/scriptfile
Finally, add this to your .emacs file:
;;; Allow editing of binary .plist files.
(if (null (require 'jka-compr nil t))
    (message "Warning: jka-compr not found.")
  (auto-compression-mode 0)
  (add-to-list 'jka-compr-compression-info-list
               [".plist'" 
                "converting text XML to binary plist" 
                "/path/to/scriptfile" ("-convert binary1") 
                "converting binary plist to text XML"
                "/path/to/scriptfile" ("-convert xml1") 
                nil nil "bplist"])
  (auto-compression-mode 1)
Restart Emacs and open up a binary .plist file. Go ahead and make some changes and save. The file will be updated and remain in binary format. Hope you find this useful.
    •    
  • Currently 3.25 / 5
  You rated: 5 / 5 (4 votes cast)
 
[13,342 views]  

10.4: Edit and save binary plist files in emacs, revisited | 6 comments | Create New Account
Click here to return to the '10.4: Edit and save binary plist files in emacs, revisited' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
10.4: Edit and save binary plist files in emacs, revisited
Authored by: ghinteclinn on Jun 28, '05 04:41:12PM

plutil has -o which specifies an alternate output file (plutil normally operates in place). To cheat a plutil filter I'd do it something like this:

#!/bin/sh
pltmp=/tmp/pltmp-$$
plutil -convert xml1 -o ${pltmp} $1
cat ${pltmp}
rm -f ${pltmp}



[ Reply to This | # ]
10.4: Edit and save binary plist files in emacs, revisited
Authored by: popguru on Jun 28, '05 08:23:50PM

That should work too. Note that your script will only work for opening a binary .plist file as text; to save a file you're editing as text to binary format, you'd need to write another version of the script which uses binary1 instead of xml1.

The cleanup of the temporary file is a good idea...I think I'll add it to my script. :)

[ Reply to This | # ]

10.4: Edit and save binary plist files in emacs, revisited
Authored by: shideg on Jul 19, '05 04:20:15PM

What about

#!/bin/sh
plutil -convert xml1 -o /dev/stdout $1



[ Reply to This | # ]
10.4: Edit and save binary plist files in emacs, revisited
Authored by: rflo on Jun 28, '05 05:31:36PM

If I read this code correctly, it will save all .plist files in binary format, including those that were originally in XML format. This would not be a desirable behavior for an editor, as many .plist files -- such as those used for launchd daemons -- need to be saved in XML format to work properly.

Apologies if I've misread the code.

---
Ronald Florence



[ Reply to This | # ]
10.4: Edit and save binary plist files in emacs, revisited
Authored by: popguru on Jun 28, '05 08:14:15PM
You're correct. Unfortunately, i didn't think of this when I figured out the code. However, you can run the
auto-compression-mode
command to disable compression mode, and then any .plist file you have open will be saved in text format until you re-enable compression-mode using the same command, or restart Emacs. I don't know if there's a way for Emacs to remember whether a file was opened using compression mode or not...anybody have any ideas?

[ Reply to This | # ]
10.4: leaving Xml plists as Xml
Authored by: chris2 on Oct 30, '05 01:48:58PM
It appears jka-compr only uses magic numbers (ie. "bplist") when saving a file to see if it has already been compressed. Thus there is no way to use it as is to discriminate between original-xml and original-binary plists. One could modify jka-compr to check files before uncompressing, and accordingly set a flag to recompress on write. (perhaps an extra state of 'jka-compr-really-do-compress') This could conflict with other compression modes with optional magic numbers. Since is the first filetype with the same extension for both formats, it may be easier to just extend the previous hint than to generalize jka-compr. So here is a .emacs snippet that recognizes both formats and reconverts only initially-binary files on save:

(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 | # ]