@@ -411,6 +411,100 @@ function! s:TableFormat()
411411 call setpos (' .' , l: pos )
412412endfunction
413413
414+ " Parameters:
415+ "
416+ " - step +1 for right, -1 for left
417+ "
418+ " TODO: multiple lines.
419+ "
420+ function ! s: FindCornerOfSyntax (lnum, col , step)
421+ let l: col = a: col
422+ let l: syn = synIDattr (synID (a: lnum , l: col , 1 ), ' name' )
423+ while synIDattr (synID (a: lnum , l: col , 1 ), ' name' ) == # l: syn
424+ let l: col += a: step
425+ endwhile
426+ return l: col - a: step
427+ endfunction
428+
429+ " Return the next position of the given syntax name,
430+ " inclusive on the given position.
431+ "
432+ " TODO: multiple lines
433+ "
434+ function ! s: FindNextSyntax (lnum, col , name)
435+ let l: col = a: col
436+ let l: step = 1
437+ while synIDattr (synID (a: lnum , l: col , 1 ), ' name' ) !=# a: name
438+ let l: col += l: step
439+ endwhile
440+ return [a: lnum , l: col ]
441+ endfunction
442+
443+ function ! s: FindCornersOfSyntax (lnum, col )
444+ return [<sid> FindLeftOfSyntax (a: lnum , a: col ), <sid> FindRightOfSyntax (a: lnum , a: col )]
445+ endfunction
446+
447+ function ! s: FindRightOfSyntax (lnum, col )
448+ return <sid> FindCornerOfSyntax (a: lnum , a: col , 1 )
449+ endfunction
450+
451+ function ! s: FindLeftOfSyntax (lnum, col )
452+ return <sid> FindCornerOfSyntax (a: lnum , a: col , -1 )
453+ endfunction
454+
455+ " Returns:
456+ "
457+ " - a string with the the URL for the link under the cursor
458+ " - an empty string if the cursor is not on a link
459+ "
460+ " `b:` instead of `s:` to make it testable.
461+ "
462+ " TODO
463+ "
464+ " - multiline support
465+ " - give an error if the separator does is not on a link
466+ "
467+ function ! b: Markdown_GetUrlForPosition (lnum, col )
468+ let l: lnum = a: lnum
469+ let l: col = a: col
470+ let l: syn = synIDattr (synID (l: lnum , l: col , 1 ), ' name' )
471+
472+ if l: syn == # ' mkdInlineURL' || l: syn == # ' mkdURL' || l: syn == # ' mkdLinkDefTarget'
473+ " Do nothing.
474+ elseif l: syn == # ' mkdLink'
475+ let [l: lnum , l: col ] = <sid> FindNextSyntax (l: lnum , l: col , ' mkdURL' )
476+ let l: syn = ' mkdURL'
477+ elseif l: syn == # ' mkdDelimiter'
478+ let l: line = getline (l: lnum )
479+ let l: char = l: line [col - 1 ]
480+ if l: char == # ' <'
481+ let l: col += 1
482+ elseif l: char == # ' >' || l: char == # ' )'
483+ let l: col -= 1
484+ elseif l: char == # ' [' || l: char == # ' ]' || l: char == # ' ('
485+ let [l: lnum , l: col ] = <sid> FindNextSyntax (l: lnum , l: col , ' mkdURL' )
486+ else
487+ return ' '
488+ endif
489+ else
490+ return ' '
491+ endif
492+
493+ let [l: left , l: right ] = <sid> FindCornersOfSyntax (l: lnum , l: col )
494+ return getline (l: lnum )[l: left - 1 : l: right - 1 ]
495+ endfunction
496+
497+ " Front end for GetUrlForPosition.
498+ "
499+ function ! s: OpenUrlUnderCursor ()
500+ let l: url = b: Markdown_GetUrlForPosition (line (' .' ), col (' .' ))
501+ if l: url != ' '
502+ call netrw#NetrwBrowseX (l: url , 0 )
503+ else
504+ echomsg ' The cursor is not on a link.'
505+ endif
506+ endfunction
507+
414508call <sid> MapNormVis (' <Plug>(Markdown_MoveToNextHeader)' , ' <sid>Markdown_MoveToNextHeader' )
415509call <sid> MapNormVis (' <Plug>(Markdown_MoveToPreviousHeader)' , ' <sid>Markdown_MoveToPreviousHeader' )
416510call <sid> MapNormVis (' <Plug>(Markdown_MoveToNextSiblingHeader)' , ' <sid>Markdown_MoveToNextSiblingHeader' )
@@ -419,6 +513,7 @@ call <sid>MapNormVis('<Plug>(Markdown_MoveToPreviousSiblingHeader)', '<sid>Markd
419513call <sid> MapNormVis (' <Plug>(Markdown_MoveToParentHeader)' , ' <sid>Markdown_MoveToParentHeader' )
420514" Menmonic: Current
421515call <sid> MapNormVis (' <Plug>(Markdown_MoveToCurHeader)' , ' <sid>Markdown_MoveToCurHeader' )
516+ nnoremap <Plug> (OpenUrlUnderCursor) :call <sid> OpenUrlUnderCursor()<cr>
422517
423518if ! get (g: , ' vim_markdown_no_default_key_mappings' , 0 )
424519 nmap <buffer> ]] <Plug> (Markdown_MoveToNextHeader)
@@ -427,6 +522,7 @@ if !get(g:, 'vim_markdown_no_default_key_mappings', 0)
427522 nmap <buffer> [] <Plug> (Markdown_MoveToPreviousSiblingHeader)
428523 nmap <buffer> ]u <Plug> (Markdown_MoveToParentHeader)
429524 nmap <buffer> ]c <Plug> (Markdown_MoveToCurHeader)
525+ nmap <buffer> gx <Plug> (OpenUrlUnderCursor)
430526
431527 vmap <buffer> ]] <Plug> (Markdown_MoveToNextHeader)
432528 vmap <buffer> [[ <Plug> (Markdown_MoveToPreviousHeader)
0 commit comments