diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java index b94354a4..f40aeda4 100644 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/FileTypeUtil.java @@ -194,42 +194,7 @@ public String guessContentType(RSyntaxTextArea textArea) { } if (firstLine.startsWith("#!")) { - - // Determine the program name. Take special care for - // the case of "#!/usr/bin/env programName". - int space = firstLine.indexOf(' ', 2); - if (space > -1) { - if (firstLine.startsWith("#!/usr/bin/env")) { - int space2 = firstLine.indexOf(' ', space + 1); - if (space2 == -1) { // Never happens in "correct" #!'s - space2 = firstLine.length(); - } - firstLine = firstLine.substring(space + 1, space2); - } - else { - firstLine = firstLine.substring(2, space); - } - } - - if (firstLine.endsWith("sh")) { // ksh, bash, sh, ... - style = SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL; - } - else if (firstLine.endsWith("perl")) { - style = SyntaxConstants.SYNTAX_STYLE_PERL; - } - else if (firstLine.endsWith("php")) { - style = SyntaxConstants.SYNTAX_STYLE_PHP; - } - else if (firstLine.endsWith("python")) { - style = SyntaxConstants.SYNTAX_STYLE_PYTHON; - } - else if (firstLine.endsWith("lua")) { - style = SyntaxConstants.SYNTAX_STYLE_LUA; - } - else if (firstLine.endsWith("ruby")) { - style = SyntaxConstants.SYNTAX_STYLE_RUBY; - } - + style = guessContentTypeFromShebang(firstLine); } else if (firstLine.startsWith("")) { @@ -341,7 +306,7 @@ public String guessContentType(File file, Map> filters, boo fileName = stripBackupExtensions(fileName); } - String style = guessContentTypeImpl(fileName, filters); + String style = guessContentTypeFromFileName(fileName, filters); return style != null ? style : SyntaxConstants.SYNTAX_STYLE_NONE; } @@ -356,17 +321,18 @@ public String guessContentType(File file, Map> filters, boo * @return The syntax style for the file, or {@code null} if nothing could * be determined. */ - private static String guessContentTypeImpl(String fileName, Map> filters) { + private static String guessContentTypeFromFileName(String fileName, Map> filters) { String syntaxStyle = null; - // First go by pattern matching (mostly by extension) + // Go by pattern matching (mostly by extension) for (Map.Entry> entry : filters.entrySet()) { for (String filter : entry.getValue()) { Pattern p = fileFilterToPattern(filter); if (p.matcher(fileName).matches()) { syntaxStyle = entry.getKey(); - // Stop immediately if we find a non-wildcard match + // Stop immediately if we find a non-wildcard match, + // as it'll be exact, e.g. "makefile" if (!filter.contains("*") && !filter.contains("?")) { break; } @@ -378,6 +344,54 @@ private static String guessContentTypeImpl(String fileName, Map -1) { + if (firstLine.startsWith("#!/usr/bin/env")) { + int space2 = firstLine.indexOf(' ', space + 1); + if (space2 == -1) { // No args, just program name + space2 = firstLine.length(); + } + firstLine = firstLine.substring(space + 1, space2); + } + else { + firstLine = firstLine.substring(2, space); + } + } + + if (firstLine.endsWith("sh")) { // ksh, bash, sh, ... + style = SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL; + } + else if (firstLine.endsWith("perl")) { + style = SyntaxConstants.SYNTAX_STYLE_PERL; + } + else if (firstLine.endsWith("php")) { + style = SyntaxConstants.SYNTAX_STYLE_PHP; + } + else if (firstLine.endsWith("python")) { + style = SyntaxConstants.SYNTAX_STYLE_PYTHON; + } + else if (firstLine.endsWith("lua")) { + style = SyntaxConstants.SYNTAX_STYLE_LUA; + } + else if (firstLine.endsWith("ruby")) { + style = SyntaxConstants.SYNTAX_STYLE_RUBY; + } + + return style; + } + + private static void initFiltersImpl(Map> map, String syntax, String... filters) { map.put(syntax, Arrays.asList(filters)); } @@ -430,6 +444,7 @@ private void initializeFilters() { initFiltersImpl(map, SYNTAX_STYLE_PROTO, "*.proto"); initFiltersImpl(map, SYNTAX_STYLE_PYTHON, "*.py"); initFiltersImpl(map, SYNTAX_STYLE_RUBY, "*.rb", "Vagrantfile"); + initFiltersImpl(map, SYNTAX_STYLE_RUST, "*.rs"); initFiltersImpl(map, SYNTAX_STYLE_SAS, "*.sas"); initFiltersImpl(map, SYNTAX_STYLE_SCALA, "*.scala"); initFiltersImpl(map, SYNTAX_STYLE_SQL, "*.sql"); diff --git a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/FileTypeUtilTest.java b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/FileTypeUtilTest.java index df565de4..c7f0808c 100644 --- a/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/FileTypeUtilTest.java +++ b/RSyntaxTextArea/src/test/java/org/fife/ui/rsyntaxtextarea/FileTypeUtilTest.java @@ -89,6 +89,9 @@ void testGuessContentType_textAreaArg_perl() { String[] texts = { "#!/usr/bin/env perl\nprint(\"Hello world!\n\");", + "#!/usr/bin/env perl -w\nprint(\"Hello world!\n\");", + "#!/usr/bin/perl\nprint(\"Hello world!\n\");", + "#!/usr/bin/perl -w\nprint(\"Hello world!\n\");", }; for (String text : texts) { @@ -105,6 +108,7 @@ void testGuessContentType_textAreaArg_php() { String[] texts = { "#!/usr/bin/env php\nprint(\"Hello world!\n\");", + "#!/usr/bin/php\nprint(\"Hello world!\n\");", }; for (String text : texts) { @@ -121,6 +125,7 @@ void testGuessContentType_textAreaArg_python() { String[] texts = { "#!/usr/bin/env python\nprint(\"Hello world!\");", + "#!/usr/bin/python\nprint(\"Hello world!\");", }; for (String text : texts) { @@ -137,6 +142,7 @@ void testGuessContentType_textAreaArg_lua() { String[] texts = { "#!/usr/bin/env lua\nprint(\"Hello world!\");", + "#!/usr/bin/lua\nprint(\"Hello world!\");", }; for (String text : texts) { @@ -153,6 +159,7 @@ void testGuessContentType_textAreaArg_ruby() { String[] texts = { "#!/usr/bin/env ruby\nprint(\"Hello world!\n\");", + "#!/usr/bin/ruby\nprint(\"Hello world!\n\");", }; for (String text : texts) { @@ -162,6 +169,23 @@ void testGuessContentType_textAreaArg_ruby() { } + @Test + void testGuessContentType_textAreaArg_unknownProgramInShebang() { + + FileTypeUtil util = FileTypeUtil.get(); + + String[] texts = { + "#!/usr/bin/env xxx\nprint(\"Hello world!\n\");", + "#!/usr/bin/xxx\nprint(\"Hello world!\n\");", + }; + + for (String text : texts) { + RSyntaxTextArea textArea = plainTextArea(text); + Assertions.assertEquals(SyntaxConstants.SYNTAX_STYLE_NONE, util.guessContentType(textArea)); + } + } + + @Test void testGuessContentType_textAreaArg_html() { @@ -205,9 +229,15 @@ void testGuessContentType_fileArg_knownTypes() { FileTypeUtil util = FileTypeUtil.get(); - File file = new File("test.java"); + File file = new File("makefile"); + Assertions.assertEquals(SyntaxConstants.SYNTAX_STYLE_MAKEFILE, util.guessContentType(file)); + + file = new File("test.java"); Assertions.assertEquals(SyntaxConstants.SYNTAX_STYLE_JAVA, util.guessContentType(file)); + file = new File("test.rs"); + Assertions.assertEquals(SyntaxConstants.SYNTAX_STYLE_RUST, util.guessContentType(file)); + file = new File("test.xml"); Assertions.assertEquals(SyntaxConstants.SYNTAX_STYLE_XML, util.guessContentType(file)); }