@@ -3,7 +3,7 @@ vim9script
33# Vim functions for file type detection
44#
55# Maintainer: The Vim Project <https://github.com/vim/vim>
6- # Last Change: 2025 Jul 09
6+ # Last Change: 2025 Sep 08
77# Former Maintainer: Bram Moolenaar <Bram@vim.org>
88
99# These functions are moved here from runtime /filetype .vim to make startup
@@ -441,29 +441,29 @@ export def FTfs()
441441 endif
442442enddef
443443
444- # Recursively search for Hare source files in a directory and any
445- # subdirectories, up to a given depth.
444+ # Recursively searches for Hare source files within a directory , up to a given
445+ # depth.
446446def IsHareModule (dir : string , depth: number ): bool
447- if depth <= 0
448- return ! empty (glob (dir .. ' /*.ha' ))
447+ if depth < 1
448+ return false
449+ elseif depth == 1
450+ return ! glob (dir .. ' /*.ha' )- >empty ()
449451 endif
450452
451- return reduce (sort (glob (dir .. ' /*' , true, true),
452- (a , b ) = > isdirectory (a ) - isdirectory (b )),
453- (acc, n ) = > acc
453+ # Check all files in the directory before recursing into subdirectories.
454+ return glob (dir .. ' /*' , true, true)
455+ - >sort ((a , b ) = > isdirectory (a ) - isdirectory (b ))
456+ - >reduce ((acc, n ) = > acc
454457 || n = ~ ' \.ha$'
455- || isdirectory (n )
456- && IsHareModule (n , depth - 1 ),
458+ || isdirectory (n ) && IsHareModule (n , depth - 1 ),
457459 false)
458460enddef
459461
460- # Determine if a README file exists within a Hare module and should be given the
461- # Haredoc filetype .
462+ # Determines whether a README file is inside a Hare module and should receive
463+ # the ' haredoc ' filetype .
462464export def FTharedoc ()
463- if exists (' g:filetype_haredoc' )
464- if IsHareModule (' <afile>:h' , get (g: , ' haredoc_search_depth' , 1 ))
465- setf haredoc
466- endif
465+ if IsHareModule (' <afile>:h' , get (g: , ' filetype_haredoc' , 1 ))
466+ setf haredoc
467467 endif
468468enddef
469469
@@ -599,6 +599,55 @@ export def FTm()
599599 endif
600600enddef
601601
602+ # For files ending in * .m4, distinguish:
603+ # – * .html.m4 files
604+ # - * fvwm2rc* .m4 files
605+ # – files in the Autoconf M4 dialect
606+ # – files in POSIX M4
607+ export def FTm4 ()
608+ var fname = expand (' %:t' )
609+ var path = expand (' %:p:h' )
610+
611+ if fname = ~# ' html\.m4$'
612+ setf htmlm4
613+ return
614+ endif
615+
616+ if fname = ~# ' fvwm2rc'
617+ setf fvwm2m4
618+ return
619+ endif
620+
621+ # Canonical Autoconf file
622+ if fname == # ' aclocal.m4'
623+ setf config
624+ return
625+ endif
626+
627+ # Repo heuristic for Autoconf M4 (nearby configure.ac)
628+ if filereadable (path .. ' /../configure.ac' ) || filereadable (path .. ' /configure.ac' )
629+ setf config
630+ return
631+ endif
632+
633+ # Content heuristic for Autoconf M4 (scan first ~200 lines )
634+ # Signals:
635+ # - Autoconf macro prefixes: AC_/AM_/ AS_/AU_/ AT_
636+ var n = 1
637+ var max = min ([200 , line (' $' )])
638+ while n <= max
639+ var line = getline (n )
640+ if line = ~# ' ^\s*A[CMSUT]_'
641+ setf config
642+ return
643+ endif
644+ n += 1
645+ endwhile
646+
647+ # Default to POSIX M4
648+ setf m4
649+ enddef
650+
602651export def FTmake ()
603652 # Check if it is a BSD, GNU, or Microsoft Makefile
604653 unlet ! b: make_flavor
@@ -779,26 +828,32 @@ export def FTinc()
779828 if exists (" g:filetype_inc" )
780829 exe " setf " .. g: filetype_inc
781830 else
782- var lines = getline ( 1 ) .. getline ( 2 ) .. getline ( 3 )
783- if lines = ~? " perlscript "
784- setf aspperl
785- elseif lines = ~ " <% "
786- setf aspvbs
787- elseif lines = ~ " <? "
788- setf php
789- # Pascal supports // comments but they' re vary rarely used for file
790- # headers so assume POV - Ray
791- elseif lines = ~ ' ^\s*\%({\|(\*\) ' || lines = ~? ft_pascal_keywords
792- setf pascal
793- elseif lines = ~# ' \<\%(require\|inherit\)\> ' || lines = ~# ' [A-Z][A-Za-z0-9_:${}]*\s\+\%(??\|[?:+]\)\?= '
794- setf bitbake
795- else
796- FTasmsyntax ()
797- if exists ( " b:asmsyntax " )
798- exe " setf " .. fnameescape ( b: asmsyntax )
799- else
800- setf pov
831+ for lnum in range ( 1 , min ([ line ( " $ " ), 20 ]) )
832+ var line = getline (lnum)
833+ if line = ~? " perlscript "
834+ setf aspperl
835+ return
836+ elseif line = ~ " <% "
837+ setf aspvbs
838+ return
839+ elseif line = ~ " <? "
840+ setf php
841+ return
842+ # Pascal supports // comments but they' re vary rarely used for file
843+ # headers so assume POV - Ray
844+ elseif line = ~ ' ^\s*\%({\|(\*\) ' || line = ~? ft_pascal_keywords
845+ setf pascal
846+ return
847+ elseif line = ~# ' \<\%(require\|inherit\)\> ' || line = ~# ' [A-Z][A-Za-z0-9_:${}/]*\s\+\%(??\|[?:+.]\)\?=.\? '
848+ setf bitbake
849+ return
801850 endif
851+ endfor
852+ FTasmsyntax ()
853+ if exists (" b:asmsyntax" )
854+ exe " setf " .. fnameescape (b: asmsyntax )
855+ else
856+ setf pov
802857 endif
803858 endif
804859enddef
0 commit comments