From 068c8a341d40b6b8c18e5f8cf7ee1fa08fc0c165 Mon Sep 17 00:00:00 2001 From: Michael Tesch Date: Sat, 14 Mar 2015 18:35:57 +0100 Subject: [PATCH 01/12] better regex for matching emacs modeline the emacs modeline is actually a per-file variable setting mechanism, which means it can have other flags in it. this regex extracts the part that corresponds to the file's language ("mode:" - ie emacs major mode) http://ergoemacs.org/emacs_manual/emacs/Specifying-File-Variables.html --- lib/linguist/strategy/modeline.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index e77597f4..ded1102c 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -1,7 +1,7 @@ module Linguist module Strategy class Modeline - EmacsModeline = /-\*-\s*mode:\s*(\w+);?\s*-\*-/i + EmacsModeline = /-\*-\s*((?!mode)[\w-]+\s*:\s*([\w+-]+)\s*;?\s*)?(mode\s*:)?\s*([\w+-]+)\s*;?\s*((?!mode)[\w-]+\s*:\s*([\w+-]+)\s*;?\s*)?-\*-/i VimModeline = /\/\*\s*vim:\s*set\s*(?:ft|filetype)=(\w+):\s*\*\//i # Public: Detects language based on Vim and Emacs modelines @@ -22,8 +22,13 @@ module Linguist # # Returns a String or nil def self.modeline(data) - match = data.match(EmacsModeline) || data.match(VimModeline) - match[1] if match + match = data.match(EmacsModeline) + if match + match[4] + else + match = data.match(VimModeline) + match[1] if match + end end end end From 1bb639617c017d389708daf4c28231ff97c5c233 Mon Sep 17 00:00:00 2001 From: Michael Tesch Date: Sat, 14 Mar 2015 22:44:02 +0100 Subject: [PATCH 02/12] Create seeplusplusEmacs1 one type of emacs modeline --- test/fixtures/Data/Modelines/seeplusplusEmacs1 | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs1 diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs1 b/test/fixtures/Data/Modelines/seeplusplusEmacs1 new file mode 100644 index 00000000..6c1b6e80 --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs1 @@ -0,0 +1,2 @@ +// -*-c++-*- +template class { X i; }; From a364e4a2dcf71eb5f5d972a9b2c57d67f5c63da0 Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sat, 14 Mar 2015 23:13:59 +0100 Subject: [PATCH 03/12] tests for emacs modeline regex --- test/fixtures/Data/Modelines/seeplusplusEmacs2 | 2 ++ test/fixtures/Data/Modelines/seeplusplusEmacs3 | 2 ++ test/fixtures/Data/Modelines/seeplusplusEmacs4 | 2 ++ test/fixtures/Data/Modelines/seeplusplusEmacs5 | 2 ++ test/fixtures/Data/Modelines/seeplusplusEmacs6 | 2 ++ test/fixtures/Data/Modelines/seeplusplusEmacs7 | 2 ++ test/fixtures/Data/Modelines/seeplusplusEmacs8 | 2 ++ test/fixtures/Data/Modelines/seeplusplusEmacs9 | 2 ++ test/test_modelines.rb | 18 ++++++++++++++++++ 9 files changed, 34 insertions(+) create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs2 create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs3 create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs4 create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs5 create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs6 create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs7 create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs8 create mode 100644 test/fixtures/Data/Modelines/seeplusplusEmacs9 diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs2 b/test/fixtures/Data/Modelines/seeplusplusEmacs2 new file mode 100644 index 00000000..3756149c --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs2 @@ -0,0 +1,2 @@ +// -*- c++ -*- +template class { X i; }; diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs3 b/test/fixtures/Data/Modelines/seeplusplusEmacs3 new file mode 100644 index 00000000..7a871e6a --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs3 @@ -0,0 +1,2 @@ +// -*- mode:C++ -*- +template class { X i; }; diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs4 b/test/fixtures/Data/Modelines/seeplusplusEmacs4 new file mode 100644 index 00000000..f020eb5a --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs4 @@ -0,0 +1,2 @@ +// -*- font:bar;mode:c++ -*- +template class { X i; }; diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs5 b/test/fixtures/Data/Modelines/seeplusplusEmacs5 new file mode 100644 index 00000000..49e9a7d6 --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs5 @@ -0,0 +1,2 @@ +// -*-foo:bar;mode:c++;bar:foo-*- +template class { X i; }; diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs6 b/test/fixtures/Data/Modelines/seeplusplusEmacs6 new file mode 100644 index 00000000..305f7f77 --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs6 @@ -0,0 +1,2 @@ +// -*- foo : bar ; mode : c++ ; bar : foo -*- +template class { X i; }; diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs7 b/test/fixtures/Data/Modelines/seeplusplusEmacs7 new file mode 100644 index 00000000..236c3b8e --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs7 @@ -0,0 +1,2 @@ +// -*- mode : c++ ; bar : foo -*- +template class { X i; }; diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs8 b/test/fixtures/Data/Modelines/seeplusplusEmacs8 new file mode 100644 index 00000000..3efc2c57 --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs8 @@ -0,0 +1,2 @@ +// -*- font:x;foo : bar ; mode : C++ ; bar : foo -*- +template class { X i; }; diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs9 b/test/fixtures/Data/Modelines/seeplusplusEmacs9 new file mode 100644 index 00000000..953ca220 --- /dev/null +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs9 @@ -0,0 +1,2 @@ +// -*-foo:bar;mode:c++;bar:foo;tyrell:corp-*- +template class { X i; }; diff --git a/test/test_modelines.rb b/test/test_modelines.rb index 6c68cc87..cd8fbaad 100644 --- a/test/test_modelines.rb +++ b/test/test_modelines.rb @@ -10,6 +10,15 @@ class TestModelines < Minitest::Test 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["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs1") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs2") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs3") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs4") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs5") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs6") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs7") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs8") + assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs9") 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") @@ -18,6 +27,15 @@ class TestModelines < Minitest::Test 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["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs1").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs2").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs3").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs4").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs5").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs6").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs7").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs8").language + assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs9").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 From 6aab682728c6b00057c16d4672240d8a01cae510 Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sat, 14 Mar 2015 23:24:41 +0100 Subject: [PATCH 04/12] fixed case with multiple other file vars before and after mode: --- 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 ded1102c..58f75b63 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -1,7 +1,7 @@ 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 + EmacsModeline = /-\*-\s*((?!mode)[\w-]+\s*:\s*([\w+-]+)\s*;?\s*)*(mode\s*:)?\s*([\w+-]+)\s*(;\s*(?!mode)[\w-]+\s*:\s*([\w+-]+)\s*)*;?\s*-\*-/i VimModeline = /\/\*\s*vim:\s*set\s*(?:ft|filetype)=(\w+):\s*\*\//i # Public: Detects language based on Vim and Emacs modelines From 6af4ab6db125428090efbe317a64af1bafc39ddb Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sat, 14 Mar 2015 23:26:08 +0100 Subject: [PATCH 05/12] harder test --- test/fixtures/Data/Modelines/seeplusplusEmacs8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/fixtures/Data/Modelines/seeplusplusEmacs8 b/test/fixtures/Data/Modelines/seeplusplusEmacs8 index 3efc2c57..f502058a 100644 --- a/test/fixtures/Data/Modelines/seeplusplusEmacs8 +++ b/test/fixtures/Data/Modelines/seeplusplusEmacs8 @@ -1,2 +1,2 @@ -// -*- font:x;foo : bar ; mode : C++ ; bar : foo -*- +// -*- font:x;foo : bar ; mode : C++ ; bar : foo ; foooooo:baaaaar;fo:ba-*- template class { X i; }; From fda0f2a0423e7211ae64fd4d980167a687a5311e Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sat, 14 Mar 2015 23:53:17 +0100 Subject: [PATCH 06/12] detect emacs modeline for fundamental as Text --- lib/linguist/languages.yml | 2 ++ test/fixtures/Data/Modelines/fundamentalEmacs.c | 6 ++++++ test/test_modelines.rb | 2 ++ 3 files changed, 10 insertions(+) create mode 100644 test/fixtures/Data/Modelines/fundamentalEmacs.c diff --git a/lib/linguist/languages.yml b/lib/linguist/languages.yml index ada5149f..2bde4702 100644 --- a/lib/linguist/languages.yml +++ b/lib/linguist/languages.yml @@ -3074,6 +3074,8 @@ Tea: Text: type: prose wrap: true + aliases: + - fundamental extensions: - .txt - .fr diff --git a/test/fixtures/Data/Modelines/fundamentalEmacs.c b/test/fixtures/Data/Modelines/fundamentalEmacs.c new file mode 100644 index 00000000..b384bc79 --- /dev/null +++ b/test/fixtures/Data/Modelines/fundamentalEmacs.c @@ -0,0 +1,6 @@ +// -*- fundamental -*- + +int main(int argc, char * argc[]) +{ + this should not be syntax highlighted, even though it looks like c. +} diff --git a/test/test_modelines.rb b/test/test_modelines.rb index cd8fbaad..a2be5d3b 100644 --- a/test/test_modelines.rb +++ b/test/test_modelines.rb @@ -19,6 +19,7 @@ class TestModelines < Minitest::Test assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs7") assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs8") assert_modeline Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs9") + assert_modeline Language["Text"], fixture_blob("Data/Modelines/fundamentalEmacs.c") 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") @@ -36,6 +37,7 @@ class TestModelines < Minitest::Test assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs7").language assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs8").language assert_equal Language["C++"], fixture_blob("Data/Modelines/seeplusplusEmacs9").language + assert_equal Language["Text"], fixture_blob("Data/Modelines/fundamentalEmacs.c").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 From 5fd7992f9829b55f0473f4f6d1d049fe16645c56 Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sun, 15 Mar 2015 12:40:31 +0100 Subject: [PATCH 07/12] dont save useless matches, thanks to pchaigno --- lib/linguist/strategy/modeline.rb | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/linguist/strategy/modeline.rb b/lib/linguist/strategy/modeline.rb index 58f75b63..f8b58ecf 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -1,7 +1,7 @@ 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 + EmacsModeline = /-\*-\s*(?:(?!mode)[\w-]+\s*:\s*(?:[\w+-]+)\s*;?\s*)*(?:mode\s*:)?\s*([\w+-]+)\s*(?:;\s*(?!mode)[\w-]+\s*:\s*[\w+-]+\s*)*;?\s*-\*-/i VimModeline = /\/\*\s*vim:\s*set\s*(?:ft|filetype)=(\w+):\s*\*\//i # Public: Detects language based on Vim and Emacs modelines @@ -22,13 +22,8 @@ module Linguist # # Returns a String or nil def self.modeline(data) - match = data.match(EmacsModeline) - if match - match[4] - else - match = data.match(VimModeline) - match[1] if match - end + match = data.match(EmacsModeline) | data.match(VimModeline) + match[1] if match end end end From ce1f51a34f060f9bbbb96f1ba1084438bd6e804f Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sun, 15 Mar 2015 12:51:14 +0100 Subject: [PATCH 08/12] forgot a | --- 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 f8b58ecf..55a8f355 100644 --- a/lib/linguist/strategy/modeline.rb +++ b/lib/linguist/strategy/modeline.rb @@ -22,7 +22,7 @@ module Linguist # # Returns a String or nil def self.modeline(data) - match = data.match(EmacsModeline) | data.match(VimModeline) + match = data.match(EmacsModeline) || data.match(VimModeline) match[1] if match end end From 419cfe54e0a7879457c130ffb460957fc9e43ac0 Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sun, 15 Mar 2015 13:05:43 +0100 Subject: [PATCH 09/12] disable modelines strategy match for dtrace sample --- samples/DTrace/javascript-trace.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/DTrace/javascript-trace.d b/samples/DTrace/javascript-trace.d index 258c6cd2..a9c4471e 100644 --- a/samples/DTrace/javascript-trace.d +++ b/samples/DTrace/javascript-trace.d @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: linguist-disable-modelines-strategy-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * From dcb14d0fc7157eac434ca03284f41717edadabd3 Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sun, 15 Mar 2015 20:06:41 +0100 Subject: [PATCH 10/12] disable modelines strategy for webidl sample --- samples/WebIDL/Fetch.webidl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/WebIDL/Fetch.webidl b/samples/WebIDL/Fetch.webidl index fb022126..87a4e957 100644 --- a/samples/WebIDL/Fetch.webidl +++ b/samples/WebIDL/Fetch.webidl @@ -1,4 +1,4 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: linguist-disable-strategy-modeline-IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. From 50db5c012eeab69ac8ef07d05d760de908b5715a Mon Sep 17 00:00:00 2001 From: michael tesch Date: Sun, 15 Mar 2015 20:18:57 +0100 Subject: [PATCH 11/12] disable modelines strategy for webidl sample --- samples/WebIDL/AnimationEvent.webidl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/WebIDL/AnimationEvent.webidl b/samples/WebIDL/AnimationEvent.webidl index e48ed571..5dbc2752 100644 --- a/samples/WebIDL/AnimationEvent.webidl +++ b/samples/WebIDL/AnimationEvent.webidl @@ -1,4 +1,4 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: linguist-disable-strategy-modeline-IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. From 5f647f2236ef87a9dc0bbbeec11269e33f3eb4c3 Mon Sep 17 00:00:00 2001 From: michael tesch Date: Mon, 16 Mar 2015 19:56:06 +0100 Subject: [PATCH 12/12] more realistic emacs modeline for dtrace sample --- samples/DTrace/javascript-trace.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/DTrace/javascript-trace.d b/samples/DTrace/javascript-trace.d index a9c4471e..0acbaa97 100644 --- a/samples/DTrace/javascript-trace.d +++ b/samples/DTrace/javascript-trace.d @@ -1,4 +1,4 @@ -/* -*- Mode: linguist-disable-modelines-strategy-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* -*- Mode: dtrace-script; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 *