Merge pull request #2812 from chrisarcand/improved-vim-modeline-detection

Improved vim modeline detection
This commit is contained in:
Arfon Smith
2016-01-21 20:12:26 -05:00
9 changed files with 41 additions and 3 deletions

View File

@@ -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:
```

View File

@@ -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
View File

@@ -0,0 +1,3 @@
# vim: filetype=ruby
# I am Ruby

3
test/fixtures/Data/Modelines/ruby5 vendored Normal file
View File

@@ -0,0 +1,3 @@
# vim: ft=ruby
# I am Ruby

3
test/fixtures/Data/Modelines/ruby6 vendored Normal file
View File

@@ -0,0 +1,3 @@
# vim: syntax=Ruby
# I am Ruby

3
test/fixtures/Data/Modelines/ruby7 vendored Normal file
View File

@@ -0,0 +1,3 @@
# vim: se syntax=ruby:
# I am Ruby

3
test/fixtures/Data/Modelines/ruby8 vendored Normal file
View File

@@ -0,0 +1,3 @@
# vim: set syntax=ruby:
# I am Ruby

3
test/fixtures/Data/Modelines/ruby9 vendored Normal file
View File

@@ -0,0 +1,3 @@
# ex: syntax=ruby
# I am Ruby

View File

@@ -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")