21.2 使用迷你缓冲区读取文本字符串

迷你缓冲区输入最基础的原语是 read-from-minibuffer,可用于读取字符串或文本形式的 Lisp 对象。函数 read-regexp 用于读取正则表达式(see Regular Expressions),它是一类特殊的字符串。还有用于读取命令、变量、文件名等的专用函数(see 补全)。

大多数情况下,不应在 Lisp 函数中间调用迷你缓冲区输入函数。而应在 interactive 声明中,将所有迷你缓冲区输入作为读取命令参数的一部分。See Defining Commands

Function: read-from-minibuffer prompt &optional initial keymap read history default inherit-input-method

该函数是从迷你缓冲区获取输入的最通用方式。默认情况下,它接受任意文本并以字符串形式返回;但如果 readnil,则会使用 read 将文本转换为 Lisp 对象(see 输入函数)。

该函数首先激活迷你缓冲区,并以 prompt(必须是字符串)作为提示显示。随后用户可在迷你缓冲区中编辑文本。

当用户输入命令退出迷你缓冲区时,read-from-minibuffer 根据迷你缓冲区中的文本构造返回值。通常返回包含该文本的字符串。但如果 readnilread-from-minibuffer 会读取文本并返回未经求值的 Lisp 对象。(See 输入函数,了解读取相关信息。)

参数 default 指定可通过历史命令使用的默认值。它应为字符串、字符串列表或 nil。该字符串或多个字符串成为迷你缓冲区的 “未来历史(future history)”,用户可通过 M-n 使用。此外,如果调用提供了补全(例如通过 keymap 参数),当 default 中的值被 M-n 遍历完毕后,补全候选会被添加到“未来历史”中;参见 minibuffer-default-add-function

如果 readnil,则当用户输入为空时,default 也会用作 read 的输入。如果 default 是字符串列表,则使用第一个字符串作为输入。如果 defaultnil,空输入会导致 end-of-file 错误。 但在通常情况下(readnil),当用户输入为空时,read-from-minibuffer 会忽略 default 并返回空字符串 ""。在这一点上,它与本章中所有其他迷你缓冲区输入函数不同。

如果 keymapnil,该键映射即为迷你缓冲区中使用的局部键映射。如果 keymap 省略或为 nil,则使用 minibuffer-local-map 作为键映射。指定键映射是为补全等各类应用定制迷你缓冲区的最重要方式。

参数 history 指定用于保存输入及迷你缓冲区中历史命令的历史列表变量。默认为 minibuffer-history。如果 history 为符号 t,则不记录历史。你还可以可选地指定历史列表中的起始位置。See 迷你缓冲历史

如果变量 minibuffer-allow-text-propertiesnil(无论是在迷你缓冲区中通过 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-methodnil,迷你缓冲区会从进入迷你缓冲区前的当前缓冲区继承当前输入法(see Input Methods)和 enable-multibyte-characters 设置(see Text Representations)。

initial 的使用已基本不推荐;我们建议仅在为 history 指定 cons 单元时才使用非 nil 值。See 初始输入

Function: read-string prompt &optional initial history default inherit-input-method

该函数从迷你缓冲区读取字符串并返回。参数 promptinitialhistoryinherit-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 函数实现。

Function: read-regexp prompt &optional defaults history

该函数从迷你缓冲区以字符串形式读取正则表达式并返回。如果迷你缓冲区提示字符串 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,取值为 foldinhibit-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))
User Option: read-regexp-defaults-function

函数 read-regexp 可使用此变量的值来确定默认正则表达式列表。若非 nil,此变量的值应为以下之一:

  • 符号 regexp-history-last
  • 一个无参数函数,返回 nil、字符串或字符串列表。

这些值的具体用法见上文 read-regexp

Variable: minibuffer-allow-text-properties

若此变量为 nil(默认值),则 read-from-minibuffer 及所有执行迷你缓冲输入的函数在返回结果前,会移除迷你缓冲输入中的所有文本属性。

read-minibuffer 及相关函数(see Reading Lisp Objects With the Minibuffer)会无条件移除文本属性,不受此变量影响。

若此变量非 nil(无论是在迷你缓冲中动态绑定还是缓冲区局部绑定),则 read-from-minibufferread-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 属性外,所有文本属性均被保留。

Variable: minibuffer-local-map

这是 迷你缓冲读取的默认局部键映射。默认情况下,它绑定如下按键:

C-j

exit-minibuffer

RET

exit-minibuffer

M-<

minibuffer-beginning-of-buffer

C-g

abort-recursive-edit

M-n
DOWN

next-history-element

M-p
UP

previous-history-element

M-s

next-matching-history-element

M-r

previous-matching-history-element

变量 minibuffer-mode-map 是此变量的别名。

Function: read-no-blanks-input prompt &optional initial inherit-input-method

该函数从迷你缓冲读取字符串,但不允许空白字符作为输入的一部分:空白字符会直接终止输入。参数 promptinitialinherit-input-method 的用法与 read-from-minibuffer 相同。

这是对 read-from-minibuffer 的简化接口,它会将键映射 minibuffer-local-ns-map 作为 keymap 参数传给该函数。由于键映射 minibuffer-local-ns-map 未重新绑定 C-q,因此可以通过引用方式输入空格。

Variable: minibuffer-local-ns-map

该内置变量是函数 read-no-blanks-input 中使用的迷你缓冲局部键映射。除继承 minibuffer-local-map 的绑定外,默认还绑定:

SPC

exit-minibuffer

TAB

exit-minibuffer

?

self-insert-and-exit

Function: format-prompt prompt default &rest format-args

根据变量 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-argsnil,则 prompt 作为字面字符串使用。若非 nil,则 prompt 作为格式控制串,与 format-args 一起传给 format(see 格式化字符串)。

minibuffer-default-prompt-format 可设为 ‘""’,此时不显示默认值。

defaultnil,则无默认值,结果中不包含 “默认值(default value)” 字符串。若 default 为非 nil 的列表,则使用列表第一个元素作为提示中的默认值。

promptminibuffer-default-prompt-format 都会经过 substitute-command-keys 处理(see Substituting Key Bindings in Documentation)。

Variable: read-minibuffer-restore-windows

若此选项非 nil(默认值),则从迷你缓冲获取输入并退出时,会恢复进入迷你缓冲所在框架的窗口配置;若与迷你缓冲窗口所属框架不同,也会恢复后者。例如,用户在同一框架使用迷你缓冲时拆分窗口,退出迷你缓冲后该拆分会被撤销。

若此选项为 nil,则不进行恢复,上述窗口拆分在退出迷你缓冲后会保留。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© 2025 Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike