From 7f589ba4e99a761fd2aa2d3efaf83dda3a756d26 Mon Sep 17 00:00:00 2001 From: Michael Liebling Date: Sat, 7 May 2022 12:54:49 +0200 Subject: [PATCH] add support for TeXShop-MacVim --- README.md | 1 + autoload/health/vimtex.vim | 15 +++ autoload/vimtex/options.vim | 3 + autoload/vimtex/view/texshop.vim | 196 +++++++++++++++++++++++++++++++ doc/vimtex.txt | 83 +++++++++++++ 5 files changed, 298 insertions(+) create mode 100644 autoload/vimtex/view/texshop.vim diff --git a/README.md b/README.md index e1a85f140e..9edcd482c1 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,7 @@ by default and must be manually enabled. - [qpdfview](https://launchpad.net/qpdfview) - [Skim](http://skim-app.sourceforge.net/) - [SumatraPDF](http://www.sumatrapdfreader.org/free-pdf-reader.html) + - [TeXShop](https://pages.uoregon.edu/koch/texshop/) - [Zathura](https://pwmt.org/projects/zathura/) - Other viewers are supported through a general interface - Completion of diff --git a/autoload/health/vimtex.vim b/autoload/health/vimtex.vim index feccacf5f7..aae8e911bd 100644 --- a/autoload/health/vimtex.vim +++ b/autoload/health/vimtex.vim @@ -133,3 +133,18 @@ function! s:check_view_skim() abort " {{{1 endfunction " }}}1 +function! s:check_view_texshop() abort " {{{1 + let l:cmd = join([ + \ 'osascript -e ', + \ '''tell application "Finder" to POSIX path of ', + \ '(get application file id (id of application "TeXShop") as alias)''', + \]) + + if system(l:cmd) + call health#report_error('TeXShop is not installed!') + else + call health#report_ok('TeXShop viewer should work!') + endif +endfunction + +" }}}1 diff --git a/autoload/vimtex/options.vim b/autoload/vimtex/options.vim index 6ed89ab09a..7b6af2276a 100644 --- a/autoload/vimtex/options.vim +++ b/autoload/vimtex/options.vim @@ -459,6 +459,7 @@ function! vimtex#options#init() abort " {{{1 call s:init_option('vimtex_view_skim_activate', 0) call s:init_option('vimtex_view_skim_sync', 0) call s:init_option('vimtex_view_skim_reading_bar', 0) + call s:init_option('vimtex_view_texshop_activate', 0) call s:init_option('vimtex_view_zathura_options', '') call s:init_option('vimtex_view_zathura_check_libsynctex', 1) @@ -540,6 +541,8 @@ function! s:check_for_deprecated_options() abort " {{{1 \ 'g:vimtex_view_mupdf_hook_view', \ 'g:vimtex_view_skim_hook_callback', \ 'g:vimtex_view_skim_hook_view', + \ 'g:vimtex_view_texshop_hook_callback', + \ 'g:vimtex_view_texshop_hook_view', \ 'g:vimtex_view_zathura_hook_callback', \ 'g:vimtex_view_zathura_hook_view', \], 'exists(v:val)') diff --git a/autoload/vimtex/view/texshop.vim b/autoload/vimtex/view/texshop.vim new file mode 100644 index 0000000000..58c5a37cdf --- /dev/null +++ b/autoload/vimtex/view/texshop.vim @@ -0,0 +1,196 @@ +" texshop.vim +" +" SHORT DESCRIPTION +" Support for TeXShop as a pdf viewer on Mac OS X +" in conjunction with Karl Yngve Lervåg's vimtex +" package for vim. +" +" LONG DESCRIPTION +" texshop.vim aims to support TeXShop as a viewer, +" following the approach suggested by TeXShop developer +" Richard Koch for interaction with external editors +" in TeXShop release notes for versions 4.24 and 4.25: +" https://pages.uoregon.edu/koch/texshop/changes_3.html +" +" texshop.vim calls TeXShop directly via an embedded +" AppleScript rather than calling an intermediary +" bash script (which is what was described by Koch). +" Note that when TeXShop is used as a viewer for +" PDF files created via a .tex file, with +" an external editor, it wants to know about the .tex +" file rather than the PDF (as TeXShop is able to trigger +" compilation on its own, with a built-in console and +" Goto error button, which takes the user directly to the +" correct line in the corresponding .tex file, in the +" preferred text editor, provided it is set up correctly.). +" +" SETTING UP TeXShop TO INTERACT WITH MacVim +" +" Setup for TeXShop to interact correctly with MacVim +" +" 1. TeXShop requires the following preferences to be set: +" +" defaults write TeXShop OtherEditorSync YES +" defaults write TeXShop UseExternalEditor -bool true +" +" 2. When using an external editor with TeXShop, it +" expects to find a script /usr/local/bin/othereditor +" which it can call when syncing to the .tex file. The +" content of the script should be as follows: +" +" #!/bin/bash +" TEXLINE=$1 +" TEXFILE=$2 +" /usr/local/bin/mvim --remote-silent +$TEXLINE "$TEXFILE" +" +" This file needs to be executable: +" chmod +x /usr/local/bin/othereditor +" +" 3. .vimrc should contain set the vimtex_view_method to 'texshop' +" let g:vimtex_view_method='texshop' +" and, depending on whether the pdf window is to be activated +" (brought to the foreground) upon compilation completion or +" request for view update, set the variable to true (1) or false (0): +" let g:vimtex_view_texshop_activate=1 +" Note that the first time the tex is compiled, +" TeXShop will be ready but the document won't be visible until +" lv is called to show the document (if the variable is +" set to 1, the focus will be on the window, if it is 9 it will +" remain in the background.) +" +" SUPPORTED FEATURES +" +" 1. Command-click (in TeXShop) in a PDF created with pdftex +" compilation option --synctex=1 will take user to MacVim +" at the corresponding line in the .tex source code. +" 2. lv within MacVim will take user to the +" corresponding place in the PDF, within TeXShop. +" 3. If the PDF is compiled with TeXShop and an error arises, +" the 'Goto Error' button in TeXShop's compilation console +" window (or using the keyboard shortcut ⌘^E) will take the +" user to the error line in MacVim. +" +" CREATION HISTORY +" Nov 1 2020 This file (texshop.vim) was created by Michael Liebling +" and is largely based on skim.vim (from the vimtex +" package) and the scripts described in the TeXShop +" release notes for version 4.24 and 4.25. +" Minor parts were also inspired from a former latex-suite +" implementation. + +function! vimtex#view#texshop#new() abort " {{{1 + " Check if TeXShop is installed + let l:cmd = join([ + \ 'osascript -e ', + \ '''tell application "Finder" to POSIX path of ', + \ '(get application file id (id of application "TeXShop") as alias)''', + \]) + + if system(l:cmd) + call vimtex#log#error('TeXShop is not installed!') + return {} + endif + + augroup vimtex_view_texshop + autocmd! + autocmd User VimtexEventCompileSuccess + \ call vimtex#view#texshop#compiler_callback() + augroup END + + return vimtex#view#common#apply_common_template(deepcopy(s:texshop)) +endfunction + +" }}}1 +function! vimtex#view#texshop#compiler_callback() abort " {{{1 + if !exists('b:vimtex.viewer') | return | endif + let self = b:vimtex.viewer + if !filereadable(self.out()) | return | endif + + let l:cmd = join([ + \ 'osascript', + \ '-e ''set theFile to POSIX file "' . self.out() . '"''', + \ '-e ''set thePath to POSIX path of (theFile as alias)''', + \ '-e ''tell application "TeXShop"''', + \ '-e ''try''', + \ '-e ''set theDocs to get documents whose path is thePath''', + \ '-e ''if (count of theDocs) > 0 then revert theDocs''', + \ '-e ''end try''', + \ '-e ''open theFile''', + \ '-e ''end tell''', + \]) + + let b:vimtex.viewer.process = vimtex#process#start(l:cmd) +endfunction + +" }}}1 + +let s:texshop = { + \ 'name' : 'TeXShop', + \ 'starttexshop' : 'open -a TeXShop', + \} + +function! s:texshop.view(file) dict abort " {{{1 + if empty(a:file) + let outfile = self.out() + + " Only copy files if they don't exist + if g:vimtex_view_use_temp_files + \ && vimtex#view#common#not_readable(outfile) + call self.copy_files() + endif + else + let outfile = a:file + endif + if vimtex#view#common#not_readable(outfile) | return | endif + +" Define variables for the source file, line and column numbers: + let sourcefile = shellescape(expand('%'), 1) + let sourcefileFull = shellescape(expand('%:p'), 1) + let linenr = line('.') + let colnr = col('.') + +" The applescript described in +" https://pages.uoregon.edu/koch/texshop/changes_3.html +" (Release notes for TeXShop 4.25) is directly integrated +" below: + let l:cmd = join([ + \ 'osascript', + \ '-e ''set MyAppVarLine to ' . linenr . ' as integer''', + \ '-e ''set MyAppVarCol to ' . colnr . ' as integer''', + \ '-e ''set MyAppVarTeXFile to "' . sourcefileFull . '"''', + \ '-e ''set MyAppVarPDFFile to "' . outfile . '"''', + \ '-e ''tell application "TeXShop"''', + \ '-e '' open MyAppVarTeXFile''', + \ '-e '' set the front_document to the front document''', + \ '-e '' tell front_document''', + \ '-e '' sync_preview_line theLine MyAppVarLine''', + \ '-e '' sync_preview_index theIndex MyAppVarCol''', + \ '-e '' sync_preview_name theName MyAppVarTeXFile''', + \ g:vimtex_view_texshop_activate ? '-e ''activate''' : '', + \ '-e '' return 0''', + \ '-e '' end tell''', + \ '-e ''end tell''', + \]) +" An alternative way of defining the command could have been +" to use a bash script that encapsulates the Applescript (has +" the advantage that the bashscript can be tested on its own) +" let l:cmd = '/usr/local/bin/ExternalSync ' +" let l:cmd .= join([linenr, colnr , sourcefileFull, outfile]) + + let self.process = vimtex#process#start(l:cmd) + + if exists('#User#VimtexEventView') + doautocmd User VimtexEventView + endif +endfunction + +" }}}1 +function! s:texshop.latexmk_append_argument() dict abort " {{{1 + if g:vimtex_view_use_temp_files || g:vimtex_view_automatic + return ' -view=none' + else + return vimtex#compiler#latexmk#wrap_option('pdf_previewer', self.starttexshop) + endif +endfunction + +" }}}1 diff --git a/doc/vimtex.txt b/doc/vimtex.txt index 22e8309b99..da3a14a571 100644 --- a/doc/vimtex.txt +++ b/doc/vimtex.txt @@ -98,6 +98,7 @@ CONTENTS *vimtex-contents* Sioyek |vimtex-view-sioyek| Skim |vimtex-view-skim| SumatraPDF |vimtex-view-sumatrapdf| + TeXShop |vimtex-view-texshop| Zathura |vimtex-view-zathura| Synctex |vimtex-synctex| Forward search |vimtex-synctex-forward-search| @@ -5284,6 +5285,23 @@ Note: There is a known issue with VimTeX + SumatraPDF when you use `xelatex`, A workaround was found and posted by @Whitebeard0 here: https://github.com/lervag/vimtex/issues/1410#issuecomment-506143020 + + *vimtex-view-texshop* +TeXShop~ +https://pages.uoregon.edu/koch/texshop/index.html +TeXShop is a TeX front end program for macOS, specifically, it allows +editing TeX-related files in a dedicated editor (which can be replaced +by other external editors such as MacVim), provides a front-end to +call TeX programs to process source files, and provides a PDF viewer +that supports syncing with the corresponding source. |vimtex| supports +forward searches (source to PDF) with TeXShop. + +Note: See |vimtex-faq-texshopviewer| for more info on how to properly set +up the TeXShop viewer for backward search. + + + + *vimtex-view-zathura* Zathura~ https://pwmt.org/projects/zathura/ @@ -5808,6 +5826,71 @@ A: Yes, it should work. The following recipe has been reported to work [0]. [0]: https://github.com/lervag/vimtex/issues/1737#issuecomment-759953886 [1]: https://brew.sh + +------------------------------------------------------------------------------ + *vimtex-faq-texshopviewer* +Q: How do I properly set up vimtex with TeXShop? +A: (Note: Tested for MacVim only) + Set |g:vimtex_view_method| to `texshop` (and read |vimtex-view-texshop| if you + did not already do so). Forward search should just work. Backward search + (Command-clicking on a location in the PDF displayed by TeXShop to reach + the corresponding location in the source file) requires several + configuration steps. + + First, TeXShop requires the following preferences to be set (the first + one is a hidden preference, the second one could be set within TeXShop's + preference pane): + + defaults write TeXShop OtherEditorSync YES + defaults write TeXShop UseExternalEditor -bool true + + (Note that the above are terminal commands that are to be run just once, + as they modify TeXShop's preference file in + ~/Library/Preferences/TeXShop.plist + and therefore persist through sessions.) + + To support backward search when using an external editor, TeXShop expects + to find a script: + + /usr/local/bin/othereditor + + that it can call when backward jumping to the correct position in the + .tex file. If using MacVim (mvim) as the external editor, the content + of that script should be: + + #!/bin/bash + TEXLINE=$1 + TEXFILE=$2 + /usr/local/bin/mvim --remote-silent +$TEXLINE "$TEXFILE" + + This script file needs to be executable: + chmod +x /usr/local/bin/othereditor + + If you wish for the TeXShop window to pop to the front during forward + search, set (e.g. in your .vimrc): + let g:vimtex_view_texshop_activate=1 + otherwise (to keep the TeXShop window in the background) set + let g:vimtex_view_texshop_activate=0 + + Note that since TeXShop is a front end to various compilers, + it could also be used for compiling the .tex files (instead of + using vimtex's compilation mechanism). If the PDF is compiled + with TeXShop and an error arises, the 'Goto Error' + button in TeXShop's compilation console window (or using the + keyboard shortcut Command-Control-E) will take the user to + the error line in MacVim. + + Some related information on backward searches with external editors + may be found in the TeXShop release notes, specifically the ones + describing changes in versions 4.24 and 4.25: + + https://pages.uoregon.edu/koch/texshop/changes_3.html + + + + + + ============================================================================== TROUBLESHOOTING *vimtex-troubleshooting*