Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add support 'plistutil'
  • Loading branch information
darfink committed Jun 12, 2020
1 parent 67280fb commit 0d8a2aa
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 55 deletions.
27 changes: 10 additions & 17 deletions README.md
Expand Up @@ -2,15 +2,17 @@

![Screenshot of vim-plist in action](http://i.imgur.com/ezBKTK7.png)

This vim bundle adds complete support for [property lists](http://en.wikipedia.org/wiki/Property_list) (*plist*) files on OS X.
This vim bundle adds complete support for [property lists](plist) (*plist*)
files.

The plugin uses the underlying **plutil** tool for manipulating property lists.
It supports reading and writing in *binary*, *xml* and *json* formats.
The plugin uses the underlying **plutil** (or **plistutil**) tool for
manipulating property lists. It supports reading and writing in *binary*,
*xml* and *json* formats.

## Requirements

- Vim 7.2 or later
- plutil (bundled with OS X)
- Vim 7.4 or later
- plutil (bundled with macOS) or [plistutil](libplist)

## Installation

Expand Down Expand Up @@ -68,17 +70,6 @@ options availabe.
opened. If you want to override this and always save property lists in a
specific format, you can use *json*, *xml* or *binary* format.

- Change the filetype used for property lists in *json* format:

```vim
let g:plist_json_filetype = 'javascript'
```

Vim does not have inherent support for *json* files (it reverts to
*JavaScript* syntax). If you do want a specific filetype for *json* property
lists, when using a json plugin (such as [vim-json][vim-json]), you can
specify *json* as the filetype instead.

## Notes

If you want syntax checking I highly recommend [Syntastic][syntastic] since it
Expand All @@ -90,7 +81,7 @@ uses the underlying Vim *write* function which bypasses the plugins
`BufWriteCmd` and `FileWriteCmd` hooks.

This does not add *plist* as a new filetype, but merely conversion
functionality between the different representible formats.
functionality between the different representable formats.

## Todo

Expand All @@ -109,3 +100,5 @@ MIT: [License][license]
[vim-json]: https://github.com/elzr/vim-json
[syntastic]: https://github.com/scrooloose/syntastic
[license]: https://github.com/darfink/vim-plist/blob/master/LICENSE
[libplist]: https://github.com/libimobiledevice/libplist
[plist]: http://en.wikipedia.org/wiki/Property_list
89 changes: 57 additions & 32 deletions autoload/plist.vim
Expand Up @@ -4,28 +4,53 @@

" Defines the mapping between the vim-plist options and plutil arguments
let s:mapping = { 'json': 'json', 'binary': 'binary1', 'xml': 'xml1' }
let s:mapping_util = { 'binary': 'bin', 'xml': 'xml' }
let s:has_plist = executable('plutil')
let s:has_plistutil = executable('plistutil')

function! s:warn(message)
echohl WarningMsg
let blackhole = input(a:message . ' (Press ENTER)')
echohl None
endfunction

function! plist#Read(bufread)
" Get the filename of the current argument
let filename = expand('<afile>')

" If the file does not exist, there is nothing to convert
if !filereadable(filename)
" We simply leave the buffer handling to Vim
silent execute ':doautocmd BufNewFile ' . fnameescape(filename)
silent execute 'doautocmd BufNewFile ' . fnameescape(filename)
return
endif

if !s:has_plist && !s:has_plistutil
echoerr 'plutil is not found in $PATH'
silent execute 'read ' . fnameescape(filename)
return
endif

" Convert the file's content directly, and read it into the current buffer
execute 'silent read !plutil -convert ' . s:mapping[g:plist_display_format] .
\ ' -r ' . shellescape(filename, 1) . ' -o -'
" Determine which format should be used when saving
let b:plist_original_format = plist#DetectFormat(filename)

" Convert the file's content and read it into the current buffer
if s:has_plist
execute 'silent read !plutil -convert ' . s:mapping[g:plist_display_format]
\ . ' -r ' . shellescape(filename, 1) . ' -o -'
else
if g:plist_display_format == 'json'
call s:warn('Plistutil does not support json display format')
endif

execute 'silent read !plistutil -f xml -i ' . shellescape(filename, 1) . ' -o -'
endif

let b:read_error = v:shell_error != 0

if (v:shell_error)
echohl WarningMsg
let blackhole = input('Plist could not be converted! (Press ENTER)')
echohl None
call s:warn('Plist could not be converted!')

" Only wipeout the buffer if we were creating one to start with.
" Only wipeout the buffer if one was being created to start with.
" FileReadCmd just reads the content into the existing buffer
if a:bufread
silent bwipeout!
Expand All @@ -34,33 +59,36 @@ function! plist#Read(bufread)
return
endif

" We need to know in which format we should save the file
call plist#DetectFormat(filename)

" Tell the user about any information we've parsed
" Tell the user about any information parsed
call plist#DisplayInfo(filename, b:plist_original_format)
endfunction

function! plist#Write()
" Cache the argument filename destination
let filename = resolve(expand('<afile>'))

" If the user has not specified his preferred format when saving, we use the
" same format as the filed had originally. Otherwise the user option takes
" If the user has not specified his preferred format when saving, use the
" same format as the file had originally. Otherwise the user option takes
" precedence.
let save_format = !len(g:plist_save_format) ? b:plist_original_format : g:plist_save_format

" Use plutil even when the current format is the same as the target format,
" since it will give the user additional error checking (he will be notified
" if there is any error upon saving).
execute "silent '[,']write !plutil -convert " . s:mapping[save_format] .
\ ' - -o ' . shellescape(filename, 1)
if s:has_plist
" Use plutil even when the current format is the same as the target
" format, since it will give the user additional error checking (they will
" be notified if there is any error upon saving).
execute "silent '[,']write !plutil -convert " . s:mapping[save_format] .
\ ' - -o ' . shellescape(filename, 1)
else
if b:plist_original_format == 'json'
call s:warn('Plistutil cannot process json, saving buffer contents directly')
else
execute "silent '[,']write !plistutil -f " . s:mapping_util[save_format] .
\ ' -i - -o ' . shellescape(filename, 1)
endif
endif

if (v:shell_error)
echohl WarningMsg
let blackhole = input('Plist could not be saved! (Press ENTER)')
echohl None

call s:warn('Plist could not be saved!')
return
else
" Give the user visual feedback about the write
Expand All @@ -83,12 +111,9 @@ function! plist#ReadPost()
endfunction

function! plist#SetFiletype()
if g:plist_display_format == 'json'
" There is no specific support for json bundled with Vim, so we let the
" user decide the filetype (by default we assume 'JavaScript').
execute 'set filetype=' . g:plist_json_filetype
if g:plist_display_format == 'json' && s:has_plist || b:plist_original_format == 'json' && !s:has_plist
execute 'set filetype=' . (len(getcompletion('json', 'filetype')) ? 'json' : 'javascript')
else
" We hardcode this to xml, since it maps one-to-one
set filetype=xml
endif
endfunction
Expand All @@ -97,11 +122,11 @@ function! plist#DetectFormat(filename)
let content = readfile(a:filename, 1, 2)

if len(content) > 0 && content[0] =~ "^bplist"
let b:plist_original_format = 'binary'
return 'binary'
elseif len(content) > 1 && content[1] =~ '^<!DOCTYPE plist'
let b:plist_original_format = 'xml'
return 'xml'
else
let b:plist_original_format = 'json'
return 'json'
endif
endfunction

Expand Down
6 changes: 0 additions & 6 deletions plugin/plist.vim
Expand Up @@ -32,9 +32,3 @@ if !exists('g:plist_save_format')
" Available options are: xml, json & binary
let g:plist_save_format = ''
end

if !exists('g:plist_json_filetype')
" Controls the filetype used for json plists (JavaScript is what Vim uses by
" default for these filetypes).
let g:plist_json_filetype = 'javascript'
end

0 comments on commit 0d8a2aa

Please sign in to comment.