Using Hook with Obsidian

Last updated 2021-01-19 23:41

Hook Integration scripts version 139 introduced support for the Obsidian note-taking app. We’ve been tweaking the support since then. And Obsidian plans to add additional support to which we expect to adapt Hook.

This means you can now link your Obsidian notes to just about anything.

We are grateful to Josh Nichols and Lisa Sieverts for this integration. (See below.)

Currently supported functions

The current integration of Hook with Obsidian makes use of obsidian:// links. It supports:

  • Copy Link in Obsidian
  • Copy Markdown Link in Obsidian
  • Copy All Links in Obsidian
  • Hook to Copied Link in Obsidian

and related functionality (e.g., find and Hook window navigation).

Limitations of Obsidian integration and planned functionality

Please note that Obsidian is still in pre 1.0 beta. Hence the following limitations.

If only one Obsidian vault is open, Copy Link and Copy Markdown Link copy a link to the currently open document. However, if more than one vault is open, Hook will obtain a link to the document that was mostly recently opened, which may or may not be the frontmost open document. More precisely when there is at least one open document, this always returns a link to the “most recently opened document”; this is equal to the “currently document” if there is only one vault open, otherwise it may or may not be. This limitation is because Obsidian does not yet provide an API to copy the link to the frontmost document. Our integration script therefore uses a heuristic.

We plan to support the following in Obsidian too:

  • Hook to New (Not yet supported because Obsidian does not have an API for this either. However, the Obsidian dev have indicated they will provide a solution for this).
  • Reveal File in Finder
  • hook://file/ URLs (see next section)

If you immediately require an app that is fully linkable without those limitations, please consult this list of apps.

Getting hook://file/ URLs

In this section we share a “Get Address” scheme that returns hook://file// URLs rather than the default obsidian:// one.

This will be handy because obsidian:// URLs currently are not robust: if you rename an Obsidian file, the obsidian:// will break — (presumably that may change by the time Obsidian exits beta). hook://file/ URLs are robust. You can even move files outside of Obsidian and hook://file/ will remain.

Using hook://file/ URLs will also have the advantage that the URLs you obtain for files managed by Obsidian, in the context of other apps than Obsidian (such as Finder, nvUltra or BBEdit), will be the same as those you get within the context of Obsidian itself hook://file/ URLs.

A disadvantage is that it does not yet seem possible to make Obsidian the default app for opening any given file extension. This is a result of Obsidian being an electron app. Developers need to put in extra work to make electron apps behave like native ones. Obsidian is still in beta; we assume by the time Obsidian is out of beta, this too will be resolved.

//JavaScript
(() => {
  'use strict';

const main = () => {
  const app = Application.currentApplication()
  app.includeStandardAdditions = true

  ObjC.import('Foundation')

  const readFile = function (path, encoding) {
    !encoding && (encoding = $.NSUTF8StringEncoding)

    const fm = $.NSFileManager.defaultManager
    const data = fm.contentsAtPath(path)
    const str = $.NSString.alloc.initWithDataEncoding(data, encoding)
    return ObjC.unwrap(str)
  }




  const homeDirectory = app.pathTo("home folder").toString()

  const obsidianJSONPath = `${homeDirectory}/Library/Application Support/obsidian/obsidian.json`
  const obsidianData = JSON.parse(readFile(obsidianJSONPath,$.NSUTF8StringEncoding))

  var vaultPath = ""
  var vaultId = ""
  if(obsidianData.hasOwnProperty("last_open")){
      vaultId = obsidianData["last_open"]
      const vault = obsidianData["vaults"][vaultId]
      vaultPath = vault["path"]
  }else{
      const vaults = obsidianData["vaults"]


      for (var key in vaults){
          if (vaults.hasOwnProperty(key) ){
             if(vaults[key].hasOwnProperty("open")){

                   if(vaults[key]["open"]){

                       vaultPath = vaults[key]["path"]
                    vaultId =key
                   }
             }
          }
       }

  }

  const workspaceJSONPath = `${vaultPath}/.obsidian/workspace`


  const workspaceData = JSON.parse(readFile(workspaceJSONPath,$.NSUTF8StringEncoding))

  const currentDocument = workspaceData["lastOpenFiles"][0]




  const slashParts = currentDocument.split("/")


  const basename = slashParts[slashParts.length - 1]
  var title=""
  if (basename) {
    title = basename.replace(/\.md$/, '')
  }
  const uri = `[${title}](file://${encodeURI(vaultPath)}/${encodeURI(currentDocument)})`


  return uri


}

return main();

})()

How is Obsidian relevant to Hook users

What is the Obsidian app?

Obsidian is an Electron note-taking app, hence with the same “look & feel”, on multiple platforms ( Windows, Linux (AppImage), Linux (Snap), and Linux (Flatpak) and macOS.

Per its home page Obsidian (2020-12-08), Obsidian is

a powerful knowledge base that works on top of a local folder of plain text Markdown files.

The Obsidian Features page (2020-12-08) boasts:

LINK AS FIRST-CLASS CITIZEN

We want your second brain to work like a real brain, so Obsidian encourages you to make connections between your notes. Simply type [[ and Obsidian will auto-complete the link.

With connections in place, you can navigate your notes and get inspiration with backlinks and graph view.

Gratitude

We at CogSci Apps Corp. would like to thank Lisa Sieverts for being a liaison between CogSci Apps and the Obsidian community.

We wish to thank Josh Nichols for publishing JavaScript on which Hook’s integration is based.

Josh is known as technicalpickles on Github and on Obsidian’s Forum and @techpickles on Twitter.

Thanks also to many Hook Productivity Forum members who contributed to this discussion .