Created
February 15, 2023 09:24
-
-
Save 14mRh4X0r/5819f10a45013280f3c7abd27b8ae1cd to your computer and use it in GitHub Desktop.
Evince view implementation for VimTeX
This file contains hidden or 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
" VimTeX - LaTeX plugin for Vim | |
" | |
" Maintainer: Karl Yngve Lervåg | |
" Email: [email protected] | |
" | |
function! vimtex#view#evince#new() abort " {{{1 | |
call vimtex#jobs#run("gdbus wait --session --activate org.gnome.evince.Daemon") | |
return s:viewer.init() | |
endfunction | |
" }}}1 | |
let s:viewer = vimtex#view#_template#new({'name': 'evince'}) | |
function! s:viewer._check() dict abort " {{{1 | |
" Check if evince is executable | |
if !executable("evince") | |
call vimtex#log#error('evince is not executable!') | |
return v:false | |
elseif !executable("gdbus") | |
call vimtex#log#error('gdbus is not executable!') | |
return v:false | |
endif | |
return v:true | |
endfunction | |
function! s:url_encode_char(char) abort " {{{1 | |
let encoded = "" | |
" Iterate over bytes, because files can contain utf-8 characters | |
let i = 0 | |
while i < strlen(a:char) | |
let encoded = encoded .. strpart(a:char, i, 1)->char2nr()->printf("%%%02x") | |
let i += 1 | |
endwhile | |
return encoded | |
endfunction | |
function! s:url_encode(path) abort " {{{1 | |
return "file://" .. substitute(a:path, "[^A-Za-z0-9_.~/-]", {m -> s:url_encode_char(m[0])}, 'g') | |
endfunction | |
function! s:evince_dest(outfile, open) abort " {{{1 | |
let l:cmd = 'gdbus call --session' | |
\ .. ' --dest org.gnome.evince.Daemon' | |
\ .. ' --object-path /org/gnome/evince/Daemon' | |
\ .. ' --method org.gnome.evince.Daemon.FindDocument' | |
\ .. ' ' .. s:url_encode(a:outfile) | |
\ .. ' ' .. (a:open ? 'true' : 'false') | |
let dest = vimtex#jobs#capture(l:cmd)[0]->substitute("('\\([^']*\\)',)", "\\1", "") | |
if !has('nvim') | |
if has_key(s:viewer, 'job') | call job_stop(s:viewer.job) | endif | |
let s:viewer.job = job_start(['gdbus', 'monitor', | |
\ '--session', | |
\ '--dest', dest, | |
\ '--object-path', '/org/gnome/evince/Window/0' | |
\], {'out_cb': function("vimtex#view#evince#handle_monitor")}) | |
endif | |
return dest | |
endfunction | |
function! s:viewer._exists() dict abort " {{{1 | |
return !s:evince_dest(self.out(), v:false)->empty() | |
endfunction | |
function! s:sync_view(dest) abort " {{{1 | |
let l:cmd = 'gdbus call --session' | |
\ .. ' --dest ' .. a:dest | |
\ .. ' --object-path /org/gnome/evince/Window/0' | |
\ .. ' --method org.gnome.evince.Window.SyncView' | |
\ .. ' ' .. expand('%:p:S') | |
\ .. ' ' .. printf("'(%d,%d)'", line('.'), col('.')) | |
\ .. ' ' .. strftime("%s") | |
call vimtex#jobs#run(l:cmd) | |
endfunction | |
function! s:viewer._start(outfile) dict abort " {{{1 | |
let dest = s:evince_dest(a:outfile, v:true) | |
call s:sync_view(dest) | |
endfunction | |
function! vimtex#view#evince#handle_monitor(channel, msg) abort " {{{1 | |
if a:msg[0] != "/" | return | endif | |
let l:parts = split(a:msg) | |
if l:parts[1] != "org.gnome.evince.Window.SyncSource" | return | endif | |
let l:file = substitute(l:parts[2], "('file://\\(.*\\)',", "\\1", "") | |
let l:line = str2nr(l:parts[3][1:]) | |
call vimtex#view#inverse_search(l:line, l:file) | |
endfunction | |
function! s:viewer._forward_search(outfile) dict abort " {{{1 | |
let dest = s:evince_dest(a:outfile, v:false) | |
if empty(dest) | return | endif | |
call s:sync_view(dest) | |
endfunction | |
" }}}1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment