response
[ikiwiki.git] / doc / forum / navigation_of_wiki_pages_on_local_filesystem_with_vim.mdwn
1 I wrote a vim function to help me navigate the wiki when I'm editing it. It extends the 'gf' (goto file) functionality. Once installed, you place the cursor on a wiki page name and press 'gf' (without the quotes); if the file exists, it gets loaded.
2
3 This function takes into account the ikiwiki linking rules when deciding which file to go to.
4
5 > 'gf' gets in the way when there are directories with the same name of a wiki page. The 
6 > function below doesn't implement the linking rules properly (test the link (ignoring case),
7 > if there is no match ascend the dir. hierarchy and start over, until we reach the root of
8 > the wiki). I'm rewriting it to follow these rules properly
9
10 > I think the page for [[LinkingRules|ikiwiki/subpage/linkingrules]] should say that ikiwiki **ascends**
11 > the dir. hierarchy when looking for a wikilink, not that it **descends** it. Am I correct? --[[jerojasro]]
12
13 >> Conventionally, the root directory is considered to be lower than other
14 >> directories, so I think the current wording is correct. --[[Joey]]
15
16 let me know what you think
17
18 To enable this functionality, paste the code below in your `.vim/ftplugin/ikiwiki.vim` file
19
20     " returns the directory which can be considered the root of the wiki the
21     " current buffer belongs to, or an empty string if we are not inside an
22     " ikiwiki wiki
23     "
24     " NOTE: the root of the wiki is considered the first directory that contains a
25     " .ikiwiki folder, except $HOME/.ikiwiki (the usual ikiwiki libdir)
26     "
27     " if you can think of a better heuristic to get ikiwiki's root, let me know!
28     function! GetWikiRootDir()
29       let check_str = '%:p:h'
30       let pos_wiki_root = expand(check_str)
31       while pos_wiki_root != '/'
32         if isdirectory(pos_wiki_root . '/.ikiwiki') && pos_wiki_root != $HOME
33           return pos_wiki_root
34         endif
35         let check_str = check_str . ':h'
36         let pos_wiki_root = expand(check_str)
37       endwhile
38       if isdirectory('/.ikiwiki')
39         return '/'
40       endif
41       return ''
42     endfunction
43     
44     " This function searches for a .mdwn file (<a:name>.mdwn) using the ikiwiki
45     " WikiLink rules and returns its full path.
46     "
47     " The rules are the following
48     "
49     " if the filename starts with '/', use as base dir the root directory of the
50     " wiki
51     "
52     " if not:
53     "
54     " try first ./<bufname>/<a:name>.mdwn
55     " then for  ./<a:name>.mdwn
56     " then for  <root_of_wiki>/<a:name>.mdwn
57     "
58     " return the first one that exists
59     "
60     " the base path (. above) is the directory that contains the current buffer
61     "
62     function! FileForWikiLink(name)
63       let target_fname=a:name . ".mdwn"
64       let wikiroot_dir = GetWikiRootDir()
65       if match(target_fname, '^/') >= 0
66         return wikiroot_dir . target_fname
67       endif
68       let subdir_file = expand('%:p:r') . "/" . target_fname
69       let currdir_file = expand('%:p:h') . "/" . target_fname
70       let wikiroot_file = wikiroot_dir . "/" . target_fname
71       if filewritable(subdir_file)
72         return subdir_file
73       endif
74       if filewritable(currdir_file)
75         return currdir_file
76       endif
77       if filewritable(wikiroot_file)
78         return wikiroot_file
79       endif
80       return a:name
81     endfunction
82     
83     setlocal includeexpr=FileForWikiLink(v:fname)