CreatBotMainsail/src/plugins/StreamParserKlipperConfig.ts
2022-07-18 00:48:34 +02:00

187 lines
6.0 KiB
TypeScript

import { StreamParser, StringStream } from '@codemirror/language'
import { gcode } from '@/plugins/StreamParserGcode'
export const klipper_config: StreamParser<any> = {
token: function (stream: StringStream, state: StreamParserKlipperConfigState): string | null {
const ch = stream.peek()
/* comments */
if (
stream.match(/^\s+[#;]/) ||
([';', '#'].includes(ch ?? '') && (stream.pos === 0 || /\s/.test(stream.string.charAt(stream.pos - 1))))
) {
stream.skipToEnd()
state.block = false
state.pair = false
return 'comment'
}
if (ch !== '[' && stream.indentation() === 0 && stream.sol() && stream.match(/^[^:]+$/i)) {
stream.skipToEnd()
return null
}
if (stream.indentation() === 0) {
if (stream.pos === 0 && ch === '[') {
state.block = true
stream.next()
return null
}
if (state.block) {
if (!ch || ch === ']' || stream.eol()) {
stream.next()
state.block = false
return null
}
if (stream.match(/^\s[^\]]+/)) {
return 'className'
}
if (stream.match(/^[^ \]]+/)) {
return 'namespace'
}
}
if (state.gcode) {
if (stream.sol() || stream.eol()) {
state.gcode = false
state.gcodeZeroPos = null
return null
}
if (!state.gcodeZeroPos) {
stream.eatSpace()
state.gcodeZeroPos = stream.pos
}
if (state.klipperMacroJinja) {
if (
(state.klipperMacroJinjaPercent && stream.match(/^%}/)) ||
(!state.klipperMacroJinjaPercent && stream.match(/^}/))
) {
state.klipperMacroJinja = false
state.klipperMacroJinjaPercent = false
stream.eatSpace()
state.gcodeZeroPos = stream.pos
return null
}
stream.next()
return 'string'
}
if (stream.match(/^\s*{[%{]?/)) {
state.klipperMacroJinjaPercent = stream.string.includes('{%')
state.klipperMacroJinja = true
return null
}
return gcode.token(stream, state, state.gcodeZeroPos ?? 0)
}
} else {
state.was = true
if (state.gcode) {
if (stream.sol()) {
stream.eatSpace()
state.gcodeZeroPos = stream.pos
}
if (state.klipperMacroJinja) {
if (
(state.klipperMacroJinjaPercent && stream.match(/^%}/)) ||
(!state.klipperMacroJinjaPercent && stream.match(/^}/))
) {
state.klipperMacroJinja = false
state.klipperMacroJinjaPercent = false
stream.eatSpace()
state.gcodeZeroPos = stream.pos
return null
}
stream.next()
return 'string'
}
if (stream.match(/^\s*{[%{]?/)) {
state.klipperMacroJinjaPercent = stream.string.includes('{%')
state.klipperMacroJinja = true
return null
}
return gcode.token(stream, state, state.gcodeZeroPos ?? stream.pos)
} else if (state.pair) {
stream.eatSpace()
if (ch !== ',') {
if (stream.match(/^-?\d*\.?(?:\d+)?($|,)/)) {
return 'number'
}
if (stream.match(/^[^#]+/)) {
return 'string'
}
}
stream.next()
return null
}
}
if (state.was && stream.indentation() === 0) {
state.pair = false
state.gcode = false
state.was = false
}
if (!state.pair && !state.gcode && stream.sol()) {
if (stream.match(/^(?:[A-Za-z]*_?gcode|enable):/)) {
state.gcode = true
} else {
stream.match(/^.+?:\s*/)
state.pair = !stream.eol()
}
return 'atom'
}
if (state.pair) {
if (ch === ':') {
stream.next()
stream.eatSpace()
return null
}
if (!ch || stream.eol()) {
state.pair = false
return null
}
if (stream.match(/^(-?\d*\.?(?:\d+)?(,|$|\s))+/)) {
state.pair = false
return 'number'
}
if (stream.match(/^[^#]+/)) {
state.pair = false
return 'string'
}
}
stream.next()
return null
},
startState: function (): StreamParserKlipperConfigState {
return {
block: false,
pair: false,
was: false,
gcode: false,
klipperMacro: false,
gcodeZeroPos: null,
klipperMacroJinja: false,
klipperMacroJinjaPercent: false,
}
},
languageData: {
commentTokens: { line: '#' },
},
}
interface StreamParserKlipperConfigState {
block: boolean
pair: boolean
was: boolean
gcode: boolean
gcodeZeroPos: number | null
klipperMacro: boolean
klipperMacroJinja: boolean
klipperMacroJinjaPercent: boolean
}