Giter Site home page Giter Site logo

Comments (14)

manateelazycat avatar manateelazycat commented on May 25, 2024 2

你把 lsp-bridge-capf 函数替换成下面的实现,看看能否解决你的问题?

(defun lsp-bridge-capf ()
  "Capf function"
  (let* ((candidates (hash-table-keys lsp-bridge-completion-candidates))
         (bounds (bounds-of-thing-at-point 'symbol))
         (bounds-start (or (car bounds) (point)))
         (bounds-end (or (cdr bounds) (point))))
    (list
     bounds-start
     bounds-end
     candidates

     :company-cache
     t

     :annotation-function
     (lambda (candidate)
       (let* ((annotation (plist-get (lsp-bridge-get-candidate-item candidate) :annotation)))
         (setq lsp-bridge-completion-prefix (buffer-substring-no-properties bounds-start (point)))
         (when annotation
           (concat " " (propertize annotation 'face 'font-lock-doc-face)))))

     :company-kind
     (lambda (candidate)
       (when-let* ((kind (plist-get (lsp-bridge-get-candidate-item candidate) :kind)))
         (intern (downcase kind))))

     :company-deprecated
     (lambda (candidate)
       (seq-contains-p (plist-get (lsp-bridge-get-candidate-item candidate) :tags) 1))

     :exit-function
     (lambda (candidate status)
       ;; Only expand candidate when status is `finished'.
       ;; Otherwise we execute command `backward-delete-char-untabify' will cause candidate expand.
       (when (memq status '(finished))
         ;; Because lsp-bridge will push new candidates when company/lsp-bridge-ui completing.
         ;; We need extract newest candidates when insert, avoid insert old candidate content.
         (let* ((candidate-index (cl-find candidate candidates :test #'string=)))
           (with-current-buffer (if (minibufferp)
                                    (window-buffer (minibuffer-selected-window))
                                  (current-buffer))
             (cond
              ;; Don't expand candidate if the user enters all characters manually.
              ((and (member candidate candidates)
                    (eq this-command 'self-insert-command)))
              ;; Just insert candidate if it has expired.
              ((null candidate-index))
              (t
               (let* ((label (string-trim candidate)) ; we need trim candidate
                      (candidate-info (lsp-bridge-get-candidate-item candidate))
                      (insert-text (plist-get candidate-info :insertText))
                      (insert-text-format (plist-get candidate-info :insertTextFormat))
                      (text-edit (plist-get candidate-info :textEdit))
                      (new-text (plist-get text-edit :newText))
                      (additionalTextEdits (plist-get candidate-info :additionalTextEdits))
                      (kind (plist-get candidate-info :kind))
                      (snippet-fn (and (or (eql insert-text-format 2) (string= kind "Snippet")) (lsp-bridge--snippet-expansion-fn)))
                      (completion-start-pos (lsp-bridge--lsp-position-to-point lsp-bridge-completion-position))
                      (delete-start-pos (if text-edit
                                            (lsp-bridge--lsp-position-to-point (plist-get (plist-get text-edit :range) :start))
                                          bounds-start))
                      (range-end-pos (if text-edit
                                         (lsp-bridge--lsp-position-to-point (plist-get (plist-get text-edit :range) :end))
                                       completion-start-pos))
                      (delete-end-pos (+ (point) (- range-end-pos completion-start-pos)))
                      (insert-candidate (or new-text insert-text label)))

                 ;; Move bound start position forward one character, if the following situation is satisfied:
                 ;; 1. `textEdit' is not exist
                 ;; 2. bound-start character is `lsp-bridge-completion-trigger-characters'
                 ;; 3. `insertText' is not start with bound-start character
                 (unless text-edit
                   (let* ((bound-start-char (save-excursion
                                              (goto-char delete-start-pos)
                                              (char-to-string (char-after)))))
                     (when (and (member bound-start-char lsp-bridge-completion-trigger-characters)
                                (not (string-prefix-p bound-start-char insert-text)))
                       (setq bound-start-char (1+ bound-start-char)))))

                 ;; Delete region.
                 (delete-region delete-start-pos delete-end-pos)

                 ;; Insert candidate or expand snippet.
                 (funcall (or snippet-fn #'insert) insert-candidate)

                 ;; Do `additionalTextEdits' if return auto-imprt information.
                 (when (and lsp-bridge-enable-auto-import
                            (cl-plusp (length additionalTextEdits)))
                   (lsp-bridge--apply-text-edits additionalTextEdits))
                 ))))))))))

from lsp-bridge.

manateelazycat avatar manateelazycat commented on May 25, 2024

你更新到最新版本了吗?

from lsp-bridge.

smartepsh avatar smartepsh commented on May 25, 2024

你更新到最新版本了吗?

lsp-bridge 版本: lsp-bridge-20220530.1712

from lsp-bridge.

manateelazycat avatar manateelazycat commented on May 25, 2024

上传一下可以复现的最小源码吧。

from lsp-bridge.

smartepsh avatar smartepsh commented on May 25, 2024

我是通过 https://github.com/twlz0ne/emacsq-sh 来复现的。

./emacsq.sh -L . -P lsp-bridge,corfu -M global-lsp-bridge-mode,global-corfu-mode

或者

(require 'corfu)
(require 'lsp-bridge)
(require 'elixir-mode)
(global-lsp-bridge-mode)
(global-corfu-mode)

from lsp-bridge.

manateelazycat avatar manateelazycat commented on May 25, 2024

我是通过 https://github.com/twlz0ne/emacsq-sh 来复现的。

./emacsq.sh -L . -P lsp-bridge,corfu -M global-lsp-bridge-mode,global-corfu-mode

或者

(require 'corfu)
(require 'lsp-bridge)
(require 'elixir-mode)
(global-lsp-bridge-mode)
(global-corfu-mode)

能上传出问题的源码让我测试一下吗?

from lsp-bridge.

smartepsh avatar smartepsh commented on May 25, 2024

Elixir 代码吗?随便新建一个 .exs 文件,定义一个 module ,就可以了。

defmodule XX do

  # @callback 在 module 内部即可触发补全

end

from lsp-bridge.

manateelazycat avatar manateelazycat commented on May 25, 2024

你的 elixirLS.json 可以直接工作?

为啥我找不到 language_server.sh ? 我已经安装了 https://aur.archlinux.org/packages/elixir-ls

from lsp-bridge.

smartepsh avatar smartepsh commented on May 25, 2024

你的 elixirLS.json 可以直接工作?

为啥我找不到 language_server.sh ? 我已经安装了 https://aur.archlinux.org/packages/elixir-ls

需要将 elixir-ls 的文件夹加入 PATH 环境变量了。

from lsp-bridge.

manateelazycat avatar manateelazycat commented on May 25, 2024

你的 elixirLS.json 可以直接工作?
为啥我找不到 language_server.sh ? 我已经安装了 https://aur.archlinux.org/packages/elixir-ls

需要将 elixir-ls 的文件夹加入 PATH 环境变量了。

我这边无法运行, 建议你打开选项 (setq lsp-bridge-enable-log t) 然后重启Emacs, 出错时切换的 *lsp-birdge* buffer, 从下面往上搜索最近的 textDocument/completion 消息, 看看@开头的候选词对应的 textEdit 信息,看看 textEdit 的 range start 值, 那是 lsp-bridge 补全时的替换文本的起点。

from lsp-bridge.

smartepsh avatar smartepsh commented on May 25, 2024

range start 的值是在输入 @ 的位置,但 text 显示只有 callback 。

--- Recv response (3279): textDocument/completion
{
   "id": 3279,
   "jsonrpc": "2.0",
   "result": {
      "isIncomplete": true,
      "items": [
         {
            "deprecated": false,
            "detail": "module attribute",
            "documentation": {
               "kind": "markdown",
               "value": ""
            },
            "filterText": "behaviour",
            "insertText": "behaviour",
            "insertTextFormat": 2,
            "kind": 6,
            "label": "@behaviour",
            "sortText": "00000006",
            "tags": []
         },
         {
            "deprecated": false,
            "detail": "module attribute",
            "documentation": {
               "kind": "markdown",
               "value": ""
            },
            "filterText": "callback",
            "insertText": "callback",
            "insertTextFormat": 2,
            "kind": 6,
            "label": "@callback",
            "sortText": "00000007",
            "tags": []
         },
         ...
      ]
   }
}

--- Send (notification): textDocument/didChange
{
   "method": "textDocument/didChange",
   "params": {
      "textDocument": {
         "uri": "file:///......",
         "version": 9
      },
      "contentChanges": [
         {
            "range": {
               "start": {
                  "line": 21,
                  "character": 4
               },
               "end": {
                  "line": 21,
                  "character": 4
               }
            },
            "rangeLength": 0,
            "text": "callback"
         }
      ]
   },
   "jsonrpc": "2.0"
}

from lsp-bridge.

manateelazycat avatar manateelazycat commented on May 25, 2024

先把

(funcall (or snippet-fn #'insert) insert-candidate)
(lsp-bridge--apply-text-edits additionalTextEdits))
之间代码都注释掉。

看看

(delete-region delete-start-pos delete-end-pos)
删除完以后,是否还有 @ 字符? 还是把候选词都删除干净了?

然后再打印一下 insert-candidate 是什么值?

from lsp-bridge.

manateelazycat avatar manateelazycat commented on May 25, 2024

已经修复了,更新吧。

from lsp-bridge.

smartepsh avatar smartepsh commented on May 25, 2024

不好意思,昨天太晚就先休息了……
谢谢更新。

from lsp-bridge.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.