Using AutoHotKey to add a quick snippet or task to daily note

Inspired by jrnl.sh, but I wanted my captures to show up in Obsidian. Some others may have use of this, so I wanted to share an AutoHotKey implementation for capturing a snippet or task.

This uses AHK’s InputHook to capture keyboard input until “Enter” or “Escape” is pressed. This input is then used as follows:

  • Enter logs input as a bullet point with a timestamp
  • Shift+Enter logs a completed task
  • Ctrl+Enter to log an uncompleted task
  • Escape ends without logging any captured input

InputHook will capture arrow keys, backspace, and delete. It does not capture modified arrow keys or modified backspace.

Requirements

Script & Instructions

  • The vault is set to vault=obsidian-main and yours is likely not named “obsidian-main,” so update the dailyNote variable to use your vault
  • I specifically append to a heading within my daily note, named 🦄running thoughts🐲
    • You can remove the entire &heading="" block, or enter a heading of your choosing
    • The heading must exist within your daily note and the template if today’s note was not yet created
  • I run this with Ctrl+F13, update ^F13 with the bind you prefer
  • Shift+Enter logs a completed task, Ctrl+Enter logs an uncompleted task, and Enter logs a regular bullet point with a timestamp in the format of HH:mm:ss
    • See AHK FormatTime for more information or to set your preference
  • I use the tasks plugin only for items with the tag “#Todo
    • Update or remove %23Todo as you see fit
^F13::
{
    _InputHook := InputHook("", "{Enter}")
    _InputHook.Start()
    _InputHook.Wait()
    _InputHook.OnEnd := DailyNoteLog(_InputHook)
    return
}

; Logs to Obsidian daily note
; Shift+Enter logs a completed task
; CTRL+Enter logs a task due today
; Enter logs a running thought
DailyNoteLog(_InputHook) {
    if (_InputHook.EndKey = "Enter") {
        Mods := RegExReplace(_InputHook.EndMods, "[<>](.)(?:>\1)?", "$1")
        DailyNote := "obsidian://advanced-uri?vault=obsidian-main&daily=true&mode=append"
        Timestamp := FormatTime(A_Now, "HH:mm:ss")
        switch Mods
        {
            Case "+":
                Run(DailyNote . "&heading=🦄running thoughts🐲&data=- [x] " . _InputHook.Input . " %23Todo")
            Case "^":
                Run(DailyNote . "&heading=🦄running thoughts🐲&data=- [ ] " . _InputHook.Input . " %23Todo")
            default:
                Run(DailyNote . "&heading=🦄running thoughts🐲&data=- " . Timestamp . " " . _InputHook.Input)
        }
    }
}

Modifications

There are, of course, many ways to write to Obsidian notes between using templates and various plugins. This is what works for me, and maybe it will for you, too.

As it is AutoHotKey, you could of course add a GUI to type into instead of using the InputHook. See QNote - AHK script for quick note creation (Windows only) for an implementation, or refer to the AutoHotKey documentation for GUI creation. This is probably the direction for version 2 of this script. As it stands, I’m not annoyed by being unable to see my input.

If you want to log to a different note other than the daily note, see the Advanced URI documentation.

Let me know if you have any questions or suggestions. Happy note-taking!

1 Like

A small update to the DailyNoteLog method was needed. I added taskCompleteDate := FormatTime(relativeNow, "yyyy-MM-dd") so that I could update the completed task path as follows: Run(DailyNote . "&heading=🦄running thoughts🐲&data=- [x] " . _InputHook.Input . " %23Todo ✅ " . taskCompleteDate). My task query wasn’t working as expected, and I needed the completed date to show up properly.

Here’s the full method to copy and paste over the old. Unfortunately, I can’t seem to edit my post anymore.

DailyNoteLog(_InputHook) {
    if (_InputHook.EndKey = "Enter") {
        Mods := RegExReplace(_InputHook.EndMods, "[<>](.)(?:>\1)?", "$1")
        DailyNote := "obsidian://advanced-uri?vault=obsidian-main&daily=true&mode=append"
        RelativeNow := A_Now
        TaskCompleteDate := FormatTime(RelativeNow, "yyyy-MM-dd")
        Timestamp := FormatTime(RelativeNow, "HH:mm:ss")
        switch Mods
        {
            Case "+":
                Run(DailyNote . "&heading=🦄running thoughts🐲&data=- [x] " . _InputHook.Input . " %23Todo ✅ " . TaskCompleteDate)
            Case "^":
                Run(DailyNote . "&heading=🦄running thoughts🐲&data=- [ ] " . _InputHook.Input . " %23Todo")
            default:
                Run(DailyNote . "&heading=🦄running thoughts🐲&data=- " . Timestamp . " " . _InputHook.Input)
        }
    }
}