Last active
February 9, 2021 22:50
-
-
Save Vftdan/86c8b48320cf425e923552e4573d50c8 to your computer and use it in GitHub Desktop.
Vim gemini:// protocol plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function! s:read_gemini(url) | |
call s:init_go_url() | |
function! s:init_go_url() | |
endfunction | |
let l:svpos = winsaveview() | |
setlocal bl ro noswapfile | |
if &ft == '' | |
setlocal ft=gmi | |
else | |
let &ft=&ft | |
endif | |
exe "%read !gmni -j once " . shellescape(a:url) . ' 2>/dev/null' | |
keepjumps normal! ggJ | |
keepjumps call winrestview(l:svpos) | |
if len(join(getline(0, line('$')))) == 0 && match(a:url, '?') == -1 | |
let l:url = a:url . '?' . input('query: ') | |
0file | |
exe 'file ' . fnameescape(l:url) | |
call s:read_gemini(l:url) | |
endif | |
endfunction | |
function! s:getsel() | |
let l:save = @a | |
norm! gv"ay | |
let l:res = @a | |
let @a = l:save | |
return l:res | |
endfunction | |
aug GeminiProtocol | |
au! | |
au BufReadCmd gemini://* exe "sil doau BufReadPre ".fnameescape(expand("<amatch>"))|call s:read_gemini(expand("<amatch>"))|exe "sil doau BufReadPost ".fnameescape(expand("<amatch>")) | |
au FileReadCmd gemini://* exe "sil doau FileReadPre ".fnameescape(expand("<amatch>"))|call s:read_gemini(expand("<amatch>"))|exe "sil doau FileReadPost ".fnameescape(expand("<amatch>")) | |
aug END | |
function! s:init_go_url() | |
" if has('python3') | |
" py3 from urllib.parse import urljoin, uses_relative, uses_netloc | |
" py3 uses_relative.append('gemini') | |
" py3 uses_netloc.append('gemini') | |
function! s:gemini_go_url(url) | |
" let l:path = py3eval('urljoin(vim.eval("@%"), vim.eval("a:url"))') | |
" exe "e " . fnameescape(l:path) | |
if match(@%, '\v^gemini\:\/\/') < 0 | |
" Should be unreachable | |
exe 'edit ' . fnameescape(a:url) | |
endif | |
let l:base = substitute(@%, '\v[\?\#].*$', '', '') | |
" TODO properly handle paths starting from '?', '#' (are they supported in gemini?) | |
if match(a:url, '\v^[^\/]{-1,}($|[^\:\/]\/)') >= 0 | |
" Relative | |
if match(l:base, '\v\c^gemini\:\/\/[^/]+\/.*[^\/]$') >= 0 | |
let l:base = substitute(l:base, '\v\c^gemini\:\/\/[^/]+\/(.+\/)?\zs[^\/]+$', '', '') | |
endif | |
if split(l:base, '\zs')[-1] != '/' | |
let l:base .= '/' | |
endif | |
let [l:base, l:oldurl] = split(l:base, '\v\c^gemini\:\/\/[^/]+\zs', 1) | |
exe 'edit ' . fnameescape(l:base . simplify(l:oldurl . a:url)) | |
elseif match(a:url, '\v^\/\/') >= 0 | |
" Another domain | |
exe 'edit ' . fnameescape('gemini:' . simplify(a:url)) | |
elseif match(a:url, '\v^\/') >= 0 | |
" Root on the same domain | |
exe 'edit ' . fnameescape(substitute(l:base, '\v\c^(gemini\:\/\/[^/]+).*$', '\1', '') . simplify(a:url)) | |
else | |
exe 'edit ' . fnameescape(a:url) | |
endif | |
return '' | |
endfunction | |
nnoremap <silent> <Plug>(gemini-protocol-go-url) <cmd>call <SID>gemini_go_url(expand('<cfile>'))<cr> | |
vnoremap <silent> <Plug>(gemini-protocol-go-url) <cmd>call <SID>gemini_go_url(<SID>getsel())<cr> | |
if !(has('g:gemini_protocol_no_gf') && g:gemini_protocol_no_gf) | |
aug GeminiProtocol | |
au BufReadPost gemini://* nmap <buffer> gf <Plug>(gemini-protocol-go-url) | |
au BufReadPost gemini://* vmap <buffer> gf <Plug>(gemini-protocol-go-url) | |
au FileReadPost gemini://* nmap <buffer> gf <Plug>(gemini-protocol-go-url) | |
au FileReadPost gemini://* vmap <buffer> gf <Plug>(gemini-protocol-go-url) | |
aug END | |
endif | |
" endif | |
endfunction |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment