obsidian-tasks-group / obsidian-tasks

Task management for the Obsidian knowledge base.
https://publish.obsidian.md/tasks/
MIT License
2.48k stars 230 forks source link

Schedule task for today keyboard shortcut #1691

Open louwers opened 1 year ago

louwers commented 1 year ago

⚠️ Please check that this feature request hasn't been suggested before.

πŸ”– Feature description

I am aware of the Auto-suggest feature, but I don't like using it, because it highjacks the down arrow.

I would like to go through a list of tasks quickly and schedule a certain task for today with a keyboard shortcut.

βœ”οΈ Solution

A shortcut that sets the scheduled day to today on the task that is currently selected.

❓ Alternatives

No response

πŸ“ Additional Context

No response

claremacrae commented 1 year ago

Nice idea. Thank you.

I guess there would need to be shortcuts for setting Due and Start dates too.

louwers commented 1 year ago

I have a custom command right now that is a bit hacky.

If a task is already done and it is scheduled, I also set it as "todo". This way I can easily manually schedule recurring tasks.

editor.setCursor(getLineEndPos(editor.getCursor().line, editor));
const currentLine = () => editor.getLine(editor.getCursor().line);
const scheduledPattern = / ⏳ \d\d\d\d-\d\d-\d\d/;

const donePattern = /^- \[x\]/;

if (isScheduled() && isDone()) {
    unschedule();
    setTodo();
    schedule();
} else if (isScheduled()) {
    unschedule();
} else {
    unschedule();
    schedule();
}

function isDone() {
    return currentLine().match(donePattern);
}

function replace(pattern: RegExp, withThis: string) {
    const currentLine = editor.getLine(editor.getCursor().line);
    const newLine = currentLine.replace(pattern, withThis);
    editor.replaceRange(
        newLine,
        {
            ch: 0,
            line: editor.getCursor().line,
        },
        getLineEndPos(editor.getCursor().line, editor),
    );
}

function isScheduled() {
    return currentLine().match(scheduledPattern);
}

if (isScheduled()) {
    return;
}

function setTodo() {
    replace(donePattern, "- [ ]");
}

function schedule() {
    editor.replaceRange(
        `${
            currentLine()[currentLine().length - 1] === " " ? "" : " "
        }⏳ ${moment().format("YYYY-MM-DD")}`,
        editor.getCursor(),
    );
}

function unschedule() {
    replace(scheduledPattern, " ");
}
claremacrae commented 1 year ago

@louwers, wow. Thank you. Please could you share the steps needed to use the code above?

louwers commented 1 year ago

Maybe I will try to submit a pull request.

The above code is wrapped in a

        this.addCommand({
            id: "schedule-task-today",
            name: "Schedule Task Today",
            editorCallback: (editor: Editor) => {

call and uses this helper function

export const getLineEndPos = (
    line: number,
    editor: Editor,
): EditorPosition => ({
    line,
    ch: editor.getLine(line).length,
});

But this code is quite hacky as I have said, so I would hold off intergrating it.

claremacrae commented 1 year ago

Oh right, thanks - so if I now understand correctly, it’s a modification to the Tasks code itself?

louwers commented 1 year ago

I created a separate plugin (that is why I am using regex and not the API of the plugin).