I've been writing more posts that contain links recently, and so it's common for me to copy/paste links into the Markdown source for a post. Often times, this means copy/pasting the URL and link title separately. Surely, this can be automated!

VSCode has a great plugin for this, but I haven't found something comparable for vim. Sounds like it's time to break out vimscript:

function GetURLTitle(url)
    " Bail early if the url obviously isn't a URL.
    if a:url !~ '^https\?://'
        return ""
    endif

    " Use Python/BeautifulSoup to get link's page title.
    let title = system("python3 -c \"import bs4, requests; print(bs4.BeautifulSoup(requests.get('" . a:url . "').content, 'lxml').title.text.strip())\"")

    " Echo the error if getting title failed.
    if v:shell_error != 0
        echom title
        return ""
    endif

    " Strip trailing newline
    return substitute(title, '\n', '', 'g')
endfunction

function PasteMDLink()
    let url = getreg("+")
    let title = GetURLTitle(url)
    let mdLink = printf("[%s](%s)", title, url)
    execute "normal! a" . mdLink . "\<Esc>"
endfunction

" Make a keybinding (mnemonic: "mark down paste")
nmap <Leader>mdp :call PasteMDLink()<cr>

The above code snippet is in 3 parts:

  1. GetURLTitle() uses python and Beautiful Soup to get the HTML title of the URL provided as an argument. This requires that python and BeautifulSoup be installed, but these are fairly common packages.
  2. PasteMDLink() gets the contents of the + register (which contains the system clipboard), uses GetURLTitle() to get the title of the URL contained in the clipboard, and formats it as a markdown link. Then, it appends that formatted link after the current cursor position.
  3. nmap sets up a keybinding in normal mode to activate the script.

So, my workflow for importing a link into a markdown draft is to (1) copy it to the system clipboard and (2) type ,mdp. Vim grabs the link's title and formats it correctly. Automation complete. 😄


As a disclaimer, I'm a total novice at vimscript. Please let me know if there's a better way of accomplishing the same task!