diff --git a/lib/linguist/blob_helper.rb b/lib/linguist/blob_helper.rb index b9255b6c..dab05c21 100644 --- a/lib/linguist/blob_helper.rb +++ b/lib/linguist/blob_helper.rb @@ -260,7 +260,7 @@ module Linguist language # See if there is a Language for the extension - elsif language = Language.find_by_extension(extname) + elsif language = Language.find_by_filename(pathname.to_s) language # Try to detect Language from shebang line diff --git a/lib/linguist/language.rb b/lib/linguist/language.rb index 55c2b202..8bf3ae39 100644 --- a/lib/linguist/language.rb +++ b/lib/linguist/language.rb @@ -8,6 +8,7 @@ module Linguist @name_index = {} @alias_index = {} @extension_index = {} + @filename_index = {} # Internal: Create a new Language object # @@ -37,6 +38,10 @@ module Linguist end language.extensions.each do |extension| + if extension !~ /^\./ + warn "Extension is missing a '.': #{extension.inspect}" + end + # All Language extensions should be unique. Warn if there is a # duplicate. if @extension_index.key?(extension) @@ -47,7 +52,11 @@ module Linguist @extension_index[extension] = language # Index the extension without a leading ".": "rb" - @extension_index[extension.sub(/^./, '')] = language + @extension_index[extension.sub(/^\./, '')] = language + end + + language.filenames.each do |filename| + @filename_index[filename] = language end language @@ -102,6 +111,21 @@ module Linguist @extension_index[extension] end + # Public: Look up Language by filename. + # + # filename - The path String. + # + # Examples + # + # Language.find_by_filename('foo.rb') + # # => # + # + # Returns the Language or nil if none was found. + def self.find_by_filename(filename) + basename, extname = File.basename(filename), File.extname(filename) + @filename_index[basename] || @extension_index[extname] + end + # Public: Look up Language by its name or lexer. # # name - The case-insensitive String name of the Language @@ -163,6 +187,7 @@ module Linguist # Set extensions or default to []. # Consider using `@lexer.extensions` @extensions = attributes[:extensions] || [] + @filenames = attributes[:filenames] || [] # Set popular, common, and searchable flags @popular = attributes.key?(:popular) ? attributes[:popular] : false @@ -211,11 +236,20 @@ module Linguist # # Examples # - # # => ['.rb', '.rake', 'Rakefile', ...] + # # => ['.rb', '.rake', ...] # # Returns the extensions Array attr_reader :extensions + # Public: Get filenames + # + # Examples + # + # # => ['Rakefile', ...] + # + # Returns the extensions Array + attr_reader :filenames + # Internal: Get default alias name # # Returns the alias name String @@ -302,6 +336,7 @@ module Linguist :searchable => options.key?(:searchable) ? options[:searchable] : true, :search_term => options[:search_term], :extensions => options[:ext], + :filenames => options[:filenames], :popular => popular.include?(name), :common => common.include?(name) ) diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index ffdd5f14..22bc9b5b 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -105,6 +105,7 @@ Clojure: CoffeeScript: :ext: - .coffee + :filenames: - Cakefile ColdFusion: :lexer: ColdFusion HTML @@ -249,9 +250,10 @@ Haskell: INI: :ext: - .cfg - - .gitconfig - .ini - .properties + :filenames: + - .gitconfig IRC log: :lexer: IRC logs :search_term: irc @@ -277,11 +279,12 @@ JavaScript: :ext: - .js - .sjs - - Jakefile - .jss - .ssjs - .jsx - .jake + :filenames: + - Jakefile JSON: :lexer: javascript :search_term: javascript @@ -303,6 +306,7 @@ Lua: Makefile: :ext: - .mak + :filenames: - Makefile Mako: :ext: @@ -341,6 +345,7 @@ Nu: - nush :ext: - .nu + :filenames: - Nukefile NumPy: :ext: @@ -451,16 +456,17 @@ Ruby: - .rb - .ru - .builder - - Capfile - .rbw - .rbx - .god - .rake - .gemspec - - Rakefile - .irbrc - - Thorfile - .thor + :filenames: + - Capfile + - Rakefile + - Thorfile - Gemfile SQL: :searchable: false @@ -491,10 +497,11 @@ Shell: - zsh :ext: - .bash + - .sh + :filenames: - .bash_profile - .bashrc - .profile - - .sh - .zlogin - .zsh - .zshrc @@ -548,6 +555,7 @@ VimL: - vim :ext: - .vim + :filenames: - .vimrc - .gvimrc Visual Basic: @@ -583,6 +591,7 @@ YAML: :ext: - .yml - .yaml + :filenames: - .gemrc Java Server Pages: :lexer: Java Server Page diff --git a/lib/linguist/pathname.rb b/lib/linguist/pathname.rb index d3847f11..8c35557b 100644 --- a/lib/linguist/pathname.rb +++ b/lib/linguist/pathname.rb @@ -39,18 +39,9 @@ module Linguist # Pathname.new('file.rb').extname # # => '.rb' # - # Pathname.new('Rakefile').extname - # # => 'Rakefile' - # # Returns a String. def extname - if basename[0] == ?. - basename - elsif basename.include?('.') - File.extname(basename) - else - basename - end + File.extname(@path) end # Public: Get the language of the path @@ -65,7 +56,7 @@ module Linguist # # Returns a Langauge. def language - Language.find_by_extension(extname) || Language['Text'] + Language.find_by_filename(@path) || Language['Text'] end # Internal: Has a language. @@ -74,7 +65,7 @@ module Linguist # # Returns true or false. def language? - Language.find_by_extension(extname) ? true : false + Language.find_by_filename(@path) ? true : false end # Deprecated: Get the lexer of the path diff --git a/test/test_blob.rb b/test/test_blob.rb index 966dba48..466a215d 100644 --- a/test/test_blob.rb +++ b/test/test_blob.rb @@ -92,7 +92,11 @@ class TestBlob < Test::Unit::TestCase assert blob("README").text? assert blob("file.json").text? assert blob("file.txt").text? + assert blob("md").text? assert blob("script.sh").text? + assert blob("tender.md").text? + assert blob("txt").text? + assert blob("zip").text? end def test_image diff --git a/test/test_language.rb b/test/test_language.rb index cf642396..1e6380d9 100644 --- a/test/test_language.rb +++ b/test/test_language.rb @@ -108,6 +108,15 @@ class TestLanguage < Test::Unit::TestCase end end + def test_find_by_filename + assert_equal Language['Ruby'], Language.find_by_filename('foo.rb') + assert_equal Language['Ruby'], Language.find_by_filename('foo/bar.rb') + assert_equal Language['Ruby'], Language.find_by_filename('Rakefile') + assert_nil Language.find_by_filename('rb') + assert_nil Language.find_by_filename('.rb') + assert_nil Language.find_by_filename('.kt') + end + def test_find assert_equal "Ruby", Language['Ruby'].name assert_equal "Ruby", Language['ruby'].name diff --git a/test/test_pathname.rb b/test/test_pathname.rb index 881c2a17..4fd2c913 100644 --- a/test/test_pathname.rb +++ b/test/test_pathname.rb @@ -13,21 +13,19 @@ class TestPathname < Test::Unit::TestCase assert_equal 'file.rb', Pathname.new("file.rb").basename assert_equal 'file.rb', Pathname.new("./file.rb").basename assert_equal 'file.rb', Pathname.new("sub/dir/file.rb").basename + assert_equal '.profile', Pathname.new(".profile").basename end def test_extname - assert_equal '.rb', Pathname.new(".rb").extname assert_equal '.rb', Pathname.new("file.rb").extname assert_equal '.rb', Pathname.new("./file.rb").extname assert_equal '.rb', Pathname.new("sub/dir/file.rb").extname - - assert_equal 'Rakefile', Pathname.new("Rakefile").extname - assert_equal 'Rakefile', Pathname.new("./Rakefile").extname - assert_equal 'Rakefile', Pathname.new("vendor/Rakefile").extname + assert_equal '', Pathname.new(".profile").extname end def test_language - assert_equal Language['Ruby'], Pathname.new(".rb").language + assert_equal Language['Text'], Pathname.new(".rb").language + assert_equal Language['Ruby'], Pathname.new("file.rb").language assert_equal Language['Ruby'], Pathname.new("./file.rb").language assert_equal Language['Ruby'], Pathname.new("sub/dir/file.rb").language