Skip to content

Commit

Permalink
Add support for visual mode gx/gf (#119)
Browse files Browse the repository at this point in the history
  • Loading branch information
SidOfc committed Sep 11, 2020
1 parent 41b1d9a commit 790bfa5
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 8 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -772,7 +772,8 @@ To overwrite a setting while editing:

mkdx enhances <kbd>g</kbd><kbd>f</kbd> and <kbd>g</kbd><kbd>x</kbd> within markdown buffers.
The main difference is that you can open files / urls / images with the cursor positioned anywhere
in a markdown link. Otherwise they will work normally.
in a markdown link. Additionally, these mappings can also be used in visual mode and
will be applied to the current selection in that case. Otherwise they will work normally.

By enabling this setting, these two mappings are merged into one, so both <kbd>g</kbd><kbd>f</kbd> and <kbd>g</kbd><kbd>x</kbd>
will work exactly the same. Functionalities from both will work for each mapping, so you can now
Expand All @@ -784,7 +785,7 @@ wether or not a file is an image and should be opened by an external application
For other files such as `doc` or `pdf` mkdx relies on the [`file`](https://man7.org/linux/man-pages/man1/file.1.html)
command to determine if a file should be opened inside (n)vim or using for example libreoffice.

mkdx uses `open` behind the scenes, on macOS this will work out of the box,
mkdx uses `open` / `xdg-open` behind the scenes, on macOS this will work out of the box,
on linux make sure the [`xdg-utils`](https://www.freedesktop.org/wiki/Software/xdg-utils/) package
is installed and that you can run `open https://github.com`.
`xdg-utils` can be installed by running `sudo apt install xdg-utils` in your terminal.
Expand Down Expand Up @@ -1492,7 +1493,9 @@ To prevent mapping of a key from happening, see: [unmapping functionality](#unma
|<kbd>ctrl</kbd>+<kbd>p</kbd> handler|insert|<kbd>ctrl</kbd>+<kbd>p</kbd>|`<Plug>(mkdx-ctrl-p-compl)`|
|<kbd>#</kbd> handler|insert|<kbd>#</kbd>|`<Plug>(mkdx-link-compl)`|
|Jump to file|normal|<kbd>g</kbd><kbd>f</kbd>|`<Plug>(mkdx-gf)`|
|Jump to file|visual|<kbd>g</kbd><kbd>f</kbd>|`<Plug>(mkdx-gf-visual)`|
|Open external file|normal|<kbd>g</kbd><kbd>x</kbd>|`<Plug>(mkdx-gx)`|
|Open external file|visual|<kbd>g</kbd><kbd>x</kbd>|`<Plug>(mkdx-gx-visual)`|
|Indent numbered list item|<kbd>tab</kbd>|`<Plug>(mkdx-indent)`|
|Unindent numbered list item|<kbd>shift</kbd>+<kbd>tab</kbd>|`<Plug>(mkdx-unindent)`|
Expand Down
34 changes: 34 additions & 0 deletions autoload/mkdx.vim
Original file line number Diff line number Diff line change
Expand Up @@ -2079,6 +2079,40 @@ fun! mkdx#in_rtp(relative_path)
return 0
endfun

" credits: https://stackoverflow.com/a/6271254/2224331 answer by xolox.
function! s:util.get_visual_selection()
" Why is this not a built-in Vim script function?!
let [line_start, column_start] = getpos("'<")[1:2]
let [line_end, column_end] = getpos("'>")[1:2]
let lines = getline(line_start, line_end)
if len(lines) == 0
return ''
endif
let lines[-1] = lines[-1][: column_end - (&selection == 'inclusive' ? 1 : 2)]
let lines[0] = lines[0][column_start - 1:]
return join(lines, "\n")
endfunction

fun! mkdx#gf_visual(...)
let mode = get(a:000, 0, 'f')
let do_ext = !g:mkdx#settings.gf_on_steroids && mode ==? 'x'
let do_int = !g:mkdx#settings.gf_on_steroids && mode ==? 'f'

let destination = substitute(s:util.get_visual_selection(), "\n", '', 'g')
let is_img = match(get(split(destination, '\.'), -1, ''), g:mkdx#settings.image_extension_pattern) > -1
let mime = s:util.getMimeType(destination)
let is_plain = mime =~? '^text' || mime =~? '^inode/x-empty'

if !do_int && (do_ext || destination =~? '^http' || is_img || !is_plain)
let cmd = executable('open') ? 'open' : (executable('xdg-open') ? 'xdg-open' : '')
if (!empty(cmd))
silent! exec '!' . cmd . ' ' . shellescape(substitute(destination, '#', '\\#', 'g'))
endif
elseif (filereadable(destination))
exe 'edit' destination
endif
endfun

fun! mkdx#gf(...)
let mode = get(a:000, 0, 'f')
let cpos = getpos('.')
Expand Down
51 changes: 46 additions & 5 deletions doc/mkdx.txt
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ Settings `.......................................................` |mkdx-setting
*mkdx-toc-highlighting*
Highlighting `...............................................` |mkdx-highlighting|
mkdxYAMLHeader `...........................` |mkdx-highlight-yaml-frontmatter|
mkdxTOMLHeader `...........................` |mkdx-highlight-TOML-frontmatter|
mkdxJSONHeader `...........................` |mkdx-highlight-JSON-frontmatter|
mkdxListItem `....................................` |mkdx-highlight-list-item|
mkdxCheckboxEmpty `..........................` |mkdx-highlight-checkbox-empty|
mkdxCheckboxPending `......................` |mkdx-highlight-checkbox-pending|
Expand Down Expand Up @@ -157,6 +159,8 @@ Plugs `.............................................................` |mkdx-plug
<Plug>(mkdx-fence-backtick) `.....................` |mkdx-plug-fence-backtick|
<Plug>(mkdx-gf) `.............................................` |mkdx-plug-gf|
<Plug>(mkdx-gx) `.............................................` |mkdx-plug-gx|
<Plug>(mkdx-gf-visual) `............................... `|mkdx-plug-gf-visual|
<Plug>(mkdx-gx-visual) `...............................` |mkdx-plug-gx-visual|
<Plug>(mkdx-indent) `.....................................` |mkdx-plug-indent|
<Plug>(mkdx-unindent) `.................................` |mkdx-plug-unindent|

Expand Down Expand Up @@ -218,6 +222,7 @@ Functions `.....................................................` |mkdx-function
mkdx#WrapText() `..................................` |mkdx-function-wrap-text|
mkdx#WrapStrike() `..............................` |mkdx-function-wrap-strike|
mkdx#gf() `...............................................` |mkdx-function-gf|
mkdx#gf_visual() `.................................` |mkdx-function-gf-visual|
mkdx#MaybeRestoreVisual() `.............` |mkdx-function-maybe-restore-visual|
mkdx#IndentHandler() `........................` |mkdx-function-indent-handler|

Expand Down Expand Up @@ -966,9 +971,20 @@ mkdxYAMLHeader *mkdx-highlight-yaml-frontmatter*
This syntax group does not apply its own highlighting, but rather allows
|yaml| highlighting to be active in a markdown frontmatter block.

This will only be activated if `syntax/yaml.vim` is found in 'rtp', if
it is found but including it fails for some other reason this group will still
be created, but highlighting will not be applied
This will only be activated if `syntax/yaml.vim` is found in 'rtp' and
|mkdx-setting-highlight-frontmatter-yaml| is enabled. If `syntax/yaml.vim`
is found but including it fails for some other reason this group
will still be created, but highlighting will not be applied.

==============================================================================
mkdxTOMLHeader *mkdx-highlight-toml-frontmatter*

Like |mkdx-highlight-yaml-frontmatter| but for TOML frontmatter.

==============================================================================
mkdxJSONHeader *mkdx-highlight-json-frontmatter*

Like |mkdx-highlight-yaml-frontmatter| but for JSON frontmatter.

==============================================================================
mkdxListItem *mkdx-highlight-list-item*
Expand Down Expand Up @@ -1309,6 +1325,16 @@ using {repeat.vim} by Tim Pope (https://github.com/tpope/vim-repeat).

`:<C-U>call mkdx#gf('x')<Cr>`

==============================================================================
<Plug>(mkdx-gf-visual) *mkdx-plug-gf-visual*

`:<C-U>call mkdx#gf_visual('f')<Cr>`

==============================================================================
<Plug>(mkdx-gx-visual) *mkdx-plug-gx-visual*

`:<C-U>call mkdx#gf_visual('x')<Cr>`

==============================================================================
<Plug>(mkdx-indent) *mkdx-plug-indent*

Expand Down Expand Up @@ -1666,6 +1692,9 @@ This mapping works like regular |gf| unless the cursor is positioned on a
markdown link. When on a link, mkdx will open the file inbetween the
parentheses. The cursor can be anywhere on the link and this will work.

This mapping also works in |Visual-Mode|. When used in visual mode, the
selection is used as the destination.

when |mkdx-setting-gf-on-steroids| is enabled, and link is not a file but a URL,
mkdx will use an `open` shell command. If `open` is not available, it will
silently fail.
Expand All @@ -1675,12 +1704,15 @@ Open external file *mkdx-mapping-open-external-file*
gx

This mapping emulates |netrw-gx| (also works without netrw enabled). It will
open an external application using the `open` shell command. If `open` is not
available, it will silently fail.
open an external application using the `open` or `xdg-open` shell command.
If neither `open` or `xdg-open` are not available, it will silently fail.

Like |mkdx-mapping-jump-to-file| it will also work on markdown links, the
cursor can be positioned anywhere on the link and this will work.

This mapping also works in |Visual-Mode|. When used in visual mode, the
selection is used as the destination.

When |mkdx-setting-gf-on-steroids| is enabled, this mapping will also read
local files just like |mkdx-mapping-jump-to-file| otherwise would.

Expand Down Expand Up @@ -2401,6 +2433,15 @@ the "correct" implementation is used based on what is found. If it looks like
an image or URL, `open` will be used, otherwise |mkdx-mapping-jump-to-file|
will be used.

==============================================================================
mkdx#gf_visual([{mode}]) *mkdx-function-gf-visual*

This function mimicks |mkdx-function-gf| but in visual mode. Selecting text
and pressing <gf> / <gx> will apply the mapping on the selection instead.

This is useful in scenarios where |mkdx-function-gf| does not work properly
(yet) as a fallback method.

==============================================================================
mkdx#MaybeRestoreVisual() *mkdx-function-maybe-restore-visual*

Expand Down
6 changes: 5 additions & 1 deletion ftplugin/markdown/mkdx.vim
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ noremap <silent> <Plug>(mkdx-shift-o) :<C-U>call mkdx#ShiftOH
noremap <silent> <Plug>(mkdx-o) :<C-U>call mkdx#OHandler()<Cr>
noremap <silent> <Plug>(mkdx-gf) :<C-U>call mkdx#gf('f')<Cr>
noremap <silent> <Plug>(mkdx-gx) :<C-U>call mkdx#gf('x')<Cr>
noremap <silent> <Plug>(mkdx-gf-visual) :<C-U>call mkdx#gf_visual('f')<Cr>
noremap <silent> <Plug>(mkdx-gx-visual) :<C-U>call mkdx#gf_visual('x')<Cr>
inoremap <silent> <Plug>(mkdx-enter) <C-R>=mkdx#EnterHandler()<Cr>:setlocal autoindent<Cr>
inoremap <silent> <Plug>(mkdx-shift-enter) <C-R>=mkdx#ShiftEnterHandler()<Cr>
inoremap <silent> <Plug>(mkdx-insert-kbd) <kbd></kbd>F<
Expand Down Expand Up @@ -117,7 +119,9 @@ if g:mkdx#settings.map.enable == 1
\ ['Backtick\ fenced\ code\ block', 0, 'i', '```', '<Plug>(mkdx-fence-backtick)', '<C-R>=mkdx#FencedCodeBlock("`")<Cr>kA'],
\ ['tilde\ fenced\ code\ block', 0, 'i', '~~~', '<Plug>(mkdx-fence-tilde)', '<C-R>=mkdx#FencedCodeBlock("~")<Cr>kA'],
\ ['Jump to file / open URL', 0, 'n', 'gf', '<Plug>(mkdx-gf)', ':<C-U>call mkdx#gf("f")<Cr>'],
\ ['Jump to file / open URL', 0, 'n', 'gx', '<Plug>(mkdx-gx)', ':<C-U>call mkdx#gf("x")<Cr>']
\ ['Jump to file / open URL', 0, 'n', 'gx', '<Plug>(mkdx-gx)', ':<C-U>call mkdx#gf("x")<Cr>'],
\ ['Jump to file / open URL', 0, 'v', 'gf', '<Plug>(mkdx-gf-visual)', ':<C-U>call mkdx#gf_visual("f")<Cr>'],
\ ['Jump to file / open URL', 0, 'v', 'gx', '<Plug>(mkdx-gx-visual)', ':<C-U>call mkdx#gf_visual("x")<Cr>']
\ ]

if (!hasmapto('<Plug>(mkdx-gf)', 'n'))
Expand Down

0 comments on commit 790bfa5

Please sign in to comment.