Skip to content

Commit

Permalink
Implement "scratch" and "tempfile" proxy types
Browse files Browse the repository at this point in the history
Thanks to @fewaffles for most of the implementation.
  • Loading branch information
AndrewRadev committed Sep 2, 2012
1 parent d8f04f5 commit 10d396c
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 25 deletions.
79 changes: 55 additions & 24 deletions autoload/inline_edit/proxy.vim
Expand Up @@ -12,13 +12,18 @@ function! inline_edit#proxy#New(controller, start_line, end_line, filetype, inde
\ 'UpdateOtherProxies': function('inline_edit#proxy#UpdateOtherProxies'),
\ }

let [lines, position] = s:LoadContents(proxy)
call s:CreateBuffer(proxy, lines)
call s:UpdateBuffer(proxy)
let [lines, position] = s:LoadOriginalBufferContents(proxy)
call s:CreateProxyBuffer(proxy, lines)
call s:UpdateProxyBuffer(proxy)
call s:SetStatusline(proxy)
call s:PositionCursor(proxy, position)

" On writing proxy buffer, update original one
autocmd BufWritePost <buffer> silent call b:proxy.UpdateOriginalBuffer()
if g:inline_edit_proxy_type == 'scratch'
autocmd BufWriteCmd <buffer> silent call b:proxy.UpdateOriginalBuffer()
elseif g:inline_edit_proxy_type == 'tempfile'
autocmd BufWritePost <buffer> silent call b:proxy.UpdateOriginalBuffer()
endif

return proxy
endfunction
Expand All @@ -43,6 +48,7 @@ function! inline_edit#proxy#UpdateOriginalBuffer() dict

" Switch to the original buffer, delete the relevant lines, add the new
" ones, switch back to the diff buffer.
setlocal nomodified
exe 'buffer ' . self.original_buffer

call inline_edit#PushCursor()
Expand All @@ -63,15 +69,16 @@ function! inline_edit#proxy#UpdateOriginalBuffer() dict
let new_line_count = len(new_lines)

let self.end = self.start + new_line_count - 1
call s:UpdateBuffer(self)
call s:UpdateProxyBuffer(self)

call inline_edit#PopCursor() " in proxy buffer

call self.controller.SyncProxies(self, new_line_count - line_count)
endfunction

" Collect data from original buffer
function! s:LoadContents(proxy)
" Called once upon setup. Returns the lines from the original buffer and the
" position of the cursor in that buffer.
function! s:LoadOriginalBufferContents(proxy)
let proxy = a:proxy
let position = getpos('.')
let lines = []
Expand All @@ -83,46 +90,70 @@ function! s:LoadContents(proxy)
return [lines, position]
endfunction

" Create proxy buffer
function! s:CreateBuffer(proxy, lines)
" Called once upon setup. Creates the actual buffer and writes the given lines
" to it.
function! s:CreateProxyBuffer(proxy, lines)
let proxy = a:proxy
let lines = a:lines

exe 'silent split ' . tempname()

" avoid warnings
let saved_readonly = &readonly
let &readonly = 0

call append(0, lines)
$delete _
write
if g:inline_edit_proxy_type == 'scratch'
exe 'silent new'
setlocal buftype=acwrite
setlocal bufhidden=hide
call append(0, lines)
$delete _
set nomodified

let original_bufname = bufname(proxy.original_buffer)
let filename = printf('[%s:%d-%d]', original_bufname, proxy.start, proxy.end)
silent exec 'keepalt file ' . filename
elseif g:inline_edit_proxy_type == 'tempfile'
exe 'silent split ' . tempname()
call append(0, lines)
$delete _
write
endif

let &readonly = saved_readonly

set foldlevel=99
let proxy.proxy_buffer = bufnr('%')
endfunction

let &readonly = saved_readonly
" Called once upon setup and then after every write. After the actual updating
" logic is finished, this sets up some needed buffer properties.
function! s:UpdateProxyBuffer(proxy)
let b:proxy = a:proxy

if proxy.filetype == ''
if a:proxy.filetype == ''
" attempt autodetection
filetype detect
let proxy.filetype = &filetype
let a:proxy.filetype = &filetype
endif
let &filetype = proxy.filetype
endfunction

function! s:UpdateBuffer(proxy)
let b:proxy = a:proxy
let &filetype = a:proxy.filetype
endfunction

" Called once upon setup. Manipulates the statusline to show information for
" the proxy. Does nothing if the proxy type is not "tempfile"
function! s:SetStatusline(proxy)
if g:inline_edit_proxy_type != 'tempfile'
return
endif

" TODO don't clobber the statusline after saving
let statusline = printf('[%s:%%{b:proxy.start}-%%{b:proxy.end}]', bufname(b:proxy.original_buffer))
let statusline = printf('[%s:%%{b:proxy.start}-%%{b:proxy.end}]', bufname(a:proxy.original_buffer))
if &statusline =~ '%[fF]'
let statusline = substitute(&statusline, '%[fF]', statusline, '')
endif
exe "setlocal statusline=" . escape(statusline, ' |')
endfunction

" Position cursor correctly
" Called once upon setup. Positions the cursor where it was in the original
" buffer, relative to the extracted contents.
function! s:PositionCursor(proxy, position)
let proxy = a:proxy
let position = a:position
Expand Down
21 changes: 21 additions & 0 deletions doc/inline_edit.txt
Expand Up @@ -158,6 +158,27 @@ those as well.
The reason for this is to be able to extend the plugin easier in this specific
case (editing an html-like filetype).

*b:inline_edit_proxy_type*
>
let b:inline_proxy_type = 'tempfile'
<

Default value: "scratch"

This variable can have one of two values, "scratch" or "tempfile".

If it is set to "scratch" (the default), the created proxy buffer is not
connected to any file. The benefit is that the filename can then be set to be
an informative string instead of a weird temporary filename. The drawback is
that you can't run some external commands on this buffer, since there is no
real backing file.

If it is set to "tempfile", the proxy buffer is actually a temporary file. The
benefit is that you run external commands that expect an actual file (like
executing |:make|). The drawback is that the only way to display information
on the proxy is by hacking the statusline, which may cause issues and can't
work reliably on all statuslines.


==============================================================================
EXTENDING *inline-edit-extending*
Expand Down
2 changes: 1 addition & 1 deletion example/example.sh
Expand Up @@ -6,6 +6,6 @@ RUBY

cat <<PYTHON
#! /usr/bin/env python3
print("OK")
PYTHON
8 changes: 8 additions & 0 deletions plugin/inline_edit.vim
Expand Up @@ -18,6 +18,14 @@ if !exists('g:inline_edit_html_like_filetypes')
let g:inline_edit_html_like_filetypes = []
endif

if !exists('g:inline_edit_proxy_type')
let g:inline_edit_proxy_type = 'scratch'
endif

if index(['scratch', 'tempfile'], g:inline_edit_proxy_type) < 0
echoerr 'Inline Edit: Proxy type can''t be "'.g:inline_edit_proxy_type.'". Needs to be one of: scratch, tempfile'
endif

" Default patterns
call add(g:inline_edit_patterns, {
\ 'main_filetype': 'markdown',
Expand Down

0 comments on commit 10d396c

Please sign in to comment.