Clarification on how textDocument/completion works

Hi, I’ve been trying to get to the bottom of a bug with Yaml Extension where multiline completions don’t indent at the correct level. So with this YAML file, typing that final letter “c”:

some-deployment.yml

      volumes:
        - name: html
          c

and you trigger the completion for configMap, it ends up with this (where (•••) is where the cursor entry point is)

      volumes:
        - name: html
          configMap:
  (•••)

But I expected it to be:

      volumes:
        - name: html
          configMap:
            (•••)

Inspecting the LSP requests, I can see this request going to the LanguageServer:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "textDocument/completion",
  "params": {
    "context": { "triggerCharacter": "c", "triggerKind": 2 },
    "textDocument": {
      "uri": "file:///.../nova/yaml/examples/some-deployment.yml"
    },
    "position": { "line": 32, "character": 11 }
  }
}

which has this concatenated response:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "items": [
      "...",
      {
        "kind": 10,
        "label": "configMap",
        "insertText": "configMap:\n  $1",
        "insertTextFormat": 2,
        "documentation": "ConfigMap represents a configMap that should populate this volume",
        "textEdit": {
          "range": {
            "start": { "line": 30, "character": 10 },
            "end": { "line": 30, "character": 11 }
          },
          "newText": "configMap:\n  $1"
        }
      },
      "..."
    ],
    "isIncomplete": false
  }
}

My question is, is Nova responsible for doing the indentation based on insertText or newText from the LanguageServer’s response, or is it the LanguageServer’s job to put the right amount of indentation into insertText / newText first?

Maybe related, I’ve also been having issues getting the extension/workspace config to the LanguageServer because it currently doesn’t pull it in, I’ve had to manually send a workspace/didChangeConfiguration. Which could be related to the LanguageServer not putting the correct indentation in.

Thanks for any help or advice,
Rob

Take a look at InsertTextMode in the LSP spec. It looks like there’s a relatively new (v3.16/v3.17 of the LSP) feature that directly answers this exact question. Since Nova’s based on v3.15 of the spec, it probably doesn’t support any of this. The protocol isn’t explicit about what the behavior was previously, but personally I’d expect this to be the responsibility of the server, not the client.

Unfortunately, I didn’t find any examples of auto-inserted text with newlines in my LSP extensions so I don’t know what Nova does for them.

1 Like

Thanks for taking time to reply and for the pointers, I will dive further into the LanguageServer! Also I borrowed your tee logic to inspect the LSP messages, so thanks for that too!

It looks like the vscode implementation does insert spaces in there so maybe I need to fudge the configuration a bit to get it to work.