+function Tasks.tag(tag)
+ local line_number = api.nvim_win_get_cursor(0)[1]
+ local line = api.nvim_get_current_line()
+ if is_task(line) then
+ local pattern = ':(.*):$'
+ local tag_string = line:match(pattern) or ''
+ if not tag or tag == '' then
+ tag = vim.fn.input('Add new tag for task (' .. tag_string .. '): ')
+ if not tag or tag == '' then
+ return
+ end
+ end
+ local tags = parse_tags(tag_string)
+ if not table_contains_value(tags, tag) then
+ table.insert(tags, tag)
+ local new_tags = table.concat(tags, ',')
+ if line:match(pattern) then
+ line = line:gsub(pattern, ':' .. new_tags .. ':', 1)
+ else
+ line = line .. ' :' .. new_tags .. ':'
+ end
+ api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {line})
+ end
+ else
+ api.nvim_err_writeln('Tagging only works on tasks')
+ end
+end
+
+--- Remove tag on a task
+function Tasks.remove_tag(tag)
+ local line_number = api.nvim_win_get_cursor(0)[1]
+ local line = api.nvim_get_current_line()
+ if is_task(line) then
+ local pattern = ':(.*):$'
+ local tag_string = line:match(pattern)
+ if not tag_string then
+ api.nvim_err_writeln('No tags to remove')
+ return
+ end
+
+ if not tag or tag == '' then
+ tag = vim.fn.input('Pick tag to remove (' .. tag_string .. '): ')
+ end
+
+ local tags = parse_tags(tag_string)
+ remove_value(tags, tag)
+ local new_tags = ''
+
+ if #tags > 0 then
+ new_tags = ':' .. table.concat(tags, ',') .. ':'
+ end
+
+ line = line:gsub(pattern, new_tags, 1):gsub('%s+$', '')
+ api.nvim_buf_set_lines(0, line_number - 1, line_number, false, {line})
+ else
+ api.nvim_err_writeln('Tagging only works on tasks')
+ end