Skip to content

Commit

Permalink
Fix #585 FileTypeUtil should identify Rust files
Browse files Browse the repository at this point in the history
  • Loading branch information
bobbylight committed Nov 29, 2024
1 parent de0604f commit 9922490
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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("<?xml") && firstLine.endsWith("?>")) {
Expand Down Expand Up @@ -341,7 +306,7 @@ public String guessContentType(File file, Map<String, List<String>> filters, boo
fileName = stripBackupExtensions(fileName);
}

String style = guessContentTypeImpl(fileName, filters);
String style = guessContentTypeFromFileName(fileName, filters);

return style != null ? style : SyntaxConstants.SYNTAX_STYLE_NONE;
}
Expand All @@ -356,17 +321,18 @@ public String guessContentType(File file, Map<String, List<String>> filters, boo
* @return The syntax style for the file, or {@code null} if nothing could
* be determined.
*/
private static String guessContentTypeImpl(String fileName, Map<String, List<String>> filters) {
private static String guessContentTypeFromFileName(String fileName, Map<String, List<String>> filters) {

String syntaxStyle = null;

// First go by pattern matching (mostly by extension)
// Go by pattern matching (mostly by extension)
for (Map.Entry<String, List<String>> 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;
}
Expand All @@ -378,6 +344,54 @@ private static String guessContentTypeImpl(String fileName, Map<String, List<Str
}


/**
* Looks at a shebang line to try to divine the syntax style.
*
* @param firstLine The shebang line, e.g. {@code #!/bin/sh}.
* @return The syntax style to use.
*/
private static String guessContentTypeFromShebang(String firstLine) {

String style = SyntaxConstants.SYNTAX_STYLE_NONE;

// Take special care for the case of "#!/usr/bin/env programName"
int space = firstLine.indexOf(' ', 2); // Skip the #!
if (space > -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<String, List<String>> map, String syntax, String... filters) {
map.put(syntax, Arrays.asList(filters));
}
Expand Down Expand Up @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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() {

Expand Down Expand Up @@ -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));
}
Expand Down

0 comments on commit 9922490

Please sign in to comment.