├── .github ├── issue_template.md └── pull_request_template.md ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.md ├── README-cn.md ├── README.md ├── autoload └── vimwiki │ ├── .gitignore │ ├── base.vim │ ├── customwiki2html.sh │ ├── default.tpl │ ├── diary.vim │ ├── html.vim │ ├── lst.vim │ ├── markdown_base.vim │ ├── path.vim │ ├── style.css │ ├── tags.vim │ ├── tbl.vim │ ├── u.vim │ └── vars.vim ├── doc ├── entries.png ├── lists.png ├── screenshot_1.png ├── screenshot_2.png ├── todos.png ├── vimwiki.txt └── wiki.png ├── ftplugin └── vimwiki.vim ├── plugin └── vimwiki.vim └── syntax ├── vimwiki.vim ├── vimwiki_default.vim ├── vimwiki_markdown.vim ├── vimwiki_markdown_custom.vim └── vimwiki_media.vim /.github/issue_template.md: -------------------------------------------------------------------------------- 1 | Prior to submitting a new issue make sure to complete these steps: 2 | 3 | - [ ] Checkout the `dev` branch and confirm the issue is present there as well. 4 | The `dev` branch contains fixes that may not have been merged to `master` yet. 5 | - [ ] Post the syntax you are using (default/mediawiki/markdown) **and** your vimwiki settings from your `.vimrc` 6 | - [ ] Provide a detailed description of the problem including **steps to reproduce the issue**. 7 | - [ ] Include the output of `:VimwikiShowVersion`. 8 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Steps for submitting a pull request: 2 | 3 | - [ ] **ALL** pull requests should be made against the `dev` branch! 4 | - [ ] Take a look at [CONTRIBUTING.MD](https://github.com/vimwiki/vimwiki/blob/dev/CONTRIBUTING.md) 5 | - [ ] Reference any related issues. 6 | - [ ] Provide a description of the proposed changes. 7 | - [ ] PRs must pass Vint tests and add new Vader tests as applicable. 8 | - [ ] Make sure to update the documentation in `doc/vimwiki.txt` if applicable, 9 | including the Changelog and Contributors sections. 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Local stuff 2 | # This section is devoted to this project 3 | ############################## 4 | doc/tags 5 | 6 | # Vim stuff 7 | ############################## 8 | *.s[a-w][a-z] 9 | *.un~ 10 | Session.vim 11 | .netrwhist 12 | *~ 13 | 14 | # OS generated files 15 | ############################## 16 | .DS_Store 17 | .DS_Store? 18 | ._* 19 | .Spotlight-V100 20 | .Trashes 21 | ehthumbs.db 22 | Thumbs.db 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Filing a bug 2 | 3 | Before filing a bug or starting to write a patch, check the latest development version from 4 | https://github.com/vimwiki/vimwiki/tree/dev to see if your problem is already fixed. 5 | 6 | Issues can be filed at https://github.com/vimwiki/vimwiki/issues/ . 7 | 8 | # Creating a pull request 9 | 10 | If you want to provide a pull request on GitHub, please start from the `dev` branch, not from the 11 | `master` branch. (Caution, GitHub shows `master` as the default branch from which to start a PR.) 12 | 13 | Make sure to update `doc/vimwiki.txt` with the following information: 14 | 15 | 1. Update the changelog to include information on the new feature the PR introduces or the bug it 16 | is fixing. 17 | 2. Add a help section to describe any new features or options. 18 | 2. If you are a first time contributor add your name to the list of contributors. 19 | 20 | # More info and advice for (aspiring) core developers 21 | 22 | - Before implementing a non-trivial feature, think twice what it means for the user. We should 23 | always try to keep backward compatibility. If you are not sure, discuss it on GitHub. 24 | - Also, when thinking about adding a new feature, it should be something which fits into the 25 | overall design of Vimwiki and which a significant portion of the users may like. Keep in mind 26 | that everybody has their own way to use Vimwiki. 27 | - Keep the coding style consistent. 28 | - Test your changes. Keep in mind that Vim has a ton of options and the users tons of different 29 | setups. Take a little time to think about under which circumstances your changes could break. 30 | 31 | ## Git branching model 32 | 33 | - there are two branches with eternal lifetime: 34 | - `dev`: This is where the main development happens. Tasks which are done in one or only a few 35 | commits go here directly. Always try to keep this branch in a working state, that is, if the 36 | task you work on requires multiple commits, make sure intermediate commits don't make Vimwiki 37 | unusable (or at least push these commits at one go). 38 | - `master`: This branch is for released states only. Whenever a reasonable set of changes has 39 | piled up in the `dev` branch, a [release is done](#Preparing a release). After a release, 40 | `dev` has been merged into `master` and `master` got exactly one additional commit in which 41 | the version number in `plugin/vimwiki.vim` is updated. Apart from these commits and the merge 42 | commit from `dev`, nothing happens on `master`. Never should `master` merge into `dev`. When 43 | the users ask, we should recommend this branch for them to use. 44 | - Larger changes which require multiple commits are done in feature branches. They are based on 45 | `dev` and merge into `dev` when the work is done. 46 | 47 | ## Preparing a release 48 | 49 | 1. `git checkout dev` 50 | 2. Update the changelog in the doc, nicely grouped, with a new version number and release date. 51 | 3. Update the list of contributors. 52 | 4. Update the version number at the top of the doc file. 53 | 5. If necessary, update the Readme and the home page. 54 | 6. `git checkout master && git merge dev` 55 | 7. Update the version number at the top of plugin/vimwiki.vim. 56 | 8. Set a tag with the version number in Git: `git tag vX.Y` 57 | 9. `git push --tags` 58 | 10. In GitHub, go to _Releases_ -> _Draft a new release_ -> choose the tag, convert the changelog from the 59 | doc to markdown and post it there. Make plans to build an automatic converter and immediately 60 | forget this plan. 61 | 11. Tell the world. 62 | 63 | %% vim:tw=99 64 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2008-2010 Maxim Kim 4 | 2013-2017 Daniel Schemala 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README-cn.md: -------------------------------------------------------------------------------- 1 | VimWiki —— Vim 个人 Wiki 插件 2 | ============================================================================== 3 | 4 | [English](README.md) 5 | 6 | ![screenshot1](doc/screenshot_1.png) 7 | ![screenshot2](doc/screenshot_2.png) * 8 | 9 | 介绍 10 | ------------------------------------------------------------------------------ 11 | 12 | Vimwiki 是 Vim 中的个人 Wiki —— 一组链接起来的、有独特语法高亮的文本文件。 13 | 14 | 通过 Vimwiki,你可以: 15 | 16 | * 组织笔记和想法 17 | * 管理待办事项 18 | * 编写文档 19 | * 坚持写日记 20 | * 将这一切导出成 HTML 网页 21 | 22 | 马上开始!按下 `ww`(通常是 `\ww`)进入作为目录页的 wiki 文件,这个文件默认存放在 `~/vimwiki/index.wiki`。 23 | 24 | 在该文件中输入以下示例: 25 | 26 | = 我的个人知识库 = 27 | * 任务列表 -- _昨天_ 就该完成的事!!! 28 | * Gutenberg 计划 -- 好书给我力量。 29 | * 草稿 -- 临时记录一些东西。 30 | 31 | 把光标移到 `任务` 二字上,按 Enter(回车)创建链接。按下后,`任务`二字会变成 `[[任务]]` —— 这是一个 Vimwiki 链接。再次按 Enter 即可进入这个链接(打开新的 wiki 文件)。编辑这个新文件,保存,然后按 Backspace(退格)就能回到目录页。 32 | 33 | 如果 Vimwiki 链接长度不止一个单词(指的是英文单词),只需在 Visual 模式选择这段文本后按 Enter 即可。用上面的 `Gutenberg 计划` 试试吧。最终结果是这样: 34 | 35 | = 我的个人知识库 = 36 | * [[任务列表]] -- _昨天_ 就该完成的事!!! 37 | * [[Gutenberg 计划]] -- 好书给我力量。 38 | * 草稿 -- 临时记录一些东西。 39 | 40 | 41 | 基本标记 42 | ------------------------------------------------------------------------------ 43 | 44 | = 一级标题 = 45 | == 二级标题 == 46 | === 三级标题 === 47 | 48 | 49 | *bold* -- 粗体文本 50 | _italic_ -- 斜体文本 51 | (应用于句中的汉字文本时,必须在标记前后加空格,例如:一段 *中文* 文本) 52 | 53 | [[wiki link]] -- wiki 链接 54 | [[wiki link|description]] -- 带有描述文本的 wiki 链接 55 | 56 | 57 | 列表: 58 | 59 | * bullet list item 1(无编号列表) 60 | - bullet list item 2 61 | - bullet list item 3 62 | * bullet list item 4 63 | * bullet list item 5 64 | * bullet list item 6 65 | * bullet list item 7 66 | - bullet list item 8 67 | - bullet list item 9 68 | 69 | 1. numbered list item 1(有编号列表) 70 | 2. numbered list item 2 71 | a) numbered list item 3 72 | b) numbered list item 4 73 | 74 | 75 | 更多格式说明,请阅 `:h vimwiki-syntax` 76 | 77 | 78 | 键位绑定 79 | ------------------------------------------------------------------------------ 80 | 81 | normal 模式: 82 | 83 | * `ww` -- 打开默认的 wiki 目录文件 84 | * `wt` -- 在新标签(Tab)中打开 wiki 目录文件 85 | * `ws` -- 在多个 wiki 中选择并打开该 wiki 的目录文件 86 | * `wd` -- 删除当前 wiki 文件 87 | * `wr` -- 重命名当前 wiki 文件 88 | * `` -- 创建或打开 wiki 链接 89 | * `` -- 先上下分屏再打开 wiki 链接(若非链接则先创建) 90 | * `` -- 先左右分屏再打开 wiki 链接(若非链接则先创建) 91 | * `` -- 返回之前浏览的 wiki 文件 92 | * `` -- 跳到本文件中下一个 wiki 链接 93 | * `` -- 跳到本文件中上一个 wiki 链接 94 | 95 | 更多快捷键说明,请阅 `:h vimwiki-mappings` 96 | 97 | 98 | 命令 99 | ------------------------------------------------------------------------------ 100 | 101 | * `:Vimwiki2HTML` -- 将当前 wiki 文件转换成 HTML 网页 102 | * `:VimwikiAll2HTML` -- 把所有 wiki 文件转换成 HTML 网页 103 | * `:help vimwiki-commands` -- 显示全部命令 104 | 105 | 106 | 安装 107 | ============================================================================== 108 | 109 | 准备工作 110 | ------------------------------------------------------------------------------ 111 | 112 | 确保在 `vimrc` 中加入了以下设置: 113 | 114 | set nocompatible 115 | filetype plugin on 116 | syntax on 117 | 118 | 没有这些设置,Vimwiki 将无法正常工作。 119 | 120 | 通过 [Vim packages](http://vimhelp.appspot.com/repeat.txt.html#packages) 安装(Vim 7.4.1528 后) 121 | ------------------------------------------------------------------------------ 122 | 123 | git clone https://github.com/vimwiki/vimwiki.git ~/.vim/pack/plugins/start/vimwiki 124 | 125 | 通过 [Pathogen](http://www.vim.org/scripts/script.php?script_id=2332) 安装 126 | ------------------------------------------------------------------------------ 127 | 128 | cd ~/.vim 129 | mkdir bundle 130 | cd bundle 131 | git clone https://github.com/vimwiki/vimwiki.git 132 | 133 | 通过 [Vim-Plug](https://github.com/junegunn/vim-plug) 安装 134 | ------------------------------------------------------------------------------ 135 | 136 | 在 `vimrc` 中加入以下插件设置: 137 | 138 | Plug 'vimwiki/vimwiki' 139 | 140 | 然后运行 `:PlugInstall`。 141 | 142 | 通过 [Vundle](https://github.com/VundleVim/Vundle.vim) 安装 143 | ------------------------------------------------------------------------------ 144 | 145 | 在 `vimrc` 中加入 `Plugin 'vimwiki/vimwiki'`,然后执行: 146 | 147 | vim +PluginInstall +qall 148 | 149 | 或者下载 [zip 压缩包](https://github.com/vimwiki/vimwiki/archive/master.zip)然后解压到 `~/.vim/bundle/` 目录下。 150 | 151 | 安装后,启动 Vim 并执行 `:Helptags` 以及 `:help vimwiki`,检查安装是否成功。 152 | 153 | 154 | 获取帮助 155 | ============================================================================== 156 | 157 | 遇到问题?在 Freenode 的 IRC 频道 `#vimwiki`([网页聊天](https://webchat.freenode.net/?channels=#vimwiki))提问,或者发送问题到[邮件列表](https://groups.google.com/forum/#!forum/vimwiki)上吧。 158 | 159 | 160 | ---- 161 | \* 前面截图中用的是 [solarized 配色方案](https://github.com/altercation/vim-colors-solarized)以及 [lightline](https://github.com/itchyny/lightline.vim) 插件。 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VimWiki: A Personal Wiki For Vim 2 | 3 | [中文](README-cn.md) 4 | 5 | - [Intro](#intro) 6 | - [Installation](#installation) 7 | - [Prerequisites](#prerequisites) 8 | - [VIM Packages](#installation-using-vim-packages-since-vim-741528) 9 | - [Pathogen](#installation-using-pathogen) 10 | - [Vim-Plug](#installation-using-vim-plug) 11 | - [Vundle](#installation-using-vundle) 12 | - [Basic Markup](#basic-markup) 13 | - [Lists](#lists) 14 | - [Key Bindings](#key-bindings) 15 | - [Commands](#commands) 16 | - [Changing Wiki Syntax](#changing-wiki-syntax) 17 | - [Getting Help](#getting-help) 18 | - [Helping VimWiki](#helping-vimwiki) 19 | - [Wiki](https://github.com/vimwiki/vimwiki/wiki) 20 | - [License](#license) 21 | 22 | ## Intro 23 | 24 | VimWiki is a personal wiki for Vim -- a number of linked text files that have 25 | their own syntax highlighting. 26 | 27 | With VimWiki you can: 28 | 29 | * Organize notes and ideas 30 | * Manage to-do lists 31 | * Write documentation 32 | * Maintain a diary 33 | * Export everything to HTML 34 | 35 | To do a quick start press `ww` (this is usually `\ww`) to go to your 36 | index wiki file. By default it is located in `~/vimwiki/index.wiki`. 37 | 38 | Feed it with the following example: 39 | 40 | ``` 41 | 42 | = My knowledge base = 43 | * Tasks -- things to be done _yesterday_!!! 44 | * Project Gutenberg -- good books are power. 45 | * Scratchpad -- various temporary stuff. 46 | 47 | ``` 48 | 49 | Place your cursor on `Tasks` and press Enter to create a link. Once pressed, 50 | `Tasks` will become `[[Tasks]]` -- a VimWiki link. Press Enter again to 51 | open it. Edit the file, save it, and then press Backspace to jump back to your 52 | index. 53 | 54 | A VimWiki link can be constructed from more than one word. Just visually 55 | select the words to be linked and press Enter. Try it with `Project Gutenberg`. 56 | The result should look something like: 57 | 58 | ``` 59 | 60 | = My knowledge base = 61 | * [[Tasks]] -- things to be done _yesterday_!!! 62 | * [[Project Gutenberg]] -- good books are power. 63 | * Scratchpad -- various temporary stuff. 64 | 65 | ``` 66 | 67 | ## Screenshots 68 | 69 | ![Lists View](doc/lists.png) 70 | ![Entries View](doc/entries.png) 71 | ![Todos View](doc/todos.png) 72 | ![Wiki View](doc/wiki.png) 73 | 74 | ## Installation 75 | 76 | ### Prerequisites 77 | 78 | Make sure you have these settings in your vimrc file: 79 | 80 | ```vim 81 | 82 | set nocompatible 83 | filetype plugin on 84 | syntax on 85 | 86 | ``` 87 | 88 | Without them VimWiki will not work properly. 89 | 90 | 91 | #### Installation using [Vim packages](http://vimhelp.appspot.com/repeat.txt.html#packages) (since Vim 7.4.1528) 92 | 93 | ```sh 94 | 95 | git clone https://github.com/vimwiki/vimwiki.git ~/.vim/pack/plugins/start/vimwiki 96 | 97 | ``` 98 | 99 | #### Installation using [Pathogen](http://www.vim.org/scripts/script.php?script_id=2332) 100 | 101 | ```sh 102 | 103 | cd ~/.vim 104 | mkdir bundle 105 | cd bundle 106 | git clone https://github.com/vimwiki/vimwiki.git 107 | 108 | ``` 109 | 110 | #### Installation using [Vim-Plug](https://github.com/junegunn/vim-plug) 111 | 112 | Add the following to the plugin-configuration in your vimrc: 113 | 114 | ```vim 115 | 116 | Plug 'vimwiki/vimwiki' 117 | 118 | ``` 119 | 120 | Then run `:PlugInstall`. 121 | 122 | #### Installation using [Vundle](https://github.com/VundleVim/Vundle.vim) 123 | 124 | Add `Plugin 'vimwiki/vimwiki'` to your vimrc file and run 125 | 126 | ```sh 127 | 128 | vim +PluginInstall +qall 129 | 130 | ``` 131 | 132 | Or download the [zip 133 | archive](https://github.com/vimwiki/vimwiki/archive/master.zip) and extract it 134 | in `~/.vim/bundle/` 135 | 136 | Then launch Vim, run `:Helptags` and then `:help vimwiki` to verify it was 137 | installed. 138 | 139 | ## Basic Markup 140 | 141 | ``` 142 | = Header1 = 143 | == Header2 == 144 | === Header3 === 145 | 146 | 147 | *bold* -- bold text 148 | _italic_ -- italic text 149 | 150 | [[wiki link]] -- wiki link 151 | [[wiki link|description]] -- wiki link with description 152 | ``` 153 | 154 | ### Lists: 155 | 156 | ``` 157 | * bullet list item 1 158 | - bullet list item 2 159 | - bullet list item 3 160 | * bullet list item 4 161 | * bullet list item 5 162 | * bullet list item 6 163 | * bullet list item 7 164 | - bullet list item 8 165 | - bullet list item 9 166 | 167 | 1. numbered list item 1 168 | 2. numbered list item 2 169 | a) numbered list item 3 170 | b) numbered list item 4 171 | ``` 172 | 173 | For other syntax elements, see `:h vimwiki-syntax` 174 | 175 | ## Key bindings 176 | 177 | Normal mode: 178 | 179 | * `ww` -- Open default wiki index file. 180 | * `wt` -- Open default wiki index file in a new tab. 181 | * `ws` -- Select and open wiki index file. 182 | * `wd` -- Delete wiki file you are in. 183 | * `wr` -- Rename wiki file you are in. 184 | * `` -- Follow/Create wiki link 185 | * `` -- Split and follow/create wiki link 186 | * `` -- Vertical split and follow/create wiki link 187 | * `` -- Go back to parent(previous) wiki link 188 | * `` -- Find next wiki link 189 | * `` -- Find previous wiki link 190 | 191 | For more keys, see `:h vimwiki-mappings` 192 | 193 | ## Commands 194 | 195 | * `:Vimwiki2HTML` -- Convert current wiki link to HTML 196 | * `:VimwikiAll2HTML` -- Convert all your wiki links to HTML 197 | * `:help vimwiki-commands` -- list all commands 198 | * `:help vimwiki` -- General vimwiki help docs 199 | 200 | ## Changing Wiki Syntax 201 | 202 | VimWiki currently ships with 3 syntaxes: VimWiki (default), Markdown 203 | (markdown), and MediaWiki (media) 204 | 205 | If you would prefer to use either Markdown or MediaWiki syntaxes, set the 206 | following option in your .vimrc: 207 | 208 | ```vim 209 | 210 | let g:vimwiki_list = [{'path': '~/vimwiki/', 211 | \ 'syntax': 'markdown', 'ext': '.md'}] 212 | 213 | ``` 214 | 215 | ## Getting help 216 | 217 | **Have a question?** 218 | Visit the IRC channel [`#vimwiki`](https://webchat.freenode.net/?channels=#vimwiki) on Freenode ([webchat](https://webchat.freenode.net/?channels=#vimwiki), also synced to Matrix/Riot: `#vimwiki:matrix.org`) or post to the [mailing list](https://groups.google.com/forum/#!forum/vimwiki). 219 | 220 | ## Helping VimWiki 221 | 222 | VimWiki has a lot of users but only very few recurring developers or people 223 | helping the community. Your help is therefore appreciated. Everyone can help! 224 | See [#625](https://github.com/vimwiki/vimwiki/issues/625) for information on 225 | how you can help. 226 | 227 | ## License 228 | 229 | MIT License 230 | 231 | Copyright (c) 2008-2010 Maxim Kim 232 | 2013-2017 Daniel Schemala 233 | 234 | Permission is hereby granted, free of charge, to any person obtaining a copy 235 | of this software and associated documentation files (the "Software"), to deal 236 | in the Software without restriction, including without limitation the rights 237 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 238 | copies of the Software, and to permit persons to whom the Software is 239 | furnished to do so, subject to the following conditions: 240 | 241 | The above copyright notice and this permission notice shall be included in all 242 | copies or substantial portions of the Software. 243 | 244 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 245 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 246 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 247 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 248 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 249 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 250 | SOFTWARE. 251 | -------------------------------------------------------------------------------- /autoload/vimwiki/.gitignore: -------------------------------------------------------------------------------- 1 | *.old 2 | -------------------------------------------------------------------------------- /autoload/vimwiki/customwiki2html.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # This script converts markdown into html, to be used with vimwiki's 5 | # "customwiki2html" option. Experiment with the two proposed methods by 6 | # commenting / uncommenting the relevant lines below. 7 | # 8 | # NEW! An alternative converter was developed by Jason6Anderson, and can 9 | # be located at https://github.com/vimwiki-backup/vimwiki/issues/384 10 | # 11 | # 12 | # To use this script, you must have the Discount converter installed. 13 | # 14 | # http://www.pell.portland.or.us/~orc/Code/discount/ 15 | # 16 | # To verify your installation, check that the commands markdown and mkd2text, 17 | # are on your path. 18 | # 19 | # Also verify that this file is executable. 20 | # 21 | # Then, in your .vimrc file, set: 22 | # 23 | # g:vimwiki_customwiki2html=$HOME.'/.vim/autoload/vimwiki/customwiki2html.sh' 24 | # 25 | # On your next restart, Vimwiki will run this script instead of using the 26 | # internal wiki2html converter. 27 | # 28 | 29 | MARKDOWN=markdown 30 | MKD2HTML=mkd2html 31 | 32 | 33 | FORCE="$1" 34 | SYNTAX="$2" 35 | EXTENSION="$3" 36 | OUTPUTDIR="$4" 37 | INPUT="$5" 38 | CSSFILE="$6" 39 | 40 | FORCEFLAG= 41 | 42 | [ $FORCE -eq 0 ] || { FORCEFLAG="-f"; }; 43 | [ $SYNTAX = "markdown" ] || { echo "Error: Unsupported syntax"; exit -2; }; 44 | 45 | OUTPUT="$OUTPUTDIR"/$(basename "$INPUT" .$EXTENSION).html 46 | 47 | # # Method 1: 48 | # # markdown [-d] [-T] [-V] [-b url-base] [-C prefix] [-F bitmap] [-f flags] [-o file] [-s text] [-t text] [textfile] 49 | # 50 | # URLBASE=http://example.com 51 | # $MARKDOWN -T -b $URLBASE -o $OUTPUT $INPUT 52 | 53 | 54 | # Method 2: 55 | # mkd2html [-css file] [-header string] [-footer string] [file] 56 | 57 | $MKD2HTML -css "$CSSFILE" "$INPUT" 58 | OUTPUTTMP=$(dirname "$INPUT")/$(basename "$INPUT" ."$EXTENSION").html 59 | mv -f "$OUTPUTTMP" "$OUTPUT" 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /autoload/vimwiki/default.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %title% 6 | 7 | 8 | 9 | %content% 10 | 11 | 12 | -------------------------------------------------------------------------------- /autoload/vimwiki/diary.vim: -------------------------------------------------------------------------------- 1 | " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 2 | " Vimwiki autoload plugin file 3 | " Description: Handle diary notes 4 | " Home: https://github.com/vimwiki/vimwiki/ 5 | 6 | 7 | if exists("g:loaded_vimwiki_diary_auto") || &cp 8 | finish 9 | endif 10 | let g:loaded_vimwiki_diary_auto = 1 11 | 12 | 13 | let s:vimwiki_max_scan_for_caption = 5 14 | 15 | 16 | function! s:prefix_zero(num) 17 | if a:num < 10 18 | return '0'.a:num 19 | endif 20 | return a:num 21 | endfunction 22 | 23 | 24 | function! s:diary_path(...) 25 | let idx = a:0 == 0 ? vimwiki#vars#get_bufferlocal('wiki_nr') : a:1 26 | return vimwiki#vars#get_wikilocal('path', idx).vimwiki#vars#get_wikilocal('diary_rel_path', idx) 27 | endfunction 28 | 29 | 30 | function! s:diary_index(...) 31 | let idx = a:0 == 0 ? vimwiki#vars#get_bufferlocal('wiki_nr') : a:1 32 | return s:diary_path(idx).vimwiki#vars#get_wikilocal('diary_index', idx). 33 | \ vimwiki#vars#get_wikilocal('ext', idx) 34 | endfunction 35 | 36 | 37 | function! vimwiki#diary#diary_date_link(...) 38 | if a:0 39 | return strftime('%Y-%m-%d', a:1) 40 | else 41 | return strftime('%Y-%m-%d') 42 | endif 43 | endfunction 44 | 45 | 46 | function! s:get_position_links(link) 47 | let idx = -1 48 | let links = [] 49 | if a:link =~# '^\d\{4}-\d\d-\d\d' 50 | let links = map(s:get_diary_files(), 'fnamemodify(v:val, ":t:r")') 51 | " include 'today' into links 52 | if index(links, vimwiki#diary#diary_date_link()) == -1 53 | call add(links, vimwiki#diary#diary_date_link()) 54 | endif 55 | call sort(links) 56 | let idx = index(links, a:link) 57 | endif 58 | return [idx, links] 59 | endfunction 60 | 61 | 62 | function! s:get_month_name(month) 63 | return vimwiki#vars#get_global('diary_months')[str2nr(a:month)] 64 | endfunction 65 | 66 | 67 | function! s:read_captions(files) 68 | let result = {} 69 | let rx_header = vimwiki#vars#get_syntaxlocal('rxHeader') 70 | for fl in a:files 71 | " remove paths and extensions 72 | let fl_key = substitute(fnamemodify(fl, ':t'), vimwiki#vars#get_wikilocal('ext').'$', '', '') 73 | 74 | if filereadable(fl) 75 | for line in readfile(fl, '', s:vimwiki_max_scan_for_caption) 76 | if line =~# rx_header && !has_key(result, fl_key) 77 | let result[fl_key] = vimwiki#u#trim(matchstr(line, rx_header)) 78 | endif 79 | endfor 80 | endif 81 | 82 | if !has_key(result, fl_key) 83 | let result[fl_key] = '' 84 | endif 85 | 86 | endfor 87 | return result 88 | endfunction 89 | 90 | 91 | function! s:get_diary_files() 92 | let rx = '^\d\{4}-\d\d-\d\d' 93 | let s_files = glob(vimwiki#vars#get_wikilocal('path'). 94 | \ vimwiki#vars#get_wikilocal('diary_rel_path').'*'.vimwiki#vars#get_wikilocal('ext')) 95 | let files = split(s_files, '\n') 96 | call filter(files, 'fnamemodify(v:val, ":t") =~# "'.escape(rx, '\').'"') 97 | 98 | " remove backup files (.wiki~) 99 | call filter(files, 'v:val !~# ''.*\~$''') 100 | 101 | return files 102 | endfunction 103 | 104 | 105 | function! s:group_links(links) 106 | let result = {} 107 | let p_year = 0 108 | let p_month = 0 109 | for fl in sort(keys(a:links)) 110 | let year = strpart(fl, 0, 4) 111 | let month = strpart(fl, 5, 2) 112 | if p_year != year 113 | let result[year] = {} 114 | let p_month = 0 115 | endif 116 | if p_month != month 117 | let result[year][month] = {} 118 | endif 119 | let result[year][month][fl] = a:links[fl] 120 | let p_year = year 121 | let p_month = month 122 | endfor 123 | return result 124 | endfunction 125 | 126 | 127 | function! s:sort(lst) 128 | if vimwiki#vars#get_wikilocal('diary_sort') ==? 'desc' 129 | return reverse(sort(a:lst)) 130 | else 131 | return sort(a:lst) 132 | endif 133 | endfunction 134 | 135 | 136 | function! s:format_diary() 137 | let result = [] 138 | 139 | let links_with_captions = s:read_captions(s:get_diary_files()) 140 | let g_files = s:group_links(links_with_captions) 141 | 142 | for year in s:sort(keys(g_files)) 143 | call add(result, '') 144 | call add(result, 145 | \ substitute(vimwiki#vars#get_syntaxlocal('rxH2_Template'), '__Header__', year , '')) 146 | 147 | for month in s:sort(keys(g_files[year])) 148 | call add(result, '') 149 | call add(result, substitute(vimwiki#vars#get_syntaxlocal('rxH3_Template'), 150 | \ '__Header__', s:get_month_name(month), '')) 151 | 152 | for [fl, cap] in s:sort(items(g_files[year][month])) 153 | let link_tpl = vimwiki#vars#get_global('WikiLinkTemplate2') 154 | 155 | if vimwiki#vars#get_wikilocal('syntax') == 'markdown' 156 | let link_tpl = vimwiki#vars#get_syntaxlocal('Weblink1Template') 157 | 158 | if empty(cap) " When using markdown syntax, we should ensure we always have a link description. 159 | let cap = fl 160 | endif 161 | elseif empty(cap) 162 | let link_tpl = vimwiki#vars#get_global('WikiLinkTemplate1') 163 | endif 164 | 165 | let entry = substitute(link_tpl, '__LinkUrl__', fl, '') 166 | let entry = substitute(entry, '__LinkDescription__', cap, '') 167 | call add(result, repeat(' ', vimwiki#lst#get_list_margin()).'* '.entry) 168 | endfor 169 | 170 | endfor 171 | endfor 172 | 173 | return result 174 | endfunction 175 | 176 | 177 | " The given wiki number a:wnum is 1 for the first wiki, 2 for the second and so on. This is in 178 | " contrast to most other places, where counting starts with 0. When a:wnum is 0, the current wiki 179 | " is used. 180 | function! vimwiki#diary#make_note(wnum, ...) 181 | if a:wnum == 0 182 | let wiki_nr = vimwiki#vars#get_bufferlocal('wiki_nr') 183 | if wiki_nr < 0 " this happens when e.g. VimwikiMakeDiaryNote was called outside a wiki buffer 184 | let wiki_nr = 0 185 | endif 186 | else 187 | let wiki_nr = a:wnum - 1 188 | endif 189 | 190 | if wiki_nr >= vimwiki#vars#number_of_wikis() 191 | echomsg 'Vimwiki Error: Wiki '.wiki_nr.' is not registered in g:vimwiki_list!' 192 | return 193 | endif 194 | 195 | " TODO: refactor it. base#goto_index uses the same 196 | 197 | call vimwiki#path#mkdir(vimwiki#vars#get_wikilocal('path', wiki_nr). 198 | \ vimwiki#vars#get_wikilocal('diary_rel_path', wiki_nr)) 199 | 200 | let cmd = 'edit' 201 | if a:0 202 | if a:1 == 1 203 | let cmd = 'tabedit' 204 | elseif a:1 == 2 205 | let cmd = 'split' 206 | elseif a:1 == 3 207 | let cmd = 'vsplit' 208 | endif 209 | endif 210 | if a:0>1 211 | let link = 'diary:'.a:2 212 | else 213 | let link = 'diary:'.vimwiki#diary#diary_date_link() 214 | endif 215 | 216 | call vimwiki#base#open_link(cmd, link, s:diary_index(wiki_nr)) 217 | endfunction 218 | 219 | 220 | function! vimwiki#diary#goto_diary_index(wnum) 221 | if a:wnum > vimwiki#vars#number_of_wikis() 222 | echomsg 'Vimwiki Error: Wiki '.a:wnum.' is not registered in g:vimwiki_list!' 223 | return 224 | endif 225 | 226 | " TODO: refactor it. base#goto_index uses the same 227 | if a:wnum > 0 228 | let idx = a:wnum - 1 229 | else 230 | let idx = 0 231 | endif 232 | 233 | call vimwiki#base#edit_file('e', s:diary_index(idx), '') 234 | 235 | if vimwiki#vars#get_wikilocal('auto_diary_index') 236 | call vimwiki#diary#generate_diary_section() 237 | write! " save changes 238 | endif 239 | endfunction 240 | 241 | 242 | function! vimwiki#diary#goto_next_day() 243 | let link = '' 244 | let [idx, links] = s:get_position_links(expand('%:t:r')) 245 | 246 | if idx == (len(links) - 1) 247 | return 248 | endif 249 | 250 | if idx != -1 && idx < len(links) - 1 251 | let link = 'diary:'.links[idx+1] 252 | else 253 | " goto today 254 | let link = 'diary:'.vimwiki#diary#diary_date_link() 255 | endif 256 | 257 | if len(link) 258 | call vimwiki#base#open_link(':e ', link) 259 | endif 260 | endfunction 261 | 262 | 263 | function! vimwiki#diary#goto_prev_day() 264 | let link = '' 265 | let [idx, links] = s:get_position_links(expand('%:t:r')) 266 | 267 | if idx == 0 268 | return 269 | endif 270 | 271 | if idx > 0 272 | let link = 'diary:'.links[idx-1] 273 | else 274 | " goto today 275 | let link = 'diary:'.vimwiki#diary#diary_date_link() 276 | endif 277 | 278 | if len(link) 279 | call vimwiki#base#open_link(':e ', link) 280 | endif 281 | endfunction 282 | 283 | 284 | function! vimwiki#diary#generate_diary_section() 285 | let current_file = vimwiki#path#path_norm(expand("%:p")) 286 | let diary_file = vimwiki#path#path_norm(s:diary_index()) 287 | if vimwiki#path#is_equal(current_file, diary_file) 288 | let content_rx = '^\%(\s*\* \)\|\%(^\s*$\)\|\%('.vimwiki#vars#get_syntaxlocal('rxHeader').'\)' 289 | call vimwiki#base#update_listing_in_buffer(s:format_diary(), 290 | \ vimwiki#vars#get_wikilocal('diary_header'), content_rx, line('$')+1, 1) 291 | else 292 | echomsg 'Vimwiki Error: You can generate diary links only in a diary index page!' 293 | endif 294 | endfunction 295 | 296 | 297 | " Callback function for Calendar.vim 298 | function! vimwiki#diary#calendar_action(day, month, year, week, dir) 299 | let day = s:prefix_zero(a:day) 300 | let month = s:prefix_zero(a:month) 301 | 302 | let link = a:year.'-'.month.'-'.day 303 | if winnr('#') == 0 304 | if a:dir ==? 'V' 305 | vsplit 306 | else 307 | split 308 | endif 309 | else 310 | wincmd p 311 | if !&hidden && &modified 312 | new 313 | endif 314 | endif 315 | 316 | call vimwiki#diary#make_note(0, 0, link) 317 | endfunction 318 | 319 | 320 | function vimwiki#diary#calendar_sign(day, month, year) 321 | let day = s:prefix_zero(a:day) 322 | let month = s:prefix_zero(a:month) 323 | let sfile = vimwiki#vars#get_wikilocal('path').vimwiki#vars#get_wikilocal('diary_rel_path'). 324 | \ a:year.'-'.month.'-'.day.vimwiki#vars#get_wikilocal('ext') 325 | return filereadable(expand(sfile)) 326 | endfunction 327 | 328 | -------------------------------------------------------------------------------- /autoload/vimwiki/markdown_base.vim: -------------------------------------------------------------------------------- 1 | " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 2 | " Vimwiki autoload plugin file 3 | " Description: Link functions for markdown syntax 4 | " Home: https://github.com/vimwiki/vimwiki/ 5 | 6 | 7 | function! s:safesubstitute(text, search, replace, mode) 8 | " Substitute regexp but do not interpret replace 9 | let escaped = escape(a:replace, '\&') 10 | return substitute(a:text, a:search, escaped, a:mode) 11 | endfunction 12 | 13 | 14 | function! vimwiki#markdown_base#scan_reflinks() 15 | let mkd_refs = {} 16 | " construct list of references using vimgrep 17 | try 18 | " Why noautocmd? Because https://github.com/vimwiki/vimwiki/issues/121 19 | noautocmd execute 'vimgrep #'.vimwiki#vars#get_syntaxlocal('rxMkdRef').'#j %' 20 | catch /^Vim\%((\a\+)\)\=:E480/ " No Match 21 | "Ignore it, and move on to the next file 22 | endtry 23 | 24 | for d in getqflist() 25 | let matchline = join(getline(d.lnum, min([d.lnum+1, line('$')])), ' ') 26 | let descr = matchstr(matchline, vimwiki#vars#get_syntaxlocal('rxMkdRefMatchDescr')) 27 | let url = matchstr(matchline, vimwiki#vars#get_syntaxlocal('rxMkdRefMatchUrl')) 28 | if descr != '' && url != '' 29 | let mkd_refs[descr] = url 30 | endif 31 | endfor 32 | call vimwiki#vars#set_bufferlocal('markdown_refs', mkd_refs) 33 | return mkd_refs 34 | endfunction 35 | 36 | 37 | " try markdown reference links 38 | function! vimwiki#markdown_base#open_reflink(link) 39 | " echom "vimwiki#markdown_base#open_reflink" 40 | let link = a:link 41 | let mkd_refs = vimwiki#vars#get_bufferlocal('markdown_refs') 42 | if has_key(mkd_refs, link) 43 | let url = mkd_refs[link] 44 | call vimwiki#base#system_open_link(url) 45 | return 1 46 | else 47 | return 0 48 | endif 49 | endfunction 50 | 51 | 52 | function! s:normalize_link_syntax_n() 53 | let lnum = line('.') 54 | 55 | " try WikiIncl 56 | let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWikiIncl')) 57 | if !empty(lnk) 58 | " NO-OP !! 59 | return 60 | endif 61 | 62 | " try WikiLink0: replace with WikiLink1 63 | let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink0')) 64 | if !empty(lnk) 65 | let sub = vimwiki#base#normalize_link_helper(lnk, 66 | \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'), 67 | \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr'), 68 | \ vimwiki#vars#get_syntaxlocal('WikiLink1Template2')) 69 | call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink0'), sub) 70 | return 71 | endif 72 | 73 | " try WikiLink1: replace with WikiLink0 74 | let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink1')) 75 | if !empty(lnk) 76 | let sub = vimwiki#base#normalize_link_helper(lnk, 77 | \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchUrl'), 78 | \ vimwiki#vars#get_syntaxlocal('rxWikiLinkMatchDescr'), 79 | \ vimwiki#vars#get_global('WikiLinkTemplate2')) 80 | call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWikiLink1'), sub) 81 | return 82 | endif 83 | 84 | " try Weblink 85 | let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink')) 86 | if !empty(lnk) 87 | let sub = vimwiki#base#normalize_link_helper(lnk, 88 | \ vimwiki#vars#get_syntaxlocal('rxWeblinkMatchUrl'), 89 | \ vimwiki#vars#get_syntaxlocal('rxWeblinkMatchDescr'), 90 | \ vimwiki#vars#get_syntaxlocal('Weblink1Template')) 91 | call vimwiki#base#replacestr_at_cursor(vimwiki#vars#get_syntaxlocal('rxWeblink'), sub) 92 | return 93 | endif 94 | 95 | " try Word (any characters except separators) 96 | " rxWord is less permissive than rxWikiLinkUrl which is used in 97 | " normalize_link_syntax_v 98 | let lnk = vimwiki#base#matchstr_at_cursor(vimwiki#vars#get_global('rxWord')) 99 | if !empty(lnk) 100 | let sub = vimwiki#base#normalize_link_helper(lnk, 101 | \ vimwiki#vars#get_global('rxWord'), '', 102 | \ vimwiki#vars#get_syntaxlocal('Weblink1Template')) 103 | call vimwiki#base#replacestr_at_cursor('\V'.lnk, sub) 104 | return 105 | endif 106 | 107 | endfunction 108 | 109 | 110 | function! s:normalize_link_syntax_v() 111 | let lnum = line('.') 112 | let sel_save = &selection 113 | let &selection = "old" 114 | let rv = @" 115 | let rt = getregtype('"') 116 | let done = 0 117 | 118 | try 119 | norm! gvy 120 | let visual_selection = @" 121 | let link = s:safesubstitute(vimwiki#vars#get_syntaxlocal('Weblink1Template'), 122 | \ '__LinkUrl__', visual_selection, '') 123 | let link = s:safesubstitute(link, '__LinkDescription__', visual_selection, '') 124 | 125 | call setreg('"', substitute(link, '\n', '', ''), visualmode()) 126 | 127 | " paste result 128 | norm! `>""pgvd 129 | 130 | finally 131 | call setreg('"', rv, rt) 132 | let &selection = sel_save 133 | endtry 134 | 135 | endfunction 136 | 137 | 138 | function! vimwiki#markdown_base#normalize_link(is_visual_mode) 139 | if 0 140 | " Syntax-specific links 141 | else 142 | if !a:is_visual_mode 143 | call s:normalize_link_syntax_n() 144 | elseif line("'<") == line("'>") 145 | " action undefined for multi-line visual mode selections 146 | call s:normalize_link_syntax_v() 147 | endif 148 | endif 149 | endfunction 150 | 151 | -------------------------------------------------------------------------------- /autoload/vimwiki/path.vim: -------------------------------------------------------------------------------- 1 | " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 2 | " Vimwiki autoload plugin file 3 | " Description: Path manipulation functions 4 | " Home: https://github.com/vimwiki/vimwiki/ 5 | 6 | 7 | function! vimwiki#path#chomp_slash(str) 8 | return substitute(a:str, '[/\\]\+$', '', '') 9 | endfunction 10 | 11 | 12 | " Define path-compare function, either case-sensitive or not, depending on OS. 13 | if vimwiki#u#is_windows() 14 | function! vimwiki#path#is_equal(p1, p2) 15 | return a:p1 ==? a:p2 16 | endfunction 17 | else 18 | function! vimwiki#path#is_equal(p1, p2) 19 | return a:p1 ==# a:p2 20 | endfunction 21 | endif 22 | 23 | 24 | " collapse sections like /a/b/../c to /a/c 25 | function! vimwiki#path#normalize(path) 26 | let path = a:path 27 | while 1 28 | let result = substitute(path, '/[^/]\+/\.\.', '', '') 29 | if result ==# path 30 | break 31 | endif 32 | let path = result 33 | endwhile 34 | return result 35 | endfunction 36 | 37 | 38 | function! vimwiki#path#path_norm(path) 39 | " /-slashes 40 | if a:path !~# '^scp:' 41 | let path = substitute(a:path, '\', '/', 'g') 42 | " treat multiple consecutive slashes as one path separator 43 | let path = substitute(path, '/\+', '/', 'g') 44 | " ensure that we are not fooled by a symbolic link 45 | return resolve(path) 46 | else 47 | return a:path 48 | endif 49 | endfunction 50 | 51 | 52 | function! vimwiki#path#is_link_to_dir(link) 53 | " Check if link is to a directory. 54 | " It should be ended with \ or /. 55 | return a:link =~# '\m[/\\]$' 56 | endfunction 57 | 58 | 59 | function! vimwiki#path#abs_path_of_link(link) 60 | return vimwiki#path#normalize(expand("%:p:h").'/'.a:link) 61 | endfunction 62 | 63 | 64 | " return longest common path prefix of 2 given paths. 65 | " '~/home/usrname/wiki', '~/home/usrname/wiki/shmiki' => '~/home/usrname/wiki' 66 | function! vimwiki#path#path_common_pfx(path1, path2) 67 | let p1 = split(a:path1, '[/\\]', 1) 68 | let p2 = split(a:path2, '[/\\]', 1) 69 | 70 | let idx = 0 71 | let minlen = min([len(p1), len(p2)]) 72 | while (idx < minlen) && vimwiki#path#is_equal(p1[idx], p2[idx]) 73 | let idx = idx + 1 74 | endwhile 75 | if idx == 0 76 | return '' 77 | else 78 | return join(p1[: idx-1], '/') 79 | endif 80 | endfunction 81 | 82 | 83 | function! vimwiki#path#wikify_path(path) 84 | let result = resolve(fnamemodify(a:path, ':p')) 85 | if vimwiki#u#is_windows() 86 | let result = substitute(result, '\\', '/', 'g') 87 | endif 88 | let result = vimwiki#path#chomp_slash(result) 89 | return result 90 | endfunction 91 | 92 | 93 | function! vimwiki#path#current_wiki_file() 94 | return vimwiki#path#wikify_path(expand('%:p')) 95 | endfunction 96 | 97 | 98 | " Returns: the relative path from a:dir to a:file 99 | function! vimwiki#path#relpath(dir, file) 100 | let result = [] 101 | let dir = split(a:dir, '/') 102 | let file = split(a:file, '/') 103 | while (len(dir) > 0 && len(file) > 0) && vimwiki#path#is_equal(dir[0], file[0]) 104 | call remove(dir, 0) 105 | call remove(file, 0) 106 | endwhile 107 | if empty(dir) && empty(file) 108 | return './' 109 | endif 110 | for segment in dir 111 | let result += ['..'] 112 | endfor 113 | for segment in file 114 | let result += [segment] 115 | endfor 116 | let result_path = join(result, '/') 117 | if a:file =~ '\m/$' 118 | let result_path .= '/' 119 | endif 120 | return result_path 121 | endfunction 122 | 123 | 124 | " If the optional argument provided and nonzero, 125 | " it will ask before creating a directory 126 | " Returns: 1 iff directory exists or successfully created 127 | function! vimwiki#path#mkdir(path, ...) 128 | let path = expand(a:path) 129 | 130 | if path =~# '^scp:' 131 | " we can not do much, so let's pretend everything is ok 132 | return 1 133 | endif 134 | 135 | if isdirectory(path) 136 | return 1 137 | else 138 | if !exists("*mkdir") 139 | return 0 140 | endif 141 | 142 | let path = vimwiki#path#chomp_slash(path) 143 | if vimwiki#u#is_windows() && !empty(vimwiki#vars#get_global('w32_dir_enc')) 144 | let path = iconv(path, &enc, vimwiki#vars#get_global('w32_dir_enc')) 145 | endif 146 | 147 | if a:0 && a:1 && input("Vimwiki: Make new directory: ".path."\n [y]es/[N]o? ") !~? '^y' 148 | return 0 149 | endif 150 | 151 | call mkdir(path, "p") 152 | return 1 153 | endif 154 | endfunction 155 | 156 | 157 | function! vimwiki#path#is_absolute(path) 158 | if vimwiki#u#is_windows() 159 | return a:path =~? '\m^\a:' 160 | else 161 | return a:path =~# '\m^/\|\~/' 162 | endif 163 | endfunction 164 | 165 | 166 | " Combine a directory and a file into one path, doesn't generate duplicate 167 | " path separator in case the directory is also having an ending / or \. This 168 | " is because on windows ~\vimwiki//.tags is invalid but ~\vimwiki/.tags is a 169 | " valid path. 170 | if vimwiki#u#is_windows() 171 | function! vimwiki#path#join_path(directory, file) 172 | let directory = vimwiki#path#chomp_slash(a:directory) 173 | let file = substitute(a:file, '\m^[\\/]\+', '', '') 174 | return directory . '/' . file 175 | endfunction 176 | else 177 | function! vimwiki#path#join_path(directory, file) 178 | let directory = substitute(a:directory, '\m/\+$', '', '') 179 | let file = substitute(a:file, '\m^/\+', '', '') 180 | return directory . '/' . file 181 | endfunction 182 | endif 183 | 184 | -------------------------------------------------------------------------------- /autoload/vimwiki/style.css: -------------------------------------------------------------------------------- 1 | body {font-family: Tahoma, Geneva, sans-serif; margin: 1em 2em 1em 2em; font-size: 100%; line-height: 130%;} 2 | h1, h2, h3, h4, h5, h6 {font-family: Trebuchet MS, Helvetica, sans-serif; font-weight: bold; line-height:100%; margin-top: 1.5em; margin-bottom: 0.5em;} 3 | h1 {font-size: 2.6em; color: #000000;} 4 | h2 {font-size: 2.2em; color: #404040;} 5 | h3 {font-size: 1.8em; color: #707070;} 6 | h4 {font-size: 1.4em; color: #909090;} 7 | h5 {font-size: 1.3em; color: #989898;} 8 | h6 {font-size: 1.2em; color: #9c9c9c;} 9 | p, pre, blockquote, table, ul, ol, dl {margin-top: 1em; margin-bottom: 1em;} 10 | ul ul, ul ol, ol ol, ol ul {margin-top: 0.5em; margin-bottom: 0.5em;} 11 | li {margin: 0.3em auto;} 12 | ul {margin-left: 2em; padding-left: 0.5em;} 13 | dt {font-weight: bold;} 14 | img {border: none;} 15 | pre {border-left: 1px solid #ccc; margin-left: 2em; padding-left: 0.5em;} 16 | blockquote {padding: 0.4em; background-color: #f6f5eb;} 17 | th, td {border: 1px solid #ccc; padding: 0.3em;} 18 | th {background-color: #f0f0f0;} 19 | hr {border: none; border-top: 1px solid #ccc; width: 100%;} 20 | del {text-decoration: line-through; color: #777777;} 21 | .toc li {list-style-type: none;} 22 | .todo {font-weight: bold; background-color: #f0ece8; color: #a03020;} 23 | .justleft {text-align: left;} 24 | .justright {text-align: right;} 25 | .justcenter {text-align: center;} 26 | .center {margin-left: auto; margin-right: auto;} 27 | .tag {background-color: #eeeeee; font-family: monospace; padding: 2px;} 28 | .header a {text-decoration: none; color: inherit;} 29 | 30 | /* classes for items of todo lists */ 31 | .rejected { 32 | /* list-style: none; */ 33 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAMAAAAMCGV4AAAACXBIWXMAAADFAAAAxQEdzbqoAAAAB3RJTUUH4QgEFhAtuWgv9wAAAPZQTFRFmpqam5iYnJaWnJeXnpSUn5OTopCQpoqKpouLp4iIqIiIrYCAt3V1vW1tv2xsmZmZmpeXnpKS/x4e/x8f/yAg/yIi/yQk/yUl/yYm/ygo/ykp/yws/zAw/zIy/zMz/zQ0/zU1/zY2/zw8/0BA/0ZG/0pK/1FR/1JS/1NT/1RU/1VV/1ZW/1dX/1pa/15e/19f/2Zm/2lp/21t/25u/3R0/3p6/4CA/4GB/4SE/4iI/46O/4+P/52d/6am/6ur/66u/7Oz/7S0/7e3/87O/9fX/9zc/93d/+Dg/+vr/+3t/+/v//Dw//Ly//X1//f3//n5//z8////gzaKowAAAA90Uk5T/Pz8/Pz8/Pz8/Pz8/f39ppQKWQAAAAFiS0dEEnu8bAAAAACuSURBVAhbPY9ZF4FQFEZPSKbIMmWep4gMGTKLkIv6/3/GPbfF97b3w17rA0kQOPgvAeHW6uJ6+5h7HqLdwowgOzejXRXBdx6UdSru216xuOMBHHNU0clTzeSUA6EhF8V8kqroluMiU6HKcuf4phGPr1o2q9kYZWwNq1qfRRmTaXpqsyjj17KkWCxKBUBgXWueHIyiAIg18gsse4KHkLF5IKIY10WQgv7fOy4ST34BRiopZ8WLNrgAAAAASUVORK5CYII=); 34 | background-repeat: no-repeat; 35 | background-position: 0 .2em; 36 | padding-left: 1.5em; 37 | } 38 | .done0 { 39 | /* list-style: none; */ 40 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAA7SURBVCiR7dMxEgAgCANBI3yVRzF5KxNbW6wsuH7LQ2YKQK1mkswBVERYF5Os3UV3gwd/jF2SkXy66gAZkxS6BniubAAAAABJRU5ErkJggg==); 41 | background-repeat: no-repeat; 42 | background-position: 0 .2em; 43 | padding-left: 1.5em; 44 | } 45 | .done1 { 46 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABtSURBVCiR1ZO7DYAwDER9BDmTeZQMFXmUbGYpOjrEryA0wOvO8itOslFrJYAug5BMM4BeSkmjsrv3aVTa8p48Xw1JSkSsWVUFwD05IqS1tmYzk5zzae9jnVVVzGyXb8sALjse+euRkEzu/uirFomVIdDGOLjuAAAAAElFTkSuQmCC); 47 | background-repeat: no-repeat; 48 | background-position: 0 .15em; 49 | padding-left: 1.5em; 50 | } 51 | .done2 { 52 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAB1SURBVCiRzdO5DcAgDAVQGxjAYgTvxlDIu1FTIRYAp8qlFISkSH7l5kk+ZIwxKiI2mIyqWoeILYRgZ7GINDOLjnmF3VqklKCUMgTee2DmM661Qs55iI3Zm/1u5h9sm4ig9z4ERHTFzLyd4G4+nFlVrYg8+qoF/c0kdpeMsmcAAAAASUVORK5CYII=); 53 | background-repeat: no-repeat; 54 | background-position: 0 .15em; 55 | padding-left: 1.5em; 56 | } 57 | .done3 { 58 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAxQAAAMUBHc26qAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAABoSURBVCiR7dOxDcAgDATA/0DtUdiKoZC3YhLkHjkVKF3idJHiztKfvrHZWnOSE8Fx95RJzlprimJVnXktvXeY2S0SEZRSAAAbmxnGGKH2I5T+8VfxPhIReQSuuY3XyYWa3T2p6quvOgGrvSFGlewuUAAAAABJRU5ErkJggg==); 59 | background-repeat: no-repeat; 60 | background-position: 0 .15em; 61 | padding-left: 1.5em; 62 | } 63 | .done4 { 64 | background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAQCAYAAAAbBi9cAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAzgAAAM4BlP6ToAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAIISURBVDiNnZQ9SFtRFMd/773kpTaGJoQk1im4VDpWQcTNODhkFBcVTCNCF0NWyeDiIIiCm82QoIMIUkHUxcFBg1SEQoZszSat6cdTn1qNue92CMbEr9Sey+XC/Z/zu+f8h6ukUil3sVg0+M+4cFxk42/jH2wAqqqKSCSiPQdwcHHAnDHH9s/tN1h8V28ETdP+eU8fT9Nt62ancYdIPvJNtsu87bmjrJlrTDVM4RROJs1JrHPrD4Bar7A6cpc54iKOaTdJXCUI2UMVrQZ0Js7YPN18ECKkYNQcJe/OE/4dZsw7VqNXQMvHy3QZXQypQ6ycrtwDjf8aJ+PNEDSCzLpn7+m2pD8ZKHlKarYhy6XjEoCYGcN95qansQeA3fNdki+SaJZGTMQIOoL3W/Z89rxv+tokubNajlvk/vm+LFpF2XnUKZHI0I+QrI7Dw0OZTqdzUkpsM7mZTyfy5OPGyw1tK7AFSvmB/Ks8w8YwbUYbe6/3QEKv0vugfxWPnMLJun+d/kI/WLdizpNjMbAIKrhMF4OuwadBALqqs+RfInwUvuNi+fBd+wjogfogAFVRmffO02q01mZZ0HHdgXIzdz0QQLPezIQygX6llxNKKgOFARYCC49CqhoHIUTlss/Vx2phlYwjw8j1CAlfAiwQiJpiy7o1VHnsG5FISkoJu7Q/2YmmaV+i0ei7v38L2CBguSi5AAAAAElFTkSuQmCC); 65 | background-repeat: no-repeat; 66 | background-position: 0 .15em; 67 | padding-left: 1.5em; 68 | } 69 | 70 | code { 71 | font-family: Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace; 72 | -webkit-border-radius: 1px; 73 | -moz-border-radius: 1px; 74 | border-radius: 1px; 75 | -moz-background-clip: padding; 76 | -webkit-background-clip: padding-box; 77 | background-clip: padding-box; 78 | padding: 0px 3px; 79 | display: inline-block; 80 | color: #52595d; 81 | border: 1px solid #ccc; 82 | background-color: #f9f9f9; 83 | } 84 | -------------------------------------------------------------------------------- /autoload/vimwiki/tags.vim: -------------------------------------------------------------------------------- 1 | " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 2 | " Vimwiki autoload plugin file 3 | 4 | 5 | let s:TAGS_METADATA_FILE_NAME = '.tags' 6 | 7 | 8 | 9 | " Tags metadata in-memory format: 10 | " metadata := { 'pagename': [entries, ...] } 11 | " entry := { 'tagname':..., 'lineno':..., 'link':... } 12 | 13 | " Tags metadata in-file format: 14 | " 15 | " Is based on CTags format (see |tags-file-format|). 16 | " 17 | " {tagaddress} is set to lineno. We'll let vim search by exact line number; we 18 | " can afford that, we assume metadata file is always updated before use. 19 | " 20 | " Pagename and link are not saved in standard ctags fields, so we'll add 21 | " an optional field, "vimwiki:". In this field, we encode tab-separated values 22 | " of missing parameters -- "pagename" and "link". 23 | 24 | 25 | 26 | " Update tags metadata. 27 | " a:full_rebuild == 1: re-scan entire wiki 28 | " a:full_rebuild == 0: only re-scan current page 29 | " a:all_files == '': only if the file is newer than .tags 30 | function! vimwiki#tags#update_tags(full_rebuild, all_files) 31 | let all_files = a:all_files != '' 32 | if !a:full_rebuild 33 | " Updating for one page (current) 34 | let page_name = vimwiki#vars#get_bufferlocal('subdir') . expand('%:t:r') 35 | " Collect tags in current file 36 | let tags = s:scan_tags(getline(1, '$'), page_name) 37 | " Load metadata file 38 | let metadata = s:load_tags_metadata() 39 | " Drop old tags 40 | let metadata = s:remove_page_from_tags(metadata, page_name) 41 | " Merge in the new ones 42 | let metadata = s:merge_tags(metadata, page_name, tags) 43 | " Save 44 | call s:write_tags_metadata(metadata) 45 | else " full rebuild 46 | let files = vimwiki#base#find_files(vimwiki#vars#get_bufferlocal('wiki_nr'), 0) 47 | let wiki_base_dir = vimwiki#vars#get_wikilocal('path') 48 | let tags_file_last_modification = getftime(vimwiki#tags#metadata_file_path()) 49 | let metadata = s:load_tags_metadata() 50 | for file in files 51 | if all_files || getftime(file) >= tags_file_last_modification 52 | let subdir = vimwiki#base#subdir(wiki_base_dir, file) 53 | let page_name = subdir . fnamemodify(file, ':t:r') 54 | let tags = s:scan_tags(readfile(file), page_name) 55 | let metadata = s:remove_page_from_tags(metadata, page_name) 56 | let metadata = s:merge_tags(metadata, page_name, tags) 57 | endif 58 | endfor 59 | call s:write_tags_metadata(metadata) 60 | endif 61 | endfunction 62 | 63 | 64 | " Scans the list of text lines (argument) and produces tags metadata as a list of tag entries. 65 | function! s:scan_tags(lines, page_name) 66 | 67 | let entries = [] 68 | 69 | " Code wireframe to scan for headers -- borrowed from 70 | " vimwiki#base#get_anchors(), with minor modifications. 71 | 72 | let rxheader = vimwiki#vars#get_syntaxlocal('header_search') 73 | let rxtag = vimwiki#vars#get_syntaxlocal('tag_search') 74 | 75 | let anchor_level = ['', '', '', '', '', '', ''] 76 | let current_complete_anchor = '' 77 | 78 | let PROXIMITY_LINES_NR = 2 79 | let header_line_nr = - (2 * PROXIMITY_LINES_NR) 80 | 81 | for line_nr in range(1, len(a:lines)) 82 | let line = a:lines[line_nr - 1] 83 | 84 | " process headers 85 | let h_match = matchlist(line, rxheader) 86 | if !empty(h_match) " got a header 87 | let header_line_nr = line_nr 88 | let header = vimwiki#u#trim(h_match[2]) 89 | let level = len(h_match[1]) 90 | let anchor_level[level-1] = header 91 | for l in range(level, 6) 92 | let anchor_level[l] = '' 93 | endfor 94 | if level == 1 95 | let current_complete_anchor = header 96 | else 97 | let current_complete_anchor = '' 98 | for l in range(level-1) 99 | if anchor_level[l] != '' 100 | let current_complete_anchor .= anchor_level[l].'#' 101 | endif 102 | endfor 103 | let current_complete_anchor .= header 104 | endif 105 | continue " tags are not allowed in headers 106 | endif 107 | 108 | " TODO ignore verbatim blocks 109 | 110 | " Scan line for tags. There can be many of them. 111 | let str = line 112 | while 1 113 | let tag_group = matchstr(str, rxtag) 114 | if tag_group == '' 115 | break 116 | endif 117 | let tagend = matchend(str, rxtag) 118 | let str = str[(tagend):] 119 | for tag in split(tag_group, ':') 120 | " Create metadata entry 121 | let entry = {} 122 | let entry.tagname = tag 123 | let entry.lineno = line_nr 124 | if line_nr <= PROXIMITY_LINES_NR && header_line_nr < 0 125 | " Tag appeared at the top of the file 126 | let entry.link = a:page_name 127 | elseif line_nr <= (header_line_nr + PROXIMITY_LINES_NR) 128 | " Tag appeared right below a header 129 | let entry.link = a:page_name . '#' . current_complete_anchor 130 | else 131 | " Tag stands on its own 132 | let entry.link = a:page_name . '#' . tag 133 | endif 134 | call add(entries, entry) 135 | endfor 136 | endwhile 137 | 138 | endfor " loop over lines 139 | return entries 140 | endfunction 141 | 142 | 143 | " Returns tags metadata file path 144 | function! vimwiki#tags#metadata_file_path() abort 145 | return fnamemodify(vimwiki#path#join_path(vimwiki#vars#get_wikilocal('path'), 146 | \ s:TAGS_METADATA_FILE_NAME), ':p') 147 | endfunction 148 | 149 | 150 | " Loads tags metadata from file, returns a dictionary 151 | function! s:load_tags_metadata() abort 152 | let metadata_path = vimwiki#tags#metadata_file_path() 153 | if !filereadable(metadata_path) 154 | return {} 155 | endif 156 | let metadata = {} 157 | for line in readfile(metadata_path) 158 | if line =~ '^!_TAG_FILE_' 159 | continue 160 | endif 161 | let parts = matchlist(line, '^\(.\{-}\);"\(.*\)$') 162 | if parts[0] == '' || parts[1] == '' || parts[2] == '' 163 | throw 'VimwikiTags1: Metadata file corrupted' 164 | endif 165 | let std_fields = split(parts[1], '\t') 166 | if len(std_fields) != 3 167 | throw 'VimwikiTags2: Metadata file corrupted' 168 | endif 169 | let vw_part = parts[2] 170 | if vw_part[0] != "\t" 171 | throw 'VimwikiTags3: Metadata file corrupted' 172 | endif 173 | let vw_fields = split(vw_part[1:], "\t") 174 | if len(vw_fields) != 1 || vw_fields[0] !~ '^vimwiki:' 175 | throw 'VimwikiTags4: Metadata file corrupted' 176 | endif 177 | let vw_data = substitute(vw_fields[0], '^vimwiki:', '', '') 178 | let vw_data = substitute(vw_data, '\\n', "\n", 'g') 179 | let vw_data = substitute(vw_data, '\\r', "\r", 'g') 180 | let vw_data = substitute(vw_data, '\\t', "\t", 'g') 181 | let vw_data = substitute(vw_data, '\\\\', "\\", 'g') 182 | let vw_fields = split(vw_data, "\t") 183 | if len(vw_fields) != 2 184 | throw 'VimwikiTags5: Metadata file corrupted' 185 | endif 186 | let pagename = vw_fields[0] 187 | let entry = {} 188 | let entry.tagname = std_fields[0] 189 | let entry.lineno = std_fields[2] 190 | let entry.link = vw_fields[1] 191 | if has_key(metadata, pagename) 192 | call add(metadata[pagename], entry) 193 | else 194 | let metadata[pagename] = [entry] 195 | endif 196 | endfor 197 | return metadata 198 | endfunction 199 | 200 | 201 | " Removes all entries for given page from metadata in-place. Returns updated 202 | " metadata (just in case). 203 | function! s:remove_page_from_tags(metadata, page_name) 204 | if has_key(a:metadata, a:page_name) 205 | call remove(a:metadata, a:page_name) 206 | return a:metadata 207 | else 208 | return a:metadata 209 | endif 210 | endfunction 211 | 212 | 213 | " Merges metadata of one file into a:metadata 214 | function! s:merge_tags(metadata, pagename, file_metadata) 215 | let metadata = a:metadata 216 | let metadata[a:pagename] = a:file_metadata 217 | return metadata 218 | endfunction 219 | 220 | 221 | " Compares two actual lines from tags file. Return value is in strcmp style. 222 | " See help on sort() -- that's what this function is going to be used for. 223 | " See also s:write_tags_metadata below -- that's where we compose these tags 224 | " file lines. 225 | " 226 | " This function is needed for tags sorting, since plain sort() compares line 227 | " numbers as strings, not integers, and so, for example, tag at line 14 228 | " preceeds the same tag on the same page at line 9. (Because string "14" is 229 | " alphabetically 'less than' string "9".) 230 | function! s:tags_entry_cmp(i1, i2) 231 | let items = [] 232 | for orig_item in [a:i1, a:i2] 233 | let fields = split(orig_item, "\t") 234 | let item = {} 235 | let item.text = fields[0]."\t".fields[1] 236 | let item.lineno = 0 + matchstr(fields[2], '\m\d\+') 237 | call add(items, item) 238 | endfor 239 | if items[0].text ># items[1].text 240 | return 1 241 | elseif items[0].text <# items[1].text 242 | return -1 243 | elseif items[0].lineno > items[1].lineno 244 | return 1 245 | elseif items[0].lineno < items[1].lineno 246 | return -1 247 | else 248 | return 0 249 | endif 250 | endfunction 251 | 252 | 253 | " Saves metadata object into a file. Throws exceptions in case of problems. 254 | function! s:write_tags_metadata(metadata) 255 | let metadata_path = vimwiki#tags#metadata_file_path() 256 | let tags = [] 257 | for pagename in keys(a:metadata) 258 | for entry in a:metadata[pagename] 259 | let entry_data = pagename . "\t" . entry.link 260 | let entry_data = substitute(entry_data, "\\", '\\\\', 'g') 261 | let entry_data = substitute(entry_data, "\t", '\\t', 'g') 262 | let entry_data = substitute(entry_data, "\r", '\\r', 'g') 263 | let entry_data = substitute(entry_data, "\n", '\\n', 'g') 264 | call add(tags, 265 | \ entry.tagname . "\t" 266 | \ . pagename . vimwiki#vars#get_wikilocal('ext') . "\t" 267 | \ . entry.lineno 268 | \ . ';"' 269 | \ . "\t" . "vimwiki:" . entry_data 270 | \) 271 | endfor 272 | endfor 273 | call sort(tags, "s:tags_entry_cmp") 274 | call insert(tags, "!_TAG_FILE_SORTED\t1\t") 275 | call writefile(tags, metadata_path) 276 | endfunction 277 | 278 | 279 | " Returns list of unique tags found in the .tags file 280 | function! vimwiki#tags#get_tags() 281 | let metadata = s:load_tags_metadata() 282 | let tags = {} 283 | for entries in values(metadata) 284 | for entry in entries 285 | let tags[entry.tagname] = 1 286 | endfor 287 | endfor 288 | return keys(tags) 289 | endfunction 290 | 291 | 292 | " Similar to vimwiki#base#generate_links. In the current buffer, appends 293 | " tags and references to all their instances. If no arguments (tags) are 294 | " specified, outputs all tags. 295 | function! vimwiki#tags#generate_tags(...) abort 296 | let need_all_tags = (a:0 == 0) 297 | let specific_tags = a:000 298 | 299 | let metadata = s:load_tags_metadata() 300 | 301 | " make a dictionary { tag_name: [tag_links, ...] } 302 | let tags_entries = {} 303 | for entries in values(metadata) 304 | for entry in entries 305 | if has_key(tags_entries, entry.tagname) 306 | call add(tags_entries[entry.tagname], entry.link) 307 | else 308 | let tags_entries[entry.tagname] = [entry.link] 309 | endif 310 | endfor 311 | endfor 312 | 313 | let lines = [] 314 | let bullet = repeat(' ', vimwiki#lst#get_list_margin()).vimwiki#lst#default_symbol().' ' 315 | for tagname in sort(keys(tags_entries)) 316 | if need_all_tags || index(specific_tags, tagname) != -1 317 | call extend(lines, [ 318 | \ '', 319 | \ substitute(vimwiki#vars#get_syntaxlocal('rxH2_Template'), '__Header__', tagname, ''), 320 | \ '' ]) 321 | for taglink in sort(tags_entries[tagname]) 322 | call add(lines, bullet . substitute(vimwiki#vars#get_global('WikiLinkTemplate1'), 323 | \ '__LinkUrl__', taglink, '')) 324 | endfor 325 | endif 326 | endfor 327 | 328 | let links_rx = '\m\%(^\s*$\)\|\%('.vimwiki#vars#get_syntaxlocal('rxH2').'\)\|\%(^\s*' 329 | \ .vimwiki#u#escape(vimwiki#lst#default_symbol()).' ' 330 | \ .vimwiki#vars#get_syntaxlocal('rxWikiLink').'$\)' 331 | 332 | call vimwiki#base#update_listing_in_buffer(lines, 'Generated Tags', links_rx, line('$')+1, 1) 333 | endfunction 334 | 335 | 336 | function! vimwiki#tags#complete_tags(ArgLead, CmdLine, CursorPos) abort 337 | " We can safely ignore args if we use -custom=complete option, Vim engine 338 | " will do the job of filtering. 339 | let taglist = vimwiki#tags#get_tags() 340 | return join(taglist, "\n") 341 | endfunction 342 | 343 | -------------------------------------------------------------------------------- /autoload/vimwiki/tbl.vim: -------------------------------------------------------------------------------- 1 | " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 2 | " Vimwiki autoload plugin file 3 | " Description: Tables 4 | " | Easily | manageable | text | tables | ! | 5 | " |--------|------------|-------|--------|---------| 6 | " | Have | fun! | Drink | tea | Period. | 7 | " 8 | " Home: https://github.com/vimwiki/vimwiki/ 9 | 10 | 11 | 12 | if exists("g:loaded_vimwiki_tbl_auto") || &cp 13 | finish 14 | endif 15 | let g:loaded_vimwiki_tbl_auto = 1 16 | 17 | 18 | let s:textwidth = &tw 19 | 20 | 21 | function! s:rxSep() 22 | return vimwiki#vars#get_syntaxlocal('rxTableSep') 23 | endfunction 24 | 25 | 26 | function! s:wide_len(str) 27 | " vim73 has new function that gives correct string width. 28 | if exists("*strdisplaywidth") 29 | return strdisplaywidth(a:str) 30 | endif 31 | 32 | " get str display width in vim ver < 7.2 33 | if !vimwiki#vars#get_global('CJK_length') 34 | let ret = strlen(substitute(a:str, '.', 'x', 'g')) 35 | else 36 | let savemodified = &modified 37 | let save_cursor = getpos('.') 38 | exe "norm! o\" 39 | call setline(line("."), a:str) 40 | let ret = virtcol("$") - 1 41 | d 42 | call setpos('.', save_cursor) 43 | let &modified = savemodified 44 | endif 45 | return ret 46 | endfunction 47 | 48 | 49 | function! s:cell_splitter() 50 | return '\s*'.s:rxSep().'\s*' 51 | endfunction 52 | 53 | 54 | function! s:sep_splitter() 55 | return '-'.s:rxSep().'-' 56 | endfunction 57 | 58 | 59 | function! s:is_table(line) 60 | return s:is_separator(a:line) || 61 | \ (a:line !~# s:rxSep().s:rxSep() && a:line =~# '^\s*'.s:rxSep().'.\+'.s:rxSep().'\s*$') 62 | endfunction 63 | 64 | 65 | function! s:is_separator(line) 66 | return a:line =~# '^\s*'.s:rxSep().'\(--\+'.s:rxSep().'\)\+\s*$' 67 | endfunction 68 | 69 | 70 | function! s:is_separator_tail(line) 71 | return a:line =~# '^\{-1}\%(\s*\|-*\)\%('.s:rxSep().'-\+\)\+'.s:rxSep().'\s*$' 72 | endfunction 73 | 74 | 75 | function! s:is_last_column(lnum, cnum) 76 | let line = strpart(getline(a:lnum), a:cnum - 1) 77 | return line =~# s:rxSep().'\s*$' && line !~# s:rxSep().'.*'.s:rxSep().'\s*$' 78 | endfunction 79 | 80 | 81 | function! s:is_first_column(lnum, cnum) 82 | let line = strpart(getline(a:lnum), 0, a:cnum - 1) 83 | return line =~# '^\s*$' || 84 | \ (line =~# '^\s*'.s:rxSep() && line !~# '^\s*'.s:rxSep().'.*'.s:rxSep()) 85 | endfunction 86 | 87 | 88 | function! s:count_separators_up(lnum) 89 | let lnum = a:lnum - 1 90 | while lnum > 1 91 | if !s:is_separator(getline(lnum)) 92 | break 93 | endif 94 | let lnum -= 1 95 | endwhile 96 | 97 | return (a:lnum-lnum) 98 | endfunction 99 | 100 | 101 | function! s:count_separators_down(lnum) 102 | let lnum = a:lnum + 1 103 | while lnum < line('$') 104 | if !s:is_separator(getline(lnum)) 105 | break 106 | endif 107 | let lnum += 1 108 | endwhile 109 | 110 | return (lnum-a:lnum) 111 | endfunction 112 | 113 | 114 | function! s:create_empty_row(cols) 115 | let row = s:rxSep() 116 | let cell = " ".s:rxSep() 117 | 118 | for c in range(a:cols) 119 | let row .= cell 120 | endfor 121 | 122 | return row 123 | endfunction 124 | 125 | 126 | function! s:create_row_sep(cols) 127 | let row = s:rxSep() 128 | let cell = "---".s:rxSep() 129 | 130 | for c in range(a:cols) 131 | let row .= cell 132 | endfor 133 | 134 | return row 135 | endfunction 136 | 137 | 138 | function! vimwiki#tbl#get_cells(line) 139 | let result = [] 140 | let cell = '' 141 | let quote = '' 142 | let state = 'NONE' 143 | 144 | " 'Simple' FSM 145 | for idx in range(strlen(a:line)) 146 | " The only way I know Vim can do Unicode... 147 | let ch = a:line[idx] 148 | if state ==# 'NONE' 149 | if ch == '|' 150 | let state = 'CELL' 151 | endif 152 | elseif state ==# 'CELL' 153 | if ch == '[' || ch == '{' 154 | let state = 'BEFORE_QUOTE_START' 155 | let quote = ch 156 | elseif ch == '|' 157 | call add(result, vimwiki#u#trim(cell)) 158 | let cell = "" 159 | else 160 | let cell .= ch 161 | endif 162 | elseif state ==# 'BEFORE_QUOTE_START' 163 | if ch == '[' || ch == '{' 164 | let state = 'QUOTE' 165 | let quote .= ch 166 | else 167 | let state = 'CELL' 168 | let cell .= quote.ch 169 | let quote = '' 170 | endif 171 | elseif state ==# 'QUOTE' 172 | if ch == ']' || ch == '}' 173 | let state = 'BEFORE_QUOTE_END' 174 | endif 175 | let quote .= ch 176 | elseif state ==# 'BEFORE_QUOTE_END' 177 | if ch == ']' || ch == '}' 178 | let state = 'CELL' 179 | endif 180 | let cell .= quote.ch 181 | let quote = '' 182 | endif 183 | endfor 184 | 185 | if cell.quote != '' 186 | call add(result, vimwiki#u#trim(cell.quote, '|')) 187 | endif 188 | return result 189 | endfunction 190 | 191 | 192 | function! s:col_count(lnum) 193 | return len(vimwiki#tbl#get_cells(getline(a:lnum))) 194 | endfunction 195 | 196 | 197 | function! s:get_indent(lnum) 198 | if !s:is_table(getline(a:lnum)) 199 | return 200 | endif 201 | 202 | let indent = 0 203 | 204 | let lnum = a:lnum - 1 205 | while lnum > 1 206 | let line = getline(lnum) 207 | if !s:is_table(line) 208 | let indent = indent(lnum+1) 209 | break 210 | endif 211 | let lnum -= 1 212 | endwhile 213 | 214 | return indent 215 | endfunction 216 | 217 | 218 | function! s:get_rows(lnum) 219 | if !s:is_table(getline(a:lnum)) 220 | return 221 | endif 222 | 223 | let upper_rows = [] 224 | let lower_rows = [] 225 | 226 | let lnum = a:lnum - 1 227 | while lnum >= 1 228 | let line = getline(lnum) 229 | if s:is_table(line) 230 | call add(upper_rows, [lnum, line]) 231 | else 232 | break 233 | endif 234 | let lnum -= 1 235 | endwhile 236 | call reverse(upper_rows) 237 | 238 | let lnum = a:lnum 239 | while lnum <= line('$') 240 | let line = getline(lnum) 241 | if s:is_table(line) 242 | call add(lower_rows, [lnum, line]) 243 | else 244 | break 245 | endif 246 | let lnum += 1 247 | endwhile 248 | 249 | return upper_rows + lower_rows 250 | endfunction 251 | 252 | 253 | function! s:get_cell_max_lens(lnum, ...) 254 | let max_lens = {} 255 | for [lnum, row] in s:get_rows(a:lnum) 256 | if s:is_separator(row) 257 | continue 258 | endif 259 | let cells = a:0 > 1 ? a:1[lnum - a:2] : vimwiki#tbl#get_cells(row) 260 | for idx in range(len(cells)) 261 | let value = cells[idx] 262 | if has_key(max_lens, idx) 263 | let max_lens[idx] = max([s:wide_len(value), max_lens[idx]]) 264 | else 265 | let max_lens[idx] = s:wide_len(value) 266 | endif 267 | endfor 268 | endfor 269 | return max_lens 270 | endfunction 271 | 272 | 273 | function! s:get_aligned_rows(lnum, col1, col2) 274 | let rows = s:get_rows(a:lnum) 275 | let startlnum = rows[0][0] 276 | let cells = [] 277 | for [lnum, row] in rows 278 | call add(cells, vimwiki#tbl#get_cells(row)) 279 | endfor 280 | let max_lens = s:get_cell_max_lens(a:lnum, cells, startlnum) 281 | let result = [] 282 | for [lnum, row] in rows 283 | if s:is_separator(row) 284 | let new_row = s:fmt_sep(max_lens, a:col1, a:col2) 285 | else 286 | let new_row = s:fmt_row(cells[lnum - startlnum], max_lens, a:col1, a:col2) 287 | endif 288 | call add(result, [lnum, new_row]) 289 | endfor 290 | return result 291 | endfunction 292 | 293 | 294 | " Number of the current column. Starts from 0. 295 | function! s:cur_column() 296 | let line = getline('.') 297 | if !s:is_table(line) 298 | return -1 299 | endif 300 | " TODO: do we need conditional: if s:is_separator(line) 301 | 302 | let curs_pos = col('.') 303 | let mpos = match(line, s:rxSep(), 0) 304 | let col = -1 305 | while mpos < curs_pos && mpos != -1 306 | let mpos = match(line, s:rxSep(), mpos+1) 307 | if mpos != -1 308 | let col += 1 309 | endif 310 | endwhile 311 | return col 312 | endfunction 313 | 314 | 315 | function! s:fmt_cell(cell, max_len) 316 | let cell = ' '.a:cell.' ' 317 | 318 | let diff = a:max_len - s:wide_len(a:cell) 319 | if diff == 0 && empty(a:cell) 320 | let diff = 1 321 | endif 322 | 323 | let cell .= repeat(' ', diff) 324 | return cell 325 | endfunction 326 | 327 | 328 | function! s:fmt_row(cells, max_lens, col1, col2) 329 | let new_line = s:rxSep() 330 | for idx in range(len(a:cells)) 331 | if idx == a:col1 332 | let idx = a:col2 333 | elseif idx == a:col2 334 | let idx = a:col1 335 | endif 336 | let value = a:cells[idx] 337 | let new_line .= s:fmt_cell(value, a:max_lens[idx]).s:rxSep() 338 | endfor 339 | 340 | let idx = len(a:cells) 341 | while idx < len(a:max_lens) 342 | let new_line .= s:fmt_cell('', a:max_lens[idx]).s:rxSep() 343 | let idx += 1 344 | endwhile 345 | return new_line 346 | endfunction 347 | 348 | 349 | function! s:fmt_cell_sep(max_len) 350 | if a:max_len == 0 351 | return repeat('-', 3) 352 | else 353 | return repeat('-', a:max_len+2) 354 | endif 355 | endfunction 356 | 357 | 358 | function! s:fmt_sep(max_lens, col1, col2) 359 | let new_line = s:rxSep() 360 | for idx in range(len(a:max_lens)) 361 | if idx == a:col1 362 | let idx = a:col2 363 | elseif idx == a:col2 364 | let idx = a:col1 365 | endif 366 | let new_line .= s:fmt_cell_sep(a:max_lens[idx]).s:rxSep() 367 | endfor 368 | return new_line 369 | endfunction 370 | 371 | 372 | function! s:kbd_create_new_row(cols, goto_first) 373 | let cmd = "\o".s:create_empty_row(a:cols) 374 | let cmd .= "\:call vimwiki#tbl#format(line('.'))\" 375 | let cmd .= "\0" 376 | if a:goto_first 377 | let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'c', line('.'))\" 378 | else 379 | let cmd .= (col('.')-1)."l" 380 | let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\" 381 | endif 382 | let cmd .= "a" 383 | 384 | return cmd 385 | endfunction 386 | 387 | 388 | function! s:kbd_goto_next_row() 389 | let cmd = "\j" 390 | let cmd .= ":call search('.\\(".s:rxSep()."\\)', 'c', line('.'))\" 391 | let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\" 392 | let cmd .= "a" 393 | return cmd 394 | endfunction 395 | 396 | 397 | function! s:kbd_goto_prev_row() 398 | let cmd = "\k" 399 | let cmd .= ":call search('.\\(".s:rxSep()."\\)', 'c', line('.'))\" 400 | let cmd .= ":call search('\\(".s:rxSep()."\\)\\zs', 'bc', line('.'))\" 401 | let cmd .= "a" 402 | return cmd 403 | endfunction 404 | 405 | 406 | " Used in s:kbd_goto_next_col 407 | function! vimwiki#tbl#goto_next_col() 408 | let curcol = virtcol('.') 409 | let lnum = line('.') 410 | let newcol = s:get_indent(lnum) 411 | let max_lens = s:get_cell_max_lens(lnum) 412 | for cell_len in values(max_lens) 413 | if newcol >= curcol-1 414 | break 415 | endif 416 | let newcol += cell_len + 3 " +3 == 2 spaces + 1 separator |... 417 | endfor 418 | let newcol += 2 " +2 == 1 separator + 1 space |... 443 | if newcol + delta > curcol-1 444 | let newcol -= (prev_cell_len + 3) " +3 == 2 spaces + 1 separator |... 445 | break 446 | elseif newcol + delta == curcol-1 447 | break 448 | endif 449 | let prev_cell_len = cell_len 450 | let newcol += delta 451 | endfor 452 | let newcol += 2 " +2 == 1 separator + 1 space |" 466 | " let cmd .= "a" 467 | "echomsg "DEBUG kbd_goto_prev_col> ".cmd 468 | return cmd 469 | endfunction 470 | 471 | 472 | function! vimwiki#tbl#kbd_cr() 473 | let lnum = line('.') 474 | if !s:is_table(getline(lnum)) 475 | return "" 476 | endif 477 | 478 | if s:is_separator(getline(lnum+1)) || !s:is_table(getline(lnum+1)) 479 | let cols = len(vimwiki#tbl#get_cells(getline(lnum))) 480 | return s:kbd_create_new_row(cols, 0) 481 | else 482 | return s:kbd_goto_next_row() 483 | endif 484 | endfunction 485 | 486 | 487 | function! vimwiki#tbl#kbd_tab() 488 | let lnum = line('.') 489 | if !s:is_table(getline(lnum)) 490 | return "\" 491 | endif 492 | 493 | let last = s:is_last_column(lnum, col('.')) 494 | let is_sep = s:is_separator_tail(getline(lnum)) 495 | "echomsg "DEBUG kbd_tab> last=".last.", is_sep=".is_sep 496 | if (is_sep || last) && !s:is_table(getline(lnum+1)) 497 | let cols = len(vimwiki#tbl#get_cells(getline(lnum))) 498 | return s:kbd_create_new_row(cols, 1) 499 | endif 500 | return s:kbd_goto_next_col(is_sep || last) 501 | endfunction 502 | 503 | 504 | function! vimwiki#tbl#kbd_shift_tab() 505 | let lnum = line('.') 506 | if !s:is_table(getline(lnum)) 507 | return "\" 508 | endif 509 | 510 | let first = s:is_first_column(lnum, col('.')) 511 | let is_sep = s:is_separator_tail(getline(lnum)) 512 | "echomsg "DEBUG kbd_tab> ".first 513 | if (is_sep || first) && !s:is_table(getline(lnum-1)) 514 | return "" 515 | endif 516 | return s:kbd_goto_prev_col(is_sep || first) 517 | endfunction 518 | 519 | 520 | function! vimwiki#tbl#format(lnum, ...) 521 | if !(&filetype ==? 'vimwiki') 522 | return 523 | endif 524 | let line = getline(a:lnum) 525 | if !s:is_table(line) 526 | return 527 | endif 528 | 529 | if a:0 == 2 530 | let col1 = a:1 531 | let col2 = a:2 532 | else 533 | let col1 = 0 534 | let col2 = 0 535 | endif 536 | 537 | let indent = s:get_indent(a:lnum) 538 | if &expandtab 539 | let indentstring = repeat(' ', indent) 540 | else 541 | let indentstring = repeat(' ', indent / &tabstop) . repeat(' ', indent % &tabstop) 542 | endif 543 | 544 | for [lnum, row] in s:get_aligned_rows(a:lnum, col1, col2) 545 | let row = indentstring.row 546 | call setline(lnum, row) 547 | endfor 548 | 549 | let &tw = s:textwidth 550 | endfunction 551 | 552 | 553 | function! vimwiki#tbl#create(...) 554 | if a:0 > 1 555 | let cols = a:1 556 | let rows = a:2 557 | elseif a:0 == 1 558 | let cols = a:1 559 | let rows = 2 560 | elseif a:0 == 0 561 | let cols = 5 562 | let rows = 2 563 | endif 564 | 565 | if cols < 1 566 | let cols = 5 567 | endif 568 | 569 | if rows < 1 570 | let rows = 2 571 | endif 572 | 573 | let lines = [] 574 | let row = s:create_empty_row(cols) 575 | 576 | call add(lines, row) 577 | if rows > 1 578 | call add(lines, s:create_row_sep(cols)) 579 | endif 580 | 581 | for r in range(rows - 1) 582 | call add(lines, row) 583 | endfor 584 | 585 | call append(line('.'), lines) 586 | endfunction 587 | 588 | 589 | function! vimwiki#tbl#align_or_cmd(cmd) 590 | if s:is_table(getline('.')) 591 | call vimwiki#tbl#format(line('.')) 592 | else 593 | exe 'normal! '.a:cmd 594 | endif 595 | endfunction 596 | 597 | 598 | function! vimwiki#tbl#reset_tw(lnum) 599 | if !(&filetype ==? 'vimwiki') 600 | return 601 | endif 602 | let line = getline(a:lnum) 603 | if !s:is_table(line) 604 | return 605 | endif 606 | 607 | let s:textwidth = &tw 608 | let &tw = 0 609 | endfunction 610 | 611 | 612 | " TODO: move_column_left and move_column_right are good candidates to be refactored. 613 | function! vimwiki#tbl#move_column_left() 614 | 615 | "echomsg "DEBUG move_column_left: " 616 | 617 | let line = getline('.') 618 | 619 | if !s:is_table(line) 620 | return 621 | endif 622 | 623 | let cur_col = s:cur_column() 624 | if cur_col == -1 625 | return 626 | endif 627 | 628 | if cur_col > 0 629 | call vimwiki#tbl#format(line('.'), cur_col-1, cur_col) 630 | call cursor(line('.'), 1) 631 | 632 | let sep = '\('.s:rxSep().'\).\zs' 633 | let mpos = -1 634 | let col = -1 635 | while col < cur_col-1 636 | let mpos = match(line, sep, mpos+1) 637 | if mpos != -1 638 | let col += 1 639 | else 640 | break 641 | endif 642 | endwhile 643 | 644 | endif 645 | endfunction 646 | 647 | 648 | function! vimwiki#tbl#move_column_right() 649 | 650 | let line = getline('.') 651 | 652 | if !s:is_table(line) 653 | return 654 | endif 655 | 656 | let cur_col = s:cur_column() 657 | if cur_col == -1 658 | return 659 | endif 660 | 661 | if cur_col < s:col_count(line('.'))-1 662 | call vimwiki#tbl#format(line('.'), cur_col, cur_col+1) 663 | call cursor(line('.'), 1) 664 | 665 | let sep = '\('.s:rxSep().'\).\zs' 666 | let mpos = -1 667 | let col = -1 668 | while col < cur_col+1 669 | let mpos = match(line, sep, mpos+1) 670 | if mpos != -1 671 | let col += 1 672 | else 673 | break 674 | endif 675 | endwhile 676 | endif 677 | endfunction 678 | 679 | 680 | function! vimwiki#tbl#get_rows(lnum) 681 | return s:get_rows(a:lnum) 682 | endfunction 683 | 684 | 685 | function! vimwiki#tbl#is_table(line) 686 | return s:is_table(a:line) 687 | endfunction 688 | 689 | 690 | function! vimwiki#tbl#is_separator(line) 691 | return s:is_separator(a:line) 692 | endfunction 693 | 694 | 695 | function! vimwiki#tbl#cell_splitter() 696 | return s:cell_splitter() 697 | endfunction 698 | 699 | 700 | function! vimwiki#tbl#sep_splitter() 701 | return s:sep_splitter() 702 | endfunction 703 | 704 | -------------------------------------------------------------------------------- /autoload/vimwiki/u.vim: -------------------------------------------------------------------------------- 1 | " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 2 | " Vimwiki autoload plugin file 3 | " Description: Utility functions 4 | " Home: https://github.com/vimwiki/vimwiki/ 5 | 6 | function! vimwiki#u#trim(string, ...) 7 | let chars = '' 8 | if a:0 > 0 9 | let chars = a:1 10 | endif 11 | let res = substitute(a:string, '^[[:space:]'.chars.']\+', '', '') 12 | let res = substitute(res, '[[:space:]'.chars.']\+$', '', '') 13 | return res 14 | endfunction 15 | 16 | 17 | " Builtin cursor doesn't work right with unicode characters. 18 | function! vimwiki#u#cursor(lnum, cnum) 19 | exe a:lnum 20 | exe 'normal! 0'.a:cnum.'|' 21 | endfunction 22 | 23 | 24 | function! vimwiki#u#is_windows() 25 | return has("win32") || has("win64") || has("win95") || has("win16") 26 | endfunction 27 | 28 | 29 | function! vimwiki#u#is_macos() 30 | if has("mac") || has("macunix") || has("gui_mac") 31 | return 1 32 | endif 33 | " that still doesn't mean we are not on Mac OS 34 | let os = substitute(system('uname'), '\n', '', '') 35 | return os == 'Darwin' || os == 'Mac' 36 | endfunction 37 | 38 | 39 | function! vimwiki#u#count_first_sym(line) 40 | let first_sym = matchstr(a:line, '\S') 41 | return len(matchstr(a:line, first_sym.'\+')) 42 | endfunction 43 | 44 | 45 | function! vimwiki#u#escape(string) 46 | return escape(a:string, '~.*[]\^$') 47 | endfunction 48 | 49 | 50 | " Load concrete Wiki syntax: sets regexes and templates for headers and links 51 | function vimwiki#u#reload_regexes() 52 | execute 'runtime! syntax/vimwiki_'.vimwiki#vars#get_wikilocal('syntax').'.vim' 53 | endfunction 54 | 55 | 56 | " Load syntax-specific functionality 57 | function vimwiki#u#reload_regexes_custom() 58 | execute 'runtime! syntax/vimwiki_'.vimwiki#vars#get_wikilocal('syntax').'_custom.vim' 59 | endfunction 60 | 61 | 62 | " Backward compatible version of the built-in function shiftwidth() 63 | if exists('*shiftwidth') 64 | func vimwiki#u#sw() 65 | return shiftwidth() 66 | endfunc 67 | else 68 | func vimwiki#u#sw() 69 | return &sw 70 | endfunc 71 | endif 72 | 73 | -------------------------------------------------------------------------------- /autoload/vimwiki/vars.vim: -------------------------------------------------------------------------------- 1 | " vim:tabstop=2:shiftwidth=2:expandtab:textwidth=99 2 | " Vimwiki autoload plugin file 3 | " Home: https://github.com/vimwiki/vimwiki/ 4 | 5 | 6 | 7 | " ------------------------------------------------------------------------------------------------ 8 | " This file provides functions to manage the various state variables which are needed during a 9 | " Vimwiki session. 10 | " They consist of: 11 | " 12 | " - global variables. These are stored in the dict g:vimwiki_global_vars. They consist mainly of 13 | " global user variables and syntax stuff which is the same for every syntax. 14 | " 15 | " - wiki-local variables. They are stored in g:vimwiki_wikilocal_vars which is a list of 16 | " dictionaries, one dict for every registered wiki. The last dictionary contains default values 17 | " (used for temporary wikis). 18 | " 19 | " - syntax variables. Stored in the dict g:vimwiki_syntax_variables which holds all the regexes and 20 | " other stuff which is needed for highlighting. 21 | " 22 | " - buffer-local variables. They are stored as buffer variables directly (b:foo) 23 | 24 | " As a developer, you should, if possible, only use the get_ and set_ functions for these types of 25 | " variables, not the underlying dicts! 26 | " ------------------------------------------------------------------------------------------------ 27 | 28 | 29 | function! s:populate_global_variables() 30 | 31 | let g:vimwiki_global_vars = {} 32 | 33 | call s:read_global_settings_from_user() 34 | call s:normalize_global_settings() 35 | 36 | " non-configurable global variables: 37 | 38 | " Scheme regexes must be defined even if syntax file is not loaded yet cause users should be 39 | " able to ww without opening any vimwiki file first 40 | let g:vimwiki_global_vars.schemes = join(['wiki\d\+', 'diary', 'local'], '\|') 41 | let g:vimwiki_global_vars.web_schemes1 = join(['http', 'https', 'file', 'ftp', 'gopher', 42 | \ 'telnet', 'nntp', 'ldap', 'rsync', 'imap', 'pop', 'irc', 'ircs', 'cvs', 'svn', 'svn+ssh', 43 | \ 'git', 'ssh', 'fish', 'sftp'], '\|') 44 | let web_schemes2 = 45 | \ join(['mailto', 'news', 'xmpp', 'sip', 'sips', 'doi', 'urn', 'tel', 'data'], '\|') 46 | 47 | let g:vimwiki_global_vars.rxSchemes = '\%('. 48 | \ g:vimwiki_global_vars.schemes . '\|'. 49 | \ g:vimwiki_global_vars.web_schemes1 . '\|'. 50 | \ web_schemes2 . 51 | \ '\)' 52 | 53 | " match URL for common protocols; see http://en.wikipedia.org/wiki/URI_scheme 54 | " http://tools.ietf.org/html/rfc3986 55 | let rxWebProtocols = 56 | \ '\%('. 57 | \ '\%('. 58 | \ '\%('.g:vimwiki_global_vars.web_schemes1 . '\):'. 59 | \ '\%(//\)'. 60 | \ '\)'. 61 | \ '\|'. 62 | \ '\%('.web_schemes2.'\):'. 63 | \ '\)' 64 | 65 | let g:vimwiki_global_vars.rxWeblinkUrl = rxWebProtocols . '\S\{-1,}'. '\%(([^ \t()]*)\)\=' 66 | 67 | let wikilink_prefix = '[[' 68 | let wikilink_suffix = ']]' 69 | let wikilink_separator = '|' 70 | let g:vimwiki_global_vars.rx_wikilink_prefix = vimwiki#u#escape(wikilink_prefix) 71 | let g:vimwiki_global_vars.rx_wikilink_suffix = vimwiki#u#escape(wikilink_suffix) 72 | let g:vimwiki_global_vars.rx_wikilink_separator = vimwiki#u#escape(wikilink_separator) 73 | 74 | " templates for the creation of wiki links 75 | " [[URL]] 76 | let g:vimwiki_global_vars.WikiLinkTemplate1 = wikilink_prefix . '__LinkUrl__'. wikilink_suffix 77 | " [[URL|DESCRIPTION]] 78 | let g:vimwiki_global_vars.WikiLinkTemplate2 = wikilink_prefix . '__LinkUrl__'. wikilink_separator 79 | \ . '__LinkDescription__' . wikilink_suffix 80 | 81 | let valid_chars = '[^\\\]]' 82 | let g:vimwiki_global_vars.rxWikiLinkUrl = valid_chars.'\{-}' 83 | let g:vimwiki_global_vars.rxWikiLinkDescr = valid_chars.'\{-}' 84 | 85 | " this regexp defines what can form a link when the user presses in the 86 | " buffer (and not on a link) to create a link 87 | " basically, it's Ascii alphanumeric characters plus #|./@-_~ plus all 88 | " non-Ascii characters, except that . is not accepted as the last character 89 | let g:vimwiki_global_vars.rxWord = '[^[:blank:]!"$%&''()*+,:;<=>?\[\]\\^`{}]*[^[:blank:]!"$%&''()*+.,:;<=>?\[\]\\^`{}]' 90 | 91 | let g:vimwiki_global_vars.rx_wikilink_prefix1 = g:vimwiki_global_vars.rx_wikilink_prefix . 92 | \ g:vimwiki_global_vars.rxWikiLinkUrl . g:vimwiki_global_vars.rx_wikilink_separator 93 | let g:vimwiki_global_vars.rx_wikilink_suffix1 = g:vimwiki_global_vars.rx_wikilink_suffix 94 | 95 | let g:vimwiki_global_vars.rxWikiInclPrefix = '{{' 96 | let g:vimwiki_global_vars.rxWikiInclSuffix = '}}' 97 | let g:vimwiki_global_vars.rxWikiInclSeparator = '|' 98 | " '{{__LinkUrl__}}' 99 | let g:vimwiki_global_vars.WikiInclTemplate1 = g:vimwiki_global_vars.rxWikiInclPrefix 100 | \ .'__LinkUrl__'. g:vimwiki_global_vars.rxWikiInclSuffix 101 | " '{{__LinkUrl____LinkDescription__}}' 102 | let g:vimwiki_global_vars.WikiInclTemplate2 = g:vimwiki_global_vars.rxWikiInclPrefix 103 | \ . '__LinkUrl__' . g:vimwiki_global_vars.rxWikiInclSeparator . '__LinkDescription__' 104 | \ . g:vimwiki_global_vars.rxWikiInclSuffix 105 | 106 | let valid_chars = '[^\\\}]' 107 | let g:vimwiki_global_vars.rxWikiInclUrl = valid_chars.'\{-}' 108 | let g:vimwiki_global_vars.rxWikiInclArg = valid_chars.'\{-}' 109 | let g:vimwiki_global_vars.rxWikiInclArgs = '\%('. g:vimwiki_global_vars.rxWikiInclSeparator. 110 | \ g:vimwiki_global_vars.rxWikiInclArg. '\)'.'\{-}' 111 | 112 | " *. {{URL}[{...}]} - i.e. {{URL}}, {{URL|ARG1}}, {{URL|ARG1|ARG2}}, etc. 113 | " *a) match {{URL}[{...}]} 114 | let g:vimwiki_global_vars.rxWikiIncl = g:vimwiki_global_vars.rxWikiInclPrefix. 115 | \ g:vimwiki_global_vars.rxWikiInclUrl. 116 | \ g:vimwiki_global_vars.rxWikiInclArgs. g:vimwiki_global_vars.rxWikiInclSuffix 117 | " *b) match URL within {{URL}[{...}]} 118 | let g:vimwiki_global_vars.rxWikiInclMatchUrl = g:vimwiki_global_vars.rxWikiInclPrefix. 119 | \ '\zs'. g:vimwiki_global_vars.rxWikiInclUrl . '\ze'. 120 | \ g:vimwiki_global_vars.rxWikiInclArgs . g:vimwiki_global_vars.rxWikiInclSuffix 121 | 122 | let g:vimwiki_global_vars.rxWikiInclPrefix1 = g:vimwiki_global_vars.rxWikiInclPrefix. 123 | \ g:vimwiki_global_vars.rxWikiInclUrl . g:vimwiki_global_vars.rxWikiInclSeparator 124 | let g:vimwiki_global_vars.rxWikiInclSuffix1 = g:vimwiki_global_vars.rxWikiInclArgs. 125 | \ g:vimwiki_global_vars.rxWikiInclSuffix 126 | 127 | let g:vimwiki_global_vars.rxTodo = '\C\<\%(TODO\|DONE\|STARTED\|FIXME\|FIXED\|XXX\)\>' 128 | 129 | " default colors when headers of different levels are highlighted differently 130 | " not making it yet another option; needed by ColorScheme autocommand 131 | let g:vimwiki_global_vars.hcolor_guifg_light = ['#aa5858', '#507030', '#1030a0', '#103040' 132 | \ , '#505050', '#636363'] 133 | let g:vimwiki_global_vars.hcolor_ctermfg_light = ['DarkRed', 'DarkGreen', 'DarkBlue', 'Black' 134 | \ , 'Black', 'Black'] 135 | let g:vimwiki_global_vars.hcolor_guifg_dark = ['#e08090', '#80e090', '#6090e0', '#c0c0f0' 136 | \ , '#e0e0f0', '#f0f0f0'] 137 | let g:vimwiki_global_vars.hcolor_ctermfg_dark = ['Red', 'Green', 'Blue', 'White', 'White' 138 | \ , 'White'] 139 | endfunction 140 | 141 | 142 | function! s:read_global_settings_from_user() 143 | let global_settings = { 144 | \ 'CJK_length': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, 145 | \ 'auto_chdir': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, 146 | \ 'autowriteall': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, 147 | \ 'conceallevel': {'type': type(0), 'default': 2, 'min': 0, 'max': 3}, 148 | \ 'diary_months': {'type': type({}), 'default': 149 | \ { 150 | \ 1: 'January', 2: 'February', 3: 'March', 151 | \ 4: 'April', 5: 'May', 6: 'June', 152 | \ 7: 'July', 8: 'August', 9: 'September', 153 | \ 10: 'October', 11: 'November', 12: 'December' 154 | \ }}, 155 | \ 'dir_link': {'type': type(''), 'default': ''}, 156 | \ 'ext2syntax': {'type': type({}), 'default': {}}, 157 | \ 'folding': {'type': type(''), 'default': '', 'possible_values': ['', 'expr', 'syntax', 158 | \ 'list', 'custom', ':quick', 'expr:quick', 'syntax:quick', 'list:quick', 159 | \ 'custom:quick']}, 160 | \ 'global_ext': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, 161 | \ 'hl_cb_checked': {'type': type(0), 'default': 0, 'min': 0, 'max': 2}, 162 | \ 'hl_headers': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, 163 | \ 'html_header_numbering': {'type': type(0), 'default': 0, 'min': 0, 'max': 6}, 164 | \ 'html_header_numbering_sym': {'type': type(''), 'default': ''}, 165 | \ 'list_ignore_newline': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, 166 | \ 'text_ignore_newline': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, 167 | \ 'listsyms': {'type': type(''), 'default': ' .oOX', 'min_length': 2}, 168 | \ 'listsym_rejected': {'type': type(''), 'default': '-', 'length': 1}, 169 | \ 'map_prefix': {'type': type(''), 'default': 'w'}, 170 | \ 'menu': {'type': type(''), 'default': 'Vimwiki'}, 171 | \ 'table_auto_fmt': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, 172 | \ 'table_mappings': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, 173 | \ 'toc_header': {'type': type(''), 'default': 'Contents', 'min_length': 1}, 174 | \ 'url_maxsave': {'type': type(0), 'default': 15, 'min': 0}, 175 | \ 'use_calendar': {'type': type(0), 'default': 1, 'min': 0, 'max': 1}, 176 | \ 'use_mouse': {'type': type(0), 'default': 0, 'min': 0, 'max': 1}, 177 | \ 'user_htmls': {'type': type(''), 'default': ''}, 178 | \ 'valid_html_tags': {'type': type(''), 'default': 179 | \ 'b,i,s,u,sub,sup,kbd,br,hr,div,center,strong,em'}, 180 | \ 'w32_dir_enc': {'type': type(''), 'default': ''}, 181 | \ } 182 | 183 | " copy the user's settings from variables of the form g:vimwiki_