private matchState()

in Composer/packages/tools/language-servers/language-generation/src/LGServer.ts [534:597]


  private matchState(
    params: TextDocumentPositionParams,
    curLineState: LGCursorState | undefined
  ): LGCursorState | undefined {
    const state: LGCursorState[] = [];
    const document = this.documents.get(params.textDocument.uri);
    if (!document) return;
    const position = params.position;
    const range = Range.create(position.line, 0, position.line, position.character);
    const lineContent = document.getText(range);

    //initialize the root state to plaintext
    state.push(ROOT);
    if (lineContent.trim().startsWith('#')) {
      return TEMPLATENAME;
    } else if (lineContent.trim().startsWith('>')) {
      return COMMENTS;
    } else if (lineContent.trim().startsWith('-') || curLineState === STRUCTURELG) {
      state.push(TEMPLATEBODY);
    } else {
      return ROOT;
    }

    // find out the context state of current cursor, offer precise suggestion and completion etc.
    /**
     * > To learn more about the LG file format...       --- COMMENTS
     * # Greeting                                        --- TEMPLATENAME
     * - Hello                                           --- TEMPLATEBODY
     * - Hi, @{name}, what's the meaning of 'state'
     *          |
     *          +------------------------------------------- EXPRESSION
     */
    let i = 0;
    while (i < lineContent.length) {
      const char = lineContent.charAt(i);
      if (char === `'`) {
        if (state[state.length - 1] === EXPRESSION || state[state.length - 1] === DOUBLE) {
          state.push(SINGLE);
        } else {
          state.pop();
        }
      }

      if (char === `"`) {
        if (state[state.length - 1] === EXPRESSION || state[state.length - 1] === SINGLE) {
          state.push(DOUBLE);
        } else {
          state.pop();
        }
      }

      if (char === '{' && i >= 1 && state[state.length - 1] !== SINGLE && state[state.length - 1] !== DOUBLE) {
        if (lineContent.charAt(i - 1) === '$') {
          state.push(EXPRESSION);
        }
      }

      if (char === '}' && state[state.length - 1] === EXPRESSION) {
        state.pop();
      }
      i++;
    }
    return state.pop();
  }