首页
归档
友情链接
关于
Search
1
在wsl2中安装archlinux
281 阅读
2
从零开始配置 vim(15)——状态栏配置
163 阅读
3
nvim番外之将配置的插件管理器更新为lazy
154 阅读
4
2018总结与2019规划
139 阅读
5
PDF标准详解(五)——图形状态
117 阅读
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
登录
Search
标签搜索
c++
c
学习笔记
windows
文本操作术
emacs
编辑器
NeoVim
Vim
elisp
win32
读书笔记
VimScript
linux
文本编辑器
投资理财
Java
反汇编
OLEDB
数据库编程
Masimaro
累计撰写
419
篇文章
累计收到
32
条评论
首页
栏目
软件与环境配置
读书笔记
编程
Thinking
FIRE
菜谱
翻译
页面
归档
友情链接
关于
搜索到
1
篇与
的结果
2026-08-30
《elisp 每日一练》——Window 树与布局状态恢复
前面的文章中,我们介绍了可以通过 split-window 来创建窗口,也介绍了通过 walk-windows 遍历窗口并且通过 overlay 机制实现了一个简单、直观的快速跳转窗口的功能。今天我们来深入了解背后的原理背景知识各位读者如果观察过Emacs执行 split-window 的效果,应该会发现它只会将当前窗口的区域进行划分,将当前窗口区域分为两个部分。这样我们很容易想到一个树的结构,光标所在的位置是树的一个叶子节点,在新建窗口时将该叶子节点作为新的根节点,在下方创建两个新的叶子节点。其实Emacs底层正是这样做的。我们可以通过 window-tree 来获取当前frame下窗口布局的树结构。我们用一个简单的例子来描述一下返回的具体结构, 假设我们有如下一个窗口布局+------------+-------------+ | | Window | | Window | B | | A +-------------+ | | Window | | | C | +------------+-------------+我们调用 window-tree 得到的结果可能是这样的( (nil (0 3 84 38) #<window 3 on *scratch*> (t (42 3 84 38) #<window 8 on *scratch*> #<window 10 on *scratch*>)) #<window 4 on *Minibuf-0*>)从整体上看它分为两个大的部分,第一个部分是一个复杂的结构,而第二个部分是一个window对象,它实际上是 mini-buffer 的窗口。我们再来看看前面一个大的结构。我们将它转换成一个树状结构├── (nil (0 3 84 38) │ ├── #<window 3 on *scratch*> │ └── (t (42 3 84 38) │ ├── #<window 8 on *scratch*> │ ├── #<window 10 on *scratch*> └── #<window 4 on *Minibuf-0*>通过这个我们发现,一个根节点实际是当前区域的分割方式和区域的大小,第一个参数为 nil 表示它是水平分割,而 t 表示垂直分割。各位读者请注意,这里的水平和数值的理解,这里并不是在窗口上按水平或者竖直方向画一条线将窗口进行划分,而是表示将新窗口按照水平或者竖直方向进行排列。所以上述结构真正含义其实是:先通过 nil 将窗口区域划分为水平方向的两个窗口,也就是左右两个其中一个为window3将右边区域一分为二,通过 t 表明它应该是竖直方向的两个窗口,也就是在中间水平位置画一条线进行区分在过去如果想要保存和恢复这个窗口布局,我们需要通过 window-tree 函数保存当前的树结构,恢复时解析每个节点并且调用 split-window 重新根据节点进行。但是从Emacs 24.1 之后提供了两个函数,可以方便的进行保存和后续的恢复: window-state-get 和 window-state-put(window-state-get &optional WINDOW WRITABLE)它可以返回指定窗口的布局状态,默认就是root 窗口,也就是当前frame 的主视图区域。我们可以在关闭时通过 window-state-get 获取root 的布局信息,保存到一个文件中,再下一次启动Emacs 时通过window-state-put 进行恢复窗口。如果我们只是临时性的保存和恢复当前窗口布局,可以使用 current-window-configuration 和 set-window-configuration 。它们的作用与前面介绍的 save-excursion、save-restriction 和 with-current-buffer 类似,如果包含临时性的窗口操作,为了让用户没有察觉或者不改变当前窗口布局,可以使用练习好了,我们来实现一个保存和恢复窗口布局的例子,因为我们还没有接触过Emacs文件的操作,所以这里简单的实现一个在Emacs启动期间执行保存和恢复的功能,后续学习了如何读取和保存文件之后我们可以继续完善因为不涉及到持久化的保存,所以我们可以简单的使用 current-window-configuration 和 set-window-configuration 函数。(defvar current-window-state nil) (defun my/save-current-window-state() (interactive) (setq current-window-state (current-window-configuration))) (defun my/restore-current-window-state() (interactive) (set-window-configuration current-window-state))我们的练习比较简单,如果读者觉得难度不过瘾,可以考虑通过保存和遍历 window-tree 的方式实现这个功能小结本篇我们介绍的函数有:window-treecurrent-window-configuration 和 set-window-configurationget-window-state 和 put-window-state
2026年08月30日
0 阅读
0 评论
0 点赞