]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
runtime(filetype): improve *.h filetype detection
authorAmelia Clarke <selene@perilune.dev>
Sat, 19 Apr 2025 09:48:10 +0000 (11:48 +0200)
committerChristian Brabandt <cb@256bit.org>
Sat, 19 Apr 2025 09:48:10 +0000 (11:48 +0200)
This commit changes *.h files to default to C (instead of C++), and
deprecates the existing `g:c_syntax_for_h` and `g:ch_syntax_for_h`
variables in favor of a unified `g:filetype_h`, like is used for other
ambiguous file extensions.

closes: #17135

Signed-off-by: Amelia Clarke <selene@perilune.dev>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/autoload/dist/ft.vim
runtime/doc/filetype.txt
runtime/doc/syntax.txt
runtime/filetype.vim

index a0be9302c6283ee17c02e6e74e4bb39be3c1b012..0c0b872f6810face96b9bd393c0789953d4b50b3 100644 (file)
@@ -3,7 +3,7 @@ vim9script
 # Vim functions for file type detection
 #
 # Maintainer:          The Vim Project <https://github.com/vim/vim>
-# Last Change:         2025 Apr 15
+# Last Change:         2025 Apr 19
 # Former Maintainer:   Bram Moolenaar <Bram@vim.org>
 
 # These functions are moved here from runtime/filetype.vim to make startup
@@ -203,19 +203,36 @@ export def FTlpc()
   setf c
 enddef
 
+# Searches within the first `maxlines` lines of the file for distinctive
+# Objective-C or C++ syntax and returns the appropriate filetype. Returns a
+# null_string if the search was inconclusive.
+def CheckObjCOrCpp(maxlines = 100): string
+  var n = 1
+  while n < maxlines && n <= line('$')
+    const line = getline(n)
+    if line =~ '\v^\s*\@%(class|interface|end)>'
+      return 'objcpp'
+    elseif line =~ '\v^\s*%(class|namespace|template|using)>'
+      return 'cpp'
+    endif
+    ++n
+  endwhile
+  return null_string
+enddef
+
+# Determines whether a *.h file is C, C++, Ch, or Objective-C/Objective-C++.
 export def FTheader()
-  if match(getline(1, min([line("$"), 200])), '^@\(interface\|end\|class\)') > -1
-    if exists("g:c_syntax_for_h")
-      setf objc
-    else
-      setf objcpp
-    endif
-  elseif exists("g:c_syntax_for_h")
+  if exists('g:filetype_h')
+    execute $'setf {g:filetype_h}'
+  elseif exists('g:c_syntax_for_h')
     setf c
-  elseif exists("g:ch_syntax_for_h")
+  elseif exists('g:ch_syntax_for_h')
     setf ch
   else
-    setf cpp
+    # Search the first 100 lines of the file for distinctive Objective-C or C++
+    # syntax and set the filetype accordingly. Otherwise, use C as the default
+    # filetype.
+    execute $'setf {CheckObjCOrCpp() ?? 'c'}'
   endif
 enddef
 
index c0bf1e616bd3257a747d149796d3dcf2028cac64..77bf5f337183e4153c35da1ba84b9d757e486541 100644 (file)
@@ -1,4 +1,4 @@
-*filetype.txt* For Vim version 9.1.  Last change: 2025 Apr 16
+*filetype.txt* For Vim version 9.1.  Last change: 2025 Apr 19
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -153,7 +153,11 @@ variables can be used to overrule the filetype used for certain extensions:
        *.f             g:filetype_f            |ft-forth-syntax|
        *.frm           g:filetype_frm          |ft-form-syntax|
        *.fs            g:filetype_fs           |ft-forth-syntax|
-       *.h             g:c_syntax_for_h        |ft-c-syntax|
+       *.h             g:c_syntax_for_h        |ft-c-syntax|   (deprecated)
+       *.h             g:ch_syntax_for_h       |ft-ch-syntax|  (deprecated)
+       *.h             g:filetype_h            |ft-c-syntax|
+                                               |ft-ch-syntax|
+                                               |ft-cpp-syntax|
        *.i             g:filetype_i            |ft-progress-syntax|
        *.inc           g:filetype_inc
        *.lsl           g:filetype_lsl
index ae89bd9f10fa677c10daf7edffe8f0fd5b612e18..a8fbe1a85c6d114201bb6e3690f0a5d5bf12e139 100644 (file)
@@ -1,4 +1,4 @@
-*syntax.txt*   For Vim version 9.1.  Last change: 2025 Apr 15
+*syntax.txt*   For Vim version 9.1.  Last change: 2025 Apr 19
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1056,8 +1056,12 @@ Variable         Highlight ~
 *c_ansi_typedefs*       ... but do standard ANSI types
 *c_ansi_constants*      ... but do standard ANSI constants
 *c_no_utf*             don't highlight \u and \U in strings
-*c_syntax_for_h*       for *.h files use C syntax instead of C++ and use objc
-                       syntax instead of objcpp
+*c_syntax_for_h*       use C syntax for *.h files instead of C++/ObjC/ObjC++
+                       (NOTE: This variable is deprecated and no longer
+                        necessary, as *.h files now default to C, unless the
+                        file contains C++ or Objective-C syntax. If the
+                        automated detection fails, the default filetype can
+                        be adjusted using `g:filetype_h`.)
 *c_no_if0*             don't highlight "#if 0" blocks as comments
 *c_no_cformat*         don't highlight %-formats in strings
 *c_no_c99*             don't highlight C99 standard items
@@ -1116,8 +1120,11 @@ the C syntax file.  See |c.vim| for all the settings that are available for C.
 
 By setting a variable you can tell Vim to use Ch syntax for *.h files, instead
 of C or C++: >
-       :let ch_syntax_for_h = 1
+       :let g:filetype_h = 'ch'
 
+NOTE: In previous versions of Vim, the following (now-deprecated) variable was
+used, but is no longer the preferred approach: >
+       :let ch_syntax_for_h = 1
 
 CHILL                                          *chill.vim* *ft-chill-syntax*
 
index e85007434652027d3cd0587acfddb1b1917fa5bb..da74e25c047c56cdd5b676c7e10868297f220259 100644 (file)
@@ -1,7 +1,7 @@
 " Vim support file to detect file types
 "
 " Maintainer:  The Vim Project <https://github.com/vim/vim>
-" Last Change: 2025 Apr 18
+" Last Change: 2025 Apr 19
 " Former Maintainer:   Bram Moolenaar <Bram@vim.org>
 
 " Listen very carefully, I will say this only once
@@ -436,9 +436,8 @@ au BufNewFile,BufRead *.ixx,*.mpp setf cpp
 " https://clang.llvm.org/docs/StandardCPlusPlusModules.html#file-name-requirement
 au BufNewFile,BufRead *.cppm,*.ccm,*.cxxm,*.c++m setf cpp
 
-" .h files can be C, Ch C++, ObjC or ObjC++.
-" Set c_syntax_for_h if you want C, ch_syntax_for_h if you want Ch. ObjC is
-" detected automatically.
+" .h files can be C, C++, Ch, Objective-C, or Objective-C++.
+" Set g_filetype_h to set a different filetype
 au BufNewFile,BufRead *.h                      call dist#ft#FTheader()
 
 " Ch (CHscript)