迷你缓冲区输入最基础的原语是 read-from-minibuffer,可用于读取字符串或文本形式的 Lisp 对象。函数 read-regexp 用于读取正则表达式(see Regular Expressions),它是一类特殊的字符串。还有用于读取命令、变量、文件名等的专用函数(see 补全)。
大多数情况下,不应在 Lisp 函数中间调用迷你缓冲区输入函数。而应在 interactive 声明中,将所有迷你缓冲区输入作为读取命令参数的一部分。See Defining Commands。
该函数是从迷你缓冲区获取输入的最通用方式。默认情况下,它接受任意文本并以字符串形式返回;但如果 read 非 nil,则会使用 read 将文本转换为 Lisp 对象(see 输入函数)。
该函数首先激活迷你缓冲区,并以 prompt(必须是字符串)作为提示显示。随后用户可在迷你缓冲区中编辑文本。
当用户输入命令退出迷你缓冲区时,read-from-minibuffer 根据迷你缓冲区中的文本构造返回值。通常返回包含该文本的字符串。但如果 read 非 nil,read-from-minibuffer 会读取文本并返回未经求值的 Lisp 对象。(See 输入函数,了解读取相关信息。)
参数 default 指定可通过历史命令使用的默认值。它应为字符串、字符串列表或 nil。该字符串或多个字符串成为迷你缓冲区的 “未来历史(future history)”,用户可通过 M-n 使用。此外,如果调用提供了补全(例如通过 keymap 参数),当 default 中的值被 M-n 遍历完毕后,补全候选会被添加到“未来历史”中;参见 minibuffer-default-add-function。
如果 read 非 nil,则当用户输入为空时,default 也会用作 read 的输入。如果 default 是字符串列表,则使用第一个字符串作为输入。如果 default 为 nil,空输入会导致 end-of-file 错误。
但在通常情况下(read 为 nil),当用户输入为空时,read-from-minibuffer 会忽略 default 并返回空字符串 ""。在这一点上,它与本章中所有其他迷你缓冲区输入函数不同。
如果 keymap 非 nil,该键映射即为迷你缓冲区中使用的局部键映射。如果 keymap 省略或为 nil,则使用 minibuffer-local-map 作为键映射。指定键映射是为补全等各类应用定制迷你缓冲区的最重要方式。
参数 history 指定用于保存输入及迷你缓冲区中历史命令的历史列表变量。默认为 minibuffer-history。如果 history 为符号 t,则不记录历史。你还可以可选地指定历史列表中的起始位置。See 迷你缓冲历史。
如果变量 minibuffer-allow-text-properties 非 nil(无论是在迷你缓冲区中通过 let 绑定还是缓冲区局部绑定),则返回的字符串会保留迷你缓冲区中的所有文本属性。否则返回值会去除所有文本属性。(默认情况下该变量为 nil。)‘
minibuffer-prompt-properties 中的文本属性会应用到提示上。默认情况下,该属性列表定义了用于提示的 face。该 face(如果存在)会被添加到 face 列表末尾,并在显示前合并。
如果用户希望完全控制提示的外观,最方便的方式是在所有 face 列表末尾指定 default face。例如:
(read-from-minibuffer (concat (propertize "Bold" 'face '(bold default)) (propertize " and normal: " 'face '(default))))
如果参数 inherit-input-method 非 nil,迷你缓冲区会从进入迷你缓冲区前的当前缓冲区继承当前输入法(see Input Methods)和 enable-multibyte-characters 设置(see Text Representations)。
initial 的使用已基本不推荐;我们建议仅在为 history 指定 cons 单元时才使用非 nil 值。See 初始输入。
该函数从迷你缓冲区读取字符串并返回。参数 prompt、initial、history 和 inherit-input-method 的用法与 read-from-minibuffer 相同。使用的键映射为 minibuffer-local-map。
可选参数 default 的用法与 read-from-minibuffer 类似,区别在于:如果非 nil‘,它还指定了用户输入空内容时返回的默认值。与 read-from-minibuffer 中一样,它应为字符串、字符串列表或 nil(等价于空字符串)。当 default 为字符串时,该字符串即为默认值。当为字符串列表时,第一个字符串为默认值。(所有这些字符串都会出现在用户的 “迷你缓冲区未来历史(future minibuffer history)” 中。)
该函数通过调用 read-from-minibuffer 实现:
(read-string prompt initial history default inherit)
≡
(let ((value
(read-from-minibuffer prompt initial nil nil
history default inherit)))
(if (and (equal value "") default)
(if (consp default) (car default) default)
value))
如果你希望编辑较长的字符串(例如跨多行),使用 read-string 可能不太理想。这种情况下,跳转到新的普通缓冲区让用户编辑会更方便,可使用 read-string-from-buffer 函数实现。
该函数从迷你缓冲区以字符串形式读取正则表达式并返回。如果迷你缓冲区提示字符串 prompt 不以 ‘:’(后接可选空白)结尾,函数会在末尾添加 ‘: ’,并在前面附上默认返回值(非空时)。
可选参数 defaults 控制用户输入空内容时返回的默认值,应为以下之一:字符串;nil(等价于空字符串);字符串列表;或符号。
如果 defaults 是符号,read-regexp 会参考变量 read-regexp-defaults-function 的值(见下文),如果该值非 nil,则优先使用它而非 defaults。此时该值应为:
regexp-history-last,表示使用对应小缓冲历史列表的第一个元素(见下文)。
nil、字符串或字符串列表)将作为 defaults 的值。
read-regexp 现在会确保处理 defaults 后的结果是一个列表(即,如果值为 nil 或字符串,会将其转换为单元素列表)。在此列表基础上,read-regexp 会追加若干可能有用的输入候选,包括:
该函数最终得到一个正则表达式列表,并将其传给 read-from-minibuffer 以获取用户输入。列表的第一个元素是空输入时的默认值。列表中所有元素都会作为“未来小缓冲历史”提供给用户(see future list in The GNU Emacs Manual)。
可选参数 history 若非 nil,则是一个符号,指定要使用的小缓冲历史列表(see 迷你缓冲历史)。若省略或为 nil,历史列表默认为 regexp-history。
用户可以使用 M-s c 命令指定是否开启大小写忽略。若用户使用过该命令,返回的字符串会被设置文本属性 case-fold,取值为 fold 或 inhibit-fold。是否实际使用该值由 read-regexp 的调用者决定,为此提供了便利函数 read-regexp-case-fold-search。典型用法示例:
(let* ((regexp (read-regexp "Search for: "))
(case-fold-search (read-regexp-case-fold-search regexp)))
(re-search-forward regexp))
函数 read-regexp 可使用此变量的值来确定默认正则表达式列表。若非 nil,此变量的值应为以下之一:
regexp-history-last。
nil、字符串或字符串列表。
这些值的具体用法见上文 read-regexp。
若此变量为 nil(默认值),则 read-from-minibuffer 及所有执行迷你缓冲输入的函数在返回结果前,会移除迷你缓冲输入中的所有文本属性。
但 read-minibuffer 及相关函数(see Reading Lisp Objects With the Minibuffer)会无条件移除文本属性,不受此变量影响。
若此变量非 nil(无论是在迷你缓冲中动态绑定还是缓冲区局部绑定),则 read-from-minibuffer、read-string 及相关函数会保留文本属性。但使用补全的迷你缓冲输入函数会移除 face 属性,同时保留其他文本属性。
(minibuffer-with-setup-hook
(lambda ()
(setq-local minibuffer-allow-text-properties t))
(completing-read
"String: " (list (propertize "foobar" 'face 'baz 'data 'zot))))
=> #("foobar" 0 6 (data zot))
本例中用户输入 ‘foo’ 后按 TAB,除 face 属性外,所有文本属性均被保留。
这是 迷你缓冲读取的默认局部键映射。默认情况下,它绑定如下按键:
exit-minibuffer
exit-minibuffer
minibuffer-beginning-of-buffer
abort-recursive-edit
next-history-element
previous-history-element
next-matching-history-element
previous-matching-history-element
变量 minibuffer-mode-map 是此变量的别名。
该函数从迷你缓冲读取字符串,但不允许空白字符作为输入的一部分:空白字符会直接终止输入。参数 prompt、initial 和 inherit-input-method 的用法与 read-from-minibuffer 相同。
这是对 read-from-minibuffer 的简化接口,它会将键映射 minibuffer-local-ns-map 作为 keymap 参数传给该函数。由于键映射 minibuffer-local-ns-map 未重新绑定 C-q,因此可以通过引用方式输入空格。
该内置变量是函数 read-no-blanks-input 中使用的迷你缓冲局部键映射。除继承 minibuffer-local-map 的绑定外,默认还绑定:
根据变量 minibuffer-default-prompt-format,将提示字符串 prompt 与默认值 default 格式化。
minibuffer-default-prompt-format 是一个格式字符串(默认为 ‘" (default %s)"’),用于控制类似 ‘"Local filename (default somefile): "’ 中默认值部分的显示格式。
为允许用户自定义显示方式,需要提示输入并带有默认值的代码应使用类似如下片段:
(read-file-name (format-prompt "Local filename" file) nil file)
若 format-args 为 nil,则 prompt 作为字面字符串使用。若非 nil,则 prompt 作为格式控制串,与 format-args 一起传给 format(see 格式化字符串)。
minibuffer-default-prompt-format 可设为 ‘""’,此时不显示默认值。
若 default 为 nil,则无默认值,结果中不包含 “默认值(default value)” 字符串。若 default 为非 nil 的列表,则使用列表第一个元素作为提示中的默认值。
prompt 和 minibuffer-default-prompt-format 都会经过 substitute-command-keys 处理(see Substituting Key Bindings in Documentation)。
若此选项非 nil(默认值),则从迷你缓冲获取输入并退出时,会恢复进入迷你缓冲所在框架的窗口配置;若与迷你缓冲窗口所属框架不同,也会恢复后者。例如,用户在同一框架使用迷你缓冲时拆分窗口,退出迷你缓冲后该拆分会被撤销。
若此选项为 nil,则不进行恢复,上述窗口拆分在退出迷你缓冲后会保留。