首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
295 阅读
2
从零开始配置 vim(15)——状态栏配置
174 阅读
3
nvim番外之将配置的插件管理器更新为lazy
162 阅读
4
2018总结与2019规划
150 阅读
5
PDF标准详解(五)——图形状态
126 阅读
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
登录
Search
标签搜索
c++
c
emacs
学习笔记
elisp
windows
文本操作术
编辑器
NeoVim
Vim
win32
读书笔记
VimScript
linux
文本编辑器
投资理财
Java
反汇编
OLEDB
数据库编程
Masimaro
累计撰写
454
篇文章
累计收到
33
条评论
首页
栏目
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
页面
归档
友情链接
关于
搜索到
2
篇与
的结果
2026-09-02
《elisp 每日一练》——minibuffer输入读取和set-transient-map 临时热键状态机
我们在前面介绍了 completing-read 给用户提供选项,让用户输入,但是如何处理这种需要用户主动输入的情况呢?本节我们将介绍一些主动读取用户输入的接口,然后补充一个我们在前面练习中涉及到的函数 set-transient-map背景知识completing-read 主要是提供几个候选项供用户选择,有点类似一般GUI程序的下拉列表框。而我们今天介绍的 read-from-minibuffer 就像GUI程序中的文本框。它的函数签名如下:(read-from-minibuffer PROMPT &optional INITIAL-CONTENTS KEYMAP READ HIST DEFAULT-VALUE)其中常用参数的含义如下:PROMPT 提示词INITIAL-CONTENTS 预先填写的内容,后续可以修改READ 如果为 t,会自动调用 Lisp Reader,将输入的文本直接解析为 Lisp 对象DEFAULT-VALUE 当用户直接按回车时返回的字符串该接口相对来说是一个偏底层的接口,如果程序预先指定用户输入数据的类型,可以选择一些相对上层的封装函数:read-string 读取纯文本read-number 读取数字read-command 读取一个命令read-file-name 读取一个文件名read-directory-name 读取一个目录名称我们可以通过 read 作为前缀搜索类似的函数。另外一个今天要补充的函数就是 set-transient-map(set-transient-map KEYMAP &optional KEEP-PRED ON-EXIT)它会临时将对应的keymap挂起,在下一次按键之后,会调用 KEEP-PRED 参数绑定的函数返回值决定是否卸载keymap。它的函数返回值有三种情况:nil 执行一个命令后理解卸载,也就是一次性的t 保持,直到下一次调用时该函数返回nil数字 如果是数字值,保持激活状态,直到连续执行了指定次数的命令后自动卸载练习今天我们的练习,我们来实现一个快速的文本大小写与替换功能。它的功能如下:利用region 选中一段文本按 C-c t 进入该模式,此时我们利用 set-tranient-map 挂载一个快捷键的keymap按 u 将选中文本转为大写按 l 转为小写按 c 转为首字母大写(Captial)按 r 调用 read-string 读取你要替换的字符串,然后替换选中区域按 q 或任意其他键退出我们先定义这些功能的函数(defun my/upcase-region() "选中区域的文本转化为大写" (interactive) (when (use-region-p) (upcase-region (region-beginning) (region-end)))) (defun my/downcase-region() "选中区域文本转为小写" (interactive) (when (use-region-p) (downcase-region (region-beginning) (region-end)))) (defun my/capitalize-region() "选中区域首字母大写" (interactive) (when (use-region-p) (capitalize-region (region-beginning) (region-end)))) (defun my/replace-region() "替换选中区域的文本" (interactive) (when (use-region-p) (let* ((old-text (buffer-substring (region-beginning) (region-end))) (new-text (read-string (format "替换 '%s' 为:" old-text)))) (delete-region (region-beginning) (rregion-end)) (insert new-text))))然后我们可以定义一个keymap,将这些操作进行绑定(defvar my/text-operator-transient-map (let ((map (make-sparse-keymap))) (keymap-set map "u" #'my/upcase-region) (keymap-set map "l" #'my/downcase-region) (keymap-set map "c" #'my/capitalize-region) (keymap-set map "r" #'my/replace-region) (keymap-set map "q" (lambda() (interactive) (set-transient-map nil))) map))最后我们绑定一个快捷键进入该模式(defun my/start-text-operate() (interactive) (if (use-region-p) (set-transient-map my/text-operator-transient-map) (message "请先选中一段文本"))) (keymap-global-set "C-c t" #'my/start-text-operate)小结本篇我们介绍了如何读取minibuffer 中用户的输入,以及补充了一个关于快捷键绑定的额外函数。本节涉及到的函数有:read-from-minibuffer 以及基于该函数实现的read 系列函数set-transient-map
2026年09月02日
7 阅读
0 评论
0 点赞
2026-09-01
《elisp 每日一练》—— Minibuffer 与 completing-read
通过前面一段时间的学习,我们学习了如何与窗口进行交互。现在我们进入minibuffer的交互。从标题上看我们本节主要就是再介绍一遍 completing-read,这个函数我们前面已经多次用到过,读者如果不熟悉,可以再一次阅读本文,如果已经熟悉了,可以跳过。背景知识minibuffer 的相关概念就不在这里展开了。我们主要聊的是如何通过控制minibuffer相关的API来实现交互。本次我们将介绍一个我们之前遇到过相对比较熟悉的老朋友—— completing-read。我们知道,它可以通过往minibuffer中注入一些选项供用户选择。并返回用户选择的字符串。它的函数原形如下:(completing-read PROMPT COLLECTION &optional PREDICATE REQUIRE-MATCH INITIAL-INPUT HIST DEF INHERIT-INPUT-METHOD)PROMPT 是给用户的提示词COLLECTION 是我们传入到minibuffer中的候选数据源, 可以是单纯的字符串、Alist、Hash Table、或者是动态生成候选词的函数PREDICATE 它是一个函数,对加入的选项进行过滤,函数返回非 nil 表示接受,否则视为放弃REQUIRE-MATCH 控制用户是否必须输入一个有效的选项DEF 默认值,当用户不选择内容时选中的默认值HIST 历史记录, 传入一个 Symbol,Emacs 会自动把用户的历史选择存入该变量,支持用 M-p / M-n 翻阅前面有好几个例子已经用到了该函数,各位读者对它的常规用法应该不陌生。我们一般通过 alist 结构,将key 设置成用户友好的提示词,而它的背后绑定了相对复杂的数据,在用户选择之后通过背后绑定的数据来实现一些功能。练习前面我们在学习其他内容时已经通过该函数实现了一些相对复杂的功能了,这次练习我们来点简单的,仅仅为了回顾一下它的用法。我们实现一个快速打开指定文件的功能。我们预先定义一些常用文件,例如emacs 的配置文件、自己的工作日志等等。然后将这些内容组织一下传入COLLECTION,最后根据用户选择打开(defvar my/favorite-file-lists '("~/.emacs.d/init.el" "d:/worklog.el")) (defun my/quick-open-favorite-file() (interactive) (let ((selected (completing-read "Input filename to open:(default ~/.emacs.d/init.el)" my/favorite-file-lists nil nil nil nil "~/.emacs.d/init.el"))) (when selected (find-file selected))))小结因为本节涉及到的函数,我们已经多次在其他练习中使用过,对于它读者应该比较熟悉了。因为本人能力不够,所以在练习上面我目前也想不出有什么深入的,又尽量少涉及其他概念内容。所以就来一个最简单的,读者如果觉得例子太简单了,可以考虑自己实现一些复杂的功能。本节涉及的函数只有一个 completing-read
2026年09月01日
5 阅读
0 评论
0 点赞