lsp-bridge -- 速度最快的语法补全插件

今天刚开始尝试 lsp-bridge,有个问题不太理解:为什么 lsp-bridge 一定依赖 yasnippet 呀?是因为 LSP 后端返回的可能是类似于 snippet 的东西,需要借助 yasnippet 来进行多个 placehold 之间的跳转吗?

另外是一个自己使用上的问题(不知道是不是我没看到什么快捷键)。我在配置好 lsp-bridge 后,就被 acm 的美观界面和极快的速度震惊到了!但是我打开 Go 文件,启动 lsp-bridge-mode 后

image

这个时候按下 TAB 会变成

image

这个样子,请问这是 Bug 还是我的问题?

yasnippet 和 lsp-bridge 的配置我都没动过(除了指定了一下 python 路径)。

因为目前来看, LSP服务器返回的 snippet 只有 yasnippet 才能比较好的展开, 其他的库都没法做到。

我测试了一下 Tab, 可以正常工作, 应该是你的 yasnippet 没有配置好。

lsp-bridge 的速度已经达到了 VSCode 的水平。

我去,感谢大佬回复,速度太快了 :joy:

的确,不好意思,我忘记开 yas-global-mode 了,十分感谢!

1 个赞

今天更新了 Range Formatting 协议的解析代码, 我发现不同的 LSP Server 返回同一个协议的内容是不一样的。

pyright/ruff 返回的 Range Formatting 能力, 要通过解析 documentRangeFormattingProvider/rangesSupport 这个字段才能判定, 而 clangd 只用判定 documentRangeFormattingProvider 这个字段就好了。

需要局部格式化功能的朋友, 需要更新到最新版。 (最新版合并和社区大牛的补丁, 又增强了远程编辑的很多功能)。

3 个赞

clangd作为server可以正常使用了 :+1:

1 个赞

大佬们,这个有碰到的吗,求个调试的办法

写 vue 时 lsp-bridge 没有提示和语法检查,还总是重启

看README底部, 打开调试选项, 提供详细日志。

打开 vue 文件:

Eval in Emacs: (lsp-bridge--first-start '56939)
Eval in Emacs: (message '"[LSP-Bridge] found language server: /Users/mzy/.nvm/versions/node/v18.19.0/bin/vue-language-server")
Eval in Emacs: (message '"[LSP-Bridge] found language server: /Users/mzy/.nvm/versions/node/v18.19.0/bin/vue-language-server")
Start lsp server (volar) for /Users/mzy/work/traffic
Eval in Emacs: (message '"[LSP-Bridge] Active project 'traffic', enjoy hacking!")
Handlers: [<class 'core.handler.completion.Completion'>,
 <class 'core.handler.completion_item.CompletionItem'>,
 <class 'core.handler.find_define.FindDefine'>,
 <class 'core.handler.find_type_define.FindTypeDefine'>,
 <class 'core.handler.find_implementation.FindImplementation'>,
 <class 'core.handler.find_references.FindReferences'>,
 <class 'core.handler.peek.PeekFindDefine'>,
 <class 'core.handler.peek.PeekFindReferences'>,
 <class 'core.handler.hover.Hover'>,
 <class 'core.handler.signature_help.SignatureHelp'>,
 <class 'core.handler.prepare_rename.PrepareRename'>,
 <class 'core.handler.rename.Rename'>,
 <class 'core.handler.jdt_uri_resolver.JDTUriResolver'>,
 <class 'core.handler.deno_uri_resolver.DenoUriResolver'>,
 <class 'core.handler.code_action.CodeAction'>,
 <class 'core.handler.formatting.Formatting'>,
 <class 'core.handler.range_formatting.RangeFormatting'>,
 <class 'core.handler.execute_command.ExecuteCommand'>,
 <class 'core.handler.workspace_symbol.WorkspaceSymbol'>,
 <class 'core.handler.call_hierarchy.PrepareCallHierarchy'>,
 <class 'core.handler.call_hierarchy.CallHierarchy'>,
 <class 'core.handler.call_hierarchy.PrepareCallHierarchyIncomingCalls'>,
 <class 'core.handler.call_hierarchy.PrepareCallHierarchyOutgoingCalls'>,
 <class 'core.handler.call_hierarchy.CallHierarchyIncomingCalls'>,
 <class 'core.handler.call_hierarchy.CallHierarchyOutgoingCalls'>,
 <class 'core.handler.document_symbol.DocumentSymbol'>,
 <class 'core.handler.jdtls.jdtls_list_overridable_methods.JdtlsListOverridableMethods'>,
 <class 'core.handler.jdtls.jdtls_add_overridable_methods.JdtlsAddOverridableMethods'>,
 <class 'core.handler.inlay_hint.InlayHint'>,
 <class 'core.handler.semantic_tokens.SemanticTokens'>]

--- [11:38:50.955761] Send initialize request (15741) to 'volar' for project traffic
{
   "id": 15741,
   "method": "initialize",
   "params": {
      "processId": 65540,
      "rootPath": "/Users/mzy/work/traffic",
      "clientInfo": {
         "name": "emacs",
         "version": "lsp-bridge"
      },
      "rootUri": "file:///Users/mzy/work/traffic",
      "capabilities": {
         "workspace": {
            "configuration": true,
            "symbol": {
               "resolveSupport": {
                  "properties": []
               }
            }
         },
         "textDocument": {
            "completion": {
               "completionItem": {
                  "snippetSupport": true,
                  "deprecatedSupport": true,
                  "tagSupport": {
                     "valueSet": [
                        1
                     ]
                  },
                  "resolveSupport": {
                     "properties": [
                        "documentation",
                        "detail",
                        "additionalTextEdits"
                     ]
                  }
               }
            },
            "codeAction": {
               "dynamicRegistration": false,
               "codeActionLiteralSupport": {
                  "codeActionKind": {
                     "valueSet": [
                        "quickfix",
                        "refactor",
                        "refactor.extract",
                        "refactor.inline",
                        "refactor.rewrite",
                        "source",
                        "source.organizeImports"
                     ]
                  }
               },
               "isPreferredSupport": true
            },
            "inlayHint": {
               "dynamicRegistration": false
            },
            "publishDiagnostics": {
               "relatedInformation": true,
               "tagSupport": {
                  "valueSet": [
                     1,
                     2
                  ]
               },
               "versionSupport": true,
               "codeDescriptionSupport": true,
               "dataSupport": true
            }
         }
      },
      "initializationOptions": {
         "typescript": {
            "tsdk": "/usr/local/lib/node_modules/typescript/lib"
         },
         "languageFeatures": {
            "references": true,
            "implementation": true,
            "definition": true,
            "typeDefinition": true,
            "callHierarchy": true,
            "hover": true,
            "rename": true,
            "renameFileRefactoring": true,
            "signatureHelp": true,
            "codeAction": true,
            "workspaceSymbol": true,
            "completion": {
               "defaultTagNameCase": "",
               "defaultAttrNameCase": "",
               "getDocumentNameCasesRequest": false,
               "getDocumentSelectionRequest": false
            },
            "schemaRequestService": {
               "getDocumentContentRequest": false
            }
         },
         "documentFeatures": {
            "selectionRange": true,
            "foldingRange": true,
            "linkedEditingRange": true,
            "documentSymbol": true,
            "documentColor": true,
            "documentFormatting": {
               "defaultPrintWidth": 100,
               "getDocumentPrintWidthRequest": false
            }
         }
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}
Eval in Emacs: (lsp-bridge-set-server-names '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '("volar"))

--- [11:38:51.241968] Recv response (15741) from 'volar' for project traffic
{
   "jsonrpc": "2.0",
   "id": 15741,
   "result": {
      "capabilities": {
         "textDocumentSync": 2,
         "workspace": {
            "fileOperations": {
               "willRename": {
                  "filters": [
                     {
                        "pattern": {
                           "glob": "**/*.{js,cjs,mjs,ts,cts,mts,jsx,tsx,json,vue}"
                        }
                     }
                  ]
               }
            }
         },
         "selectionRangeProvider": true,
         "foldingRangeProvider": true,
         "linkedEditingRangeProvider": true,
         "colorProvider": true,
         "documentSymbolProvider": true,
         "documentFormattingProvider": true,
         "documentRangeFormattingProvider": true,
         "referencesProvider": true,
         "implementationProvider": true,
         "definitionProvider": true,
         "typeDefinitionProvider": true,
         "callHierarchyProvider": true,
         "hoverProvider": true,
         "renameProvider": {
            "prepareProvider": true
         },
         "signatureHelpProvider": {
            "triggerCharacters": [],
            "retriggerCharacters": []
         },
         "completionProvider": {
            "triggerCharacters": [
               "*",
               "/",
               "-",
               ":",
               "\"",
               ".",
               "<",
               "=",
               "@",
               ">",
               "+",
               "^",
               "(",
               ")",
               "#",
               "[",
               "]",
               "$",
               "{",
               "}"
            ],
            "resolveProvider": true
         },
         "documentHighlightProvider": true,
         "documentLinkProvider": {
            "resolveProvider": true
         },
         "codeLensProvider": {
            "resolveProvider": true
         },
         "codeActionProvider": {
            "codeActionKinds": [
               "",
               "quickfix",
               "refactor",
               "refactor.extract",
               "refactor.inline",
               "refactor.rewrite",
               "source",
               "source.fixAll",
               "source.organizeImports"
            ],
            "resolveProvider": true
         },
         "inlayHintProvider": {
            "resolveProvider": true
         },
         "workspaceSymbolProvider": true,
         "documentOnTypeFormattingProvider": {
            "firstTriggerCharacter": ";",
            "moreTriggerCharacter": [
               "}",
               "\n"
            ]
         }
      }
   }
}

--- [11:38:51.242242] Send initialized notification to 'volar' for project traffic

--- [11:38:51.299062] Recv workspace/configuration request (0) from 'volar' for project traffic
{
   "method": "initialized",
   "params": {},
   "message_type": "notification",
   "jsonrpc": "2.0"
}
{
   "jsonrpc": "2.0",
   "id": 0,
   "method": "workspace/configuration",
   "params": {
      "items": [
         {
            "section": "http"
         }
      ]
   }
}

--- [11:38:51.299266] Send workspace/didChangeConfiguration notification to 'volar' for project traffic
{
   "method": "workspace/didChangeConfiguration",
   "params": {
      "settings": {}
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:38:51.342167] Send textDocument/didOpen notification to 'volar' for project traffic
{
   "method": "textDocument/didOpen",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "languageId": "vue",
         "version": 0,
         "text": "<template>\n  <div class=\"draw-lanes\">\n    <!-- <el-button @click=\"handleZoomIn\">+</el-button> -->\n    <!-- <el-button @click=\"handleZoomOut\">-</el-button> -->\n    <canvas ref=\"canvasRef\" id=\"canvas\"> Your browser is not suppot canvas </canvas>\n  </div>\n</template>\n\n<script setup lang=\"ts\" name=\"DrawLanes\">\n// props:\n// @data: \u6e20\u5316\u56fe\u6570\u636e\n// @bgColor: canvas \u80cc\u666f\u8272, \u9ed8\u8ba4\u503c\u662f \"#04232e\"\n\nimport { ref, Ref, reactive, onMounted, onBeforeUnmount, onUnmounted } from \"vue\";\nimport { Coor, InLink, Lane } from \"@/utils/interface\";\nimport Cdraw from \"@/utils/cdraw\";\nimport { calculateSquareVertices } from \"@/utils/calc\";\n\nconst props = defineProps([\"data\", \"bgColor\"]);\n// const emits = defineEmits([\"add\", \"minus\"]);\nconst roadColor = \"#194359\";\nconst yellowColor = \"#C6B41C\";\nconst whiteColor = \"#AEC8D6\";\nconst canvasBg = \"#04232e\";\n\nconst canvasRef: Ref<HTMLCanvasElement | null> = ref(null);\nlet ctx: CanvasRenderingContext2D | null = null;\nlet cdraw: Cdraw;\n\nconst center: Coor = {\n  x: 0,\n  y: 0\n};\n\nlet squareWidth = 210;\nlet laneWidth = 30;\nlet zebraStripesWidth = laneWidth * 2;\nlet laneLength = squareWidth * 2 - zebraStripesWidth * 1.2;\nlet vertices: Coor[] = [];\n\nonMounted(() => {\n  initCanvas();\n  window.addEventListener(\"resize\", initCanvas);\n});\n\nonUnmounted(() => window.removeEventListener(\"resize\", initCanvas));\n\nfunction handleZoomIn() {\n  laneWidth += 2;\n  initCanvas();\n}\n\nfunction handleZoomOut() {\n  laneWidth -= 2;\n  initCanvas();\n}\n\nfunction drawCross() {\n  const firstNode = props.data[0];\n  const inLinks: InLink[] = firstNode.inLinks;\n  const towardHash = {\n    \"0\": \"east\",\n    \"1\": \"south\",\n    \"2\": \"west\",\n    \"3\": \"north\"\n  };\n\n  // lanes \u6700\u5927\u6570\n  const maxLanesCount = Math.max(...inLinks.map(item => item.lanes.length));\n  const multiple = Math.floor(maxLanesCount / 2);\n  // \u5916\u6b63\u65b9\u5f62\u9876\u70b9\n  vertices = calculateSquareVertices(center.x, center.y, squareWidth + laneWidth * multiple * 3);\n  const [a, b, c, d] = vertices;\n  cdraw.drawShape(a, b, c, d, roadColor);\n\n  squareWidth = maxLanesCount * laneWidth;\n  inLinks.forEach((item: InLink, index: number) => {\n    const laneCount = item.lanes.length;\n    item.zebraStripesLength = laneCount * laneWidth;\n\n    // 1 2 3 4 - \u897f \u5317 \u4e1c \u5357 - \u5de6 \u4e0a \u53f3 \u4e0b\n    // if (index > 1) return;\n    const { lanes } = item;\n    item.inLinkCount = item.lanes.filter(item => item.toward).length;\n    item.outLinkCount = item.lanes.filter(item => !item.toward).length;\n\n    lanes.forEach((lane: Lane, i: number) => {\n      let edgePos: Coor;\n      let lanePosStart: Coor;\n      let lanePosEnd: Coor;\n      let lineStart: Coor;\n      let lineEnd: Coor;\n      let zebraStart: Coor;\n      let zebraEnd: Coor;\n      let laneCount: number = lanes.length - 1;\n\n      switch (index) {\n        case 0:\n          edgePos = {\n            x: -(squareWidth / 2) + center.x - zebraStripesWidth,\n            y: center.y + item.inLinkCount * laneWidth\n          };\n          lanePosStart = {\n            x: edgePos.x,\n            y: edgePos.y + laneWidth / 2 - laneWidth * (i + 1)\n          };\n          lanePosEnd = {\n            x: lanePosStart.x - laneLength,\n            y: lanePosStart.y\n          };\n          lineStart = {\n            ...edgePos,\n            y: edgePos.y - laneWidth * i\n          };\n          lineEnd = {\n            x: edgePos.x - laneLength,\n            y: lineStart.y\n          };\n          zebraStart = {\n            x: edgePos.x + zebraStripesWidth / 2,\n            y: edgePos.y\n          };\n          zebraEnd = {\n            x: zebraStart.x,\n            y: edgePos.y - item.zebraStripesLength\n          };\n          break;\n\n        case 1:\n          edgePos = {\n            x: center.x - item.inLinkCount * laneWidth,\n            y: center.y - squareWidth / 2 - zebraStripesWidth\n          };\n          lanePosStart = {\n            x: edgePos.x - laneWidth / 2 + laneWidth * (i + 1),\n            y: edgePos.y\n          };\n          lanePosEnd = {\n            x: lanePosStart.x,\n            y: edgePos.y - laneLength\n          };\n          lineStart = {\n            ...edgePos,\n            x: edgePos.x + laneWidth * i\n          };\n          lineEnd = {\n            x: lineStart.x,\n            y: lineStart.y - laneLength\n          };\n          zebraStart = {\n            x: edgePos.x,\n            y: edgePos.y + zebraStripesWidth / 2\n          };\n          zebraEnd = {\n            x: zebraStart.x + item.zebraStripesLength,\n            y: zebraStart.y\n          };\n          break;\n\n        case 2:\n          edgePos = {\n            x: center.x + squareWidth / 2 + zebraStripesWidth,\n            y: center.y - item.inLinkCount * laneWidth\n          };\n          lanePosStart = {\n            x: edgePos.x,\n            y: edgePos.y - laneWidth / 2 + laneWidth * (i + 1)\n          };\n          lanePosEnd = {\n            x: lanePosStart.x + laneLength,\n            y: lanePosStart.y\n          };\n          lineStart = {\n            ...edgePos,\n            y: edgePos.y + laneWidth * i\n          };\n          lineEnd = {\n            x: edgePos.x + laneLength,\n            y: lineStart.y\n          };\n          zebraStart = {\n            x: edgePos.x - zebraStripesWidth / 2,\n            y: edgePos.y\n          };\n          zebraEnd = {\n            x: zebraStart.x,\n            y: edgePos.y + item.zebraStripesLength\n          };\n          break;\n\n        default:\n          edgePos = {\n            x: center.x + item.inLinkCount * laneWidth,\n            y: center.y + squareWidth / 2 + zebraStripesWidth\n          };\n          lanePosStart = {\n            x: edgePos.x + laneWidth / 2 - laneWidth * (i + 1),\n            y: edgePos.y\n          };\n          lanePosEnd = {\n            x: lanePosStart.x,\n            y: edgePos.y + laneLength\n          };\n          lineStart = {\n            ...edgePos,\n            x: edgePos.x - laneWidth * i\n          };\n          lineEnd = {\n            x: lineStart.x,\n            y: lineStart.y + laneLength\n          };\n          // zebraStripesWidth\n          zebraStart = {\n            x: edgePos.x,\n            y: edgePos.y - zebraStripesWidth / 2\n          };\n          zebraEnd = {\n            x: zebraStart.x - item.zebraStripesLength,\n            y: zebraStart.y\n          };\n      }\n\n      // cdraw.drawCircle(edgePos, 30, 'cyan');\n      lane.logoPos = lanePosStart;\n      lane.edgePos = edgePos;\n      // draw lane\n      cdraw.drawLine(lanePosStart, lanePosEnd, roadColor, laneWidth);\n      if (i !== 0) {\n        // \u5982\u679c\u524d\u4e00\u4e2a lane \u6709 toward \u5f53\u524d\u7684 lane \u6ca1\u6709\u5219\u662f\u9ec4\u7ebf\n        const previousLane = i === 0 ? lanes[0] : lanes[i - 1];\n        const isYellow = !!previousLane.toward && !lane.toward;\n        drawLaneLine(lineStart, lineEnd, isYellow, !lane.toward);\n      }\n      drawZebra(zebraStart, zebraEnd);\n\n      if (lane.toward && lane.logoPos) {\n        const toward = towardHash[index];\n        const prefix = toward[0];\n        const image = new URL(`../../assets/lanes/${toward}/${prefix}-${lane.toward}.png`, import.meta.url).href;\n        renderImage(image, lane.logoPos, toward);\n      }\n    });\n  });\n\n  // cdraw.drawASquare(center, squareWidth, 'red');\n\n  // \u6247\u5f62\u533a\u57df\n  const insideVertices = calculateSquareVertices(center.x, center.y, squareWidth);\n  const laneStartAndEnd = vertices.map((v, vindex) => {\n    const { inLinkCount, outLinkCount } = inLinks[vindex];\n    const nextInLink = vindex === 3 ? inLinks[0] : inLinks[vindex + 1];\n    const { edgePos } = nextInLink.lanes[0];\n    let b: Coor;\n    let c: Coor;\n    let d: Coor;\n    const doubleLW = laneWidth * 2;\n    // \u6839\u636e\u5916\u9876\u70b9\u8fde\u63a5\u8def\u5bbd\n    switch (vindex) {\n      case 0:\n        b = {\n          x: v.x,\n          y: center.y - laneWidth * outLinkCount\n        };\n        c = {\n          x: edgePos.x,\n          y: b.y\n        };\n        d = {\n          x: c.x,\n          y: v.y\n        };\n        return { a: v, b, c, d };\n      case 1:\n        b = {\n          x: center.x + laneWidth * outLinkCount,\n          y: v.y\n        };\n        c = {\n          x: b.x,\n          y: edgePos.y\n        };\n        d = {\n          x: v.x,\n          y: c.y\n        };\n        return { a: v, b, c, d };\n      case 2:\n        b = {\n          x: v.x,\n          y: center.y + laneWidth * outLinkCount\n        };\n        c = {\n          x: edgePos.x,\n          y: b.y\n        };\n        d = {\n          x: c.x,\n          y: v.y\n        };\n        return { a: v, b, c, d };\n      default:\n        b = {\n          x: center.x - laneWidth * outLinkCount,\n          y: v.y\n        };\n        c = {\n          x: b.x,\n          y: edgePos.y\n        };\n        d = {\n          x: v.x - 100,\n          y: c.y\n        };\n        return { a: v, b, c, d };\n    }\n  });\n\n  ctx.beginPath();\n  const radius = laneWidth * 2;\n  laneStartAndEnd.forEach((item, itemIndex) => {\n    const { a, b, c, d } = item;\n    // cdraw.drawCircle(b, 18, 'blue');\n    // cdraw.drawCircle(c, 18, 'cyan');\n    // cdraw.drawCircle(d, 18, 'red');\n    const curInsideVertice = insideVertices[itemIndex];\n    const { x: insideX, y: insideY } = c;\n    ctx.moveTo(a.x, a.y);\n    ctx.lineTo(b.x, b.y);\n    ctx.arcTo(c.x, c.y, d.x, d.y, laneWidth * multiple);\n    ctx.lineTo(d.x, d.y);\n    ctx.fillStyle = props.bgColor ?? canvasBg;\n    // ctx.fillStyle = 'green';\n    ctx.fill();\n  });\n}\n\nfunction drawLaneLine(start: Coor, end: Coor, isYellow: boolean = false, isDash: boolean) {\n  const c = ctx!;\n  c.setLineDash(!isDash ? [] : [10, 10]);\n  if (isYellow) {\n    c.setLineDash([]);\n  }\n  cdraw.drawLine(start, end, isYellow ? yellowColor : whiteColor, 2);\n  c.setLineDash([]);\n}\n\nfunction renderImage(path: string, pos: Coor, dir: \"east\" | \"west\" | \"south\" | \"north\") {\n  const width = laneWidth * 0.7;\n  const height = laneWidth * 0.7;\n  const hash = {\n    west: {\n      x: pos.x + width,\n      y: pos.y - height / 2\n    },\n    south: {\n      x: pos.x - width / 2,\n      y: pos.y - height * 2\n    },\n    east: {\n      x: pos.x - width * 2,\n      y: pos.y - height / 2\n    },\n    north: {\n      x: pos.x - width / 2,\n      y: pos.y + height\n    }\n  };\n  const img = new Image();\n  img.src = path;\n  img.onload = function () {\n    ctx!.drawImage(img, hash[dir].x, hash[dir].y, width, height);\n  };\n}\n\nfunction initCanvas() {\n  const canvas = document.querySelector(\"#canvas\") as HTMLCanvasElement;\n  canvas.style.backgroundColor = props.bgColor ?? canvasBg;\n  cdraw = new Cdraw(canvas);\n\n  if (!canvasRef?.value?.offsetWidth) {\n    console.log(\"no offsetWidth\");\n    return;\n  }\n\n  canvas.width = (canvasRef.value as HTMLCanvasElement).offsetWidth;\n  canvas.height = (canvasRef.value as HTMLCanvasElement).offsetHeight;\n  ctx = canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n  center.x = canvas.width / 2;\n  center.y = canvas.height / 2;\n  laneWidth = canvas.width / 40;\n  zebraStripesWidth = laneWidth * 2;\n  laneLength = squareWidth * 2 - zebraStripesWidth * 1.2;\n  drawCross();\n}\n\nfunction drawZebra(start: Coor, end: Coor) {\n  // ctx!.setLineDash([8, 10]);\n  ctx!.setLineDash([laneWidth / 4, laneWidth / 3]);\n  cdraw.drawLine(start, end, whiteColor, zebraStripesWidth / 2);\n  ctx!.setLineDash([]);\n  ctx!.lineWidth = 1;\n}\n\n// defineExpose({\n//   initCanvas\n// });\n</script>\n\n<style scoped lang=\"scss\">\n.draw-lanes {\n  width: 100%;\n  height: 100%;\n}\n#canvas {\n  width: 100%;\n  height: 100%;\n  border: 1px solid #235773;\n}\n</style>\n"
      }
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:38:51.668072] Recv workspace/configuration request (1) from 'volar' for project traffic

--- [11:38:51.962031] Send response to server request 0 to 'volar' for project traffic
{
   "jsonrpc": "2.0",
   "id": 1,
   "method": "workspace/configuration",
   "params": {
      "items": [
         {
            "section": "css.customData"
         }
      ]
   }
}
{
   "id": 0,
   "result": [
      null
   ],
   "message_type": "response",
   "jsonrpc": "2.0"
}

--- [11:38:51.962563] Send response to server request 1 to 'volar' for project traffic

--- [11:38:51.976016] Recv workspace/configuration request (2) from 'volar' for project traffic
{
   "id": 1,
   "result": [
      null
   ],
   "message_type": "response",
   "jsonrpc": "2.0"
}
{
   "jsonrpc": "2.0",
   "id": 2,
   "method": "workspace/configuration",
   "params": {
      "items": [
         {
            "section": "scss"
         }
      ]
   }
}

--- [11:38:52.019867] Send response to server request 2 to 'volar' for project traffic
{
   "id": 2,
   "result": [
      null
   ],
   "message_type": "response",
   "jsonrpc": "2.0"
}

--- [11:38:52.034434] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:38:52.034641] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 0
   }
}

--- [11:38:52.035107] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:38:52.078583] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 0
   }
}
Eval in Emacs: (lsp-bridge-diagnostic--render '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '0)

输入内容后:

--- [11:39:51.412247] Send textDocument/didChange notification to 'volar' for project traffic
{
   "method": "textDocument/didChange",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "version": 1
      },
      "contentChanges": [
         {
            "range": {
               "start": {
                  "line": 85,
                  "character": 0
               },
               "end": {
                  "line": 85,
                  "character": 0
               }
            },
            "rangeLength": 0,
            "text": "c"
         }
      ]
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}
Eval in Emacs: (lsp-bridge-search-backend--record-items '"search-file-words" '())

--- [11:39:51.573639] Send textDocument/completion request (10618) to 'volar' for project traffic
{
   "id": 10618,
   "method": "textDocument/completion",
   "params": {
      "position": {
         "line": 85,
         "character": 1
      },
      "context": {
         "triggerKind": 1
      },
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [11:39:51.590090] Recv textDocument/completion response (10618) from 'volar' for project traffic

--- [11:39:51.590184] Got completion candidates (0) from 'volar' for file index.vue

--- [11:39:51.590206] Record completion candidates (0) from 'volar' for file index.vue
Eval in Emacs: (lsp-bridge-completion--record-items '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '(:line 85 :character 1) '"volar" '("*" "/" "-" ":" "\"" "." "<" "=" "@" ">" "+" "^" "(" ")" "#" "[" "]" "$" "{" "}") '("volar"))
{
   "jsonrpc": "2.0",
   "id": 10618,
   "result": {
      "isIncomplete": false,
      "items": []
   }
}

--- [11:39:51.671852] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:39:51.671925] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 1
   }
}

--- [11:39:51.672082] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:39:51.672097] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 1
   }
}
Eval in Emacs: (lsp-bridge-search-backend--record-items '"search-file-words" '((:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words") (:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words")))

--- [11:39:51.704106] Send textDocument/didChange notification to 'volar' for project traffic
{
   "method": "textDocument/didChange",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "version": 2
      },
      "contentChanges": [
         {
            "range": {
               "start": {
                  "line": 85,
                  "character": 1
               },
               "end": {
                  "line": 85,
                  "character": 1
               }
            },
            "rangeLength": 0,
            "text": "d"
         }
      ]
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}
Eval in Emacs: (lsp-bridge-search-backend--record-items '"search-file-words" '((:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words") (:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words")))

--- [11:39:51.768565] Send textDocument/didChange notification to 'volar' for project traffic
{
   "method": "textDocument/didChange",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "version": 3
      },
      "contentChanges": [
         {
            "range": {
               "start": {
                  "line": 85,
                  "character": 2
               },
               "end": {
                  "line": 85,
                  "character": 2
               }
            },
            "rangeLength": 0,
            "text": "r"
         }
      ]
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}
Eval in Emacs: (lsp-bridge-search-backend--record-items '"search-file-words" '((:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words") (:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words")))

--- [11:39:51.913473] Send textDocument/completion request (13139) to 'volar' for project traffic
{
   "id": 13139,
   "method": "textDocument/completion",
   "params": {
      "position": {
         "line": 85,
         "character": 3
      },
      "context": {
         "triggerKind": 1
      },
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [11:39:51.913648] Send textDocument/didChange notification to 'volar' for project traffic
{
   "method": "textDocument/didChange",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "version": 4
      },
      "contentChanges": [
         {
            "range": {
               "start": {
                  "line": 85,
                  "character": 3
               },
               "end": {
                  "line": 85,
                  "character": 3
               }
            },
            "rangeLength": 0,
            "text": "a"
         }
      ]
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:39:51.921437] Recv textDocument/completion response (13139) from 'volar' for project traffic
Discard response: file changed since last request
{
   "jsonrpc": "2.0",
   "id": 13139,
   "result": {
      "isIncomplete": false,
      "items": []
   }
}

--- [11:39:51.995873] Send textDocument/completion request (53116) to 'volar' for project traffic
{
   "id": 53116,
   "method": "textDocument/completion",
   "params": {
      "position": {
         "line": 85,
         "character": 4
      },
      "context": {
         "triggerKind": 1
      },
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [11:39:51.998096] Recv textDocument/completion response (53116) from 'volar' for project traffic

--- [11:39:51.998153] Got completion candidates (0) from 'volar' for file index.vue

--- [11:39:51.998169] Record completion candidates (0) from 'volar' for file index.vue
Eval in Emacs: (lsp-bridge-completion--record-items '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '(:line 85 :character 4) '"volar" '("*" "/" "-" ":" "\"" "." "<" "=" "@" ">" "+" "^" "(" ")" "#" "[" "]" "$" "{" "}") '("volar"))
{
   "jsonrpc": "2.0",
   "id": 53116,
   "result": {
      "isIncomplete": false,
      "items": []
   }
}
Eval in Emacs: (lsp-bridge-search-backend--record-items '"search-file-words" '((:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words") (:key "cdraw" :icon "search" :label "cdraw" :displayLabel "cdraw" :annotation "Search Word" :backend "search-file-words")))

--- [11:39:52.060526] Send textDocument/didChange notification to 'volar' for project traffic
{
   "method": "textDocument/didChange",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "version": 5
      },
      "contentChanges": [
         {
            "range": {
               "start": {
                  "line": 85,
                  "character": 4
               },
               "end": {
                  "line": 85,
                  "character": 4
               }
            },
            "rangeLength": 0,
            "text": "w"
         }
      ]
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:39:52.165603] Send textDocument/completion request (44983) to 'volar' for project traffic
{
   "id": 44983,
   "method": "textDocument/completion",
   "params": {
      "position": {
         "line": 85,
         "character": 5
      },
      "context": {
         "triggerKind": 1
      },
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}
Eval in Emacs: (lsp-bridge-diagnostic--render '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '0)

--- [11:39:52.175449] Recv textDocument/completion response (44983) from 'volar' for project traffic

--- [11:39:52.175498] Got completion candidates (0) from 'volar' for file index.vue

--- [11:39:52.175515] Record completion candidates (0) from 'volar' for file index.vue
Eval in Emacs: (lsp-bridge-completion--record-items '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '(:line 85 :character 5) '"volar" '("*" "/" "-" ":" "\"" "." "<" "=" "@" ">" "+" "^" "(" ")" "#" "[" "]" "$" "{" "}") '("volar"))
{
   "jsonrpc": "2.0",
   "id": 44983,
   "result": {
      "isIncomplete": false,
      "items": []
   }
}

--- [11:39:52.319550] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:39:52.319676] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 5
   }
}

--- [11:39:52.319904] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:39:52.319935] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 5
   }
}

--- [11:39:52.600859] Send textDocument/signatureHelp request (40886) to 'volar' for project traffic
{
   "id": 40886,
   "method": "textDocument/signatureHelp",
   "params": {
      "position": {
         "line": 85,
         "character": 5
      },
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [11:39:52.603231] Recv textDocument/signatureHelp response (40886) from 'volar' for project traffic
{
   "jsonrpc": "2.0",
   "id": 40886,
   "result": null
}
Eval in Emacs: (lsp-bridge-diagnostic--render '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '0)
Eval in Emacs: (lsp-bridge-search-backend--record-items '"search-file-words" '())

--- [11:39:52.863369] Send textDocument/didChange notification to 'volar' for project traffic
{
   "method": "textDocument/didChange",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "version": 6
      },
      "contentChanges": [
         {
            "range": {
               "start": {
                  "line": 85,
                  "character": 5
               },
               "end": {
                  "line": 85,
                  "character": 5
               }
            },
            "rangeLength": 0,
            "text": "."
         }
      ]
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:39:52.968380] Send textDocument/completion request (17026) to 'volar' for project traffic
{
   "id": 17026,
   "method": "textDocument/completion",
   "params": {
      "position": {
         "line": 85,
         "character": 6
      },
      "context": {
         "triggerCharacter": ".",
         "triggerKind": 2
      },
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [11:39:52.974743] Recv textDocument/completion response (17026) from 'volar' for project traffic

--- [11:39:52.981678] Got completion candidates (0) from 'volar' for file index.vue

--- [11:39:52.981715] Record completion candidates (0) from 'volar' for file index.vue
Eval in Emacs: (lsp-bridge-completion--record-items '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '(:line 85 :character 6) '"volar" '("*" "/" "-" ":" "\"" "." "<" "=" "@" ">" "+" "^" "(" ")" "#" "[" "]" "$" "{" "}") '("volar"))
{
   "jsonrpc": "2.0",
   "id": 17026,
   "result": {
      "isIncomplete": false,
      "items": []
   }
}

--- [11:39:53.122640] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:39:53.122749] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 6
   }
}

--- [11:39:53.123031] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:39:53.123096] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 6
   }
}

--- [11:39:53.481555] Send textDocument/signatureHelp request (56326) to 'volar' for project traffic
{
   "id": 56326,
   "method": "textDocument/signatureHelp",
   "params": {
      "position": {
         "line": 85,
         "character": 6
      },
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [11:39:53.484342] Recv textDocument/signatureHelp response (56326) from 'volar' for project traffic
{
   "jsonrpc": "2.0",
   "id": 56326,
   "result": null
}
Eval in Emacs: (lsp-bridge-diagnostic--render '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '0)

保存文件:

--- [11:42:07.340993] Send textDocument/didClose notification to 'volar' for project traffic
{
   "method": "textDocument/didClose",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:42:07.341134] Send shutdown request (41021) to 'volar' for project traffic
{
   "id": 41021,
   "method": "shutdown",
   "params": {},
   "message_type": "request",
   "jsonrpc": "2.0"
}

--- [11:42:07.341247] Exit server /Users/mzy/work/traffic#volar

--- [11:42:07.341282] Send exit notification to 'volar' for project traffic
{
   "method": "exit",
   "params": {},
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:42:07.343620] LSP server 'volar' exited with code -9
b''
Eval in Emacs: (message '"[LSP-Bridge] found language server: /Users/mzy/.nvm/versions/node/v18.19.0/bin/vue-language-server")
Eval in Emacs: (message '"[LSP-Bridge] found language server: /Users/mzy/.nvm/versions/node/v18.19.0/bin/vue-language-server")
Start lsp server (volar) for /Users/mzy/work/traffic
Eval in Emacs: (message '"[LSP-Bridge] Active project 'traffic', enjoy hacking!")
Handlers: [<class 'core.handler.completion.Completion'>,
 <class 'core.handler.completion_item.CompletionItem'>,
 <class 'core.handler.find_define.FindDefine'>,
 <class 'core.handler.find_type_define.FindTypeDefine'>,
 <class 'core.handler.find_implementation.FindImplementation'>,
 <class 'core.handler.find_references.FindReferences'>,
 <class 'core.handler.peek.PeekFindDefine'>,
 <class 'core.handler.peek.PeekFindReferences'>,
 <class 'core.handler.hover.Hover'>,
 <class 'core.handler.signature_help.SignatureHelp'>,
 <class 'core.handler.prepare_rename.PrepareRename'>,
 <class 'core.handler.rename.Rename'>,
 <class 'core.handler.jdt_uri_resolver.JDTUriResolver'>,
 <class 'core.handler.deno_uri_resolver.DenoUriResolver'>,
 <class 'core.handler.code_action.CodeAction'>,
 <class 'core.handler.formatting.Formatting'>,
 <class 'core.handler.range_formatting.RangeFormatting'>,
 <class 'core.handler.execute_command.ExecuteCommand'>,
 <class 'core.handler.workspace_symbol.WorkspaceSymbol'>,
 <class 'core.handler.call_hierarchy.PrepareCallHierarchy'>,
 <class 'core.handler.call_hierarchy.CallHierarchy'>,
 <class 'core.handler.call_hierarchy.PrepareCallHierarchyIncomingCalls'>,
 <class 'core.handler.call_hierarchy.PrepareCallHierarchyOutgoingCalls'>,
 <class 'core.handler.call_hierarchy.CallHierarchyIncomingCalls'>,
 <class 'core.handler.call_hierarchy.CallHierarchyOutgoingCalls'>,
 <class 'core.handler.document_symbol.DocumentSymbol'>,
 <class 'core.handler.jdtls.jdtls_list_overridable_methods.JdtlsListOverridableMethods'>,
 <class 'core.handler.jdtls.jdtls_add_overridable_methods.JdtlsAddOverridableMethods'>,
 <class 'core.handler.inlay_hint.InlayHint'>,
 <class 'core.handler.semantic_tokens.SemanticTokens'>]

--- [11:42:07.447341] Send initialize request (23108) to 'volar' for project traffic
{
   "id": 23108,
   "method": "initialize",
   "params": {
      "processId": 65540,
      "rootPath": "/Users/mzy/work/traffic",
      "clientInfo": {
         "name": "emacs",
         "version": "lsp-bridge"
      },
      "rootUri": "file:///Users/mzy/work/traffic",
      "capabilities": {
         "workspace": {
            "configuration": true,
            "symbol": {
               "resolveSupport": {
                  "properties": []
               }
            }
         },
         "textDocument": {
            "completion": {
               "completionItem": {
                  "snippetSupport": true,
                  "deprecatedSupport": true,
                  "tagSupport": {
                     "valueSet": [
                        1
                     ]
                  },
                  "resolveSupport": {
                     "properties": [
                        "documentation",
                        "detail",
                        "additionalTextEdits"
                     ]
                  }
               }
            },
            "codeAction": {
               "dynamicRegistration": false,
               "codeActionLiteralSupport": {
                  "codeActionKind": {
                     "valueSet": [
                        "quickfix",
                        "refactor",
                        "refactor.extract",
                        "refactor.inline",
                        "refactor.rewrite",
                        "source",
                        "source.organizeImports"
                     ]
                  }
               },
               "isPreferredSupport": true
            },
            "inlayHint": {
               "dynamicRegistration": false
            },
            "publishDiagnostics": {
               "relatedInformation": true,
               "tagSupport": {
                  "valueSet": [
                     1,
                     2
                  ]
               },
               "versionSupport": true,
               "codeDescriptionSupport": true,
               "dataSupport": true
            }
         }
      },
      "initializationOptions": {
         "typescript": {
            "tsdk": "/usr/local/lib/node_modules/typescript/lib"
         },
         "languageFeatures": {
            "references": true,
            "implementation": true,
            "definition": true,
            "typeDefinition": true,
            "callHierarchy": true,
            "hover": true,
            "rename": true,
            "renameFileRefactoring": true,
            "signatureHelp": true,
            "codeAction": true,
            "workspaceSymbol": true,
            "completion": {
               "defaultTagNameCase": "",
               "defaultAttrNameCase": "",
               "getDocumentNameCasesRequest": false,
               "getDocumentSelectionRequest": false
            },
            "schemaRequestService": {
               "getDocumentContentRequest": false
            }
         },
         "documentFeatures": {
            "selectionRange": true,
            "foldingRange": true,
            "linkedEditingRange": true,
            "documentSymbol": true,
            "documentColor": true,
            "documentFormatting": {
               "defaultPrintWidth": 100,
               "getDocumentPrintWidthRequest": false
            }
         }
      }
   },
   "message_type": "request",
   "jsonrpc": "2.0"
}
Eval in Emacs: (lsp-bridge-set-server-names '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '("volar"))

--- [11:42:07.786194] Recv response (23108) from 'volar' for project traffic
{
   "jsonrpc": "2.0",
   "id": 23108,
   "result": {
      "capabilities": {
         "textDocumentSync": 2,
         "workspace": {
            "fileOperations": {
               "willRename": {
                  "filters": [
                     {
                        "pattern": {
                           "glob": "**/*.{js,cjs,mjs,ts,cts,mts,jsx,tsx,json,vue}"
                        }
                     }
                  ]
               }
            }
         },
         "selectionRangeProvider": true,
         "foldingRangeProvider": true,
         "linkedEditingRangeProvider": true,
         "colorProvider": true,
         "documentSymbolProvider": true,
         "documentFormattingProvider": true,
         "documentRangeFormattingProvider": true,
         "referencesProvider": true,
         "implementationProvider": true,
         "definitionProvider": true,
         "typeDefinitionProvider": true,
         "callHierarchyProvider": true,
         "hoverProvider": true,
         "renameProvider": {
            "prepareProvider": true
         },
         "signatureHelpProvider": {
            "triggerCharacters": [],
            "retriggerCharacters": []
         },
         "completionProvider": {
            "triggerCharacters": [
               "*",
               "/",
               "-",
               ":",
               "\"",
               ".",
               "<",
               "=",
               "@",
               ">",
               "+",
               "^",
               "(",
               ")",
               "#",
               "[",
               "]",
               "$",
               "{",
               "}"
            ],
            "resolveProvider": true
         },
         "documentHighlightProvider": true,
         "documentLinkProvider": {
            "resolveProvider": true
         },
         "codeLensProvider": {
            "resolveProvider": true
         },
         "codeActionProvider": {
            "codeActionKinds": [
               "",
               "quickfix",
               "refactor",
               "refactor.extract",
               "refactor.inline",
               "refactor.rewrite",
               "source",
               "source.fixAll",
               "source.organizeImports"
            ],
            "resolveProvider": true
         },
         "inlayHintProvider": {
            "resolveProvider": true
         },
         "workspaceSymbolProvider": true,
         "documentOnTypeFormattingProvider": {
            "firstTriggerCharacter": ";",
            "moreTriggerCharacter": [
               "}",
               "\n"
            ]
         }
      }
   }
}

--- [11:42:07.786425] Send initialized notification to 'volar' for project traffic

--- [11:42:07.850944] Recv workspace/configuration request (0) from 'volar' for project traffic
{
   "method": "initialized",
   "params": {},
   "message_type": "notification",
   "jsonrpc": "2.0"
}
{
   "jsonrpc": "2.0",
   "id": 0,
   "method": "workspace/configuration",
   "params": {
      "items": [
         {
            "section": "http"
         }
      ]
   }
}

--- [11:42:07.851099] Send workspace/didChangeConfiguration notification to 'volar' for project traffic
{
   "method": "workspace/didChangeConfiguration",
   "params": {
      "settings": {}
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:42:07.913904] Send textDocument/didOpen notification to 'volar' for project traffic
{
   "method": "textDocument/didOpen",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
         "languageId": "vue",
         "version": 0,
         "text": "<template>\n  <div class=\"draw-lanes\">\n    <!-- <el-button @click=\"handleZoomIn\">+</el-button> -->\n    <!-- <el-button @click=\"handleZoomOut\">-</el-button> -->\n    <canvas ref=\"canvasRef\" id=\"canvas\"> Your browser is not suppot canvas </canvas>\n  </div>\n</template>\n\n<script setup lang=\"ts\" name=\"DrawLanes\">\n// props:\n// @data: \u6e20\u5316\u56fe\u6570\u636e\n// @bgColor: canvas \u80cc\u666f\u8272, \u9ed8\u8ba4\u503c\u662f \"#04232e\"\n\nimport { ref, Ref, reactive, onMounted, onBeforeUnmount, onUnmounted } from \"vue\";\nimport { Coor, InLink, Lane } from \"@/utils/interface\";\nimport Cdraw from \"@/utils/cdraw\";\nimport { calculateSquareVertices } from \"@/utils/calc\";\n\nconst props = defineProps([\"data\", \"bgColor\"]);\n// const emits = defineEmits([\"add\", \"minus\"]);\nconst roadColor = \"#194359\";\nconst yellowColor = \"#C6B41C\";\nconst whiteColor = \"#AEC8D6\";\nconst canvasBg = \"#04232e\";\n\nconst canvasRef: Ref<HTMLCanvasElement | null> = ref(null);\nlet ctx: CanvasRenderingContext2D | null = null;\nlet cdraw: Cdraw;\n\nconst center: Coor = {\n  x: 0,\n  y: 0\n};\n\nlet squareWidth = 210;\nlet laneWidth = 30;\nlet zebraStripesWidth = laneWidth * 2;\nlet laneLength = squareWidth * 2 - zebraStripesWidth * 1.2;\nlet vertices: Coor[] = [];\n\nonMounted(() => {\n  initCanvas();\n  window.addEventListener(\"resize\", initCanvas);\n});\n\nonUnmounted(() => window.removeEventListener(\"resize\", initCanvas));\n\nfunction handleZoomIn() {\n  laneWidth += 2;\n  initCanvas();\n}\n\nfunction handleZoomOut() {\n  laneWidth -= 2;\n  initCanvas();\n}\n\nfunction drawCross() {\n  const firstNode = props.data[0];\n  const inLinks: InLink[] = firstNode.inLinks;\n  const towardHash = {\n    \"0\": \"east\",\n    \"1\": \"south\",\n    \"2\": \"west\",\n    \"3\": \"north\"\n  };\n\n  // lanes \u6700\u5927\u6570\n  const maxLanesCount = Math.max(...inLinks.map(item => item.lanes.length));\n  const multiple = Math.floor(maxLanesCount / 2);\n  // \u5916\u6b63\u65b9\u5f62\u9876\u70b9\n  vertices = calculateSquareVertices(center.x, center.y, squareWidth + laneWidth * multiple * 3);\n  const [a, b, c, d] = vertices;\n  cdraw.drawShape(a, b, c, d, roadColor);\n\n  squareWidth = maxLanesCount * laneWidth;\n  inLinks.forEach((item: InLink, index: number) => {\n    const laneCount = item.lanes.length;\n    item.zebraStripesLength = laneCount * laneWidth;\n\n    // 1 2 3 4 - \u897f \u5317 \u4e1c \u5357 - \u5de6 \u4e0a \u53f3 \u4e0b\n    // if (index > 1) return;\n    const { lanes } = item;\n    item.inLinkCount = item.lanes.filter(item => item.toward).length;\n    item.outLinkCount = item.lanes.filter(item => !item.toward).length;\n    lanes.forEach((lane: Lane, i: number) => {\n      let edgePos: Coor;\n      let lanePosStart: Coor;\n      let lanePosEnd: Coor;\n      let lineStart: Coor;\n      let lineEnd: Coor;\n      let zebraStart: Coor;\n      let zebraEnd: Coor;\n      let laneCount: number = lanes.length - 1;\n\n      switch (index) {\n        case 0:\n          edgePos = {\n            x: -(squareWidth / 2) + center.x - zebraStripesWidth,\n            y: center.y + item.inLinkCount * laneWidth\n          };\n          lanePosStart = {\n            x: edgePos.x,\n            y: edgePos.y + laneWidth / 2 - laneWidth * (i + 1)\n          };\n          lanePosEnd = {\n            x: lanePosStart.x - laneLength,\n            y: lanePosStart.y\n          };\n          lineStart = {\n            ...edgePos,\n            y: edgePos.y - laneWidth * i\n          };\n          lineEnd = {\n            x: edgePos.x - laneLength,\n            y: lineStart.y\n          };\n          zebraStart = {\n            x: edgePos.x + zebraStripesWidth / 2,\n            y: edgePos.y\n          };\n          zebraEnd = {\n            x: zebraStart.x,\n            y: edgePos.y - item.zebraStripesLength\n          };\n          break;\n\n        case 1:\n          edgePos = {\n            x: center.x - item.inLinkCount * laneWidth,\n            y: center.y - squareWidth / 2 - zebraStripesWidth\n          };\n          lanePosStart = {\n            x: edgePos.x - laneWidth / 2 + laneWidth * (i + 1),\n            y: edgePos.y\n          };\n          lanePosEnd = {\n            x: lanePosStart.x,\n            y: edgePos.y - laneLength\n          };\n          lineStart = {\n            ...edgePos,\n            x: edgePos.x + laneWidth * i\n          };\n          lineEnd = {\n            x: lineStart.x,\n            y: lineStart.y - laneLength\n          };\n          zebraStart = {\n            x: edgePos.x,\n            y: edgePos.y + zebraStripesWidth / 2\n          };\n          zebraEnd = {\n            x: zebraStart.x + item.zebraStripesLength,\n            y: zebraStart.y\n          };\n          break;\n\n        case 2:\n          edgePos = {\n            x: center.x + squareWidth / 2 + zebraStripesWidth,\n            y: center.y - item.inLinkCount * laneWidth\n          };\n          lanePosStart = {\n            x: edgePos.x,\n            y: edgePos.y - laneWidth / 2 + laneWidth * (i + 1)\n          };\n          lanePosEnd = {\n            x: lanePosStart.x + laneLength,\n            y: lanePosStart.y\n          };\n          lineStart = {\n            ...edgePos,\n            y: edgePos.y + laneWidth * i\n          };\n          lineEnd = {\n            x: edgePos.x + laneLength,\n            y: lineStart.y\n          };\n          zebraStart = {\n            x: edgePos.x - zebraStripesWidth / 2,\n            y: edgePos.y\n          };\n          zebraEnd = {\n            x: zebraStart.x,\n            y: edgePos.y + item.zebraStripesLength\n          };\n          break;\n\n        default:\n          edgePos = {\n            x: center.x + item.inLinkCount * laneWidth,\n            y: center.y + squareWidth / 2 + zebraStripesWidth\n          };\n          lanePosStart = {\n            x: edgePos.x + laneWidth / 2 - laneWidth * (i + 1),\n            y: edgePos.y\n          };\n          lanePosEnd = {\n            x: lanePosStart.x,\n            y: edgePos.y + laneLength\n          };\n          lineStart = {\n            ...edgePos,\n            x: edgePos.x - laneWidth * i\n          };\n          lineEnd = {\n            x: lineStart.x,\n            y: lineStart.y + laneLength\n          };\n          // zebraStripesWidth\n          zebraStart = {\n            x: edgePos.x,\n            y: edgePos.y - zebraStripesWidth / 2\n          };\n          zebraEnd = {\n            x: zebraStart.x - item.zebraStripesLength,\n            y: zebraStart.y\n          };\n      }\n\n      // cdraw.drawCircle(edgePos, 30, 'cyan');\n      lane.logoPos = lanePosStart;\n      lane.edgePos = edgePos;\n      // draw lane\n      cdraw.drawLine(lanePosStart, lanePosEnd, roadColor, laneWidth);\n      if (i !== 0) {\n        // \u5982\u679c\u524d\u4e00\u4e2a lane \u6709 toward \u5f53\u524d\u7684 lane \u6ca1\u6709\u5219\u662f\u9ec4\u7ebf\n        const previousLane = i === 0 ? lanes[0] : lanes[i - 1];\n        const isYellow = !!previousLane.toward && !lane.toward;\n        drawLaneLine(lineStart, lineEnd, isYellow, !lane.toward);\n      }\n      drawZebra(zebraStart, zebraEnd);\n\n      if (lane.toward && lane.logoPos) {\n        const toward = towardHash[index];\n        const prefix = toward[0];\n        const image = new URL(`../../assets/lanes/${toward}/${prefix}-${lane.toward}.png`, import.meta.url).href;\n        renderImage(image, lane.logoPos, toward);\n      }\n    });\n  });\n\n  // cdraw.drawASquare(center, squareWidth, 'red');\n\n  // \u6247\u5f62\u533a\u57df\n  const insideVertices = calculateSquareVertices(center.x, center.y, squareWidth);\n  const laneStartAndEnd = vertices.map((v, vindex) => {\n    const { inLinkCount, outLinkCount } = inLinks[vindex];\n    const nextInLink = vindex === 3 ? inLinks[0] : inLinks[vindex + 1];\n    const { edgePos } = nextInLink.lanes[0];\n    let b: Coor;\n    let c: Coor;\n    let d: Coor;\n    const doubleLW = laneWidth * 2;\n    // \u6839\u636e\u5916\u9876\u70b9\u8fde\u63a5\u8def\u5bbd\n    switch (vindex) {\n      case 0:\n        b = {\n          x: v.x,\n          y: center.y - laneWidth * outLinkCount\n        };\n        c = {\n          x: edgePos.x,\n          y: b.y\n        };\n        d = {\n          x: c.x,\n          y: v.y\n        };\n        return { a: v, b, c, d };\n      case 1:\n        b = {\n          x: center.x + laneWidth * outLinkCount,\n          y: v.y\n        };\n        c = {\n          x: b.x,\n          y: edgePos.y\n        };\n        d = {\n          x: v.x,\n          y: c.y\n        };\n        return { a: v, b, c, d };\n      case 2:\n        b = {\n          x: v.x,\n          y: center.y + laneWidth * outLinkCount\n        };\n        c = {\n          x: edgePos.x,\n          y: b.y\n        };\n        d = {\n          x: c.x,\n          y: v.y\n        };\n        return { a: v, b, c, d };\n      default:\n        b = {\n          x: center.x - laneWidth * outLinkCount,\n          y: v.y\n        };\n        c = {\n          x: b.x,\n          y: edgePos.y\n        };\n        d = {\n          x: v.x - 100,\n          y: c.y\n        };\n        return { a: v, b, c, d };\n    }\n  });\n\n  ctx.beginPath();\n  const radius = laneWidth * 2;\n  laneStartAndEnd.forEach((item, itemIndex) => {\n    const { a, b, c, d } = item;\n    // cdraw.drawCircle(b, 18, 'blue');\n    // cdraw.drawCircle(c, 18, 'cyan');\n    // cdraw.drawCircle(d, 18, 'red');\n    const curInsideVertice = insideVertices[itemIndex];\n    const { x: insideX, y: insideY } = c;\n    ctx.moveTo(a.x, a.y);\n    ctx.lineTo(b.x, b.y);\n    ctx.arcTo(c.x, c.y, d.x, d.y, laneWidth * multiple);\n    ctx.lineTo(d.x, d.y);\n    ctx.fillStyle = props.bgColor ?? canvasBg;\n    // ctx.fillStyle = 'green';\n    ctx.fill();\n  });\n}\n\nfunction drawLaneLine(start: Coor, end: Coor, isYellow: boolean = false, isDash: boolean) {\n  const c = ctx!;\n  c.setLineDash(!isDash ? [] : [10, 10]);\n  if (isYellow) {\n    c.setLineDash([]);\n  }\n  cdraw.drawLine(start, end, isYellow ? yellowColor : whiteColor, 2);\n  c.setLineDash([]);\n}\n\nfunction renderImage(path: string, pos: Coor, dir: \"east\" | \"west\" | \"south\" | \"north\") {\n  const width = laneWidth * 0.7;\n  const height = laneWidth * 0.7;\n  const hash = {\n    west: {\n      x: pos.x + width,\n      y: pos.y - height / 2\n    },\n    south: {\n      x: pos.x - width / 2,\n      y: pos.y - height * 2\n    },\n    east: {\n      x: pos.x - width * 2,\n      y: pos.y - height / 2\n    },\n    north: {\n      x: pos.x - width / 2,\n      y: pos.y + height\n    }\n  };\n  const img = new Image();\n  img.src = path;\n  img.onload = function () {\n    ctx!.drawImage(img, hash[dir].x, hash[dir].y, width, height);\n  };\n}\n\nfunction initCanvas() {\n  const canvas = document.querySelector(\"#canvas\") as HTMLCanvasElement;\n  canvas.style.backgroundColor = props.bgColor ?? canvasBg;\n  cdraw = new Cdraw(canvas);\n\n  if (!canvasRef?.value?.offsetWidth) {\n    console.log(\"no offsetWidth\");\n    return;\n  }\n\n  canvas.width = (canvasRef.value as HTMLCanvasElement).offsetWidth;\n  canvas.height = (canvasRef.value as HTMLCanvasElement).offsetHeight;\n  ctx = canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n  center.x = canvas.width / 2;\n  center.y = canvas.height / 2;\n  laneWidth = canvas.width / 40;\n  zebraStripesWidth = laneWidth * 2;\n  laneLength = squareWidth * 2 - zebraStripesWidth * 1.2;\n  drawCross();\n}\n\nfunction drawZebra(start: Coor, end: Coor) {\n  // ctx!.setLineDash([8, 10]);\n  ctx!.setLineDash([laneWidth / 4, laneWidth / 3]);\n  cdraw.drawLine(start, end, whiteColor, zebraStripesWidth / 2);\n  ctx!.setLineDash([]);\n  ctx!.lineWidth = 1;\n}\n\n// defineExpose({\n//   initCanvas\n// });\n</script>\n\n<style scoped lang=\"scss\">\n.draw-lanes {\n  width: 100%;\n  height: 100%;\n}\n#canvas {\n  width: 100%;\n  height: 100%;\n  border: 1px solid #235773;\n}\n</style>\n"
      }
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:42:08.215350] Recv workspace/configuration request (1) from 'volar' for project traffic
{
   "jsonrpc": "2.0",
   "id": 1,
   "method": "workspace/configuration",
   "params": {
      "items": [
         {
            "section": "css.customData"
         }
      ]
   }
}

--- [11:42:08.760797] Send textDocument/didSave notification to 'volar' for project traffic
{
   "method": "textDocument/didSave",
   "params": {
      "textDocument": {
         "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue"
      }
   },
   "message_type": "notification",
   "jsonrpc": "2.0"
}

--- [11:42:08.807980] Send response to server request 0 to 'volar' for project traffic
{
   "id": 0,
   "result": [
      null
   ],
   "message_type": "response",
   "jsonrpc": "2.0"
}

--- [11:42:08.808077] Send response to server request 1 to 'volar' for project traffic
{
   "id": 1,
   "result": [
      null
   ],
   "message_type": "response",
   "jsonrpc": "2.0"
}

--- [11:42:08.813207] Recv workspace/configuration request (2) from 'volar' for project traffic
{
   "jsonrpc": "2.0",
   "id": 2,
   "method": "workspace/configuration",
   "params": {
      "items": [
         {
            "section": "scss"
         }
      ]
   }
}

--- [11:42:08.813337] Send response to server request 2 to 'volar' for project traffic
{
   "id": 2,
   "result": [
      null
   ],
   "message_type": "response",
   "jsonrpc": "2.0"
}

--- [11:42:08.821826] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:42:08.888344] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 0
   }
}

--- [11:42:08.888610] Recv textDocument/publishDiagnostics notification from 'volar' for project traffic

--- [11:42:08.888638] Record diagnostics from 'volar' for file index.vue
{
   "jsonrpc": "2.0",
   "method": "textDocument/publishDiagnostics",
   "params": {
      "uri": "file:///Users/mzy/work/traffic/src/components/DrawLanes/index.vue",
      "diagnostics": [],
      "version": 0
   }
}
Eval in Emacs: (lsp-bridge-diagnostic--render '"/Users/mzy/work/traffic/src/components/DrawLanes/index.vue" '"" '() '0)

*** lsp-bridge-try-completion execute predicate 'lsp-bridge-not-delete-command' failed with result: 'nil'

你的 vue 项目, npm install; npm build 这些都操作了吧?

都操作了,也找到原因了,我用16.13.2的 node 就行,18 的就会这样

我在切到 18 的版本也安装了那些需要的 npm 包,不知道为什么就不行

好, 解决就行了, volar 确实是 LSP server 界里的扛把子。

lsp-bridge 补全能在类似无 file 的 buffer 内比如 *scratch* 内生效吗,我经常要临时性的写一些测试的 code,比如切换到 js-ts-mode, 写一些console.log之类的,但是 lsp server没启动,写elisp不依赖lsp倒是没问题,写其他的 mode 就不行了

有可能,参考org-babel补全的实现,需要创建临时文件,因为lsp server需要有文件才行。

欢迎研究发送补丁。

51陪家人,没时间写代码,请理解。

5 个赞

五一快乐。我去看看org-babel :grin:

2 个赞

@manateelazycat lsp-bridge 的 fuzzy match 好像失效了?我试了html和js的server都必须严格匹配了,是默认值改了吗?

这个补丁改了,不改的话像tailwindcss会有成千个补全,就会发生没有匹配的问题

我看默认值还是fuzzy呀,我也没动过这个选项

emacs -Q先测试下?