关于 Jupyter Console 没有自动提示 (补全) 的修复

现象描述

在命令行中通过 jupyter console 进入控制台, 发现输入命令时, 不会自动弹出提示. 比如:

a = 1  # 我在第一行输入了 `a = 1`
a  # 当输入第一个字母 "a" 时, 按理来说应该弹出补全提示 " = 1", 但是没有

解决方法

该操作需要修改 jupyter-console 的源文件:

  1. 源文件位于: {site-packages}/jupyter_console/ptshell.py

  2. 在第 47 行插入以下内容:

    from prompt_toolkit.auto_suggest import AutoSuggestFromHistory  # <--- HERE
    

    示意图:

    ...
    from prompt_toolkit import __version__ as ptk_version
    PTK3 = ptk_version.startswith('3.')
    
    if not PTK3:
        # use_ayncio_event_loop obsolete in PKT3
        from prompt_toolkit.eventloop.defaults import use_asyncio_event_loop
    
    from prompt_toolkit.auto_suggest import AutoSuggestFromHistory  # <--- HERE
    from prompt_toolkit.completion import Completer, Completion
    from prompt_toolkit.document import Document
    from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
    ...
    
  3. 在第 559 行插入以下内容:

    auto_suggest=AutoSuggestFromHistory(),  # <--------------------------- HERE
    

    示意图:

    ...
    # Tell prompt_toolkit to use the asyncio event loop.
    # Obsolete in prompt_toolkit.v3
    if not PTK3:
        use_asyncio_event_loop()
    
    self.pt_cli = PromptSession(
        auto_suggest=AutoSuggestFromHistory(),  # <----------------------- HERE
        message=(lambda: PygmentsTokens(self.get_prompt_tokens())),
        multiline=True,
        complete_style=self.pt_complete_style,
        editing_mode=editing_mode,
        lexer=PygmentsLexer(get_pygments_lexer(lexer)),
        prompt_continuation=(
            lambda width, lineno, is_soft_wrap: PygmentsTokens(
                self.get_continuation_tokens(width)
            )
        ),
        ...
    )
    ...
    

即可解决.

测试一下效果

该测试场景模拟了 A 窗口启动了 ipython 内核服务, B 窗口使用 jupyter console 连接该服务, 并获得完美的自动补全功能.

# test/ipython_service.py
from IPython import embed_kernel

def hello():
    print('hello world')

embed_kernel(user_ns={
    'a'    : 'alpha',
    'b'    : 'beta',
    'hello': hello,
})

打开一个命令行, 作为 A 窗口, 输入以下命令:

python test/ipython_service.py
# 控制台出现打印信息: 
#   to connect another client to this kernel, use:
#       --existing kernel-12345.json

再新开一个命令行, 作为 B 窗口, 输入以下命令:

jupyter console --existing 12345

尝试输入以下命令, 可以观察到自动补全的效果:

a, b
a + b  # 当输入 "a" 时, 会提示 ", b"
a, b, hello()  # 当输入 "a" 时, 会提示 " + b"; 继续输入 "a,", 会转为提示 " b"
...

exit()
#   exit(keep_kernel=False)  # 断开 B 且停止 A. (默认)
#   exit(keep_kernel=True)  # 断开 B 但不停止 A.

附录: 研究过程

prompt-toolkit 是一个 python 库, 用来给命令行 REPL 提供上下文感知, 自动补全, 历史记录等功能. 它是 ipython 和 jupyter 的重要依赖之一.

jupyter consoleipython 都会启动命令行界面, 但二者在体验上存在一些不同之处, 其中最显著的就是前者没有自动补全, 而后者有, 因此使用体验受到影响. 好在本文就是为了解决这个问题的.

观察 jupyter console -h 的参数, 有一个 --no-simple-prompt, 是用来启用 prompt-toolkit 的功能的.

按理来说 jupyter console 提供这个参数, 就应该能够使用自动补全功能, 但本人测试最新版 (截至 2023-07-01) 并没有作用, 个人怀疑是 jupyter 的一个 bug.

此外, 根据官方文档描述, 启动 jupyter console 的命令行界面后, 使用下面的命令也能激活自动补全功能:

通过阅读 jupyter_console 的源代码, 发现 jupyter_console/ptshell.py 文件确实少了 prompt_toolkit.auto_suggest.AutoSuggestFromHistory, 所以问题就好解决了, 把它作为参数传到 ZMQTerminalInteractiveShell.pt_cli 的实例化构造中即可.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要启用Jupyter Notebook的代码自动功能,需要进行以下几个步骤。 首先,您需要确保您的Jupyter Notebook版本是IPython 3.x或更高版本。在早期版本中,IPython还包括了notebook和qtconsole,但从IPython 4.0版本开始,它变得更加轻量化,只专注于交互式shell的功能。 然后,您需要修改Jupyter Notebook的默认配置文件。您可以使用以下命令在`~/.ipython/profile_default/`目录下生成`ipython_config.py`和`ipython_kernel_config.py`文件:`ipython profile create`。 在生成的配置文件中,您需要修改以下几行来启用自动功能: ``` ## Activate greedy completion # This will enable completion on elements of lists, results of function calls, etc., # but can be unsafe because the code is actually evaluated on TAB. c.Completer.greedy = True ## Experimental: restrict time (in milliseconds) during which Jedi can compute types. # Set to 0 to stop computing types. Non-zero value lower than 100ms may hurt performance # by preventing Jedi to build its cache. c.Completer.jedi_compute_type_timeout = 400 ## Experimental: Use Jedi to generate autocompletions. Off by default. c.Completer.use_jedi = True ``` 修改完成后,保存配置文件并重新启动Jupyter Notebook。现在,您应该能够在Notebook中使用自动功能了。 请注意,自动功能可能会稍微降低性能,尤其是当Jedi需要计算类型时。如果您对计算时间有限制,可以将`c.Completer.jedi_compute_type_timeout`的值设置为较小的非零值,以避免影响性能。 希望这些信息对您有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span><span class="em">4</span>

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值