Merge branch 'master' into 2512-local

This commit is contained in:
Arfon Smith
2016-03-17 14:00:34 -06:00
334 changed files with 53887 additions and 1152 deletions

73
lib/linguist/blob.rb Normal file
View File

@@ -0,0 +1,73 @@
require 'linguist/blob_helper'
module Linguist
# A Blob is a wrapper around the content of a file to make it quack
# like a Grit::Blob. It provides the basic interface: `name`,
# `data`, `path` and `size`.
class Blob
include BlobHelper
# Public: Initialize a new Blob.
#
# path - A path String (does not necessarily exists on the file system).
# content - Content of the file.
#
# Returns a Blob.
def initialize(path, content)
@path = path
@content = content
end
# Public: Filename
#
# Examples
#
# Blob.new("/path/to/linguist/lib/linguist.rb", "").path
# # => "/path/to/linguist/lib/linguist.rb"
#
# Returns a String
attr_reader :path
# Public: File name
#
# Returns a String
def name
File.basename(@path)
end
# Public: File contents.
#
# Returns a String.
def data
@content
end
# Public: Get byte size
#
# Returns an Integer.
def size
@content.bytesize
end
# Public: Get file extension.
#
# Returns a String.
def extension
extensions.last || ""
end
# Public: Return an array of the file extensions
#
# >> Linguist::Blob.new("app/views/things/index.html.erb").extensions
# => [".html.erb", ".erb"]
#
# Returns an Array
def extensions
basename, *segments = name.downcase.split(".")
segments.map.with_index do |segment, index|
"." + segments[index..-1].join(".")
end
end
end
end

View File

@@ -6,7 +6,7 @@ require 'yaml'
module Linguist
# DEPRECATED Avoid mixing into Blob classes. Prefer functional interfaces
# like `Language.detect` over `Blob#language`. Functions are much easier to
# like `Linguist.detect` over `Blob#language`. Functions are much easier to
# cache and compose.
#
# Avoid adding additional bloat to this module.
@@ -325,7 +325,7 @@ module Linguist
#
# Returns a Language or nil if none is detected
def language
@language ||= Language.detect(self)
@language ||= Linguist.detect(self)
end
# Internal: Get the TextMate compatible scope for the blob

View File

@@ -13,11 +13,18 @@
- (^|/)[Dd]ocumentation/
- (^|/)javadoc/
- ^man/
- ^[Ee]xamples/
## Documentation files ##
- (^|/)CHANGE(S|LOG)?(\.|$)
- (^|/)CONTRIBUTING(\.|$)
- (^|/)COPYING(\.|$)
- (^|/)INSTALL(\.|$)
- (^|/)LICEN[CS]E(\.|$)
- (^|/)[Ll]icen[cs]e(\.|$)
- (^|/)README(\.|$)
- (^|/)[Rr]eadme(\.|$)
# Samples folders
- ^[Ss]amples/

View File

@@ -1,10 +1,11 @@
require 'linguist/blob_helper'
require 'linguist/blob'
module Linguist
# A FileBlob is a wrapper around a File object to make it quack
# like a Grit::Blob. It provides the basic interface: `name`,
# `data`, `path` and `size`.
class FileBlob
class FileBlob < Blob
include BlobHelper
# Public: Initialize a new FileBlob from a path
@@ -18,20 +19,6 @@ module Linguist
@path = base_path ? path.sub("#{base_path}/", '') : path
end
# Public: Filename
#
# Examples
#
# FileBlob.new("/path/to/linguist/lib/linguist.rb").path
# # => "/path/to/linguist/lib/linguist.rb"
#
# FileBlob.new("/path/to/linguist/lib/linguist.rb",
# "/path/to/linguist").path
# # => "lib/linguist.rb"
#
# Returns a String
attr_reader :path
# Public: Read file permissions
#
# Returns a String like '100644'
@@ -39,13 +26,6 @@ module Linguist
File.stat(@fullpath).mode.to_s(8)
end
# Public: File name
#
# Returns a String
def name
File.basename(@fullpath)
end
# Public: Read file contents.
#
# Returns a String.
@@ -59,26 +39,5 @@ module Linguist
def size
File.size(@fullpath)
end
# Public: Get file extension.
#
# Returns a String.
def extension
extensions.last || ""
end
# Public: Return an array of the file extensions
#
# >> Linguist::FileBlob.new("app/views/things/index.html.erb").extensions
# => [".html.erb", ".erb"]
#
# Returns an Array
def extensions
basename, *segments = name.downcase.split(".")
segments.map.with_index do |segment, index|
"." + segments[index..-1].join(".")
end
end
end
end

View File

@@ -71,7 +71,10 @@ module Linguist
generated_jni_header? ||
vcr_cassette? ||
generated_module? ||
generated_unity3d_meta?
generated_unity3d_meta? ||
generated_racc? ||
generated_jflex? ||
generated_grammarkit?
end
# Internal: Is the blob an Xcode file?
@@ -241,22 +244,26 @@ module Linguist
return lines[0].include?("Code generated by")
end
PROTOBUF_EXTENSIONS = ['.py', '.java', '.h', '.cc', '.cpp']
# Internal: Is the blob a C++, Java or Python source file generated by the
# Protocol Buffer compiler?
#
# Returns true of false.
def generated_protocol_buffer?
return false unless ['.py', '.java', '.h', '.cc', '.cpp'].include?(extname)
return false unless PROTOBUF_EXTENSIONS.include?(extname)
return false unless lines.count > 1
return lines[0].include?("Generated by the protocol buffer compiler. DO NOT EDIT!")
end
APACHE_THRIFT_EXTENSIONS = ['.rb', '.py', '.go', '.js', '.m', '.java', '.h', '.cc', '.cpp']
# Internal: Is the blob generated by Apache Thrift compiler?
#
# Returns true or false
def generated_apache_thrift?
return false unless ['.rb', '.py', '.go', '.js', '.m', '.java', '.h', '.cc', '.cpp'].include?(extname)
return false unless APACHE_THRIFT_EXTENSIONS.include?(extname)
return false unless lines.count > 1
return lines[0].include?("Autogenerated by Thrift Compiler") || lines[1].include?("Autogenerated by Thrift Compiler")
@@ -355,5 +362,45 @@ module Linguist
return false unless lines.count > 1
return lines[0].include?("fileFormatVersion: ")
end
# Internal: Is this a Racc-generated file?
#
# A Racc-generated file contains:
# # This file is automatically generated by Racc x.y.z
# on the third line.
#
# Return true or false
def generated_racc?
return false unless extname == '.rb'
return false unless lines.count > 2
return lines[2].start_with?("# This file is automatically generated by Racc")
end
# Internal: Is this a JFlex-generated file?
#
# A JFlex-generated file contains:
# /* The following code was generated by JFlex x.y.z on d/at/e ti:me */
# on the first line.
#
# Return true or false
def generated_jflex?
return false unless extname == '.java'
return false unless lines.count > 1
return lines[0].start_with?("/* The following code was generated by JFlex ")
end
# Internal: Is this a GrammarKit-generated file?
#
# A GrammarKit-generated file typically contain:
# // This is a generated file. Not intended for manual editing.
# on the first line. This is not always the case, as it's possible to
# customize the class header.
#
# Return true or false
def generated_grammarkit?
return false unless extname == '.java'
return false unless lines.count > 1
return lines[0].start_with?("// This is a generated file. Not intended for manual editing.")
end
end
end

View File

@@ -1,6 +1,3 @@
# Note: This file is included in the github-linguist-grammars gem, not the
# github-linguist gem.
module Linguist
module Grammars
# Get the path to the directory containing the language grammar JSON files.

View File

@@ -13,11 +13,14 @@ module Linguist
# ])
#
# Returns an Array of languages, or empty if none matched or were inconclusive.
def self.call(blob, languages)
def self.call(blob, candidates)
data = blob.data
@heuristics.each do |heuristic|
return Array(heuristic.call(data)) if heuristic.matches?(languages)
if heuristic.matches?(blob.name)
languages = Array(heuristic.call(data))
return languages if languages.any? || languages.all? { |l| candidates.include?(l) }
end
end
[] # No heuristics matched
@@ -30,7 +33,7 @@ module Linguist
#
# Examples
#
# disambiguate "Perl", "Prolog" do |data|
# disambiguate ".pm" do |data|
# if data.include?("use strict")
# Language["Perl"]
# elsif /^[^#]+:-/.match(data)
@@ -38,22 +41,23 @@ module Linguist
# end
# end
#
def self.disambiguate(*languages, &heuristic)
@heuristics << new(languages, &heuristic)
def self.disambiguate(*extensions, &heuristic)
@heuristics << new(extensions, &heuristic)
end
# Internal: Array of defined heuristics
@heuristics = []
# Internal
def initialize(languages, &heuristic)
@languages = languages
def initialize(extensions, &heuristic)
@extensions = extensions
@heuristic = heuristic
end
# Internal: Check if this heuristic matches the candidate languages.
def matches?(candidates)
candidates.any? && candidates.all? { |l| @languages.include?(l.name) }
def matches?(filename)
filename = filename.downcase
@extensions.any? { |ext| filename.end_with?(ext) }
end
# Internal: Perform the heuristic
@@ -62,99 +66,9 @@ module Linguist
end
# Common heuristics
ObjectiveCRegex = /^[ \t]*@(interface|class|protocol|property|end|synchronised|selector|implementation)\b/
ObjectiveCRegex = /^\s*(@(interface|class|protocol|property|end|synchronised|selector|implementation)\b|#import\s+.+\.h[">])/
disambiguate "BitBake", "BlitzBasic" do |data|
if /^\s*; /.match(data) || data.include?("End Function")
Language["BlitzBasic"]
elsif /^\s*(# |include|require)\b/.match(data)
Language["BitBake"]
end
end
disambiguate "C#", "Smalltalk" do |data|
if /![\w\s]+methodsFor: /.match(data)
Language["Smalltalk"]
elsif /^\s*namespace\s*[\w\.]+\s*{/.match(data) || /^\s*\/\//.match(data)
Language["C#"]
end
end
disambiguate "Objective-C", "C++", "C" do |data|
if ObjectiveCRegex.match(data)
Language["Objective-C"]
elsif (/^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/.match(data) ||
/^\s*template\s*</.match(data) || /^[ \t]*try/.match(data) || /^[ \t]*catch\s*\(/.match(data) || /^[ \t]*(class|(using[ \t]+)?namespace)\s+\w+/.match(data) || /^[ \t]*(private|public|protected):$/.match(data) || /std::\w+/.match(data))
Language["C++"]
end
end
disambiguate "Perl", "Perl6", "Prolog" do |data|
if data.include?("use v6")
Language["Perl6"]
elsif data.match(/use strict|use\s+v?5\./)
Language["Perl"]
elsif /^[^#]+:-/.match(data)
Language["Prolog"]
end
end
disambiguate "ECL", "Prolog" do |data|
if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?(":=")
Language["ECL"]
end
end
disambiguate "IDL", "Prolog", "INI", "QMake" do |data|
if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?("last_client=")
Language["INI"]
elsif data.include?("HEADERS") && data.include?("SOURCES")
Language["QMake"]
elsif /^\s*function[ \w,]+$/.match(data)
Language["IDL"]
end
end
disambiguate "GAP", "Scilab" do |data|
if (data.include?("gap> "))
Language["GAP"]
# Heads up - we don't usually write heuristics like this (with no regex match)
else
Language["Scilab"]
end
end
disambiguate "Common Lisp", "OpenCL", "Cool" do |data|
if /^\s*\((defun|in-package|defpackage) /i.match(data)
Language["Common Lisp"]
elsif /^class/x.match(data)
Language["Cool"]
elsif /\/\* |\/\/ |^\}/.match(data)
Language["OpenCL"]
end
end
disambiguate "Hack", "PHP" do |data|
if data.include?("<?hh")
Language["Hack"]
elsif /<?[^h]/.match(data)
Language["PHP"]
end
end
disambiguate "Scala", "SuperCollider" do |data|
if /\^(this|super)\./.match(data) || /^\s*(\+|\*)\s*\w+\s*{/.match(data) || /^\s*~\w+\s*=\./.match(data)
Language["SuperCollider"]
elsif /^\s*import (scala|java)\./.match(data) || /^\s*val\s+\w+\s*=/.match(data) || /^\s*class\b/.match(data)
Language["Scala"]
end
end
disambiguate "AsciiDoc", "AGS Script", "Public Key" do |data|
disambiguate ".asc" do |data|
if /^(----[- ]BEGIN|ssh-(rsa|dss)) /.match(data)
Language["Public Key"]
elsif /^[=-]+(\s|\n)|{{[A-Za-z]/.match(data)
@@ -164,15 +78,75 @@ module Linguist
end
end
disambiguate "FORTRAN", "Forth", "Formatted" do |data|
disambiguate ".bb" do |data|
if /^\s*; /.match(data) || data.include?("End Function")
Language["BlitzBasic"]
elsif /^\s*(# |include|require)\b/.match(data)
Language["BitBake"]
end
end
disambiguate ".ch" do |data|
if /^\s*#\s*(if|ifdef|ifndef|define|command|xcommand|translate|xtranslate|include|pragma|undef)\b/i.match(data)
Language["xBase"]
end
end
disambiguate ".cl" do |data|
if /^\s*\((defun|in-package|defpackage) /i.match(data)
Language["Common Lisp"]
elsif /^class/x.match(data)
Language["Cool"]
elsif /\/\* |\/\/ |^\}/.match(data)
Language["OpenCL"]
end
end
disambiguate ".cs" do |data|
if /![\w\s]+methodsFor: /.match(data)
Language["Smalltalk"]
elsif /^\s*namespace\s*[\w\.]+\s*{/.match(data) || /^\s*\/\//.match(data)
Language["C#"]
end
end
disambiguate ".d" do |data|
if /^module /.match(data)
Language["D"]
elsif /^((dtrace:::)?BEGIN|provider |#pragma (D (option|attributes)|ident)\s)/.match(data)
Language["DTrace"]
elsif /(\/.*:( .* \\)$| : \\$|^ : |: \\$)/.match(data)
Language["Makefile"]
end
end
disambiguate ".ecl" do |data|
if /^[^#]+:-/.match(data)
Language["ECLiPSe"]
elsif data.include?(":=")
Language["ECL"]
end
end
disambiguate ".for", ".f" do |data|
if /^: /.match(data)
Language["Forth"]
elsif /^([c*][^a-z]| (subroutine|program)\s|\s*!)/i.match(data)
elsif /^([c*][^abd-z]| (subroutine|program|end)\s|\s*!)/i.match(data)
Language["FORTRAN"]
end
end
disambiguate "F#", "Forth", "GLSL", "Filterscript" do |data|
disambiguate ".fr" do |data|
if /^(: |also |new-device|previous )/.match(data)
Language["Forth"]
elsif /^\s*(import|module|package|data|type) /.match(data)
Language["Frege"]
else
Language["Text"]
end
end
disambiguate ".fs" do |data|
if /^(: |new-device)/.match(data)
Language["Forth"]
elsif /^\s*(#light|import|let|module|namespace|open|type)/.match(data)
@@ -184,7 +158,48 @@ module Linguist
end
end
disambiguate "Limbo", "M", "MUF", "Mathematica", "Matlab", "Mercury", "Objective-C" do |data|
disambiguate ".gs" do |data|
Language["Gosu"] if /^uses java\./.match(data)
end
disambiguate ".h" do |data|
if ObjectiveCRegex.match(data)
Language["Objective-C"]
elsif (/^\s*#\s*include <(cstdint|string|vector|map|list|array|bitset|queue|stack|forward_list|unordered_map|unordered_set|(i|o|io)stream)>/.match(data) ||
/^\s*template\s*</.match(data) || /^[ \t]*try/.match(data) || /^[ \t]*catch\s*\(/.match(data) || /^[ \t]*(class|(using[ \t]+)?namespace)\s+\w+/.match(data) || /^[ \t]*(private|public|protected):$/.match(data) || /std::\w+/.match(data))
Language["C++"]
end
end
disambiguate ".l" do |data|
if /\(def(un|macro)\s/.match(data)
Language["Common Lisp"]
elsif /^(%[%{}]xs|<.*>)/.match(data)
Language["Lex"]
elsif /^\.[a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /^\((de|class|rel|code|data|must)\s/.match(data)
Language["PicoLisp"]
end
end
disambiguate ".ls" do |data|
if /^\s*package\s*[\w\.\/\*\s]*\s*{/.match(data)
Language["LoomScript"]
else
Language["LiveScript"]
end
end
disambiguate ".lsp", ".lisp" do |data|
if /^\s*\((defun|in-package|defpackage) /i.match(data)
Language["Common Lisp"]
elsif /^\s*\(define /.match(data)
Language["NewLisp"]
end
end
disambiguate ".m" do |data|
if ObjectiveCRegex.match(data)
Language["Objective-C"]
elsif data.include?(":- module")
@@ -202,46 +217,144 @@ module Linguist
end
end
disambiguate "Gosu", "JavaScript" do |data|
Language["Gosu"] if /^uses java\./.match(data)
end
disambiguate "LoomScript", "LiveScript" do |data|
if /^\s*package\s*[\w\.\/\*\s]*\s*{/.match(data)
Language["LoomScript"]
else
Language["LiveScript"]
disambiguate ".ml" do |data|
if /(^\s*module)|let rec |match\s+(\S+\s)+with/.match(data)
Language["OCaml"]
elsif /=> |case\s+(\S+\s)+of/.match(data)
Language["Standard ML"]
end
end
disambiguate "Common Lisp", "NewLisp" do |data|
if /^\s*\((defun|in-package|defpackage) /i.match(data)
Language["Common Lisp"]
elsif /^\s*\(define /.match(data)
Language["NewLisp"]
end
end
disambiguate "TypeScript", "XML" do |data|
if data.include?("<TS ")
disambiguate ".mod" do |data|
if data.include?('<!ENTITY ')
Language["XML"]
elsif /MODULE\s\w+\s*;/i.match(data) || /^\s*END \w+;$/i.match(data)
Language["Modula-2"]
else
Language["TypeScript"]
[Language["Linux Kernel Module"], Language["AMPL"]]
end
end
disambiguate "Frege", "Forth", "Text" do |data|
if /^(: |also |new-device|previous )/.match(data)
Language["Forth"]
elsif /^\s*(import|module|package|data|type) /.match(data)
Language["Frege"]
disambiguate ".ms" do |data|
if /^[.'][a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /(?<!\S)\.(include|globa?l)\s/.match(data) || /(?<!\/\*)(\A|\n)\s*\.[A-Za-z]/.match(data.gsub(/"([^\\"]|\\.)*"|'([^\\']|\\.)*'|\\\s*(?:--.*)?\n/, ""))
Language["GAS"]
else
Language["MAXScript"]
end
end
disambiguate ".n" do |data|
if /^[.']/.match(data)
Language["Groff"]
elsif /^(module|namespace|using)\s/.match(data)
Language["Nemerle"]
end
end
disambiguate ".ncl" do |data|
if data.include?("THE_TITLE")
Language["Text"]
end
end
disambiguate "PLSQL", "SQLPL", "PLpgSQL", "SQL" do |data|
if /^\\i\b|AS \$\$|LANGUAGE '+plpgsql'+/i.match(data) || /SECURITY (DEFINER|INVOKER)/i.match(data) || /BEGIN( WORK| TRANSACTION)?;/i.match(data)
disambiguate ".nl" do |data|
if /^(b|g)[0-9]+ /.match(data)
Language["NL"]
else
Language["NewLisp"]
end
end
disambiguate ".php" do |data|
if data.include?("<?hh")
Language["Hack"]
elsif /<?[^h]/.match(data)
Language["PHP"]
end
end
disambiguate ".pl" do |data|
if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif /use strict|use\s+v?5\./.match(data)
Language["Perl"]
elsif /^(use v6|(my )?class|module)/.match(data)
Language["Perl6"]
end
end
disambiguate ".pm", ".t" do |data|
if /use strict|use\s+v?5\./.match(data)
Language["Perl"]
elsif /^(use v6|(my )?class|module)/.match(data)
Language["Perl6"]
end
end
disambiguate ".pod" do |data|
if /^=\w+$/.match(data)
Language["Pod"]
else
Language["Perl"]
end
end
disambiguate ".pro" do |data|
if /^[^#]+:-/.match(data)
Language["Prolog"]
elsif data.include?("last_client=")
Language["INI"]
elsif data.include?("HEADERS") && data.include?("SOURCES")
Language["QMake"]
elsif /^\s*function[ \w,]+$/.match(data)
Language["IDL"]
end
end
disambiguate ".props" do |data|
if /^(\s*)(<Project|<Import|<Property|<?xml|xmlns)/i.match(data)
Language["XML"]
elsif /\w+\s*=\s*/i.match(data)
Language["INI"]
end
end
disambiguate ".r" do |data|
if /\bRebol\b/i.match(data)
Language["Rebol"]
elsif data.include?("<-")
Language["R"]
end
end
disambiguate ".rpy" do |data|
if /(^(import|from|class|def)[\s\S])/m.match(data)
Language["Python"]
else
Language["Ren'Py"]
end
end
disambiguate ".rs" do |data|
if /^(use |fn |mod |pub |macro_rules|impl|#!?\[)/.match(data)
Language["Rust"]
elsif /#include|#pragma\s+(rs|version)|__attribute__/.match(data)
Language["RenderScript"]
end
end
disambiguate ".sc" do |data|
if /\^(this|super)\./.match(data) || /^\s*(\+|\*)\s*\w+\s*{/.match(data) || /^\s*~\w+\s*=\./.match(data)
Language["SuperCollider"]
elsif /^\s*import (scala|java)\./.match(data) || /^\s*val\s+\w+\s*=/.match(data) || /^\s*class\b/.match(data)
Language["Scala"]
end
end
disambiguate ".sql" do |data|
if /^\\i\b|AS \$\$|LANGUAGE '?plpgsql'?/i.match(data) || /SECURITY (DEFINER|INVOKER)/i.match(data) || /BEGIN( WORK| TRANSACTION)?;/i.match(data)
#Postgres
Language["PLpgSQL"]
elsif /(alter module)|(language sql)|(begin( NOT)+ atomic)/i.match(data) || /signal SQLSTATE '[0-9]+'/i.match(data)
@@ -256,81 +369,20 @@ module Linguist
end
end
disambiguate "D", "DTrace", "Makefile" do |data|
if /^module /.match(data)
Language["D"]
elsif /^((dtrace:::)?BEGIN|provider |#pragma (D (option|attributes)|ident)\s)/.match(data)
Language["DTrace"]
elsif /(\/.*:( .* \\)$| : \\$|^ : |: \\$)/.match(data)
Language["Makefile"]
end
end
disambiguate "OCaml", "Standard ML" do |data|
if /(^\s*module)|let rec |match\s+(\S+\s)+with/.match(data)
Language["OCaml"]
elsif /=> |case\s+(\S+\s)+of/.match(data)
Language["Standard ML"]
end
end
disambiguate "XML", "Modula-2", "Linux Kernel Module", "AMPL" do |data|
if data.include?('<!ENTITY ')
disambiguate ".ts" do |data|
if data.include?("<TS ")
Language["XML"]
elsif /MODULE\s\w+\s*;/i.match(data) || /^\s*END \w+;$/i.match(data)
Language["Modula-2"]
else
[Language["Linux Kernel Module"], Language["AMPL"]]
Language["TypeScript"]
end
end
disambiguate "Text", "NCL" do |data|
if data.include?("THE_TITLE")
Language["Text"]
end
end
disambiguate "NL", "NewLisp" do |data|
if /^(b|g)[0-9]+ /.match(data)
Language["NL"]
disambiguate ".tst" do |data|
if (data.include?("gap> "))
Language["GAP"]
# Heads up - we don't usually write heuristics like this (with no regex match)
else
Language["NewLisp"]
end
end
disambiguate "Rust", "RenderScript" do |data|
if /^(use |fn |mod |pub |macro_rules|impl|#!?\[)/.match(data)
Language["Rust"]
elsif /#include|#pragma\s+(rs|version)|__attribute__/.match(data)
Language["RenderScript"]
end
end
disambiguate "Common Lisp", "Lex", "Groff", "PicoLisp" do |data|
if /\(def(un|macro)\s/.match(data)
Language["Common Lisp"]
elsif /^(%[%{}]xs|<.*>)/.match(data)
Language["Lex"]
elsif /^\.[a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /^\((de|class|rel|code|data|must)\s/.match(data)
Language["PicoLisp"]
end
end
disambiguate "Groff", "Nemerle" do |data|
if /^[.']/.match(data)
Language["Groff"]
elsif /^(module|namespace|using)\s/.match(data)
Language["Nemerle"]
end
end
disambiguate "GAS", "Groff" do |data|
if /^[.'][a-z][a-z](\s|$)/i.match(data)
Language["Groff"]
elsif /((^|\s)move?[. ])|\.(include|globa?l)\s/.match(data)
Language["GAS"]
Language["Scilab"]
end
end
end

View File

@@ -87,14 +87,6 @@ module Linguist
language
end
STRATEGIES = [
Linguist::Strategy::Modeline,
Linguist::Shebang,
Linguist::Strategy::Filename,
Linguist::Heuristics,
Linguist::Classifier
]
# Public: Detects the Language of the blob.
#
# blob - an object that includes the Linguist `BlobHelper` interface;
@@ -102,34 +94,8 @@ module Linguist
#
# Returns Language or nil.
def self.detect(blob)
# Bail early if the blob is binary or empty.
return nil if blob.likely_binary? || blob.binary? || blob.empty?
Linguist.instrument("linguist.detection", :blob => blob) do
# Call each strategy until one candidate is returned.
languages = []
returning_strategy = nil
STRATEGIES.each do |strategy|
returning_strategy = strategy
candidates = Linguist.instrument("linguist.strategy", :blob => blob, :strategy => strategy, :candidates => languages) do
strategy.call(blob, languages)
end
if candidates.size == 1
languages = candidates
break
elsif candidates.size > 1
# More than one candidate was found, pass them to the next strategy.
languages = candidates
else
# No candidates, try the next strategy
end
end
Linguist.instrument("linguist.detected", :blob => blob, :strategy => returning_strategy, :language => languages.first)
languages.first
end
warn "[DEPRECATED] `Linguist::Language.detect` is deprecated. Use `Linguist.detect`. #{caller[0]}"
Linguist.detect(blob)
end
# Public: Get all Languages
@@ -150,7 +116,8 @@ module Linguist
#
# Returns the Language or nil if none was found.
def self.find_by_name(name)
name && @name_index[name.downcase]
return nil if name.to_s.empty?
name && (@name_index[name.downcase] || @name_index[name.split(',').first.downcase])
end
# Public: Look up Language by one of its aliases.
@@ -164,7 +131,8 @@ module Linguist
#
# Returns the Language or nil if none was found.
def self.find_by_alias(name)
name && @alias_index[name.downcase]
return nil if name.to_s.empty?
name && (@alias_index[name.downcase] || @alias_index[name.split(',').first.downcase])
end
# Public: Look up Languages by filename.
@@ -240,7 +208,8 @@ module Linguist
#
# Returns the Language or nil if none was found.
def self.[](name)
name && @index[name.downcase]
return nil if name.to_s.empty?
name && (@index[name.downcase] || @index[name.split(',').first.downcase])
end
# Public: A List of popular languages

373
lib/linguist/languages.yml Normal file → Executable file
View File

@@ -8,7 +8,8 @@
# Use "text" if a mode does not exist.
# wrap - Boolean wrap to enable line wrapping (default: false)
# extensions - An Array of associated extensions (the first one is
# considered the primary extension)
# considered the primary extension, the others should be
# listed alphabetically)
# interpreters - An Array of associated interpreters
# searchable - Boolean flag to enable searching (defaults to true)
# search_term - Deprecated: Some languages maybe indexed under a
@@ -141,7 +142,7 @@ Agda:
Alloy:
type: programming # 'modeling' would be more appropiate
color: "#cc5c24"
color: "#64C800"
extensions:
- .als
ace_mode: text
@@ -182,6 +183,7 @@ AppleScript:
interpreters:
- osascript
ace_mode: applescript
color: "#101F1F"
Arc:
type: programming
@@ -214,7 +216,7 @@ AspectJ:
color: "#a957b0"
extensions:
- .aj
tm_scope: none
tm_scope: source.aspectj
ace_mode: text
Assembly:
@@ -289,6 +291,7 @@ Batchfile:
- .cmd
tm_scope: source.dosbatch
ace_mode: batchfile
color: "#C1F12E"
Befunge:
type: programming
@@ -303,6 +306,7 @@ Bison:
extensions:
- .bison
ace_mode: text
color: "#6A463F"
BitBake:
type: programming
@@ -392,6 +396,7 @@ C#:
- csharp
extensions:
- .cs
- .cake
- .cshtml
- .csx
@@ -470,6 +475,13 @@ CSS:
extensions:
- .css
CSV:
type: data
ace_mode: text
tm_scope: none
extensions:
- .csv
Cap'n Proto:
type: programming
tm_scope: source.capnp
@@ -501,6 +513,13 @@ Chapel:
- .chpl
ace_mode: text
Charity:
type: programming
extensions:
- .ch
tm_scope: none
ace_mode: text
ChucK:
type: programming
extensions:
@@ -532,6 +551,14 @@ Clean:
tm_scope: none
ace_mode: text
Click:
type: programming
color: "#E4E6F3"
extensions:
- .click
tm_scope: source.click
ace_mode: text
Clojure:
type: programming
ace_mode: clojure
@@ -560,6 +587,7 @@ CoffeeScript:
extensions:
- .coffee
- ._coffee
- .cake
- .cjsx
- .cson
- .iced
@@ -609,6 +637,7 @@ Common Lisp:
- .lsp
- .ny
- .podsl
- .sexp
interpreters:
- lisp
- sbcl
@@ -619,7 +648,7 @@ Common Lisp:
Component Pascal:
type: programming
color: "#b0ce4e"
color: "#B0CE4E"
extensions:
- .cp
- .cps
@@ -682,6 +711,7 @@ Cucumber:
aliases:
- gherkin
ace_mode: text
color: "#5B2063"
Cuda:
type: programming
@@ -690,6 +720,7 @@ Cuda:
- .cuh
tm_scope: source.cuda-c++
ace_mode: c_cpp
color: "#3A4E3A"
Cycript:
type: programming
@@ -711,7 +742,7 @@ Cython:
D:
type: programming
color: "#fcd46d"
color: "#ba595e"
extensions:
- .d
- .di
@@ -743,6 +774,14 @@ DM:
tm_scope: source.c++
ace_mode: c_cpp
DNS Zone:
type: data
extensions:
- .zone
- .arpa
tm_scope: text.zone_file
ace_mode: text
DTrace:
type: programming
aliases:
@@ -774,7 +813,6 @@ Dart:
Diff:
type: data
color: "#88dddd"
extensions:
- .diff
- .patch
@@ -827,6 +865,14 @@ ECL:
tm_scope: none
ace_mode: text
ECLiPSe:
type: programming
group: prolog
extensions:
- .ecl
tm_scope: source.prolog.eclipse
ace_mode: prolog
Eagle:
type: markup
color: "#814C05"
@@ -860,6 +906,8 @@ Elixir:
ace_mode: elixir
filenames:
- mix.lock
interpreters:
- elixir
Elm:
type: programming
@@ -902,6 +950,8 @@ Erlang:
- .es
- .escript
- .hrl
- .xrl
- .yrl
filenames:
- rebar.config
- rebar.config.lock
@@ -987,6 +1037,7 @@ Formatted:
type: data
extensions:
- .for
- .eam.fs
tm_scope: none
ace_mode: text
@@ -1004,6 +1055,16 @@ Forth:
- .fs
ace_mode: forth
FreeMarker:
type: programming
color: "#0050b2"
aliases:
- ftl
extensions:
- .ftl
tm_scope: text.html.ftl
ace_mode: ftl
Frege:
type: programming
color: "#00cafe"
@@ -1229,6 +1290,7 @@ Groff:
- '.8'
- '.9'
- .l
- .me
- .ms
- .n
- .rno
@@ -1249,6 +1311,8 @@ Groovy:
- .gvy
interpreters:
- groovy
filenames:
- Jenkinsfile
Groovy Server Pages:
type: programming
@@ -1261,6 +1325,24 @@ Groovy Server Pages:
tm_scope: text.html.jsp
ace_mode: jsp
HCL:
type: programming
extensions:
- .hcl
- .tf
ace_mode: ruby
tm_scope: source.ruby
HLSL:
type: programming
extensions:
- .hlsl
- .fx
- .fxh
- .hlsli
ace_mode: text
tm_scope: none
HTML:
type: markup
tm_scope: text.html.basic
@@ -1285,11 +1367,22 @@ HTML+Django:
- .mustache
- .jinja
aliases:
- django
- html+django/jinja
- html+jinja
- htmldjango
ace_mode: django
HTML+EEX:
type: markup
tm_scope: text.html.elixir
group: HTML
aliases:
- eex
extensions:
- .eex
ace_mode: text
HTML+ERB:
type: markup
tm_scope: text.html.erb
@@ -1299,7 +1392,7 @@ HTML+ERB:
extensions:
- .erb
- .erb.deface
ace_mode: html_ruby
ace_mode: text
HTML+PHP:
type: markup
@@ -1323,6 +1416,7 @@ Hack:
- .hh
- .php
tm_scope: text.html.php
color: "#878787"
Haml:
group: HTML
@@ -1331,10 +1425,12 @@ Haml:
- .haml
- .haml.deface
ace_mode: haml
color: "#ECE2A9"
Handlebars:
type: markup
color: "#01a9d6"
group: HTML
aliases:
- hbs
- htmlbars
@@ -1442,7 +1538,7 @@ Inform 7:
extensions:
- .ni
- .i7x
tm_scope: source.Inform7
tm_scope: source.inform7
aliases:
- i7
- inform7
@@ -1513,7 +1609,9 @@ JSON:
searchable: false
extensions:
- .json
- .geojson
- .lock
- .topojson
filenames:
- .jshintrc
- composer.lock
@@ -1541,12 +1639,20 @@ JSONiq:
- .jq
tm_scope: source.jq
JSX:
type: programming
group: JavaScript
extensions:
- .jsx
tm_scope: source.js.jsx
ace_mode: javascript
Jade:
group: HTML
type: markup
extensions:
- .jade
tm_scope: source.jade
tm_scope: text.jade
ace_mode: jade
Jasmin:
@@ -1591,10 +1697,10 @@ JavaScript:
- .gs
- .jake
- .jsb
- .jscad
- .jsfl
- .jsm
- .jss
- .jsx
- .njs
- .pac
- .sjs
@@ -1626,6 +1732,18 @@ Julia:
color: "#a270ba"
ace_mode: julia
Jupyter Notebook:
type: markup
ace_mode: json
tm_scope: source.json
color: "#DA5B0B"
extensions:
- .ipynb
filenames:
- Notebook
aliases:
- IPython Notebook
KRL:
type: programming
color: "#28431f"
@@ -1638,6 +1756,7 @@ KiCad:
type: programming
extensions:
- .sch
- .brd
- .kicad_pcb
tm_scope: none
ace_mode: text
@@ -1673,6 +1792,7 @@ LLVM:
extensions:
- .ll
ace_mode: text
color: "#185619"
LOLCODE:
type: programming
@@ -1687,6 +1807,7 @@ LSL:
ace_mode: lsl
extensions:
- .lsl
- .lslp
interpreters:
- lsl
color: '#3d9970'
@@ -1695,8 +1816,8 @@ LabVIEW:
type: programming
extensions:
- .lvproj
tm_scope: none
ace_mode: text
tm_scope: text.xml
ace_mode: xml
Lasso:
type: programming
@@ -1735,6 +1856,7 @@ Less:
- .less
tm_scope: source.css.less
ace_mode: less
color: "#A1D9A1"
Lex:
type: programming
@@ -1886,6 +2008,34 @@ M:
tm_scope: source.lisp
ace_mode: lisp
M4:
type: programming
extensions:
- .m4
tm_scope: none
ace_mode: text
M4Sugar:
type: programming
group: M4
aliases:
- autoconf
extensions:
- .m4
filenames:
- configure.ac
tm_scope: none
ace_mode: text
MAXScript:
type: programming
color: "#00a6a6"
extensions:
- .ms
- .mcr
tm_scope: source.maxscript
ace_mode: text
MTML:
type: markup
color: "#b7e1f4"
@@ -1918,6 +2068,9 @@ Makefile:
- GNUmakefile
- Kbuild
- Makefile
- Makefile.am
- Makefile.in
- Makefile.inc
- makefile
interpreters:
- make
@@ -1943,6 +2096,7 @@ Markdown:
- .mkdown
- .ron
tm_scope: source.gfm
color: "#083FA1"
Mask:
type: markup
@@ -1959,6 +2113,7 @@ Mathematica:
- .cdf
- .m
- .ma
- .mt
- .nb
- .nbp
- .wl
@@ -1970,6 +2125,8 @@ Mathematica:
Matlab:
type: programming
color: "#bb92ac"
aliases:
- octave
extensions:
- .matlab
- .m
@@ -2003,6 +2160,7 @@ MediaWiki:
wrap: true
extensions:
- .mediawiki
- .wiki
tm_scope: text.html.mediawiki
ace_mode: text
@@ -2018,6 +2176,14 @@ Mercury:
tm_scope: source.mercury
ace_mode: prolog
Metal:
type: programming
color: "#8f14e9"
extensions:
- .metal
tm_scope: source.c++
ace_mode: c_cpp
MiniD: # Legacy
type: programming
searchable: false
@@ -2093,7 +2259,7 @@ Myghty:
NCL:
type: programming
color: #28431f
color: "#28431f"
extensions:
- .ncl
tm_scope: source.ncl
@@ -2170,6 +2336,7 @@ Nginx:
aliases:
- nginx configuration file
ace_mode: text
color: "#9469E9"
Nimrod:
type: programming
@@ -2228,6 +2395,7 @@ NumPy:
- .numsc
tm_scope: none
ace_mode: text
color: "#9C8AF9"
OCaml:
type: programming
@@ -2397,6 +2565,7 @@ PHP:
- .php3
- .php4
- .php5
- .phps
- .phpt
filenames:
- Phakefile
@@ -2410,8 +2579,10 @@ PLSQL:
type: programming
ace_mode: sql
tm_scope: source.plsql.oracle
color: "#dad8d8"
extensions:
- .pls
- .pck
- .pkb
- .pks
- .plb
@@ -2426,6 +2597,16 @@ PLpgSQL:
extensions:
- .sql
POV-Ray SDL:
type: programming
aliases:
- pov-ray
- povray
extensions:
- .pov
- .inc
ace_mode: text
Pan:
type: programming
color: '#cc0000'
@@ -2476,7 +2657,7 @@ Parrot Internal Representation:
Pascal:
type: programming
color: "#b0ce4e"
color: "#E3F171"
extensions:
- .pas
- .dfm
@@ -2525,9 +2706,16 @@ Perl6:
- Rexfile
interpreters:
- perl6
tm_scope: source.perl.6
tm_scope: source.perl6fe
ace_mode: perl
Pickle:
type: data
extensions:
- .pkl
tm_scope: none
ace_mode: text
PicoLisp:
type: programming
extensions:
@@ -2572,6 +2760,13 @@ PogoScript:
tm_scope: source.pogoscript
ace_mode: text
Pony:
type: programming
extensions:
- .pony
tm_scope: source.pony
ace_mode: text
PostScript:
type: markup
extensions:
@@ -2604,11 +2799,13 @@ Prolog:
color: "#74283c"
extensions:
- .pl
- .ecl
- .pro
- .prolog
- .yap
interpreters:
- swipl
- yap
tm_scope: source.prolog
ace_mode: prolog
Propeller Spin:
@@ -2639,7 +2836,7 @@ Public Key:
Puppet:
type: programming
color: "#332A77"
color: "#302B6D"
extensions:
- .pp
filenames:
@@ -2668,7 +2865,7 @@ PureScript:
color: "#1D222D"
extensions:
- .purs
tm_scope: source.haskell
tm_scope: source.purescript
ace_mode: haskell
Python:
@@ -2677,6 +2874,7 @@ Python:
color: "#3572A5"
extensions:
- .py
- .bzl
- .cgi
- .fcgi
- .gyp
@@ -2685,10 +2883,12 @@ Python:
- .pyp
- .pyt
- .pyw
- .rpy
- .tac
- .wsgi
- .xpy
filenames:
- BUCK
- BUILD
- SConscript
- SConstruct
@@ -2730,7 +2930,7 @@ QMake:
R:
type: programming
color: "#198ce7"
color: "#198CE7"
aliases:
- R
- Rscript
@@ -2746,7 +2946,7 @@ R:
ace_mode: r
RAML:
type: data
type: markup
ace_mode: yaml
tm_scope: source.yaml
color: "#77d9fb"
@@ -2760,6 +2960,7 @@ RDoc:
extensions:
- .rdoc
tm_scope: text.rdoc
color: "#8E84BF"
REALbasic:
type: programming
@@ -2789,7 +2990,7 @@ RMarkdown:
ace_mode: markdown
extensions:
- .rmd
tm_scope: none
tm_scope: source.gfm
Racket:
type: programming
@@ -2855,6 +3056,16 @@ Redcode:
tm_scope: none
ace_mode: text
Ren'Py:
type: programming
aliases:
- renpy
color: "#ff7f7f"
extensions:
- .rpy
tm_scope: source.renpy
ace_mode: python
RenderScript:
type: programming
extensions:
@@ -2919,6 +3130,7 @@ Ruby:
- .pryrc
- Appraisals
- Berksfile
- Brewfile
- Buildfile
- Deliverfile
- Fastfile
@@ -2939,6 +3151,7 @@ Rust:
color: "#dea584"
extensions:
- .rs
- .rs.in
ace_mode: rust
SAS:
@@ -2956,6 +3169,7 @@ SCSS:
ace_mode: scss
extensions:
- .scss
color: "#CF649A"
SMT:
type: programming
@@ -3058,11 +3272,12 @@ Sass:
extensions:
- .sass
ace_mode: sass
color: "#CF649A"
Scala:
type: programming
ace_mode: scala
color: "#7dd3b0"
color: "#DC322F"
extensions:
- .scala
- .sbt
@@ -3115,6 +3330,7 @@ Shell:
color: "#89e051"
aliases:
- sh
- shell-script
- bash
- zsh
extensions:
@@ -3125,6 +3341,7 @@ Shell:
- .command
- .fcgi
- .ksh
- .sh.in
- .tmux
- .tool
- .zsh
@@ -3167,6 +3384,7 @@ Slim:
color: "#ff8f77"
extensions:
- .slim
tm_scope: text.slim
ace_mode: text
Smali:
@@ -3213,6 +3431,14 @@ Squirrel:
tm_scope: source.c++
ace_mode: c_cpp
Stan:
type: programming
color: "#b2011d"
extensions:
- .stan
ace_mode: text
tm_scope: source.stan
Standard ML:
type: programming
color: "#dc566d"
@@ -3250,9 +3476,12 @@ SuperCollider:
type: programming
color: "#46390b"
extensions:
- .scd
- .sc
tm_scope: none
- .scd
interpreters:
- sclang
- scsynth
tm_scope: source.supercollider
ace_mode: text
Swift:
@@ -3337,6 +3566,16 @@ Tea:
tm_scope: source.tea
ace_mode: text
Terra:
type: programming
extensions:
- .t
color: "#00004c"
ace_mode: lua
group: Lua
interpreters:
- lua
Text:
type: prose
wrap: true
@@ -3345,7 +3584,20 @@ Text:
extensions:
- .txt
- .fr
- .nb
- .ncl
- .no
filenames:
- COPYING
- INSTALL
- LICENSE
- NEWS
- README.me
- click.me
- delete.me
- keep.me
- read.me
- test.me
tm_scope: none
ace_mode: text
@@ -3395,6 +3647,7 @@ TypeScript:
- ts
extensions:
- .ts
- .tsx
tm_scope: source.ts
ace_mode: typescript
@@ -3410,7 +3663,6 @@ Unified Parallel C:
Unity3D Asset:
type: data
ace_mode: yaml
color: "#ab69a1"
extensions:
- .anim
- .asset
@@ -3420,6 +3672,13 @@ Unity3D Asset:
- .unity
tm_scope: source.yaml
Uno:
type: programming
extensions:
- .uno
ace_mode: csharp
tm_scope: source.cs
UnrealScript:
type: programming
color: "#a54c4d"
@@ -3428,6 +3687,17 @@ UnrealScript:
tm_scope: source.java
ace_mode: java
UrWeb:
type: programming
aliases:
- Ur/Web
- Ur
extensions:
- .ur
- .urs
tm_scope: source.ur
ace_mode: text
VCL:
group: Perl
type: programming
@@ -3510,6 +3780,14 @@ Volt:
tm_scope: source.d
ace_mode: d
Vue:
type: markup
color: "#2c3e50"
extensions:
- .vue
tm_scope: text.html.vue
ace_mode: html
Web Ontology Language:
type: markup
color: "#9cc9dd"
@@ -3525,6 +3803,16 @@ WebIDL:
tm_scope: source.webidl
ace_mode: text
X10:
type: programming
aliases:
- xten
ace_mode: text
extensions:
- .x10
color: "#4B6BEF"
tm_scope: source.x10
XC:
type: programming
color: "#99DA07"
@@ -3547,6 +3835,7 @@ XML:
- .ccxml
- .clixml
- .cproject
- .csl
- .csproj
- .ct
- .dita
@@ -3562,6 +3851,7 @@ XML:
- .iml
- .ivy
- .jelly
- .jsproj
- .kml
- .launch
- .mdpolicy
@@ -3574,6 +3864,7 @@ XML:
- .osm
- .plist
- .pluginspec
- .props
- .ps1xml
- .psc1
- .pt
@@ -3592,8 +3883,10 @@ XML:
- .tmSnippet
- .tmTheme
- .ts
- .tsx
- .ui
- .urdf
- .ux
- .vbproj
- .vcxproj
- .vxml
@@ -3610,6 +3903,7 @@ XML:
- .xliff
- .xmi
- .xml.dist
- .xproj
- .xsd
- .xul
- .zcml
@@ -3622,6 +3916,14 @@ XML:
- Web.config
- packages.config
XPages:
type: programming
extensions:
- .xsp-config
- .xsp.metadata
tm_scope: none
ace_mode: xml
XProc:
type: programming
extensions:
@@ -3658,6 +3960,7 @@ XSLT:
- .xsl
tm_scope: text.xml.xsl
ace_mode: xml
color: "#EB8CEB"
Xojo:
type: programming
@@ -3686,9 +3989,19 @@ YAML:
- .yml
- .reek
- .rviz
- .sublime-syntax
- .syntax
- .yaml
- .yaml-tmlanguage
ace_mode: yaml
YANG:
type: data
extensions:
- .yang
tm_scope: source.yang
ace_mode: text
Yacc:
type: programming
extensions:
@@ -3697,6 +4010,7 @@ Yacc:
- .yy
tm_scope: source.bison
ace_mode: text
color: "#4B6C4B"
Zephir:
type: programming
@@ -3736,7 +4050,6 @@ eC:
edn:
type: data
ace_mode: clojure
color: "#db5855"
extensions:
- .edn
tm_scope: source.clojure
@@ -3778,7 +4091,10 @@ reStructuredText:
extensions:
- .rst
- .rest
- .rest.txt
- .rst.txt
ace_mode: text
color: "#B3BCBC"
wisp:
type: programming
@@ -3791,8 +4107,13 @@ wisp:
xBase:
type: programming
color: "#403a40"
aliases:
- advpl
- clipper
- foxpro
extensions:
- .prg
- .ch
- .prw
tm_scope: source.harbour
ace_mode: text

View File

@@ -4,7 +4,11 @@ require 'rugged'
module Linguist
class LazyBlob
GIT_ATTR = ['linguist-documentation', 'linguist-language', 'linguist-vendored']
GIT_ATTR = ['linguist-documentation',
'linguist-language',
'linguist-vendored',
'linguist-generated']
GIT_ATTR_OPTS = { :priority => [:index], :skip_system => true }
GIT_ATTR_FLAGS = Rugged::Repository::Attributes.parse_opts(GIT_ATTR_OPTS)
@@ -31,14 +35,6 @@ module Linguist
name, GIT_ATTR, GIT_ATTR_FLAGS)
end
def vendored?
if attr = git_attributes['linguist-vendored']
return boolean_attribute(attr)
else
return super
end
end
def documentation?
if attr = git_attributes['linguist-documentation']
boolean_attribute(attr)
@@ -47,6 +43,22 @@ module Linguist
end
end
def generated?
if attr = git_attributes['linguist-generated']
boolean_attribute(attr)
else
super
end
end
def vendored?
if attr = git_attributes['linguist-vendored']
return boolean_attribute(attr)
else
super
end
end
def language
return @language if defined?(@language)
@@ -67,11 +79,15 @@ module Linguist
@size
end
def cleanup!
@data.clear if @data
end
protected
# Returns true if the attribute is present and not the string "false".
def boolean_attribute(attr)
attr != "false"
def boolean_attribute(attribute)
attribute != "false"
end
def load_blob!

View File

@@ -126,12 +126,13 @@ module Linguist
end
protected
MAX_TREE_SIZE = 100_000
def compute_stats(old_commit_oid, cache = nil)
return {} if current_tree.count_recursive(MAX_TREE_SIZE) >= MAX_TREE_SIZE
old_tree = old_commit_oid && Rugged::Commit.lookup(repository, old_commit_oid).tree
read_index
diff = Rugged::Tree.diff(repository, old_tree, current_tree)
# Clear file map and fetch full diff if any .gitattributes files are changed
@@ -157,8 +158,11 @@ module Linguist
blob = Linguist::LazyBlob.new(repository, delta.new_file[:oid], new, mode.to_s(8))
next unless blob.include_in_language_stats?
file_map[new] = [blob.language.group.name, blob.size]
if blob.include_in_language_stats?
file_map[new] = [blob.language.group.name, blob.size]
end
blob.cleanup!
end
end

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+):/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=ruby'
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=ruby:'
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

View File

@@ -86,17 +86,17 @@ module Linguist
if s.peek(1) == "\""
s.getch
else
s.skip_until(/[^\\]"/)
s.skip_until(/(?<!\\)"/)
end
elsif s.scan(/'/)
if s.peek(1) == "'"
s.getch
else
s.skip_until(/[^\\]'/)
s.skip_until(/(?<!\\)'/)
end
# Skip number literals
elsif s.scan(/(0x)?\d(\d|\.)*/)
elsif s.scan(/(0x\h(\h|\.)*|\d(\d|\.)*)([uU][lL]{0,2}|([eE][-+]\d*)?[fFlL]*)/)
# SGML style brackets
elsif token = s.scan(/<[^\s<>][^<>]*>/)

View File

@@ -20,10 +20,17 @@
- ^deps/
- ^tools/
- (^|/)configure$
- (^|/)configure.ac$
- (^|/)config.guess$
- (^|/)config.sub$
# stuff autogenerated by autoconf - still C deps
- (^|/)aclocal.m4
- (^|/)libtool.m4
- (^|/)ltoptions.m4
- (^|/)ltsugar.m4
- (^|/)ltversion.m4
- (^|/)lt~obsolete.m4
# Linters
- cpplint.py
@@ -78,6 +85,9 @@
# Haxelib projects often contain a neko bytecode file named run.n
- run.n$
# Bootstrap Datepicker
- bootstrap-datepicker/
## Commonly Bundled JavaScript frameworks ##
# jQuery
@@ -88,6 +98,34 @@
- (^|/)jquery\-ui(\-\d\.\d+(\.\d+)?)?(\.\w+)?\.(js|css)$
- (^|/)jquery\.(ui|effects)\.([^.]*)\.(js|css)$
# jQuery Gantt
- jquery.fn.gantt.js
# jQuery fancyBox
- jquery.fancybox.(js|css)
# Fuel UX
- fuelux.js
# jQuery File Upload
- (^|/)jquery\.fileupload(-\w+)?\.js$
# Slick
- (^|/)slick\.\w+.js$
# Leaflet plugins
- (^|/)Leaflet\.Coordinates-\d+\.\d+\.\d+\.src\.js$
- leaflet.draw-src.js
- leaflet.draw.css
- Control.FullScreen.css
- Control.FullScreen.js
- leaflet.spin.js
- wicket-leaflet.js
# Sublime Text workspace files
- .sublime-project
- .sublime-workspace
# Prototype
- (^|/)prototype(.*)\.js$
- (^|/)effects\.js$
@@ -122,7 +160,7 @@
- (^|/)Chart\.js$
# Codemirror
- (^|/)[Cc]ode[Mm]irror/(lib|mode|theme|addon|keymap)
- (^|/)[Cc]ode[Mm]irror/(\d+\.\d+/)?(lib|mode|theme|addon|keymap|demo)
# SyntaxHighlighter - http://alexgorbatchev.com/
- (^|/)shBrush([^.]*)\.js$
@@ -164,6 +202,11 @@
## Obj-C ##
# Xcode
- \.xctemplate/
- \.imageset/
# Carthage
- ^Carthage/
@@ -179,6 +222,10 @@
# Fabric
- Fabric.framework/
# git config files
- gitattributes$
- gitignore$
- gitmodules$
## Groovy ##
@@ -224,21 +271,9 @@
# Html5shiv
- (^|/)html5shiv\.js$
# Samples folders
- ^[Ss]amples/
# LICENSE, README, git config files
- ^COPYING$
- LICENSE$
- License$
- gitattributes$
- gitignore$
- gitmodules$
- ^README$
- ^readme$
# Test fixtures
- ^[Tt]ests?/fixtures/
- ^[Ss]pecs?/fixtures/
# PhoneGap/Cordova
- (^|/)cordova([^.]*)\.js$
@@ -274,3 +309,6 @@
# Android Google APIs
- (^|/)\.google_apis/
# Jenkins Pipeline
- ^Jenkinsfile$

View File

@@ -1,3 +1,3 @@
module Linguist
VERSION = "4.5.9"
VERSION = "4.8.0"
end