Version 0.3

DONE: - Highlight non-existent WikiWords.
DONE: - delete current WikiWord (<Leader>wd)
DONE: - g:vimwiki_smartCR=2 => use vim comments (see :h comments :h formatoptions) feature to deal with list items. (thx - Dmitry Alexandrov)
DONE: Add highlighting to TODO:, DONE:, FIXED:.
DONE: Rename current WikiWord - be careful on Windows you cannot rename wikiword to WikiWord. After renaming update all links to that renamed WikiWord
FIXED: Bug - do not duplicate WikiWords in wiki history.
FIXED: after renaming [[wiki word]] twice buffers are not deleted
FIXED: when renaming from [[wiki word]] to WikiWord result is [[WikiWord]]
FIXED: more than one complex words on one line is bugging each other when try go to one of them. [[bla bla bla]] [[dodo dodo dodo]] becomes bla bla bla ]] [[dodo dodo dodo
This commit is contained in:
Maxim Kim 2008-05-15 00:00:00 +00:00 committed by Able Scraper
parent c0b56d572b
commit 0df6adccc3
3 changed files with 376 additions and 197 deletions

View File

@ -1,11 +1,10 @@
" Vim filetype plugin file " Vim filetype plugin file
" Language: Wiki " Language: Wiki
" Maintainer: Maxim Kim (habamax at gmail dot com) " Author: Maxim Kim (habamax at gmail dot com)
" Home: http://code.google.com/p/vimwiki/ " Home: http://code.google.com/p/vimwiki/
" Author: Maxim Kim
" Filenames: *.wiki " Filenames: *.wiki
" Last Change: (07.05.2008 19:25) " Last Change: (14.05.2008 17:25)
" Version: 0.2.2 " Version: 0.3pre
if exists("b:did_ftplugin") if exists("b:did_ftplugin")
finish finish
@ -13,8 +12,12 @@ endif
let b:did_ftplugin = 1 " Don't load another plugin for this buffer let b:did_ftplugin = 1 " Don't load another plugin for this buffer
"" Defaults
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" Reset the following options to undo this plugin. " Reset the following options to undo this plugin.
let b:undo_ftplugin = "setl tw< wrap< lbr< fenc< ff< sua< isf< awa<" let b:undo_ftplugin = "setl tw< wrap< lbr< fenc< ff< sua< isf< awa< com< fo<"
setlocal textwidth=0 setlocal textwidth=0
setlocal wrap setlocal wrap
@ -23,182 +26,13 @@ setlocal fileencoding=utf-8
setlocal fileformat=unix setlocal fileformat=unix
setlocal autowriteall setlocal autowriteall
" for gf " for gf
setlocal suffixesadd=.wiki execute 'setlocal suffixesadd='.g:vimwiki_ext
setlocal isfname-=[,] setlocal isfname-=[,]
if g:vimwiki_smartCR>=2
"" Defaults setlocal comments=b:*,b:#
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" setlocal formatoptions=ctnqro
function! s:default(varname,value)
if !exists('g:vimwiki_'.a:varname)
let g:vimwiki_{a:varname} = a:value
endif endif
endfunction
"" Could be redefined by users
call s:default('index',"")
call s:default('home',"")
call s:default('upper','A-ZА-Я')
call s:default('lower','a-zа-я')
call s:default('other','0-9_')
call s:default('ext','.wiki')
call s:default('smartCR',1)
call s:default('stripsym','_')
call s:default('history',[])
let upp = g:vimwiki_upper
let low = g:vimwiki_lower
let oth = g:vimwiki_other
let nup = low.oth
let nlo = upp.oth
let any = upp.nup
let g:vimwiki_word1 = '['.upp.']['.nlo.']*['.low.']['.nup.']*['.upp.']['.any.']*'
let g:vimwiki_word2 = '\[\[['.upp.low.oth.'[:punct:][:space:]]\+\]\]'
let s:wiki_word = '\C\<'.g:vimwiki_word1.'\>\|'.g:vimwiki_word2
"" Functions {{{
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! s:SearchWord(wikiRx,cmd)
let hl = &hls
let lasts = @/
let @/ = a:wikiRx
set nohls
try
:silent exe 'normal ' a:cmd
catch /Pattern not found/
echoh WarningMsg
echo "No WikiWord found."
echoh None
endt
let @/ = lasts
let &hls = hl
endfunction
function! s:WikiNextWord()
call s:SearchWord(s:wiki_word, 'n')
endfunction
function! s:WikiPrevWord()
call s:SearchWord(s:wiki_word, 'N')
endfunction
function! s:WikiGetWordAtCursor(wikiRX)
let col = col('.') - 1
let line = getline('.')
let ebeg = -1
let cont = match(line, a:wikiRX, 0)
while (ebeg >= 0 || (0 <= cont) && (cont <= col))
let contn = matchend(line, a:wikiRX, cont)
if (cont <= col) && (col < contn)
let ebeg = match(line, a:wikiRX, cont)
let elen = contn - ebeg
break
else
let cont = match(line, a:wikiRX, contn)
endif
endwh
if ebeg >= 0
return strpart(line, ebeg, elen)
else
return ""
endif
endf
function! s:WikiStripWord(word, sym)
function! s:WikiStripWordHelper(word, sym)
return substitute(a:word, '[<>|?*/\:"]', a:sym, 'g')
endfunction
let result = a:word
if strpart(a:word, 0, 2) == "[["
let result = s:WikiStripWordHelper(strpart(a:word, 2, strlen(a:word)-4), a:sym)
endif
return result
endfunction
" Check if word is link to a non-wiki file.
" The easiest way is to check if it has extension like .txt or .html
function! s:WikiLinkToNonWikiFile(word)
if a:word =~ '\..\{1,4}$'
return 1
endif
return 0
endfunction
if !exists('*s:WikiFollowWord')
function! s:WikiFollowWord(split)
if a:split == "split"
let cmd = ":split "
elseif a:split == "vsplit"
let cmd = ":vsplit "
else
let cmd = ":e "
endif
let word = s:WikiStripWord(s:WikiGetWordAtCursor(s:wiki_word), g:vimwiki_stripsym)
" insert doesn't work properly inside :if. Check :help :if.
if word == ""
execute "normal! \n"
return
endif
if s:WikiLinkToNonWikiFile(word)
execute cmd.word
else
" history is [['WikiWord.wiki', 11], ['AnotherWikiWord', 3] ... etc]
" where numbers are column positions we should return when coming back.
call insert(g:vimwiki_history, [expand('%:p'), col('.')])
execute cmd.g:vimwiki_home.word.g:vimwiki_ext
endif
endfunction
function! s:WikiGoBackWord()
if len(g:vimwiki_history) > 0
let word = remove(g:vimwiki_history, 0)
" go back to saved WikiWord
execute ":e ".get(word, 0)
call cursor(line('.'), get(word,1))
endif
endfunction
endif
function! s:WikiNewLine()
function! WikiAutoListItemInsert(listSym)
let sym = escape(a:listSym, '*')
let prevline = getline(line('.')-1)
if prevline =~ '^\s*'.sym
let curline = substitute(getline('.'),'^\s\+',"","g")
if prevline =~ '^\s*'.sym.'\s*$'
" there should be easier way ...
execute 'normal kA '."\<ESC>".'"_dF'.a:listSym.'JX'
return 1
endif
let ind = indent(line('.')-1)
call setline(line('.'), strpart(prevline, 0, ind).a:listSym.' '.curline)
call cursor(line('.'), ind+3)
return 1
endif
return 0
endfunction
if WikiAutoListItemInsert('*')
return
endif
if WikiAutoListItemInsert('#')
return
endif
" delete <space>
execute 'normal x'
endfunction
" Functions }}}
"" Keybindings {{{ "" Keybindings {{{
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
@ -215,15 +49,18 @@ vmap <buffer> j gj
imap <buffer> <Down> <C-o>gj imap <buffer> <Down> <C-o>gj
imap <buffer> <Up> <C-o>gk imap <buffer> <Up> <C-o>gk
nmap <buffer> <CR> :call <SID>WikiFollowWord('nosplit')<CR> nmap <silent><buffer> <CR> :call WikiFollowWord('nosplit')<CR>
nmap <buffer> <S-CR> :call <SID>WikiFollowWord('split')<CR> nmap <silent><buffer> <S-CR> :call WikiFollowWord('split')<CR>
nmap <buffer> <C-CR> :call <SID>WikiFollowWord('vsplit')<CR> nmap <silent><buffer> <C-CR> :call WikiFollowWord('vsplit')<CR>
nmap <buffer> <BS> :call <SID>WikiGoBackWord()<CR> nmap <silent><buffer> <BS> :call WikiGoBackWord()<CR>
nmap <buffer> <TAB> :call <SID>WikiNextWord()<CR> nmap <silent><buffer> <TAB> :call WikiNextWord()<CR>
nmap <buffer> <S-TAB> :call <SID>WikiPrevWord()<CR> nmap <silent><buffer> <S-TAB> :call WikiPrevWord()<CR>
if g:vimwiki_smartCR nmap <silent><buffer> <Leader>wd :call WikiDeleteWord()<CR>
inoremap <CR> <CR> <C-O>:call <SID>WikiNewLine()<CR> nmap <silent><buffer> <Leader>wr :call WikiRenameWord()<CR>
if g:vimwiki_smartCR==1
inoremap <silent><buffer><CR> <CR><Space><C-O>:call WikiNewLine()<CR>
endif endif
" Keybindings }}} " Keybindings }}}

331
plugin/vimwiki.vim Normal file
View File

@ -0,0 +1,331 @@
" VimWiki plugin file
" Language: Wiki
" Author: Maxim Kim (habamax at gmail dot com)
" Home: http://code.google.com/p/vimwiki/
" Filenames: *.wiki
" Last Change: (14.05.2008 17:24)
" Version: 0.3 pre
if exists("loaded_vimwiki") || &cp
finish
endif
let loaded_vimwiki = 1
let s:save_cpo = &cpo
set cpo&vim
function! s:default(varname,value)
if !exists('g:vimwiki_'.a:varname)
let g:vimwiki_{a:varname} = a:value
endif
endfunction
"" Could be redefined by users
call s:default('home',"")
call s:default('index',"index")
call s:default('ext','.wiki')
call s:default('upper','A-ZА-Я')
call s:default('lower','a-zа-я')
call s:default('maxhi','1')
call s:default('other','0-9_')
call s:default('smartCR',1)
call s:default('stripsym','_')
call s:default('history',[])
let upp = g:vimwiki_upper
let low = g:vimwiki_lower
let oth = g:vimwiki_other
let nup = low.oth
let nlo = upp.oth
let any = upp.nup
let g:vimwiki_word1 = '\C['.upp.']['.nlo.']*['.low.']['.nup.']*['.upp.']['.any.']*'
let g:vimwiki_word2 = '\[\[['.upp.low.oth.'[:punct:][:space:]]\{-}\]\]'
let s:wiki_word = '\<'.g:vimwiki_word1.'\>\|'.g:vimwiki_word2
let s:wiki_badsymbols = '[<>|?*/\:"]'
execute 'autocmd! BufNewFile,BufReadPost,BufEnter *'.g:vimwiki_ext.' set ft=vimwiki'
"" Functions {{{
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
function! s:msg(message)"{{{
echohl WarningMsg
echomsg 'vimwiki: '.a:message
echohl None
endfunction"}}}
function! s:SearchWord(wikiRx,cmd)"{{{
let hl = &hls
let lasts = @/
let @/ = a:wikiRx
set nohls
try
:silent exe 'normal ' a:cmd
catch /Pattern not found/
call s:msg('WikiWord not found')
endt
let @/ = lasts
let &hls = hl
endfunction"}}}
function! WikiNextWord()"{{{
call s:SearchWord(s:wiki_word, 'n')
endfunction"}}}
function! WikiPrevWord()"{{{
call s:SearchWord(s:wiki_word, 'N')
endfunction"}}}
function! s:WikiGetWordAtCursor(wikiRX) "{{{
let col = col('.') - 1
let line = getline('.')
let ebeg = -1
let cont = match(line, a:wikiRX, 0)
while (ebeg >= 0 || (0 <= cont) && (cont <= col))
let contn = matchend(line, a:wikiRX, cont)
if (cont <= col) && (col < contn)
let ebeg = match(line, a:wikiRX, cont)
let elen = contn - ebeg
break
else
let cont = match(line, a:wikiRX, contn)
endif
endwh
if ebeg >= 0
return strpart(line, ebeg, elen)
else
return ""
endif
endf "}}}
function! s:WikiStripWord(word, sym)"{{{
function! s:WikiStripWordHelper(word, sym)
return substitute(a:word, s:wiki_badsymbols, a:sym, 'g')
endfunction
let result = a:word
if strpart(a:word, 0, 2) == "[["
let result = s:WikiStripWordHelper(strpart(a:word, 2, strlen(a:word)-4), a:sym)
endif
return result
endfunction"}}}
" Check if word is link to a non-wiki file.
" The easiest way is to check if it has extension like .txt or .html
function! s:WikiIsLinkToNonWikiFile(word)"{{{
if a:word =~ '\..\{1,4}$'
return 1
endif
return 0
endfunction"}}}
" history is [['WikiWord.wiki', 11], ['AnotherWikiWord', 3] ... etc]
" where numbers are column positions we should return when coming back.
"" WikiWord history helper functions {{{2
function! s:GetHistoryWord(historyItem)
return get(a:historyItem, 0)
endfunction
function! s:GetHistoryColumn(historyItem)
return get(a:historyItem, 1)
endfunction
"2}}}
function! WikiFollowWord(split)"{{{
if a:split == "split"
let cmd = ":split "
elseif a:split == "vsplit"
let cmd = ":vsplit "
else
let cmd = ":e "
endif
let word = s:WikiStripWord(s:WikiGetWordAtCursor(s:wiki_word), g:vimwiki_stripsym)
" insert doesn't work properly inside :if. Check :help :if.
if word == ""
execute "normal! \n"
return
endif
if s:WikiIsLinkToNonWikiFile(word)
execute cmd.word
else
call insert(g:vimwiki_history, [expand('%:p'), col('.')])
execute cmd.g:vimwiki_home.word.g:vimwiki_ext
endif
endfunction"}}}
function! WikiGoBackWord() "{{{
if !empty(g:vimwiki_history)
let word = remove(g:vimwiki_history, 0)
" go back to saved WikiWord
execute ":e ".s:GetHistoryWord(word)
call cursor(line('.'), s:GetHistoryColumn(word))
endif
endfunction "}}}
function! WikiNewLine() "{{{
function! s:WikiAutoListItemInsert(listSym)
let sym = escape(a:listSym, '*')
let prevline = getline(line('.')-1)
if prevline =~ '^\s\+'.sym
let curline = substitute(getline('.'),'^\s\+',"","g")
if prevline =~ '^\s*'.sym.'\s*$'
" there should be easier way ...
execute 'normal kA '."\<ESC>".'"_dF'.a:listSym.'JX'
return 1
endif
let ind = indent(line('.')-1)
call setline(line('.'), strpart(prevline, 0, ind).a:listSym.' '.curline)
call cursor(line('.'), ind+3)
return 1
endif
return 0
endfunction
if s:WikiAutoListItemInsert('*')
return
endif
if s:WikiAutoListItemInsert('#')
return
endif
" delete <space>
execute 'normal x'
endfunction "}}}
"" file system funcs
"" Delete WikiWord you are in from filesystem
function! WikiDeleteWord()"{{{
let val = input('Delete ['.expand('%').'] (y/n)? ', "")
if val!='y'
return
endif
let fname = expand('%:p')
" call WikiGoBackWord()
call delete(fname)
execute "bwipeout ".escape(fname, " ")
" delete from g:vimwiki_history list
call filter (g:vimwiki_history, 's:GetHistoryWord(v:val) != fname')
" as we got back to previous WikiWord - delete it from history - as much
" as possible
let hword = s:GetHistoryWord(remove(g:vimwiki_history, 0))
while !empty(g:vimwiki_history) && hword == s:GetHistoryWord(g:vimwiki_history[0])
let hword = s:GetHistoryWord(remove(g:vimwiki_history, 0))
endwhile
" reread buffer => deleted WikiWord should appear as non-existent
execute "e"
endfunction"}}}
"" Rename WikiWord, update all links to renamed WikiWord
function! WikiRenameWord() "{{{
let wwtorename = expand('%:r')
let isOldWordComplex = 0
if wwtorename !~ g:vimwiki_word1
let isOldWordComplex = 1
endif
" there is no file (new one maybe)
if glob(g:vimwiki_home.expand('%')) == ''
call s:msg('Cannot rename "'.expand('%').'". It does not exist!')
return
endif
let val = input('Rename "'.expand('%:r').'" (y/n)? ', "")
if val!='y'
return
endif
let newWord = input('Enter new name: ', "")
" check newWord - it should be 'good', not empty
if substitute(newWord, '\s', '', 'g') == ''
call s:msg('Cannot rename to an empty filename!')
return
endif
if s:WikiIsLinkToNonWikiFile(newWord)
call s:msg('Cannot rename to a filename with extension (ie .txt .html)!')
return
endif
if newWord !~ g:vimwiki_word1
" if newWord is 'complex wiki word' then add [[]]
let newWord = '[['.newWord.']]'
endif
let newFileName = s:WikiStripWord(newWord, g:vimwiki_stripsym).g:vimwiki_ext
" do not rename if word with such name exists
let fname = glob(g:vimwiki_home.newFileName)
if fname != ''
call s:msg('Cannot rename to "'.newFileName.'". File with that name exist!')
return
endif
" rename WikiWord file
try
call rename(expand('%'), newFileName)
bd
execute 'e '.newFileName
catch /.*/
call s:msg('Cannot rename "'.expand('%:r').'" to "'.newFileName.'"')
return
endtry
" save open buffers
let openbuffers = []
let bcount = 1
while bcount<=bufnr("$")
if bufexists(bcount)
call add(openbuffers, bufname(bcount))
endif
let bcount = bcount + 1
endwhile
" update links
execute ':args '.g:vimwiki_home.'*'.g:vimwiki_ext
if isOldWordComplex
execute ':silent argdo %s/\[\['.wwtorename.'\]\]/'.newWord.'/geI | update'
else
execute ':silent argdo %s/\<'.wwtorename.'\>/'.newWord.'/geI | update'
endif
execute ':argd *'.g:vimwiki_ext
" restore open buffers
let bcount = 1
while bcount<=bufnr("$")
if bufexists(bcount)
if index(openbuffers, bufname(bcount)) == -1
execute 'silent bwipeout '.escape(bufname(bcount), " ")
end
endif
let bcount = bcount + 1
endwhile
"" DONE: after renaming GUI caption is a bit corrupted?
"" FIXME: buffers menu is also not in the "normal" state, howto Refresh menu?
endfunction "}}}
function! WikiHighlightWords()"{{{
let wikies = glob(g:vimwiki_home.'*')
let wikies = substitute(wikies, '\'.g:vimwiki_ext, "", "g")
let g:vimwiki_wikiwords = split(wikies, '\n')
call map(g:vimwiki_wikiwords, 'substitute(v:val, ''.*[/\\]'', "", "g")')
for word in g:vimwiki_wikiwords
if word =~ g:vimwiki_word1 && !s:WikiIsLinkToNonWikiFile(word)
execute 'syntax match wikiWord /\<'.word.'\>/'
else
execute 'syntax match wikiWord /\[\['.substitute(word, g:vimwiki_stripsym, s:wiki_badsymbols, "g").'\]\]/'
endif
endfor
endfunction "}}}
function! WikiGoHome()"{{{
execute ':e '.g:vimwiki_home.g:vimwiki_index.g:vimwiki_ext
let g:vimwiki_history = []
endfunction"}}}
" Functions }}}
nmap <silent><unique> <Leader>ww :call WikiGoHome()<CR>

View File

@ -1,12 +1,10 @@
" Vim syntax file " Vim syntax file
" Language: Wiki " Language: Wiki
" Maintainer: Maxim Kim (habamax at gmail dot com) " Author: Maxim Kim (habamax at gmail dot com)
" Home: http://code.google.com/p/vimwiki/ " Home: http://code.google.com/p/vimwiki/
" Author: Maxim Kim
" Filenames: *.wiki " Filenames: *.wiki
" Last Change: (07.05.2008 19:25) " Last Change: (14.05.2008 17:25)
" Version: 0.2.2 " Version: 0.3pre
" Based on FlexWiki
" Quit if syntax file is already loaded " Quit if syntax file is already loaded
if version < 600 if version < 600
@ -15,10 +13,20 @@ elseif exists("b:current_syntax")
finish finish
endif endif
"" use max highlighting - could be quite slow if there are too many wikifiles
if g:vimwiki_maxhi
" Every WikiWord is nonexistent
execute 'syntax match wikiNoExistsWord /'.g:vimwiki_word1.'/'
execute 'syntax match wikiNoExistsWord /'.g:vimwiki_word2.'/'
" till we find them in g:vimwiki_home
call WikiHighlightWords()
else
" A WikiWord (unqualifiedWikiName) " A WikiWord (unqualifiedWikiName)
execute 'syntax match wikiWord /'.g:vimwiki_word1.'/' execute 'syntax match wikiWord /'.g:vimwiki_word1.'/'
" A [bracketed wiki word] " A [[bracketed wiki word]]
execute 'syntax match wikiWord /'.g:vimwiki_word2.'/' execute 'syntax match wikiWord /'.g:vimwiki_word2.'/'
endif
" text: "this is a link (optional tooltip)":http://www.microsoft.com " text: "this is a link (optional tooltip)":http://www.microsoft.com
" TODO: check URL syntax against RFC " TODO: check URL syntax against RFC
@ -69,9 +77,12 @@ syntax match wikiTable /||/
" highlight only bullets and digits. " highlight only bullets and digits.
syntax match wikiList /^\s\+\(\*\|[1-9]\+0*\.\|#\)/ syntax match wikiList /^\s\+\(\*\|[1-9]\+0*\.\|#\)/
syntax match wikiTodo /\(TODO:\|DONE:\|FIXME:\|FIXED:\)/
" Treat all other lines that start with spaces as PRE-formatted text. " Treat all other lines that start with spaces as PRE-formatted text.
syntax match wikiPre /^\s\+[^[:blank:]*#].*$/ syntax match wikiPre /^\s\+[^[:blank:]*#].*$/
syntax region wikiPre start=/^{{{\s*$/ end=/^}}}\s*$/
" Link FlexWiki syntax items to colors " Link FlexWiki syntax items to colors
hi def link wikiH1 Title hi def link wikiH1 Title
@ -87,6 +98,7 @@ hi def wikiItalic term=italic cterm=italic gui=italic
hi def link wikiCode PreProc hi def link wikiCode PreProc
hi def link wikiWord Underlined hi def link wikiWord Underlined
hi def link wikiNoExistsWord Error
hi def link wikiEscape Todo hi def link wikiEscape Todo
hi def link wikiPre PreProc hi def link wikiPre PreProc
@ -99,8 +111,7 @@ hi def link wikiInsText Constant
hi def link wikiSuperScript Constant hi def link wikiSuperScript Constant
hi def link wikiSubScript Constant hi def link wikiSubScript Constant
hi def link wikiCitation Constant hi def link wikiCitation Constant
hi def link wikiTodo Todo
hi def link wikiSingleLineProperty Identifier
let b:current_syntax="vimwiki" let b:current_syntax="vimwiki"