vimwiki/plugin/vimwiki.vim
Maxim Kim 2cd2e35d0a Version 0.3.3
* FIXED: `[[wiki word with dots at the end...]]` didn't work.
  * DONE: Added error handling for `delete wiki word` function.
  * DONE: Added keybindings `o` and `O` for list items when g:vimwiki_smartCR=1.
  * DONE: Added keybinding `<Leader>wh` to visit wiki home directory.
0001-01-01 00:00:00 +00:00

383 lines
11 KiB
VimL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

" VimWiki plugin file
" Language: Wiki
" Author: Maxim Kim (habamax at gmail dot com)
" Home: http://code.google.com/p/vimwiki/
" Filenames: *.wiki
" Last Change: (23.05.2008 16:38)
" Version: 0.3.3
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('addheading','1')
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:getfilename(filename)
let word = substitute(a:filename, '\'.g:vimwiki_ext, "", "g")
let word = substitute(word, '.*[/\\]', "", "g")
return word
endfunction
function! s:editfile(command, filename)
let fname = escape(a:filename, '% ')
execute a:command.' '.fname
" if fname is new
" if g:vimwiki_addheading!=0 && glob(fname) == ''
" execute 'normal I! '.s:getfilename(fname)
" update
" endif
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 =~ '\.\w\{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)
call s:editfile(cmd, word)
else
call insert(g:vimwiki_history, [expand('%:p'), col('.')])
call s:editfile(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 "}}}
"" direction == checkup - use previous line for checking
"" direction == checkdown - use next line for checking
function! WikiNewLine(direction) "{{{
function! s:WikiAutoListItemInsert(listSym, dir)
let sym = escape(a:listSym, '*')
if a:dir=='checkup'
let linenum = line('.')-1
else
let linenum = line('.')+1
end
let prevline = getline(linenum)
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(linenum)
call setline(line('.'), strpart(prevline, 0, ind).a:listSym.' '.curline)
call cursor(line('.'), ind+3)
return 1
endif
return 0
endfunction
if s:WikiAutoListItemInsert('*', a:direction)
return
endif
if s:WikiAutoListItemInsert('#', a:direction)
return
endif
" delete <space>
if getline('.') =~ '^\s\+$'
execute 'normal x'
else
execute 'normal X'
endif
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()
try
call delete(fname)
catch /.*/
call s:msg('Cannot delete "'.expand('%:r').'"!')
return
endtry
execute "bdelete! ".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 wwtorename = substitute(wwtorename, g:vimwiki_stripsym, s:wiki_badsymbols, "g")
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
"function call doesn't work
call s:editfile('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 bdelete '.escape(bufname(bcount), " ")
end
endif
let bcount = bcount + 1
endwhile
"" DONE: after renaming GUI caption is a bit corrupted?
"" FIXED: buffers menu is also not in the "normal" state, howto Refresh menu?
execute "emenu Buffers.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 }}}
"" Commands {{{
command WikiRenameWord call WikiRenameWord()
command WikiDeleteWord call WikiDeleteWord()
command WikiGoHome call WikiGoHome()
command WikiGoBackWord call WikiGoBackWord()
command -nargs=1 WikiFollowWord call WikiFollowWord(<f-args>)
command WikiNextWord call WikiNextWord()
command WikiPrevWord call WikiPrevWord()
"" Commands }}}
nmap <silent><unique> <Leader>ww :call WikiGoHome()<CR>
nmap <silent><unique> <Leader>wh :execute "edit ".g:vimwiki_home."."<CR>