diff --git a/src/editorExtension/syntaxHighlight.ts b/src/editorExtension/syntaxHighlight.ts index cc470b4..8b337dd 100644 --- a/src/editorExtension/syntaxHighlight.ts +++ b/src/editorExtension/syntaxHighlight.ts @@ -87,20 +87,27 @@ export class SQLSealViewPlugin implements PluginValue { if (decorations) { decorations.forEach(dec => { if (dec.type === 'filename') { + let hasQuotes = false; // Get the actual filename text from the document - const filePath = view.state.doc.sliceString( + let filePath = view.state.doc.sliceString( contentStart + dec.start, contentStart + dec.end ); + // Remove leading & trailing quotes, if captured. + if (filePath.startsWith('"')) { + filePath = filePath.substring(1, filePath.length - 1) + hasQuotes = true; + } + // Create widget decoration for the filename const widget = new FilePathWidget(filePath, this.app); builder.push(Decoration.replace({ widget, inclusive: true }).range( - contentStart + dec.start, - contentStart + dec.end + contentStart + dec.start + Number(hasQuotes), + contentStart + dec.end - Number(hasQuotes) )); } else { const decoration = markDecorations[dec.type as keyof typeof markDecorations]; diff --git a/src/grammar/parser.test.ts b/src/grammar/parser.test.ts index 3dc0cb1..4917f51 100644 --- a/src/grammar/parser.test.ts +++ b/src/grammar/parser.test.ts @@ -49,6 +49,26 @@ describe('Ohm parser', () => { }) }) + it("should parse table expression with comma in name with name quoted", () => { + expect(parse('TABLE x = file("abcdef, ghijk.csv")', DEFAULT_VIEWS)).toEqual( + { + query: "", + tables: [ + { + arguments: ["abcdef, ghijk.csv"], + type: "file", + tableAlias: "x", + }, + ], + flags: {}, + renderer: { + name: "GRID", + options: "", + }, + }, + ); + }) + it('should parse SELECT statement alone', () => { expect(parse('SELECT * FROM files', DEFAULT_VIEWS)).toEqual({ query: 'SELECT * FROM files', diff --git a/src/grammar/parser.ts b/src/grammar/parser.ts index e6e409e..76640ab 100644 --- a/src/grammar/parser.ts +++ b/src/grammar/parser.ts @@ -38,7 +38,8 @@ export const SQLSealLangDefinition = (views: ViewDefinition[], flags: readonly F | tableOpening NonemptyListOf tableDefinitionClosing -- mdtable TableFileExpressionArgs = filename ("," NonemptyListOf)? identifier = (alnum | "_")+ - filename = (alnum | "." | "-" | space | "_" | "/" | "\\" | "$" | "[" | "]" | "\"")+ + filename = ~("\"") (alnum | "." | "-" | space | "_" | "/" | "\\" | "$" | "[" | "]" | "\"")+ ~("\"") -- unquoted + | "\"" (alnum | "." | "-" | space | "_" | "/" | "\\" | "$" | "[" | "]" | ",")+ "\"" -- quoted fileOpening = caseInsensitive<"file("> tableOpening = caseInsensitive<"table("> tableDefinitionClosing = ")"