Документация Engee

REPL Julia

В состав Julia входит полнофункциональная интерактивная среда командной строки REPL (read-eval-print loop, цикл «чтение — вычисление — вывод»), которая встроена в исполняемый файл julia. Она не только позволяет быстро и легко выполнять команды Julia, но и предоставляет историю с возможностью поиска, автозавершение клавишей TAB, много полезных привязок клавиш, а также специальные режимы справки и оболочки. Чтобы запустить REPL, достаточно вызвать julia без аргументов или дважды щелкнуть по исполняемому файлу:

$ julia

               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.9.3
 _/ |\__'_|_|_|\__'_|  |
|__/                   |


julia>

Для выхода из интерактивного сеанса используйте сочетание ^D (удерживая клавишу CONTROL, нажмите клавишу d в пустой строке) или введите exit(), а затем нажмите клавишу RETURN или ВВОД. Появится баннер с приветствием и приглашение к вводу julia>.

Различные режимы командной строки

Режим Julia

REPL может работать в пяти основных режимах. Первый и наиболее часто используемый — это командная строка Julia. Это режим работы по умолчанию; каждая новая строка изначально начинается с приглашения julia>. После него можно вводить выражения Julia. При нажатии клавиши RETURN или ВВОД после ввода выражения оно вычисляется, и выводится результат последнего выражения.

julia> string(1 + 2)
"3"

В интерактивном режиме работы доступен ряд полезных возможностей. Помимо вывода результата, REPL также привязывает его к переменной ans. Чтобы результат не выводился, в конце строки можно поставить точку с запятой.

julia> string(3 * 4);

julia> ans
"12"

В режиме Julia среда REPL поддерживает возможность, которая называется вставкой командной строки. Она активируется при вставке в REPL текста, который начинается с julia>. В этом случае анализируются только выражения, начинающиеся с julia>, а остальные удаляются. Это позволяет вставить фрагмент кода, скопированный из сеанса REPL, не убирая из него приглашения к вводу и выходные данные. Данная функция включена по умолчанию, но ее можно отключать и снова включать по желанию с помощью REPL.enable_promptpaste(::Bool). Если она включена, ее можно испытать, вставив блок кода, приведенный перед данным абзацем, непосредственно в REPL. Эта функция не работает в стандартной командной строке Windows из-за невозможности определить событие вставки.

Объекты выводятся в REPL с использованием функции show с определенным контекстом IOContext. В частности, атрибут :limit имеет значение true. Другие атрибуты, например :compact, могут получать в определенных методах show значения по умолчанию, если они еще не заданы. В качестве экспериментальной функции можно указывать атрибуты, используемые REPL, посредством словаря Base.active_repl.options.iocontext (связывая значения с атрибутами). Пример:

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

Для автоматического определения значений этого словаря при запуске можно использовать функцию atreplinit в файле ~/.julia/config/startup.jl, например:

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

Режим справки

Когда курсор находится в начале строки, командную строку можно перевести в режим справки, введя символ ?. Julia попытается вывести справку или документацию по любому запросу, введенному в режиме справки:

julia> ? # после ввода символа «?» приглашение меняется (моментально) на 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.

При вводе строки или регулярного выражения выполняется поиск по всем строкам docstring с помощью apropos:

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

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

Еще одна особенность режима справки — возможность доступа к расширенным строкам docstring. Для этого следует ввести, например, ??Print вместо ?Print, в результате чего будет выведен раздел # Extended help из документации к исходному коду.

Для выхода из режима справки нажмите клавишу BACKSPACE в начале строки.

Режим оболочки

Режим справки полезен для быстрого доступа к документации, однако еще одной распространенной задачей является использование системной оболочки для выполнения системных команд. Так же как при вводе символа ?, в начале строки происходит переход в режим справки, при вводе точки с запятой (;) активируется режим оболочки. Для выхода из него также следует нажать клавишу BACKSPACE в начале строки.

julia> ; # при вводе ;, приглашение к вводу меняется на shell>

shell> echo hello
hello

В Windows в режиме оболочки Julia команды оболочки Windows недоступны. Поэтому следующая команда завершится ошибкой:

julia> ; # при вводе ;, приглашение к вводу меняется на shell>

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

Однако вы можете получить доступ к PowerShell следующим образом:

julia> ; # при вводе ;, приглашение к вводу меняется на shell>

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

или к cmd.exe следующим образом (см. команду dir):

julia> ; # при вводе ;, приглашение к вводу меняется на 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

В режиме диспетчера пакетов можно вводить специальные команды для загрузки и обновления пакетов. Для перехода в этом режим следует нажать клавишу ] в командной строке REPL Julia, а для выхода из него — сочетание клавиш CTRL+C или клавишу BACKSPACE в начале строки. Приглашение к вводу в этом режиме имеет вид pkg>. В нем имеется собственный режим справки, для перехода в который нужно нажать клавишу ? в начале строки с приглашением pkg>. Режим диспетчера пакетов задокументирован в руководстве Pkg, доступном на странице https://julialang.github.io/Pkg.jl/v1/.

Режимы поиска

Во всех перечисленных выше режимах выполняемые строки сохраняются в файле истории, по которому можно выполнять поиск. Чтобы инициировать инкрементный поиск по предыдущей истории, нажмите сочетание клавиш ^R (удерживая нажатой клавишу CONTROL, нажмите клавишу r). Приглашение к вводу поменяется на (reverse-i-search)’:, and as you type the search query will appear in the quotes. The most recent result that matches the query will dynamically update to the right of the colon as more is typed. To find an older result using the same query, simply type ^R.

Так же как при нажатии ^R происходит поиск в обратном направлении, нажатие ^S активирует поиск в прямом направлении. Приглашение к вводу при этом принимает вид (i-search)’:. Эти два режима можно использовать в сочетании друг с другом для перехода по предыдущим или следующим результатам соответственно.

Все команды, выполненные в REPL Julia, регистрируются в файле ~/.julia/logs/repl_history.jl вместе с меткой времени выполнения и текущим режимом REPL. В режиме поиска производятся запросы к этому файлу журнала для поиска ранее выполненных команд. Эту функцию можно отключить при запуске, передав в Julia флаг --history-file=no.

Привязки клавиш

В REPL Julia широко применяются привязки клавиш. Несколько привязок с клавишей CONTROL уже были представлены выше (^D для выхода, ^R и ^S для поиска), но есть и множество других. Помимо привязок с клавишей CONTROL, есть также привязки с метаклавишей. Метаклавиша зависит от платформы, но в большинстве терминалов по умолчанию следует удерживать нажатой клавишу ALT или OPTION, а затем нажать нужную клавишу (либо можно настроить такой вариант ввода), или следует нажать клавишу ESC, а затем нужную клавишу.

Привязка клавиш Описание

Управление программой

^D

Выход (при пустом буфере)

^C

Прерывание или отмена

^L

Очистка экрана консоли

RETURN/ВВОД, ^J

Новая строка с выполнением, если выражение введено полностью

метаклавиша+RETURN/ВВОД

Вставка новой строки без выполнения

? или ;

Переход в режим справки или оболочки (при нажатии в начале строки)

^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

Удаление следующего символа (когда в буфере есть текст)

Метаклавиша+BACKSPACE

Удаление предыдущего слова

meta-d

Удаление следующего слова

^W

Удаление предыдущего текста до ближайшего пробела

meta-w

Копирование текущего фрагмента в буфер обмена

meta-W

Удаление текущего фрагмента с помещением текста в буфер обмена

^U

Удаление текста до начала строки с его помещением в буфер обмена

^K

Удаление текста до конца строки с его помещением в буфер обмена

^Y

Вставка текста из буфера обмена

meta-y

Замена ранее вставленного текста на более старую запись из буфера обмена

^T

Перестановка символов вокруг курсора

meta-Up arrow

Перестановка текущей строки и строки выше

meta-Down arrow

Перестановка текущей строки и строки ниже

meta-u

Преобразование следующего слова в верхний регистр

meta-c

Преобразование первой буквы следующего слова в верхний регистр, а остальных — в нижний

meta-l

Преобразование следующего слова в нижний регистр

^/, ^_

Отмена предыдущего действия редактирования

^Q

Введите число в REPL и нажмите ^Q, чтобы перейти в редакторе к соответствующему стековому фрейму или методу

meta-Left Arrow

Добавление отступа к текущей строке слева

meta-Right Arrow

Добавление отступа к текущей строке справа

meta-.

Вставка последнего слова из предыдущей записи в истории

meta-e

Изменение текущего введенного текста в редакторе

Настройка привязок клавиш

Привязки клавиш в REPL Julia можно настроить согласно предпочтениям пользователя, передав словарь в REPL.setup_interface. Ключами в этом словаре могут быть символы или строки. Ключ '*' означает действие по умолчанию. Привязки, состоящие из клавиши CONTROL и символа x, обозначаются как "^x". Сочетание из метаклавиши и символа x можно записать как "\\M-x" или "\ex", а сочетание из клавиши CONTROL и символа x — как "\\C-x" или "^x". Значениями пользовательской конфигурации сочетаний клавиш должны быть nothing (что означает, что ввод следует игнорировать) или функции с сигнатурой (PromptState, AbstractREPL, Char). Перед инициализацией REPL следует вызвать функцию REPL.setup_interface путем регистрации операции с помощью atreplinit. Например, чтобы привязать клавиши со стрелками вверх и вниз для перемещения по истории без префиксного поиска, в ~/.julia/config/startup.jl можно поместить следующий код:

import REPL
import REPL.LineEdit

const mykeys = Dict{Any,Any}(
    # Стрелка вверх
    "\e[A" => (s,o...)->(LineEdit.edit_move_up(s) || LineEdit.history_prev(s, LineEdit.mode(s).hist)),
    # Стрелка вниз
    "\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

Как в режиме Julia, так и в режиме справки в REPL можно ввести первые несколько символов функции или типа, а затем нажать клавишу 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 можно также заменять математические символы 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     # √ эквивалентно функции sqrt
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 также работает в строках
julia> α="α"

Полный список завершений клавишей TAB можно найти в разделе Ввод символов Юникода данного руководства.

Автозавершение путей работает для строк и в режиме оболочки Julia:

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] # Отображаются все методы; здесь они не показаны из-за размера списка

julia> max([1, 2], [TAB] # Все методы с первым аргументом, соответствующим `Vector{Int}`
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] # Все методы, соответствующие аргументам.
max(x, y) in Base at operators.jl:215
max(a, b, c, xs...) in Base at operators.jl:281

Именованные аргументы также отображаются в предлагаемых методах после ;; см. строку ниже, где limit и keepempty являются именованными аргументами:

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)

Чтобы узнать доступные ключи цветов, можно ввести Base.text_colors в режиме справки в REPL. Кроме того, в качестве ключей цветов для терминалов с поддержкой 256 цветов можно использовать целочисленные значения от 0 до 255.

Изменить цвета для приглашения к вводу в режимах справки и оболочки, а также для текста входных и выходных данных можно путем задания соответствующих полей repl в приведенной выше функции customize_colors (help_color, shell_color, input_color и answer_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), где m — это объект Module, или путем ввода имени модуля в REPL и нажатия сочетания клавиш ALT+M (курсор должен находиться на имени модуля). Активный модуль отображается в командной строке:

julia> using REPL

julia> REPL.activate(Base)

(Base) julia> @__MODULE__
Base

(Base) julia> using REPL # Необходимо загрузить REPL в модуль Base для его использования

(Base) julia> REPL.activate(Main)

julia>

julia> Core<Alt-m> # используем сочетание клавиш для смены модуля

(Core) julia>

(Core) julia> Main<Alt-m> # возвращаемся к Main с помощью сочетания клавиш

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

Командная строка с нумерацией

Интерфейс можно переключить в режим, похожий на REPL IPython или записную книжку 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 — это подмодуль REPL Julia, который позволяет выводить в терминале небольшие интерактивные меню.

Примеры

import REPL
using REPL.TerminalMenus

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

RadioMenu

RadioMenu позволяет пользователю выбирать один вариант из списка. Функция request отображает интерактивное меню и возвращает индекс выбранного варианта. Если пользователь нажимает «q» или ctrl-c, функция request возвращает -1.

# `pagesize` — это количество одновременно отображаемых элементов.
#  Если количество вариантов больше значения `pagesize`,
#   их можно прокрутить
menu = RadioMenu(options, pagesize=4)

# `request` отображает меню и возвращает индекс после
#   выбора варианта пользователем
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 позволяет пользователю выбрать несколько вариантов в списке.

# здесь используется значение `pagesize` по умолчанию, равное 10
menu = MultiSelectMenu(options)

# `request` возвращает `Set` индексов выбранных вариантов
# в случае отмены (CTRL+C или Q) возвращается пустое множество
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
[press: Enter=toggle, a=all, n=none, d=done, q=abort]
   [ ] apple
   [X] orange
   [ ] grape
 > [X] strawberry
v  [ ] blueberry

можно использовать символы Юникода для выбора и навигации:

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 для настройки меню можно было вызывать TerminalMenus.config(). Эта возможность также поддерживается во всех версиях Julia 1.x.

Справка

REPL

# Base.atreplinitFunction

atreplinit(f)

Регистрирует функцию с одним аргументом, которая вызывается перед инициализацией интерфейса REPL в интерактивных сеансах; полезна для настройки интерфейса. Аргумент f — это объект REPL. Эта функция должна вызываться из файла инициализации .julia/config/startup.jl .

TerminalMenus

Меню

# REPL.TerminalMenus.RadioMenuType

RadioMenu

Меню, в котором пользователь может выбрать один пункт из списка.

Пример вывода

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

# REPL.TerminalMenus.MultiSelectMenuType

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.ConfigType

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, вызывается исключение InterruptException при нажатии пользователем клавиш CTRL+C во время выбора элементов меню. Если задано значение false, TerminalMenus.request возвращает результат по умолчанию из TerminalMenus.selected.

  • charset: влияет на значения по умолчанию для cursor, up_arrow и down_arrow. Возможные значения: :ascii или :unicode.

  • cursor: символ, указывающий на вариант, который будет выбран при нажатии клавиши ВВОД. Значение по умолчанию — «>» или «→» в зависимости от charset.

  • up_arrow: символ, выводимый в случае, если не отображается первый элемент. Значение по умолчанию — «^» или «↑» в зависимости от charset.

  • down_arrow: символ, выводимый в случае, если не отображается последний элемент. Значение по умолчанию — «v» или «↓» в зависимости от charset.

Подтипы ConfiguredMenu выводят cursor, up_arrow и down_arrow автоматически по мере необходимости; ваш метод writeline не должен их выводить.

Совместимость: Julia 1.6

Тип Config доступен начиная с версии Julia 1.6. В более старых версиях используйте глобальную переменную CONFIG.

# REPL.TerminalMenus.MultiSelectConfigType

MultiSelectConfig(; charset=:ascii, checked::String, unchecked::String, kwargs...)

Настраивает поведение меню с множественным выбором посредством именованных аргументов:

  • checked: строка, выводимая при выборе варианта. Значение по умолчанию — «[X]» или «✓» в зависимости от charset.

  • unchecked: строка, выводимая, когда вариант не выбран. Значение по умолчанию — «[ ]» или «⬚» в зависимости от charset.

Все остальные именованные аргументы аналогичны описанным для TerminalMenus.Config. checked и unchecked не выводятся автоматически и должны выводиться вашим методом writeline.

Совместимость: Julia 1.6

Тип MultiSelectConfig доступен начиная с версии Julia 1.6. В более старых версиях используйте глобальную переменную CONFIG.

# REPL.TerminalMenus.configFunction

config( <see arguments> )

Функция, принимающая только именованные аргументы, для настройки глобальных параметров меню.

Аргументы

  • charset::Symbol=:na: используемые символы пользовательского интерфейса (: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 является устаревшей. Используйте вместо нее Config или MultiSelectConfig.

Взаимодействие пользователя

# REPL.TerminalMenus.requestFunction

request(m::AbstractMenu; cursor=1)

Отображает меню и активирует интерактивный режим. cursor указывает номер элемента, на котором изначально установлен курсор. cursor может быть либо Int, либо RefValue{Int}. Второй вариант полезен для отслеживания положения курсора и управления им извне.

Возвращает selected(m).

Совместимость: Julia 1.6

Для аргумента cursor требуется версия не ниже Julia 1.6.

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

Краткая форма записи для вызова println(msg); request(m).

Интерфейс расширения AbstractMenu

Любой подтип AbstractMenu должен быть изменяемым и содержать поля pagesize::Int и pageoffset::Int. Любой подтип также должен реализовывать следующие функции:

# REPL.TerminalMenus.pickFunction

pick(m::AbstractMenu, cursor::Int)

Определяет, что происходит при нажатии пользователем клавиши ВВОД, когда меню открыто. Если возвращается значение true, выполнение request() завершается. cursor индексирует положение выбранного элемента.

# REPL.TerminalMenus.cancelFunction

cancel(m::AbstractMenu)

Определяет, что происходит, когда пользователь отменяет меню (нажатием клавиш Q или CTRL+C). После вызова этой функции выполнение request() всегда завершается.

# REPL.TerminalMenus.writelineFunction

writeline(buf::IO, m::AbstractMenu, idx::Int, iscursor::Bool)

Записывает элемент с индексом idx в buf. Если iscursor имеет значение true, указывает, что данный элемент находится в текущей позиции курсора (и будет выбран при нажатии клавиши ВВОД).

Если m — это ConfiguredMenu, TerminalMenus выводит индикатор курсора. В противном случае за его вывод отвечает вызываемая сторона.

Совместимость: 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.

Кроме того, он должен реализовывать options или numoptions:

# REPL.TerminalMenus.optionsFunction

options(m::AbstractMenu)

Возвращает список строк, которые будут отображаться как пункты меню на текущей странице.

В качестве альтернативы можно реализовать numoptions; в этом случае options не требуется.

# REPL.TerminalMenus.numoptionsFunction

numoptions(m::AbstractMenu) -> Int

Возвращает количество пунктов в меню m. Значение по умолчанию — length(options(m)).

Совместимость: Julia 1.6

Для этой функции требуется версия не ниже Julia 1.6.

Если подтип не содержит поля selected, он также должен реализовывать следующую функцию:

# REPL.TerminalMenus.selectedFunction

selected(m::AbstractMenu)

Возвращает информацию о пункте, выбранном пользователем. По умолчанию возвращает m.selected.

Следующие функции являются необязательными, но обеспечивают дополнительные возможности настройки:

# REPL.TerminalMenus.headerFunction

header(m::AbstractMenu) -> String

Возвращает строку заголовка, выводимую над меню. По умолчанию пустая строка.

# REPL.TerminalMenus.keypressFunction

keypress(m::AbstractMenu, i::UInt32) -> Bool

Обрабатывает нестандартное событие нажатия клавиш. Если возвращается значение true, выполнение TerminalMenus.request завершается. Значение по умолчанию — false.