From c2dfc407b49edc7680df0fbdf28315e6ba4ac17e Mon Sep 17 00:00:00 2001 From: Stefan Huber Date: Sun, 6 Nov 2022 19:55:44 +0100 Subject: [PATCH 1/3] doc: rename "recursive search" to "directory scan" The method 6 of finding the main file is based on a directory scan which is described as "recursive" scan. However, while a recursive scan suggests a (recursive) directory descent, the opposite is true: the unique ascending path of parent directories is scanned. This is fixed in the following steps: 1. The method is renamed to "directory scan method". 2. The method description is adapted to reflect this behavior more clearly. In particular, it is explicitly mentioned that no recursive directory descent is performed. 3. The option to disable this method is renamed to g:vimtex_disable_directory_scan_main_file_detection 4. Some vimscript comments are fixed that actually mention an upwards recursion in the directory tree. As a side effect, the overall description of the directory scan method is reworked. As a further side effect, the name of this method is more independent of the algorithmic mechanism, but rather reflects the policy, cf. "policy versus mechanism" paradigm --- autoload/vimtex/options.vim | 1 + autoload/vimtex/state.vim | 2 +- doc/vimtex.txt | 80 +++++++++++++++++++++---------------- 3 files changed, 47 insertions(+), 36 deletions(-) diff --git a/autoload/vimtex/options.vim b/autoload/vimtex/options.vim index 8f62d24121..e329694b8b 100644 --- a/autoload/vimtex/options.vim +++ b/autoload/vimtex/options.vim @@ -487,6 +487,7 @@ function! s:check_for_deprecated_options() abort " {{{1 \ 'g:vimtex_change_set_formatexpr', \ 'g:vimtex_change_toggled_delims', \ 'g:vimtex_compiler_callback_hooks', + \ 'g:vimtex_disable_recursive_main_file_detection', \ 'g:vimtex_env_complete_list', \ 'g:vimtex_fold_commands', \ 'g:vimtex_fold_commands_default', diff --git a/autoload/vimtex/state.vim b/autoload/vimtex/state.vim index f29713931c..df97bae698 100644 --- a/autoload/vimtex/state.vim +++ b/autoload/vimtex/state.vim @@ -237,7 +237,7 @@ function! s:get_main() abort " {{{1 endif " Search for main file recursively through include specifiers - if !get(g:, 'vimtex_disable_recursive_main_file_detection', 0) + if !get(g:, 'vimtex_disable_directory_scan_main_file_detection', 0) if &filetype ==# 'tex' let l:candidate = s:get_main_choose(s:get_main_recurse()) if !empty(l:candidate) diff --git a/doc/vimtex.txt b/doc/vimtex.txt index d170933c1a..b47a570be9 100644 --- a/doc/vimtex.txt +++ b/doc/vimtex.txt @@ -323,23 +323,24 @@ VimTeX supports most multi-file documents and has several methods to locate the `main` document. Locating this file is very important, because the main file is the one that must be compiled. -The main method for locating the main file uses a recursive search algorithm -that should find the main LaTeX file in most cases (method 6 in the list -below). There are several alternative methods for specifying the main file -that can be more flexible and is relevant for certain work flows and use -cases. These alternative methods all require some explicit declaration of the -main file. Thus, these methods will be tried first, and the recursive search -is tried last if there are no explicit declarations that yield an appropriate -main LaTeX file candidate. +The default method for locating the main file uses a directory scan algorithm +that searches for a main LaTeX file, see method 6 below. It is expected to +work in the vast majority of cases. -The methods are tried in the following order: +There are several alternative methods for specifying the main file that can be +more flexible and are relevant for certain work flows and use cases. These +methods all require some explicit declaration of the main file and are +therefore tried prior to the directory scan. + +The complete list of methods in the order of priority is as follows and are +then described in more detail: 1. Buffer variable 2. TeX root directive 3. Subfiles package 4. File `.latexmain` specifier 5. Local `latexmkrc` file specifier (from `@default_files` option) - 6. Recursive search + 6. Directory scan *b:vimtex_main* Buffer variable~ @@ -447,34 +448,38 @@ Local latexmkrc file specifier~ Note: `@default_files` is a list of files, VimTeX will use the first entry that is found. -Recursive search~ - If no other method provides an appropriate candidate, then the recursive - search detects the main LaTeX file by searching for a file in the current - and parent directories that +Directory scan~ + If the above methods give no appropriate candidate for a main file of the + present file then a search for a suitable main file from the current + directory upwards is started. - 1. includes the present file (directly or indirectly), - 2. has a `\documentclass` line near the top of its parsed content, and - 3. contains `\begin{document}` in its parsed content. + To test whether a candidate tex file qualifies as a main file the following + happens: First, the candidate tex file is parsed and recursively expanded by + all tex files included. Then it is checked whether all of the following + three requirements are met in order to qualify as a main file for the + present file: - As long as a project follows these rules, the recursive search should work. - Notice, though, that the first point is important and is where the recursive - nature is implemented. There must be a "straight" inclusive line from the - main file to the present file. If not, then rule 1 is violated. + 1. It includes the present file, either directly or indirectly. + 2. The expanded content contains a `\documentclass` line near the top. + 3. The expanded content contains `\begin{document}`. - Let's consider a common construct that will fail: > + Note that the main file itself does not need to contain the `\documentclass` + line and `\begin{docment}`; it could instead stem from included tex files. - path1/main.tex - path2/chapter.tex -< - In this example, the main file does not live in the same folder or a parent - folder, and so the recursive search fails. + See details on |g:vimtex_include_indicators| for all commands that are + considered to include tex files by the parser for the recursive expansion. - In these cases where the recursive method fails, one may safely rely on the - TeX root directive as an alternative. + Note that no recursive directory descents are performed to find a main file. + That is, if the current file is `./B/chapter.tex` then `./A/main.tex` will not + be found as the main file, because the descent to subdirectory `./A/` is not + performed. + + In cases where automatic detection of the main file through the directory + scan fails, one may explicitly set up method 1 to 5 instead. Note: In rare cases, such as if there are _very_ many tex files in the directory tree, this method may be slow. One may therefore disable it - through the option |g:vimtex_disable_recursive_main_file_detection|. + by the option |g:vimtex_disable_directory_scan_main_file_detection|. ------------------------------------------------------------------------------ SUPPORT FOR TEX DIRECTIVES *vimtex-tex-directives* @@ -1493,11 +1498,11 @@ OPTIONS *vimtex-options* Default value: 500 -*g:vimtex_disable_recursive_main_file_detection* - In rare cases, the recursive method of finding the main file in multi file - projects may be slow. This might happen for instance when there are _very_ - many tex files in the directory tree that is searched. In such cases, one - may disable the recursive method by setting this variable to a nonzero +*g:vimtex_disable_directory_scan_main_file_detection* + In rare cases, the directory scan method of finding the main file in multi + file projects may be slow. This might happen for instance when there are + _very_ many tex files in the directories scanned. In such cases, one may + disable the directory scan method by setting this variable to a nonzero value. Default value: 0 @@ -6115,6 +6120,11 @@ The following changelog only logs particularly important changes, such as changes that break backwards compatibility. See the git log for the detailed changelog. +2022-11-05: Better main file detection algorithm~ +The detection whether a file is a main file has been improved. In course of +this *g:vimtex_disable_recursive_main_file_detection* has been deprecated in +favor of |g:vimtex_disable_directory_scan_main_file_detection|. + 2021-10-25: Better inverse search~ Deprecate *g:vimtex_compiler_progname* as it is no longer necessary. From e12a176f2cd9e8ce04c7da9a1368bd60aa79b1e4 Mon Sep 17 00:00:00 2001 From: Stefan Huber Date: Sun, 6 Nov 2022 19:54:24 +0100 Subject: [PATCH 2/3] chore: s:findfiles_recursive -> s:globpathupwards The static function s:findfiles_recursive(expr, path) in state.vim is actually not recursive, but iterates from path upwards in the directory tree. Furthermore, it is an extended version of globpath() with (basically) the same signature. Rename it to s:globpathupwards() to reflect this. --- autoload/vimtex/state.vim | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/autoload/vimtex/state.vim b/autoload/vimtex/state.vim index df97bae698..765974a819 100644 --- a/autoload/vimtex/state.vim +++ b/autoload/vimtex/state.vim @@ -340,7 +340,7 @@ endfunction " }}}1 function! s:get_main_latexmain(file) abort " {{{1 - for l:cand in s:findfiles_recursive('*.latexmain', expand('%:p:h')) + for l:cand in s:globpathupwards('*.latexmain', expand('%:p:h')) let l:cand = fnamemodify(l:cand, ':p:r') if s:file_reaches_current(l:cand) return l:cand @@ -394,9 +394,9 @@ function! s:get_main_recurse(...) abort " {{{1 let l:re_filter1 = fnamemodify(l:file, ':t:r') let l:re_filter2 = g:vimtex#re#tex_input . '\s*\f*' . l:re_filter1 - " Search through candidates found recursively upwards in the directory tree + " Search through candidates found upwards in the directory tree let l:results = [] - for l:cand in s:findfiles_recursive('*.tex', fnamemodify(l:file, ':p:h')) + for l:cand in s:globpathupwards('*.tex', fnamemodify(l:file, ':p:h')) if index(l:tried[l:file], l:cand) >= 0 | continue | endif call add(l:tried[l:file], l:cand) @@ -420,9 +420,9 @@ function! s:get_main_recurse_from_bib() abort " {{{1 let l:re_filter1 = fnamemodify(l:file, ':t:r') let l:re_filter2 = g:vimtex#re#bib_input . '\s*\f*' . l:re_filter1 - " Search through candidates found recursively upwards in the directory tree + " Search through candidates found upwards in the directory tree let l:results = [] - for l:cand in s:findfiles_recursive('*.tex', fnamemodify(l:file, ':p:h')) + for l:cand in s:globpathupwards('*.tex', fnamemodify(l:file, ':p:h')) if index(l:tried[l:file], l:cand) >= 0 | continue | endif call add(l:tried[l:file], l:cand) @@ -523,7 +523,9 @@ function! s:file_reaches_current(file) abort " {{{1 endfunction " }}}1 -function! s:findfiles_recursive(expr, path) abort " {{{1 +function! s:globpathupwards(expr, path) abort " {{{1 + " Returns the list of files obtained by globpath(p, expr) with p going from + " path upwards in the directory tree. let l:path = a:path let l:dirs = l:path while l:path != fnamemodify(l:path, ':h') From 80da48d52b8cd6a44aad2f3931e35d181410f7ef Mon Sep 17 00:00:00 2001 From: Stefan Huber Date: Sun, 6 Nov 2022 20:38:09 +0100 Subject: [PATCH 3/3] =?UTF-8?q?chore:=20Kill=20g:vimtex=5Fdisable=5F?= =?UTF-8?q?=E2=80=A6=5Fmain=5Ffile=5Fdetection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Performance evaluation for the work on PR #2558 gave evidence that disabling the directory scan method for the main file detection due to performance concerns appears to be unjustified. Remove this option. Note that recently g:vimtex_disable_recursive_main_file_detection has been renamed to g:vimtex_disable_directory_scan_main_file_detection. --- autoload/vimtex/state.vim | 20 +++++++++----------- doc/vimtex.txt | 18 ++---------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/autoload/vimtex/state.vim b/autoload/vimtex/state.vim index 765974a819..9ef4b130a0 100644 --- a/autoload/vimtex/state.vim +++ b/autoload/vimtex/state.vim @@ -237,17 +237,15 @@ function! s:get_main() abort " {{{1 endif " Search for main file recursively through include specifiers - if !get(g:, 'vimtex_disable_directory_scan_main_file_detection', 0) - if &filetype ==# 'tex' - let l:candidate = s:get_main_choose(s:get_main_recurse()) - if !empty(l:candidate) - return [l:candidate, 'recursive search'] - endif - else - let l:candidate = s:get_main_choose(s:get_main_recurse_from_bib()) - if !empty(l:candidate) - return [l:candidate, 'recursive search (bib)'] - endif + if &filetype ==# 'tex' + let l:candidate = s:get_main_choose(s:get_main_recurse()) + if !empty(l:candidate) + return [l:candidate, 'recursive search'] + endif + else + let l:candidate = s:get_main_choose(s:get_main_recurse_from_bib()) + if !empty(l:candidate) + return [l:candidate, 'recursive search (bib)'] endif endif diff --git a/doc/vimtex.txt b/doc/vimtex.txt index b47a570be9..9afbd2f70f 100644 --- a/doc/vimtex.txt +++ b/doc/vimtex.txt @@ -477,10 +477,6 @@ Directory scan~ In cases where automatic detection of the main file through the directory scan fails, one may explicitly set up method 1 to 5 instead. - Note: In rare cases, such as if there are _very_ many tex files in the - directory tree, this method may be slow. One may therefore disable it - by the option |g:vimtex_disable_directory_scan_main_file_detection|. - ------------------------------------------------------------------------------ SUPPORT FOR TEX DIRECTIVES *vimtex-tex-directives* @@ -1498,15 +1494,6 @@ OPTIONS *vimtex-options* Default value: 500 -*g:vimtex_disable_directory_scan_main_file_detection* - In rare cases, the directory scan method of finding the main file in multi - file projects may be slow. This might happen for instance when there are - _very_ many tex files in the directories scanned. In such cases, one may - disable the directory scan method by setting this variable to a nonzero - value. - - Default value: 0 - *g:vimtex_doc_handlers* With this option, one may specify a list of custom documentation handlers. The following pre-made handlers are available: @@ -6120,10 +6107,9 @@ The following changelog only logs particularly important changes, such as changes that break backwards compatibility. See the git log for the detailed changelog. -2022-11-05: Better main file detection algorithm~ +2022-11-06: Better main file detection algorithm~ The detection whether a file is a main file has been improved. In course of -this *g:vimtex_disable_recursive_main_file_detection* has been deprecated in -favor of |g:vimtex_disable_directory_scan_main_file_detection|. +this *g:vimtex_disable_recursive_main_file_detection* has been removed. 2021-10-25: Better inverse search~ Deprecate *g:vimtex_compiler_progname* as it is no longer necessary.