From 388bc749e73cc2214e633fb397ad631e7943c145 Mon Sep 17 00:00:00 2001 From: gryf Date: Tue, 7 Dec 2010 20:57:23 +0100 Subject: [PATCH] Removed ACP plugin. Found it annoying after a while. Reorganized rst2blogger plugin. Added documentation for it. --- GetLatest/GetLatestVimScripts.dat | 1 - autoload/acp.vim | 431 ----------- doc/acp.txt | 512 ------------- doc/project.txt | 710 ------------------ doc/vimblogger_ft.txt | 198 +++++ ftplugin/rst/blogger.vim | 98 --- ftplugin/rst/commons.vim | 4 + ftplugin/rst/rst2blogger/__init__.py | 1 + ftplugin/rst/rst2blogger/blogger.py | 258 +++++++ ftplugin/rst/rst2blogger/main.py | 197 +++++ .../rst/{vimblogger => rst2blogger}/rest.py | 35 +- ftplugin/rst/vimblogger/blogger.py | 130 ---- ftplugin/rst/vimblogger_ft.vim | 72 ++ plugin/acp.vim | 170 ----- snippets/python.snippets | 8 + 15 files changed, 760 insertions(+), 2065 deletions(-) delete mode 100644 autoload/acp.vim delete mode 100644 doc/acp.txt delete mode 100644 doc/project.txt create mode 100644 doc/vimblogger_ft.txt delete mode 100644 ftplugin/rst/blogger.vim create mode 100644 ftplugin/rst/rst2blogger/__init__.py create mode 100644 ftplugin/rst/rst2blogger/blogger.py create mode 100644 ftplugin/rst/rst2blogger/main.py rename ftplugin/rst/{vimblogger => rst2blogger}/rest.py (90%) delete mode 100644 ftplugin/rst/vimblogger/blogger.py create mode 100644 ftplugin/rst/vimblogger_ft.vim delete mode 100644 plugin/acp.vim diff --git a/GetLatest/GetLatestVimScripts.dat b/GetLatest/GetLatestVimScripts.dat index de6141c..fc57161 100644 --- a/GetLatest/GetLatestVimScripts.dat +++ b/GetLatest/GetLatestVimScripts.dat @@ -9,7 +9,6 @@ ScriptID SourceID Filename 2666 13424 Mark 2262 8944 occur.vim 910 14349 pydoc.vim -1879 11894 AutoComplPop #2421 9423 pysmell.vim 152 3342 showmarks.vim 2540 11006 snipMate.vim diff --git a/autoload/acp.vim b/autoload/acp.vim deleted file mode 100644 index 827bbcc..0000000 --- a/autoload/acp.vim +++ /dev/null @@ -1,431 +0,0 @@ -"============================================================================= -" Copyright (c) 2007-2009 Takeshi NISHIDA -" -"============================================================================= -" LOAD GUARD {{{1 - -if exists('g:loaded_autoload_acp') || v:version < 702 - finish -endif -let g:loaded_autoload_acp = 1 - -" }}}1 -"============================================================================= -" GLOBAL FUNCTIONS: {{{1 - -" -function acp#enable() - call acp#disable() - - augroup AcpGlobalAutoCommand - autocmd! - autocmd InsertEnter * unlet! s:posLast s:lastUncompletable - autocmd InsertLeave * call s:finishPopup(1) - augroup END - - if g:acp_mappingDriven - call s:mapForMappingDriven() - else - autocmd AcpGlobalAutoCommand CursorMovedI * call s:feedPopup() - endif - - nnoremap i i=feedPopup() - nnoremap a a=feedPopup() - nnoremap R R=feedPopup() -endfunction - -" -function acp#disable() - call s:unmapForMappingDriven() - augroup AcpGlobalAutoCommand - autocmd! - augroup END - nnoremap i | nunmap i - nnoremap a | nunmap a - nnoremap R | nunmap R -endfunction - -" -function acp#lock() - let s:lockCount += 1 -endfunction - -" -function acp#unlock() - let s:lockCount -= 1 - if s:lockCount < 0 - let s:lockCount = 0 - throw "AutoComplPop: not locked" - endif -endfunction - -" -function acp#meetsForSnipmate(context) - if g:acp_behaviorSnipmateLength < 0 - return 0 - endif - let matches = matchlist(a:context, '\(^\|\s\|\<\)\(\u\{' . - \ g:acp_behaviorSnipmateLength . ',}\)$') - return !empty(matches) && !empty(s:getMatchingSnipItems(matches[2])) -endfunction - -" -function acp#meetsForKeyword(context) - if g:acp_behaviorKeywordLength < 0 - return 0 - endif - let matches = matchlist(a:context, '\(\k\{' . g:acp_behaviorKeywordLength . ',}\)$') - if empty(matches) - return 0 - endif - for ignore in g:acp_behaviorKeywordIgnores - if stridx(ignore, matches[1]) == 0 - return 0 - endif - endfor - return 1 -endfunction - -" -function acp#meetsForFile(context) - if g:acp_behaviorFileLength < 0 - return 0 - endif - if has('win32') || has('win64') - let separator = '[/\\]' - else - let separator = '\/' - endif - if a:context !~ '\f' . separator . '\f\{' . g:acp_behaviorFileLength . ',}$' - return 0 - endif - return a:context !~ '[*/\\][/\\]\f*$\|[^[:print:]]\f*$' -endfunction - -" -function acp#meetsForRubyOmni(context) - if !has('ruby') - return 0 - endif - if g:acp_behaviorRubyOmniMethodLength >= 0 && - \ a:context =~ '[^. \t]\(\.\|::\)\k\{' . - \ g:acp_behaviorRubyOmniMethodLength . ',}$' - return 1 - endif - if g:acp_behaviorRubyOmniSymbolLength >= 0 && - \ a:context =~ '\(^\|[^:]\):\k\{' . - \ g:acp_behaviorRubyOmniSymbolLength . ',}$' - return 1 - endif - return 0 -endfunction - -" -function acp#meetsForPythonOmni(context) - return has('python') && g:acp_behaviorPythonOmniLength >= 0 && - \ a:context =~ '\k\.\k\{' . g:acp_behaviorPythonOmniLength . ',}$' -endfunction - -" -function acp#meetsForPerlOmni(context) - return g:acp_behaviorPerlOmniLength >= 0 && - \ a:context =~ '\w->\k\{' . g:acp_behaviorPerlOmniLength . ',}$' -endfunction - -" -function acp#meetsForXmlOmni(context) - return g:acp_behaviorXmlOmniLength >= 0 && - \ a:context =~ '\(<\|<\/\|<[^>]\+ \|<[^>]\+=\"\)\k\{' . - \ g:acp_behaviorXmlOmniLength . ',}$' -endfunction - -" -function acp#meetsForHtmlOmni(context) - return g:acp_behaviorHtmlOmniLength >= 0 && - \ a:context =~ '\(<\|<\/\|<[^>]\+ \|<[^>]\+=\"\)\k\{' . - \ g:acp_behaviorHtmlOmniLength . ',}$' -endfunction - -" -function acp#meetsForCssOmni(context) - if g:acp_behaviorCssOmniPropertyLength >= 0 && - \ a:context =~ '\(^\s\|[;{]\)\s*\k\{' . - \ g:acp_behaviorCssOmniPropertyLength . ',}$' - return 1 - endif - if g:acp_behaviorCssOmniValueLength >= 0 && - \ a:context =~ '[:@!]\s*\k\{' . - \ g:acp_behaviorCssOmniValueLength . ',}$' - return 1 - endif - return 0 -endfunction - -" -function acp#completeSnipmate(findstart, base) - if a:findstart - let s:posSnipmateCompletion = len(matchstr(s:getCurrentText(), '.*\U')) - return s:posSnipmateCompletion - endif - let lenBase = len(a:base) - let items = filter(GetSnipsInCurrentScope(), - \ 'strpart(v:key, 0, lenBase) ==? a:base') - return map(sort(items(items)), 's:makeSnipmateItem(v:val[0], v:val[1])') -endfunction - -" -function acp#onPopupCloseSnipmate() - let word = s:getCurrentText()[s:posSnipmateCompletion :] - for trigger in keys(GetSnipsInCurrentScope()) - if word ==# trigger - call feedkeys("\=TriggerSnippet()\", "n") - return 0 - endif - endfor - return 1 -endfunction - -" -function acp#onPopupPost() - " to clear = expression on command-line - echo '' - if pumvisible() - inoremap acp#onBs() - inoremap acp#onBs() - " a command to restore to original text and select the first match - return (s:behavsCurrent[s:iBehavs].command =~# "\" ? "\\" - \ : "\\") - endif - let s:iBehavs += 1 - if len(s:behavsCurrent) > s:iBehavs - call s:setCompletefunc() - return printf("\%s\=acp#onPopupPost()\", - \ s:behavsCurrent[s:iBehavs].command) - else - let s:lastUncompletable = { - \ 'word': s:getCurrentWord(), - \ 'commands': map(copy(s:behavsCurrent), 'v:val.command')[1:], - \ } - call s:finishPopup(0) - return "\" - endif -endfunction - -" -function acp#onBs() - " using "matchstr" and not "strpart" in order to handle multi-byte - " characters - if call(s:behavsCurrent[s:iBehavs].meets, - \ [matchstr(s:getCurrentText(), '.*\ze.')]) - return "\" - endif - return "\\" -endfunction - -" }}}1 -"============================================================================= -" LOCAL FUNCTIONS: {{{1 - -" -function s:mapForMappingDriven() - call s:unmapForMappingDriven() - let s:keysMappingDriven = [ - \ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - \ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - \ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - \ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - \ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - \ '-', '_', '~', '^', '.', ',', ':', '!', '#', '=', '%', '$', '@', '<', '>', '/', '\', - \ '', '', '', ] - for key in s:keysMappingDriven - execute printf('inoremap %s %s=feedPopup()', - \ key, key) - endfor -endfunction - -" -function s:unmapForMappingDriven() - if !exists('s:keysMappingDriven') - return - endif - for key in s:keysMappingDriven - execute 'iunmap ' . key - endfor - let s:keysMappingDriven = [] -endfunction - -" -function s:setTempOption(group, name, value) - call extend(s:tempOptionSet[a:group], { a:name : eval('&' . a:name) }, 'keep') - execute printf('let &%s = a:value', a:name) -endfunction - -" -function s:restoreTempOptions(group) - for [name, value] in items(s:tempOptionSet[a:group]) - execute printf('let &%s = value', name) - endfor - let s:tempOptionSet[a:group] = {} -endfunction - -" -function s:getCurrentWord() - return matchstr(s:getCurrentText(), '\k*$') -endfunction - -" -function s:getCurrentText() - return strpart(getline('.'), 0, col('.') - 1) -endfunction - -" -function s:getPostText() - return strpart(getline('.'), col('.') - 1) -endfunction - -" -function s:isModifiedSinceLastCall() - if exists('s:posLast') - let posPrev = s:posLast - let nLinesPrev = s:nLinesLast - let textPrev = s:textLast - endif - let s:posLast = getpos('.') - let s:nLinesLast = line('$') - let s:textLast = getline('.') - if !exists('posPrev') - return 1 - elseif posPrev[1] != s:posLast[1] || nLinesPrev != s:nLinesLast - return (posPrev[1] - s:posLast[1] == nLinesPrev - s:nLinesLast) - elseif textPrev ==# s:textLast - return 0 - elseif posPrev[2] > s:posLast[2] - return 1 - elseif has('gui_running') && has('multi_byte') - " NOTE: auto-popup causes a strange behavior when IME/XIM is working - return posPrev[2] + 1 == s:posLast[2] - endif - return posPrev[2] != s:posLast[2] -endfunction - -" -function s:makeCurrentBehaviorSet() - let modified = s:isModifiedSinceLastCall() - if exists('s:behavsCurrent[s:iBehavs].repeat') && s:behavsCurrent[s:iBehavs].repeat - let behavs = [ s:behavsCurrent[s:iBehavs] ] - elseif exists('s:behavsCurrent[s:iBehavs]') - return [] - elseif modified - let behavs = copy(exists('g:acp_behavior[&filetype]') - \ ? g:acp_behavior[&filetype] - \ : g:acp_behavior['*']) - else - return [] - endif - let text = s:getCurrentText() - call filter(behavs, 'call(v:val.meets, [text])') - let s:iBehavs = 0 - if exists('s:lastUncompletable') && - \ stridx(s:getCurrentWord(), s:lastUncompletable.word) == 0 && - \ map(copy(behavs), 'v:val.command') ==# s:lastUncompletable.commands - let behavs = [] - else - unlet! s:lastUncompletable - endif - return behavs -endfunction - -" -function s:feedPopup() - " NOTE: CursorMovedI is not triggered while the popup menu is visible. And - " it will be triggered when popup menu is disappeared. - if s:lockCount > 0 || pumvisible() || &paste - return '' - endif - if exists('s:behavsCurrent[s:iBehavs].onPopupClose') - if !call(s:behavsCurrent[s:iBehavs].onPopupClose, []) - call s:finishPopup(1) - return '' - endif - endif - let s:behavsCurrent = s:makeCurrentBehaviorSet() - if empty(s:behavsCurrent) - call s:finishPopup(1) - return '' - endif - " In case of dividing words by symbols (e.g. "for(int", "ab==cd") while a - " popup menu is visible, another popup is not available unless input - " or try popup once. So first completion is duplicated. - call insert(s:behavsCurrent, s:behavsCurrent[s:iBehavs]) - call s:setTempOption(s:GROUP0, 'spell', 0) - call s:setTempOption(s:GROUP0, 'completeopt', 'menuone' . (g:acp_completeoptPreview ? ',preview' : '')) - call s:setTempOption(s:GROUP0, 'complete', g:acp_completeOption) - call s:setTempOption(s:GROUP0, 'ignorecase', g:acp_ignorecaseOption) - " NOTE: With CursorMovedI driven, Set 'lazyredraw' to avoid flickering. - " With Mapping driven, set 'nolazyredraw' to make a popup menu visible. - call s:setTempOption(s:GROUP0, 'lazyredraw', !g:acp_mappingDriven) - " NOTE: 'textwidth' must be restored after . - call s:setTempOption(s:GROUP1, 'textwidth', 0) - call s:setCompletefunc() - call feedkeys(s:behavsCurrent[s:iBehavs].command . "\=acp#onPopupPost()\", 'n') - return '' " this function is called by = -endfunction - -" -function s:finishPopup(fGroup1) - inoremap | iunmap - inoremap | iunmap - let s:behavsCurrent = [] - call s:restoreTempOptions(s:GROUP0) - if a:fGroup1 - call s:restoreTempOptions(s:GROUP1) - endif -endfunction - -" -function s:setCompletefunc() - if exists('s:behavsCurrent[s:iBehavs].completefunc') - call s:setTempOption(0, 'completefunc', s:behavsCurrent[s:iBehavs].completefunc) - endif -endfunction - -" -function s:makeSnipmateItem(key, snip) - if type(a:snip) == type([]) - let descriptions = map(copy(a:snip), 'v:val[0]') - let snipFormatted = '[MULTI] ' . join(descriptions, ', ') - else - let snipFormatted = substitute(a:snip, '\(\n\|\s\)\+', ' ', 'g') - endif - return { - \ 'word': a:key, - \ 'menu': strpart(snipFormatted, 0, 80), - \ } -endfunction - -" -function s:getMatchingSnipItems(base) - let key = a:base . "\n" - if !exists('s:snipItems[key]') - let s:snipItems[key] = items(GetSnipsInCurrentScope()) - call filter(s:snipItems[key], 'strpart(v:val[0], 0, len(a:base)) ==? a:base') - call map(s:snipItems[key], 's:makeSnipmateItem(v:val[0], v:val[1])') - endif - return s:snipItems[key] -endfunction - -" }}}1 -"============================================================================= -" INITIALIZATION {{{1 - -let s:GROUP0 = 0 -let s:GROUP1 = 1 -let s:lockCount = 0 -let s:behavsCurrent = [] -let s:iBehavs = 0 -let s:tempOptionSet = [{}, {}] -let s:snipItems = {} - -" }}}1 -"============================================================================= -" vim: set fdm=marker: diff --git a/doc/acp.txt b/doc/acp.txt deleted file mode 100644 index 324c88b..0000000 --- a/doc/acp.txt +++ /dev/null @@ -1,512 +0,0 @@ -*acp.txt* Automatically opens popup menu for completions. - - Copyright (c) 2007-2009 Takeshi NISHIDA - -AutoComplPop *autocomplpop* *acp* - -INTRODUCTION |acp-introduction| -INSTALLATION |acp-installation| -USAGE |acp-usage| -COMMANDS |acp-commands| -OPTIONS |acp-options| -SPECIAL THANKS |acp-thanks| -CHANGELOG |acp-changelog| -ABOUT |acp-about| - - -============================================================================== -INTRODUCTION *acp-introduction* - -With this plugin, your vim comes to automatically opens popup menu for -completions when you enter characters or move the cursor in Insert mode. It -won't prevent you continuing entering characters. - - -============================================================================== -INSTALLATION *acp-installation* - -Put all files into your runtime directory. If you have the zip file, extract -it to your runtime directory. - -You should place the files as follows: -> - /plugin/acp.vim - /doc/acp.txt - ... -< -If you disgust to jumble up this plugin and other plugins in your runtime -directory, put the files into new directory and just add the directory path to -'runtimepath'. It's easy to uninstall the plugin. - -And then update your help tags files to enable fuzzyfinder help. See -|add-local-help| for details. - - -============================================================================== -USAGE *acp-usage* - -Once this plugin is installed, auto-popup is enabled at startup by default. - -Which completion method is used depends on the text before the cursor. The -default behavior is as follows: - - kind filetype text before the cursor ~ - Keyword * two keyword characters - Filename * a filename character + a path separator - + 0 or more filename character - Omni ruby ".", "::" or non-word character + ":" - (|+ruby| required.) - Omni python "." (|+python| required.) - Omni xml "<", "" characters + " ") - Omni html/xhtml "<", "" characters + " ") - Omni css (":", ";", "{", "^", "@", or "!") - + 0 or 1 space - -Also, you can make user-defined completion and snipMate's trigger completion -(|acp-snipMate|) auto-popup if the options are set. - -These behavior are customizable. - - *acp-snipMate* -snipMate's Trigger Completion ~ - -snipMate's trigger completion enables you to complete a snippet trigger -provided by snipMate plugin -(http://www.vim.org/scripts/script.php?script_id=2540) and expand it. - - -To enable auto-popup for this completion, add following function to -plugin/snipMate.vim: -> - fun! GetSnipsInCurrentScope() - let snips = {} - for scope in [bufnr('%')] + split(&ft, '\.') + ['_'] - call extend(snips, get(s:snippets, scope, {}), 'keep') - call extend(snips, get(s:multi_snips, scope, {}), 'keep') - endfor - return snips - endf -< -And set |g:acp_behaviorSnipmateLength| option to 1. - -There is the restriction on this auto-popup, that the word before cursor must -consist only of uppercase characters. - - *acp-perl-omni* -Perl Omni-Completion ~ - -AutoComplPop supports perl-completion.vim -(http://www.vim.org/scripts/script.php?script_id=2852). - -To enable auto-popup for this completion, set |g:acp_behaviorPerlOmniLength| -option to 0 or more. - - -============================================================================== -COMMANDS *acp-commands* - - *:AcpEnable* -:AcpEnable - enables auto-popup. - - *:AcpDisable* -:AcpDisable - disables auto-popup. - - *:AcpLock* -:AcpLock - suspends auto-popup temporarily. - - For the purpose of avoiding interruption to another script, it is - recommended to insert this command and |:AcpUnlock| than |:AcpDisable| - and |:AcpEnable| . - - *:AcpUnlock* -:AcpUnlock - resumes auto-popup suspended by |:AcpLock| . - - -============================================================================== -OPTIONS *acp-options* - - *g:acp_enableAtStartup* > - let g:acp_enableAtStartup = 1 -< - If non-zero, auto-popup is enabled at startup. - - *g:acp_mappingDriven* > - let g:acp_mappingDriven = 0 -< - If non-zero, auto-popup is triggered by key mappings instead of - |CursorMovedI| event. This is useful to avoid auto-popup by moving - cursor in Insert mode. - - *g:acp_ignorecaseOption* > - let g:acp_ignorecaseOption = 1 -< - Value set to 'ignorecase' temporarily when auto-popup. - - *g:acp_completeOption* > - let g:acp_completeOption = '.,w,b,k' -< - Value set to 'complete' temporarily when auto-popup. - - *g:acp_completeoptPreview* > - let g:acp_completeoptPreview = 0 -< - If non-zero, "preview" is added to 'completeopt' when auto-popup. - - *g:acp_behaviorUserDefinedFunction* > - let g:acp_behaviorUserDefinedFunction = '' -< - |g:acp_behavior-completefunc| for user-defined completion. If empty, - this completion will be never attempted. - - *g:acp_behaviorUserDefinedMeets* > - let g:acp_behaviorUserDefinedMeets = '' -< - |g:acp_behavior-meets| for user-defined completion. If empty, this - completion will be never attempted. - - *g:acp_behaviorSnipmateLength* > - let g:acp_behaviorSnipmateLength = -1 -< - Pattern before the cursor, which are needed to attempt - snipMate-trigger completion. - - *g:acp_behaviorKeywordCommand* > - let g:acp_behaviorKeywordCommand = "\" -< - Command for keyword completion. This option is usually set "\" or - "\". - - *g:acp_behaviorKeywordLength* > - let g:acp_behaviorKeywordLength = 2 -< - Length of keyword characters before the cursor, which are needed to - attempt keyword completion. If negative value, this completion will be - never attempted. - - *g:acp_behaviorKeywordIgnores* > - let g:acp_behaviorKeywordIgnores = [] -< - List of string. If a word before the cursor matches to the front part - of one of them, keyword completion won't be attempted. - - E.g., when there are too many keywords beginning with "get" for the - completion and auto-popup by entering "g", "ge", or "get" causes - response degradation, set ["get"] to this option and avoid it. - - *g:acp_behaviorFileLength* > - let g:acp_behaviorFileLength = 0 -< - Length of filename characters before the cursor, which are needed to - attempt filename completion. If negative value, this completion will - be never attempted. - - *g:acp_behaviorRubyOmniMethodLength* > - let g:acp_behaviorRubyOmniMethodLength = 0 -< - Length of keyword characters before the cursor, which are needed to - attempt ruby omni-completion for methods. If negative value, this - completion will be never attempted. - - *g:acp_behaviorRubyOmniSymbolLength* > - let g:acp_behaviorRubyOmniSymbolLength = 1 -< - Length of keyword characters before the cursor, which are needed to - attempt ruby omni-completion for symbols. If negative value, this - completion will be never attempted. - - *g:acp_behaviorPythonOmniLength* > - let g:acp_behaviorPythonOmniLength = 0 -< - Length of keyword characters before the cursor, which are needed to - attempt python omni-completion. If negative value, this completion - will be never attempted. - - *g:acp_behaviorPerlOmniLength* > - let g:acp_behaviorPerlOmniLength = -1 -< - Length of keyword characters before the cursor, which are needed to - attempt perl omni-completion. If negative value, this completion will - be never attempted. - - See also: |acp-perl-omni| - - *g:acp_behaviorXmlOmniLength* > - let g:acp_behaviorXmlOmniLength = 0 -< - Length of keyword characters before the cursor, which are needed to - attempt XML omni-completion. If negative value, this completion will - be never attempted. - - *g:acp_behaviorHtmlOmniLength* > - let g:acp_behaviorHtmlOmniLength = 0 -< - Length of keyword characters before the cursor, which are needed to - attempt HTML omni-completion. If negative value, this completion will - be never attempted. - - *g:acp_behaviorCssOmniPropertyLength* > - let g:acp_behaviorCssOmniPropertyLength = 1 -< - Length of keyword characters before the cursor, which are needed to - attempt CSS omni-completion for properties. If negative value, this - completion will be never attempted. - - *g:acp_behaviorCssOmniValueLength* > - let g:acp_behaviorCssOmniValueLength = 0 -< - Length of keyword characters before the cursor, which are needed to - attempt CSS omni-completion for values. If negative value, this - completion will be never attempted. - - *g:acp_behavior* > - let g:acp_behavior = {} -< - This option is for advanced users. This setting overrides other - behavior options. This is a |Dictionary|. Each key corresponds to a - filetype. '*' is default. Each value is a list. These are attempted in - sequence until completion item is found. Each element is a - |Dictionary| which has following items: - - "command": *g:acp_behavior-command* - Command to be fed to open popup menu for completions. - - "completefunc": *g:acp_behavior-completefunc* - 'completefunc' will be set to this user-provided function during the - completion. Only makes sense when "command" is "". - - "meets": *g:acp_behavior-meets* - Name of the function which dicides whether or not to attempt this - completion. It will be attempted if this function returns non-zero. - This function takes a text before the cursor. - - "onPopupClose": *g:acp_behavior-onPopupClose* - Name of the function which is called when popup menu for this - completion is closed. Following completions will be suppressed if - this function returns zero. - - "repeat": *g:acp_behavior-repeat* - If non-zero, the last completion is automatically repeated. - - -============================================================================== -SPECIAL THANKS *acp-thanks* - -- Daniel Schierbeck -- Ingo Karkat - - -============================================================================== -CHANGELOG *acp-changelog* - -2.14.1 - - Changed the way of auto-popup for avoiding an issue about filename - completion. - - Fixed a bug that popup menu was opened twice when auto-popup was done. - -2.14 - - Added the support for perl-completion.vim. - -2.13 - - Changed to sort snipMate's triggers. - - Fixed a bug that a wasted character was inserted after snipMate's trigger - completion. - -2.12.1 - - Changed to avoid a strange behavior with Microsoft IME. - -2.12 - - Added g:acp_behaviorKeywordIgnores option. - - Added g:acp_behaviorUserDefinedMeets option and removed - g:acp_behaviorUserDefinedPattern. - - Changed to do auto-popup only when a buffer is modified. - - Changed the structure of g:acp_behavior option. - - Changed to reflect a change of behavior options (named g:acp_behavior*) - any time it is done. - - Fixed a bug that completions after omni completions or snipMate's trigger - completion were never attempted when no candidate for the former - completions was found. - -2.11.1 - - Fixed a bug that a snipMate's trigger could not be expanded when it was - completed. - -2.11 - - Implemented experimental feature which is snipMate's trigger completion. - -2.10 - - Improved the response by changing not to attempt any completion when - keyword characters are entered after a word which has been found that it - has no completion candidate at the last attempt of completions. - - Improved the response by changing to close popup menu when was - pressed and the text before the cursor would not match with the pattern of - current behavior. - -2.9 - - Changed default behavior to support XML omni completion. - - Changed default value of g:acp_behaviorKeywordCommand option. - The option with "\" cause a problem which inserts a match without - when 'dictionary' has been set and keyword completion is done. - - Changed to show error message when incompatible with a installed vim. - -2.8.1 - - Fixed a bug which inserted a selected match to the next line when - auto-wrapping (enabled with 'formatoptions') was performed. - -2.8 - - Added g:acp_behaviorUserDefinedFunction option and - g:acp_behaviorUserDefinedPattern option for users who want to make custom - completion auto-popup. - - Fixed a bug that setting 'spell' on a new buffer made typing go crazy. - -2.7 - - Changed naming conventions for filenames, functions, commands, and options - and thus renamed them. - - Added g:acp_behaviorKeywordCommand option. If you prefer the previous - behavior for keyword completion, set this option "\". - - Changed default value of g:acp_ignorecaseOption option. - - The following were done by Ingo Karkat: - - - ENH: Added support for setting a user-provided 'completefunc' during the - completion, configurable via g:acp_behavior. - - BUG: When the configured completion is or , the command to - restore the original text (in on_popup_post()) must be reverted, too. - - BUG: When using a custom completion function () that also uses - an s:...() function name, the s:GetSidPrefix() function dynamically - determines the wrong SID. Now calling s:DetermineSidPrefix() once during - sourcing and caching the value in s:SID. - - BUG: Should not use custom defined completion mappings. Now - consistently using unmapped completion commands everywhere. (Beforehand, - s:PopupFeeder.feed() used mappings via feedkeys(..., 'm'), but - s:PopupFeeder.on_popup_post() did not due to its invocation via - :map-expr.) - -2.6: - - Improved the behavior of omni completion for HTML/XHTML. - -2.5: - - Added some options to customize behavior easily: - g:AutoComplPop_BehaviorKeywordLength - g:AutoComplPop_BehaviorFileLength - g:AutoComplPop_BehaviorRubyOmniMethodLength - g:AutoComplPop_BehaviorRubyOmniSymbolLength - g:AutoComplPop_BehaviorPythonOmniLength - g:AutoComplPop_BehaviorHtmlOmniLength - g:AutoComplPop_BehaviorCssOmniPropertyLength - g:AutoComplPop_BehaviorCssOmniValueLength - -2.4: - - Added g:AutoComplPop_MappingDriven option. - -2.3.1: - - Changed to set 'lazyredraw' while a popup menu is visible to avoid - flickering. - - Changed a behavior for CSS. - - Added support for GetLatestVimScripts. - -2.3: - - Added a behavior for Python to support omni completion. - - Added a behavior for CSS to support omni completion. - -2.2: - - Changed not to work when 'paste' option is set. - - Fixed AutoComplPopEnable command and AutoComplPopDisable command to - map/unmap "i" and "R". - -2.1: - - Fixed the problem caused by "." command in Normal mode. - - Changed to map "i" and "R" to feed completion command after starting - Insert mode. - - Avoided the problem caused by Windows IME. - -2.0: - - Changed to use CursorMovedI event to feed a completion command instead of - key mapping. Now the auto-popup is triggered by moving the cursor. - - Changed to feed completion command after starting Insert mode. - - Removed g:AutoComplPop_MapList option. - -1.7: - - Added behaviors for HTML/XHTML. Now supports the omni completion for - HTML/XHTML. - - Changed not to show expressions for CTRL-R =. - - Changed not to set 'nolazyredraw' while a popup menu is visible. - -1.6.1: - - Changed not to trigger the filename completion by a text which has - multi-byte characters. - -1.6: - - Redesigned g:AutoComplPop_Behavior option. - - Changed default value of g:AutoComplPop_CompleteOption option. - - Changed default value of g:AutoComplPop_MapList option. - -1.5: - - Implemented continuous-completion for the filename completion. And added - new option to g:AutoComplPop_Behavior. - -1.4: - - Fixed the bug that the auto-popup was not suspended in fuzzyfinder. - - Fixed the bug that an error has occurred with Ruby-omni-completion unless - Ruby interface. - -1.3: - - Supported Ruby-omni-completion by default. - - Supported filename completion by default. - - Added g:AutoComplPop_Behavior option. - - Added g:AutoComplPop_CompleteoptPreview option. - - Removed g:AutoComplPop_MinLength option. - - Removed g:AutoComplPop_MaxLength option. - - Removed g:AutoComplPop_PopupCmd option. - -1.2: - - Fixed bugs related to 'completeopt'. - -1.1: - - Added g:AutoComplPop_IgnoreCaseOption option. - - Added g:AutoComplPop_NotEnableAtStartup option. - - Removed g:AutoComplPop_LoadAndEnable option. -1.0: - - g:AutoComplPop_LoadAndEnable option for a startup activation is added. - - AutoComplPopLock command and AutoComplPopUnlock command are added to - suspend and resume. - - 'completeopt' and 'complete' options are changed temporarily while - completing by this script. - -0.4: - - The first match are selected when the popup menu is Opened. You can insert - the first match with CTRL-Y. - -0.3: - - Fixed the problem that the original text is not restored if 'longest' is - not set in 'completeopt'. Now the plugin works whether or not 'longest' is - set in 'completeopt', and also 'menuone'. - -0.2: - - When completion matches are not found, insert CTRL-E to stop completion. - - Clear the echo area. - - Fixed the problem in case of dividing words by symbols, popup menu is - not opened. - -0.1: - - First release. - - -============================================================================== -ABOUT *acp-about* *acp-contact* *acp-author* - -Author: Takeshi NISHIDA -Licence: MIT Licence -URL: http://www.vim.org/scripts/script.php?script_id=1879 - http://bitbucket.org/ns9tks/vim-autocomplpop/ - -Bugs/Issues/Suggestions/Improvements ~ - -Please submit to http://bitbucket.org/ns9tks/vim-autocomplpop/issues/ . - -============================================================================== - vim:tw=78:ts=8:ft=help:norl: - diff --git a/doc/project.txt b/doc/project.txt deleted file mode 100644 index 8f85c23..0000000 --- a/doc/project.txt +++ /dev/null @@ -1,710 +0,0 @@ -*project.txt* Plugin for managing multiple projects with multiple sources - For Vim version 6.x and Vim version 7.x. - Last Change: Fri 13 Oct 2006 10:20:13 AM EDT - - - By Aric Blumer - aricvim email-at-sign charter.net - - *project* *project-plugin* - Contents: - - Commands...................|project-invoking| - Inheritance.............|project-inheritance| - Mappings...................|project-mappings| - Adding Mappings.....|project-adding-mappings| - Settings...................|project-settings| - Example File................|project-example| - Tips...........................|project-tips| - - -You can use this plugin's basic functionality to set up a list of -frequently-accessed files for easy navigation. The list of files will be -displayed in a window on the left side of the Vim window, and you can press - or double-click on filenames in the list to open the files. I find -this easier to use than having to navigate a directory hierarchy with the -|file-explorer|. - -You can also instruct the Plugin to change to a directory and to run Vim -scripts when you select a file. These scripts can, for example, modify the -environment to include compilers in $PATH. This makes it very easy to use -quickfix with multiple projects that use different environments. - -Other features include: - o Loading/Unloading all the files in a Project (\l, \L, \w, and \W) - o Grepping all the files in a Project (\g and \G) - o Running a user-specified script on a file (can be used to launch an - external program on the file) (\1 through \9) - o Running a user-specified script on all the files in a Project - (\f1-\f9 and \F1-\F9) - o High degree of user-configurability - o Also works with |netrw| using the XXXX://... notation where XXXX is - ftp, rcp, scp, or http. - -All of this is specified within a simple text file and a few global variables -in your vimrc file. - -You must set 'nocompatible' in your |vimrc| file to use this plugin. You can -stop the plugin from being loaded by setting the "loaded_project" variable: > - :let loaded_project = 1 - - -============================================================================== -COMMANDS *project-invoking* - -You can use the plugin by placing it in your plugin directory (e.g., -~/.vim/plugin). See |add-global-plugin|. When you start vim the next time, you -then enter the command > - :Project -or > - :Project {file} - -If you do not specify the filename, $HOME/.vimprojects is used. - -To have Vim come up with the Project Window enabled automatically (say, from a -GUI launcher), run Vim like this: [g]vim +Project - -Note that you can invoke :Project on only one file at a time. If you wish to -change the Project File, do a :bwipe in the Project Buffer, then re-invoke the -Plugin as described above. - -Several Projects can be kept and displayed in the same file, each in a fold -delimited by { and } (see |fold.txt|). There can be any number of nested -folds to provide you with a Project hierarchy. Any line without a { or a } in -the file is considered to be a filename. Blank lines are ignored, and any -text after a # is ignored. - -Because the plugin uses standard Vim folds, you can use any of the -|fold-commands|. You can double-click on the first line of a fold to open and -close it. You can select a file to open by putting the cursor on its name and -pressing or by double-clicking on it. The plugin will create a new -window to the right or use the |CTRL-W_p| equivalent if it exists. - - *project-syntax* -Each Project Entry has this form: - -project_entry ::= - ={projpath} [{options}] { - [ filename ] - [ project_entry ] - } - -{options} is one or more of the following (on the same line): - CD={path} - in={filename} - out={filename} - filter="{pat}" - flags={flag} - -Note that a project_entry can reside within a project_entry. This allows you -to set up a hierarchy within your Project. - -The will be displayed in the foldtext and cannot contain "=". -There can be no space character directly on either side of the =. - -The {projpath} is the path in which the files listed in the Project's fold -will be found, and it may contain environment variables. If the path is a -relative path, then the plugin constructs the whole path from the Project's -parent, grandparent, etc., all the way up the hierarchy. An outermost -project_entry must have an absolute path. See the |project-inheritance| -example below. {projpath} may contain spaces, but they must be escaped like -normal Vim escapes. Here are two examples of the same directory: -> - Example=/my/directory/with\ spaces { - } - Example="/my/directory/with spaces" { - } - -I recommend this for Windows®: > - - Example="c:\My Documents" { - } - -But Vim is smart enough to do this, too: > - - Example=c:\My\ Documents { - } - -CD= provides the directory that Vim will change to when you select a file in -that fold (using |:cd|). This allows you, for example, to enter |:make| to use -the local Makefile. A CD=. means that Vim will make {projpath} or its -inherited equivalent the current working directory. When CD is omitted, the -directory is not changed. There can be no space on either side of the =. The -value of CD can also be a relative path from a parent's CD. See the -|project-inheritance| example below. This directive is ignored for |netrw| -projects. Spaces are allowed in the path as for {projpath}. - -in= and out= provide the means to run arbitrary Vim scripts whenever you enter -or leave a file's buffer (see the |BufEnter| and |BufLeave| autocommand -events). The idea is to have a Vim script that sets up or tears down the -environment for the Project like this: - -in.vim: > - let $PROJECT_HOME='~/my_project' - " Put the compiler in $PATH - if $PATH !~ '/path/to/my/compiler' - let $PATH=$PATH.':/path/to/my/compiler' - endif - -out.vim: > - " Remove compiler from $PATH - if $PATH =~ '/path/to/my/compiler' - let $PATH=substitute($PATH, ':/path/to/my/compiler', '', 'g') - endif - -Then you can use :make with the proper environment depending on what file you -are currently editing. If the path to the script is relative, then it is -relative from {projpath}. These directives are inherited by Subprojects -unless the Subproject specifies its own. For use with |netrw| projects, the -paths specified for in= and out= must be absolute and local. - -filter= specifies a |glob()| file pattern. It is used to regenerate the list -of files in a Project fold when using the \r (r) map in the -Project Window. The filter value must be in quotes because it can contain -multiple file patterns. If filter is omitted, then the * pattern is used. -There can be no space on either side of the =. A Subproject will inherit the -filter of its parent unless it specifies its own filter. - -flags= provides the means to enable/disable features for a particular fold. -The general mnemonic scheme is for lower case to turn something off and upper -case to turn something on. {flag} can contain any of the following -characters: - - flag Description ~ - - l Turn off recursion for this fold for \L. Subfolds are also - blocked from the recursion. - - r Turn off refresh. When present, do not refresh this fold when - \r or \R is used. This does not affect subfold recursion. - - S Turn on sorting for refresh and create. - - s Turn off sorting for refresh and create. - - T Turn on top gravity. Forces folds to the top of the current - fold when refreshing. It has the same affect as the 'T' flag - in g:proj_flags, but controls the feature on a per-fold basis. - - t Turn off top gravity. Forces folds to the bottom of the - current fold when refreshing. - - w Turn off recursion for this fold for \W. Subfolds are also - blocked from the recursion. - - -Flags are not inherited by Subprojects. - -Any text outside a fold is ignored. - - -============================================================================== -INHERITANCE *project-inheritance* - -It's best to show inheritance by comparing these two Project Files: -> - Parent=~/my_project CD=. filter="Make* *.mk" flags=r { - Child1=c_code { - } - Child2=include CD=. filter="*.h" { - } - } - -Child1's path is "~/my_project/c_code" because ~/my_project is inherited. It -also inherits the CD from Parent. Since Parent has CD=., the Parent's cwd is -"~/my_project". Child1 therefore inherits a CD of "~/my_project". Finally, -Child1 inherits the filter from Parent. The flags are not inherited. - -Child2 only inherits the "~/my_project" from Parent. - -Thus, the example above is exactly equivalent to this: -> - Parent=~/my_project CD=. filter="Make* *.mk" flags=r { - Child1=~/my_project/c_code CD=~/my_project filter="Make* *.mk" { - } - Child2=~/my_project/include CD=~/my_project/include filter="*.h" { - } - } - -(For a real Project, Child1 would not want to inherit its parent's filter, but -this example shows the concept.) You can always enter \i to display what the -cursor's project inherits. - - -============================================================================== -MAPPINGS *project-mappings* - -Map Action ~ - -\r Refreshes the Project fold that the cursor is in by placing in the - fold all the files that match the filter. The Project is refreshed - using an indent of one space for every foldlevel in the hierarchy. - - You may place a "# pragma keep" (without the quotes) at the end of a - line, and the file entry on that line will not be removed when you - refresh. This is useful, for example, when you have . as an entry so - you can easily browse the directory. - - Note that this mapping is actually r, and the default of - || is \. - - This does not work for Projects using |netrw|. - -\R Executes \r recursively in the current fold and all folds below. - This does not work for Projects using |netrw|. - -\c Creates a Project fold entry. It asks for the description, the path - to the files, the CD parameter, and the filename |glob()| pattern. - From this information, it will create the Project Entry below the - cursor. - - This does not work for Projects using |netrw|. - -\C Creates a Project fold entry like \c, but recursively includes all the - subdirectories. - - - Select a file to open in the |CTRL-W_p| window or in a new window. If - the cursor is on a fold, open or close it. - - -\s - Same as but horizontally split the target window. - s is provided for those terminals that don't recognize - . - -\S - Load all files in a project by doing horizontal splits. - - -\o - Same as but ensure that the opened file is the only other - window. o is provided for those terminals that don't - recognize . - - -\v - Same as but only display the file--the cursor stays in the - Project Window. - -<2-LeftMouse> - (Double-click) If on a closed fold, open it. If on an open fold - boundary, close it. If on a filename, open the file in the |CTRL-W_p| - window or in a new window. - - - Same as . - - - Same as . - - - Increase the width of the Project Window by g:proj_window_increment or - toggle between a width of - g:proj_window_width + g:proj_window_increment - and - g:proj_window_width. - - Whether you toggle or monotonically increase the width is determined - by the 't' flag of the g:proj_flags variable (see |project-flags|). - - Note that a Right Mouse click will not automatically place the cursor - in the Project Window if it is in a different window. The window will - go back to the g:proj_window_width width when you leave the window. - - Same as - - -\ - Move the text or fold under the cursor up one row. This may not work - in a terminal because the terminal is unaware of this key combination. - is provided for those terminals that don't recognize - . - - - -\ - Move the text or fold under the cursor down one row. This may not work - in a terminal because the terminal is unaware of this key combination. - is provided for those terminals that don't - recognize . - -\i Show in the status line the completely resolved and inherited - parameters for the fold the cursor is in. This is intended for - debugging your relative path and inherited parameters for manually - entered Projects. - -\I Show in the status line the completely resolved filename. Uses the - Project_GetFname(line('.')) function. - -\1 - \9 - Run the command specified in g:proj_run{x} where {x} is the number - of the key. See the documentation of g:proj_run1 below. - -\f1-\f9 - Run the command specified in g:proj_run_fold{x} where {x} is the - number of the key. The command is run on the files at the current - Project level. See the |project-settings| below. - -\F1-\F9 - Run the command specified in g:proj_run_fold{x} where {x} is the - number of the key. The command is run on the files at the current - Project level and all Subprojects. See the |project-settings| below. - -\0 Display the commands that are defined for \1 through \9. - -\f0 Display the commands that are defined for \f1 through \f9 and \F1 - through \F0. Same as \F0. - -\l Load all the files in the current Project level into Vim. While files - are being loaded, you may press any key to stop. - -\L Load all the files in the current Project and all Subprojects into - Vim. Use this mapping with caution--I wouldn't suggest using \L to - load a Project with thousands of files. (BTW, my Project file has more - than 5,300 files in it!) While files are being loaded, you may press - any key to stop. - -\w Wipe all the files in the current Project level from Vim. (If files - are modified, they will be saved first.) While files are being wiped, - you may press any key to stop. - -\W Wipe all the files in the current Project and all Subprojects from - Vim. (If files are modified, they will be saved first.) While files - are being wiped, you may press any key to stop. - -\g Grep all the files in the current Project level. - -\G Grep all the files in the current Project level and all Subprojects. - -\e Set up the Environment for the Project File as though you had selected - it with . This allows you to do a \e and a :make without - having to open any files in the project. - -\E Explore (using |file-explorer|) the directory of the project the - cursor is in. Does not work with netrw. - - When the 'g' flag is present in g:proj_flags (see |project-flags|) - this key toggles the Project Window open and closed. You may remap - this toggle function by putting the following in your vimrc and - replacing P with whatever key combination you wish: - - nmap P ToggleProject - -Note that the Project Plugin remaps :help because the Help Window and the -Project Window get into a fight over placement. The mapping avoids the -problem. - -============================================================================== -ADDING MAPPINGS *project-adding-mappings* - -You can add your own mappings or change the mappings of the plugin by placing -them in the file $HOME/.vimproject_mappings. This file, if it exists, will be -sourced when the plugin in loaded. Here is an example that will count the -number of entries in a project when you press \K (Kount, C is taken :-): > - - function! s:Wc() - let b:loadcount=0 - function! SpawnExec(infoline, fname, lineno, data) - let b:loadcount = b:loadcount + 1 - if getchar(0) != 0 | let b:stop_everything=1 | endif - endfunction - call Project_ForEach(1, line('.'), "*SpawnExec", 0, '') - delfunction SpawnExec - echon b:loadcount." Files\r" - unlet b:loadcount - if exists("b:stop_everything") - unlet b:stop_everything - echon "Aborted.\r" - endif - endfunction - - nnoremap K :call Wc() - -Here's another example of how I integrated the use of perforce with the plugin -in my $HOME/.vimproject_mappings: -> - function! s:DoP4(cmd) - let name=Project_GetFname(line('.')) - let dir=substitute(name, '\(.*\)/.*', '\1', 'g') - exec 'cd '.dir - exec "!".a:cmd.' '.Project_GetFname(line('.')) - cd - - endfunction - - nmap \pa :call DoP4("p4add") - nmap \pe :call DoP4("p4edit") -< -(Note that I CD to the directory the file is in so I can pick of the $P4CONFIG -file. See the perforce documentation.) - -This creates the mappings \pe to check out the file for edit and \pa to add -the file to the depot. - -Here is another example where I remap the mapping to use an external -program to launch a special kind of file (in this case, it launches ee to view -a jpg file). It is a bit contrived, but it works. -> - let s:sid = substitute(maparg('', 'n'), '.*\(.\{-}\)_.*', '\1', '') - function! s:LaunchOrWhat() - let fname=Project_GetFname(line('.')) - if fname =~ '\.jpg$' - exec 'silent! !ee "'.fname.'"&' - else - call {s:sid}_DoFoldOrOpenEntry('', 'e') - endif - endfunction - nnoremap \|:call LaunchOrWhat() -< -If the file ends in .jpg, the external program is launched, otherwise the -original mapping of is run. - -============================================================================== -SETTINGS *project-settings* - -You can set these variables in your vimrc file before the plugin is loaded to -change its default behavior - -g:proj_window_width - The width of the Project Window that the plugin attempts to maintain. - Default: 24 - - The Project Plugin is not always successful in keeping the window - where I want it with the size specified here, but it does a decent - job. - -g:proj_window_increment - The increment by which to increase the width of the Project Window - when pressing or clicking the . Default: 100 - (See |project-mappings|.) - - *project-flags* -g:proj_flags - Default: "imst" - Various flags to control the behavior of the Project Plugin. This - variable can contain any of the following character flags. - - flag Description ~ - - b When present, use the |browse()| when selecting directories - for \c and \C. This is off by default for Windows, because - the windows browser does not allow you to select directories. - - c When present, the Project Window will automatically close when - you select a file. - - F Float the Project Window. That is, turn off automatic - resizing and placement. This allows placement between other - windows that wish to share similar placement at the side of - the screen. It is also particularly helpful for external - window managers. - - g When present, the mapping for will be created to toggle - the Project Window open and closed. - - i When present, display the filename and the current working - directory in the command line when a file is selected for - opening. - - l When present, the Project Plugin will use the |:lcd| command - rather than |:cd| to change directories when you select a file - to open. This flag is really obsolete and not of much use - because of L below. - - L Similar to l, but install a BufEnter/Leave |:autocommand| to - ensure that the current working directory is changed to the - one specified in the fold CD specification whenever that - buffer is active. (|:lcd| only changes the CWD for a window, - not a buffer.) - - m Turn on mapping of the |CTRL-W_o| and |CTRL-W_CTRL_O| normal - mode commands to make the current buffer the only visible - buffer, but keep the Project Window visible, too. - - n When present, numbers will be turned on for the project - window. - - s When present, the Project Plugin will use syntax highlighting - in the Project Window. - - S Turn on sorting for refresh and create. - - t When present, toggle the size of the window rather than just - increase the size when pressing or right-clicking. - See the entry for in |project-mappings|. - - T When present, put Subproject folds at the top of the fold when - refreshing. - - v When present, use :vimgrep rather than :grep when using \G. - -g:proj_run1 ... g:proj_run9 - Contains a Vim command to execute on the file. See the - mappings of \1 to \9 above. - - %f is replaced with the full path and filename - %F is replaced with the full path and filename with spaces - quoted - %n is replaced with the filename alone - %N is replaced with the filename alone with spaces quoted - %h is replaced with the home directory - %H is replaced with the home directory with spaces quoted - %r is replaced with the directory relative to the CD path - %R is replaced with the directory relative to the CD path - with spaces quoted - %d is replaced with the CD directory. - %D is replaced with the CD directory.with spaces quoted - %% is replaced with a single % that is not used in - expansion. - - (Deprecated: %s is also replaced with the full path and - filename for backward compatibility.) - - For example, gvim will be launched on the file under the - cursor when you enter \3 if the following is in your vimrc - file: > - let g:proj_run3='silent !gvim %f' -< Here are a few other examples: > - let g:proj_run1='!p4 edit %f' - let g:proj_run2='!p4 add %f' - let g:proj_run4="echo 'Viewing %f'|sil !xterm -e less %f &" -< - On Windows systems you will want to put the %f, %h, and %d in - single quotes to avoid \ escaping. - -g:proj_run_fold1 ... g:proj_run_fold9 - Contains a Vim command to execute on the files in a fold. See - the mappings of \f1 to \f9 and \F1 to \F9 above. - - %f is the filename, %h is replaced with the project home - directory, and %d is replaced with the CD directory. Multiple - filenames can be handled in two ways: - - The first (default) way is to have %f replaced with all the - absolute filenames, and the command is run once. The second - is to have the command run for each of the non-absolute - filenames (%f is replaced with one filename at a time). To - select the second behavior, put an '*' character at the - beginning of the g:proj_run_fold{x} variable. (The '*' is - stripped before the command is run.) - - For example, note the difference between the following: > - let g:proj_run_fold3="*echo '%h/%f'" - let g:proj_run_fold4="echo '%f'" -< - Note that on Windows systems, you will want the %f, %h, and %c - within single quotes, or the \ in the paths will cause - problems. The alternative is to put them in |escape()|. - - -============================================================================== -PROJECT EXAMPLE FILE *project-example* - -Here is an example ~/.vimprojects file: > - - 1 My Project=~/c/project CD=. in=in.vim out=out.vim flags=r { - 2 Makefile - 3 in.vim - 4 out.vim - 5 GUI Files=. filter="gui*.c gui*.h" { - 6 gui_window.c - 7 gui_dialog.c - 8 gui_list.c - 9 gui.h # Header file - 10 } - 11 Database Files=. filter="data*.c data*.h" { - 12 data_read.c - 13 data_write.c - 14 data.h - 15 } - 16 OS-Specific Files { - 17 Win32=. filter="os_win32*.c os_win32*.h" { - 18 os_win32_gui.c - 19 os_win32_io.c - 20 } - 21 Unix=. filter="os_unix*.c os_unix*.h" { - 22 os_unix_gui.c - 23 os_unix_io.c - 24 } - 25 } - 26 } - -(Don't type in the line numbers, of course.) - - -============================================================================== -TIPS ON USING PROJECT PLUGIN *project-tips* - -1. You can create a Project Entry by entering this: > - - Label=~/wherever CD=. filter="*.c *.h" { - } -< - Then you can put the cursor in the fold and press \r. The script will fill - in the files (C files in this case) from this directory for you. This is - equivalent to \c without any dialogs. - -2. You can edit the Project File at any time to add, remove, or reorder files - in the Project list. - -3. If the Project Window ever gets closed, you can just enter > - :Project -< to bring it back again. (You don't need to give it the filename; the - plugin remembers.) - - If you have the 'm' flag set in g:proj_flags, then you get the Project - Window to show up again by pressing |CTRL-W_o|. This, of course, will - close any other windows that may be open that the cursor is not in. - -4. Adding files to a Project is very easy. To add, for example, the 'more.c' - file to the Project, just insert the filename in the Project Entry then - hit on it. - -5. When |quickfix| loads files, it is not equivalent to pressing on - a filename, so the directory will not be changed and the scripts will not - be run. (If I could make this otherwise, I would.) The solution is to use - the \L key to load all of the files in the Project before running - quickfix. - -6. If the Project window gets a bit cluttered with folds partially - open/closed, you can press |zM| to close everything and tidy it up. - -7. For advanced users, I am exporting the function Project_GetAllFnames() - which returns all the filenames within a fold and optionally all its - Subprojects. Also, I export Project_ForEach() for running a function for - each filename in the project. See the code for examples on how to use - these. Finally, I export Project_GetFname(line_number) so that you can - write your own mappings and get the filename for it. - -8. Some people have asked how to do a global mapping to take the cursor to - the Project window. One of my goals for the plugin is for it to be as - self-contained as possible, so I'm not going to add it by default. But you - can put this in your vimrc: -> - nmap P :Project - -< -9. You can put the . entry in a project, and it will launch the - |file-explorer| plugin on the directory. To avoid removal when you - refresh, make the entry look like this: -> - . # pragma keep -< -============================================================================== -THANKS - - The following people have sent me patches to help with the Project - Plugin development: - - Tomas Zellerin - Lawrence Kesteloot - Dave Eggum - A Harrison - Thomas Link - Richard Bair - Eric Arnold - Peter Jones - Eric Van Dewoestine - - - vim:ts=8 sw=8 noexpandtab tw=78 ft=help: diff --git a/doc/vimblogger_ft.txt b/doc/vimblogger_ft.txt new file mode 100644 index 0000000..cb00b41 --- /dev/null +++ b/doc/vimblogger_ft.txt @@ -0,0 +1,198 @@ +*vimblogger_ft.txt* reStructuredText to Blogger Interface + Author: Roman Dobosz, gryf73 at gmail com + +Simple interface to create blog articles in rsST format. It provides +commands for preview in browser, post and delete articles. + +----------------------------------------------------------------------- +Requirements~ + +Module for communication was written in Python. So, VIm has to be +compiled with +python. + +Other requirements: + +- Python (tested with version 2.6, should work also in others) + - gdata http://code.google.com/p/gdata-python-client + - docutils http://docutils.sourceforge.net + - pygments http://pygments.org +- Blogger account + +----------------------------------------------------------------------- +Install~ + +Extract zip file into your ~/.vim. + +======================================================================== +Usage~ + +This plugin is targeting for people, who has blogger account, want to +use vim for creating blog articles and don't really likes to manually do +this in html. + +Unfortunately it has several limitations, like you cannot use multiple +blogs or edit existing articles without reST source files. You have to +somehow convert it reStructuredText, add *Id* and then update it. + +----------------------------------------------------------------------- +Options~ + *g:blogger_browser* +g:blogger_browser (default: 0) + + If set to 1 output file from :PreviewBlogArticle will be opened in + browser (used webbrowser Python module) + + *g:blogger_name* +g:blogger_name (default: "") + + This is blog name, which is part of the URL, and you was obligated + to enter it during blog creation. If you don't remember it, just + check first part od the URL of your blog, just after 'http://'. + Don't be confused with the blog title. + + *g:blogger_login* +g:blogger_login (default: "") + + Google login name, usually gmail address. + *g:blogger_pass* +g:blogger_pass (default: "") + + Password. If set to empty string, You'll be asked for it every time + you do any blogger activity. + *g:blogger_draft* +g:blogger_draft (default: 1) + + By default, don't publish articles immediately, just save it on the + service. If set to 0, article will be published. + + *g:blogger_maxarticles* +g:blogger_maxarticles (default: 0) + + Number of displayed articles during deletion. 0 means all. Any + positive number will display only that numbers of articles on list. + + *g:blogger_confirm_del* +g:blogger_confirm_del (default: 1) + + Confirm every deletion. If set to 0, suppress the confirmation. + + *g:blogger_stylesheets* +g:blogger_stylesheets (default: []) + + List of relative paths (relative to generated HTML document) of CSS + stylesheets, used only for article preview in HTML document. Usually + one wanted to save stylesheets from his own blog, so that article + can be displayed almost in the same way as in blog. + +======================================================================== +Commands~ + +*:PreviewBlogArticle* + + Generate article in HTML format, save it to the file with te same + name as a reST source with .html extension in the same directory, + and optionally opens it in browser. No connection to the blogger is + performed. + +*:SendBlogArticle* + + Generate partial HTML document, which holds article, from current + reST buffer and send it to the blog. + + See reST document structure below for further description. + +*:DeleteBlogArticle* + + Display list of articles, and lets user choose one (or none) of them + to perform deletions. + +======================================================================== +reST document structure~ + +It is assumed, that following template will be used: + +-----8<----- +:Id: +:Title: Title for the blog +:Date: +:Modified: +:Tags: some, tags + +Penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla +facilisis massa ut massa. Sed nisi purus, malesuada eu, porta vulputate, +suscipit auctor, nunc. Vestibulum convallis, augue eu luctus malesuada, +mi ante mattis odio, ac venenatis neque sem vitae nisi. + +.. more + + +heading +------- + +**Congue** mi, quis posuere augue nulla a augue. Pellentesque sed est. +Mauris cursus urna id lectus. Integer dignissim feugiat eros. Sed tempor +volutpat dolor. Vestibulum vel lectus nec mauris semper adipiscing. + +Aliquam tincidunt enim sit amet tellus. Sed mauris nulla, semper +tincidunt, luctus a, sodales eget, leo. Sed ligula augue, cursus et. +----->8----- + +reST document (optionally) starts with *docinfo* section (first several +lines, that are starting from *:* character) separaded from other +content with one empty line. + +Docinfo items holds article attributes, and are updated automatically +every each of upload to blogger, which is triggered by +*:SendBlogArticle* command. + +*:Id:* + Holds article id on blogger side. If not defined, new article will + be created (even if there is already existing one with the very same + content). If wrong id is entered (or an Id of deleted article), + exception will be raised, and no action on blogger side will be + performed. + +*:Title:* + Holds article title. Can be changed when *:Id:* is obtained. + +*:Date:* + This is published date in RFC 3339 + http://www.ietf.org/rfc/rfc3339.txt format. If empty on first + upload, it will be set to current date. Can be set/changed to + desired date. + +*:Modified:* + This is read-only item, which store modification date which happens + on blogger side. + +*:Tags:* + Comma separated list of tags (Labels). Can be empty. + +All other items are ignored. + +After docinfo block, article body should be placed using markup for +reStructuredText. + +Additionally, there is sourcecode directive, simple syntax highlighter +using Pygments module. Very simple usage could be as follows: + +-----8<----- +.. sourcecode:: python + + import vim + print vim.current.buffer.name + +----->8----- + +Note: All headings for generated HTML by *:SendBlogArticle* will be +shifted by 3, so the first heading will become

, second

and so +on, to fit into blogger template (well, most of them). Remember, that +HTML allow up to 6 level of headings, while reST doesn't have this +limitation. + +======================================================================== +Changelog~ + +0.1 First release + +vim:tw=72:fo=tcq2:isk=!-~,^*,^|,^":ts=8:ft=help:norl: diff --git a/ftplugin/rst/blogger.vim b/ftplugin/rst/blogger.vim deleted file mode 100644 index ec84ef9..0000000 --- a/ftplugin/rst/blogger.vim +++ /dev/null @@ -1,98 +0,0 @@ -" Blogger vim interface. -" Provide some convinient functions for creating preview from the reST file -" and to send articles to blog. - -if exists("b:did_rst_plugin") - finish " load only once -else - let b:did_rst_plugin = 1 -endif - -if !exists("g:blogger_browser") - let g:blogger_browser = 0 -endif - -if !exists("g:blogger_name") - let g:blogger_name = "" -endif - -if !exists("g:blogger_login") - let g:blogger_login= "" -endif - -if !exists("g:blogger_pass") - let g:blogger_pass = "" -endif - -map :call Restify() -map :call Rst2Blogger() - -if !exists('*s:Restify') - python << EOF -#{{{ -import os -import sys -import webbrowser - -import vim - -scriptdir = os.path.dirname(vim.eval('expand("")')) -sys.path.insert(0, scriptdir) -try: - from vimblogger.rest import blogPreview, blogArticleString - from vimblogger.blogger import VimBlogger -except ImportError: - print "Plugin blogger cannot be loaded, due to lack of required modules" -#}}} -EOF - - " Translate reSt text into html fragment suitable for preview in browser. - fun Restify() - python << EOF -# {{{ -bufcontent = "\n".join(vim.current.buffer) -name = vim.current.buffer.name - -name = name[:-4] + ".html" -html = blogPreview(bufcontent) -output_file = open(name, "w") -output_file.write(html) -output_file.close() -if vim.eval("g:blogger_browser"): - webbrowser.open(name) - print "Generated HTML has been opened in browser" -else: - print "Generated HTML has been written to %s" % name -#}}} -EOF - endfun - - " Generate headless html, gather title, dates and tags from filed list and - " then send it to blog. - fun Rst2Blogger() - python << EOF -#{{{ -bufcontent = "\n".join(vim.current.buffer) -name = vim.current.buffer.name -html, attrs = blogArticleString(bufcontent) - -login = vim.eval("g:blogger_login") -password = vim.eval("g:blogger_pass") -blogname = vim.eval("g:blogger_name") - -if not password: - password = vim.eval('inputsecret("Enter your gmail password: ")') - -title = 'title' in attrs and attrs['title'] or None -date = 'date' in attrs and attrs['date'] or None -tags = 'tags' in attrs and attrs['tags'] or "" -tags = [tag.strip() for tag in tags.split(',')] -modified = 'modified' in attrs and attrs['modified'] or None - -blog = VimBlogger(blogname, login, password) -print blog.create_article(title, html, tags=tags) - -#}}} -EOF - endfun -endif diff --git a/ftplugin/rst/commons.vim b/ftplugin/rst/commons.vim index ec045de..0d25ac2 100644 --- a/ftplugin/rst/commons.vim +++ b/ftplugin/rst/commons.vim @@ -9,3 +9,7 @@ setlocal formatoptions=tcq "set VIms default let g:blogger_login="gryf73" let g:blogger_name="rdobosz" let g:blogger_browser=1 +let g:blogger_stylesheets=["css/widget_css_2_bundle.css", "css/style_custom.css", "css/style_blogger.css"] + +map :PreviewBlogArticle +map :SendBlogArticle diff --git a/ftplugin/rst/rst2blogger/__init__.py b/ftplugin/rst/rst2blogger/__init__.py new file mode 100644 index 0000000..a402df0 --- /dev/null +++ b/ftplugin/rst/rst2blogger/__init__.py @@ -0,0 +1 @@ +# module vimblogger diff --git a/ftplugin/rst/rst2blogger/blogger.py b/ftplugin/rst/rst2blogger/blogger.py new file mode 100644 index 0000000..67714f9 --- /dev/null +++ b/ftplugin/rst/rst2blogger/blogger.py @@ -0,0 +1,258 @@ +# vim: fileencoding=utf8 +# +# Blogger interface to make easy way to create/update articles for specified +# blog. +# +# It is assumed one way communication only, so you may create or update an +# article from reST source files. There is no way to recreate article from +# html to reST format. +# +# requirements: +# +# - Vim compiled with +python +# - python 2.x (tested with 2.6) +# - modules +# - gdata (http://code.google.com/p/gdata-python-client) +# - docutils (http://docutils.sourceforge.net) +# +# USE CASES: +# 1. Create new post +# +# use reST template: +# ===8<--- +# :Title: Blog post title +# :Date: optional publish date (for example: 2010-11-28 18:47:05), +# default: now() +# :Modified: optional, default: None +# :Tags: comma separated blog tags +# +# .. more +# +# --->8=== +# +# All four docinfo are optional, however it is nice to give at least a title +# to the article :) +# +# +# +# which is provided under templates directory or as a +# snipMate shoortcut (see .vim/snippets/rst.snippets) +# + +#----------------------------------------------------------------------------- +# +import datetime +import re + +import atom +from gdata.blogger.client import BloggerClient, BLOG_POST_URL +from gdata.blogger.data import BlogPost + + +class VimBlogger(object): + """ + """ + DATE_PATTERN = re.compile(r"^(\d{4}-\d{2}-\d{2})" + "T(\d{2}:\d{2}:\d{2})(\.\d{3})?[+-]" + "(\d{2}:\d{2})$") + DATE_FORMAT = "%Y-%m-%d" + TIME_FORMAT = "%H:%M:%S" + TZ_FORMAT = "%H:%M" + + # TODO: dodać usuwanie artykułów (prosta lista, wybieramy art, + # potwierdzamy) + # TODO: Dokumentacja jako vimdoc! + + def __init__(self, blogname, login, password): + """ + """ + self.draft = True + self.blog_id = None + self.blog = None + self.client = BloggerClient() + self._authorize(login, password) + + self.feed = self.client.get_blogs() + self._set_blog(blogname) + + def get_articles(self, maxarticles=0): + """ + Return list of articles + """ + + feed = self.client.get_posts(self.blog_id) + posts = [] + + for index, entry in enumerate(feed.entry): + if maxarticles and index >= maxarticles: + break + posts.append((entry.get_post_id(), + entry.title.text, + self._extract_date(entry.published.text))) + return posts + + + def create_article(self, html_doc, attrs=None): + """ + Create new article + html_doc is content of the article in HTML format, without headers, + preamble, doctype and body tags. + attrs is a dictionary that should hold title, date and tags. + return BlogPost object + """ + if not attrs: + attrs = {} + + title = 'title' in attrs and attrs['title'] or "" + title = atom.data.Title(text=title, type="text") + html_doc = atom.data.Content(text=html_doc, type="html") + + new_post = BlogPost(title=title, content=html_doc) + + if 'tags' in attrs and attrs['tags']: + for tag in attrs['tags'].split(','): + new_post.add_label(tag.strip()) + + if 'date' in attrs and attrs['date'] and \ + self._check_date(attrs['date']): + new_post.published = atom.data.Published(text=attrs['date']) + + if self.draft: + new_post.control = atom.data.Control(\ + draft=atom.data.Draft(text='yes')) + + return self.client.post(new_post, BLOG_POST_URL % self.blog_id) + + def update_article(self, html_doc, attrs): + """ + Update article. + html_doc is content of the article in HTML format, without headers, + preamble, doctype and body tags. + attrs is a dictionary that should hold title, date and tags. + return BlogPost object + """ + if "id" not in attrs: + raise Exception("Post Id not found in attributes!") + + post = self._get_post(attrs['id']) + post.content = atom.data.Content(text=html_doc, type="html") + + # update publish date + if 'date' in attrs and attrs['date'] and \ + self._check_date(attrs['date']): + post.published = atom.data.Published(text=attrs['date']) + + if 'title' in attrs and attrs['title']: + post.title = atom.data.Title(text=attrs['title'], type="text") + # + # update tag list + if 'tags' in attrs: + tags = [tag.strip() for tag in attrs['tags'].split(',')] + for index, label in enumerate(post.category): + if label.term not in tags: + del(post.category[index]) + + for tag in tags: + self._add_tag(post, tag.strip()) + + return self.client.update(post) + + def delete_article(self, post_id): + """ + Delete selected article + """ + if not post_id: + return "No article id provided" + + post = self._get_post(post_id) + self.client.delete(post) + return None + + + def _get_post(self, post_id): + """ + """ + post_href = self.blog.get_post_link().href + return self.client.get_feed(post_href + "/%s" % post_id, + desired_class=BlogPost) + + def _add_tag(self, post, tag): + """ + post - BlogPost object + tag - string with tag/label to add + """ + for label in post.category: + if label.term == tag: + return + + post.add_label(tag) + + def _extract_date(self, date_string, time=False): + """ + Extract date from the string and optionally time + """ + + if not self.DATE_PATTERN.match(date_string): + return False + + if not time: + return self.DATE_PATTERN.match(date_string).groups()[0] + + groups = self.DATE_PATTERN.match(date_string).groups() + return groups[0] + " " + groups[1] + + def _check_date(self, date): + """ + Parse date as RFC 3339 format, for example: + 2010-11-30T21:06:48.678+01:00 + or + 2010-11-30T21:06:48+01:00 + + Returns true, if date is acceptable, false otherwise + """ + if not self.DATE_PATTERN.match(date): + return False + + groups = self.DATE_PATTERN.match(date).groups() + _date = groups[0] + _time = groups[1] + _tz = len(groups) == 3 and groups[2] or groups[3] + + try: + datetime.datetime.strptime(_date, self.DATE_FORMAT) + datetime.datetime.strptime(_time, self.TIME_FORMAT) + datetime.datetime.strptime(_tz, self.TZ_FORMAT) + except ValueError: + return False + + return True + + def _update_date(self, post, attrs): + """ + Update articles published date + """ + + def _authorize(self, login, password): + """ + Try to authorize in Google service. + Authorization is kept in client object. In case of wrong credentials, + exception is thrown. + """ + source = 'Blogger_Python_Sample-2.0' + service = 'blogger' + + self.client.client_login(login, + password, + source=source, + service=service) + + def _set_blog(self, blogname): + """ + Set correct blog, as defined in blogname + """ + for blog in self.feed.entry: + if blog.get_blog_name() == blogname: + self.blog_id = blog.get_blog_id() + self.blog = blog + break + diff --git a/ftplugin/rst/rst2blogger/main.py b/ftplugin/rst/rst2blogger/main.py new file mode 100644 index 0000000..da4e87f --- /dev/null +++ b/ftplugin/rst/rst2blogger/main.py @@ -0,0 +1,197 @@ +# vim: fileencoding=utf8 +import webbrowser +from xml.dom import minidom +from xml.parsers.expat import ExpatError + +import vim + +from rst2blogger.rest import blogPreview, blogArticleString +from rst2blogger.blogger import VimBlogger + + +class Rst2Blogger(object): + """ + Provide convenient way to communicate between vim and blogger through reST + """ + def __init__(self): + vim.command('call setqflist([])') + + self.buff = vim.current.buffer + self.docinfo_len = 0 + self._set_docinfo_len() + self.login = vim.eval("g:blogger_login") + self.password = vim.eval("g:blogger_pass") + self.blogname = vim.eval("g:blogger_name") + self.buffer_encoding = vim.eval("&fileencoding") + self.vim_encoding = vim.eval("&encoding") + self.draft = int(vim.eval("g:blogger_draft")) + self.maxarticles = int(vim.eval("g:blogger_maxarticles")) + self.confirm_del = int(vim.eval("g:blogger_confirm_del")) + self.stylesheets = vim.eval("g:blogger_stylesheets") + + def preview(self): + """ + Generate HTML Blogger article preview and (optionally) display it in + systems' web browser + """ + bufcontent = "\n".join(self.buff) + name = vim.current.buffer.name + + name = name[:-4] + ".html" + html = blogPreview(bufcontent, self.stylesheets) + self._open_qf(self._check_html(html)) + + output_file = open(name, "w") + output_file.write(html) + output_file.close() + if vim.eval("g:blogger_browser"): + webbrowser.open(name) + return "Generated HTML has been opened in browser" + else: + return "Generated HTML has been written to %s" % name + + def post(self): + bufcontent = "\n".join(vim.current.buffer) + html, attrs = blogArticleString(bufcontent) + + parse_msg = self._check_html(html, True) + if parse_msg: + self._open_qf(parse_msg) + return "There are errors in generated document" + + if not self.password: + self.password = vim.eval('inputsecret("Enter your gmail password: ")') + + blog = VimBlogger(self.blogname, self.login, self.password) + blog.draft = self.draft > 0 + + if 'id' in attrs and attrs['id']: + post = blog.update_article(html, attrs=attrs) + msg = unicode("Article '%s' has been updated" % post.title.text) + msg = msg.encode(self.vim_encoding) + else: + post = blog.create_article(html, attrs=attrs) + msg = "New article with id %s has been created" % \ + post.get_post_id() + + if not post: + return "There is something fishy with creating new article." + + for item, value in (('id', post.get_post_id()), + ('date', post.published.text), + ('title', post.title.text), + ('modified', post.updated.text), + ('tags', + ", ".join([cat.term for cat in post.category]))): + self._update_docinfo(item, value) + return msg + + def delete(self): + """ + Get list of articles, display it to the user, make him choose one and + delete + """ + if not self.password: + self.password = vim.eval('inputsecret("Enter your gmail password: ")') + blog = VimBlogger(self.blogname, self.login, self.password) + + posts = blog.get_articles(self.maxarticles) + + msg = u"inputlist([" + for index, entries in enumerate(posts): + line = "%2d %s %s" % (index+1, + entries[1], + entries[2]) + msg += u'"' + line.replace('"', '\\"') + u'",' + msg = msg[:-1] + msg += u"])" + msg = unicode(msg).encode(self.vim_encoding) + + choice = int(vim.eval(msg)) + if choice: + art = posts[choice-1] + msg = 'confirm("You are about to delete article \'%s\'. Are you sure?"' + msg = unicode(msg % art[1]).encode(self.vim_encoding) + msg += ', "&No\n&Yes")' + + if self.confirm_del: + choice = int(vim.eval(msg)) + else: + choice = 2 + + if choice == 2: + result = blog.delete_article(art[0]) + if result is None: + return "Article deleted" + else: + return result + return "No articles deleted" + + + def _update_docinfo(self, attr, val): + """ + Update current buffer with attributes value + """ + + val = unicode(":%s: %s" % (attr.capitalize(), val)) + val = val.encode(self.buffer_encoding) + + if not self.docinfo_len: + self.buff.append(val, 0) + return + + for num, line in enumerate(self.buff[:self.docinfo_len]): + if ':%s:' % attr in line.lower() and line.startswith(":"): + self.buff[num] = val + return + + self.buff.append(val, 0) + self.docinfo_len += 1 + + def _set_docinfo_len(self): + """ + Set docinfo_len, which means number of lines from the beginning of the + buffer to the first empty line. + """ + for num, line in enumerate(self.buff): + if line and line.startswith(':'): + continue + elif not line: + self.docinfo_len = num + break + else: + self.docinfo_len = 0 + break + + def _open_qf(self, msg): + """ + Open VIm QuickFix window with message, if argument msg is non empty + string. + """ + if msg: + msg1 = "There are problems reported by XML parser:" + msg2 = "Check generated html for errors." + vim.command('call setqflist([{"text": "%s"}, {"text": "%s"}, ' + '{"text": "%s"}])' % (msg1, msg, msg2)) + vim.command('copen') + + def _check_html(self, html, add_container=False): + """ + Check HTML generated document, by simply use minidom parser + If add_container is set to True, entire document is wrapped inside + additional div + returns empty string if parses succeed, else exception message. + """ + + if add_container: + html = "
" + html + "
" + + message = "" + try: + minidom.parseString(html) + except ExpatError as ex: + message = str(ex) + + return message + + diff --git a/ftplugin/rst/vimblogger/rest.py b/ftplugin/rst/rst2blogger/rest.py similarity index 90% rename from ftplugin/rst/vimblogger/rest.py rename to ftplugin/rst/rst2blogger/rest.py index 8a0b707..44f93fd 100644 --- a/ftplugin/rst/vimblogger/rest.py +++ b/ftplugin/rst/rst2blogger/rest.py @@ -14,7 +14,7 @@ class Attrs(object): class Pygments(Directive): """ - Source code syntax hightlighting. + Source code syntax highlighting. """ required_arguments = 1 optional_arguments = 0 @@ -72,7 +72,7 @@ class CustomHTMLTranslator(HTMLTranslator): def depart_docinfo(self, node): """ - Reset body, remove unnecesairy content. + Reset body, remove unnecessary content. """ self.body = [] @@ -165,8 +165,7 @@ class NoHeaderHTMLTranslator(CustomHTMLTranslator): Harvest docinfo fields and store it in global dictionary. """ key, val = [n.astext() for n in node] - key = key.lower() - Attrs.ATTRS[key] = val + Attrs.ATTRS[key.lower()] = val.strip() def visit_date(self, node): """ @@ -176,8 +175,9 @@ class NoHeaderHTMLTranslator(CustomHTMLTranslator): class PreviewHTMLTranslator(CustomHTMLTranslator): """ - Class for dislpay article in the browser as a preview. + Class for display article in the browser as a preview. """ + CSS = [] def __init__(self, document): """ Alter levels for the heading tags, define custom, blog specific @@ -188,9 +188,7 @@ class PreviewHTMLTranslator(CustomHTMLTranslator): self.initial_header_level = 1 self.section_level = 1 # order of css files is important - self.default_stylesheets = ["css/widget_css_2_bundle.css", - "css/style_custom.css", - "css/style_blogger.css"] + self.default_stylesheets = PreviewHTMLTranslator.CSS self.stylesheet = [self.stylesheet_link % self.encode(css) \ for css in self.default_stylesheets] self.body_ = [] @@ -230,21 +228,27 @@ class BlogPreviewWriter(Writer): """ Custom Writer class for generating full HTML of the article """ - def __init__(self): + def __init__(self, stylesheets=None): Writer.__init__(self) + if not stylesheets: + stylesheets = [] self.translator_class = PreviewHTMLTranslator + self.translator_class.CSS = stylesheets def translate(self): self.document.settings.output_encoding = "utf-8" Writer.translate(self) -def blogPreview(string): +def blogPreview(string, stylesheets=None): """ - Returns partial HTML of the article, and attribute dictionary + Returns full HTML of the article. string argument is an article in reST """ - html_output = core.publish_string(string, writer=BlogPreviewWriter()) + if not stylesheets: + stylesheets = [] + html_output = core.publish_string(string, + writer=BlogPreviewWriter(stylesheets)) html_output = html_output.strip() html_output = html_output.replace("", "\n\n") return html_output @@ -259,5 +263,10 @@ def blogArticleString(string): html_output = core.publish_string(string, writer=BlogBodyWriter()) html_output = html_output.strip() html_output = html_output.replace("", "\n\n") - return html_output, Attrs.ATTRS + attrs = {} + for key in Attrs.ATTRS: + if Attrs.ATTRS[key]: + attrs[key] = Attrs.ATTRS[key] + + return html_output, attrs diff --git a/ftplugin/rst/vimblogger/blogger.py b/ftplugin/rst/vimblogger/blogger.py deleted file mode 100644 index f7fb139..0000000 --- a/ftplugin/rst/vimblogger/blogger.py +++ /dev/null @@ -1,130 +0,0 @@ -# vim: fileencoding=utf8 -# -# Blogger interface to make easy way to create/update articles for specified -# blog. -# -# It is assumed one way communication only, so you may create or update an -# article from reST source files. There is no way to recreate article from -# html to reST format. -# -# requirements: -# -# - Vim compiled with +python -# - python 2.x (tested with 2.6) -# - modules -# - gdata (http://code.google.com/p/gdata-python-client) -# - docutils (http://docutils.sourceforge.net) -# - pytz (http://pytz.sourceforge.net) -# -# USE CASES: -# 1. Create new post -# -# use reST template: -# ===8<--- -# :Title: Blog post title -# :Date: optional publish date (for example: 2010-11-28 18:47:05), -# default: now() -# :Modified: optional, default: None -# :Tags: comma separated blog tags -# -# .. more -# -# --->8=== -# -# All four docinfo are optional, however it is nice to give at least a title -# to the article :) -# -# -# -# which is provided under templates directory or as a -# snipMate shoortcut (see .vim/snippets/rst.snippets) -# - -# vim.eval('inputsecret("Password: ")') -# echomsg expand("%:p") -#----------------------------------------------------------------------------- -# -import getpass # TODO: remove -import time -import datetime - -import pytz -import atom -from gdata.blogger.client import BloggerClient - - -class VimBlogger(object): - """ - """ - - def __init__(self, blogname, login, password): - """ - """ - self.blog = None - self.client = BloggerClient() - self._authorize(login, password) - - self.feed = self.client.get_blogs() - self._set_blog(blogname) - #self._get_arts(blogname) - - def _set_blog(self, blogname): - """ - """ - for blog in self.feed.entry: - if blog.get_blog_name() == blogname: - self.blog = blog - break - - - def _get_arts(self, blogname): - """ - """ - feed = self.client.get_posts(self.blog.get_blog_id()) - for entry in feed.entry: - print entry.title.text - # - import ipdb; ipdb.set_trace() - # - # entry.content obiekt zawiera ciało artykułu (entry.content.text - # posiada czystą formę która mnie interesuje najbardziej, do której - # można pisać - # - # entry.category - lista wszystkich kategorii (blogowych tagów), które - # post posiada. Są to elementy klasy atom.data.Category, które - # łatwiutko stworzyć i dodać do posta: - # import atom - # cat1 = atom.data.Category() - # cat1.term = "nowy tag dla bloggera" - # entry.category.append(cat1) - # - # entry.title przechowuje tytuł posta - - def _authorize(self, login, password): - """ - """ - source = 'Blogger_Python_Sample-2.0' - service = 'blogger' - - self.client.client_login(login, - password, - source=source, - service=service) - def create_article(self, title, html_doc, tags=None): - """ - """ - - blog_id = self.blog.get_blog_id() - if tags is None: - tags = [] - return self.client.add_post(blog_id, title, html_doc, labels=tags, - draft=True) - - def update_article(self, title, html_doc, tags=None): - """ - """ - pass - -if __name__ == "__main__": - p = getpass.getpass("Password: ") - b = VimBlogger("rdobosz", "gryf73@gmail.com", p) diff --git a/ftplugin/rst/vimblogger_ft.vim b/ftplugin/rst/vimblogger_ft.vim new file mode 100644 index 0000000..283ea0c --- /dev/null +++ b/ftplugin/rst/vimblogger_ft.vim @@ -0,0 +1,72 @@ +" reST to blogger vim interface. +" Provide some convinient commands for creating preview from the reST file +" and to send articles to blog. + +if exists("b:did_rst_plugin") + finish " load only once +else + let b:did_blogger_plugin = 1 +endif + +if exists(':PreviewBlogArticle') + finish +endif + +if !exists("g:blogger_browser") + let g:blogger_browser = 0 +endif + +if !exists("g:blogger_name") + let g:blogger_name = "" +endif + +if !exists("g:blogger_login") + let g:blogger_login= "" +endif + +if !exists("g:blogger_pass") + let g:blogger_pass = "Kurcz4czek" +endif + +if !exists("g:blogger_draft") + let g:blogger_draft = 1 +endif + +if !exists("g:blogger_maxarticles") + let g:blogger_maxarticles = 0 +endif + +if !exists("g:blogger_confirm_del") + let g:blogger_confirm_del = 1 +endif + +if !exists("g:blogger_stylesheets") + let g:blogger_stylesheets = [] +endif + +python << EOF +import os +import sys + +import vim + +scriptdir = os.path.dirname(vim.eval('expand("")')) +sys.path.insert(0, scriptdir) + +try: + from rst2blogger.main import Rst2Blogger +except ImportError: + print "Plugin vimblogger cannot be loaded, due to lack of required modules" +EOF + +if !exists(":PreviewBlogArticle") + command PreviewBlogArticle py print Rst2Blogger().preview() +endif + +if !exists(":SendBlogArticle") + command SendBlogArticle py print Rst2Blogger().post() +endif + +if !exists(":DeleteBlogArticle") + command DeleteBlogArticle py print Rst2Blogger().delete() +endif diff --git a/plugin/acp.vim b/plugin/acp.vim deleted file mode 100644 index 0c01a31..0000000 --- a/plugin/acp.vim +++ /dev/null @@ -1,170 +0,0 @@ -"============================================================================= -" Copyright (c) 2007-2009 Takeshi NISHIDA -" -" GetLatestVimScripts: 1879 1 :AutoInstall: AutoComplPop -"============================================================================= -" LOAD GUARD {{{1 - -if exists('g:loaded_acp') - finish -elseif v:version < 702 - echoerr 'AutoComplPop does not support this version of vim (' . v:version . ').' - finish -endif -let g:loaded_acp = 1 - -" }}}1 -"============================================================================= -" FUNCTION: {{{1 - -" -function s:defineOption(name, default) - if !exists(a:name) - let {a:name} = a:default - endif -endfunction - -" -function s:makeDefaultBehavior() - let behavs = { - \ '*' : [], - \ 'ruby' : [], - \ 'python' : [], - \ 'perl' : [], - \ 'xml' : [], - \ 'html' : [], - \ 'xhtml' : [], - \ 'css' : [], - \ } - "--------------------------------------------------------------------------- - if !empty(g:acp_behaviorUserDefinedFunction) && - \ !empty(g:acp_behaviorUserDefinedMeets) - for key in keys(behavs) - call add(behavs[key], { - \ 'command' : "\\", - \ 'completefunc' : g:acp_behaviorUserDefinedFunction, - \ 'meets' : g:acp_behaviorUserDefinedMeets, - \ 'repeat' : 0, - \ }) - endfor - endif - "--------------------------------------------------------------------------- - for key in keys(behavs) - call add(behavs[key], { - \ 'command' : "\\", - \ 'completefunc' : 'acp#completeSnipmate', - \ 'meets' : 'acp#meetsForSnipmate', - \ 'onPopupClose' : 'acp#onPopupCloseSnipmate', - \ 'repeat' : 0, - \ }) - endfor - "--------------------------------------------------------------------------- - for key in keys(behavs) - call add(behavs[key], { - \ 'command' : g:acp_behaviorKeywordCommand, - \ 'meets' : 'acp#meetsForKeyword', - \ 'repeat' : 0, - \ }) - endfor - "--------------------------------------------------------------------------- - for key in keys(behavs) - call add(behavs[key], { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForFile', - \ 'repeat' : 1, - \ }) - endfor - "--------------------------------------------------------------------------- - call add(behavs.ruby, { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForRubyOmni', - \ 'repeat' : 0, - \ }) - "--------------------------------------------------------------------------- - call add(behavs.python, { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForPythonOmni', - \ 'repeat' : 0, - \ }) - "--------------------------------------------------------------------------- - call add(behavs.perl, { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForPerlOmni', - \ 'repeat' : 0, - \ }) - "--------------------------------------------------------------------------- - call add(behavs.xml, { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForXmlOmni', - \ 'repeat' : 1, - \ }) - "--------------------------------------------------------------------------- - call add(behavs.html, { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForHtmlOmni', - \ 'repeat' : 1, - \ }) - "--------------------------------------------------------------------------- - call add(behavs.xhtml, { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForHtmlOmni', - \ 'repeat' : 1, - \ }) - "--------------------------------------------------------------------------- - call add(behavs.css, { - \ 'command' : "\\", - \ 'meets' : 'acp#meetsForCssOmni', - \ 'repeat' : 0, - \ }) - "--------------------------------------------------------------------------- - return behavs -endfunction - -" }}}1 -"============================================================================= -" INITIALIZATION {{{1 - -"----------------------------------------------------------------------------- -call s:defineOption('g:acp_enableAtStartup', 1) -call s:defineOption('g:acp_mappingDriven', 0) -call s:defineOption('g:acp_ignorecaseOption', 1) -call s:defineOption('g:acp_completeOption', '.,w,b,k') -call s:defineOption('g:acp_completeoptPreview', 0) -call s:defineOption('g:acp_behaviorUserDefinedFunction', '') -call s:defineOption('g:acp_behaviorUserDefinedMeets', '') -call s:defineOption('g:acp_behaviorSnipmateLength', -1) -call s:defineOption('g:acp_behaviorKeywordCommand', "\") -call s:defineOption('g:acp_behaviorKeywordLength', 2) -call s:defineOption('g:acp_behaviorKeywordIgnores', []) -call s:defineOption('g:acp_behaviorFileLength', 0) -call s:defineOption('g:acp_behaviorRubyOmniMethodLength', 0) -call s:defineOption('g:acp_behaviorRubyOmniSymbolLength', 1) -call s:defineOption('g:acp_behaviorPythonOmniLength', 0) -call s:defineOption('g:acp_behaviorPerlOmniLength', -1) -call s:defineOption('g:acp_behaviorXmlOmniLength', 0) -call s:defineOption('g:acp_behaviorHtmlOmniLength', 0) -call s:defineOption('g:acp_behaviorCssOmniPropertyLength', 1) -call s:defineOption('g:acp_behaviorCssOmniValueLength', 0) -call s:defineOption('g:acp_behavior', {}) -"----------------------------------------------------------------------------- -call extend(g:acp_behavior, s:makeDefaultBehavior(), 'keep') -"----------------------------------------------------------------------------- -command! -bar -narg=0 AcpEnable call acp#enable() -command! -bar -narg=0 AcpDisable call acp#disable() -command! -bar -narg=0 AcpLock call acp#lock() -command! -bar -narg=0 AcpUnlock call acp#unlock() -"----------------------------------------------------------------------------- -" legacy commands -command! -bar -narg=0 AutoComplPopEnable AcpEnable -command! -bar -narg=0 AutoComplPopDisable AcpDisable -command! -bar -narg=0 AutoComplPopLock AcpLock -command! -bar -narg=0 AutoComplPopUnlock AcpUnlock -"----------------------------------------------------------------------------- -if g:acp_enableAtStartup - AcpEnable -endif -"----------------------------------------------------------------------------- - -" }}}1 -"============================================================================= -" vim: set fdm=marker: diff --git a/snippets/python.snippets b/snippets/python.snippets index a26ef7e..8896120 100644 --- a/snippets/python.snippets +++ b/snippets/python.snippets @@ -106,3 +106,11 @@ snippet docmodule """ snippet debug LOG.debug(self.${1:method_name}.__doc__.strip()) +snippet edbg + import sys + pydevdPath = r"/mnt/data/IDE/eclipse/plugins/org.python.pydev.debug_1.6.3.2010100513/pysrc" + if not pydevdPath in sys.path: + sys.path.append(pydevdPath) + import pydevd + pydevd.settrace() +