From e536eea5b6396df3bd641520c23ec6b02fddf677 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 14:22:09 -0600 Subject: [PATCH 01/19] Basic Vim modeline detection strategy --- lib/linguist/language.rb | 2 ++ lib/linguist/strategy/modeline.rb | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 lib/linguist/strategy/modeline.rb diff --git a/lib/linguist/language.rb b/lib/linguist/language.rb index 365beb06..43076a2b 100644 --- a/lib/linguist/language.rb +++ b/lib/linguist/language.rb @@ -11,6 +11,7 @@ require 'linguist/samples' require 'linguist/file_blob' require 'linguist/blob_helper' require 'linguist/strategy/filename' +require 'linguist/strategy/modeline' require 'linguist/shebang' module Linguist @@ -95,6 +96,7 @@ module Linguist STRATEGIES = [ Linguist::Strategy::Filename, + Linguist::Strategy::Modeline, Linguist::Shebang, Linguist::Heuristics, Linguist::Classifier diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb new file mode 100644 index 00000000..569f6581 --- /dev/null +++ b/lib/linguist/strategy/modeline.rb @@ -0,0 +1,31 @@ +module Linguist + module Strategy + class Modeline + # Public: Detects language based on Vim and Emacs modelines + # + # blob - An object that quacks like a blob. + # + # Examples + # + # Modeline.call(FileBlob.new("path/to/file")) + # + # Returns an Array with one Language if the blob has a shebang with a valid + # interpreter, or empty if there is no shebang. + def self.call(blob, _ = nil) + if language = Language.find_by_alias(modeline(blob.data)) + return [language] + else + return [] + end + end + + # Public: Get the modeline from the first n-lines of the file + # + # Returns a String or nil + def self.modeline(data) + data.lines.first(5).any? { |l| l.match(/\W(?:filetype|ft)=\s*(\w+)/) } + lang = $1 + end + end + end +end From 429c791377be0615fcc7cb7d79ae0ebe2e9ae694 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 14:39:07 -0600 Subject: [PATCH 02/19] Testing Vim modeline support --- test/fixtures/Data/Modelines/not_perl.pl | 3 +++ test/fixtures/Data/Modelines/ruby | 3 +++ test/fixtures/Data/Modelines/seeplusplus | 3 +++ test/test_modelines.rb | 20 ++++++++++++++++++++ 4 files changed, 29 insertions(+) create mode 100644 test/fixtures/Data/Modelines/not_perl.pl create mode 100644 test/fixtures/Data/Modelines/ruby create mode 100644 test/fixtures/Data/Modelines/seeplusplus create mode 100644 test/test_modelines.rb diff --git a/test/fixtures/Data/Modelines/not_perl.pl b/test/fixtures/Data/Modelines/not_perl.pl new file mode 100644 index 00000000..df8e9fc5 --- /dev/null +++ b/test/fixtures/Data/Modelines/not_perl.pl @@ -0,0 +1,3 @@ +/* vim: set filetype=prolog: */ + +# I am Prolog diff --git a/test/fixtures/Data/Modelines/ruby b/test/fixtures/Data/Modelines/ruby new file mode 100644 index 00000000..9dee00eb --- /dev/null +++ b/test/fixtures/Data/Modelines/ruby @@ -0,0 +1,3 @@ +/* vim: set filetype=ruby: */ + +# I am Ruby diff --git a/test/fixtures/Data/Modelines/seeplusplus b/test/fixtures/Data/Modelines/seeplusplus new file mode 100644 index 00000000..a5cdd9d3 --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplus @@ -0,0 +1,3 @@ +/* vim: set ft=cpp: */ + +I would like to be C++ please. diff --git a/test/test_modelines.rb b/test/test_modelines.rb new file mode 100644 index 00000000..8ef2ef6c --- /dev/null +++ b/test/test_modelines.rb @@ -0,0 +1,20 @@ +require_relative "./helper" + +class TestModelines < Minitest::Test + include Linguist + + def fixtures_path + File.expand_path("../fixtures", __FILE__) + end + + def fixture_blob(name) + name = File.join(fixtures_path, name) unless name =~ /^\// + FileBlob.new(name, fixtures_path) + end + + def test_modelines + assert_equal Language["Ruby"], fixture_blob("Data/Modelines/ruby").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplus").language + assert_equal Language["Prolog"], fixture_blob("Data/Modelines/not_perl.pl").language + end +end From e8e95f113c25da0b6683be16a025d7086e0fde61 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 15:03:22 -0600 Subject: [PATCH 03/19] Modeline should come first (as it's an override) --- lib/linguist/language.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/linguist/language.rb b/lib/linguist/language.rb index 43076a2b..7fbf8a96 100644 --- a/lib/linguist/language.rb +++ b/lib/linguist/language.rb @@ -95,8 +95,8 @@ module Linguist end STRATEGIES = [ - Linguist::Strategy::Filename, Linguist::Strategy::Modeline, + Linguist::Strategy::Filename, Linguist::Shebang, Linguist::Heuristics, Linguist::Classifier From 7929e7ab9c332faadc604ede6e33c8aa96a232b9 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 15:11:55 -0600 Subject: [PATCH 04/19] Adding Emacs modes --- lib/linguist/strategy/modeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 569f6581..1aecb8ec 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -23,7 +23,7 @@ module Linguist # # Returns a String or nil def self.modeline(data) - data.lines.first(5).any? { |l| l.match(/\W(?:filetype|ft)=\s*(\w+)/) } + data.lines.first(5).any? { |l| l.match(/\W(?:filetype=|ft=|mode:|-*-)\s*(\w+)/) } lang = $1 end end From d773c2e90dce1c0a890b186bd13ccdb819db06b3 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 15:18:40 -0600 Subject: [PATCH 05/19] Escape the * --- lib/linguist/strategy/modeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 1aecb8ec..cc65ec00 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -23,7 +23,7 @@ module Linguist # # Returns a String or nil def self.modeline(data) - data.lines.first(5).any? { |l| l.match(/\W(?:filetype=|ft=|mode:|-*-)\s*(\w+)/) } + data.lines.first(5).any? { |l| l.match(/\W(?:filetype=|ft=|mode:|-\*-)\s*(\w+)/) } lang = $1 end end From 98fc4d78aa4e09e8478517228c047fe0e036e26d Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 15:37:45 -0600 Subject: [PATCH 06/19] Slightly reworked regex. --- lib/linguist/strategy/modeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index cc65ec00..69fe0d79 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -23,7 +23,7 @@ module Linguist # # Returns a String or nil def self.modeline(data) - data.lines.first(5).any? { |l| l.match(/\W(?:filetype=|ft=|mode:|-\*-)\s*(\w+)/) } + data.lines.first(5).any? { |l| l.match(/\W(?:filetype=|ft=|-\*- mode:|-\*-)\s*(\w+)/) } lang = $1 end end From 8094b1bd92f7b316509b3259dc4c276bd089ee1b Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 15:38:07 -0600 Subject: [PATCH 07/19] Test strategy and language --- test/test_modelines.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/test_modelines.rb b/test/test_modelines.rb index 8ef2ef6c..717dadf9 100644 --- a/test/test_modelines.rb +++ b/test/test_modelines.rb @@ -12,9 +12,23 @@ class TestModelines < Minitest::Test FileBlob.new(name, fixtures_path) end - def test_modelines + def assert_modeline(language, blob) + assert_equal language, Linguist::Strategy::Modeline.call(blob).first + end + + def test_modeline_strategy + assert_modeline Language["Ruby"], fixture_blob("Data/Modelines/ruby") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplus") + assert_modeline Language["Prolog"], fixture_blob("Data/Modelines/not_perl.pl") + assert_modeline Language["Smalltalk"], fixture_blob("Data/Modelines/example_smalltalk.md") + assert_modeline Language["PHP"], fixture_blob("Data/Modelines/iamphp.inc") + end + + def test_modeline_languages assert_equal Language["Ruby"], fixture_blob("Data/Modelines/ruby").language assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplus").language assert_equal Language["Prolog"], fixture_blob("Data/Modelines/not_perl.pl").language + assert_equal Language["Smalltalk"], fixture_blob("Data/Modelines/example_smalltalk.md").language + assert_equal Language["PHP"], fixture_blob("Data/Modelines/iamphp.inc").language end end From 119a8fff1edf35bc9ca09b79214cdb66a4fa585d Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 15:38:19 -0600 Subject: [PATCH 08/19] Emacs modeline fixtures --- test/fixtures/Data/Modelines/example_smalltalk.md | 1 + test/fixtures/Data/Modelines/iamphp.inc | 1 + 2 files changed, 2 insertions(+) create mode 100644 test/fixtures/Data/Modelines/example_smalltalk.md create mode 100644 test/fixtures/Data/Modelines/iamphp.inc diff --git a/test/fixtures/Data/Modelines/example_smalltalk.md b/test/fixtures/Data/Modelines/example_smalltalk.md new file mode 100644 index 00000000..6a927e40 --- /dev/null +++ b/test/fixtures/Data/Modelines/example_smalltalk.md @@ -0,0 +1 @@ +; -*-Smalltalk-*- diff --git a/test/fixtures/Data/Modelines/iamphp.inc b/test/fixtures/Data/Modelines/iamphp.inc new file mode 100644 index 00000000..14370309 --- /dev/null +++ b/test/fixtures/Data/Modelines/iamphp.inc @@ -0,0 +1 @@ +; -*- mode: php;-*- From 20a3e7e4b8de8efab6be18b6d89e43ed84f6c4e7 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 16:12:20 -0600 Subject: [PATCH 09/19] Update docs --- lib/linguist/strategy/modeline.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 69fe0d79..8e13c829 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -9,8 +9,8 @@ module Linguist # # Modeline.call(FileBlob.new("path/to/file")) # - # Returns an Array with one Language if the blob has a shebang with a valid - # interpreter, or empty if there is no shebang. + # Returns an Array with one Language if the blob has a Vim or Emacs modeline + # that matches a Language name or alias. Returns an empty array if no match. def self.call(blob, _ = nil) if language = Language.find_by_alias(modeline(blob.data)) return [language] From 69b68f3a447a14aec64feb78eaca7274cb6cbc1d Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Mon, 26 Jan 2015 16:22:55 -0600 Subject: [PATCH 10/19] Extracting common methods into helper. --- test/helper.rb | 18 ++++++++++++++++++ test/test_blob.rb | 18 ------------------ test/test_classifier.rb | 4 ---- test/test_generated.rb | 4 ---- test/test_heuristics.rb | 4 ---- test/test_modelines.rb | 9 --------- test/test_tokenizer.rb | 4 ---- 7 files changed, 18 insertions(+), 43 deletions(-) diff --git a/test/helper.rb b/test/helper.rb index ebfeefc7..a6a03672 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -2,3 +2,21 @@ require "bundler/setup" require "minitest/autorun" require "mocha/setup" require "linguist" + +def fixtures_path + File.expand_path("../fixtures", __FILE__) +end + +def fixture_blob(name) + name = File.join(fixtures_path, name) unless name =~ /^\// + Linguist::FileBlob.new(name, fixtures_path) +end + +def samples_path + File.expand_path("../../samples", __FILE__) +end + +def sample_blob(name) + name = File.join(samples_path, name) unless name =~ /^\// + Linguist::FileBlob.new(name, samples_path) +end diff --git a/test/test_blob.rb b/test/test_blob.rb index 372ff13f..ceb54bb3 100644 --- a/test/test_blob.rb +++ b/test/test_blob.rb @@ -14,24 +14,6 @@ class TestBlob < Minitest::Test Encoding.default_external = @original_external end - def samples_path - File.expand_path("../../samples", __FILE__) - end - - def fixtures_path - File.expand_path("../fixtures", __FILE__) - end - - def sample_blob(name) - name = File.join(samples_path, name) unless name =~ /^\// - FileBlob.new(name, samples_path) - end - - def fixture_blob(name) - name = File.join(fixtures_path, name) unless name =~ /^\// - FileBlob.new(name, fixtures_path) - end - def script_blob(name) blob = sample_blob(name) blob.instance_variable_set(:@name, 'script') diff --git a/test/test_classifier.rb b/test/test_classifier.rb index 1d10d512..2ae2f45e 100644 --- a/test/test_classifier.rb +++ b/test/test_classifier.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestClassifier < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - def fixture(name) File.read(File.join(samples_path, name)) end diff --git a/test/test_generated.rb b/test/test_generated.rb index 1c3f8d90..b714e19e 100644 --- a/test/test_generated.rb +++ b/test/test_generated.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestGenerated < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - class DataLoadedError < StandardError; end def generated_without_loading_data(name) diff --git a/test/test_heuristics.rb b/test/test_heuristics.rb index b88d0fda..3ea4af78 100644 --- a/test/test_heuristics.rb +++ b/test/test_heuristics.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestHeuristcs < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - def fixture(name) File.read(File.join(samples_path, name)) end diff --git a/test/test_modelines.rb b/test/test_modelines.rb index 717dadf9..6c68cc87 100644 --- a/test/test_modelines.rb +++ b/test/test_modelines.rb @@ -3,15 +3,6 @@ require_relative "./helper" class TestModelines < Minitest::Test include Linguist - def fixtures_path - File.expand_path("../fixtures", __FILE__) - end - - def fixture_blob(name) - name = File.join(fixtures_path, name) unless name =~ /^\// - FileBlob.new(name, fixtures_path) - end - def assert_modeline(language, blob) assert_equal language, Linguist::Strategy::Modeline.call(blob).first end diff --git a/test/test_tokenizer.rb b/test/test_tokenizer.rb index 339d5485..780db019 100644 --- a/test/test_tokenizer.rb +++ b/test/test_tokenizer.rb @@ -3,10 +3,6 @@ require_relative "./helper" class TestTokenizer < Minitest::Test include Linguist - def samples_path - File.expand_path("../../samples", __FILE__) - end - def tokenize(data) data = File.read(File.join(samples_path, data.to_s)) if data.is_a?(Symbol) Tokenizer.tokenize(data) From 96154627d3a405f45098fb3f9cdb3a9306d5f3cc Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Tue, 27 Jan 2015 09:42:24 -0600 Subject: [PATCH 11/19] Clearer regex --- lib/linguist/strategy/modeline.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 8e13c829..24108c6f 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -23,8 +23,20 @@ module Linguist # # Returns a String or nil def self.modeline(data) - data.lines.first(5).any? { |l| l.match(/\W(?:filetype=|ft=|-\*- mode:|-\*-)\s*(\w+)/) } - lang = $1 + pattern = %q{(?: + (-\*- \s* (?:mode:)? \s*) | # $1: Emacs + (\/\* \s* vim: \s* set \s* (?:ft|filetype)=) # $2: Vim + ) + (\w+) # $3: language + (?: + (?(1) # If $1 matched... + ;?\s* -\*- | # then close Emacs syntax + : \s* \*\/ # otherwise close Vim syntax + ) + )} + + data.lines.first(5).any? { |l| l.match(/#{pattern}/x) } + lang = $3 end end end From bf6bd246fd6b55180dab16b19aa18ab63854d4bd Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Wed, 28 Jan 2015 16:52:26 -0600 Subject: [PATCH 12/19] Syntax tweak --- lib/linguist/strategy/modeline.rb | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 24108c6f..9dbd2dba 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -23,19 +23,21 @@ module Linguist # # Returns a String or nil def self.modeline(data) - pattern = %q{(?: - (-\*- \s* (?:mode:)? \s*) | # $1: Emacs - (\/\* \s* vim: \s* set \s* (?:ft|filetype)=) # $2: Vim - ) - (\w+) # $3: language - (?: - (?(1) # If $1 matched... - ;?\s* -\*- | # then close Emacs syntax - : \s* \*\/ # otherwise close Vim syntax - ) - )} + regex = <<-EOF + /(?: + (-\*- \s* (?:mode:)? \s*) | # $1: Emacs + (\/\* \s* vim: \s* set \s* (?:ft|filetype)=) # $2: Vim + ) + (\w+) # $3: language + (?: + (?(1) # If $1 matched... + ;?\s* -\*- | # then close Emacs syntax + : \s* \*\/ # otherwise close Vim syntax + ) + )/x + EOF - data.lines.first(5).any? { |l| l.match(/#{pattern}/x) } + data.lines.first(5).any? { |l| l.match(regex) } lang = $3 end end From 7a601b196eb92953f5b54e2e932d987889ee7b63 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Thu, 29 Jan 2015 13:07:18 -0600 Subject: [PATCH 13/19] Fix regex syntax --- lib/linguist/strategy/modeline.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 9dbd2dba..7e4fda84 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -23,7 +23,7 @@ module Linguist # # Returns a String or nil def self.modeline(data) - regex = <<-EOF + regex = /(?: (-\*- \s* (?:mode:)? \s*) | # $1: Emacs (\/\* \s* vim: \s* set \s* (?:ft|filetype)=) # $2: Vim @@ -35,7 +35,6 @@ module Linguist : \s* \*\/ # otherwise close Vim syntax ) )/x - EOF data.lines.first(5).any? { |l| l.match(regex) } lang = $3 From fadca563bc1a60f56ea5939a2f171f763902218e Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Thu, 29 Jan 2015 13:09:12 -0600 Subject: [PATCH 14/19] Move regex to a constant --- lib/linguist/strategy/modeline.rb | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 7e4fda84..96a73ff8 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -1,6 +1,20 @@ module Linguist module Strategy class Modeline + Regex = / + (?: + (-\*- \s* (?:mode:)? \s*) | # $1: Emacs + (\/\* \s* vim: \s* set \s* (?:ft|filetype)=) # $2: Vim + ) + (\w+) # $3: language + (?: + (?(1) # If $1 matched... + ;?\s* -\*- | # then close Emacs syntax + : \s* \*\/ # otherwise close Vim syntax + ) + ) + /x + # Public: Detects language based on Vim and Emacs modelines # # blob - An object that quacks like a blob. @@ -23,20 +37,7 @@ module Linguist # # Returns a String or nil def self.modeline(data) - regex = - /(?: - (-\*- \s* (?:mode:)? \s*) | # $1: Emacs - (\/\* \s* vim: \s* set \s* (?:ft|filetype)=) # $2: Vim - ) - (\w+) # $3: language - (?: - (?(1) # If $1 matched... - ;?\s* -\*- | # then close Emacs syntax - : \s* \*\/ # otherwise close Vim syntax - ) - )/x - - data.lines.first(5).any? { |l| l.match(regex) } + data.lines.first(5).any? { |l| l.match(Regex) } lang = $3 end end From 437ba70b9ee006fd24d894155bfba43499e443f6 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Thu, 29 Jan 2015 13:14:06 -0600 Subject: [PATCH 15/19] Find modeline anywhere in the data --- lib/linguist/strategy/modeline.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 96a73ff8..b23fe08e 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -37,7 +37,7 @@ module Linguist # # Returns a String or nil def self.modeline(data) - data.lines.first(5).any? { |l| l.match(Regex) } + data.match(Regex) lang = $3 end end From 512cfc48589f573a8ee5157b490d53e6b730f929 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Thu, 29 Jan 2015 15:45:07 -0600 Subject: [PATCH 16/19] Dropping 1.9.3 --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4d0c2351..89b5e027 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ sudo: false before_install: script/travis/before_install rvm: - - 1.9.3 - 2.0.0 - 2.1 - 2.2 From e7f57796595f11117b53ca37502056ce83aac85b Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Thu, 29 Jan 2015 16:16:41 -0600 Subject: [PATCH 17/19] Break modelines into two regular expressions This makes them easier to read and maintains Ruby 1.9 compatibility --- lib/linguist/strategy/modeline.rb | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index b23fe08e..176bd292 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -1,19 +1,8 @@ module Linguist module Strategy class Modeline - Regex = / - (?: - (-\*- \s* (?:mode:)? \s*) | # $1: Emacs - (\/\* \s* vim: \s* set \s* (?:ft|filetype)=) # $2: Vim - ) - (\w+) # $3: language - (?: - (?(1) # If $1 matched... - ;?\s* -\*- | # then close Emacs syntax - : \s* \*\/ # otherwise close Vim syntax - ) - ) - /x + EmacsModeline = /-\*-\s*(?:mode:)?\s*(\w+);?\s*-\*-/ + VimModeline = /\/\*\s*vim:\s*set\s*(?:ft|filetype)=(\w+):\s*\*\// # Public: Detects language based on Vim and Emacs modelines # @@ -37,8 +26,8 @@ module Linguist # # Returns a String or nil def self.modeline(data) - data.match(Regex) - lang = $3 + match = data.match(EmacsModeline) || data.match(VimModeline) + match[1] if match end end end From 4f92d620eb215ed82f49a70108253b3fd9446e02 Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Thu, 29 Jan 2015 16:28:20 -0600 Subject: [PATCH 18/19] Simplify detect --- lib/linguist/strategy/modeline.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 176bd292..6a07fe3f 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -15,11 +15,7 @@ module Linguist # Returns an Array with one Language if the blob has a Vim or Emacs modeline # that matches a Language name or alias. Returns an empty array if no match. def self.call(blob, _ = nil) - if language = Language.find_by_alias(modeline(blob.data)) - return [language] - else - return [] - end + Array(Language.find_by_alias(modeline(blob.data))) end # Public: Get the modeline from the first n-lines of the file From 5ff1b02e49f36fda9fc502335b969a6ac24be591 Mon Sep 17 00:00:00 2001 From: Arfon Smith Date: Thu, 29 Jan 2015 16:47:45 -0600 Subject: [PATCH 19/19] 1.9.3 reprieve --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 89b5e027..4d0c2351 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ sudo: false before_install: script/travis/before_install rvm: + - 1.9.3 - 2.0.0 - 2.1 - 2.2