diff --git a/package-lock.json b/package-lock.json index 66de52d..56aa424 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@openwebwork/codemirror-lang-pg", - "version": "0.0.1-beta.4", + "version": "0.0.1-beta.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@openwebwork/codemirror-lang-pg", - "version": "0.0.1-beta.4", + "version": "0.0.1-beta.5", "license": "MIT", "dependencies": { "@codemirror/language": "^6.10.2", diff --git a/package.json b/package.json index d0a7691..a68175a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@openwebwork/codemirror-lang-pg", - "version": "0.0.1-beta.4", + "version": "0.0.1-beta.5", "description": "PG language support for CodeMirror", "author": "The WeBWorK Project", "license": "MIT", diff --git a/src/index.ts b/src/index.ts index 6b76cfc..f02c538 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,7 +36,7 @@ export const pgLanguage = LRLanguage.define({ IfStatement: continuedIndent({ except: /^\s*({|else\b|elsif\b)/ }), Block: delimitedIndent({ closing: '}' }), 'StringSingleQuoted StringQQuoted StringDoubleQuoted StringQqQuoted': () => null, - 'StatementEnd InterpolatedHeredocBody UninterpolatedHeredocBody': () => null, + 'StatementEnd InterpolatedHeredocBody UninterpolatedHeredocBody EndDocument': () => null, Statement: continuedIndent(), 'PGMLBlock PGTextBlock LaTeXImageCode': flatIndent }), @@ -59,7 +59,9 @@ export const pgLanguage = LRLanguage.define({ ) return { from: node.firstChild.nextSibling.from, to: node.firstChild.nextSibling.to }; return null; - } + }, + 'EndDocument EndDataStatement': (node) => + node.firstChild ? { from: node.firstChild.to, to: node.to } : null }) ], wrap: parseMixed((node) => diff --git a/src/pg-highlighting.ts b/src/pg-highlighting.ts index ee76895..ad24d32 100644 --- a/src/pg-highlighting.ts +++ b/src/pg-highlighting.ts @@ -8,7 +8,7 @@ export const pgHighlighting = styleTags({ 'NamedUnaryOperator ListOperator Eval each grep': t.function(t.keyword), 'join keys map pop push shift sort splice time times': t.function(t.keyword), 'unpack unshift values wantarray': t.special(t.keyword), - 'DOCUMENT ENDDOCUMENT PGOperator': t.special(t.function(t.operatorKeyword)), + 'ENDDOCUMENT PGOperator': t.special(t.function(t.operatorKeyword)), 'BeginPG EndPG': t.keyword, 'BEGIN CHECK END INIT UNITCHECK': t.processingInstruction, '__FILE__ __LINE__ __PACKAGE__ __SUB__': t.literal, @@ -46,7 +46,7 @@ export const pgHighlighting = styleTags({ 'qw QWListContent/... Pair/Identifier HashAccessVariable/Identifier Version': t.string, 'HeredocInitializer/... HeredocEndIdentifier Glob LaTeXImageCodeStart': t.string, 'm qr s tr y RegexOptions': t.special(t.string), - 'PodStatement EndDataStatement/...': t.blockComment, + 'PodStatement EndDataStatement/... EndDocument': t.blockComment, EscapeSequence: t.escape, 'Comma FatComma': t.punctuation, '( )': t.paren, diff --git a/src/pg-parser.ts b/src/pg-parser.ts index 2e73831..367f8a6 100644 --- a/src/pg-parser.ts +++ b/src/pg-parser.ts @@ -56,7 +56,13 @@ export const pgCompletion = (isTop = false) => { if ( isTop && - !inside(['InterpolatedHeredocBody', 'UninterpolatedHeredocBody']) && + !inside([ + 'InterpolatedHeredocBody', + 'UninterpolatedHeredocBody', + 'PodStatement', + 'EndDataStatement', + 'EndDocument' + ]) && ((context.matchBefore(/^\s*\w*/) && context.explicit) || context.matchBefore(/^\s*B\w*/)) ) { completionOptions.push( diff --git a/src/pg.grammar b/src/pg.grammar index f154294..ecf92d8 100644 --- a/src/pg.grammar +++ b/src/pg.grammar @@ -94,6 +94,7 @@ statement[@isGroup=Statement] { EmptyStatement { ~block ";" } | PodStatement | EndDataStatement[@dynamicPrecedence=4] { (kw<"__END__"> | kw<"__DATA__">) endDataBlock } | + EndDocument[@dynamicPrecedence=4] { kw<"ENDDOCUMENT"> endDataBlock } | LaTeXImageCode { (ScalarVariable | PGVariable | expression) ArrowOperator diff --git a/src/pg.grammar.terms.d.ts b/src/pg.grammar.terms.d.ts index f8f55f0..0afb35c 100644 --- a/src/pg.grammar.terms.d.ts +++ b/src/pg.grammar.terms.d.ts @@ -5,6 +5,7 @@ export declare const automaticSemicolon: number, NamedUnaryOperator: number, ListOperator: number, PGOperator: number, + ENDDOCUMENT: number, HeredocStartIdentifier: number, LaTeXImageCodeStart: number, uninterpolatedHeredocStart: number, diff --git a/src/tokens.ts b/src/tokens.ts index 05ed926..57f9450 100644 --- a/src/tokens.ts +++ b/src/tokens.ts @@ -10,6 +10,7 @@ import { NamedUnaryOperator, ListOperator, PGOperator, + ENDDOCUMENT, HeredocStartIdentifier, LaTeXImageCodeStart, uninterpolatedHeredocStart, @@ -421,7 +422,8 @@ const peekLCWord = (input: InputStream): [string, number] => { export const builtinOperator = new ExternalTokenizer((input, stack) => { if (stack.canShift(PGOperator)) { const [word, nextChar] = peekWord(input); - if (pgOperators.has(word) && !isIdentifierChar(nextChar)) input.acceptToken(PGOperator, word.length); + if (word.startsWith('ENDDOCUMENT')) input.acceptToken(ENDDOCUMENT, 11); + else if (pgOperators.has(word) && !isIdentifierChar(nextChar)) input.acceptToken(PGOperator, word.length); } if (stack.canShift(NamedUnaryOperator)) {