diff options
Diffstat (limited to 'autoload/l9')
-rw-r--r-- | autoload/l9/async.py | 92 | ||||
-rw-r--r-- | autoload/l9/async.vim | 67 | ||||
-rw-r--r-- | autoload/l9/quickfix.vim | 107 | ||||
-rw-r--r-- | autoload/l9/tempbuffer.vim | 112 | ||||
-rw-r--r-- | autoload/l9/tempvariables.vim | 60 |
5 files changed, 438 insertions, 0 deletions
diff --git a/autoload/l9/async.py b/autoload/l9/async.py new file mode 100644 index 0000000..eeb0cc3 --- /dev/null +++ b/autoload/l9/async.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python + +from __future__ import with_statement +import vim +import os +import subprocess +import threading +import Queue + + +class Asyncer: + + def __init__(self): + self._workers = {} + + def execute(self, var_key, var_command, var_cwd, var_input, var_appends): + key = vim.eval(var_key) + command = vim.eval(var_command) + cwd = vim.eval(var_cwd) + input = vim.eval(var_input) + appends = vim.eval(var_appends) + if key not in self._workers: + self._workers[key] = Worker() + self._workers[key].start() + self._workers[key].put(Executor(command, cwd, input, appends)) + + def print_output(self, var_key): + key = vim.eval(var_key) + if key not in self._workers: + return + for l in self._workers[key].copy_outputs(): + print l, + + def print_worker_keys(self): + for k in self._workers.keys(): + print k + + def print_active_worker_keys(self): + for k in self._workers.keys(): + print k + + +class Worker(threading.Thread): + + def __init__(self): + threading.Thread.__init__(self) + self._queue = Queue.Queue() + self._lines = [] + self._lock = threading.Lock() + + def run(self): + while True: + self._queue.get().execute(self) + self._queue.task_done() + + def put(self, executor): + self._queue.put(executor) + + def clear_outputs(self): + with self._lock: + self._lines = [] + + def record_output(self, line): + with self._lock: + self._lines.append(line) + + def copy_outputs(self): + with self._lock: + return self._lines[:] + + +class Executor: + + def __init__(self, command, cwd, input, appends): + self._command = command + self._cwd = cwd + self._input = input + self._appends = appends + + def execute(self, worker): + if not self._appends: + worker.clear_outputs() + os.chdir(self._cwd) + p = subprocess.Popen(self._command, shell=True, stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + p.stdin.write(self._input) + line = p.stdout.readline() + while line: + worker.record_output(line) + line = p.stdout.readline() + + diff --git a/autoload/l9/async.vim b/autoload/l9/async.vim new file mode 100644 index 0000000..fa66e9f --- /dev/null +++ b/autoload/l9/async.vim @@ -0,0 +1,67 @@ +"============================================================================= +" Copyright (C) 2009-2010 Takeshi NISHIDA +" +"============================================================================= +" LOAD GUARD {{{1 + +if !l9#guardScriptLoading(expand('<sfile>:p'), 0, 0, ['has("python")']) + finish +endif + +" }}}1 +"============================================================================= +" ASYNC EXECUTE {{{1 + +" +function s:checkKey(key) + if a:key =~ '\n' || a:key !~ '\S' + throw "Asyncer: Invalid key: " . a:key + endif +endfunction + +" +function l9#async#execute(key, cmd, cwd, input, appends) + call s:checkKey(a:key) + python asyncer.execute('a:key', 'a:cmd', 'a:cwd', 'a:input', 'a:appends') +endfunction + +" +function l9#async#read(key) + call s:checkKey(a:key) + redir => result + silent python asyncer.print_output('a:key') + redir END + " NOTE: "\n" is somehow inserted by redir. + return (result[0] ==# "\n" ? result[1:] : result) +endfunction + +" +function l9#async#listWorkers() + redir => result + silent python asyncer.print_worker_keys() + redir END + return split(result, "\n") +endfunction + +" +function l9#async#listActiveWorkers() + redir => result + silent python asyncer.print_active_worker_keys() + redir END + return split(result, "\n") +endfunction + +" }}}1 +"============================================================================= +" INITIALIZATION {{{1 + +let s:ASYNC_PY_PATH = fnamemodify(expand('<sfile>:p:h'), ':p') . 'async.py' + +pyfile `=s:ASYNC_PY_PATH` +python asyncer = Asyncer() + +" }}}1 +"============================================================================= +" vim: set fdm=marker: + + diff --git a/autoload/l9/quickfix.vim b/autoload/l9/quickfix.vim new file mode 100644 index 0000000..1758b39 --- /dev/null +++ b/autoload/l9/quickfix.vim @@ -0,0 +1,107 @@ +"============================================================================= +" Copyright (C) 2009-2010 Takeshi NISHIDA +" +"============================================================================= +" LOAD GUARD {{{1 + +if !l9#guardScriptLoading(expand('<sfile>:p'), 0, 0, []) + finish +endif + +" }}}1 +"============================================================================= +" QUICKFIX {{{1 + +" Returns non-zero if quickfix window is opened. +function l9#quickfix#isWindowOpened() + return count(map(range(1, winnr('$')), 'getwinvar(v:val, "&buftype")'), 'quickfix') > 0 +endfunction + +" Opens quickfix window if quickfix is not empty, and echo the number of errors. +" +" a:onlyRecognized: if non-zero, opens only if quickfix has recognized errors. +" a:holdCursor: if non-zero, the cursor won't move to quickfix window. +function l9#quickfix#openIfNotEmpty(onlyRecognized, holdCursor) + let numErrors = len(filter(getqflist(), 'v:val.valid')) + let numOthers = len(getqflist()) - numErrors + if numErrors > 0 || (!a:onlyRecognized && numOthers > 0) + copen + if a:holdCursor + wincmd p + endif + else + cclose + endif + redraw + if numOthers > 0 + echo printf('Quickfix: %d(+%d)', numErrors, numOthers) + else + echo printf('Quickfix: %d', numErrors) + endif +endfunction + +" Toggles Quickfix window +function l9#quickfix#toggleWindow() + if l9#quickfix#isWindowOpened() + cclose + else + call l9#quickfix#openIfNotEmpty(0, 0) + endif +endfunction + +" Creates quickfix list form given lines and opens the quickfix window if +" errors exists. +" +" a:lines: +" a:jump: if non-zero, jump to the first error. +function l9#quickfix#setMakeResult(lines) + cexpr a:lines + call l9#quickfix#openIfNotEmpty(0, 1) +endfunction + +" Compares quickfix entries for sorting. +function l9#quickfix#compareEntries(e0, e1) + if a:e0.bufnr != a:e1.bufnr + let i0 = bufname(a:e0.bufnr) + let i1 = bufname(a:e1.bufnr) + elseif a:e0.lnum != a:e1.lnum + let i0 = a:e0.lnum + let i1 = a:e1.lnum + elseif a:e0.col != a:e1.col + let i0 = a:e0.col + let i1 = a:e1.col + else + return 0 + endif + return (i0 > i1 ? +1 : -1) +endfunction + +" Sorts quickfix +function l9#quickfix#sort() + call setqflist(sort(getqflist(), 'l9#quickfix#compareEntries'), 'r') +endfunction + +" Highlights Quickfix lines by :sign. +" Inspired by errormarker plugin. +" +" You can customize the highlighting via L9ErrorLine and L9WarningLine +" highlight groups. +function l9#quickfix#placeSign() + let warnings = [] + let errors = [] + for e in filter(getqflist(), 'v:val.valid') + let warning = (e.type ==? 'w' || e.text =~? '^\s*warning:') + call add((warning ? warnings : errors), [e.bufnr, e.lnum]) + endfor + sign unplace * + call l9#placeSign('L9WarningLine', '>>', '', warnings) + call l9#placeSign('L9ErrorLine', '>>', '', errors) +endfunction + +highlight default L9ErrorLine ctermfg=white ctermbg=52 guibg=#5F0000 +highlight default L9WarningLine ctermfg=white ctermbg=17 guibg=#00005F + +" }}}1 +"============================================================================= +" vim: set fdm=marker: + diff --git a/autoload/l9/tempbuffer.vim b/autoload/l9/tempbuffer.vim new file mode 100644 index 0000000..6f11a78 --- /dev/null +++ b/autoload/l9/tempbuffer.vim @@ -0,0 +1,112 @@ +"============================================================================= +" Copyright (C) 2009-2010 Takeshi NISHIDA +" +"============================================================================= +" LOAD GUARD {{{1 + +if !l9#guardScriptLoading(expand('<sfile>:p'), 0, 0, []) + finish +endif + +" }}}1 +"============================================================================= +" TEMPORARY BUFFER {{{1 + +" each key is a buffer name. +let s:dataMap = {} + +" +function s:onBufDelete(bufname) + if exists('s:dataMap[a:bufname].listener.onClose') + call s:dataMap[a:bufname].listener.onClose(s:dataMap[a:bufname].written) + endif + if bufnr('%') == s:dataMap[a:bufname].bufNr && winnr('#') != 0 + " if winnr('#') returns 0, "wincmd p" causes ringing the bell. + wincmd p + endif +endfunction + +" +function s:onBufWriteCmd(bufname) + if !exists('s:dataMap[a:bufname].listener.onWrite') || + \ s:dataMap[a:bufname].listener.onWrite(getline(1, '$')) + setlocal nomodified + let s:dataMap[a:bufname].written = 1 + call l9#tempbuffer#close(a:bufname) + else + endif +endfunction + +" a:bufname: +" a:height: Window height. If 0, default height is used. +" If less than 0, the window becomes full-screen. +" a:listener: +" a:listener.onClose(written) +function l9#tempbuffer#openScratch(bufname, filetype, lines, topleft, vertical, height, listener) + let openCmdPrefix = (a:topleft ? 'topleft ' : '') + \ . (a:vertical ? 'vertical ' : '') + \ . (a:height > 0 ? a:height : '') + if !exists('s:dataMap[a:bufname]') || !bufexists(s:dataMap[a:bufname].bufNr) + execute openCmdPrefix . 'new' + else + call l9#tempbuffer#close(a:bufname) + execute openCmdPrefix . 'split' + execute 'silent ' . s:dataMap[a:bufname].bufNr . 'buffer' + endif + if a:height < 0 + only + endif + setlocal buflisted noswapfile bufhidden=delete modifiable noreadonly buftype=nofile + let &l:filetype = a:filetype + silent file `=a:bufname` + call setline(1, a:lines) + setlocal nomodified + augroup L9TempBuffer + autocmd! * <buffer> + execute printf('autocmd BufDelete <buffer> call s:onBufDelete (%s)', string(a:bufname)) + execute printf('autocmd BufWriteCmd <buffer> nested call s:onBufWriteCmd(%s)', string(a:bufname)) + augroup END + let s:dataMap[a:bufname] = { + \ 'bufNr': bufnr('%'), + \ 'written': 0, + \ 'listener': a:listener, + \ } +endfunction + +" +function l9#tempbuffer#openReadOnly(bufname, filetype, lines, topleft, vertical, height, listener) + call l9#tempbuffer#openScratch(a:bufname, a:filetype, a:lines, a:topleft, a:vertical, a:height, a:listener) + setlocal nomodifiable readonly +endfunction + +" a:listener: +" a:listener.onClose(written) +" a:listener.onWrite(lines) +function l9#tempbuffer#openWritable(bufname, filetype, lines, topleft, vertical, height, listener) + call l9#tempbuffer#openScratch(a:bufname, a:filetype, a:lines, a:topleft, a:vertical, a:height, a:listener) + setlocal buftype=acwrite +endfunction + +" makes specified temp buffer current. +function l9#tempbuffer#moveTo(bufname) + return l9#moveToBufferWindowInCurrentTabpage(s:dataMap[a:bufname].bufNr) || + \ l9#moveToBufferWindowInOtherTabpage(s:dataMap[a:bufname].bufNr) +endfunction + +" +function l9#tempbuffer#close(bufname) + if !l9#tempbuffer#isOpen(a:bufname) + return + endif + execute printf('%dbdelete!', s:dataMap[a:bufname].bufNr) +endfunction + +" +function l9#tempbuffer#isOpen(bufname) + return exists('s:dataMap[a:bufname]') && bufloaded(s:dataMap[a:bufname].bufNr) +endfunction + +" }}}1 +"============================================================================= +" vim: set fdm=marker: + diff --git a/autoload/l9/tempvariables.vim b/autoload/l9/tempvariables.vim new file mode 100644 index 0000000..ee847ee --- /dev/null +++ b/autoload/l9/tempvariables.vim @@ -0,0 +1,60 @@ +"============================================================================= +" Copyright (C) 2010 Takeshi NISHIDA +" +"============================================================================= +" LOAD GUARD {{{1 + +if !l9#guardScriptLoading(expand('<sfile>:p'), 0, 0, []) + finish +endif + +" }}}1 +"============================================================================= +" TEMPORARY VARIABLES {{{1 + +" +let s:origMap = {} + +" set temporary variables +function l9#tempvariables#set(group, name, value) + if !exists('s:origMap[a:group]') + let s:origMap[a:group] = {} + endif + if !exists('s:origMap[a:group][a:name]') + let s:origMap[a:group][a:name] = eval(a:name) + endif + execute 'let ' . a:name . ' = a:value' +endfunction + +" set temporary variables +function l9#tempvariables#setList(group, variables) + for [name, value] in a:variables + call l9#tempvariables#set(a:group, name, value) + unlet value " to avoid E706 + endfor +endfunction + +" get temporary variables +function l9#tempvariables#getList(group) + if !exists('s:origMap[a:group]') + return [] + endif + return map(keys(s:origMap[a:group]), '[v:val, eval(v:val)]') +endfunction + +" restore original variables and clean up. +function l9#tempvariables#end(group) + if !exists('s:origMap[a:group]') + return + endif + for [name, value] in items(s:origMap[a:group]) + execute 'let ' . name . ' = value' + unlet value " to avoid E706 + endfor + unlet s:origMap[a:group] +endfunction + +" }}}1 +"============================================================================= +" vim: set fdm=marker: + |