(Inspired by Luke Smith.)
I’m playing around with Neovim, Telescope, and Fennel, and just finished creating a first version of a markdown link handler.
It allows you to fuzzy search for a link in a markdown file, and open it with whatever application (“linkhandler”) you specify. If you don’t specify a linkhandler, it will default to x-www-browser
, or to open
on macOS.
Prerequisites:
Benefits:
mpv
as the linkhandler for a command (example shown below in the usage section). In case that’s not allowed by YouTube, I uh, heard that from a friend. :)Need to be fixed:
[...](...)
occcurrences on the same line, without spaces or newlines between ]
and (
, currently. This can probably easily be improved, but it works fine for my purposes as is.mpv
video playback. Will have to change this so the command will be triggered with something like bash its <command> &
ampersand thingy.~/my-markdown-links.md
in your browser:lua require('my.module').telescope_markdown_url_opener({})
~/some-file.md
with mpv:lua require('my.module').telescope_markdown_url_opener(
{
urls_file='~/some-file.md',
linkhandler='mpv'
}
)
(module my.modulerequire {telescope telescope}})
{
(defn split-string [inputstr sep];; split-string source: https://stackoverflow.com/a/7615129
do
(when (= sep nil) (set-forcibly! sep "%s"))
(local t [])
(each [str (string.gmatch inputstr (.. "([^" sep "]+)"))]
(table.insert t str))
(
t))
(defn get-file-lines [path-to-file]-> (vim.fn.system (.. "cat " path-to-file))
("\n")))
(split-string
(defn match-single-line-markdown-url [line];; NOTE: this will only match single line "[...](...)" patterns
string.match line "(%b[])(%b())"))
(
(defn get-single-line-markdown-urls-from-file [path-to-file]local name-url-pairs [])
(each [k line (ipairs (get-file-lines path-to-file))]
(when (not (= nil (match-single-line-markdown-url line)))
(table.insert name-url-pairs line)))
(
name-url-pairs)
(defn create-markdown-url-opener [opts]fn [prompt-bufnr]
(let [actions (require "telescope.actions")
(require "telescope.utils")
utils (require "telescope.actions.state")
action-state (
selection (action-state.get_selected_entry)"linkhandler")
linkhandler (. opts fn [] (= "Darwin\n" (vim.fn.system "uname -s")))
is-mac-os? (if linkhandler linkhandler
open-function ("open"
(is-mac-os?) true "x-www-browser")]
(actions.close prompt-bufnr)local (_ ret stderr)
(
(utils.get_os_command_output [open-function selection.value]))if (= ret 0)
(print (.. "Opened with '"
(
open-function"': "
selection.value))print (string.format
("Could not open %s - \"%s\""
selection.valuetable.concat stderr " ")))))))
(
(defn markdown-url-entry-maker []let [entry-display (require "telescope.pickers.entry_display")
(40}
displayer (entry-display.create {:items [{:width true}]
{:remaining " "})]
:separator fn make-display [entry]
("TelescopeResultsIdentifier"]
(displayer [[entry.value
entry.msg]))fn [entry]
(when (= entry "")
(lua "return nil"))
(var (name-with-brackets url-with-parentheses)
(
(match-single-line-markdown-url entry))var name
(string.sub name-with-brackets 2 -2))
(var url
(string.sub url-with-parentheses 2 -2))
(
{:display make-display
:msg name" " url) ; TODO: find out what this is/does
:ordinal (.. name
:value url})))
(defn telescope_markdown_url_opener [options]let [opts (or options {})
(or options.urls_file "~/my-markdown-links.md")
urls-file (require "telescope.pickers")
pickers (require "telescope.actions")
actions (require "telescope.finders")
finders (require "telescope.config") "values")
conf (. (
results (get-single-line-markdown-urls-from-file urls-file)]: (pickers.new
(
optsfn []
{:attach_mappings (: actions.select_default
("replace"
(create-markdown-url-opener opts));; return true = add default Telescope mappings.
true)
:finder (finders.new_tableor opts.entry_maker
{:entry_maker (
(markdown-url-entry-maker opts))
:results results})nil
:previewer "< select markdown url in " urls-file ">")
:prompt_title (.. "find")))
:sorter (conf.file_sorter opts)})
;; This block is the return value of this module.
{ :telescope_markdown_url_opener telescope_markdown_url_opener}