mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-12-07 20:08:48 +00:00
Merge pull request #2041 from github/emacs-vim-mode-lines
Emacs vim modelines
This commit is contained in:
@@ -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
|
||||
@@ -94,6 +95,7 @@ module Linguist
|
||||
end
|
||||
|
||||
STRATEGIES = [
|
||||
Linguist::Strategy::Modeline,
|
||||
Linguist::Strategy::Filename,
|
||||
Linguist::Shebang,
|
||||
Linguist::Heuristics,
|
||||
|
||||
30
lib/linguist/strategy/modeline.rb
Normal file
30
lib/linguist/strategy/modeline.rb
Normal file
@@ -0,0 +1,30 @@
|
||||
module Linguist
|
||||
module Strategy
|
||||
class Modeline
|
||||
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
|
||||
#
|
||||
# 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 Vim or Emacs modeline
|
||||
# that matches a Language name or alias. Returns an empty array if no match.
|
||||
def self.call(blob, _ = nil)
|
||||
Array(Language.find_by_alias(modeline(blob.data)))
|
||||
end
|
||||
|
||||
# Public: Get the modeline from the first n-lines of the file
|
||||
#
|
||||
# Returns a String or nil
|
||||
def self.modeline(data)
|
||||
match = data.match(EmacsModeline) || data.match(VimModeline)
|
||||
match[1] if match
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
1
test/fixtures/Data/Modelines/example_smalltalk.md
vendored
Normal file
1
test/fixtures/Data/Modelines/example_smalltalk.md
vendored
Normal file
@@ -0,0 +1 @@
|
||||
; -*-Smalltalk-*-
|
||||
1
test/fixtures/Data/Modelines/iamphp.inc
vendored
Normal file
1
test/fixtures/Data/Modelines/iamphp.inc
vendored
Normal file
@@ -0,0 +1 @@
|
||||
; -*- mode: php;-*-
|
||||
3
test/fixtures/Data/Modelines/not_perl.pl
vendored
Normal file
3
test/fixtures/Data/Modelines/not_perl.pl
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/* vim: set filetype=prolog: */
|
||||
|
||||
# I am Prolog
|
||||
3
test/fixtures/Data/Modelines/ruby
vendored
Normal file
3
test/fixtures/Data/Modelines/ruby
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/* vim: set filetype=ruby: */
|
||||
|
||||
# I am Ruby
|
||||
3
test/fixtures/Data/Modelines/seeplusplus
vendored
Normal file
3
test/fixtures/Data/Modelines/seeplusplus
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/* vim: set ft=cpp: */
|
||||
|
||||
I would like to be C++ please.
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
25
test/test_modelines.rb
Normal file
25
test/test_modelines.rb
Normal file
@@ -0,0 +1,25 @@
|
||||
require_relative "./helper"
|
||||
|
||||
class TestModelines < Minitest::Test
|
||||
include Linguist
|
||||
|
||||
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
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user