├── .gitignore ├── doc ├── example.taskpaper ├── taskpaper_hacking.txt ├── taskpaper.txt └── taskpaper_licence.txt ├── ftdetect └── taskpaper.vim ├── syntax └── taskpaper.vim ├── ftplugin └── taskpaper.vim ├── README.md └── autoload └── taskpaper.vim /.gitignore: -------------------------------------------------------------------------------- 1 | tags 2 | -------------------------------------------------------------------------------- /doc/example.taskpaper: -------------------------------------------------------------------------------- 1 | Example Project: 2 | - Start example project file @computer @done 3 | - Brainstorm project with colleagues @work 4 | - Email Joan about project @email 5 | Sub Project: 6 | - Sub task 7 | 8 | Next Project: 9 | - Draft ideas for next project @anywhere 10 | - Email Bob to arrange meeting @email 11 | -------------------------------------------------------------------------------- /doc/taskpaper_hacking.txt: -------------------------------------------------------------------------------- 1 | Version Control 2 | ---------------- 3 | 4 | github (http://github.com) is used for version control. The main 5 | repository is at . 6 | 7 | To start working on the source code you should create an account on github, 8 | fork taskpaper.vim and checkout your fork. 9 | -------------------------------------------------------------------------------- /ftdetect/taskpaper.vim: -------------------------------------------------------------------------------- 1 | " Vim filetype detection file 2 | " Language: Taskpaper (http://hogbaysoftware.com/projects/taskpaper) 3 | " Maintainer: David O'Callaghan 4 | " URL: https://github.com/davidoc/taskpaper.vim 5 | " Last Change: 2011-03-28 6 | " 7 | augroup taskpaper 8 | au! BufRead,BufNewFile *.taskpaper setfiletype taskpaper 9 | augroup END 10 | -------------------------------------------------------------------------------- /syntax/taskpaper.vim: -------------------------------------------------------------------------------- 1 | " Vim syntax file 2 | " Language: Taskpaper (http://hogbaysoftware.com/projects/taskpaper) 3 | " Maintainer: David O'Callaghan 4 | " URL: https://github.com/davidoc/taskpaper.vim 5 | " Last Change: 2012-03-07 6 | 7 | if version < 600 8 | syntax clear 9 | elseif exists("b:current_syntax") 10 | finish 11 | endif 12 | 13 | if version < 508 14 | command! -nargs=+ HiLink hi link 15 | else 16 | command! -nargs=+ HiLink hi def link 17 | endif 18 | 19 | " Define tag styles 20 | if !exists('g:task_paper_styles') 21 | let g:task_paper_styles = {'FAIL': 'guibg=Red guifg=White'} 22 | endif 23 | 24 | syn case ignore 25 | 26 | syn match taskpaperComment /^.*$/ contains=taskpaperContext 27 | syn match taskpaperProject /^.\+:\(\s\+@[^ \t(]\+\(([^)]*)\)\?\)*$/ contains=taskpaperContext 28 | syn match taskpaperListItem /^\t*-\s\+/ 29 | syn match taskpaperContext /\s\zs@[^ \t(]\+\(([^)]*)\)\?/ 30 | syn match taskpaperToday /@today/ 31 | syn match taskpaperUrgent /@urgent/ 32 | syn match taskpaperDone /^.*\s@done\(\(\s\|([^)]*)\).*\)\?$/ contains=taskpaperToday,taskpaperUrgent 33 | syn match taskpaperCancelled /^.*\s@cancelled\(\(\s\|([^)]*)\).*\)\?$/ contains=taskpaperToday,taskpaperUrgent 34 | 35 | syn sync fromstart 36 | 37 | "highlighting for Taskpaper groups 38 | HiLink taskpaperListItem Identifier 39 | HiLink taskpaperContext String 40 | HiLink taskpaperToday Search 41 | HiLink taskpaperUrgent ErrorMsg 42 | HiLink taskpaperProject Title 43 | HiLink taskpaperDone Comment 44 | HiLink taskpaperCancelled Comment 45 | HiLink taskpaperComment Comment 46 | 47 | call taskpaper#tag_style_dict(g:task_paper_styles) 48 | 49 | let b:current_syntax = "taskpaper" 50 | 51 | delcommand HiLink 52 | " vim: ts=8 53 | -------------------------------------------------------------------------------- /ftplugin/taskpaper.vim: -------------------------------------------------------------------------------- 1 | " plugin to handle the TaskPaper to-do list format 2 | " Language: Taskpaper (http://hogbaysoftware.com/projects/taskpaper) 3 | " Maintainer: David O'Callaghan 4 | " URL: https://github.com/davidoc/taskpaper.vim 5 | " Last Change: 2012-02-20 6 | 7 | if exists("b:did_ftplugin") 8 | finish 9 | endif 10 | let b:did_ftplugin = 1 11 | 12 | let s:save_cpo = &cpo 13 | set cpo&vim 14 | 15 | " Define a default date format 16 | if !exists('g:task_paper_date_format') 17 | let g:task_paper_date_format = "%Y-%m-%d" 18 | endif 19 | 20 | " Define a default archive project name 21 | if !exists('g:task_paper_archive_project') 22 | let g:task_paper_archive_project = "Archive" 23 | endif 24 | 25 | " When moving a task, should the cursor follow or stay in the same place 26 | " (default: follow) 27 | if !exists('g:task_paper_follow_move') 28 | let g:task_paper_follow_move = 1 29 | endif 30 | 31 | " Hide @done tasks when searching tags 32 | if !exists('g:task_paper_search_hide_done') 33 | let g:task_paper_search_hide_done = 0 34 | endif 35 | 36 | " Add '@' to keyword character set so that we can complete contexts as keywords 37 | setlocal iskeyword+=@-@ 38 | 39 | " Tab character has special meaning on TaskPaper 40 | setlocal noexpandtab 41 | 42 | " Change 'comments' and 'formatoptions' to continue to write a task item 43 | setlocal comments=b:- 44 | setlocal fo-=c fo+=rol 45 | 46 | " Set 'autoindent' to maintain indent level 47 | setlocal autoindent 48 | 49 | " Set up mappings 50 | nnoremap TaskPaperFoldProjects 51 | \ :call taskpaper#fold_projects() 52 | nnoremap TaskPaperFoldNotes 53 | \ :call taskpaper#search('\v^(\s*\|\t+-\s+.*\|.+:)$') 54 | nnoremap TaskPaperFocusProject 55 | \ :call taskpaper#focus_project() 56 | 57 | nnoremap TaskPaperSearchKeyword 58 | \ :call taskpaper#search() 59 | nnoremap TaskPaperSearchTag 60 | \ :call taskpaper#search_tag() 61 | 62 | nnoremap TaskPaperGoToProject 63 | \ :call taskpaper#go_to_project() 64 | nnoremap TaskPaperNextProject 65 | \ :call taskpaper#next_project() 66 | nnoremap TaskPaperPreviousProject 67 | \ :call taskpaper#previous_project() 68 | 69 | nnoremap TaskPaperArchiveDone 70 | \ :call taskpaper#archive_done() 71 | nnoremap TaskPaperShowToday 72 | \ :call taskpaper#search_tag('today') 73 | nnoremap TaskPaperShowCancelled 74 | \ :call taskpaper#search_tag('cancelled') 75 | nnoremap TaskPaperToggleCancelled 76 | \ :call taskpaper#toggle_tag('cancelled', taskpaper#date()):silent! call repeat#set("\TaskPaperToggleCancelled", v:count) 77 | nnoremap TaskPaperToggleDone 78 | \ :call taskpaper#toggle_tag('done', taskpaper#date()):silent! call repeat#set("\TaskPaperToggleDone", v:count) 79 | nnoremap TaskPaperToggleToday 80 | \ :call taskpaper#toggle_tag('today', ''):silent! call repeat#set("\TaskPaperToggleToday", v:count) 81 | nnoremap TaskPaperMoveToProject 82 | \ :call taskpaper#move_to_project() 83 | 84 | nnoremap TaskPaperNewline 85 | \ o=taskpaper#newline() 86 | inoremap TaskPaperNewline 87 | \ =taskpaper#newline() 88 | 89 | if !exists("no_plugin_maps") && !exists("no_taskpaper_maps") 90 | nmap tp TaskPaperFoldProjects 91 | nmap t. TaskPaperFoldNotes 92 | nmap tP TaskPaperFocusProject 93 | 94 | nmap t/ TaskPaperSearchKeyword 95 | nmap ts TaskPaperSearchTag 96 | 97 | nmap tg TaskPaperGoToProject 98 | nmap tj TaskPaperNextProject 99 | nmap tk TaskPaperPreviousProject 100 | 101 | nmap tD TaskPaperArchiveDone 102 | nmap tT TaskPaperShowToday 103 | nmap tX TaskPaperShowCancelled 104 | nmap td TaskPaperToggleDone 105 | nmap tt TaskPaperToggleToday 106 | nmap tx TaskPaperToggleCancelled 107 | nmap tm TaskPaperMoveToProject 108 | 109 | vnoremap td :norm td 110 | vnoremap tt :norm tt 111 | vnoremap tx :norm tx 112 | 113 | if mapcheck("o", "n") == '' 114 | nmap o TaskPaperNewline 115 | endif 116 | if mapcheck("\", "i") == '' 117 | imap TaskPaperNewline 118 | endif 119 | endif 120 | 121 | let &cpo = s:save_cpo 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vim-taskpaper 2 | 3 | ## Introduction 4 | 5 | From the TaskPaper website (): 6 | 7 | "TaskPaper is a simple to-do list application that helps you stay 8 | organized. Unlike competing applications, TaskPaper is based on plain text 9 | files which offer you paper-like simplicity and ease of use." 10 | 11 | TaskPaper is a to-do list application for Mac OS X based on the "Getting 12 | Things Done" approach of David Allen (). It supports 13 | the GTD notions of projects, tasks and contexts. 14 | 15 | This package contains a syntax file and a file-type plugin for the simple 16 | format used by the TaskPaper application. It is intended for Mac users who 17 | want to edit their TaskPaper lists in Vim from time to time (for example, in 18 | a SSH session, or on a non-Mac system) and for anyone who is looking for a 19 | simple to-do list format. 20 | 21 | ## Installation 22 | 23 | Assuming you're using [vim-plug](https://github.com/junegunn/vim-plug): 24 | 25 | ```vim 26 | Plug 'cweagans/vim-taskpaper' 27 | ``` 28 | 29 | If you're using the [Vigor](https://github.com/vim-vigor) neovim distribution, 30 | you can also install the [language-taskpaper](https://github.com/vim-vigor/language-taskpaper) 31 | layer. 32 | 33 | ## Features 34 | 35 | Vim can complete context names after the '@' using the keyword completion 36 | commands (e.g. Ctrl-X Ctrl-N). 37 | 38 | The plugin defines some new mappings: 39 | 40 | | Key | Description | 41 | | ------------ | ---------------------------------- | 42 | | `td` | Mark task as done | 43 | | `tx` | Mark task as cancelled | 44 | | `tt` | Mark task as today | 45 | | `tD` | Archive @done items | 46 | | `tX` | Show tasks marked as cancelled | 47 | | `tT` | Show tasks marked as today | 48 | | `t/` | Search for items including keyword | 49 | | `ts` | Search for items including tag | 50 | | `tp` | Fold all projects | 51 | | `t.` | Fold all notes | 52 | | `tP` | Focus on the current project | 53 | | `tj` | Go to next project | 54 | | `tk` | Go to previous project | 55 | | `tg` | Go to specified project | 56 | | `tm` | Move task to specified project | 57 | 58 | Marking a task as done will add the "@done" context tag to the end of the 59 | task, and it will be greyed out by the syntax file. 60 | 61 | To show all tasks with a particular context tag, type `\ts` and a tag name to 62 | search. If you use the `\ts` command over the desired context tag, the tag 63 | name is set as default value. This will fold all the irrelevant tasks leaving 64 | only the tasks in the current context visible. 65 | 66 | To fold all top-level projects leaving only the headings visible use the `\tp` 67 | command. Standard fold commands can be used to open (`zo`) and close (`zc`) 68 | individual projects. 69 | 70 | To show all projects and tasks use the `zR` command. This disables folding so 71 | that the entire file is expanded. 72 | 73 | To go to next or previous project use the `\tj` command or `\tk` command. To 74 | go to a project you specify use the `\tg` command. You can complete project 75 | names with on prompt. 76 | 77 | ## Options 78 | 79 | The plugin supports a number of configuration variables, which can be set in 80 | your .vimrc file. 81 | 82 | To change the default date format string used when marking a task complete, 83 | define the `task_paper_date_format` variable. The format matches your system's 84 | `strftime()` function. 85 | 86 | For example, to include the date and time in ISO8601 format: 87 | 88 | ```vim 89 | let g:task_paper_date_format = "%Y-%m-%dT%H:%M:%S%z" 90 | ``` 91 | 92 | To change the default archive project name, define the 93 | `task_paper_archive_project` variable. The default value is "Archive". 94 | 95 | ```vim 96 | let g:task_paper_archive_project = "Archive" 97 | ``` 98 | 99 | By default, when you move a task, the cursor will follow that task to its new 100 | location. To make the cursor stay in it's current location, change the 101 | `task_paper_follow_move` variable. 102 | 103 | ```vim 104 | let g:task_paper_follow_move = 0 105 | ``` 106 | 107 | If you want to hide done tasks when searching you can change the 108 | `task_paper_search_hide_done` variable. 109 | 110 | ```vim 111 | let g:task_paper_search_hide_done = 1 112 | ``` 113 | 114 | To set a custom style (colour, bold, etc.) for tags task_paper_styles variable, 115 | which is a dictionary. 116 | 117 | ```vim 118 | let g:task_paper_styles={'wait': 'ctermfg=Blue guifg=Blue', 'FAIL': 119 | 'ctermbg=Red guibg=Red'} 120 | ``` 121 | 122 | See `:h highlight-args` for a full description of the syntax. 123 | 124 | Customize 125 | ========== 126 | 127 | You can create your own shortcut for tagging. To define your own shortcut, 128 | write settings in ~/.vim/ftplugin/taskpaper.vim or ~/.vimrc. If you use the 129 | .vimrc file, define settings like: 130 | 131 | ```vim 132 | function! s:taskpaper_setup() 133 | " Your settings 134 | nnoremap tn 135 | \ :call taskpaper#toggle_tag('next', '') 136 | endfunction 137 | 138 | augroup vimrc-taskpaper 139 | autocmd! 140 | autocmd FileType taskpaper call s:taskpaper_setup() 141 | augroup END 142 | ``` 143 | 144 | To add a tag without argument: 145 | 146 | ```vim 147 | nnoremap tn 148 | \ :call taskpaper#add_tag('next', '') 149 | ``` 150 | 151 | To delete a tag: 152 | 153 | ```vim 154 | nnoremap tN 155 | \ :call taskpaper#delete_tag('next', '') 156 | ``` 157 | 158 | To toggle a tag: 159 | 160 | ```vim 161 | nnoremap tn 162 | \ :call taskpaper#toggle_tag('next', '') 163 | ``` 164 | 165 | To add a tag with an argument: 166 | 167 | ```vim 168 | nnoremap tq 169 | \ :call taskpaper#add_tag('priority') 170 | ``` 171 | 172 | You can specify the priority value on prompt. 173 | 174 | To delete the priority tag with any argument: 175 | 176 | ```vim 177 | nnoremap tQ 178 | \ :call taskpaper#delete_tag('priority', '') 179 | ``` 180 | 181 | To delete only the level 1 of priority tag: 182 | 183 | ```vim 184 | nnoremap tQ 185 | \ :call taskpaper#delete_tag('priority', '1') 186 | ``` 187 | 188 | To toggle a tag with an argument: 189 | 190 | ```vim 191 | nnoremap tq 192 | \ :call taskpaper#toggle_tag('priority') 193 | ``` 194 | 195 | To update a tag (not delete if the tag exists): 196 | 197 | ```vim 198 | nnoremap tq 199 | \ :call taskpaper#update_tag('priority') 200 | ``` 201 | 202 | ## Acknowledgements 203 | 204 | * The [original plugin](https://github.com/davidoc/taskpaper.vim) was written by David O'Callaghan 205 | * This fork has been improved by contributions from many forks of the original repository 206 | -------------------------------------------------------------------------------- /doc/taskpaper.txt: -------------------------------------------------------------------------------- 1 | *taskpaper.txt* For Vim version 6.0 Last change: 2012 March 13 2 | 3 | David O'Callaghan 4 | 5 | 13th March 2012 6 | 7 | Introduction 8 | ============= 9 | *taskpaper* 10 | 11 | *Latest version from https://github.com/davidoc/taskpaper.vim* 12 | 13 | From the TaskPaper website (): 14 | 15 | "TaskPaper is a simple to-do list application that helps you stay 16 | organized. Unlike competing applications, TaskPaper is based on plain text 17 | files which offer you paper-like simplicity and ease of use." 18 | 19 | TaskPaper is a to-do list application for Mac OS X based on the "Getting 20 | Things Done" approach of David Allen (). It supports 21 | the GTD notions of projects, tasks and contexts. 22 | 23 | This package contains a syntax file and a file-type plugin for the simple 24 | format used by the TaskPaper application. It is intended for Mac users who 25 | want to edit their TaskPaper lists in Vim from time to time (for example, in 26 | a SSH session, or on a non-Mac system) and for anyone who is looking for a 27 | simple to-do list format. 28 | 29 | Installation 30 | ============= 31 | *taskpaper-install* 32 | 33 | It should be safe to simply unpack the package into your .vim directory. 34 | It contains the following files: 35 | 36 | autoload/taskpaper.vim 37 | doc/example.taskpaper 38 | doc/taskpaper.txt 39 | doc/taskpaper_licence.txt 40 | ftdetect/taskpaper.vim 41 | ftplugin/taskpaper.vim 42 | syntax/taskpaper.vim 43 | 44 | To access this help file from within Vim you must first update your help 45 | tags: 46 | 47 | :helptags ~/.vim/doc 48 | 49 | The path may need to be modified depending on where you install to. Once 50 | you have done this you can access the help with this command: 51 | 52 | :help taskpaper 53 | 54 | Syntax 55 | ======= 56 | *taskpaper-syntax* 57 | 58 | The syntax file highlights project headings and task contexts (tags), and 59 | "greys out" completed tasks. The exact style of the displayed file depends 60 | on your Vim colour scheme. 61 | 62 | A project heading is a piece of text ending in a colon. 63 | 64 | A task is a line beginning with a hyphen '-' and can have zero or more 65 | context tags. 66 | 67 | A context tag has the form "@tag". 68 | 69 | Other text is considered as a "note" and is displayed as a Vim comment. 70 | 71 | File-type Plugin 72 | ================= 73 | *taskpaper-plugin* 74 | 75 | The file-type plugin tries to make editing TaskPaper files in Vim more 76 | comfortable. 77 | 78 | Vim can complete context names after the '@' using the keyword completion 79 | commands (e.g. Ctrl-X Ctrl-N). 80 | 81 | *taskpaper-mappings* 82 | The plugin defines some new mappings: 83 | 84 | \td Mark task as done 85 | \tx Mark task as cancelled 86 | \tt Mark task as today 87 | \tD Archive @done items 88 | \tX Show tasks marked as cancelled 89 | \tT Show tasks marked as today 90 | \t/ Search for items including keyword 91 | \ts Search for items including tag 92 | \tp Fold all projects 93 | \t. Fold all notes 94 | \tP Focus on the current project 95 | \tj Go to next project 96 | \tk Go to previous project 97 | \tg Go to specified project 98 | \tm Move task to specified project 99 | 100 | Note: if `` has been changed (e.g. `:let mapleader=",,"`) 101 | then its value should be used instead of `\` in the mappings. 102 | 103 | Marking a task as done will add the "@done" context tag to the end of the 104 | task, and it will be greyed out by the syntax file. 105 | 106 | To show all tasks with a particular context tag, type `\ts` and a tag name to 107 | search. If you use the `\ts` command over the desired context tag, the tag 108 | name is set as default value. This will fold all the irrelevant tasks leaving 109 | only the tasks in the current context visible. 110 | 111 | To fold all top-level projects leaving only the headings visible use the `\tp` 112 | command. Standard fold commands can be used to open (`zo`) and close (`zc`) 113 | individual projects. 114 | 115 | To show all projects and tasks use the `zR` command. This disables folding so 116 | that the entire file is expanded. 117 | 118 | To go to next or previous project use the `\tj` command or `\tk` command. To 119 | go to a project you specify use the `\tg` command. You can complete project 120 | names with on prompt. 121 | 122 | Configuration 123 | ============== 124 | *taskpaper-config* 125 | 126 | The plugin supports a number of configuration variables, which can be set in 127 | your .vimrc file. 128 | 129 | To change the default date format string used when marking a task complete, 130 | define the `task_paper_date_format` variable. The format matches your system's 131 | `strftime()` function. 132 | 133 | For example, to include the date and time in ISO8601 format: 134 | 135 | let g:task_paper_date_format = "%Y-%m-%dT%H:%M:%S%z" 136 | 137 | To change the default archive project name, define the 138 | `task_paper_archive_project` variable. The default value is "Archive". 139 | 140 | let g:task_paper_archive_project = "Archive" 141 | 142 | By default, when you move a task, the cursor will follow that task to its new 143 | location. To make the cursor stay in it's current location, change the 144 | `task_paper_follow_move` variable. 145 | 146 | let g:task_paper_follow_move = 0 147 | 148 | If you want to hide done tasks when searching you can change the 149 | `task_paper_search_hide_done` variable. 150 | 151 | let g:task_paper_search_hide_done = 1 152 | 153 | To set a custom style (colour, bold, etc.) for tags task_paper_styles variable, 154 | which is a dictionary. 155 | 156 | let g:task_paper_styles={'wait': 'ctermfg=Blue guifg=Blue', 'FAIL': 157 | 'ctermbg=Red guibg=Red'} 158 | 159 | See |highlight-args| for a full description of the syntax. 160 | 161 | 162 | File-type Detection 163 | ==================== 164 | 165 | This package also contains a script to automatically use the TaskPaper file 166 | type for all files with the ".taskpaper" extension. 167 | 168 | Customize 169 | ========== 170 | *taskpaper-customize* 171 | 172 | You can create your own shortcut for tagging. To define your own shortcut, 173 | write settings in ~/.vim/ftplugin/taskpaper.vim or ~/.vimrc. If you use the 174 | .vimrc file, define settings like: 175 | 176 | function! s:taskpaper_setup() 177 | " Your settings 178 | nnoremap tn 179 | \ :call taskpaper#toggle_tag('next', '') 180 | endfunction 181 | 182 | augroup vimrc-taskpaper 183 | autocmd! 184 | autocmd FileType taskpaper call s:taskpaper_setup() 185 | augroup END 186 | 187 | To add a tag without argument: 188 | 189 | nnoremap tn 190 | \ :call taskpaper#add_tag('next', '') 191 | 192 | To delete a tag: 193 | 194 | nnoremap tN 195 | \ :call taskpaper#delete_tag('next', '') 196 | 197 | To toggle a tag: 198 | 199 | nnoremap tn 200 | \ :call taskpaper#toggle_tag('next', '') 201 | 202 | To add a tag with an argument: 203 | 204 | nnoremap tq 205 | \ :call taskpaper#add_tag('priority') 206 | 207 | You can specify the priority value on prompt. 208 | 209 | To delete the priority tag with any argument: 210 | 211 | nnoremap tQ 212 | \ :call taskpaper#delete_tag('priority', '') 213 | 214 | To delete only the level 1 of priority tag: 215 | 216 | nnoremap tQ 217 | \ :call taskpaper#delete_tag('priority', '1') 218 | 219 | To toggle a tag with an argument: 220 | 221 | nnoremap tq 222 | \ :call taskpaper#toggle_tag('priority') 223 | 224 | To update a tag (not delete if the tag exists): 225 | 226 | nnoremap tq 227 | \ :call taskpaper#update_tag('priority') 228 | 229 | Licence 230 | ======== 231 | *taskpaper-licence* 232 | 233 | Copyright (C) 2007--2012 by David O'Callaghan 234 | 235 | This program is free software; you can redistribute it and/or modify 236 | it under the terms of the GNU General Public License as published by 237 | the Free Software Foundation; either version 2 of the License, or 238 | (at your option) any later version. 239 | 240 | This program is distributed in the hope that it will be useful, 241 | but WITHOUT ANY WARRANTY; without even the implied warranty of 242 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 243 | GNU General Public License for more details. 244 | 245 | You should have received a copy of the GNU General Public License 246 | along with this program; if not, write to the Free Software 247 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 248 | 249 | Acknowledgements 250 | ================= 251 | 252 | The initial version of the ToggleDone() function was based on SwitchBox() 253 | from the VimOutliner Checkboxes script written by Noel Henson (available 254 | from ). 255 | 256 | Context folding expression was based on a snippet from Vim Tip 282 257 | (). 258 | 259 | Thanks are due to a number of contributors who have supplied suggestions 260 | or patches to improve TaskPaper.vim: 261 | 262 | * Alexander Wodniok 263 | - hint to allow this file to be used as a help file 264 | * Ben Armstron 265 | - various fixes that make the scripts more robust 266 | - fix to show only complete tag matches 267 | - include `_` in contexts 268 | * Huahai Yang 269 | - fixed handling of indented tasks 270 | * Steve Audette 271 | - suggested change to folding 272 | * Andreas Kühntopf 273 | - display non-tasks as comments 274 | * Julien Blanchard (https://github.com/julienXX) 275 | - added ToggleCancelled 276 | * Robert James Kaes (https://github.com/rjkaes) 277 | - added task_paper_date_format 278 | * Adriano Castro (https://github.com/adrianocastro) 279 | - use tabs not spaces (noexpandtab) 280 | * Morgan Sutherland (https://github.com/msutherl) 281 | - Use rather than 282 | - Start new task after 283 | * Matt Sacks (https://github.com/mattsa) 284 | - Optional (date) syntax for @done tasks 285 | - Add Tag command for add/removing tag 286 | - Fix lagging space after removing a tag 287 | - Better syntax 288 | * Anyakichi (https://github.com/anyakichi) 289 | - Add useful functions for users to define his own mappings easily 290 | - Add, delete, toggle, and update tags 291 | - Go previous or next project 292 | - Move projects, tasks and notes to another project 293 | - Search for keywords or tags with regexp 294 | - More compatible with HogBaySoftware's TaskPaper 295 | - Tag to projects and notes not only tasks 296 | - Shortcut to @today tag 297 | - Archiving done support 298 | - Multi-level folding of projects work perfectly 299 | - Add a new feature to fold only notes 300 | 301 | 302 | 303 | Contact 304 | ======== 305 | 306 | The author of these Vim scripts is David O'Callaghan 307 | . 308 | 309 | For all information regarding the TaskPaper application itself please visit 310 | . 311 | -------------------------------------------------------------------------------- /autoload/taskpaper.vim: -------------------------------------------------------------------------------- 1 | " plugin to handle the TaskPaper to-do list format 2 | " Language: Taskpaper (http://hogbaysoftware.com/projects/taskpaper) 3 | " Maintainer: David O'Callaghan 4 | " URL: https://github.com/davidoc/taskpaper.vim 5 | " Last Change: 2012-03-07 6 | 7 | let s:save_cpo = &cpo 8 | set cpo&vim 9 | 10 | function! s:add_delete_tag(tag, value, add) 11 | let cur_line = getline(".") 12 | 13 | let tag = " @" . a:tag 14 | if a:value != '' 15 | let tag .= "(" . a:value . ")" 16 | endif 17 | 18 | " Add tag 19 | if a:add 20 | let new_line = cur_line . tag 21 | call setline(".", new_line) 22 | return 1 23 | endif 24 | 25 | " Delete tag 26 | if cur_line =~# '\V' . tag 27 | if a:value != '' 28 | let new_line = substitute(cur_line, '\V' . tag, "", "g") 29 | else 30 | let new_line = substitute(cur_line, '\V' . tag . '\v(\([^)]*\))?', 31 | \ "", "g") 32 | endif 33 | 34 | call setline(".", new_line) 35 | return 1 36 | endif 37 | return 0 38 | endfunction 39 | 40 | function! taskpaper#add_tag(tag, ...) 41 | let value = a:0 > 0 ? a:1 : input('Value: ') 42 | return s:add_delete_tag(a:tag, value, 1) 43 | endfunction 44 | 45 | function! taskpaper#delete_tag(tag, ...) 46 | let value = a:0 > 0 ? a:1 : '' 47 | return s:add_delete_tag(a:tag, value, 0) 48 | endfunction 49 | 50 | function! taskpaper#swap_tag(oldtag, newtag) 51 | call taskpaper#delete_tag(a:oldtag) 52 | call taskpaper#add_tag(a:newtag, '') 53 | endfunction 54 | 55 | function! taskpaper#swap_tags(oldtags, newtags) 56 | for oldtag in a:oldtags 57 | call taskpaper#delete_tag(oldtag) 58 | endfor 59 | for newtag in a:newtags 60 | call taskpaper#add_tag(newtag, '') 61 | endfor 62 | endfunction 63 | 64 | function! taskpaper#toggle_tag(tag, ...) 65 | if !taskpaper#delete_tag(a:tag, '') 66 | let args = a:0 > 0 ? [a:tag, a:1] : [a:tag] 67 | call call("taskpaper#add_tag", args) 68 | endif 69 | endfunction 70 | 71 | function! taskpaper#has_tag(tag) 72 | let cur_line = getline(".") 73 | let m = matchstr(cur_line, '@'.a:tag) 74 | if m != '' 75 | return 1 76 | else 77 | return 0 78 | endfunction 79 | 80 | function! taskpaper#cycle_tags(...) 81 | let tags_index = 0 82 | let tag_list = a:000 83 | let tag_added = 0 84 | for tag_name in tag_list 85 | let tags_index = tags_index + 1 86 | if tags_index == len(tag_list) 87 | let tags_index = 0 88 | endif 89 | let has_tag = taskpaper#has_tag(tag_name) 90 | if has_tag == 1 91 | let tag_added = 1 92 | call taskpaper#delete_tag(tag_name) 93 | let new_tag = tag_list[tags_index] 94 | if new_tag != '' 95 | call taskpaper#add_tag(new_tag, '') 96 | endif 97 | break 98 | endif 99 | endfor 100 | if tag_added == 0 101 | call taskpaper#add_tag(tag_list[0], '') 102 | endif 103 | endfunction 104 | 105 | function! taskpaper#update_tag(tag, ...) 106 | call taskpaper#delete_tag(a:tag, '') 107 | let args = a:0 > 0 ? [a:tag, a:1] : [a:tag] 108 | call call("taskpaper#add_tag", args) 109 | endfunction 110 | 111 | function! taskpaper#date() 112 | return strftime(g:task_paper_date_format, localtime()) 113 | endfunction 114 | 115 | function! taskpaper#complete_project(lead, cmdline, pos) 116 | let lnum = 1 117 | let list = [] 118 | let stack = [''] 119 | let depth = 0 120 | 121 | while lnum <= line('$') 122 | let line = getline(lnum) 123 | let ml = matchlist(line, '\v\C^\t*(.+):(\s+\@[^ \t(]+(\([^)]*\))?)*$') 124 | 125 | if !empty(ml) 126 | let d = len(matchstr(line, '^\t*')) 127 | 128 | while d < depth 129 | call remove(stack, -1) 130 | let depth -= 1 131 | endwhile 132 | 133 | while d > depth 134 | call add(stack, '') 135 | let depth += 1 136 | endwhile 137 | 138 | let stack[d] = ml[1] 139 | 140 | let candidate = join(stack, ':') 141 | if candidate =~ '^' . a:lead 142 | call add(list, join(stack, ':')) 143 | endif 144 | endif 145 | 146 | let lnum += 1 147 | endwhile 148 | 149 | return list 150 | endfunction 151 | 152 | function! taskpaper#go_to_project() 153 | let res = input('Project: ', '', 'customlist,taskpaper#complete_project') 154 | 155 | if res != '' 156 | call taskpaper#search_project(split(res, ':')) 157 | endif 158 | endfunction 159 | 160 | function! taskpaper#next_project() 161 | return search('^\t*\zs.\+:\(\s\+@[^\s(]\+\(([^)]*)\)\?\)*$', 'w') 162 | endfunction 163 | 164 | function! taskpaper#previous_project() 165 | return search('^\t*\zs.\+:\(\s\+@[^\s(]\+\(([^)]*)\)\?\)*$', 'bw') 166 | endfunction 167 | 168 | function! s:search_project(project, depth, begin, end) 169 | call cursor(a:begin, 1) 170 | return search('\v^\t{' . a:depth . '}\V' . a:project . ':', 'c', a:end) 171 | endfunction 172 | 173 | function! taskpaper#search_project(projects) 174 | if empty(a:projects) 175 | return 0 176 | endif 177 | 178 | let save_pos = getpos('.') 179 | 180 | let begin = 1 181 | let end = line('$') 182 | let depth = 0 183 | 184 | for project in a:projects 185 | if !s:search_project(project, depth, begin, end) 186 | call setpos('.', save_pos) 187 | return 0 188 | endif 189 | 190 | let begin = line('.') 191 | let end = taskpaper#search_end_of_item(begin) 192 | let depth += 1 193 | endfor 194 | 195 | call cursor(begin, 1) 196 | normal! ^ 197 | 198 | return begin 199 | endfunction 200 | 201 | function! taskpaper#search_end_of_item(...) 202 | let lnum = a:0 > 0 ? a:1 : line('.') 203 | let flags = a:0 > 1 ? a:2 : '' 204 | 205 | let depth = len(matchstr(getline(lnum), '^\t*')) 206 | 207 | let end = lnum 208 | let lnum += 1 209 | while lnum <= line('$') 210 | let line = getline(lnum) 211 | 212 | if line =~ '^\s*$' 213 | " Do nothing 214 | elseif depth < len(matchstr(line, '^\t*')) 215 | let end = lnum 216 | else 217 | break 218 | endif 219 | 220 | let lnum += 1 221 | endwhile 222 | 223 | if flags !~# 'n' 224 | call cursor(end, 0) 225 | normal! ^ 226 | endif 227 | 228 | return end 229 | endfunction 230 | 231 | function! taskpaper#delete(...) 232 | let start = a:0 > 0 ? a:1 : line('.') 233 | let reg = a:0 > 1 ? a:2 : '"' 234 | let kill_indent = a:0 > 2 ? a:3 : 0 235 | 236 | let reg_save = '' 237 | if kill_indent && reg =~# '\u' 238 | let reg = tolower(reg) 239 | let reg_save = getreg(reg) 240 | endif 241 | 242 | let save_fen = &l:foldenable 243 | setlocal nofoldenable 244 | 245 | let depth = len(matchstr(getline(start), '^\t*')) 246 | 247 | let end = taskpaper#search_end_of_item(start) 248 | silent execute start . ',' . end . 'delete ' . reg 249 | 250 | let &l:foldenable = save_fen 251 | 252 | if kill_indent 253 | let pat = '\(^\|\n\)\t\{' . depth . '\}' 254 | let content = substitute(getreg(reg), pat, '\1', 'g') 255 | if reg_save != '' 256 | let content = reg_save . content 257 | endif 258 | call setreg(reg, content) 259 | endif 260 | 261 | return end - start + 1 262 | endfunction 263 | 264 | function! taskpaper#put(...) 265 | let projects = a:0 > 0 ? a:1 : [] 266 | let reg = a:0 > 1 ? a:2 : '"' 267 | let indent = a:0 > 2 ? a:3 : 0 268 | 269 | let save_fen = &l:foldenable 270 | setlocal nofoldenable 271 | 272 | if !empty(projects) && !taskpaper#search_project(projects) 273 | let &l:foldenable = save_fen 274 | return 0 275 | endif 276 | 277 | if indent > 0 278 | let project_depth = len(matchstr(getline('.'), '^\t*')) 279 | let tabs = repeat("\t", project_depth + indent) 280 | else 281 | let tabs = '' 282 | endif 283 | 284 | execute 'put' reg 285 | silent execute "'[,']" . 's/^\ze./' . tabs 286 | 287 | let &l:foldenable = save_fen 288 | 289 | return line("']") - line("'[") + 1 290 | endfunction 291 | 292 | function! taskpaper#move(projects, ...) 293 | let lnum = a:0 > 0 ? a:1 : line('.') 294 | 295 | let save_fen = &l:foldenable 296 | setlocal nofoldenable 297 | 298 | if !taskpaper#search_project(a:projects) 299 | let &l:foldenable = save_fen 300 | return 0 301 | endif 302 | 303 | let reg = 'a' 304 | let save_reg = [getreg(reg), getregtype(reg)] 305 | 306 | let nlines = taskpaper#delete(lnum, reg, 1) 307 | call taskpaper#put(a:projects, reg, 1) 308 | 309 | let &l:foldenable = save_fen 310 | call setreg(reg, save_reg[0], save_reg[1]) 311 | if g:task_paper_follow_move == 0 312 | execute lnum 313 | endif 314 | return nlines 315 | endfunction 316 | 317 | function! taskpaper#move_to_project() 318 | let res = input('Project: ', '', 'customlist,taskpaper#complete_project') 319 | call taskpaper#move(split(res, ':')) 320 | endfunction 321 | 322 | function! taskpaper#update_project() 323 | let indent = matchstr(getline("."), '^\t*') 324 | let depth = len(indent) 325 | 326 | let projects = [] 327 | 328 | for linenr in range(line('.'), 1, -1) 329 | let line = getline(linenr) 330 | let ml = matchlist(line, '\v^\t{0,' . depth . '}([^\t:]+):') 331 | if empty(ml) 332 | continue 333 | endif 334 | 335 | let project = ml[1] 336 | if project != "" 337 | call add(projects, project) 338 | 339 | let indent = matchstr(line, '^\t*') 340 | let depth = len(indent) - 1 341 | 342 | if depth < 0 343 | break 344 | endif 345 | endif 346 | endfor 347 | 348 | call taskpaper#update_tag('project', join(reverse(projects), ' / ')) 349 | endfunction 350 | 351 | function! taskpaper#archive_done() 352 | let oldView = winsaveview() 353 | let archive_start = search('^' . g:task_paper_archive_project . ':', 'cw') 354 | if archive_start == 0 355 | call append('$', g:task_paper_archive_project . ':') 356 | let archive_start = line('$') 357 | let archive_end = 0 358 | else 359 | let archive_end = search('^\S\+:', 'W') 360 | endif 361 | 362 | let save_fen = &l:foldenable 363 | let save_reg = [getreg('a'), getregtype('a')] 364 | setlocal nofoldenable 365 | call setreg('a', '') 366 | 367 | call cursor(1, 1) 368 | let deleted = 0 369 | 370 | while 1 371 | let lnum = search('@done', 'W', archive_start - deleted) 372 | if lnum == 0 373 | break 374 | endif 375 | 376 | call taskpaper#update_project() 377 | let deleted += taskpaper#delete(lnum, 'A', 1) 378 | endwhile 379 | 380 | if archive_end != 0 381 | call cursor(archive_end, 1) 382 | 383 | while 1 384 | let lnum = search('@done', 'W') 385 | if lnum == 0 386 | break 387 | endif 388 | 389 | call taskpaper#update_project() 390 | let deleted += taskpaper#delete(lnum, 'A', 1) 391 | endwhile 392 | endif 393 | 394 | if deleted != 0 395 | call taskpaper#put([g:task_paper_archive_project], 'a', 1) 396 | else 397 | echo 'No done items.' 398 | endif 399 | 400 | let &l:foldenable = save_fen 401 | call setreg('a', save_reg[0], save_reg[1]) 402 | 403 | call winrestview(oldView) 404 | 405 | return deleted 406 | endfunction 407 | 408 | function! taskpaper#fold(lnum, pat, ipat) 409 | let line = getline(a:lnum) 410 | let level = foldlevel(a:lnum) 411 | 412 | if line =~? a:pat && (a:ipat == '' || line !~? a:ipat) 413 | return 0 414 | elseif synIDattr(synID(a:lnum, 1, 1), "name") != 'taskpaperProject' 415 | return 1 416 | elseif level != -1 417 | return level 418 | endif 419 | 420 | let depth = len(matchstr(getline(a:lnum), '^\t*')) 421 | 422 | for lnum in range(a:lnum + 1, line('$')) 423 | let line = getline(lnum) 424 | 425 | if depth >= len(matchstr(line, '^\t*')) 426 | break 427 | endif 428 | 429 | if line =~? a:pat && (a:ipat == '' || line !~? a:ipat) 430 | return 0 431 | endif 432 | endfor 433 | return 1 434 | endfunction 435 | 436 | function! taskpaper#search(...) 437 | let pat = a:0 > 0 ? a:1 : input('Search: ') 438 | let ipat = a:0 > 1 ? a:2 : '' 439 | if pat == '' 440 | return 441 | endif 442 | 443 | setlocal foldexpr=taskpaper#fold(v:lnum,pat,ipat) 444 | setlocal foldminlines=0 foldtext='' 445 | setlocal foldmethod=expr foldlevel=0 foldenable 446 | endfunction 447 | 448 | function! taskpaper#fold_except_range(lnum, begin, end) 449 | if a:lnum > a:end 450 | return 1 451 | elseif a:lnum >= a:begin 452 | return 0 453 | elseif synIDattr(synID(a:lnum, 1, 1), "name") != 'taskpaperProject' 454 | return 1 455 | elseif level != -1 456 | return level 457 | endif 458 | 459 | if a:end <= taskpaper#search_end_of_item(a:lnum, 'n') 460 | return 0 461 | endif 462 | 463 | return 1 464 | endfunction 465 | 466 | function! taskpaper#focus_project() 467 | let pos = getpos('.') 468 | 469 | normal! $ 470 | let begin = taskpaper#previous_project() 471 | if begin == 0 472 | call setpos('.', pos) 473 | return 474 | endif 475 | 476 | let end = taskpaper#search_end_of_item(begin, 'n') 477 | 478 | " Go to the top level project 479 | while taskpaper#previous_project() 480 | if getline('.') =~ '^[^\t]' 481 | break 482 | endif 483 | endwhile 484 | 485 | setlocal foldexpr=taskpaper#fold_except_range(v:lnum,begin,end) 486 | setlocal foldminlines=0 foldtext='' 487 | setlocal foldmethod=expr foldlevel=0 foldenable 488 | endfunction 489 | 490 | function! taskpaper#search_tag(...) 491 | if a:0 > 0 492 | let tag = a:1 493 | else 494 | let cword = expand('') 495 | let tag = input('Tag: ', cword =~ '@\k\+' ? cword[1:] : '') 496 | endif 497 | 498 | if tag != '' 499 | let ipat = (g:task_paper_search_hide_done == 1)?'\<@done\>':'' 500 | call taskpaper#search('\<@' . tag . '\>', ipat) 501 | endif 502 | endfunction 503 | 504 | function! taskpaper#_fold_projects(lnum) 505 | if synIDattr(synID(a:lnum, 1, 1), "name") != 'taskpaperProject' 506 | return '=' 507 | endif 508 | 509 | let line = getline(a:lnum) 510 | let depth = len(matchstr(line, '^\t*')) 511 | return '>' . (depth + 1) 512 | endfunction 513 | 514 | function! taskpaper#fold_projects() 515 | setlocal foldexpr=taskpaper#_fold_projects(v:lnum) 516 | setlocal foldminlines=0 foldtext=foldtext() 517 | setlocal foldmethod=expr foldlevel=0 foldenable 518 | endfunction 519 | 520 | function! taskpaper#newline() 521 | let lnum = line('.') 522 | let line = getline('.') 523 | 524 | if lnum == 1 || line !~ '^\s*$' || 525 | \ synIDattr(synID(lnum - 1, 1, 1), "name") != 'taskpaperProject' 526 | return '' 527 | endif 528 | 529 | let pline = getline(lnum - 1) 530 | let depth = len(matchstr(pline, '^\t*')) 531 | call setline(lnum, repeat("\t", depth + 1) . '- ') 532 | 533 | return "\" 534 | endfunction 535 | 536 | 537 | function! taskpaper#tag_style(...) 538 | if a:0 > 0 539 | let tag_name = a:1 540 | endif 541 | 542 | if a:0 > 1 543 | let tag_style = a:2 544 | let tag_style_name = 'taskpaperAutoStyle_' . tag_name 545 | execute 'syn match' tag_style_name '/\s\zs@'.tag_name.'\(([^)]*)\)\?/' 546 | execute 'hi' tag_style_name tag_style 547 | if version < 508 548 | execute 'hi link' tag_style_name tag_style_name 549 | else 550 | execute 'hi def link' tag_style_name tag_style_name 551 | endif 552 | else 553 | echo "No style specified." 554 | return '' 555 | endif 556 | endfunction 557 | 558 | function! taskpaper#tag_style_dict(tsd) 559 | for tag_name in keys(a:tsd) 560 | call taskpaper#tag_style(tag_name,a:tsd[tag_name]) 561 | endfor 562 | endfunction 563 | 564 | let &cpo = s:save_cpo 565 | -------------------------------------------------------------------------------- /doc/taskpaper_licence.txt: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | --------------------------------------------------------------------------------