Add new stuff

This commit is contained in:
ViktorBarzin 2018-02-14 00:00:02 +00:00
parent 69661de82f
commit 07744f6823
333 changed files with 1989 additions and 6 deletions

View file

@ -0,0 +1,379 @@
" Author: Eric Van Dewoestine
"
" Description: {{{
"
" License:
"
" Copyright (C) 2005 - 2014 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" ScriptVariables {{{
let s:eclim_tab_id = 0
" }}}
function! eclim#common#buffers#Buffers(bang) " {{{
" Like, :buffers, but opens a temporary buffer.
let options = {'maxfilelength': 0}
let buffers = eclim#common#buffers#GetBuffers(options)
if g:EclimBuffersSort != ''
call sort(buffers, 'eclim#common#buffers#BufferCompare')
endif
let lines = []
let buflist = []
let filelength = options['maxfilelength']
let tabid = exists('*gettabvar') ? s:GetTabId() : 0
let tabbuffers = tabpagebuflist()
for buffer in buffers
let eclim_tab_id = getbufvar(buffer.bufnr, 'eclim_tab_id')
if a:bang != '' || eclim_tab_id == '' || eclim_tab_id == tabid
" for buffers w/ out a tab id, don't show them in the list if they
" are active, but aren't open on the current tab.
if a:bang == '' && buffer.status =~ 'a' && index(tabbuffers, buffer.bufnr) == -1
continue
endif
call add(lines, s:BufferEntryToLine(buffer, filelength))
call add(buflist, buffer)
endif
endfor
call eclim#util#TempWindow('[buffers]', lines)
setlocal modifiable noreadonly
call append(line('$'), ['', '" use ? to view help'])
setlocal nomodifiable readonly
let b:eclim_buffers = buflist
" syntax
set ft=eclim_buffers
hi link BufferActive Special
hi link BufferHidden Comment
syntax match BufferActive /+\?active\s\+\(\[RO\]\)\?/
syntax match BufferHidden /+\?hidden\s\+\(\[RO\]\)\?/
syntax match Comment /^".*/
" mappings
nnoremap <silent> <buffer> <cr> :call <SID>BufferOpen(g:EclimBuffersDefaultAction)<cr>
nnoremap <silent> <buffer> E :call <SID>BufferOpen('edit')<cr>
nnoremap <silent> <buffer> S :call <SID>BufferOpen('split')<cr>
nnoremap <silent> <buffer> V :call <SID>BufferOpen('vsplit')<cr>
nnoremap <silent> <buffer> T :call <SID>BufferOpen('tablast \| tabnew')<cr>
nnoremap <silent> <buffer> D :call <SID>BufferDelete()<cr>
nnoremap <silent> <buffer> R :Buffers<cr>
" assign to buffer var to get around weird vim issue passing list containing
" a string w/ a '<' in it on execution of mapping.
let b:buffers_help = [
\ '<cr> - open buffer with default action',
\ 'E - open with :edit',
\ 'S - open in a new split window',
\ 'V - open in a new vertically split window',
\ 'T - open in a new tab',
\ 'D - delete the buffer',
\ 'R - refresh the buffer list',
\ ]
nnoremap <buffer> <silent> ?
\ :call eclim#help#BufferHelp(b:buffers_help, 'vertical', 40)<cr>
"augroup eclim_buffers
" autocmd!
" autocmd BufAdd,BufWinEnter,BufDelete,BufWinLeave *
" \ call eclim#common#buffers#BuffersUpdate()
" autocmd BufUnload <buffer> autocmd! eclim_buffers
"augroup END
endfunction " }}}
function! eclim#common#buffers#BuffersToggle(bang) " {{{
let name = eclim#util#EscapeBufferName('[buffers]')
if bufwinnr(name) == -1
call eclim#common#buffers#Buffers(a:bang)
else
exec "bdelete " . bufnr(name)
endif
endfunction " }}}
function! eclim#common#buffers#BufferCompare(buffer1, buffer2) " {{{
exec 'let attr1 = a:buffer1.' . g:EclimBuffersSort
exec 'let attr2 = a:buffer2.' . g:EclimBuffersSort
let compare = attr1 == attr2 ? 0 : attr1 > attr2 ? 1 : -1
if g:EclimBuffersSortDirection == 'desc'
let compare = 0 - compare
endif
return compare
endfunction " }}}
function! eclim#common#buffers#Only() " {{{
let curwin = winnr()
let winnum = 1
while winnum <= winnr('$')
let fixed = g:EclimOnlyExcludeFixed && (
\ getwinvar(winnum, '&winfixheight') == 1 ||
\ getwinvar(winnum, '&winfixwidth') == 1)
let excluded = bufname(winbufnr(winnum)) =~ g:EclimOnlyExclude
if winnum != curwin && !fixed && !excluded
if winnum < curwin
let curwin -= 1
endif
exec winnum . 'winc w'
close
exec curwin . 'winc w'
continue
endif
let winnum += 1
endwhile
endfunction " }}}
function! eclim#common#buffers#GetBuffers(...) " {{{
let options = a:0 ? a:1 : {}
redir => list
silent buffers
redir END
let buffers = []
let maxfilelength = 0
for entry in split(list, '\n')
let buffer = {}
let buffer.status = substitute(entry, '\s*[0-9]\+\s\+\(.\{-}\)\s\+".*', '\1', '')
let buffer.path = substitute(entry, '.\{-}"\(.\{-}\)".*', '\1', '')
let buffer.path = fnamemodify(buffer.path, ':p')
let buffer.file = fnamemodify(buffer.path, ':p:t')
let buffer.dir = fnamemodify(buffer.path, ':p:h')
let buffer.bufnr = str2nr(substitute(entry, '\s*\([0-9]\+\).*', '\1', ''))
let buffer.lnum = str2nr(substitute(entry, '.*"\s\+\w\+\s\+\(\d\+\)', '\1', ''))
call add(buffers, buffer)
if len(buffer.file) > maxfilelength
let maxfilelength = len(buffer.file)
endif
endfor
if has_key(options, 'maxfilelength')
let options['maxfilelength'] = maxfilelength
endif
return buffers
endfunction " }}}
function! eclim#common#buffers#TabInit() " {{{
let tabnr = 1
while tabnr <= tabpagenr('$')
let tab_id = gettabvar(tabnr, 'eclim_tab_id')
if tab_id == ''
let s:eclim_tab_id += 1
call settabvar(tabnr, 'eclim_tab_id', s:eclim_tab_id)
for bufnr in tabpagebuflist(tabnr)
let btab_id = getbufvar(bufnr, 'eclim_tab_id')
if btab_id == ''
call setbufvar(bufnr, 'eclim_tab_id', s:eclim_tab_id)
endif
endfor
endif
let tabnr += 1
endwhile
endfunction " }}}
function! eclim#common#buffers#TabEnter() " {{{
if !s:GetTabId()
call s:SetTabId()
endif
if g:EclimBuffersDeleteOnTabClose
if exists('s:tab_count') && s:tab_count > tabpagenr('$')
" delete any buffers associated with the closed tab
let buffers = eclim#common#buffers#GetBuffers()
for buffer in buffers
let eclim_tab_id = getbufvar(buffer.bufnr, 'eclim_tab_id')
" don't delete active buffers, just in case the tab has the wrong
" eclim_tab_id
if eclim_tab_id == s:tab_prev && buffer.status !~ 'a'
try
exec 'bdelete ' . buffer.bufnr
catch /E89/
" ignore since it happens when using bd! on the last buffer for
" another tab.
endtry
endif
endfor
endif
endif
endfunction " }}}
function! eclim#common#buffers#TabLeave() " {{{
let s:tab_prev = s:GetTabId()
let s:tab_count = tabpagenr('$')
endfunction " }}}
function! eclim#common#buffers#TabLastOpenIn() " {{{
if !buflisted('%')
silent! unlet b:eclim_tab_id
endif
if !s:GetTabId()
call s:SetTabId()
endif
let tabnr = 1
let other_tab = 0
let bufnr = bufnr('%')
while tabnr <= tabpagenr('$')
if tabnr != tabpagenr() &&
\ eclim#util#ListContains(tabpagebuflist(tabnr), bufnr)
let other_tab = tabnr
break
endif
let tabnr += 1
endwhile
if !exists('b:eclim_tab_id') || !other_tab
let b:eclim_tab_id = s:GetTabId()
endif
endfunction " }}}
function! eclim#common#buffers#OpenNextHiddenTabBuffer(current) " {{{
let allbuffers = eclim#common#buffers#GetBuffers()
" build list of buffers open in other tabs to exclude
let tabbuffers = []
let lasttab = tabpagenr('$')
let index = 1
while index <= lasttab
if index != tabpagenr()
for bnum in tabpagebuflist(index)
call add(tabbuffers, bnum)
endfor
endif
let index += 1
endwhile
" build list of buffers not open in any window, and last seen on the
" current tab.
let hiddenbuffers = []
for buffer in allbuffers
let bnum = buffer.bufnr
if bnum != a:current && index(tabbuffers, bnum) == -1 && bufwinnr(bnum) == -1
let eclim_tab_id = getbufvar(bnum, 'eclim_tab_id')
if eclim_tab_id != '' && eclim_tab_id != t:eclim_tab_id
continue
endif
if bnum < a:current
call insert(hiddenbuffers, bnum)
else
call add(hiddenbuffers, bnum)
endif
endif
endfor
" we found a hidden buffer, so open it
if len(hiddenbuffers) > 0
exec 'buffer ' . hiddenbuffers[0]
doautocmd BufEnter
doautocmd BufWinEnter
doautocmd BufReadPost
return hiddenbuffers[0]
endif
return 0
endfunction " }}}
function! s:BufferDelete() " {{{
let line = line('.')
if line > len(b:eclim_buffers)
return
endif
let index = line - 1
setlocal modifiable
setlocal noreadonly
exec line . ',' . line . 'delete _'
setlocal nomodifiable
setlocal readonly
let buffer = b:eclim_buffers[index]
call remove(b:eclim_buffers, index)
let winnr = winnr()
" make sure the autocmds are executed in the following order
noautocmd exec 'bd ' . buffer.bufnr
doautocmd BufDelete
doautocmd BufEnter
exec winnr . 'winc w'
endfunction " }}}
function! s:BufferEntryToLine(buffer, filelength) " {{{
let line = ''
let line .= a:buffer.status =~ '+' ? '+' : ' '
let line .= a:buffer.status =~ 'a' ? 'active' : 'hidden'
let line .= a:buffer.status =~ '[-=]' ? ' [RO] ' : ' '
let line .= a:buffer.file
let pad = a:filelength - len(a:buffer.file) + 2
while pad > 0
let line .= ' '
let pad -= 1
endwhile
let line .= a:buffer.dir
return line
endfunction " }}}
function! s:BufferOpen(cmd) " {{{
let line = line('.')
if line > len(b:eclim_buffers)
return
endif
let file = bufname(b:eclim_buffers[line - 1].bufnr)
let winnr = b:winnr
close
" prevent opening the buffer in a split of a vertical tool window (project
" tree, taglist, etc.)
if exists('g:VerticalToolBuffers') && has_key(g:VerticalToolBuffers, winbufnr(winnr))
let winnr = 1
while has_key(g:VerticalToolBuffers, winbufnr(winnr))
let winnr += 1
if winnr > winnr('$')
let winnr -= 1
break
endif
endwhile
endif
exec winnr . 'winc w'
call eclim#util#GoToBufferWindowOrOpen(file, a:cmd)
endfunction " }}}
function! s:GetTabId(...) " {{{
let tabnr = a:0 ? a:1 : tabpagenr()
" using gettabvar over t:eclim_tab_id because while autocmds are executing,
" the tabpagenr() may return the correct tab number, but accessing
" t:eclim_tab_id may return the value from the previously focused tab.
return gettabvar(tabnr, 'eclim_tab_id')
endfunction " }}}
function! s:SetTabId(...) " {{{
let tabnr = a:0 ? a:1 : tabpagenr()
let s:eclim_tab_id += 1
" using settabvar for reason explained in s:GetTabId()
call settabvar(tabnr, 'eclim_tab_id', s:eclim_tab_id)
endfunction " }}}
" vim:ft=vim:fdm=marker

View file

@ -0,0 +1,316 @@
" Author: Eric Van Dewoestine
"
" License: {{{
"
" Copyright (C) 2005 - 2014 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" Script Variables {{{
let s:command_add = '-command history_add -p "<project>" -f "<file>"'
let s:command_list = '-command history_list -p "<project>" -f "<file>"'
let s:command_revision =
\ '-command history_revision -p "<project>" -f "<file>" -r <revision>'
let s:command_clear = '-command history_clear -p "<project>" -f "<file>"'
" }}}
function! eclim#common#history#AddHistory() " {{{
" Adds the current state of the file to the eclipse local history (should be
" invoked prior to saving to disk).
if !filereadable(expand('%')) || !eclim#project#util#IsCurrentFileInProject(0)
return
endif
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let command = s:command_add
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
call eclim#Execute(command)
endfunction " }}}
function! eclim#common#history#History() " {{{
" Opens a temporary buffer with a list of local history revisions.
if !eclim#project#util#IsCurrentFileInProject()
return
endif
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let command = s:command_list
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let history = eclim#Execute(command)
if type(history) != g:LIST_TYPE
return
endif
let lines = [file]
let revisions = [0]
let indent = eclim#util#GetIndent(1)
for rev in history
call add(lines, indent . rev.datetime . ' (' . rev.delta . ')')
call add(revisions, rev.timestamp)
endfor
call add(lines, '')
call eclim#util#TempWindow('[History]', lines)
setlocal modifiable noreadonly
if !g:EclimKeepLocalHistory
call append(line('$'),
\ '" Note: local history is currently disabled: ' .
\ 'g:EclimKeepLocalHistory = ' . g:EclimKeepLocalHistory)
endif
call append(line('$'), '" use ? to view help')
setlocal nomodifiable readonly
syntax match Comment /^".*/
let b:history_revisions = revisions
call s:Syntax()
command! -count=1 HistoryDiffNext call s:DiffNextPrev(1, <count>)
command! -count=1 HistoryDiffPrev call s:DiffNextPrev(-1, <count>)
augroup eclim_history_window
autocmd! BufWinLeave <buffer>
autocmd BufWinLeave <buffer>
\ delcommand HistoryDiffNext |
\ delcommand HistoryDiffPrev
augroup END
noremap <buffer> <silent> <cr> :call <SID>View()<cr>
noremap <buffer> <silent> d :call <SID>Diff()<cr>
noremap <buffer> <silent> r :call <SID>Revert()<cr>
noremap <buffer> <silent> c :call <SID>Clear(1)<cr>
" assign to buffer var to get around weird vim issue passing list containing
" a string w/ a '<' in it on execution of mapping.
let b:history_help = [
\ '<cr> - view the entry',
\ 'd - diff the file with the version under the cursor',
\ 'r - revert the file to the version under the cursor',
\ 'c - clear the history',
\ ':HistoryDiffNext - diff the file with the next version in the history',
\ ':HistoryDiffPrev - diff the file with the previous version in the history',
\ ]
nnoremap <buffer> <silent> ?
\ :call eclim#help#BufferHelp(b:history_help, 'vertical', 50)<cr>
endfunction " }}}
function! eclim#common#history#HistoryClear(bang) " {{{
" Clear the history for the current file.
if !eclim#project#util#IsCurrentFileInProject()
return
endif
call s:Clear(a:bang == '', expand('%:p'))
endfunction " }}}
function s:View(...) " {{{
" View the contents of the revision under the cursor.
if line('.') == 1 || line('.') > len(b:history_revisions)
return
endif
let current = b:filename
let entry = line('.') - 1
let revision = b:history_revisions[entry]
if eclim#util#GoToBufferWindow(current)
let filetype = &ft
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let command = s:command_revision
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let command = substitute(command, '<revision>', revision, '')
let result = eclim#Execute(command)
if result == "0"
return
endif
let cmd = len(a:000) > 0 ? a:000[0] : 'split'
call eclim#util#GoToBufferWindowOrOpen(
\ current . '_' . revision, 'keepalt ' . cmd)
setlocal modifiable
setlocal noreadonly
let temp = tempname()
call writefile(split(result, '\n'), temp)
try
silent 1,$delete _
silent read ++edit `=temp`
silent 1,1delete _
finally
call delete(temp)
endtry
exec 'setlocal filetype=' . filetype
setlocal nomodified
setlocal readonly
setlocal nomodifiable
setlocal noswapfile
setlocal nobuflisted
setlocal buftype=nofile
setlocal bufhidden=wipe
doautocmd BufReadPost
call s:HighlightEntry(entry)
return 1
else
call eclim#util#EchoWarning('Target file is no longer open.')
endif
endfunction " }}}
function s:Diff() " {{{
" Diff the contents of the revision under the cursor against the current
" contents.
let hist_buf = bufnr('%')
let winend = winnr('$')
let winnum = 1
while winnum <= winend
let bufnr = winbufnr(winnum)
if getbufvar(bufnr, 'history_diff') != ''
exec bufnr . 'bd'
continue
endif
let winnum += 1
endwhile
call eclim#util#GoToBufferWindow(hist_buf)
let current = b:filename
let orien = g:EclimHistoryDiffOrientation == 'horizontal' ? '' : 'vertical'
if s:View(orien . ' below split')
let b:history_diff = 1
diffthis
augroup history_diff
autocmd! BufWinLeave <buffer>
call eclim#util#GoToBufferWindowRegister(current)
autocmd BufWinLeave <buffer> diffoff
augroup END
call eclim#util#GoToBufferWindow(current)
diffthis
endif
endfunction " }}}
function s:DiffNextPrev(dir, count) " {{{
let winnr = winnr()
if eclim#util#GoToBufferWindow('[History]')
let num = v:count > 0 ? v:count : a:count
let cur = exists('b:history_current_entry') ? b:history_current_entry : 0
let index = cur + (a:dir * num)
if index < 0 || index > len(b:history_revisions)
call eclim#util#EchoError('Operation exceeds history stack range.')
exec winnr . 'winc w'
return
endif
call cursor(index + 1, 0)
call s:Diff()
endif
endfunction " }}}
function s:Revert() " {{{
" Revert the file to the revision under the cursor.
if line('.') == 1 || line('.') > len(b:history_revisions)
return
endif
let current = b:filename
let revision = b:history_revisions[line('.') - 1]
if eclim#util#GoToBufferWindow(current)
let project = eclim#project#util#GetCurrentProjectName()
let file = eclim#project#util#GetProjectRelativeFilePath()
let command = s:command_revision
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', file, '')
let command = substitute(command, '<revision>', revision, '')
let result = eclim#Execute(command)
if result == "0"
return
endif
let ff = &ff
let temp = tempname()
call writefile(split(result, '\n'), temp)
try
silent 1,$delete _
silent read ++edit `=temp`
silent 1,1delete _
finally
call delete(temp)
endtry
if ff != &ff
call eclim#util#EchoWarning(
\ "Warning: the file format is being reverted from '" . ff . "' to '" .
\ &ff . "'. Using vim's undo will not restore the previous format so " .
\ "if you choose to undo the reverting of this file, you will need to " .
\ "manually set the file format back to " . ff . " (set ff=" . ff . ").")
endif
endif
endfunction " }}}
function s:Clear(prompt, ...) " {{{
" Optional args:
" filename
let response = 1
if a:prompt
let response = eclim#util#PromptConfirm(
\ 'Clear local history?', g:EclimHighlightInfo)
endif
if response == 1
let filename = len(a:000) > 0 ? a:000[0] : b:filename
let current = eclim#project#util#GetProjectRelativeFilePath(filename)
let project = eclim#project#util#GetCurrentProjectName()
let command = s:command_clear
let command = substitute(command, '<project>', project, '')
let command = substitute(command, '<file>', current, '')
let result = eclim#Execute(command)
if result == "0"
return
endif
if filename != expand('%:p')
quit
endif
call eclim#util#Echo(result)
endif
endfunction " }}}
function! s:Syntax() " {{{
set ft=eclim_history
hi link HistoryFile Identifier
hi link HistoryCurrentEntry Constant
syntax match HistoryFile /.*\%1l.*/
syntax match Comment /^".*/
endfunction " }}}
function s:HighlightEntry(index) " {{{
let winnr = winnr()
if eclim#util#GoToBufferWindow('[History]')
let b:history_current_entry = a:index
try
" forces reset of syntax
call s:Syntax()
exec 'syntax match HistoryCurrentEntry /.*\%' . (a:index + 1) . 'l.*/'
finally
exec winnr . 'winc w'
endtry
endif
endfunction " }}}
" vim:ft=vim:fdm=marker

View file

@ -0,0 +1,58 @@
" Author: Eric Van Dewoestine
"
" Description: {{{
" Initially based on vimscript 1506
"
" License:
"
" Copyright (C) 2005 - 2012 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" Script Settings {{{
let s:file_size = g:EclimLargeFileSize * 1024 * 1024
let s:events = ['BufRead', 'CursorHold', 'FileType']
" }}}
function! eclim#common#largefile#InitSettings() " {{{
let file = expand("<afile>")
let size = getfsize(file)
if size >= s:file_size || size == -2
if !exists('b:save_events')
let b:save_events = &eventignore
call s:ApplySettings()
setlocal noswapfile nowrap bufhidden=unload
autocmd eclim_largefile BufEnter,BufWinEnter <buffer> call <SID>ApplySettings()
autocmd eclim_largefile BufLeave,BufWinLeave <buffer> call <SID>RevertSettings()
endif
endif
endfunction " }}}
function! s:ApplySettings() " {{{
let &eventignore=join(s:events, ',')
if !exists('b:largefile_notified')
let b:largefile_notified = 1
call eclim#util#Echo('Note: Large file settings applied.')
endif
endfunction " }}}
function! s:RevertSettings() " {{{
if exists('b:save_events')
let &eventignore=b:save_events
endif
endfunction " }}}
" vim:ft=vim:fdm=marker

View file

@ -0,0 +1,87 @@
" Author: Eric Van Dewoestine
"
" Description: {{{
"
" License:
"
" Copyright (C) 2005 - 2012 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" Script Variables {{{
let s:year = exists('*strftime') ? strftime('%Y') : '2009'
" }}}
" GetLicense() {{{
" Retrieves the file containing the license text.
function! eclim#common#license#GetLicense()
let file = eclim#project#util#GetProjectSetting('org.eclim.project.copyright')
if type(file) == g:NUMBER_TYPE
return
elseif file == ''
call eclim#util#EchoWarning(
\ "Project setting 'org.eclim.project.copyright' has not been supplied.")
return
endif
let file = eclim#project#util#GetCurrentProjectRoot() . '/' . file
if !filereadable(file)
return
endif
return file
endfunction " }}}
" License(pre, post, mid) {{{
" Retrieves the license configured license and applies the specified prefix
" and postfix as the lines before and after the license and uses 'mid' as the
" prefix for every line.
" Returns the license as a list of strings.
function! eclim#common#license#License(pre, post, mid)
let file = eclim#common#license#GetLicense()
if type(file) == g:NUMBER_TYPE && file == 0
return ''
endif
let contents = readfile(file)
if a:mid != ''
call map(contents, 'a:mid . v:val')
endif
if a:pre != ''
call insert(contents, a:pre)
endif
if a:post != ''
call add(contents, a:post)
endif
call map(contents, "substitute(v:val, '${year}', s:year, 'g')")
let author = eclim#project#util#GetProjectSetting('org.eclim.user.name')
if type(author) == g:STRING_TYPE && author != ''
call map(contents, "substitute(v:val, '${author}', author, 'g')")
endif
let email = eclim#project#util#GetProjectSetting('org.eclim.user.email')
if type(email) == g:STRING_TYPE && email != ''
call map(contents, "substitute(v:val, '${email}', email, 'g')")
endif
call map(contents, "substitute(v:val, '\\s\\+$', '', '')")
return contents
endfunction " }}}
" vim:ft=vim:fdm=marker

View file

@ -0,0 +1,650 @@
" Author: Eric Van Dewoestine
"
" License: {{{
"
" Copyright (C) 2005 - 2014 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" Global Variables {{{
let g:eclim_locate_default_updatetime = &updatetime
" disable autocomplpop in the locate prompt
if exists('g:acp_behavior')
let g:acp_behavior['locate_prompt'] = []
endif
" }}}
" Script Variables {{{
let s:command_locate = '-command locate_file -s "<scope>"'
let s:scopes = [
\ 'project',
\ 'workspace',
\ 'buffers',
\ 'quickfix',
\ ]
let s:help = [
\ '<esc> - close the locate prompt + results',
\ '<tab>, <down> - select the next file',
\ '<s-tab>, <up> - select the previous file',
\ '<cr> - open selected file w/ default action',
\ '<c-e> - open with :edit',
\ '<c-s> - open in a split window',
\ '<c-t> - open in a new tab',
\ '<c-l> - choose search scope',
\ '<c-h> - toggle help buffer',
\ ]
" }}}
function! eclim#common#locate#LocateFile(action, file, ...) " {{{
" Locates a file using the specified action for opening the file when found.
" action - '' (use user default), 'split', 'edit', etc.
" file - 'somefile.txt',
" '', (kick off completion mode),
" '<cursor>' (locate the file under the cursor)
" scope - optional scope to search in (project, workspace, buffers, etc.)
let project = eclim#project#util#GetCurrentProjectName()
let scope = a:0 > 0 ? a:1 : g:EclimLocateFileScope
if !eclim#util#ListContains(s:scopes, scope) &&
\ !eclim#util#ListContains(g:EclimLocateUserScopes, scope)
call eclim#util#EchoWarning('Unrecognized scope: ' . scope)
return
endif
if scope == 'project' && (project == '' || !eclim#EclimAvailable(0))
let scope = g:EclimLocateFileNonProjectScope
endif
let workspace = ''
if scope == 'project' || scope == 'workspace'
let instance = eclim#client#nailgun#ChooseEclimdInstance()
if type(instance) != g:DICT_TYPE
return
endif
let workspace = instance.workspace
if !eclim#PingEclim(0, workspace)
call eclim#util#EchoError('Unable to connect to eclimd.')
return
endif
endif
let results = []
let action = a:action
if action == ''
let action = g:EclimLocateFileDefaultAction
endif
let file = a:file
if file == ''
call s:LocateFileCompletionInit(action, scope, project, workspace)
return
elseif file == '<cursor>'
let file = eclim#util#GrabUri()
" if grabbing a relative url, remove any anchor info or query parameters
let file = substitute(file, '[#?].*', '', '')
endif
let name = fnamemodify(file, ':t')
if name == ''
call eclim#util#Echo('Please supply more than just a directory name.')
return
endif
let pattern = file
let pattern = s:LocateFileConvertPattern(pattern, 0)
let pattern = '[^/]*' . pattern
try
let b:workspace = workspace
let b:project = project
let results = s:LocateFileFunction(scope)(pattern)
finally
unlet! b:workspace
unlet! b:project
endtry
call map(results, "v:val.path")
let result = ''
" One result.
if len(results) == 1
let result = results[0]
" More than one result.
elseif len(results) > 1
let message = "Multiple results, choose the file to open"
let response = eclim#util#PromptList(message, results, g:EclimHighlightInfo)
if response == -1
return
endif
let result = results[response]
" No results
else
call eclim#util#Echo('Unable to locate file pattern "' . file . '".')
return
endif
if has('win32unix')
let result = eclim#cygwin#CygwinPath(result)
endif
call eclim#util#GoToBufferWindowOrOpen(eclim#util#Simplify(result), action)
call eclim#util#Echo(' ')
endfunction " }}}
function! eclim#common#locate#LocateFileCompletion() " {{{
let line = getline('.')
if line !~ '^> '
call setline(1, substitute(line, '^>\?\s*', '> \1', ''))
call cursor(1, 3)
let line = getline('.')
endif
let completions = []
let display = []
let name = substitute(line, '^>\s*', '', '')
if name !~ '^\s*$'
let pattern = name
let pattern = s:LocateFileConvertPattern(pattern, g:EclimLocateFileFuzzy)
let results = s:LocateFileFunction(b:scope)(pattern)
if !empty(results)
for result in results
let rel = eclim#util#Simplify(get(result, 'projectPath', result.path))
let dict = {'word': result.name, 'menu': rel, 'info': result.path}
call add(completions, dict)
call add(display, result.name . ' ' . rel)
endfor
endif
endif
let b:completions = completions
let winnr = winnr()
noautocmd exec bufwinnr(b:results_bufnum) . 'winc w'
setlocal modifiable
1,$delete _
call append(1, display)
1,1delete _
setlocal nomodifiable
exec winnr . 'winc w'
" part of bad hack for gvim on windows
let b:start_selection = 1
call s:LocateFileSelection(1)
endfunction " }}}
function! eclim#common#locate#LocateFileClose() " {{{
if bufname(bufnr('%')) !~ '^\[Locate.*\]$'
let bufnr = bufnr('\[Locate in *\]')
let winnr = bufwinnr(bufnr)
if winnr != -1
let curbuf = bufnr('%')
exec winnr . 'winc w'
try
exec 'bw ' . b:results_bufnum
bw
autocmd! locate_file_init
stopinsert
finally
exec bufwinnr(curbuf) . 'winc w'
endtry
endif
endif
endfunction " }}}
function! s:LocateFileCompletionInit(action, scope, project, workspace) " {{{
let file = expand('%')
let bufnum = bufnr('%')
let winnr = winnr()
let winrestcmd = winrestcmd()
topleft 12split [Locate\ Results]
set filetype=locate_results
setlocal nonumber nowrap
setlocal noswapfile nobuflisted
setlocal nospell norelativenumber
setlocal buftype=nofile bufhidden=delete
let results_bufnum = bufnr('%')
let locate_in = (a:scope == 'project' ? a:project : a:scope)
exec 'topleft 1split ' . escape('[Locate in ' . locate_in . ']', ' -')
setlocal modifiable
call setline(1, '> ')
call cursor(1, col('$'))
set filetype=locate_prompt
syntax match Keyword /^>/
setlocal winfixheight
setlocal nonumber
setlocal nolist
setlocal noswapfile nobuflisted
setlocal nospell norelativenumber
setlocal buftype=nofile bufhidden=delete
let b:bufnum = bufnum
let b:winnr = winnr
let b:project = a:project
let b:workspace = a:workspace
let b:scope = a:scope
let b:results_bufnum = results_bufnum
let b:help_bufnum = 0
let b:selection = 1
let b:winrestcmd = winrestcmd
set updatetime=300
augroup locate_file_init
autocmd!
autocmd BufEnter <buffer> nested startinsert! | let &updatetime = 300
autocmd BufLeave \[Locate*\]
\ call eclim#util#DelayedCommand('call eclim#common#locate#LocateFileClose()')
exec 'autocmd InsertLeave <buffer> ' .
\ 'let &updatetime = g:eclim_locate_default_updatetime | ' .
\ 'doautocmd BufWinLeave | bw | ' .
\ 'doautocmd BufWinLeave | bw ' . b:results_bufnum . ' | ' .
\ 'call eclim#util#GoToBufferWindow(' . b:bufnum . ') | ' .
\ 'doautocmd BufEnter | ' .
\ 'doautocmd WinEnter | ' .
\ winrestcmd
exec 'autocmd WinEnter <buffer=' . b:results_bufnum .'> '
\ 'exec bufwinnr(' . bufnr('%') . ') "winc w"'
augroup END
" enable completion after user starts typing
call s:LocateFileCompletionAutocmdDeferred()
inoremap <buffer> <silent> <tab> <c-r>=<SID>LocateFileSelection("n")<cr>
inoremap <buffer> <silent> <c-j> <c-r>=<SID>LocateFileSelection("n")<cr>
inoremap <buffer> <silent> <down> <c-r>=<SID>LocateFileSelection("n")<cr>
inoremap <buffer> <silent> <s-tab> <c-r>=<SID>LocateFileSelection("p")<cr>
inoremap <buffer> <silent> <up> <c-r>=<SID>LocateFileSelection("p")<cr>
inoremap <buffer> <silent> <c-k> <c-r>=<SID>LocateFileSelection("p")<cr>
exec 'inoremap <buffer> <silent> <cr> ' .
\ '<c-r>=<SID>LocateFileSelect("' . a:action . '")<cr>'
inoremap <buffer> <silent> <c-e> <c-r>=<SID>LocateFileSelect('edit')<cr>
inoremap <buffer> <silent> <c-s> <c-r>=<SID>LocateFileSelect('split')<cr>
inoremap <buffer> <silent> <c-t> <c-r>=<SID>LocateFileSelect("tablast \| tabnew")<cr>
inoremap <buffer> <silent> <c-l> <c-r>=<SID>LocateFileChangeScope()<cr>
inoremap <buffer> <silent> <c-h> <c-r>=<SID>LocateFileHelp()<cr>
startinsert!
endfunction " }}}
function! s:LocateFileCompletionAutocmd() " {{{
augroup locate_file
autocmd!
autocmd CursorHoldI <buffer> call eclim#common#locate#LocateFileCompletion()
augroup END
endfunction " }}}
function! s:LocateFileCompletionAutocmdDeferred() " {{{
augroup locate_file
autocmd!
autocmd CursorMovedI <buffer> call <SID>LocateFileCompletionAutocmd()
augroup END
endfunction " }}}
function! s:LocateFileSelection(sel) " {{{
" pause completion while tabbing though results
augroup locate_file
autocmd!
augroup END
let sel = a:sel
let prev_sel = b:selection
" bad hack for gvim on windows
let start_sel = b:start_selection
let double_defer = 0
if sel =~ '^[np]$' && (has('win32') || has('win64'))
let double_defer = b:start_selection == 1
let b:start_selection = 0
endif
let winnr = winnr()
noautocmd exec bufwinnr(b:results_bufnum) . 'winc w'
if sel == 'n'
let sel = prev_sel < line('$') ? prev_sel + 1 : 1
elseif sel == 'p'
let sel = prev_sel > 1 ? prev_sel - 1 : line('$')
endif
syntax clear
exec 'syntax match PmenuSel /\%' . sel . 'l.*/'
exec 'call cursor(' . sel . ', 1)'
let save_scrolloff = &scrolloff
let &scrolloff = 5
normal! zt
let &scrolloff = save_scrolloff
exec winnr . 'winc w'
exec 'let b:selection = ' . sel
if double_defer
augroup locate_file
autocmd!
autocmd CursorMovedI <buffer> call <SID>LocateFileCompletionAutocmdDeferred()
augroup END
else
call s:LocateFileCompletionAutocmdDeferred()
endif
return ''
endfunction " }}}
function! s:LocateFileSelect(action) " {{{
if exists('b:completions') && !empty(b:completions)
let &updatetime = g:eclim_locate_default_updatetime
let file = eclim#util#Simplify(b:completions[b:selection - 1].info)
if has('win32unix')
let file = eclim#cygwin#CygwinPath(file)
endif
let bufnum = b:bufnum
let winnr = b:winnr
let winrestcmd = b:winrestcmd
" close locate windows
exec 'bdelete ' . b:results_bufnum
exec 'bdelete ' . bufnr('%')
" reset windows to pre-locate sizes
exec winrestcmd
" open the selected result
exec winnr . "wincmd w"
" call eclim#util#GoToBufferWindow(bufnum)
call eclim#util#GoToBufferWindowOrOpen(file, a:action)
call feedkeys("\<esc>", 'n')
doautocmd WinEnter
endif
return ''
endfunction " }}}
function! s:LocateFileChangeScope() " {{{
if b:help_bufnum && bufexists(b:help_bufnum)
exec 'bdelete ' . b:help_bufnum
endif
let bufnr = bufnr('%')
let winnr = winnr()
" trigger [Locate] buffer's BufLeave autocmd before we leave the buffer
doautocmd BufLeave
noautocmd exec bufwinnr(b:results_bufnum) . 'winc w'
silent noautocmd exec '50vnew [Locate\ Scope]'
let b:locate_bufnr = bufnr
let b:locate_winnr = winnr
stopinsert
setlocal modifiable
call append(1, s:scopes + g:EclimLocateUserScopes)
1,1delete _
call append(line('$'),
\ ['', '" <cr> - select a scope', '" <c-c>, <c-l>, or q - cancel'])
syntax match Comment /^".*/
setlocal nomodifiable
setlocal winfixheight
setlocal nonumber
setlocal nolist
setlocal noswapfile nobuflisted
setlocal nospell norelativenumber
setlocal buftype=nofile bufhidden=delete
nnoremap <buffer> <silent> <cr> :call <SID>ChooseScope()<cr>
nnoremap <buffer> <silent> q :call <SID>CloseScopeChooser()<cr>
nnoremap <buffer> <silent> <c-c> :call <SID>CloseScopeChooser()<cr>
nnoremap <buffer> <silent> <c-l> :call <SID>CloseScopeChooser()<cr>
autocmd BufLeave <buffer> call <SID>CloseScopeChooser()
return ''
endfunction " }}}
function! s:ChooseScope() " {{{
let scope = getline('.')
if scope =~ '^"\|^\s*$'
return
endif
let project = ''
let locate_in = scope
if scope == 'project'
let project = ''
let names = eclim#project#util#GetProjectNames()
let prompt = 'Choose a project (ctrl-c to cancel): '
while project == ''
let project = input(
\ prompt, '', 'customlist,eclim#project#util#CommandCompleteProject')
if project == ''
echo ''
return
endif
if !eclim#util#ListContains(names, project)
let prompt = "Project '" . project . "' not found (ctrl-c to cancel): "
let project = ''
endif
endwhile
let locate_in = project
let workspace = eclim#project#util#GetProjectWorkspace(project)
if type(workspace) == g:LIST_TYPE
let workspaces = workspace
unlet workspace
let response = eclim#util#PromptList(
\ 'Muliple workspaces found, please choose the target workspace',
\ workspaces, g:EclimHighlightInfo)
" user cancelled, error, etc.
if response < 0
return
endif
let workspace = workspaces[response]
endif
elseif scope == 'workspace'
let project = ''
let instance = eclim#client#nailgun#ChooseEclimdInstance()
if type(instance) != g:DICT_TYPE
return
endif
let workspace = instance.workspace
else
let workspace = ''
endif
call s:CloseScopeChooser()
let b:scope = scope
let b:project = project
let b:workspace = workspace != '' ? workspace : b:workspace
exec 'file ' . escape('[Locate in ' . locate_in . ']', ' ')
call eclim#common#locate#LocateFileCompletion()
endfunction " }}}
function! s:CloseScopeChooser() " {{{
let winnum = b:locate_winnr
bwipeout
exec winnum . 'winc w'
" hack to make :q work like the other close mappings
doautocmd BufEnter
" if we end up in a non-Locate window, make sure everything is as it should
" be (a hack for the above hack).
augroup locate_file_chooser_hack
autocmd!
autocmd BufEnter *
\ if bufname('%') !~ '^\[Locate in .*\]$' |
\ call eclim#common#locate#LocateFileClose() |
\ endif |
\ autocmd! locate_file_chooser_hack
augroup END
endfunction " }}}
function! s:LocateFileHelp() " {{{
let winnr = winnr()
noautocmd exec bufwinnr(b:results_bufnum) . 'winc w'
let help_bufnum = eclim#help#BufferHelp(s:help, 'vertical', 50)
exec winnr . 'winc w'
let b:help_bufnum = help_bufnum
return ''
endfunction " }}}
function! s:LocateFileConvertPattern(pattern, fuzzy) " {{{
let pattern = a:pattern
if a:fuzzy
let pattern = '.*' . substitute(pattern, '\(.\)', '\1.*?', 'g')
let pattern = substitute(pattern, '\.\([^*]\)', '\\.\1', 'g')
else
" if the user supplied a path, prepend a '.*/' to it so that they don't need
" to type full paths to match.
if pattern =~ '.\+/'
let pattern = '.*/' . pattern
endif
let pattern = substitute(pattern, '\*\*', '.*', 'g')
let pattern = substitute(pattern, '\(^\|\([^.]\)\)\*', '\1[^/]*?', 'g')
let pattern = substitute(pattern, '\.\([^*]\)', '\\.\1', 'g')
"let pattern = substitute(pattern, '\([^*]\)?', '\1.', 'g')
let pattern .= '.*'
endif
return pattern
endfunction " }}}
function! s:LocateFileFunction(scope) " {{{
if eclim#util#ListContains(s:scopes, a:scope)
return function('s:LocateFile_' . a:scope)
endif
return function('LocateFile_' . a:scope)
endfunction " }}}
function! s:LocateFileCommand(pattern) " {{{
let command = s:command_locate
if g:EclimLocateFileCaseInsensitive == 'always' ||
\ (a:pattern !~# '[A-Z]' && g:EclimLocateFileCaseInsensitive != 'never')
let command .= ' -i'
endif
let command .= ' -p "' . a:pattern . '"'
return command
endfunction " }}}
function! s:LocateFile_workspace(pattern) " {{{
let command = substitute(s:LocateFileCommand(a:pattern), '<scope>', 'workspace', '')
let results = eclim#Execute(command, {'workspace': b:workspace})
if type(results) != g:LIST_TYPE
return []
endif
return results
endfunction " }}}
function! s:LocateFile_project(pattern) " {{{
let command = substitute(s:LocateFileCommand(a:pattern), '<scope>', 'project', '')
let command .= ' -n "' . b:project . '"'
let results = eclim#Execute(command, {'workspace': b:workspace})
if type(results) != g:LIST_TYPE
return []
endif
return results
endfunction " }}}
function! s:LocateFile_buffers(pattern) " {{{
redir => list
silent exec 'buffers'
redir END
let buffers = map(split(list, '\n'),
\ "substitute(v:val, '.\\{-}\"\\(.\\{-}\\)\".*', '\\1', '')")
if a:pattern =~ '/'
let buffers = map(buffers, "fnamemodify(v:val, ':p')")
endif
if len(buffers) > 0
let tempfile = substitute(tempname(), '\', '/', 'g')
call writefile(buffers, tempfile)
try
return eclim#common#locate#LocateFileFromFileList(a:pattern, tempfile)
finally
call delete(tempfile)
endtry
endif
return []
endfunction " }}}
function! s:LocateFile_quickfix(pattern) " {{{
let buffers = []
let prev = ''
for entry in getqflist()
let name = bufname(entry.bufnr)
if a:pattern =~ '/'
let name = fnamemodify(name, ':p')
endif
if name != prev
call add(buffers, name)
let prev = name
endif
endfor
if len(buffers) > 0
let tempfile = substitute(tempname(), '\', '/', 'g')
call writefile(buffers, tempfile)
try
return eclim#common#locate#LocateFileFromFileList(a:pattern, tempfile)
finally
call delete(tempfile)
endtry
endif
return []
endfunction " }}}
function! eclim#common#locate#LocateFileFromFileList(pattern, file) " {{{
let file = a:file
if has('win32unix')
let file = eclim#cygwin#WindowsPath(file)
endif
if eclim#EclimAvailable(0)
let command = substitute(s:LocateFileCommand(a:pattern), '<scope>', 'list', '')
let command .= ' -f "' . file . '"'
let results = eclim#Execute(command, {'workspace': b:workspace})
if type(results) != g:LIST_TYPE
return []
endif
else
let results = []
for result in readfile(file)
call add(results, {'name': fnamemodify(result, ':t'), 'path': result})
endfor
endif
return results
endfunction " }}}
" vim:ft=vim:fdm=marker

View file

@ -0,0 +1,237 @@
" Author: Eric Van Dewoestine
"
" Description: {{{
"
" License:
"
" Copyright (C) 2005 - 2012 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" Global Variables {{{
if !exists("g:EclimTemplateDir")
let g:EclimTemplateDir = g:EclimBaseDir . '/template'
endif
if !exists("g:EclimTemplateExtension")
let g:EclimTemplateExtension = '.vim'
endif
if !exists("g:EclimTemplateIgnore")
let g:EclimTemplateIgnore = []
endif
" }}}
" Script Variables {{{
let s:quote = "['\"]"
let s:tag_regex =
\ '<vim:[a-zA-Z]\+\(\s\+[a-zA-Z]\+\s*=\s*' . s:quote . '.*' . s:quote . '\)\?\s*/>'
let s:tagname_regex = '.\{-}<vim:\([a-zA-Z]\+\).*'
" }}}
" Template() {{{
" Main method for finding and executing the template.
function! eclim#common#template#Template()
" allow some plugins to disable templates temporarily
if exists('g:EclimTemplateTempIgnore') && g:EclimTemplateTempIgnore
return
endif
" ignore certain file patterns
for ignore in g:EclimTemplateIgnore
if expand('%') =~ ignore
return
endif
endfor
let template = s:FindTemplate()
if template != ''
let lines = readfile(template)
call s:ExecuteTemplate(lines)
1,1delete _
endif
endfunction " }}}
" s:FindTemplate() {{{
" Finds the template file and returns the location.
function! s:FindTemplate()
let templatesDir = expand(g:EclimTemplateDir)
if !isdirectory(templatesDir)
call eclim#util#EchoDebug(
\ 'Template dir not found (g:EclimTemplateDir): ' . templatesDir)
return ''
endif
let filename = expand('%:t')
let ext = ""
" template equal to the filename
if filereadable(templatesDir . '/' . filename . g:EclimTemplateExtension)
return templatesDir . '/' . filename . g:EclimTemplateExtension
endif
" template pattern
let templates = globpath(templatesDir, '*' . g:EclimTemplateExtension)
for template in split(templates, '\n')
" remove path info
let temp_template = substitute(template, '.*[/\\]', '', '')
if g:EclimTemplateExtension != ''
let temp_template =
\ strpart(temp_template, 0, stridx(temp_template, g:EclimTemplateExtension))
endif
while stridx(temp_template, '.') != -1
let ext = strpart(temp_template, stridx(temp_template, '.'))
let temp_template = strpart(temp_template, 0, stridx(temp_template, '.'))
if filename =~ '.*' . temp_template . '.*' . ext
return template
endif
endwhile
endfor
" template equal to file extension
if stridx(filename, '.') > 0
let ext = strpart(filename, stridx(filename, '.'))
while stridx(ext, '.') != -1
let ext = strpart(ext, stridx(ext, '.') + 1)
if filereadable(templatesDir . '/' . ext . g:EclimTemplateExtension)
return templatesDir . '/' . ext . g:EclimTemplateExtension
endif
endwhile
endif
" template equal to file type
if filereadable(templatesDir . '/' . &ft . g:EclimTemplateExtension)
return templatesDir . '/' . &ft . g:EclimTemplateExtension
endif
return ''
endfunction " }}}
" s:ExecuteTemplate(lines) {{{
" Executes any logic in the supplied lines and appends those lines to the
" current file.
function! s:ExecuteTemplate(lines)
for line in a:lines
if line =~ s:tag_regex
let tag = substitute(line, s:tagname_regex, '\1', '')
call s:ExecuteTemplate(s:Process_{tag}(line))
else
call append(line('$'), line)
endif
endfor
endfunction " }}}
" s:EvaluateExpression(expression) {{{
" Evaluates the supplied expression.
function! s:EvaluateExpression(expression)
exec "return " . a:expression
endfunction " }}}
" s:GetAttribute(line, tag, attribute, fail) {{{
" Gets the an attribute value.
function! s:GetAttribute(line, tag, attribute, fail)
let attribute = substitute(a:line,
\ '.\{-}<vim:' . a:tag . '.\{-}\s\+' . a:attribute .
\ '\s*=\s*\(' . s:quote . '\)\(.\{-}\)\1.*/>.*',
\ '\2', '')
if attribute == a:line
if a:fail
call s:TemplateError(
\ a:line, "syntax error - missing '" . a:attribute . "' attribute")
endif
return ""
endif
return attribute
endfunction " }}}
" s:TemplateError(line, message) {{{
" Echos an error message to the user.
function! s:TemplateError(line, message)
call eclim#util#EchoError("Template error, line " . a:line . ": " . a:message)
endfunction " }}}
" s:Process_var(line) {{{
" Process <vim:var/> tags.
function! s:Process_var(line)
let name = expand(s:GetAttribute(a:line, 'var', 'name', 1))
let value = expand(s:GetAttribute(a:line, 'var', 'value', 1))
exec "let " . name . " = \"" . s:EvaluateExpression(value) . "\""
return []
endfunction " }}}
" s:Process_import(line) {{{
" Process <vim:import/> tags.
function! s:Process_import(line)
let resource = expand(s:GetAttribute(a:line, 'import', 'resource', 1))
if resource !~ '^/\'
let resource = expand(g:EclimTemplateDir . '/' . resource)
endif
if !filereadable(resource)
call s:TemplateError(a:line, "resource not found '" . resource . "'")
endif
exec "source " . resource
return []
endfunction " }}}
" s:Process_out(line) {{{
" Process <vim:out/> tags.
function! s:Process_out(line)
let value = s:GetAttribute(a:line, 'out', 'value', 1)
let result = s:EvaluateExpression(value)
return s:Out(a:line, '<vim:out\s\+.\{-}\s*\/>', result)
endfunction " }}}
" s:Process_include(line) {{{
" Process <vim:include/> tags.
function! s:Process_include(line)
let template = expand(
\ g:EclimTemplateDir . '/' . s:GetAttribute(a:line, 'include', 'template', 1))
if !filereadable(template)
call s:TemplateError(a:line, "template not found '" . template . "'")
return []
endif
return readfile(template)
endfunction " }}}
" s:Process_username(line) {{{
" Process <vim:username/> tags.
function! s:Process_username(line)
silent! let username = eclim#project#util#GetProjectSetting('org.eclim.user.name')
if type(username) == g:NUMBER_TYPE
let username = ''
endif
return s:Out(a:line, '<vim:username\s*\/>', username)
endfunction " }}}
" s:Out(line, pattern, value) {{{
function! s:Out(line, pattern, value)
let results = type(a:value) == g:LIST_TYPE ? a:value : [a:value]
if results[0] == '' && a:line =~ '^\s*' . a:pattern . '\s*$'
return []
endif
let line = substitute(a:line, a:pattern, results[0], '')
return [line] + (len(results) > 1 ? results[1:] : [])
endfunction " }}}
" vim:ft=vim:fdm=marker

View file

@ -0,0 +1,258 @@
" Author: Eric Van Dewoestine
"
" License: {{{
"
" Copyright (C) 2005 - 2014 Eric Van Dewoestine
"
" This program is free software: you can redistribute it and/or modify
" it under the terms of the GNU General Public License as published by
" the Free Software Foundation, either version 3 of the License, or
" (at your option) any later version.
"
" This program is distributed in the hope that it will be useful,
" but WITHOUT ANY WARRANTY; without even the implied warranty of
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
" GNU General Public License for more details.
"
" You should have received a copy of the GNU General Public License
" along with this program. If not, see <http://www.gnu.org/licenses/>.
"
" }}}
" Script Variables {{{
let s:command_read = '-command archive_read -f "<file>"'
" }}}
function! eclim#common#util#DiffLastSaved() " {{{
" Diff a modified file with the last saved version.
if &modified
let winnum = winnr()
let filetype=&ft
vertical belowright new | r #
1,1delete _
diffthis
setlocal buftype=nofile
setlocal bufhidden=wipe
setlocal nobuflisted
setlocal noswapfile
setlocal readonly
exec "setlocal ft=" . filetype
let diffnum = winnr()
augroup diff_saved
autocmd! BufUnload <buffer>
autocmd BufUnload <buffer> :diffoff!
augroup END
exec winnum . "winc w"
diffthis
" for some reason, these settings only take hold if set here.
call setwinvar(diffnum, "&foldmethod", "diff")
call setwinvar(diffnum, "&foldlevel", "0")
else
echo "No changes"
endif
endfunction " }}}
function! eclim#common#util#SwapWords() " {{{
" Initially based on http://www.vim.org/tips/tip.php?tip_id=329
" save the last search pattern
let save_search = @/
normal! "_yiw
let pos = getpos('.')
keepjumps s/\(\%#\w\+\)\(\_W\+\)\(\w\+\)/\3\2\1/
call setpos('.', pos)
" restore the last search pattern
let @/ = save_search
silent! call repeat#set(":call eclim#common#util#SwapWords()\<cr>", v:count)
endfunction " }}}
function! eclim#common#util#SwapAround(char) " {{{
if len(a:char) != 1
call eclim#util#EchoError('Arg must be a single character.')
return
endif
let pos = getpos('.')
let save_search = @/
try
let lnum = line('.')
let line = getline('.')
let start_col = 0
if line[col('.') - 1] =~ '[(\[{]'
let start_col = col('.')
normal! %
endif
let col = col('.')
exec 'normal! f' . a:char
if col('.') == col
call eclim#util#EchoError('Char not found on this line.')
return
endif
let delim_col = col('.')
let [_, end_col] = searchpos('\S', 'b', lnum)
if !start_col
if line[col('.') - 1] =~ '[)\]}]'
normal! %
let start_col = col('.')
else
let [_, start_col] = searchpos('[(\[{' . a:char . ']', 'b', lnum)
if start_col == end_col
call eclim#util#EchoError('Unable to determine the start of the first block.')
return
endif
let start_col += 1
endif
endif
let first = [start_col, end_col]
call cursor(0, delim_col)
let [_, start_col] = searchpos('\S', '', lnum)
if start_col == delim_col
call eclim#util#EchoError('Could not find item to swap with.')
return
endif
if line[col('.') - 1] =~ '[(\[{]'
normal! %
let end_col = col('.')
else
let [_, end_col] = searchpos('[)\]}' . a:char . ']', '', lnum)
if start_col == end_col
call eclim#util#EchoError('Unable to determine the end of the second block.')
return
endif
let end_col -= 1
endif
let second = [start_col, end_col]
let first_part = strpart(line, first[0] - 1, first[1] - first[0] + 1)
let second_part = strpart(line, second[0] - 1, second[1] - second[0] + 1)
" replace second with first
let prefix = strpart(line, 0, second[0] - 1)
let suffix = strpart(line, second[1])
let line = prefix . first_part . suffix
" replace first with second
let prefix = strpart(line, 0, first[0] - 1)
let suffix = strpart(line, first[1])
let line = prefix . second_part . suffix
call setline('.', line)
silent! call repeat#set(
\ ":call eclim#common#util#SwapAround(" . string(a:char) . ")\<cr>", v:count)
finally
call setpos('.', pos)
let @/ = save_search
endtry
endfunction " }}}
function! eclim#common#util#Tcd(dir) " {{{
" Like vim's :lcd, but tab local instead of window local.
let t:cwd = fnamemodify(a:dir, ':p')
" initialize the tab cwd for all other tabs if not already set
let curtab = tabpagenr()
try
let index = 1
while index <= tabpagenr('$')
if index != curtab
exec 'tabn ' . index
if !exists('t:cwd')
let t:cwd = getcwd()
" try to find a window without a localdir if necessary
if haslocaldir()
let curwin = winnr()
let windex = 1
while windex <= winnr('$')
if windex != curwin
exec windex . 'winc w'
if !haslocaldir()
let t:cwd = getcwd()
break
endif
endif
let windex += 1
endwhile
exec curwin . 'winc w'
endif
endif
endif
let index += 1
endwhile
finally
exec 'tabn ' . curtab
endtry
call s:ApplyTcd(0)
augroup tcd
autocmd!
autocmd TabEnter * call <SID>ApplyTcd(1)
augroup END
endfunction " }}}
function! s:ApplyTcd(honor_lcd) " {{{
if !exists('t:cwd')
return
endif
if a:honor_lcd && haslocaldir()
let lcwd = getcwd()
exec 'cd ' . escape(t:cwd, ' ')
exec 'lcd ' . escape(lcwd, ' ')
else
exec 'cd ' . escape(t:cwd, ' ')
endif
endfunction " }}}
function! eclim#common#util#ReadFile() " {{{
" Reads the contents of an archived file.
let archive = substitute(expand('%'), '\', '/', 'g')
let command = substitute(s:command_read, '<file>', archive, '')
let file = eclim#Execute(command)
if string(file) != '0'
let project = exists('b:eclim_project') ? b:eclim_project : ''
let bufnum = bufnr('%')
if has('win32unix')
let file = eclim#cygwin#CygwinPath(file)
endif
silent exec "keepalt keepjumps edit! " . escape(file, ' ')
if project != ''
let b:eclim_project = project
let b:eclim_file = archive
endif
exec 'bdelete ' . bufnum
" alternate solution, that keeps the archive url as the buffer's filename,
" but prevents taglist from being able to parse tags.
"setlocal noreadonly
"setlocal modifiable
"silent! exec "read " . file
"1,1delete _
silent exec "doautocmd BufReadPre " . file
silent exec "doautocmd BufReadPost " . file
setlocal readonly
setlocal nomodifiable
setlocal noswapfile
" causes taglist.vim errors (fold then delete fails)
"setlocal bufhidden=delete
endif
endfunction " }}}
" vim:ft=vim:fdm=marker