Search code examples
vimvim-plugin

Vim - set custom editors to open `.md` & '.pdf' files


According to this official guide it is possible to determine your own editors that are called per the filename suffix when in VIM we use command g + x (while cursor is over a file name or URI).

This partially works for me. I used this block of code in the ~/.vimrc file:

" make sure that viewer is selected according to the suffix.
let g:netrw_browsex_viewer="-"

" functions for file extension '.md'.
function! NFH_md(filename)
    typora filename
endfunction

" functions for file extension '.pdf'.
function! NFH_pdf(filename)
    zathura filename
endfunction

Now I use Vim to open a source file e.g. main.c and navigate to these two line comments:

// EXAMPLE: ../../001--documentation/motorola--SREC_format.pdf
// EXAMPLE: ./markdown.md

If I hover with the cursor over the 1st one and press g + x I get this error:

Not an editor command:  zathura filename

If I hover with the cursor over the 2nd one and press g + x I get this error:

Not an editor command:  typora filename

So it looks like functions are executed according to a file suffix (this is good), but why isnt a file opened? I am probably missing the knowledge on how to properly pass an argument to the funmctions? What should I do to sucessfuly open the files with editors zathura and typora (both are installed on my system and can be run from the terminal)?


After @phd suggestions I tried this:

" make sure that viewer is selected according to the suffix.
let g:netrw_browsex_viewer="-"

" functions for file extension '.md'.
function! NFH_md(filename)
    :! typora filename
endfunction

" functions for file extension '.md'.
function! NFH_pdf(filename)
    :! zathura filename
endfunction

Which now opens the programs but it searches for the filename and can't find it. So function doesn't get the argument properly...

Errors are now:

error: Unknown file type: 'cannot open `/home/ziga/Dropbox/workspace/racunalnistvo/projects--pistam/2021-01-06--programmer_migration/002--sw/006/filename' (No such file or directory)'

and:

ENOENT: no such file or directory, open '/home/ziga/.../002--sw--006/filename

Also I read here that ! is not asynchronous and !start is a Windows only. I need Linux solution which is asynchronous.


Solution

  • The answer is:

    " make sure that viewer is selected according to the suffix.
    let g:netrw_browsex_viewer="-"
    
    " functions for file extension '.md'.
    function! NFH_md(f)
        execute '!typora' a:f
    endfunction
    
    " functions for file extension '.pdf'.
    function! NFH_pdf(f)
        execute '!zathura' a:f
    endfunction
    

    If execute is not used then a:f is not expanded.

    Note:

    This is not asynchronous solution!

    For an asynchronous solution we can install vim plugin asyncrun and change the above code to this:

    " make sure that viewer is selected according to the suffix.
    let g:netrw_browsex_viewer="-"
    
    " functions for file extension '.md'.
    function! NFH_md(f)
        call asyncrun#run("", "cwd", "typora " . a:f)
    endfunction
    
    " functions for file extension '.pdf'.
    function! NFH_pdf(f)
        call asyncrun#run("", "cwd" , "evince " . a:f)
    endfunction
    
    " functions for file extension '.html'.
    function! NFH_html(f)
        call asyncrun#run("", "cwd", "firefox --new-window " . a:f)
    endfunction
    

    TODO:

    With this there are very little annoying problems left. For example URI's ending in .com, .org, gov, php... aren't opened as it is virtually impossible to create a handler function for every possible top domain! There is another problem, because URI's to a PDF files that end with #page=100 or #some_chapter aren't opened. Similar is with markdown source files where '#some_chapter' is ignored.

    Here is a quick reference works and what does not (copy in vim, hoover over the URI / file and press g+x):

    // ✔ EXAMPLE (g + x): ./markdown.md
    // ✘ EXAMPLE (g + x): ./markdown.md#test
    // ✔ EXAMPLE (g + x): ../../001--documentation/motorola--SREC_format.pdf
    // ✘ EXAMPLE (g + x): ../../001--documentation/stm32--boot_mode_and_bootloader.pdf#page=2
    // ✔ EXAMPLE (g + x): ../../001--documentation/C_--_HTML_documentation/en/index.html
    // ✔ EXAMPLE (g + x): https://learnvimscriptthehardway.stevelosh.com/chapters/23.html
    // ✘ EXAMPLE (g + x): https://www.google.com
    // ✔ EXAMPLE (g + x): https://www.google.com/index.html
    // ✘ EXAMPLE (g + x): https://wiki.archlinux.org/index.php/HiDPI#GNOME
    // ✘ EXAMPLE (g + x): file:///home/ziga/Dropbox/workspace/racunalnistvo/projects/2021-01-06--programmer_migration/001--documentation/stm32--usart_protocol_used_to_talk_with_bootloader.pdf
    // ✘ EXAMPLE (g + x): file:///home/ziga/Dropbox/workspace/racunalnistvo/projects/2021-01-06--programmer_migration/001--documentation/stm32--usart_protocol_used_to_talk_with_bootloader.pdf#page=10
    

    If anyone finds a way to fix these problems or can write a vim plugin capable of opening these URIs it would be wonderful!