" Vimball Archiver by Charles E. Campbell, Jr., Ph.D. UseVimball finish autoload/vikitasks.vim [[[1 1766 " @Author: Tom Link (mailto:micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Revision: 2089 scriptencoding utf-8 if !exists('g:loaded_tlib') || g:loaded_tlib < 116 runtime plugin/02tlib.vim if !exists('g:loaded_tlib') || g:loaded_tlib < 116 echoerr 'tlib >= 1.16 is required' finish endif endif if !exists('g:loaded_trag') || g:loaded_trag < 102 runtime plugin/trag.vim if !exists('g:loaded_trag') || g:loaded_trag < 102 echoerr 'trag >= 1.02 is required' finish endif endif " A list of glob patterns (or files) that will be searched for task " lists. " Can be buffer-local. " If you add ! to 'viminfo', this variable will be automatically saved " between editing sessions. " Alternatively, add new items in the *after-directory* in 'runtimepath' " (e.g. ~/vimfiles/after/plugin/vikitasks.vim) TLet g:vikitasks#files = [] " A list of |regexp| patterns for filenames that should not be " scanned. TLet g:vikitasks#files_ignored = ['_archived\.[^.]\+$'] let s:files_ignored = '\%('. join(g:vikitasks#files_ignored, '\|') .'\)' " If true, completely ignore completed tasks. TLet g:vikitasks#ignore_completed_tasks = 1 " If true, obey threshold information (t:YYYY-MM-DD), i.e. don't show " the task before this date. TLet g:vikitasks#use_threshold = 1 " If the value is > 0 and no t: option (see see " |g:vikitasks#use_threshold|) is given for a task, hide tasks whose due " date is more than N days in the future. " " The value will be ignored if |g:vikitasks#use_threshold| is false. TLet g:vikitasks#threshold_days = 90 " If non-false, provide tighter integration with the vim viki plugin. TLet g:vikitasks#sources = { \ 'viki': exists('g:loaded_viki'), \ 'taskpaper': 1, \ 'todotxt': 1 \ } " A dictionary of 'filetype' => source (see |g:vikitasks#sources|). " " By default vikitasks expects todo.txt files to have the filetype " |todotxt| (which is used by the todo.txt plugin found at " https://github.com/davidoc/todo.txt-vim and my own fork at " https://github.com/tomtom/todo.txt-vim-1/). Using this map allows " users to use todo.txt plugins that use the filetype "todo" (e.g. " https://github.com/freitass/todo.txt-vim). TLet g:vikitasks#filetype_map = { \ 'txt': 'viki', \ 'todo': 'todotxt' \ } " Default category/priority when converting tasks without priorities. TLet g:vikitasks#default_priority = 'F' " The viewer for the quickfix list. If empty, use |:TRagcw|. TLet g:vikitasks#qfl_viewer = '' " Item classes that should be included in the list when calling " |:VikiTasks|. " A user-defined value must be set in |vimrc| before the plugin is " loaded. TLet g:vikitasks#rx_categories = 'A-P' " Item levels that should be included in the list when calling " |:VikiTasks|. " A user-defined value must be set in |vimrc| before the plugin is " loaded. TLet g:vikitasks#rx_levels = '1-5' " If non-empty, vikitasks will insert a break line when displaying a " list in the background. TLet g:vikitasks#today = 'DUE' " Cache file name. " By default, use |tlib#cache#Filename()| to determine the file name. TLet g:vikitasks#cache = tlib#cache#Filename('vikitasks', 'files', 1) call add(g:tlib#cache#dont_purge, '[\/]vikitasks[\/]files$') " If true, check whether the mtime of files with cached tasks has " changed and update the info as necessary. TLet g:vikitasks#cache_check_mtime_rx = '.' " Definition of the tasks that should be included in the Alarms list. " Fields: " all_tasks ... If non-null, also display tasks with no due-date " tasks ... Either 'tasks' or 'sometasks' " constraint ... See |:VikiTasks| TLet g:vikitasks#alarms = {'all_tasks': 0, 'tasks': 'sometasks', 'persistent_categories': 'A', 'constraint': 14} " If true, the end-date of date ranges (FROM..TO) is significant. TLet g:vikitasks#use_end_date = 1 " Interpret entries with an unspecified date ("_") as current tasks. TLet g:vikitasks#use_unspecified_dates = 1 " If true, remove unreadable files from the tasks list. TLet g:vikitasks#remove_unreadable_files = 1 " |:execute| a command (as string) after changing a line. " A useful value is |:update|. TLet g:vikitasks#after_change_line_exec = '' " |:execute| a command (as string) after changing a buffer. " A useful value is |:update|. TLet g:vikitasks#after_change_buffer_exec = '' " If true, save _all_ modified buffers via |:wall|, when leaving the " tasks list. TLet g:vikitasks#auto_save = 0 " The parameters for |:TRagcw| when |g:vikitasks#qfl_viewer| is empty. " :read: TLet g:vikitasks#inputlist_params = {...} " :nodoc: TLet g:vikitasks#inputlist_params = { \ 'qfl_short_filename': 1, \ 'index_next_syntax': 'vikitasksItem', \ 'GetBufferLines': function('vikitasks#GetBufferLines'), \ 'on_leave': ['vikitasks#OnLeave'], \ 'scratch': '__VikiTasks__', \ 'key_map': { \ 'default': { \ "\" : {'key': "\", 'agent': 'vikitasks#AgentKeymap', 'key_name': '', 'help': 'Switch to vikitasks keymap'}, \ 24 : {'key': 24, 'agent': 'vikitasks#AgentMarkDone', 'key_name': '', 'help': 'Mark done'}, \ 4 : {'key': 4, 'agent': 'vikitasks#AgentDueDays', 'key_name': '', 'help': 'Mark as due in N days'}, \ 23 : {'key': 23, 'agent': 'vikitasks#AgentDueWeeks', 'key_name': '', 'help': 'Mark as due in N weeks'}, \ 3 : {'key': 3, 'agent': 'vikitasks#AgentItemChangeCategory', 'key_name': '', 'help': 'Change task category'}, \ 14 : {'key': 14, 'agent': 'vikitasks#AgentPaste', 'key_name': '', 'help': 'Paste selected items in a new buffer'}, \ }, \ 'vikitasks': extend(copy(g:tlib#input#keyagents_InputList_s), \ { \ char2nr('x') : {'agent': 'vikitasks#AgentMarkDone', 'key_name': 'x', 'help': 'Mark done'}, \ char2nr('d') : {'agent': 'vikitasks#AgentDueDays', 'key_name': 'd', 'help': 'Mark as due in N days'}, \ char2nr('w') : {'agent': 'vikitasks#AgentDueWeeks', 'key_name': 'w', 'help': 'Mark as due in N weeks'}, \ char2nr('m') : {'agent': 'vikitasks#AgentDueMonths', 'key_name': 'w', 'help': 'Mark as due in N months'}, \ char2nr('c') : {'agent': 'vikitasks#AgentItemChangeCategory', 'key_name': 'c', 'help': 'Change task category'}, \ char2nr('k') : {'agent': 'vikitasks#AgentSelectCategory', 'key_name': 'k', 'help': 'Select tasks of a category'}, \ 'unknown_key': {'agent': 'tlib#agent#Null', 'key_name': 'other keys', 'help': 'ignore key'}, \ } \ ) \ } \ } " \ 'AfterRunCmd': function('vikitasks#ScanCurrentBuffer'), " Mapleader for some vikitasks related maps. TLet g:vikitasks#mapleader = 't' " If true, add a date tag when marking a task done with |vikitasks#ItemMarkDone()|. TLet g:vikitasks#done_add_date = 1 " A vim expression that returns the filename of the archive where " archived tasks should be moved to. TLet g:vikitasks#archive_filename_fmt = '"%s_archived". g:vikiNameSuffix' " A list of strings. The header for newly created task archives. TLet g:vikitasks#archive_header = ['* Archived tasks'] " The date format string (see |strftime()|). TLet g:vikitasks#date_fmt = "%Y-%m-%d" " The archive header format string (see |strftime()|) for archived entries. TLet g:vikitasks#archive_header_fmt = "** " . g:vikitasks#date_fmt " Letters of final categories, i.e. tasks that should not be altered " after assigning them to one of these categories. " " Tasks in these categories will be considered suitable candidates for " automatic archival by |vikitasks#ItemArchiveFinal()|. " " By default the following categories are considered final: " X ... done " Y ... cancelled " Z ... ??? TLet g:vikitasks#final_categories = 'XYZ' " If non-empty, use |:Calendar| as date picker when marking an item as " due in N days. " " NOTE: This experimental feature is disabled by default. Enable it by " setting this variable to, e.g., "Calendar" in your |vimrc| file. TLet g:vikitasks#use_calendar = '' " TLet g:vikitasks#use_calendar = exists(':Calendar') ? 'Calendar' : '' " Define how to format the list when calling |:VikiTasksPaste|. " A dictionary with the fields (default values are marked with "*"): " filename: add*|group|none TLet g:vikitasks#paste = {} TLet g:vikitasks#debug = 0 " If non-null, convert cygwin filenames to windows format. TLet g:vikitasks#convert_cygwin = has('win32unix') && executable('cygpath') let s:tasks_rx = {} function! vikitasks#TasksRx(which_tasks, ...) "{{{3 if a:0 >= 1 if type(a:1) == 4 let filetype = a:1.GetFiletype() else let filetype = a:1 endif else let filetype = 'viki' endif if has_key(get(s:tasks_rx, filetype, {}), a:which_tasks) return s:tasks_rx[filetype][a:which_tasks] else let ftdef = vikitasks#ft#{filetype}#GetInstance() let fmt = ftdef[a:which_tasks .'_rx'] if fmt =~ '%s' let rv = printf(fmt, '.*') else let rv = fmt endif if !has_key(s:tasks_rx, filetype) let s:tasks_rx[filetype] = {} endif let s:tasks_rx[filetype][a:which_tasks] = rv return rv endif endf let g:vikitasks#viki_date_rx = printf('\C^\s*#[A-Z0-9]\+\s\+\zs\(x\?\)\(_\|%s\)\(\.\.\(\(_\|%s\)\)\)\?\ze\s', g:tlib#date#date_rx, g:tlib#date#date_rx) " :nodoc: function! vikitasks#GetArgs(bang, list) "{{{3 let args = {} let args.cached = !a:bang let a0 = get(a:list, 0, '.') let files_idx = 2 " TLogVAR a0 if a0 =~ '^\(t\%[oday]\|c\%[urrent]\|w\%[eek]\|m\%[onth]\|[+-]\?\d\+[dwm]\?\|[.*]\)$' let args.all_tasks = a0 =~ '^[.*]$' let args.tasks = a0 =~ '^[*-]' ? 'tasks' : 'sometasks' let args.constraint = a0 if !empty(a:list) call remove(a:list, 0) let files_idx -= 1 endif else let args.all_tasks = 1 let args.tasks = 'sometasks' let args.constraint = '.' endif let args.rx = s:MakePattern(get(a:list, 0, '.')) let args.files = a:list[files_idx : -1] let args.ignore_completed = g:vikitasks#ignore_completed_tasks " TLogVAR args return args endf function! s:GetTasks(args, use_cached) "{{{3 " TLogVAR a:args, a:use_cached if a:use_cached let qfl = copy(s:GetCachedTasks()) let files = get(a:args, 'files', []) " TLogVAR files if !empty(files) " TLogVAR filter(copy(files), 'v:val =~ ''\CAcademia.txt$''') for file in files let file_rx = vikitasks#Glob2Rx(file) call filter(qfl, '(has_key(v:val, "filename") ? v:val.filename : bufname(v:val.bufnr)) =~ file_rx') endfor endif if !empty(g:vikitasks#cache_check_mtime_rx) let file_defs = s:GetCachedFiles() " TLogVAR file_defs let cfiles = map(filter(copy(qfl), 'has_key(v:val, "filename")'), 's:CanonicFilename(v:val.filename)') let cfiles = tlib#list#Uniq(cfiles, '', 1) " TLogVAR filter(copy(cfiles), 'v:val =~ ''\CAcademia.txt$''') " TLogVAR len(cfiles) if !empty(cfiles) let update = {} let remove = [] " TLogVAR g:vikitasks#cache_check_mtime_rx for cfilename in cfiles " TLogVAR cfilename if cfilename =~ g:vikitasks#cache_check_mtime_rx " TLogVAR cfilename if filereadable(cfilename) let mtime = getftime(cfilename) let cmtime = get(get(file_defs, cfilename, {}), 'mtime', 0) " TLogVAR cfilename, mtime, cmtime " TLogVAR get(file_defs,cfilename,{}) if mtime > cmtime " TLogVAR mtime>cmtime if has_key(file_defs, cfilename) let filetype = file_defs[cfilename].filetype if !has_key(update, cfilename) let update[filetype] = [] endif call add(update[filetype], cfilename) else echom 'VikiTasks: GetTasks: Internal error: No info about' cfilename " echom 'DBG' string(keys(file_defs)) endif endif else call add(remove, cfilename) endif endif endfor " TLogVAR len(update) if !empty(update) " TLogVAR update for [filetype, cfiles] in items(update) let [file_defs, tasks] = s:UpdateFiles(cfiles, filetype) endfor let qfl = copy(tasks) endif if !empty(remove) call s:RemoveFiles(remove) endif endif endif " TLogVAR len(qfl) return qfl else if g:vikitasks#sources.viki && s:GetBufferFiletype() != 'viki' && !viki#HomePage() echoerr "VikiTasks: Not a viki buffer and cannot open the homepage" return endif let files = get(a:args, 'files', []) " TLogVAR 1, files if empty(files) let [files, file_defs] = s:CollectTaskFiles(0) " TLogVAR filter(copy(files), 'v:val =~ ''\= 1 ? a:1 : s:GetCachedFiles() let tasks0 = a:0 >= 2 ? a:2 : s:GetCachedTasks() " TLogVAR len(file_defs0), len(tasks0) let new_file_defs = s:SetTimestamp(a:new_file_defs) " TLogVAR a:new_file_defs, new_file_defs " TLogVAR len(new_file_defs) " TLogVAR keys(new_file_defs)[0 : 20] " TLogVAR map(copy(tasks0), 'v:val.filename')[0 : 20] let file_defs = filter(copy(file_defs0), '!has_key(new_file_defs, v:key )') let tasks = filter(copy(tasks0), '!has_key(new_file_defs, v:val.filename)') " TLogVAR tasks " TLogVAR len(file_defs), len(tasks) let file_defs = extend(file_defs, new_file_defs) let tasks += a:new_tasks " TLogVAR len(file_defs), len(tasks) call s:SaveInfo(file_defs, tasks) return [file_defs, tasks] endf function! s:SetTimestamp(file_defs, ...) "{{{3 let cfilenames = a:0 >= 1 ? a:1 : [] let file_defs = a:file_defs for cfilename in keys(file_defs) if empty(cfilenames) || index(cfilenames, cfilename) != -1 let mtime = getftime(cfilename) let file_defs[cfilename]['mtime'] = mtime endif endfor return file_defs endf let s:did_init_trag = 0 function! s:InitTrag() "{{{3 if !s:did_init_trag for [source, enabled] in items(g:vikitasks#sources) if enabled call vikitasks#ft#{source}#GetInstance() endif endfor let s:did_init_trag = 1 endif endf function! s:ScanFiles(cfiles, ...) "{{{3 let filetype0 = a:0 >= 1 ? a:1 : '' let file_defs = a:0 >= 2 ? a:2 : s:GetCachedFiles() " TLogVAR len(a:cfiles), filetype0 call s:InitTrag() let qfl = trag#Grep('tasks', 1, copy(a:cfiles), filetype0) " TLogVAR len(qfl) " TLogVAR qfl " TLogVAR filter(copy(qfl), 'v:val.text =~ "#D7"') " TLogVAR keys(file_defs) " TLogVAR filter(copy(a:cfiles), 'v:val =~ ''\Ctodo.txt$''') " TLogVAR filter(keys(file_defs), 'v:val =~ ''\Ctodo.txt$''') let new_file_defs = {} for cfilename in a:cfiles " TLogVAR cfilename, has_key(file_defs,cfilename) if has_key(file_defs, cfilename) let new_file_defs[cfilename] = file_defs[cfilename] else let filetype = empty(filetype0) ? s:GetFiletype(cfilename) : filetype0 call s:MaybeRegisterFilename(new_file_defs, cfilename, filetype, '') endif endfor let new_tasks = copy(qfl) " TLogVAR len(file_defs), len(new_file_defs), len(new_tasks) " TLogVAR file_defs " TLogVAR new_file_defs " TLogVAR new_tasks let remove_tasks = [] let ntasks = len(new_tasks) call tlib#progressbar#Init(ntasks, 'VikiTasks: Scan %s', 20) try for i in range(ntasks) " TLogVAR new_tasks[i] let bufnr = get(new_tasks[i], 'bufnr', 0) if bufnr > 0 let cfilename = s:CanonicFilename(fnamemodify(bufname(bufnr), ':p')) call tlib#progressbar#Display(i, ' '. pathshorten(cfilename)) " TLogVAR cfilename let new_tasks[i].filename = cfilename " let filetype = empty(filetype0) ? s:GetFiletype(cfilename) : filetype0 let these_file_defs = has_key(new_file_defs, cfilename) ? new_file_defs : file_defs if has_key(these_file_defs, cfilename) let file_def = these_file_defs[cfilename] let filetype = file_def.filetype " if filetype != 'viki' let new_tasks[i].text = s:ConvertLine(these_file_defs, cfilename, filetype, new_tasks[i].text) " endif if empty(new_tasks[i].text) call add(remove_tasks, i) else call remove(new_tasks[i], 'bufnr') endif else echohl WarningMsg echom 'VikiTasks: Internal error: No filedef for' has_key(new_file_defs, cfilename) has_key(file_defs, cfilename) bufnr string(cfilename) echohl NONE endif endif endfor finally call tlib#progressbar#Restore() endtry " TLogVAR remove_tasks for i in reverse(remove_tasks) call remove(new_tasks, i) endfor " TLogVAR len(new_file_defs), len(new_tasks) return [new_file_defs, new_tasks] endf " :display: vikitasks#Tasks(?{'all_tasks': 0, 'cached': 1, 'files': [], 'constraint': '', 'rx': ''}, ?suspend=0) " If files is non-empty, use these files (glob patterns actually) " instead of those defined in |g:vikitasks#files|. " " suspend must be one of: " -1 ... Don't display a list " 0 ... List takes the focus " 1 ... Current buffer takes the focus function! vikitasks#Tasks(...) "{{{3 TVarArg ['args', {}], ['suspend', 0] " TLogVAR args, suspend let qfl = s:GetTasks(args, get(args, 'cached', 1)) if !empty(qfl) call s:TasksList(qfl, args, suspend) endif endf function! s:ConvertLine(file_defs, cfilename, filetype, line) "{{{3 let ftdef = vikitasks#ft#{a:filetype}#GetInstance() if !empty(a:line) && has_key(ftdef, 'ConvertLine') let ftdef = vikitasks#ft#{a:filetype}#GetInstance() let line = ftdef.ConvertLine(a:line, a:cfilename) if !empty(line) && line =~ vikitasks#TasksRx('tasks', ftdef) if !has_key(a:file_defs, a:cfilename) throw 'VikiTasks: Internal error: No filedef for '. a:cfilename else let mapsource = get(a:file_defs[a:cfilename], 'mapsource', {}) let mapsource[a:line] = line let a:file_defs[a:cfilename].mapsource = mapsource " TLogVAR a:filetype, a:line, line endif endif else let line = a:line endif let line = s:CleanLine(line) return line endf function! s:CleanLine(line) "{{{3 let line = substitute(a:line, '\= 0 call s:View(i, a:suspend) endif endf function! s:DueText() "{{{3 let break = repeat('- ', (&columns - 20 - len(g:vikitasks#today)) / 4) let break = substitute(break, ' $', '', '') let text = join([break, g:vikitasks#today, break]) return text endf function! s:Setqflist(qfl, today) "{{{3 " TLogVAR a:today, len(a:qfl) if !empty(g:vikitasks#today) && len(a:qfl) > 1 && a:today > 1 && a:today <= len(a:qfl) let qfl = insert(a:qfl, {'bufnr': 0, 'text': s:DueText()}, a:today - 1) call setqflist(qfl) else call setqflist(a:qfl) endif endf function! s:FileReadable(filename, cache) "{{{3 let readable = get(a:cache, a:filename, -1) if readable >= 0 return readable else let a:cache[a:filename] = filereadable(a:filename) return a:cache[a:filename] endif endf function! s:FilterTasks(tasks, args) "{{{3 " TLogVAR len(a:tasks), a:args let rx = get(a:args, 'rx', '') if !empty(rx) call filter(a:tasks, 'v:val.text =~ rx') endif if g:vikitasks#remove_unreadable_files let filenames = {} " TLogVAR filter(copy(a:tasks), '!has_key(v:val, "filename")') call filter(a:tasks, 's:FileReadable(v:val.filename, filenames)') endif let ignore_completed = get(a:args, 'ignore_completed', g:vikitasks#ignore_completed_tasks) if ignore_completed call filter(a:tasks, 'empty(get(matchlist(v:val.text, g:vikitasks#viki_date_rx), 1, ""))') endif let which_tasks = get(a:args, 'tasks', 'tasks') " TLogVAR which_tasks if which_tasks == 'sometasks' let rx = vikitasks#TasksRx('sometasks') " TLogVAR rx " TLogVAR len(a:tasks) call filter(a:tasks, 'v:val.text =~ rx') " TLogVAR len(a:tasks) endif if !get(a:args, 'all_tasks', 0) call filter(a:tasks, '!empty(s:GetTaskDueDate(v:val.text, 0, g:vikitasks#use_unspecified_dates, a:args))') " TLogVAR len(a:tasks) let constraint = get(a:args, 'constraint', '.') " TLogVAR constraint if constraint !~ '^[+-]\?\d\+' let future = '' let n = 1 else let [m0, future, n; _] = matchlist(constraint, '^\([+-]\?\)\(\d\+\)') endif let from = empty(future) ? 0 : localtime() let to = 0 if constraint =~ '^t\%[oday]' let from = localtime() let to = from elseif constraint =~ '^c\%[urrent]' let from = 0 let to = localtime() elseif constraint =~ '^m\%[onth]' let to = localtime() + 86400 * 31 elseif constraint == 'w\%[eek]' let to = localtime() + 86400 * 7 elseif constraint =~ '^[+-]\?\d\+[dwm]\?$' let to = localtime() let delta = n * 86400 if constraint =~ 'w$' let delta = delta * 7 elseif constraint =~ 'm$' let delta = delta * 31 endif if constraint =~ '^-' let from -= delta else let to += delta endif else echoerr "vikitasks: Malformed constraint: ". constraint endif " TLogVAR from, to if from != 0 || to != 0 call filter(a:tasks, 's:Select(v:val.text, from, to, a:args)') endif let use_threshold = get(a:args, 'use_threshold', g:vikitasks#use_threshold) if use_threshold let today = strftime(g:vikitasks#date_fmt) if g:vikitasks#threshold_days > 0 let threshold_date = strftime(g:vikitasks#date_fmt, localtime() + g:vikitasks#threshold_days * g:tlib#date#dayshift) else let threshold_date = '' endif call filter(a:tasks, 's:IsThresholdOk(v:val.text, today, threshold_date)') endif endif endf function! s:View(index, suspend) "{{{3 let bufnr = bufnr('%') if empty(g:vikitasks#qfl_viewer) let w = deepcopy(g:vikitasks#inputlist_params) if a:index > 1 let w.initial_index = a:index endif let w.format_data = 'vikitasks#FormatQFLE' let w.set_syntax = 'vikitasks#SetSyntax' let w.dueline = s:DueText() call trag#QuickList(w, a:suspend) else exec g:vikitasks#qfl_viewer endif if a:suspend && bufnr != bufnr('%') let bufwinnr = bufwinnr(bufnr) exec bufwinnr 'wincmd w' endif endf function! vikitasks#SetSyntax() dict "{{{3 syn match TTagedFilesFilenameSep / | / syn match TTagedFilesFilename / | [^|]*$/ contains=TTagedFilesFilenameSep hi def link TTagedFilesFilenameSep Special hi def link TTagedFilesFilename Directory let b:vikiMarkInexistent = 0 runtime syntax/viki.vim if has('conceal') syn match vikitasksDates /\s*\(created\|t\):\d\+-\d\+-\d\+/ contained conceal endif syn match vikitasksItem /#\(T: \+.\{-}\u.\{-}:\|\d*\u\d*\)\s.*$/ contains=vikiContact,vikiTag,@vikiPriorityListTodo,@vikiText,TTagedFilesFilename,vikitasksDates endf function! vikitasks#FormatQFLE(qfe) dict "{{{3 let text = get(a:qfe, "text") let filename = tlib#qfl#QfeFilename(a:qfe) if empty(filename) || text == self.dueline return text else if get(self, 'trag_short_filename', '') let filename = pathshorten(filename) endif return printf("%-". (&co / 2) ."s | %s#%d", text, filename, a:qfe.lnum) endif endf " If the |regexp| PATTERN seems to be a word, |\<| is prepended. " The PATTERN is case-sensitive if it contains an upper-case letter " and if 'smartcase' is true. function! s:MakePattern(pattern) "{{{3 let pattern = a:pattern if empty(pattern) let pattern = '.' elseif pattern != '.' if pattern =~ '^\w' let pattern = '\<'. pattern endif if &smartcase && pattern =~ '\u' let pattern = '\C'. pattern endif endif return pattern endf function! s:GetTaskCategory(task) "{{{3 let c = matchstr(a:task, '^\s*#\d*\zs\u') return c endf function! s:GetTaskDueDate(task, use_end_date, use_unspecified, args) "{{{3 let m = matchlist(a:task, g:vikitasks#viki_date_rx) if a:use_end_date && g:vikitasks#use_end_date let rv = get(m, 4, '') elseif has_key(a:args, 'persistent_categories') && s:GetTaskCategory(a:task) =~ '^['. a:args.persistent_categories .']$' let rv = '_' else let rv = '' endif if empty(rv) let rv = get(m, 2, '') endif if rv == '_' && !a:use_unspecified let rv = '' endif " TLogVAR a:task, m, rv return rv endf function! s:IsThresholdOk(task, today, threshold_date) "{{{3 " TLogVAR a:task, a:today let t = matchstr(a:task, '\ bd ? 1 : -1 else return a == b ? 0 : a > b ? 1 : -1 endif endf function! vikitasks#ResetCachedInfo() "{{{3 let s:file_defs = {} let s:tasks = [] call s:SaveInfo(s:file_defs, s:tasks) endf function! s:GetCachedFiles() "{{{3 if !exists('s:file_defs') let cdata = s:GetInfo() let s:file_defs = get(cdata, 'file_defs', {}) " echom "DBG file_defs" string(s:file_defs) if empty(s:file_defs) let files = get(cdata, 'files', []) for file in files let cfilename = s:CanonicFilename(file) call vikitasks#RegisterFilename(cfilename, s:GetFiletype(cfilename), '') endfor endif call filter(s:file_defs, 'v:key !~# s:files_ignored') endif return s:file_defs endf function! s:GetCachedTasks() "{{{3 if !exists('s:tasks') let s:tasks = get(s:GetInfo(), 'tasks', []) let s:tasks = filter(s:tasks, 'has_key(v:val, "filename")') " echom "DBG ntasks = ". len(s:tasks) endif return s:tasks endf function! s:GetInfo() "{{{3 if !exists('s:cdata') let s:cdata = tlib#cache#Get(g:vikitasks#cache) endif return s:cdata endf function! s:SaveInfo(file_defs, tasks) "{{{3 " TLogVAR len(a:file_defs), len(a:tasks) let s:file_defs = a:file_defs let s:tasks = a:tasks let s:timestamp = localtime() let s:cdata = {'file_defs': a:file_defs, 'tasks': a:tasks, 'timestamp': s:timestamp} call tlib#cache#Save(g:vikitasks#cache, s:cdata) endf function! vikitasks#MustUseCanonicFilename() return !has('fname_case') || g:tlib#dir#sep == '\' endf let s:cygpath = {} function! s:CanonicFilename(filename) "{{{3 if !vikitasks#MustUseCanonicFilename() let filename = a:filename else let filename = a:filename if g:vikitasks#convert_cygwin && filename !~ '^\c[a-z]:' if !has_key(s:cygpath, filename) let s:cygpath[filename] = substitute(system('cygpath -m '. shellescape(filename)), '\n$', '', '') endif let filename = s:cygpath[filename] " TLogVAR a:filename, filename endif if !has('fname_case') let filename = tolower(filename) endif if g:tlib#dir#sep == '\' let filename = substitute(filename, '\\', '/', 'g') endif if filename !~ '^\w\+://' let filename = substitute(filename, '//\+', '/', 'g') endif endif return resolve(filename) endf function! vikitasks#EachSource(fallback, fn, args, params) "{{{3 " Tlibtrace 'vikitasks', a:fn, a:args, a:params let rvs = {} for [source, ok] in items(g:vikitasks#sources) if source != a:fallback " Tlibtrace 'vikitasks', source let ftdef = vikitasks#ft#{source}#GetInstance() let rv = call(ftdef[a:fn], a:args, ftdef) let rvs[source] = rv if has_key(a:params, 'Check') && a:params.Check(rv) " Tlibtrace 'vikitasks', source, rv return [source, rv] endif unlet rv endif endfor " Tlibtrace 'vikitasks', a:fallback let ftdef = vikitasks#ft#{a:fallback}#GetInstance() let rv = call(ftdef[a:fn], a:args, ftdef) let rvs[a:fallback] = rv if has_key(a:params, 'Check') return [a:fallback, rv] else return rvs endif endf let s:find_params = {} function! s:find_params.Check(val) dict return !empty(a:val) endf function! s:GetFileSource(cfilename, filetype) "{{{3 return vikitasks#EachSource(s:TaskSource(a:filetype), 'IsA', [a:filetype, a:cfilename], s:find_params) endf function! s:GetBufferFiletype(...) "{{{3 let bufnr = a:0 >= 1 ? a:1 : bufnr('%') let ft = getbufvar(bufnr, '&filetype') return get(g:vikitasks#filetype_map, ft, ft) endf function! s:GetFiletype(...) "{{{3 let cfilename = a:0 >= 1 ? a:1 : s:CanonicFilename(expand('%:p')) let filetype = a:0 >= 2 ? a:2 : getbufvar(cfilename, '&ft') let on_error = a:0 >= 3 ? a:3 : 0 let [ft, ok] = s:GetFileSource(cfilename, filetype) if !ok if on_error == 2 throw 'VikiTasks: Unsupported filetype: '. filetype elseif on_error == 1 return '' endif endif return ft endf function! s:GetArchiveName(filename, filetype) "{{{3 let cfilename = s:CanonicFilename(a:filename) let [ft, archive] = vikitasks#EachSource(s:TaskSource(a:filetype), 'GetArchiveName', [cfilename], s:find_params) return archive endf function! s:CollectTaskFiles(reset) "{{{3 if a:reset call vikitasks#ResetCachedInfo() endif let file_defs = s:GetCachedFiles() " TLogVAR filter(keys(file_defs), 'v:val =~ ''\Ctodo.txt$''') for [source, ok] in items(g:vikitasks#sources) " TLogVAR source, ok if ok let ftdef = vikitasks#ft#{source}#GetInstance() call ftdef.GetFiles(function('vikitasks#RegisterFilename')) endif endfor let taskfiles = sort(keys(s:file_defs)) " TLogVAR filter(copy(taskfiles), 'v:val =~ ''\Ctodo.txt$''') " TLogVAR taskfiles " TLogVAR len(taskfiles) return [taskfiles, s:file_defs] endf function! vikitasks#UnRegisterFilename(filename) "{{{3 let cfilename = s:CanonicFilename(a:filename) if has_key(s:file_defs, cfilename) call remove(s:file_defs, cfilename) endif endf function! vikitasks#RegisterFilename(dirpattern, filetype, archive, ...) "{{{3 TVarArg 'ignore_rx' " TLogVAR a:dirpattern, a:filetype, a:archive, ignore_rx for filename in tlib#file#Glob(a:dirpattern) if filereadable(filename) && !isdirectory(filename) let cfilename = s:CanonicFilename(filename) if empty(ignore_rx) || filename !~ ignore_rx call s:MaybeRegisterFilename(s:file_defs, cfilename, a:filetype, a:archive) endif " TLogVAR cfilename endif endfor endf function! s:MaybeRegisterFilename(file_defs, cfilename, filetype, archive) "{{{3 " TLogVAR a:cfilename, a:filetype, a:archive " echom 'DBG s:files_ignored' s:files_ignored " if a:cfilename =~ '\Ctodo.txt$' | echom "DBG MaybeRegisterFilename" a:cfilename | endif " DBG if !has_key(a:file_defs, a:cfilename) && a:cfilename !~# s:files_ignored let a:file_defs[a:cfilename] = {'filetype': a:filetype} " TLogVAR a:cfilename, a:filetype, a:archive if !empty(a:archive) let a:file_defs[a:cfilename].archive = a:archive endif return 1 endif return 0 endf function! s:Select(text, from, to, args) "{{{3 let sfrom = strftime(g:vikitasks#date_fmt, a:from) let sto = strftime(g:vikitasks#date_fmt, a:to) let date1 = s:GetTaskDueDate(a:text, 0, g:vikitasks#use_unspecified_dates, a:args) let date2 = s:GetTaskDueDate(a:text, 1, g:vikitasks#use_unspecified_dates, a:args) if date1 == '_' let rv = 1 elseif date1 == date2 let rv = date1 >= sfrom && date1 <= sto else let rv = (date1 >= sfrom && date1 <= sto) || (date2 >= sfrom && date2 <= sto) endif " TLogVAR sfrom, sto, date1, date2, rv return rv endf function! s:TaskSource(filetype) "{{{3 if has_key(g:vikitasks#sources, a:filetype) && g:vikitasks#sources[a:filetype] return a:filetype else return 'viki' endif endf " Register BUFFER as a file that should be scanned for task lists. function! vikitasks#AddBuffer(buffer, ...) "{{{3 if type(a:buffer) == 0 let bufnr = a:buffer let bufname = bufname(bufnr) else let bufname = a:buffer let bufnr = bufnr(bufname) endif let bft = s:GetBufferFiletype(bufnr) TVarArg ['save', 1], ['filetype', bft] " TLogVAR a:buffer, bufnr, bufname, save, filetype let cfilename = s:CanonicFilename(fnamemodify(bufname, ':p')) let file_defs = s:GetCachedFiles() if filereadable(cfilename) && !has_key(file_defs, cfilename) let filetype = s:TaskSource(filetype) call vikitasks#RegisterFilename(cfilename, filetype, '') if save && !vikitasks#ScanCurrentBuffer(cfilename) " TLogVAR len(file_defs) let file_defs = s:SetTimestamp(file_defs, [cfilename]) " TLogVAR len(file_defs) call s:SaveInfo(file_defs, s:GetCachedTasks()) endif endif endf " Unregister BUFFER as a file that should be scanned for task lists. function! vikitasks#RemoveBuffer(buffer, ...) "{{{3 TVarArg ['save', 1] " TLogVAR a:buffer, save let cfilename = s:CanonicFilename(fnamemodify(a:buffer, ':p')) let file_defs = s:GetCachedFiles() if has_key(file_defs, cfilename) let source = s:TaskSource(file_defs[cfilename].filetype) let ftdef = vikitasks#ft#{source}#GetInstance() if has_key(ftdef, 'RemoveFile') call ftdef.RemoveFile(cfilename) endif call vikitasks#UnRegisterFilename(cfilename) " <+TODO+> Are tasks from a:buffer removed? if save && !vikitasks#ScanCurrentBuffer(cfilename) call s:SaveInfo(file_defs, s:GetCachedTasks()) endif endif endf " Edit the list of files. function! vikitasks#EditFiles() "{{{3 let file_defs = s:GetCachedFiles() let cfiles = keys(file_defs) let cfiles1 = tlib#input#EditList('Edit task files:', cfiles) if cfiles != cfiles1 for cfilename in cfiles1 if !has_key(file_defs) let file_defs[cfilename] = s:GetFiletype(cfilename) endif endfor for cfilename in cfiles if index(cfiles1, cfilename) == -1 && has_key(file_defs, cfilename) call remove(file_defs, cfilename) endif endfor call s:SaveInfo(file_defs, s:GetCachedTasks()) call tlib#notify#Echo('Please update your task list by running :VikiTasks!', 'WarningMsg') endif endf " :nodoc: " :display: vikitasks#Alarm(?ddays = -1, ?use_cached = 1) " Display a list of alarms. " If ddays >= 0, the constraint value in |g:vikitasks#alarms| is set to " ddays days. " If ddays is -1 and |g:vikitasks#alarms| is empty, no alarms will be " listed. function! vikitasks#Alarm(...) "{{{3 TVarArg ['ddays', -1], ['use_cached', 1] " TLogVAR ddays if ddays < 0 && empty(g:vikitasks#alarms) return endif let tasks = s:GetTasks({}, use_cached) call sort(tasks, "s:SortTasks") let alarms = copy(g:vikitasks#alarms) if ddays >= 0 let alarms.constraint = ddays endif " TLogVAR alarms call s:FilterTasks(tasks, alarms) if !empty(tasks) " TLogVAR tasks call s:Setqflist(tasks, s:GetCurrentTask(tasks, 0)) call s:View(0, 1) redraw endif endf function! vikitasks#GetBufferLines(from, to) "{{{3 let lines = getline(a:from, a:to) let file_defs = s:GetCachedFiles() let ftdef = s:GetBufferTasksDef() let cfilename = s:CanonicFilename(expand('%:p')) let filetype = ftdef.GetFiletype() let lines = map(lines, 's:ConvertLine(file_defs, cfilename, filetype, v:val)') " call s:SaveInfo(file_defs, tasks) return lines endf " :nodoc: " Scan the current buffer for task lists. function! vikitasks#ScanCurrentBuffer(...) "{{{3 TVarArg ['filename', ''] let use_buffer = empty(filename) if use_buffer let bufnr = bufnr('%') let cfilename = s:CanonicFilename(expand('%:p')) else let bufnr = bufnr(filename) let cfilename = s:CanonicFilename(filename) endif " echom "DBG vikitasks#ScanCurrentBuffer" filename use_buffer bufnr cfilename if getbufvar(bufnr, '&buftype') =~ '\' || (!empty(s:files_ignored) && cfilename =~ s:files_ignored) || !filereadable(cfilename) || isdirectory(cfilename) || empty(cfilename) return 0 endif let [source, ok] = s:GetFileSource(cfilename, s:GetBufferFiletype(bufnr)) " TLogVAR source, ok, cfilename if !ok return 0 endif let file_defs = s:GetCachedFiles() call s:MaybeRegisterFilename(file_defs, cfilename, source, '') " TLogVAR cfilename, use_buffer, has_key(file_defs, cfilename) let tasks0 = s:GetCachedTasks() let ntasks = len(tasks0) " TLogVAR ntasks let tasks = [] let buftasks = {} let ftdef = vikitasks#ft#{source}#GetInstance() for task in tasks0 " TLogVAR task if s:CanonicFilename(task.filename) == cfilename " TLogVAR task.lnum, task if has_key(task, 'text') let buftasks[task.lnum] = task endif else call add(tasks, task) endif unlet task endfor " TLogVAR len(tasks), len(buftasks) let rx = vikitasks#TasksRx('tasks', source) let def = {'inline': 0, 'sometasks': 0, 'letters': 'A-Z', 'levels': '0-9'} let @r = rx let update = 0 let tasks_found = 0 let lnum = 1 " echom "DBG ". string(keys(buftasks)) " TLogVAR keys(buftasks) if use_buffer let lines = getline(1, '$') else let lines = readfile(cfilename) endif " call filter(tasks, 'v:val.filename != cfilename') for line0 in lines let line = s:ConvertLine(file_defs, cfilename, source, line0) if line =~ '^%\s*vikitasks:' let paramss = matchstr(line, '^%\s*vikitasks:\s*\zs.*$') " TLogVAR paramss if paramss =~ '^\s*none\s*$' return else let paramsl = split(paramss, ':') " TLogVAR paramsl call map(paramsl, 'split(v:val, "=", 1)') " TLogVAR paramsl try for [var, val] in paramsl let def[var] = val endfor catch echoerr 'Vikitasks: Malformed vikitasks-mode-line parameters: '. paramss endtry unlet! var val endif let rx = printf(ftdef.TaskLineRx(def.inline, def.sometasks, def.letters, def.levels), '.*') elseif line =~ rx let text = tlib#string#Strip(line) let ltext = get(get(buftasks, lnum, {}), 'text', '') let tasks_found = 1 if ltext != text " echom "DBG ". get(buftasks,lnum,'') let update = 1 " TLogVAR lnum, text call add(tasks, { \ 'filename': cfilename, \ 'lnum': lnum, \ 'text': text \ }) else call add(tasks, buftasks[lnum]) endif endif let lnum += 1 endfor " TLogVAR len(tasks) " TLogVAR update if update call vikitasks#AddBuffer(bufnr, 0, source) let file_defs = s:SetTimestamp(file_defs, [cfilename]) call s:SaveInfo(file_defs, tasks) elseif !tasks_found call vikitasks#RemoveBuffer(cfilename, 0) call s:SaveInfo(file_defs, tasks) endif return update endf " Mark N tasks as done, i.e. assign them to category X -- see also " |g:vikitasks#final_categories|. function! vikitasks#ItemMarkDone(count, ...) "{{{3 let ftdef = a:0 >= 1 ? a:1 : s:GetBufferTasksDef() let rx = vikitasks#TasksRx('tasks', ftdef) " TLogVAR rx let modified = 0 for lnum in range(line('.'), line('.') + a:count) let line = getline(lnum) " TLogVAR lnum, line if line =~ rx && line !~ ftdef.FinalRx() let rline = ftdef.ItemMarkDone(line) " TLogVAR rline if type(rline) == 3 call setline(lnum, rline[0]) call append(lnum, rline[1 : -1]) else call setline(lnum, rline) endif unlet! rline let modified = 1 call s:AfterChange('Line', ftdef, lnum) endif endfor if modified call s:AfterChange('Buffer', ftdef) endif endf " Archive finalized (see |g:vikitasks#final_categories|) tasks. function! vikitasks#ItemArchiveFinal(...) "{{{3 let ftdef = a:0 >= 1 ? a:1 : s:GetBufferTasksDef() let archive_filename = ftdef.GetArchiveName(expand("%:p:r")) if filereadable(archive_filename) let archived = readfile(archive_filename) else let archived = split(ftdef.ArchiveHeader(1), '\n') endif let to_be_archived = [] let clnum = line('.') for lnum in reverse(range(1, line('$'))) let line = getline(lnum) if line =~ ftdef.FinalRx() call insert(to_be_archived, line) if lnum <= clnum norm! k endif exec lnum 'delete' endif endfor if !empty(to_be_archived) let archive_header = ftdef.ArchiveHeader(0) if !empty(archive_header) let archived += split(strftime(archive_header), '\n') endif let archived += map(to_be_archived, 'ftdef.ArchiveItem(v:val)') call writefile(archived, archive_filename) endif endf " Edit a file monitored by vikitasks. function! vikitasks#ListTaskFiles() "{{{3 let file_defs = s:GetCachedFiles() let files = keys(file_defs) let selected = tlib#input#List('m', 'Select files:', files) for file in selected exec 'edit' fnameescape(file) endfor endf " Mark task(s) as due in N days. function! vikitasks#ItemsMarkDueInDays(count, days, ...) "{{{3 let ftdef = a:0 >= 1 ? a:1 : s:GetBufferTasksDef() let duedate = strftime(g:vikitasks#date_fmt, localtime() + a:days * g:tlib#date#dayshift) " Tlibtrace 'vikitasks', a:count, a:days, duedate for lnum in range(line('.'), line('.') + a:count) call vikitasks#LineItemMarkDueInDays(lnum, duedate, ftdef) endfor endf function! s:GetBufferTasksDef() "{{{3 let source = s:GetFiletype() " Tlibtrace 'vikitasks', source let ftdef = vikitasks#ft#{source}#GetInstance() return ftdef endf function! s:AfterChange(type, ftdef, ...) "{{{3 let lnum = a:0 >= 1 ? a:1 : 0 let name = 'AfterChange'. a:type " TLogVAR a:type, a:ftdef, lnum, name if a:type ==# 'Buffer' call s:RegisterChangedBuffer(bufnr('%')) endif if has_key(a:ftdef, name) let pos = getpos('.') try if lnum > 0 exec lnum norm! ^ endif call call(a:ftdef[name], [], a:ftdef) finally call setpos('.', pos) endtry endif endf " :nodoc: function! vikitasks#LineItemMarkDueInDays(lnum, duedate, ...) "{{{3 " Tlibtrace 'vikitasks', a:lnum, a:duedate " TLogVAR bufname('%'), a:lnum, a:duedate let ftdef = a:0 >= 1 ? a:1 : s:GetBufferTasksDef() " TLogVAR ftdef let rx = vikitasks#TasksRx('tasks', ftdef) " TLogVAR rx let line = getline(a:lnum) " TLogVAR line, line=~rx " TLogVAR line =~ rx, line =~ ftdef.DateRx(), line !~ ftdef.FinalRx() " Tlibtrace 'vikitasks', line, rx, line=~ftdef.DateRx(), line!~ftdef.FinalRx() " if line =~ rx && line =~ ftdef.DateRx() && line !~ ftdef.FinalRx() if line =~ rx && line !~ ftdef.FinalRx() let line1 = ftdef.MarkItemDueInDays(line, a:duedate) " Tlibtrace 'vikitasks', line1 call setline(a:lnum, line1) call s:AfterChange('Line', ftdef, a:lnum) call s:AfterChange('Buffer', ftdef) endif endf " Mark task(s) as due in N weeks. function! vikitasks#ItemsMarkDueInWeeks(count, weeks, ...) "{{{3 " Tlibtrace 'vikitasks', a:count, a:weeks let ftdef = a:0 >= 1 ? a:1 : s:GetBufferTasksDef() call vikitasks#ItemsMarkDueInDays(a:count, a:weeks * 7, ftdef) endf " Mark task(s) as due in N months, " NOTE: A "month" means 30 days. function! vikitasks#ItemsMarkDueInMonths(count, months, ...) "{{{3 " Tlibtrace 'vikitasks', a:count, a:months let ftdef = a:0 >= 1 ? a:1 : s:GetBufferTasksDef() call vikitasks#ItemsMarkDueInDays(a:count, a:months * 30, ftdef) endf " Change the category for the current and the next a:count tasks. function! vikitasks#ItemChangeCategory(count, ...) "{{{3 if a:0 >= 1 && !empty(a:1) let category = a:1 else call inputsave() let category = input('New task category [A-Z]: ') call inputrestore() endif let ftdef = a:0 >= 2 ? a:2 : s:GetBufferTasksDef() let category = toupper(category) if category =~ '\C^[A-Z]$' let rx = vikitasks#TasksRx('tasks', ftdef) " TLogVAR rx let modified = 0 for lnum in range(line('.'), line('.') + a:count) let line = getline(lnum) " TLogVAR lnum, line if line =~ rx let line = ftdef.ChangeCategory(line, category) " TLogVAR line call setline(lnum, line) let modified = 1 call s:AfterChange('Line', ftdef, lnum) endif endfor if modified call s:AfterChange('Buffer', ftdef) endif else echohl WarningMsg echom 'Invalid category (must be A-Z):' category echohl NONE endif endf " :nodoc: function! vikitasks#AgentItemChangeCategory(world, selected) "{{{3 call inputsave() let category = toupper(input('New task category [A-Z]: ')) call inputrestore() if category =~ '\C^[A-Z]$' return tlib#qfl#AgentWithSelected(a:world, a:selected, 'call vikitasks#ItemChangeCategory(0,'. string(category) .')') else echohl WarningMsg echom 'Invalid category (must be A-Z):' category echohl NONE let a:world.state = 'redisplay' return a:world endif endf " :nodoc: function! vikitasks#AgentSelectCategory(world, selected) "{{{3 call inputsave() let category = toupper(input('New task category [A-Z]: ')) call inputrestore() if category =~ '\C^[A-Z]$' call a:world.SetFrontFilter('\^\C#'. category) " call inputdialog(string(a:world.filter)) let a:world.state = 'display' return a:world else echohl WarningMsg echom 'Invalid category (must be A-Z):' category echohl NONE let a:world.state = 'redisplay' return a:world endif endf " :nodoc: function! vikitasks#AgentKeymap(world, selected) "{{{3 let a:world.key_mode = 'vikitasks' let a:world.state = 'display' return a:world endf " :nodoc: function! vikitasks#AgentMarkDone(world, selected) "{{{3 return tlib#qfl#AgentWithSelected(a:world, a:selected, 'VikiTasksDone') endf " :nodoc: function! vikitasks#AgentDueDays(world, selected) "{{{3 if !empty(g:vikitasks#use_calendar) let s:calendar_action = exists('g:calendar_action') ? g:calendar_action : "CalendarDiary" let s:calendar_callback_window = winnr() let s:calendar_callback_buffer = winbufnr(0) let s:calendar_callback_world = a:world let s:calendar_callback_selected = a:selected let g:calendar_action = 'vikitasks#CalendarCallback' exec g:vikitasks#use_calendar let s:calendar_window = winnr() let s:calendar_buffer = winbufnr(0) let world = tlib#agent#Suspend(a:world, a:selected) exec s:calendar_window 'wincmd w' return world else call inputsave() let val = input("Number of days: ", 1) call inputrestore() if empty(val) let a:world.state = 'redisplay' return a:world else return tlib#qfl#AgentWithSelected(a:world, a:selected, 'VikiTasksDueInDays '. val) endif endif endf " :nodoc: function! vikitasks#CalendarCallback(day, month, year, week, dir) "{{{3 " TLogVAR a:day, a:month, a:year, a:week, a:dir if winbufnr(s:calendar_window) == s:calendar_buffer silent! exec s:calendar_window 'wincmd c' endif let g:calendar_action = s:calendar_action let duedate = printf('%4d-%02d-%02d', a:year, a:month, a:day) " TLogVAR duedate let world = trag#RunCmdOnSelected(s:calendar_callback_world, s:calendar_callback_selected, \ printf('call vikitasks#LineItemMarkDueInDays(line("."), %s)', string(duedate)), 0) " TLogVAR world.state call setbufvar(s:calendar_callback_buffer, 'tlib_world', world) exec s:calendar_callback_window 'wincmd w' endf " :nodoc: function! vikitasks#AgentDueWeeks(world, selected) "{{{3 call inputsave() let val = input("Number of weeks: ", 1) call inputrestore() if empty(val) let a:world.state = 'redisplay' return a:world else return tlib#qfl#AgentWithSelected(a:world, a:selected, 'VikiTasksDueInWeeks '. val) endif endf " :nodoc: function! vikitasks#AgentDueMonths(world, selected) "{{{3 call inputsave() let val = input("Number of months: ", 1) call inputrestore() if empty(val) let a:world.state = 'redisplay' return a:world else return tlib#qfl#AgentWithSelected(a:world, a:selected, 'VikiTasksDueInMonths '. val) endif endf " :nodoc: function! s:Paste(newbuffer, qfl) "{{{3 let mode_filename = get(g:vikitasks#paste, 'filename', 'add') let lines = [] if mode_filename == 'group' let due = s:DueText() let qfld = {} for item in a:qfl if item.text != due let bufname = fnamemodify(bufname(item.bufnr), ':p') if !has_key(qfld, bufname) let qfld[bufname] = [] endif call add(qfld[bufname], item) endif endfor else let qfld = {'*': a:qfl} endif for key in sort(keys(qfld)) if key != '*' call add(lines, s:FormatPasteLink(key, 0)) endif for item in qfld[key] " TLogVAR item let bufname = fnamemodify(bufname(item.bufnr), ':p') if mode_filename == 'group' call add(lines, repeat(' ', &sw) . item.text) elseif mode_filename == 'add' call add(lines, ' '. item.text .' ' . s:FormatPasteLink(bufname, 1)) endif endfor if key != '*' call add(lines, '') endif endfor silent! colder " TLogVAR lines if !empty(a:newbuffer) let name = substitute(a:newbuffer, '[[:space:]\/*&<>]', '_', 'g') . g:vikiNameSuffix exec 'split' name setf viki endif call append(line('.'), lines) if a:newbuffer 0delete endif endf function! vikitasks#AgentPaste(world, selected) "{{{3 if empty(a:selected) call a:world.RestoreOrigin() else call a:world.RestoreOrigin() let qfl = [] let max = len(a:world.qfl) for idx in a:selected let idx -= 1 if idx >= 0 && idx <= max let qfe = a:world.qfl[idx] call add(qfl, qfe) endif endfor call s:Paste(a:world.DisplayFilter(), qfl) endif let a:world.state = "exit" return a:world endf " :nodoc: function! vikitasks#Paste(newbuffer, args) "{{{3 call vikitasks#Tasks(a:args, -1) call s:Paste(newbuffer, getqflist()) endf function! s:FormatPasteLink(fname, inpars) "{{{3 if has('conceal') let fmt = a:inpars ? '([[%s][%s]])' : '[[%s][%s]]' let link = printf(fmt, a:fname, fnamemodify(a:fname, ':t')) else let link = printf('[[%s]]', a:fname) endif return link endf function! vikitasks#Glob2Rx(pattern) "{{{3 " let rx = escape(a:pattern, '\') let rx = substitute(a:pattern, '[\/]', '\\[\\/]', 'g') let rx = substitute(rx, '\*\*', '\\.\\{-}', 'g') let rx = substitute(rx, '\*', '\\[^\\/]\\*', 'g') let rx = substitute(rx, '?', '\\.\\?', 'g') if has('fname_case') let rx = '\C'. rx endif return '\V'. rx endf function! s:RegisterChangedBuffer(bufnr) "{{{3 if !exists('s:changed_buffers') let s:changed_buffers = {} endif let s:changed_buffers[a:bufnr] = 1 endf function! vikitasks#OnLeave(w) "{{{3 " TLogVAR g:vikitasks#auto_save if g:vikitasks#auto_save if exists('s:changed_buffers') let bn = bufnr('%') try for b in keys(s:changed_buffers) exec 'hide buffer' b update call vikitasks#ScanCurrentBuffer() endfor finally exec 'hide buffer' bn endtry unlet s:changed_buffers " wall endif endif endf plugin/vikitasks.vim [[[1 169 " @Author: Tom Link (micathom AT gmail com?subject=[vim]) " @Website: http://www.vim.org/account/profile.php?user_id=4037 " @GIT: http://github.com/tomtom/vikitasks_vim/ " @License: GPL (see http://www.gnu.org/licenses/gpl.txt) " @Created: 2009-12-15. " @Last Change: 2015-11-03. " @Revision: 336 " GetLatestVimScripts: 2894 0 :AutoInstall: vikitasks.vim " Search for task lists and display them in a list scriptencoding utf-8 if &cp || exists("g:loaded_vikitasks") finish endif let g:loaded_vikitasks = 102 let s:save_cpo = &cpo set cpo&vim " An expression that determines whether to show alarms on pending tasks " on startup. " If the expression evaluates to 0, don't display alarms for pending " tasks. " If it evaluates to a value > 0, display alarms for pending tasks or " tasks with a deadline in n days. " " Possibly useful values (for your |vimrc|) are: > " " let g:vikitasks_startup_alarms = "(!has('clientserver') || len(split(serverlist(), '\n')) <= 1) && argc() == 0" " let g:vikitasks_startup_alarms = has('clientserver') && v:servername == 'GVIM' " " This will display alarms when running the first instance of gvim " without arguments. TLet g:vikitasks_startup_alarms = 0 " Scan a buffer on these events. TLet g:vikitasks_scan_events = 'BufWritePost,BufWinEnter' " A list of filename patterns (see 'wildcards') for files that should " automatically on events specified in |g:vikitasks_scan_events|. TLet g:vikitasks_scan_patterns = ['*.txt', '*.viki'] " :display: :VikiTasks[!] [CONSTRAINT] [PATTERN] [FILE_PATTERNS] " CONSTRAINT constrains which tasks should be displayed. Possible values " are: " " today ... Show tasks that are due today " current ... Show today's tasks and pending tasks " NUMBER (of days) ... Show tasks that are due within N days " Nd ... Tasks for the next N days " Nw ... Tasks for the next N weeks (i.e. 7 days) " Nm ... Tasks for the next N months (i.e. 31 days) " week ... Tasks for the next week (i.e. 7 days) " month ... Tasks for the next month (i.e. 31 days) " . ... Show some tasks (see |g:vikitasks#rx_categories| " and |g:vikitasks#rx_levels|) " * ... Show all tasks " " The default value for CONSTRAINT is ".". " " Prepend + to N (e.g. "+2w") to hide tasks with a deadline in the past. " " Prepend - to N (e.g. "-2w") to show only tasks with a deadline in " the past (in this example in the last two weeks). This implies showing " all tasks, as with "*". " " If CONSTRAINT doesn't match one of the constraints described above, it " is assumed to be a PATTERN -- see also |viki-tasks|. " " The |regexp| PATTERN is prepended with |\<| if it seems to be a word. " The PATTERN is made case sensitive if it contains an upper-case letter " and if 'smartcase' is true. Only tasks matching the PATTERN will be " listed. Use "." to match any task. " " With the optional !, all files are rescanned. Otherwise cached " information is used. Either scan all known files (|interviki|s and " pages registered via |:VikiTasksAdd|) or files matching FILE_PATTERNS. " " The current buffer has to be a viki buffer. If it isn't, your " |g:vikiHomePage|, which must be set, is opened first. " " Examples: " Show all cached tasks with a date: > " :VikiTasks " < Rescan files and show all tasks: > " :VikiTasks! " < Show all cached tasks for today: > " :VikiTasks today " < Show all current cached tasks (today or with a deadline in the " past) in a specified list of files: > " :VikiTasks current Notes*.txt command! -bang -nargs=* -bar VikiTasks call vikitasks#Tasks(vikitasks#GetArgs(!empty(""), []), 0) " The same as |:VikiTasks| but the tasks list doesn't take the focus. command! -bang -nargs=* -bar VikiTasksStatic call vikitasks#Tasks(vikitasks#GetArgs(!empty(""), []), 1) " cabbr vikitasks VikiTasks " :display: :VikiTasksPaste[!] [ARGUMENTS...] " Paste the results of a VIKITASKSCOMMAND (default: |:VikiTasks|) in a " buffer. When called with a |bang| [!], create a new buffer. See " |:VikiTasks| for the allowed ARGUMENTS. command! -bang -nargs=* -bar VikiTasksPaste call vikitasks#Paste(empty("") ? '' : 'VikiTasksPaste', vikitasks#GetArgs(0, [])) " :display: :[count]VikiTasksAlarms " Display a list of alarms. Shows alarms due within N days. " If N is -1, uses |g:vikitasks#alarms|, if any. command! -count -bang -bar VikiTasksAlarms call vikitasks#Alarm(, empty('')) " :display: :VikiTasksAdd " Add the current buffer to |g:vikitasks#files|. command! VikiTasksAdd call vikitasks#AddBuffer(expand('%:p')) " Mark a task as done (see |vikitasks#ItemMarkDone()|). command! -count=0 -bar VikiTasksDone call vikitasks#ItemMarkDone() " Archive finalized tasks (see |g:vikitasks#final_categories|). command! -bar VikiTasksArchive call vikitasks#ItemArchiveFinal() " :display: :VikiEditTasksFiles " Edit |g:vikitasks#files|. This allows you to remove buffers from the " list. command! -bar VikiEditTasksFiles call vikitasks#EditFiles() " :display: :VikiTasksFiles " Edit a file monitored by vikitasks. command! -bar VikiTasksFiles call vikitasks#ListTaskFiles() " :display: :[count]VikiTasksDueInDays [DAYS=0] " Mark [count] task(s) as due in N days. command! -bar -range -nargs=? VikiTasksDueInDays ,call vikitasks#ItemsMarkDueInDays(0, 0 + ) " :display: :[count]VikiTasksDueInWeeks [WEEKS=1] " Mark [count] task(s) as due in N weeks. command! -bar -range -nargs=? VikiTasksDueInWeeks ,call vikitasks#ItemsMarkDueInWeeks(0, empty() ? 1 : 0 + ) " :display: :[count]VikiTasksDueInMonths [MONTHS=1] " Mark [count] task(s) as due in N months. command! -bar -range -nargs=? VikiTasksDueInMonths ,call vikitasks#ItemsMarkDueInMonths(0, empty() ? 1 : 0 + ) augroup VikiTasks autocmd! if has('vim_starting') autocmd VimEnter * if eval(g:vikitasks_startup_alarms) | call vikitasks#Alarm() | endif elseif eval(g:vikitasks_startup_alarms) call vikitasks#Alarm() endif if !empty(g:vikitasks_scan_events) for s:pattern in g:vikitasks_scan_patterns " exec 'autocmd' g:vikitasks_scan_events s:pattern 'if exists("b:vikiEnabled") && b:vikiEnabled | call vikitasks#ScanCurrentBuffer(expand(":p")) | endif' exec 'autocmd' g:vikitasks_scan_events s:pattern 'call vikitasks#ScanCurrentBuffer(expand(":p"))' endfor endif unlet g:vikitasks_scan_events s:pattern augroup END let &cpo = s:save_cpo unlet s:save_cpo doc/vikitasks.txt [[[1 566 *vikitasks.txt* Search viki files for tasks and display them in a list Author: Tom Link, micathom at gmail com This plugin provides a quick overview of priority/task lists maintained in different viki files. Depending on your settings, you can quickly search all "homepages" of intervikis or search only project-specific files. Usage: :VikiTasks[!] [CONSTRAINT] [PATTERN] [FILE_PATTERNS] Features: - Collect tasks from viki's priority lists (see |viki-tasks|) - Sort those tasks - Browse tasks with a given date - Optionally browse all tasks (incl. those without a date) Demo: http://vimsomnia.blogspot.com/2010/11/vikitasks-viki-demonstration-personal.html ----------------------------------------------------------------------- Tutorial: How does it work?~ Let's say you have the files: foo.txt: > * Foo #A 2009-12-13 Do this #C 2009-12-20 Call @Anna #A Whatever bar.txt: > * Bar #C 2009-12-24 Wish @Bernie good luck #D 2009-11-01 Do that Let's assume you have added both files to |g:vikitasks#files|. Switch to the buffer foo.txt and call > :VikiTasks and you get the following list: > Bar.txt|2| #D 2009-11-01 Do that Foo.txt|2| #A 2009-12-13 Do this Foo.txt|3| #C 2009-12-20 Call @Anna Bar.txt|3| #C 2009-12-24 Wish @Bernie good luck If you do/had done this on the 15 December 2009, the third line would be highlighted, i.e. the entries above the cursor refer to passed/missed events. If you had called :VikiTasks! (behold the bang), then the "Whatever" entry would have been included in the list too. If you had called > :VikiTasks current only the first two items would be listed. This week's tasks (i.e. the tasks that should be accomplished today or within the following six days) can be listed with > :VikiTasks 6 ----------------------------------------------------------------------- Install~ Edit the vba file and type: > :so % See :help vimball for details. If you have difficulties or use vim 7.0, please make sure that you have the current version of vimball (vimscript #1502) installed, or update your runtime. This script requires tlib (vimscript #1863), trag (vimscript #2033), and viki (vimscript #861) to be installed. Also available via git: http://github.com/tomtom/vikitasks_vim/ ======================================================================== Contents~ g:vikitasks#files ...................... |g:vikitasks#files| g:vikitasks#files_ignored .............. |g:vikitasks#files_ignored| g:vikitasks#ignore_completed_tasks ..... |g:vikitasks#ignore_completed_tasks| g:vikitasks#use_threshold .............. |g:vikitasks#use_threshold| g:vikitasks#threshold_days ............. |g:vikitasks#threshold_days| g:vikitasks#sources .................... |g:vikitasks#sources| g:vikitasks#filetype_map ............... |g:vikitasks#filetype_map| g:vikitasks#default_priority ........... |g:vikitasks#default_priority| g:vikitasks#qfl_viewer ................. |g:vikitasks#qfl_viewer| g:vikitasks#rx_categories .............. |g:vikitasks#rx_categories| g:vikitasks#rx_levels .................. |g:vikitasks#rx_levels| g:vikitasks#today ...................... |g:vikitasks#today| g:vikitasks#cache ...................... |g:vikitasks#cache| g:vikitasks#cache_check_mtime_rx ....... |g:vikitasks#cache_check_mtime_rx| g:vikitasks#alarms ..................... |g:vikitasks#alarms| g:vikitasks#use_end_date ............... |g:vikitasks#use_end_date| g:vikitasks#use_unspecified_dates ...... |g:vikitasks#use_unspecified_dates| g:vikitasks#remove_unreadable_files .... |g:vikitasks#remove_unreadable_files| g:vikitasks#after_change_line_exec ..... |g:vikitasks#after_change_line_exec| g:vikitasks#after_change_buffer_exec ... |g:vikitasks#after_change_buffer_exec| g:vikitasks#auto_save .................. |g:vikitasks#auto_save| g:vikitasks#inputlist_params ........... |g:vikitasks#inputlist_params| g:vikitasks#mapleader .................. |g:vikitasks#mapleader| g:vikitasks#done_add_date .............. |g:vikitasks#done_add_date| g:vikitasks#archive_filename_fmt ....... |g:vikitasks#archive_filename_fmt| g:vikitasks#archive_header ............. |g:vikitasks#archive_header| g:vikitasks#date_fmt ................... |g:vikitasks#date_fmt| g:vikitasks#archive_header_fmt ......... |g:vikitasks#archive_header_fmt| g:vikitasks#final_categories ........... |g:vikitasks#final_categories| g:vikitasks#use_calendar ............... |g:vikitasks#use_calendar| g:vikitasks#paste ...................... |g:vikitasks#paste| g:vikitasks#debug ...................... |g:vikitasks#debug| g:vikitasks#convert_cygwin ............. |g:vikitasks#convert_cygwin| vikitasks#TasksRx ...................... |vikitasks#TasksRx()| vikitasks#Tasks ........................ |vikitasks#Tasks()| vikitasks#SetSyntax .................... |vikitasks#SetSyntax()| vikitasks#FormatQFLE ................... |vikitasks#FormatQFLE()| vikitasks#ResetCachedInfo .............. |vikitasks#ResetCachedInfo()| vikitasks#MustUseCanonicFilename ....... |vikitasks#MustUseCanonicFilename()| vikitasks#EachSource ................... |vikitasks#EachSource()| vikitasks#UnRegisterFilename ........... |vikitasks#UnRegisterFilename()| vikitasks#RegisterFilename ............. |vikitasks#RegisterFilename()| vikitasks#AddBuffer .................... |vikitasks#AddBuffer()| vikitasks#RemoveBuffer ................. |vikitasks#RemoveBuffer()| vikitasks#EditFiles .................... |vikitasks#EditFiles()| vikitasks#GetBufferLines ............... |vikitasks#GetBufferLines()| vikitasks#ItemMarkDone ................. |vikitasks#ItemMarkDone()| vikitasks#ItemArchiveFinal ............. |vikitasks#ItemArchiveFinal()| vikitasks#ListTaskFiles ................ |vikitasks#ListTaskFiles()| vikitasks#ItemsMarkDueInDays ........... |vikitasks#ItemsMarkDueInDays()| vikitasks#ItemsMarkDueInWeeks .......... |vikitasks#ItemsMarkDueInWeeks()| vikitasks#ItemsMarkDueInMonths ......... |vikitasks#ItemsMarkDueInMonths()| vikitasks#ItemChangeCategory ........... |vikitasks#ItemChangeCategory()| vikitasks#AgentPaste ................... |vikitasks#AgentPaste()| vikitasks#Glob2Rx ...................... |vikitasks#Glob2Rx()| vikitasks#OnLeave ...................... |vikitasks#OnLeave()| g:vikitasks_startup_alarms ............. |g:vikitasks_startup_alarms| g:vikitasks_scan_events ................ |g:vikitasks_scan_events| g:vikitasks_scan_patterns .............. |g:vikitasks_scan_patterns| :VikiTasks ............................. |:VikiTasks| :VikiTasksStatic ....................... |:VikiTasksStatic| :VikiTasksPaste ........................ |:VikiTasksPaste| :VikiTasksAlarms ....................... |:VikiTasksAlarms| :VikiTasksAdd .......................... |:VikiTasksAdd| :VikiTasksDone ......................... |:VikiTasksDone| :VikiTasksArchive ...................... |:VikiTasksArchive| :VikiEditTasksFiles .................... |:VikiEditTasksFiles| :VikiTasksFiles ........................ |:VikiTasksFiles| :VikiTasksDueInDays .................... |:VikiTasksDueInDays| :VikiTasksDueInWeeks ................... |:VikiTasksDueInWeeks| :VikiTasksDueInMonths .................. |:VikiTasksDueInMonths| ======================================================================== autoload/vikitasks.vim~ *g:vikitasks#files* g:vikitasks#files (default: []) A list of glob patterns (or files) that will be searched for task lists. Can be buffer-local. If you add ! to 'viminfo', this variable will be automatically saved between editing sessions. Alternatively, add new items in the *after-directory* in 'runtimepath' (e.g. ~/vimfiles/after/plugin/vikitasks.vim) *g:vikitasks#files_ignored* g:vikitasks#files_ignored (default: ['_archived\.[^.]\+$']) A list of |regexp| patterns for filenames that should not be scanned. *g:vikitasks#ignore_completed_tasks* g:vikitasks#ignore_completed_tasks (default: 1) If true, completely ignore completed tasks. *g:vikitasks#use_threshold* g:vikitasks#use_threshold (default: 1) If true, obey threshold information (t:YYYY-MM-DD), i.e. don't show the task before this date. *g:vikitasks#threshold_days* g:vikitasks#threshold_days (default: 90) If the value is > 0 and no t: option (see see |g:vikitasks#use_threshold|) is given for a task, hide tasks whose due date is more than N days in the future. The value will be ignored if |g:vikitasks#use_threshold| is false. *g:vikitasks#sources* g:vikitasks#sources (default: {) If non-false, provide tighter integration with the vim viki plugin. *g:vikitasks#filetype_map* g:vikitasks#filetype_map (default: {) A dictionary of 'filetype' => source (see |g:vikitasks#sources|). By default vikitasks expects todo.txt files to have the filetype |todotxt| (which is used by the todo.txt plugin found at https://github.com/davidoc/todo.txt-vim and my own fork at https://github.com/tomtom/todo.txt-vim-1/). Using this map allows users to use todo.txt plugins that use the filetype "todo" (e.g. https://github.com/freitass/todo.txt-vim). *g:vikitasks#default_priority* g:vikitasks#default_priority (default: 'F') Default category/priority when converting tasks without priorities. *g:vikitasks#qfl_viewer* g:vikitasks#qfl_viewer (default: '') The viewer for the quickfix list. If empty, use |:TRagcw|. *g:vikitasks#rx_categories* g:vikitasks#rx_categories (default: 'A-P') Item classes that should be included in the list when calling |:VikiTasks|. A user-defined value must be set in |vimrc| before the plugin is loaded. *g:vikitasks#rx_levels* g:vikitasks#rx_levels (default: '1-5') Item levels that should be included in the list when calling |:VikiTasks|. A user-defined value must be set in |vimrc| before the plugin is loaded. *g:vikitasks#today* g:vikitasks#today (default: 'DUE') If non-empty, vikitasks will insert a break line when displaying a list in the background. *g:vikitasks#cache* g:vikitasks#cache (default: tlib#cache#Filename('vikitasks', 'files', 1)) Cache file name. By default, use |tlib#cache#Filename()| to determine the file name. *g:vikitasks#cache_check_mtime_rx* g:vikitasks#cache_check_mtime_rx (default: '.') If true, check whether the mtime of files with cached tasks has changed and update the info as necessary. *g:vikitasks#alarms* g:vikitasks#alarms (default: {'all_tasks': 0, 'tasks': 'sometasks', 'persistent_categories': 'A', 'constraint': 14}) Definition of the tasks that should be included in the Alarms list. Fields: all_tasks ... If non-null, also display tasks with no due-date tasks ... Either 'tasks' or 'sometasks' constraint ... See |:VikiTasks| *g:vikitasks#use_end_date* g:vikitasks#use_end_date (default: 1) If true, the end-date of date ranges (FROM..TO) is significant. *g:vikitasks#use_unspecified_dates* g:vikitasks#use_unspecified_dates (default: 1) Interpret entries with an unspecified date ("_") as current tasks. *g:vikitasks#remove_unreadable_files* g:vikitasks#remove_unreadable_files (default: 1) If true, remove unreadable files from the tasks list. *g:vikitasks#after_change_line_exec* g:vikitasks#after_change_line_exec (default: '') |:execute| a command (as string) after changing a line. A useful value is |:update|. *g:vikitasks#after_change_buffer_exec* g:vikitasks#after_change_buffer_exec (default: '') |:execute| a command (as string) after changing a buffer. A useful value is |:update|. *g:vikitasks#auto_save* g:vikitasks#auto_save (default: 0) If true, save _all_ modified buffers via |:wall|, when leaving the tasks list. *g:vikitasks#inputlist_params* g:vikitasks#inputlist_params (default: {...}) The parameters for |:TRagcw| when |g:vikitasks#qfl_viewer| is empty. *g:vikitasks#mapleader* g:vikitasks#mapleader (default: 't') Mapleader for some vikitasks related maps. *g:vikitasks#done_add_date* g:vikitasks#done_add_date (default: 1) If true, add a date tag when marking a task done with |vikitasks#ItemMarkDone()|. *g:vikitasks#archive_filename_fmt* g:vikitasks#archive_filename_fmt (default: '"%s_archived". g:vikiNameSuffix') A vim expression that returns the filename of the archive where archived tasks should be moved to. *g:vikitasks#archive_header* g:vikitasks#archive_header (default: ['* Archived tasks']) A list of strings. The header for newly created task archives. *g:vikitasks#date_fmt* g:vikitasks#date_fmt (default: "%Y-%m-%d") The date format string (see |strftime()|). *g:vikitasks#archive_header_fmt* g:vikitasks#archive_header_fmt (default: "** " . g:vikitasks#date_fmt) The archive header format string (see |strftime()|) for archived entries. *g:vikitasks#final_categories* g:vikitasks#final_categories (default: 'XYZ') Letters of final categories, i.e. tasks that should not be altered after assigning them to one of these categories. Tasks in these categories will be considered suitable candidates for automatic archival by |vikitasks#ItemArchiveFinal()|. By default the following categories are considered final: X ... done Y ... cancelled Z ... ??? *g:vikitasks#use_calendar* g:vikitasks#use_calendar (default: '') If non-empty, use |:Calendar| as date picker when marking an item as due in N days. NOTE: This experimental feature is disabled by default. Enable it by setting this variable to, e.g., "Calendar" in your |vimrc| file. *g:vikitasks#paste* g:vikitasks#paste (default: {}) Define how to format the list when calling |:VikiTasksPaste|. A dictionary with the fields (default values are marked with "*"): filename: add*|group|none *g:vikitasks#debug* g:vikitasks#debug (default: 0) *g:vikitasks#convert_cygwin* g:vikitasks#convert_cygwin (default: has('win32unix') && executable('cygpath')) If non-null, convert cygwin filenames to windows format. *vikitasks#TasksRx()* vikitasks#TasksRx(which_tasks, ...) *vikitasks#Tasks()* vikitasks#Tasks(?{'all_tasks': 0, 'cached': 1, 'files': [], 'constraint': '', 'rx': ''}, ?suspend=0) If files is non-empty, use these files (glob patterns actually) instead of those defined in |g:vikitasks#files|. suspend must be one of: -1 ... Don't display a list 0 ... List takes the focus 1 ... Current buffer takes the focus *vikitasks#SetSyntax()* vikitasks#SetSyntax() *vikitasks#FormatQFLE()* vikitasks#FormatQFLE(qfe) *vikitasks#ResetCachedInfo()* vikitasks#ResetCachedInfo() *vikitasks#MustUseCanonicFilename()* vikitasks#MustUseCanonicFilename() *vikitasks#EachSource()* vikitasks#EachSource(fallback, fn, args, params) *vikitasks#UnRegisterFilename()* vikitasks#UnRegisterFilename(filename) *vikitasks#RegisterFilename()* vikitasks#RegisterFilename(dirpattern, filetype, archive, ...) *vikitasks#AddBuffer()* vikitasks#AddBuffer(buffer, ...) Register BUFFER as a file that should be scanned for task lists. *vikitasks#RemoveBuffer()* vikitasks#RemoveBuffer(buffer, ...) Unregister BUFFER as a file that should be scanned for task lists. *vikitasks#EditFiles()* vikitasks#EditFiles() Edit the list of files. *vikitasks#GetBufferLines()* vikitasks#Alarm(?ddays = -1, ?use_cached = 1) *vikitasks#ItemMarkDone()* vikitasks#ItemMarkDone(count, ...) Mark N tasks as done, i.e. assign them to category X -- see also |g:vikitasks#final_categories|. *vikitasks#ItemArchiveFinal()* vikitasks#ItemArchiveFinal(...) Archive finalized (see |g:vikitasks#final_categories|) tasks. *vikitasks#ListTaskFiles()* vikitasks#ListTaskFiles() Edit a file monitored by vikitasks. *vikitasks#ItemsMarkDueInDays()* vikitasks#ItemsMarkDueInDays(count, days, ...) Mark task(s) as due in N days. *vikitasks#ItemsMarkDueInWeeks()* vikitasks#ItemsMarkDueInWeeks(count, weeks, ...) Mark task(s) as due in N weeks. *vikitasks#ItemsMarkDueInMonths()* vikitasks#ItemsMarkDueInMonths(count, months, ...) Mark task(s) as due in N months, NOTE: A "month" means 30 days. *vikitasks#ItemChangeCategory()* vikitasks#ItemChangeCategory(count, ...) Change the category for the current and the next a:count tasks. *vikitasks#AgentPaste()* vikitasks#AgentPaste(world, selected) *vikitasks#Glob2Rx()* vikitasks#Glob2Rx(pattern) *vikitasks#OnLeave()* vikitasks#OnLeave(w) ======================================================================== plugin/vikitasks.vim~ *g:vikitasks_startup_alarms* g:vikitasks_startup_alarms (default: 0) An expression that determines whether to show alarms on pending tasks on startup. If the expression evaluates to 0, don't display alarms for pending tasks. If it evaluates to a value > 0, display alarms for pending tasks or tasks with a deadline in n days. Possibly useful values (for your |vimrc|) are: > let g:vikitasks_startup_alarms = "(!has('clientserver') || len(split(serverlist(), '\n')) <= 1) && argc() == 0" let g:vikitasks_startup_alarms = has('clientserver') && v:servername == 'GVIM' < This will display alarms when running the first instance of gvim without arguments. *g:vikitasks_scan_events* g:vikitasks_scan_events (default: 'BufWritePost,BufWinEnter') Scan a buffer on these events. *g:vikitasks_scan_patterns* g:vikitasks_scan_patterns (default: ['*.txt', '*.viki']) A list of filename patterns (see 'wildcards') for files that should automatically on events specified in |g:vikitasks_scan_events|. *:VikiTasks* :VikiTasks[!] [CONSTRAINT] [PATTERN] [FILE_PATTERNS] CONSTRAINT constrains which tasks should be displayed. Possible values are: today ... Show tasks that are due today current ... Show today's tasks and pending tasks NUMBER (of days) ... Show tasks that are due within N days Nd ... Tasks for the next N days Nw ... Tasks for the next N weeks (i.e. 7 days) Nm ... Tasks for the next N months (i.e. 31 days) week ... Tasks for the next week (i.e. 7 days) month ... Tasks for the next month (i.e. 31 days) . ... Show some tasks (see |g:vikitasks#rx_categories| and |g:vikitasks#rx_levels|) * ... Show all tasks The default value for CONSTRAINT is ".". Prepend + to N (e.g. "+2w") to hide tasks with a deadline in the past. Prepend - to N (e.g. "-2w") to show only tasks with a deadline in the past (in this example in the last two weeks). This implies showing all tasks, as with "*". If CONSTRAINT doesn't match one of the constraints described above, it is assumed to be a PATTERN -- see also |viki-tasks|. The |regexp| PATTERN is prepended with |\<| if it seems to be a word. The PATTERN is made case sensitive if it contains an upper-case letter and if 'smartcase' is true. Only tasks matching the PATTERN will be listed. Use "." to match any task. With the optional !, all files are rescanned. Otherwise cached information is used. Either scan all known files (|interviki|s and pages registered via |:VikiTasksAdd|) or files matching FILE_PATTERNS. The current buffer has to be a viki buffer. If it isn't, your |g:vikiHomePage|, which must be set, is opened first. Examples: Show all cached tasks with a date: > :VikiTasks < Rescan files and show all tasks: > :VikiTasks! < Show all cached tasks for today: > :VikiTasks today < Show all current cached tasks (today or with a deadline in the past) in a specified list of files: > :VikiTasks current Notes*.txt < *:VikiTasksStatic* :VikiTasksStatic The same as |:VikiTasks| but the tasks list doesn't take the focus. *:VikiTasksPaste* :VikiTasksPaste[!] [ARGUMENTS...] Paste the results of a VIKITASKSCOMMAND (default: |:VikiTasks|) in a buffer. When called with a |bang| [!], create a new buffer. See |:VikiTasks| for the allowed ARGUMENTS. *:VikiTasksAlarms* :[count]VikiTasksAlarms Display a list of alarms. Shows alarms due within N days. If N is -1, uses |g:vikitasks#alarms|, if any. *:VikiTasksAdd* :VikiTasksAdd Add the current buffer to |g:vikitasks#files|. *:VikiTasksDone* :VikiTasksDone Mark a task as done (see |vikitasks#ItemMarkDone()|). *:VikiTasksArchive* :VikiTasksArchive Archive finalized tasks (see |g:vikitasks#final_categories|). *:VikiEditTasksFiles* :VikiEditTasksFiles Edit |g:vikitasks#files|. This allows you to remove buffers from the list. *:VikiTasksFiles* :VikiTasksFiles Edit a file monitored by vikitasks. *:VikiTasksDueInDays* :[count]VikiTasksDueInDays [DAYS=0] Mark [count] task(s) as due in N days. *:VikiTasksDueInWeeks* :[count]VikiTasksDueInWeeks [WEEKS=1] Mark [count] task(s) as due in N weeks. *:VikiTasksDueInMonths* :[count]VikiTasksDueInMonths [MONTHS=1] Mark [count] task(s) as due in N months. vim:tw=78:fo=w2croql:isk=!-~,^*,^|,^":ts=8:ft=help:norl: