mirror of
				https://github.com/KevinMidboe/linguist.git
				synced 2025-10-29 17:50:22 +00:00 
			
		
		
		
	Improved vim modeline detection
TLDR: This greatly increases the flexibility of vim modeline detection
to manually set the language of a file.
In vim there are two forms of modelines:
[text]{white}{vi:|vim:|ex:}[white]{options}
examples: 'vim: syntax=perl', 'ex: filetype=ruby'
-and-
[text]{white}{vi:|vim:|Vim:|ex:}[white]se[t] {options}:[text]
examples: 'vim set syntax=perl:', 'Vim: se ft=ruby:'
As you can see, there are many combinations. These changes should allow
most combinations to be used. The two most important additions are the
use of the keyword 'syntax', as well as the addition of the first form
(you now no longer need to use the keyword 'set' with a colon at the end).
The use of first form with 'syntax' is very, very common across GitHub:
https://github.com/search?l=ruby&q=vim%3A+syntax%3D&ref=searchresults&type=Code&utf8=%E2%9C%93
			
			
This commit is contained in:
		| @@ -59,6 +59,9 @@ Alternatively, you can use Vim or Emacs style modelines to set the language for | ||||
|  | ||||
| ##### Vim | ||||
| ``` | ||||
| # Some examples of various styles: | ||||
| vim: syntax=java | ||||
| vim: set syntax=ruby: | ||||
| vim: set filetype=prolog: | ||||
| vim: set ft=cpp: | ||||
| ``` | ||||
|   | ||||
| @@ -1,8 +1,19 @@ | ||||
| module Linguist | ||||
|   module Strategy | ||||
|     class Modeline | ||||
|       EmacsModeline = /-\*-\s*(?:(?!mode)[\w-]+\s*:\s*(?:[\w+-]+)\s*;?\s*)*(?:mode\s*:)?\s*([\w+-]+)\s*(?:;\s*(?!mode)[\w-]+\s*:\s*[\w+-]+\s*)*;?\s*-\*-/i | ||||
|       VimModeline = /vim:\s*set.*\s(?:ft|filetype)=(\w+)\s?.*:/i | ||||
|       EMACS_MODELINE = /-\*-\s*(?:(?!mode)[\w-]+\s*:\s*(?:[\w+-]+)\s*;?\s*)*(?:mode\s*:)?\s*([\w+-]+)\s*(?:;\s*(?!mode)[\w-]+\s*:\s*[\w+-]+\s*)*;?\s*-\*-/i | ||||
|  | ||||
|       # First form vim modeline | ||||
|       # [text]{white}{vi:|vim:|ex:}[white]{options} | ||||
|       # ex: 'vim: syntax=perl' | ||||
|       VIM_MODELINE_1 = /(?:vim|vi|ex):\s*(?:ft|filetype|syntax)=(\w+)\s?/i | ||||
|  | ||||
|       # Second form vim modeline (compatible with some versions of Vi) | ||||
|       # [text]{white}{vi:|vim:|Vim:|ex:}[white]se[t] {options}:[text] | ||||
|       # ex: 'vim set syntax=perl:' | ||||
|       VIM_MODELINE_2 = /(?:vim|vi|Vim|ex):\s*se(?:t)?.*\s(?:ft|filetype|syntax)=(\w+)\s?.*:/i | ||||
|  | ||||
|       MODELINES = [EMACS_MODELINE, VIM_MODELINE_1, VIM_MODELINE_2] | ||||
|  | ||||
|       # Public: Detects language based on Vim and Emacs modelines | ||||
|       # | ||||
| @@ -22,7 +33,7 @@ module Linguist | ||||
|       # | ||||
|       # Returns a String or nil | ||||
|       def self.modeline(data) | ||||
|         match = data.match(EmacsModeline) || data.match(VimModeline) | ||||
|         match = MODELINES.map { |regex| data.match(regex) }.reject(&:nil?).first | ||||
|         match[1] if match | ||||
|       end | ||||
|     end | ||||
|   | ||||
							
								
								
									
										3
									
								
								test/fixtures/Data/Modelines/ruby4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/fixtures/Data/Modelines/ruby4
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # vim: filetype=ruby | ||||
|  | ||||
| # I am Ruby | ||||
							
								
								
									
										3
									
								
								test/fixtures/Data/Modelines/ruby5
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/fixtures/Data/Modelines/ruby5
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # vim: ft=ruby | ||||
|  | ||||
| # I am Ruby | ||||
							
								
								
									
										3
									
								
								test/fixtures/Data/Modelines/ruby6
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/fixtures/Data/Modelines/ruby6
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # vim: syntax=Ruby | ||||
|  | ||||
| # I am Ruby | ||||
							
								
								
									
										3
									
								
								test/fixtures/Data/Modelines/ruby7
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/fixtures/Data/Modelines/ruby7
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # vim: se syntax=ruby: | ||||
|  | ||||
| # I am Ruby | ||||
							
								
								
									
										3
									
								
								test/fixtures/Data/Modelines/ruby8
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/fixtures/Data/Modelines/ruby8
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # vim: set syntax=ruby: | ||||
|  | ||||
| # I am Ruby | ||||
							
								
								
									
										3
									
								
								test/fixtures/Data/Modelines/ruby9
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								test/fixtures/Data/Modelines/ruby9
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| # ex: syntax=ruby | ||||
|  | ||||
| # I am Ruby | ||||
| @@ -11,6 +11,12 @@ class TestModelines < Minitest::Test | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby2") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby3") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby4") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby5") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby6") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby7") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby8") | ||||
|     assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby9") | ||||
|     assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplus") | ||||
|     assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs1") | ||||
|     assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs2") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user