moved discussion to the forum main page
[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 >         " NOTE: the root of the wiki is considered the first directory that contains a
19 >         " .ikiwiki folder, except $HOME/.ikiwiki (the usual ikiwiki libdir)
20
21 > That's not going to work in all situations; for example, with an ikiwiki which uses git as the backend, the normal setup is that one has
22
23 > * a bare git repository
24 > * a git repository which ikiwiki builds the wiki from (which has a .ikiwiki directory in it)
25 > * an *additional* git repository cloned from the bare repository, which is used for making changes from the command-line rather than the web.  It is this repository in which one would be editing files with vim, and *this* repository does not have a .ikiwiki directory in it.  It does have a .git directory in the root, however, so I suppose you could use that as a method of detection of a root directory, but of course that would only work for git repositories.
26
27 > -- [[KathrynAndersen]]
28
29 >> You are completely right; all of my wikis are compiled both locally and
30 >> remotely, and so the local repo also has a `.ikiwiki` folder. And that's not the
31 >> "usual" setup.
32 >> 
33 >> checking for a `.git` dir would not work when the wiki's source files aren't
34 >> located at the root of the repo.
35 >> 
36 >> So, besides of doing a `touch .ikiwiki` at the root of the wiki in your local
37 >> repo, do you see any alternative?
38 >> 
39 >> -- [[jerojasro]]
40 To enable this functionality, paste the code below in your `.vim/ftplugin/ikiwiki.vim` file
41
42     " returns the directory which can be considered the root of the wiki the
43     " current buffer belongs to, or an empty string if we are not inside an
44     " ikiwiki wiki
45     "
46     " NOTE: the root of the wiki is considered the first directory that contains a
47     " .ikiwiki folder, except $HOME/.ikiwiki (the usual ikiwiki libdir)
48     "
49     " if you can think of a better heuristic to get ikiwiki's root, let me know!
50     function! GetWikiRootDir()
51       let check_str = '%:p:h'
52       let pos_wiki_root = expand(check_str)
53       while pos_wiki_root != '/'
54         if isdirectory(pos_wiki_root . '/.ikiwiki') && pos_wiki_root != $HOME
55           return pos_wiki_root
56         endif
57         let check_str = check_str . ':h'
58         let pos_wiki_root = expand(check_str)
59       endwhile
60       if isdirectory('/.ikiwiki')
61         return '/'
62       endif
63       return ''
64     endfunction
65     
66     " This function searches for a .mdwn file (<a:name>.mdwn) using the ikiwiki
67     " WikiLink rules and returns its full path.
68     "
69     " The rules are the following
70     "
71     " if the filename starts with '/', use as base dir the root directory of the
72     " wiki
73     "
74     " if not:
75     "
76     " try first ./<bufname>/<a:name>.mdwn
77     " then for  ./<a:name>.mdwn
78     " then for  <root_of_wiki>/<a:name>.mdwn
79     "
80     " return the first one that exists
81     "
82     " the base path (. above) is the directory that contains the current buffer
83     "
84     function! FileForWikiLink(name)
85       let target_fname=a:name . ".mdwn"
86       let wikiroot_dir = GetWikiRootDir()
87       if match(target_fname, '^/') >= 0
88         return wikiroot_dir . target_fname
89       endif
90       let subdir_file = expand('%:p:r') . "/" . target_fname
91       let currdir_file = expand('%:p:h') . "/" . target_fname
92       let wikiroot_file = wikiroot_dir . "/" . target_fname
93       if filewritable(subdir_file)
94         return subdir_file
95       endif
96       if filewritable(currdir_file)
97         return currdir_file
98       endif
99       if filewritable(wikiroot_file)
100         return wikiroot_file
101       endif
102       return a:name
103     endfunction
104     
105     setlocal includeexpr=FileForWikiLink(v:fname)