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