Opening Obsidian Files in Vim
Sometimes it seems like nothing is ever easy. Follow along on my adventure in getting my $EDITOR
to open markdown files.
Goal
When editing a markdown file in Obsidian sometimes I just want to open the file in a proper editor like Neovim.
Attempt 1 - Open in default app
Obsidian already has a command Open in default app
. This seemed like the obvious first choice. Unfortunately to start with this just opens the file in Firefox.
What sets the program?
I suspected this was related to xdg-open
. Since there are multiple ways this could work I figured a good first step would be to double check. I wanted to know what it was calling and there's (at least) two ways to do this:
BCC's execsnoop
The BPF Compiler Collection is a toolkit with a lot of useful tracing tools. The one I used was sudo execsnoop -u kenny
. This can be run in any terminal and will log all programs started by any processes I own. This method is useful because it doesn't require any changes to how the program is executed. Additionally, it doesn't require the program to be restarted."
After starting execsnoop
and running the Open in default app
command in Obsidian I was given the following output:
xdg-mime 1176318 1176317 0 /nix/store/...-xdg-utils-1.2.1/bin/xdg-mime query filetype /home/kenny/obsidian/test.md
...
xdg-mime 1176337 1176298 0 /nix/store/...-xdg-utils-1.2.1/bin/xdg-mime query default text/markdown
strace
Unlike execsnoop
the strace
tool generally works best if you restart the program while wrapping it. It's not technically required, as you can attach to an existing process, but in the case of a program like Obsidian it likely already has subprocesses which complicates things.
To start Obsidian and log the commands executed I used:
strace -e execve -s 1024 -f -o /tmp/exec -- obsidian
The arguments here are:
-e execve
- Only trace theexecve
syscalls (ie the ones that start processes)-s 1024
- Increase the max string size to make sure commands are truncated-f
- Follow all child processes-o /tmp/exec
- Write the output to a file to review afterwards--
- Ends the options for strace. Not required this time, but good practice
The output after running the command contains:
1190785 execve("/nix/store/...-xdg-utils-1.2.1/bin/xdg-mime", ["/nix/store/...-xdg-utils-1.2.1/bin/xdg-mime", "query", "filetype", "/home/kenny/obsidian/test.md"], 0xb6b7a20 /* 141 vars */ <unfinished ...>
...
1190803 execve("/nix/store/...-xdg-utils-1.2.1/bin/xdg-mime", ["/nix/store/...-xdg-utils-1.2.1/bin/xdg-mime", "query", "default", "text/markdown"], 0xb6bfda0 /* 141 vars */)
xdg-mime query
Looking at the above commands we can see that it calls xdg-mime query filetype test.md
. By trying this on the command line I get back text/markdown
. This is the value passed to the next query in attempting to look up the program that should be run. On my system there was no value.
To see where it's actually checking for these types I can run:
$ XDG_UTILS_DEBUG_LEVEL=2 xdg-mime query default text/markdown
Checking /home/kenny/.config/mimeapps.list
Checking /home/kenny/.local/share/applications/defaults.list and /home/kenny/.local/share/applications/mimeinfo.cache
Checking /var/lib/snapd/desktop/applications/defaults.list and /var/lib/snapd/desktop/applications/mimeinfo.cache
Checking /nix/store/...-desktops/share/applications/defaults.list and /nix/store/...-desktops/share/applications/mimeinfo.cache
There's a bunch more, but only the first one actually matters.
~/.config/mimeapps.list
Opening the mimeapps.list
file I see some existing entries for Firefox in a [Default Applications]
section:
[Default Applications]
x-scheme-handler/http=firefox.desktop
x-scheme-handler/https=firefox.desktop
x-scheme-handler/chrome=firefox.desktop
text/html=firefox.desktop
Seems easy enough, I added an entry for text/markdown=nvim.desktop
. Now programs should use neovim
to open markdown files. Testing with xdg-open test.md
shows this to work
Obsidian Result
After making this change I tested it in Obsidian and... it didn't work. Using the above methods I could see that it was calling nvim test.md
. This isn't right as the .desktop
file contains:
Exec=nvim %F
Terminal=true
It should be run in a terminal. If I run the nvim
desktop file from either the window manager or from a command line then I get a new terminal. I'm not sure if this is a bug in Obsidian or if I'm missing some other setting, but Obsidian is unfortunately closed-source (boo!), so at this point, I started looking for other options.
Attempt 2 - obsidian-open-with
Giving up on the expected solution I found the plugin obsidian-open-with. After installing it I opened the config and did an Add new application
with the value:
- Display Name: Vim
- Path/Command: kitty
- Arguments (optional): nvim
I clicked the little +
to add it, then enabled Show in File-Menu
. Now I can right-click on the file in the tree and I get the option to Open in Vim
.
Conclusion
Ultimately, this solution works well, and as a bonus, I now have the correct entry in my mimeapps.list
. Hopefully my steps will help someone in figuring out their own mimetype or tracing issues.