completion buffer有没有可能像lsp-bridge、company那种方式显示?

在python-shell中,按tab键会显示一个 Completions buffer,如图。有没有方式设置像 lsp-bridge、company那种在光标位置显示补全选项的? 有没有大神指导下?

我在用 corfu,默认就可以,好久没有 company 了,不确定。

你的表述有点奇怪。

completion-buffer 本身就是一种显示方式,它跟 company 是相互替代的关系。而不是说让 completion-buffercompany 那样显示。

lsp-bridge 是另一个层面的东西。

所以,应该问:python-shell 能不能用 company 显示补全?

答案是肯定的。

不知道你平时是怎么用 company 的。你真的用上了 company 吗?

python-shell 中使用 company 根本无须额外的配置,即使从零开始配置也非常简单:

  1. 终端运行: emacsq.sh -P company -M global-company-mode -nw -f run-python
  2. 在刚刚启动的 Emacs 中输入:import os\nos.

emacs-acm-terminal

要的就是你图上这种效果,但用的是lsp-bridge不是company,没有显示补全窗口,不知道需要怎么配置?现在的配置是:

(use-package lsp-bridge
  ;; :hook
  ;; ((prog-mode . lsp-bridge-mode)
  ;;  (org-mode . lsp-bridge-mode))
  :config
  (setq acm-enable-doc nil)
  (global-lsp-bridge-mode)
  )

你应该去 lsp-brigde 的帖子或者到 github 上提需求。目前 lsp-brigde 应该是只支持关联到文件的buffer。

*scratch* 这样的 buffer 都是不支持的。

我开始也是这么认为,但 scratch 好像是可以补全的。搞一个 company,只在这个mode下用应该也可以吧。

lsp-bridge可以在任意文件和buffer打开, 只是acm没有针对 python-shell 的补全后端。

:+1: 看来之前我用的版本还不够新。回头再试试看

按这里的说法 GNU ELPA - python

Shell completion: hitting tab will try to complete the current
word.  The two built-in mechanisms depend on Python's readline
module: the "native" completion is tried first and is activated
when `python-shell-completion-native-enable' is non-nil, the
current `python-shell-interpreter' is not a member of the
`python-shell-completion-native-disabled-interpreters' variable and
`python-shell-completion-native-setup' succeeds; the "fallback" or
"legacy" mechanism works by executing Python code in the background
and enables auto-completion for shells that do not support
receiving escape sequences (with some limitations, i.e. completion
in blocks does not work).  The code executed for the "fallback"
completion can be found in `python-shell-completion-setup-code' and
`python-shell-completion-string-code' variables.  Their default
values enable completion for both CPython and IPython, and probably
any readline based shell (it's known to work with PyPy).  If your
Python installation lacks readline (like CPython for Windows),
installing pyreadline (URL `https://ipython.org/pyreadline.html')
should suffice.

是不是 python-shell-completion-setup-code 里定义的这个函数 __PYTHON_EL_get_completions 提供了补全的选项?怎么从 elisp 调用这个 python 的函数把结果提供给 acm 后端? python-shell-completion-setup-code 的定义:

def __PYTHON_EL_get_completions(text):
    completions = []
    completer = None

    try:
        import readline

        try:
            import __builtin__
        except ImportError:
            # Python 3
            import builtins as __builtin__
        builtins = dir(__builtin__)

        is_ipython = ('__IPYTHON__' in builtins or
                      '__IPYTHON__active' in builtins)
        splits = text.split()
        is_module = splits and splits[0] in ('from', 'import')

        if is_ipython and is_module:
            from IPython.core.completerlib import module_completion
            completions = module_completion(text.strip())
        elif is_ipython and '__IP' in builtins:
            completions = __IP.complete(text)
        elif is_ipython and 'get_ipython' in builtins:
            completions = get_ipython().Completer.all_completions(text)
        else:
            # Try to reuse current completer.
            completer = readline.get_completer()
            if not completer:
                # importing rlcompleter sets the completer, use it as a
                # last resort to avoid breaking customizations.
                import rlcompleter
                completer = readline.get_completer()
            if getattr(completer, 'PYTHON_EL_WRAPPED', False):
                completer.print_mode = False
            i = 0
            while True:
                completion = completer(text, i)
                if not completion:
                    break
                i += 1
                completions.append(completion)
    except:
        pass
    finally:
        if getattr(completer, 'PYTHON_EL_WRAPPED', False):
            completer.print_mode = True
    return completions

可以模仿 acm-backend-search-words.el 后端

  1. lsp-bridge/search_file_words.py at 468b2526525cde2c2b0af6368c25e101b7a8ef67 · manateelazycat/lsp-bridge · GitHub 建立一个新的模块, 把你上面的代码加入线程中
  2. lsp-bridge/lsp-bridge.el at 468b2526525cde2c2b0af6368c25e101b7a8ef67 · manateelazycat/lsp-bridge · GitHub 文件改变的时候, 调用 search_words 后端, 只不过你要注意的是, 只在 python-shell mode 才启用
  3. lsp-bridge/search_file_words.py at 468b2526525cde2c2b0af6368c25e101b7a8ef67 · manateelazycat/lsp-bridge · GitHub 线程执行完以后, 调用 elisp 函数更新 search_words 后端的候选词
  4. lsp-bridge/lsp-bridge.el at 468b2526525cde2c2b0af6368c25e101b7a8ef67 · manateelazycat/lsp-bridge · GitHub lsp-bridge-try-completion 会尝试弹出补全窗口
  5. lsp-bridge/acm-backend-search-words.el at 468b2526525cde2c2b0af6368c25e101b7a8ef67 · manateelazycat/lsp-bridge · GitHub python-shell 的 acm 补全后端可以模仿 acm-backend-search-words.el , 基本上逻辑都是一样的

从 lsp-bridge 的线程兜一圈的目的是通过python线程来避免Emacs卡顿。

3 个赞