Julia REPL

Julia 带有一个功能齐全的交互式命令行 REPL (读取-求值-打印循环),内置于 julia 可执行文件中。除了允许快速轻松地求值 Julia 语句之外,它还具有可搜索的历史记录、制表符补全、许多有用的按键绑定以及专门的帮助和 shell 模式。可以通过在不带任何参数的情况下调用 julia 或双击可执行文件来启动 REPL。

$ julia

               _
   _       _ _(_)_     |  Documentation: https://docs.julia-lang.cn
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.10.2 (2024-03-01)
 _/ |\__'_|_|_|\__'_|  |  Official https://julia-lang.cn/ release
|__/                   |


julia>

要退出交互式会话,请在空白行中键入 ^D(即控制键和 d 键一起按下),或者键入 exit(),然后按回车键或 Enter 键。REPL 会以横幅和 julia> 提示符迎接您。

不同的提示模式

Julia 模式

REPL 有五种主要的运行模式。第一种也是最常见的一种是 Julia 提示符。它是默认的运行模式;每行最初都以 julia> 开头。您可以在此输入 Julia 表达式。在输入完完整的表达式后按回车键或 Enter 键,将求值该条目并显示最后一个表达式的结果。

julia> string(1 + 2)
"3"

交互式工作中有一些有用的独特功能。除了显示结果外,REPL 还将结果绑定到变量 ans。行末的冒号可以作为抑制显示结果的标记。

julia> string(3 * 4);

julia> ans
"12"

在 Julia 模式下,REPL 支持称为“提示符粘贴”的功能。当您将以 julia> 开头的文本粘贴到 REPL 中时,此功能会激活。在这种情况下,只有以 julia> 开头的表达式(以及其他 REPL 模式提示符:shell>help?>pkg>)会被解析,而其他表达式会被删除。这使得您可以将从 REPL 会话中复制的文本块粘贴到 REPL 中,而无需擦除提示符和输出。此功能默认情况下处于启用状态,但可以通过 REPL.enable_promptpaste(::Bool) 随时禁用或启用。如果启用了此功能,您可以通过将本段文字前面的代码块直接粘贴到 REPL 中来尝试一下。此功能在标准 Windows 命令提示符中无法正常工作,因为它无法检测到粘贴操作何时发生。

对象使用 show 函数以特定的 IOContext 在 REPL 中打印。特别是,:limit 属性被设置为 true。在某些 show 方法中,其他属性可以接收一个默认值(如果尚未设置),例如 :compact。作为实验性功能,可以通过 Base.active_repl.options.iocontext 字典(将值与属性关联)来指定 REPL 使用的属性。例如

julia> rand(2, 2)
2×2 Array{Float64,2}:
 0.8833    0.329197
 0.719708  0.59114

julia> show(IOContext(stdout, :compact => false), "text/plain", rand(2, 2))
 0.43540323669187075  0.15759787870609387
 0.2540832269192739   0.4597637838786053
julia> Base.active_repl.options.iocontext[:compact] = false;

julia> rand(2, 2)
2×2 Array{Float64,2}:
 0.2083967319174056  0.13330606013126012
 0.6244375177790158  0.9777957560761545

为了在启动时自动定义此字典的值,可以在 ~/.julia/config/startup.jl 文件中使用 atreplinit 函数,例如

atreplinit() do repl
    repl.options.iocontext[:compact] = false
end

帮助模式

当光标位于行首时,可以通过键入 ? 将提示符更改为帮助模式。Julia 会尝试打印任何在帮助模式下输入的内容的帮助或文档。

julia> ? # upon typing ?, the prompt changes (in place) to: help?>

help?> string
search: string String Cstring Cwstring RevString randstring bytestring SubString

  string(xs...)

  Create a string from any values using the print function.

宏、类型和变量也可以查询

help?> @time
  @time

  A macro to execute an expression, printing the time it took to execute, the number of allocations,
  and the total number of bytes its execution caused to be allocated, before returning the value of the
  expression.

  See also @timev, @timed, @elapsed, and @allocated.

help?> Int32
search: Int32 UInt32

  Int32 <: Signed

  32-bit signed integer type.

字符串或正则表达式字面量使用 apropos 搜索所有文档字符串

help?> "aprop"
REPL.stripmd
Base.Docs.apropos

help?> r"ap..p"
Base.:∘
Base.shell_escape_posixly
Distributed.CachingPool
REPL.stripmd
Base.Docs.apropos

帮助模式的另一个功能是能够访问扩展的文档字符串。您可以通过键入 ??Print 而不是 ?Print 来实现,这将显示源代码文档中的 # Extended help 部分。

可以通过在行首按退格键退出帮助模式。

shell 模式

正如帮助模式对快速访问文档很有用一样,另一个常见的任务是使用系统 shell 执行系统命令。正如在行首输入 ? 会进入帮助模式一样,分号 (;) 会进入 shell 模式。可以通过在行首按退格键退出该模式。

julia> ; # upon typing ;, the prompt changes (in place) to: shell>

shell> echo hello
hello
注意

对于 Windows 用户,Julia 的 shell 模式不会公开 Windows shell 命令。因此,这将失败

julia> ; # upon typing ;, the prompt changes (in place) to: shell>

shell> dir
ERROR: IOError: could not spawn `dir`: no such file or directory (ENOENT)
Stacktrace!
.......

但是,您可以通过以下方式访问 PowerShell

julia> ; # upon typing ;, the prompt changes (in place) to: shell>

shell> powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\elm>

...以及以下方式访问 cmd.exe(参见 dir 命令)

julia> ; # upon typing ;, the prompt changes (in place) to: shell>

shell> cmd
Microsoft Windows [version 10.0.17763.973]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\Users\elm>dir
 Volume in drive C has no label
 Volume Serial Number is 1643-0CD7
  Directory of C:\Users\elm

29/01/2020  22:15    <DIR>          .
29/01/2020  22:15    <DIR>          ..
02/02/2020  08:06    <DIR>          .atom

Pkg 模式

包管理器模式接受用于加载和更新包的专门命令。可以通过在 Julia REPL 提示符下按 ] 键进入,并通过按 CTRL-C 或在行首按退格键退出。此模式的提示符为 pkg>。它支持自己的帮助模式,可以通过在 pkg> 提示符的行首按 ? 键进入。包管理器模式在 Pkg 手册中有所介绍,该手册位于 https://julialang.github.io/Pkg.jl/v1/

搜索模式

在以上所有模式中,执行的行都会保存到一个历史记录文件中,该文件可以搜索。要启动对之前历史记录的增量搜索,请键入 ^R(即控制键和 r 键一起按下)。提示符将更改为 (reverse-i-search)`':,并且随着您键入,搜索查询将显示在引号中。与查询匹配的最新的结果将随着键入更多内容而动态更新到冒号的右侧。要使用相同的查询查找更旧的结果,只需再次键入 ^R

正如 ^R 是反向搜索,^S 是正向搜索,提示符为 (i-search)`':。这两个可以一起使用,分别用于在匹配结果中向前或向后移动。

在 Julia REPL 中执行的所有命令都会记录到 ~/.julia/logs/repl_history.jl 中,以及执行时间戳和您当时所在的 REPL 模式。搜索模式会查询此日志文件,以查找您之前运行的命令。这可以通过在启动时将 --history-file=no 标志传递给 Julia 来禁用。

按键绑定

Julia 的 REPL 充分利用了按键绑定。前面已经介绍了一些控制键绑定(^D 用于退出,^R^S 用于搜索),但还有更多。除了控制键之外,还有元键绑定。这些按键绑定因平台而异,但大多数终端默认使用 Alt 或 Option 键与另一个键一起按下以发送元键(或可以配置为这样做),或者先按下 Esc 键,然后再按下另一个键。

按键绑定描述
程序控制
^D退出(当缓冲区为空时)
^C中断或取消
^L清除控制台屏幕
Return/Enter,^J新行,如果完整则执行
元-Return/Enter插入新行而不执行它
?;进入帮助或 shell 模式(当在行的开头时)
^R^S增量历史搜索,如上所述
光标移动
右箭头,^F向右移动一个字符
左箭头,^B向左移动一个字符
ctrl-右,meta-F向右移动一个单词
ctrl-左,meta-B向左移动一个单词
Home,^A移动到行的开头
End,^E移动到行的结尾
上箭头,^P向上移动一行(或更改为与光标之前的文本匹配的先前历史条目)
下箭头,^N向下移动一行(或更改为与光标之前的文本匹配的下一个历史条目)
Shift-箭头键根据箭头键的方向移动光标,同时激活区域(“shift 选择”)
Page-up,meta-P更改为先前的历史条目
Page-down,meta-N更改为下一个历史条目
meta-<更改为第一个历史条目(如果它在历史记录中当前位置之前,则为当前会话的第一个历史条目)
meta->更改为最后一个历史条目
^-Space在编辑区域中设置“标记”(如果区域处于活动状态,则取消激活区域)
^-Space ^-Space在编辑区域中设置“标记”并使区域“活动”,即突出显示
^G取消激活区域(即使其不突出显示)
^X^X将当前位置与标记交换
编辑
Backspace,^H删除前一个字符,或者当它处于活动状态时删除整个区域
Delete,^D向前删除一个字符(当缓冲区有文本时)
meta-Backspace删除前一个单词
meta-d向前删除下一个单词
^W删除先前文本,直到最近的空格
meta-w将当前区域复制到 kill ring 中
meta-W“杀死”当前区域,并将文本放置在 kill ring 中
^U“杀死”到行的开头,并将文本放置在 kill ring 中
^K“杀死”到行的结尾,并将文本放置在 kill ring 中
^Y“粘贴”插入 kill ring 中的文本
meta-y用 kill ring 中的较旧条目替换先前粘贴的文本
^T转置光标周围的字符
meta-上箭头将当前行与上面的行转置
meta-下箭头将当前行与下面的行转置
meta-u将下一个单词更改为大写
meta-c将下一个单词更改为标题大小写
meta-l将下一个单词更改为小写
^/, ^_撤消上一步编辑操作
^Q在 REPL 中写入一个数字,然后按 ^Q 以在相应的堆栈帧或方法中打开编辑器
meta-左箭头向左缩进当前行
meta-右箭头向右缩进当前行
meta-.插入先前历史条目中的最后一个单词
meta-e在编辑器中编辑当前输入

自定义按键绑定

可以通过将字典传递给 REPL.setup_interface 来完全自定义 Julia 的 REPL 按键绑定以满足用户的偏好。此字典的键可以是字符或字符串。键 '*' 指的是默认操作。Control 加字符 x 绑定用 "^x" 表示。Meta 加 x 可以写成 "\\M-x""\ex",Control 加 x 可以写成 "\\C-x""^x"。自定义键映射的值必须为 nothing(表示应忽略输入)或接受签名 (PromptState, AbstractREPL, Char) 的函数。REPL.setup_interface 函数必须在 REPL 初始化之前调用,方法是使用 atreplinit 注册操作。例如,要将向上和向下箭头键绑定到在不进行前缀搜索的情况下浏览历史记录,可以将以下代码放入 ~/.julia/config/startup.jl

import REPL
import REPL.LineEdit

const mykeys = Dict{Any,Any}(
    # Up Arrow
    "\e[A" => (s,o...)->(LineEdit.edit_move_up(s) || LineEdit.history_prev(s, LineEdit.mode(s).hist)),
    # Down Arrow
    "\e[B" => (s,o...)->(LineEdit.edit_move_down(s) || LineEdit.history_next(s, LineEdit.mode(s).hist))
)

function customize_keys(repl)
    repl.interface = REPL.setup_interface(repl; extra_repl_keymap = mykeys)
end

atreplinit(customize_keys)

用户应参考 LineEdit.jl 以发现按键输入上可用的操作。

Tab 完成

在 REPL 的 Julian 和帮助模式中,都可以输入函数或类型的头几个字符,然后按 Tab 键以获取所有匹配项的列表

julia> x[TAB]
julia> xor

在某些情况下,它只完成名称的一部分,直到下一个歧义

julia> mapf[TAB]
julia> mapfold

如果再次按下 Tab 键,则会得到可能完成此操作的项目的列表

julia> mapfold[TAB]
mapfoldl mapfoldr

与 REPL 的其他组件一样,搜索区分大小写

julia> stri[TAB]
stride     strides     string      strip

julia> Stri[TAB]
StridedArray    StridedMatrix    StridedVecOrMat  StridedVector    String

Tab 键还可以用来用其 Unicode 等效项替换 LaTeX 数学符号,并获取 LaTeX 匹配项的列表

julia> \pi[TAB]
julia> π
π = 3.1415926535897...

julia> e\_1[TAB] = [1,0]
julia> e₁ = [1,0]
2-element Array{Int64,1}:
 1
 0

julia> e\^1[TAB] = [1 0]
julia> e¹ = [1 0]
1×2 Array{Int64,2}:
 1  0

julia> \sqrt[TAB]2     # √ is equivalent to the sqrt function
julia> √2
1.4142135623730951

julia> \hbar[TAB](h) = h / 2\pi[TAB]
julia> ħ(h) = h / 2π
ħ (generic function with 1 method)

julia> \h[TAB]
\hat              \hermitconjmatrix  \hkswarow          \hrectangle
\hatapprox        \hexagon           \hookleftarrow     \hrectangleblack
\hbar             \hexagonblack      \hookrightarrow    \hslash
\heartsuit        \hksearow          \house             \hspace

julia> α="\alpha[TAB]"   # LaTeX completion also works in strings
julia> α="α"

可以在手册的 Unicode 输入 部分找到 Tab 完成的完整列表。

路径完成适用于字符串和 julia 的 shell 模式

julia> path="/[TAB]"
.dockerenv  .juliabox/   boot/        etc/         lib/         media/       opt/         root/        sbin/        sys/         usr/
.dockerinit bin/         dev/         home/        lib64/       mnt/         proc/        run/         srv/         tmp/         var/
shell> /[TAB]
.dockerenv  .juliabox/   boot/        etc/         lib/         media/       opt/         root/        sbin/        sys/         usr/
.dockerinit bin/         dev/         home/        lib64/       mnt/         proc/        run/         srv/         tmp/         var/

字典键也可以进行 Tab 完成

julia> foo = Dict("qwer1"=>1, "qwer2"=>2, "asdf"=>3)
Dict{String,Int64} with 3 entries:
  "qwer2" => 2
  "asdf"  => 3
  "qwer1" => 1

julia> foo["q[TAB]

"qwer1" "qwer2"
julia> foo["qwer

Tab 完成还可以帮助完成字段

julia> x = 3 + 4im;

julia> x.[TAB][TAB]
im re

julia> import UUIDs

julia> UUIDs.uuid[TAB][TAB]
uuid1        uuid4         uuid5        uuid_version

函数输出的字段也可以完成

julia> split("","")[1].[TAB]
lastindex  offset  string

函数输出的字段完成使用类型推断,并且只有在函数类型稳定时才能建议字段。

Tab 完成可以帮助调查与输入参数匹配的可用方法

julia> max([TAB] # All methods are displayed, not shown here due to size of the list

julia> max([1, 2], [TAB] # All methods where `Vector{Int}` matches as first argument
max(x, y) in Base at operators.jl:215
max(a, b, c, xs...) in Base at operators.jl:281

julia> max([1, 2], max(1, 2), [TAB] # All methods matching the arguments.
max(x, y) in Base at operators.jl:215
max(a, b, c, xs...) in Base at operators.jl:281

关键字也会在 ; 之后的建议方法中显示,请参见下面一行,其中 limitkeepempty 是关键字参数

julia> split("1 1 1", [TAB]
split(str::AbstractString; limit, keepempty) in Base at strings/util.jl:302
split(str::T, splitter; limit, keepempty) where T<:AbstractString in Base at strings/util.jl:277

方法的完成使用类型推断,因此可以查看参数是否匹配,即使参数是函数的输出。函数需要是类型稳定的,才能让完成能够删除不匹配的方法。

如果您想知道哪些方法可以与特定参数类型一起使用,请使用 ? 作为函数名称。这展示了在 InteractiveUtils 中查找接受单个字符串的函数的示例

julia> InteractiveUtils.?("somefile")[TAB]
edit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197
less(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266

这列出了 InteractiveUtils 模块中可以对字符串调用的方法。默认情况下,这排除了所有参数都类型化为 Any 的方法,但您也可以通过按住 SHIFT-TAB 而不是 TAB 来查看这些方法

julia> InteractiveUtils.?("somefile")[SHIFT-TAB]
apropos(string) in REPL at REPL/src/docview.jl:796
clipboard(x) in InteractiveUtils at InteractiveUtils/src/clipboard.jl:64
code_llvm(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:221
code_native(f) in InteractiveUtils at InteractiveUtils/src/codeview.jl:243
edit(path::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:197
edit(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:225
eval(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3
include(x) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:3
less(file::AbstractString) in InteractiveUtils at InteractiveUtils/src/editless.jl:266
less(f) in InteractiveUtils at InteractiveUtils/src/editless.jl:274
report_bug(kind) in InteractiveUtils at InteractiveUtils/src/InteractiveUtils.jl:391
separate_kwargs(args...; kwargs...) in InteractiveUtils at InteractiveUtils/src/macros.jl:7

您也可以使用 ?("somefile")[TAB] 并查看所有模块,但方法列表可能很长。

通过省略关闭括号,您可以包含可能需要其他参数的函数

julia> using Mmap

help?> Mmap.?("file",[TAB]
Mmap.Anonymous(name::String, readonly::Bool, create::Bool) in Mmap at Mmap/src/Mmap.jl:16
mmap(file::AbstractString) in Mmap at Mmap/src/Mmap.jl:245
mmap(file::AbstractString, ::Type{T}) where T<:Array in Mmap at Mmap/src/Mmap.jl:245
mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245
mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:Array, N} in Mmap at Mmap/src/Mmap.jl:245
mmap(file::AbstractString, ::Type{T}, len::Integer) where T<:Array in Mmap at Mmap/src/Mmap.jl:251
mmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:Array in Mmap at Mmap/src/Mmap.jl:251
mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316
mmap(file::AbstractString, ::Type{T}, dims::Tuple{Vararg{Integer, N}}, offset::Integer; grow, shared) where {T<:BitArray, N} in Mmap at Mmap/src/Mmap.jl:316
mmap(file::AbstractString, ::Type{T}, len::Integer) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322
mmap(file::AbstractString, ::Type{T}, len::Integer, offset::Integer; grow, shared) where T<:BitArray in Mmap at Mmap/src/Mmap.jl:322

自定义颜色

也可以自定义 Julia 和 REPL 使用的颜色。要更改 Julia 提示符的颜色,可以在您的 ~/.julia/config/startup.jl 文件中添加类似以下内容,该文件应放置在您的主目录中

function customize_colors(repl)
    repl.prompt_color = Base.text_colors[:cyan]
end

atreplinit(customize_colors)

可在 REPL 的帮助模式中键入 Base.text_colors 查看可用的颜色键。此外,对于具有 256 色支持的终端,可以使用 0 到 255 的整数作为颜色键。

您还可以更改帮助和 shell 提示符以及输入和答案文本的颜色,方法是在上面的 customize_colors 函数中设置 repl 的相应字段(分别是 help_colorshell_colorinput_coloranswer_color)。对于后两者,请确保 envcolors 字段也设置为 false。

还可以通过使用 Base.text_colors[:bold] 作为颜色来应用粗体格式。例如,要以粗体字体打印答案,可以使用以下内容作为 ~/.julia/config/startup.jl

function customize_colors(repl)
    repl.envcolors = false
    repl.answer_color = Base.text_colors[:bold]
end

atreplinit(customize_colors)

您还可以自定义用于渲染警告和信息消息的颜色,方法是设置相应的环境变量。例如,要分别以洋红色、黄色和青色渲染错误、警告和信息消息,可以在您的 ~/.julia/config/startup.jl 文件中添加以下内容

ENV["JULIA_ERROR_COLOR"] = :magenta
ENV["JULIA_WARN_COLOR"] = :yellow
ENV["JULIA_INFO_COLOR"] = :cyan

更改 REPL 上处于活动状态的上下文模块

在 REPL 中输入表达式时,它们默认情况下在 Main 模块中进行评估;

julia> @__MODULE__
Main

可以通过函数 REPL.activate(m)(其中 mModule)或在 REPL 中键入模块并按 Alt-m 按键绑定(光标必须位于模块名称上)来更改此上下文模块。活动模块显示在提示符中

julia> using REPL

julia> REPL.activate(Base)

(Base) julia> @__MODULE__
Base

(Base) julia> using REPL # Need to load REPL into Base module to use it

(Base) julia> REPL.activate(Main)

julia>

julia> Core<Alt-m> # using the keybinding to change module

(Core) julia>

(Core) julia> Main<Alt-m> # going back to Main via keybinding

julia>

采用可选模块参数的函数通常默认为 REPL 上下文模块。例如,调用 varinfo() 将显示当前活动模块的变量

julia> module CustomMod
           export var, f
           var = 1
           f(x) = x^2
       end;

julia> REPL.activate(CustomMod)

(Main.CustomMod) julia> varinfo()
  name         size summary
  ––––––––– ––––––– ––––––––––––––––––––––––––––––––––
  CustomMod         Module
  f         0 bytes f (generic function with 1 method)
  var       8 bytes Int64

编号提示

可以获得类似于 IPython REPL 和 Mathematica 笔记本的界面,其中包含编号的输入提示符和输出前缀。这可以通过调用 REPL.numbered_prompt!() 来完成。如果您希望在启动时启用此功能,请添加

atreplinit() do repl
    @eval import REPL
    if !isdefined(repl, :interface)
        repl.interface = REPL.setup_interface(repl)
    end
    REPL.numbered_prompt!(repl)
end

到您的 startup.jl 文件中。在编号提示符中,变量 Out[n](其中 n 是一个整数)可以用来引用之前的结果

In [1]: 5 + 3
Out[1]: 8

In [2]: Out[1] + 5
Out[2]: 13

In [3]: Out
Out[3]: Dict{Int64, Any} with 2 entries:
  2 => 13
  1 => 8
注意

由于之前所有 REPL 评估的输出都保存在 Out 变量中,因此如果返回许多像数组这样的大型内存中对象,则应小心,因为只要 Out 中存在对它们的引用,它们就会受到垃圾回收的保护。如果您需要删除对 Out 中对象的引用,可以使用 empty!(Out) 清除它存储的整个历史记录,或者使用 Out[n] = nothing 清除单个条目。

TerminalMenus

TerminalMenus 是 Julia REPL 的一个子模块,它可以在终端中启用小型、低调的交互式菜单。

示例

import REPL
using REPL.TerminalMenus

options = ["apple", "orange", "grape", "strawberry",
            "blueberry", "peach", "lemon", "lime"]

单选菜单

RadioMenu 允许用户从列表中选择一个选项。request 函数将显示交互式菜单并返回所选选项的索引。如果用户按下 'q' 或 ctrl-crequest 将返回 -1

# `pagesize` is the number of items to be displayed at a time.
#  The UI will scroll if the number of options is greater
#   than the `pagesize`
menu = RadioMenu(options, pagesize=4)

# `request` displays the menu and returns the index after the
#   user has selected a choice
choice = request("Choose your favorite fruit:", menu)

if choice != -1
    println("Your favorite fruit is ", options[choice], "!")
else
    println("Menu canceled.")
end

输出

Choose your favorite fruit:
^  grape
   strawberry
 > blueberry
v  peach
Your favorite fruit is blueberry!

MultiSelectMenu

MultiSelectMenu 允许用户从列表中选择多个选项。

# here we use the default `pagesize` 10
menu = MultiSelectMenu(options)

# `request` returns a `Set` of selected indices
# if the menu us canceled (ctrl-c or q), return an empty set
choices = request("Select the fruits you like:", menu)

if length(choices) > 0
    println("You like the following fruits:")
    for i in choices
        println("  - ", options[i])
    end
else
    println("Menu canceled.")
end

输出

Select the fruits you like:
[press: Enter=toggle, a=all, n=none, d=done, q=abort]
   [ ] apple
 > [X] orange
   [X] grape
   [ ] strawberry
   [ ] blueberry
   [X] peach
   [ ] lemon
   [ ] lime
You like the following fruits:
  - orange
  - grape
  - peach

自定义/配置

ConfiguredMenu 子类型

从 Julia 1.6 开始,推荐使用构造函数来配置菜单。例如,默认的多选菜单

julia> menu = MultiSelectMenu(options, pagesize=5);

julia> request(menu) # ASCII is used by default
[press: Enter=toggle, a=all, n=none, d=done, q=abort]
   [ ] apple
   [X] orange
   [ ] grape
 > [X] strawberry
v  [ ] blueberry

可以用 Unicode 选择和导航字符渲染为

julia> menu = MultiSelectMenu(options, pagesize=5, charset=:unicode);

julia> request(menu)
[press: Enter=toggle, a=all, n=none, d=done, q=abort]
   ⬚ apple
   ✓ orange
   ⬚ grape
 → ✓ strawberry
↓  ⬚ blueberry

还可以进行更细粒度的配置

julia> menu = MultiSelectMenu(options, pagesize=5, charset=:unicode, checked="YEP!", unchecked="NOPE", cursor='⧐');

julia> request(menu)
julia> request(menu)
[press: Enter=toggle, a=all, n=none, d=done, q=abort]
   NOPE apple
   YEP! orange
   NOPE grape
 ⧐ YEP! strawberry
↓  NOPE blueberry

除了整体的 charset 选项外,对于 RadioMenu,可配置的选项有

  • cursor::Char='>'|'→':用于光标的字符
  • up_arrow::Char='^'|'↑':用于向上箭头字符
  • down_arrow::Char='v'|'↓':用于向下箭头字符
  • updown_arrow::Char='I'|'↕':用于单行页面中的向上/向下箭头字符
  • scroll_wrap::Bool=false:可选地在菜单的开头/结尾进行环绕
  • ctrl_c_interrupt::Bool=true:如果为 false,则在 ^C 时返回空,如果为 true,则在 ^C 时抛出 InterruptException()

MultiSelectMenu 添加了

  • checked::String="[X]"|"✓":用于选中状态的字符串
  • unchecked::String="[ ]"|"⬚"):用于未选中状态的字符串

您可以创建自己的新菜单类型。从 TerminalMenus.ConfiguredMenu 派生的类型在构造时配置菜单选项。

传统接口

在 Julia 1.6 之前,并且仍然在整个 Julia 1.x 中得到支持,也可以通过调用 TerminalMenus.config() 来配置菜单。

参考

REPL

Base.atreplinit函数
atreplinit(f)

注册一个单参数函数,在交互式会话中初始化 REPL 接口之前调用;这对于自定义接口很有用。f 的参数是 REPL 对象。此函数应从 .julia/config/startup.jl 初始化文件内调用。

来源

TerminalMenus

REPL.TerminalMenus.RadioMenu类型
RadioMenu

允许用户从列表中选择单个选项的菜单。

示例输出

julia> request(RadioMenu(options, pagesize=4))
Choose your favorite fruit:
^  grape
   strawberry
 > blueberry
v  peach
Your favorite fruit is blueberry!
REPL.TerminalMenus.MultiSelectMenu类型
MultiSelectMenu

允许用户从列表中选择多个选项的菜单。

示例输出

julia> request(MultiSelectMenu(options))
Select the fruits you like:
[press: Enter=toggle, a=all, n=none, d=done, q=abort]
   [ ] apple
 > [X] orange
   [X] grape
   [ ] strawberry
   [ ] blueberry
   [X] peach
   [ ] lemon
   [ ] lime
You like the following fruits:
  - orange
  - grape
  - peach

配置

REPL.TerminalMenus.Config类型
Config(; scroll_wrap=false, ctrl_c_interrupt=true, charset=:ascii, cursor::Char, up_arrow::Char, down_arrow::Char)

通过关键字参数配置选择菜单的行为

  • scroll_wrap,如果为 true,则在滚动到第一个条目以上或最后一个条目以下时,菜单会环绕
  • ctrl_c_interrupt,如果为 true,则在用户在菜单选择期间按下 Ctrl-C 时抛出 InterruptException。如果为 falseTerminalMenus.request 将返回来自 TerminalMenus.selected 的默认结果。
  • charset 影响 cursorup_arrowdown_arrow 的默认值,可以是 :ascii:unicode
  • cursor 是用于指示通过按下“Enter”键选择的选项的字符。默认值为 '>' 或 '→',取决于 charset
  • up_arrow 是当显示不包含第一个条目时打印的字符。默认值为 '^' 或 '↑',取决于 charset
  • down_arrow 是当显示不包含最后一个条目时打印的字符。默认值为 'v' 或 '↓',取决于 charset

ConfiguredMenu 的子类型将根据需要自动打印 cursorup_arrowdown_arrow,您的 writeline 方法不应打印它们。

Julia 1.6

Config 可用自 Julia 1.6。在旧版本中使用全局 CONFIG

REPL.TerminalMenus.MultiSelectConfig类型
MultiSelectConfig(; charset=:ascii, checked::String, unchecked::String, kwargs...)

通过关键字参数配置多选菜单的行为

  • checked 是当选项被选中时打印的字符串。默认值为 "[X]" 或 "✓",取决于 charset
  • unchecked 是当选项未被选中时打印的字符串。默认值为 "[ ]" 或 "⬚",取决于 charset

所有其他关键字参数的描述与 TerminalMenus.Config 相同。checkedunchecked 不会自动打印,应由您的 writeline 方法打印。

Julia 1.6

MultiSelectConfig 可用自 Julia 1.6。在旧版本中使用全局 CONFIG

REPL.TerminalMenus.config函数
config( <see arguments> )

仅关键字函数用于配置全局菜单参数

参数

  • charset::Symbol=:na:要使用的 UI 字符(:ascii:unicode);被其他参数覆盖
  • cursor::Char='>'|'→':用于光标的字符
  • up_arrow::Char='^'|'↑':用于向上箭头字符
  • down_arrow::Char='v'|'↓':用于向下箭头字符
  • checked::String="[X]"|"✓":用于选中状态的字符串
  • unchecked::String="[ ]"|"⬚"):用于未选中状态的字符串
  • scroll::Symbol=:nowrap:如果为 :wrap,则将光标环绕顶部和底部,如果为 :nowrap,则不环绕光标
  • supress_output::Bool=false:忽略的传统参数,而是将 suppress_output 作为关键字参数传递给 request
  • ctrl_c_interrupt::Bool=true:如果为 false,则在 ^C 时返回空,如果为 true,则在 ^C 时抛出 InterruptException()
Julia 1.6

从 Julia 1.6 开始,config 已被弃用。请改用 ConfigMultiSelectConfig

用户交互

REPL.TerminalMenus.request函数
request(m::AbstractMenu; cursor=1)

显示菜单并进入交互模式。cursor 指示用于初始光标位置的项目编号。cursor 可以是 IntRefValue{Int}。后者对于从外部观察和控制光标位置很有用。

返回 selected(m)

Julia 1.6

cursor 参数需要 Julia 1.6 或更高版本。

request([term,] msg::AbstractString, m::AbstractMenu)

println(msg); request(m) 的简写。

AbstractMenu 扩展接口

AbstractMenu 的任何子类型都必须是可变的,并且必须包含字段 pagesize::Intpageoffset::Int。任何子类型还必须实现以下函数

REPL.TerminalMenus.pick函数
pick(m::AbstractMenu, cursor::Int)

定义用户在菜单打开时按下 Enter 键时会发生什么。如果返回 truerequest() 将退出。cursor 为选择的索引位置。

REPL.TerminalMenus.cancel函数
cancel(m::AbstractMenu)

定义用户取消 ('q' 或 ctrl-c) 菜单时会发生什么。request() 在调用此函数后将始终退出。

REPL.TerminalMenus.writeline函数
writeline(buf::IO, m::AbstractMenu, idx::Int, iscursor::Bool)

将索引为 idx 的选项写入 bufiscursor,如果为 true,则表示此项位于当前光标位置(按下“Enter”键将选择的项)。

如果 m 是一个 ConfiguredMenuTerminalMenus 将打印光标指示器。否则,调用方应处理此类打印。

Julia 1.6

writeline 需要 Julia 1.6 或更高版本。

在旧版本的 Julia 中,此函数为 writeLine(buf::IO, m::AbstractMenu, idx, iscursor::Bool),并且假设 m 未配置。可以选择和光标指示器从 TerminalMenus.CONFIG 获取。

此旧函数在所有 Julia 1.x 版本中都受支持,但在 Julia 2.0 中将被删除。

它还必须实现 optionsnumoptions

REPL.TerminalMenus.options函数
options(m::AbstractMenu)

返回要在当前页面中显示为选项的字符串列表。

或者,实现 numoptions,在这种情况下,options 不需要。

REPL.TerminalMenus.numoptions函数
numoptions(m::AbstractMenu) -> Int

返回菜单 m 中的选项数量。默认为 length(options(m))

Julia 1.6

此函数需要 Julia 1.6 或更高版本。

如果子类型没有名为 selected 的字段,它还必须实现

REPL.TerminalMenus.selected函数
selected(m::AbstractMenu)

返回有关用户选择选项的信息。默认情况下,它返回 m.selected

以下是可选的,但可以允许进一步自定义

REPL.TerminalMenus.header函数
header(m::AbstractMenu) -> String

返回要在菜单上方打印的标题字符串。默认为 ""。