《elisp 每日一练》—— Region

在关于保存和恢复现场的例子中,我们了解了 marker 相关的概念。 markerpoint 都是一个表示位置的整数,不同的是marker 是动态的,由Emacs 内部根据buffer内容变化进行维护,而 point 是静态的。

它们两个结合可以构成我们今天要讨论的内容——Region

知识铺垫

在图形界面编辑器中,我们经常用鼠标拖拽高亮一段文字,这叫“选中文本”。而在 Emacs 中,这个概念叫 Region(选区)。

Region 是一个区间,它由 markerpoint 组成的闭区间。

我们可以使用这样一个公式来描述区间的组成: Region=[min⁡(point,mark),max⁡(point,mark)]\text{Region} = [\min(\text{point}, \text{mark}), \max(\text{point}, \text{mark})]Region=[min(point,mark),max(point,mark)]

也就是说,起始位置是从 marker 和当前 point 中找到最小值,终点位置是二者的最大值。所以我们需要注意,在编写有关 Region 的代码时绝对不能假设使用 marker 或者 point 作为起点,或者终点。

实际上为了解决这个问题,Emacs 提供了两个函数 region-beginningregion-end 来获取Region的开始和结束位置

我们如何激活一个区域呢?可以通过 activate-mark 函数来激活当前选取。又或者可以通过 push-mark 在创建 marker 的同时进行激活。实际上 push-mark 的函数原形为:

(push-mark &optional LOCATION NOMSG ACTIVATE)

后面几个参数是可选的,它们分别代表:

  • LOCATION: 表示作为新 marker 位置的 point 值,默认是当前光标所在位置
  • NOMSG : 是否在minibuffer 中显示 Mark set 字样, 默认为 nil 也就是不显示
  • ACTIVATE : 是否激活当前 Region,默认为 nil 不激活

我们可以用一个例子测试一下

(defun my/select-whole-buffer()
  (interactive)
  (goto-char (point-min))
  (push-mark (point-max) nil t))

上述例子我们将整个buffer的内容进行全选。

另外,在操作 Region 时我们经常需要判断当前 Region 是否出于激活状态。因为前面介绍过实际上 markerpoint 天然就构成一个 Region。如果不进行判断,用户想要进行某些操作时会出现不可预料的情况。例如如果用户想在选中区域进行查找,或者在当前行查找,如果不进行判断,有可能用户没有进行选区操作但是查找时却因为隐藏的region 导致查找发生在region中

我们可以通过 use-region-p 来判断用户是否激活了选取

练习

我们实现一个函数,如果用户选择了一个区域,那么将区域中的所有字母大写,否则将光标所在单词的字母转换为大写。

将单个单词大写可以使用函数 upcase-region,而将单词大写可以使用 upcase-word

upcase-region 接收一个起始位置和结束位置,将这个区间内的字母都转化为大写
upcase-word 接收一个整数,表示将光标所在位置之后(正数)、或者之前(负数参数)的多少个单词转化为大写

upcase-word 仅仅只能将光标所在位置到单词结尾位置的字母大写,我们还需要一个方法来获取单词首部,然后通过 goto-char 的方式移动光标到词首,最后执行 upcase-word。当然有了范围也可以使用 upcase-region

获取光标所在单词的范围可以使用 bounds-of-thing-at-point。他的函数原形如下:

(bounds-of-thing-at-point THING)

它支持的 THING 非常多,有 wordlistsymbolnumberfilename 等等。这里我们使用 word 就行。

它返回的格式是 (START . END)。结合之前介绍的CELL的操作就可以获得START 的值。

我们可以做一个快速选择光标所在单词的函数来看看它的用法

(defun my/select-the-word()
  (interactive)
    (let ((bound (bounds-of-thing-at-point 'word)))
      (progn
	(goto-char (car bound))
	(push-mark (cdr bound))
	(activate-mark))))

这里我们确实需要改变mark栈来和当前光标位置组成一个新的区域,所以不适合使用 save-excursion 来保存和还原现场。

另外这里也演示了如何通过 activate-mark 来激活一个选区。

有了这些函数的辅助,最终我的实现如下:

(defun my/upcase-target()
  (interactive)
  (if (use-region-p)
      ;;用户选中区域,转换区域内文本
      (upcase-region (region-beginning) (region-end))
    ;;用户未选中文本,直接转换单词
    (save-excursion ;; 考虑保存和恢复现场
      (let ((bound (bounds-of-thing-at-point 'word)))
	(if bound
	    (progn
	      (goto-char (car bound))
	      (upcase-word 1)))))))

至于如何使用 upcase-region 来实现将光标所在单词转化为大写的功能,读者可以自行尝试。

总结

本篇我们了解了 Region 的概念,以及可以使用Region做一些事情。后续很多高级的功能都可以依赖region 来实现,例如在选区中搜索、替换文本。

今天介绍的函数有:

  • region-beginningregion-end 获取选区的区间
  • activate-mark 激活选区
  • use-region-p 判断选区是否激活
  • upcase-word 将光标所在位置之后的单词转化为大写
  • upcase-region 将对应区间的单词转化为大写
  • bounds-of-thing-at-point 获取指定事物所在的区间
下载代码方式:https://pan.quark.cn/s/a4b39357ea24 HTML大屏展示模板是一种用于设计具有视觉冲击力且内容充实的巨型显示屏应用的设计方案,其应用范围广泛,涵盖了数据分析、监控以及决策支持等多个领域。这些模板通常整合了HTML、CSS、JavaScript等多种技术,尤其借助ECharts等数据可视化工具以达成复杂数据的图形化呈现。以下是对相关技术细节的深入说明: 1. **可视化**:数据可视化是将抽象的数据转化为直观的图像或图表的技术手段。这种技术有助于迅速识别数据中的模式、发展趋势和异常情况,使得非专业背景的人员也能轻松理解复杂的数据信息。在大屏展示场景中,可视化通常包含折线图、柱状图、饼图、热力图、地图等多种图表形式。 2. **大数据**:大数据指的是规模庞大、增长迅速、种类多样且数据密度较低的数据集合。在HTML大屏展示中,大数据的应用旨在支持实时或近乎实时的决策制定,例如监控销售业绩、交通流量、能源消耗等关键性能指标。 3. **HTML**:超文本标记语言(HTML)构成了网页内容的基础结构,用于界定页面的布局和元素。在大屏展示模板中,HTML负责构建页面组件,例如标题、段落、图像以及图表容器等。 4. **CSS**:层叠样式表(CSS)用于调控网页的视觉风格和布局结构。在大屏模板设计中,CSS扮演着核心角色,确保设计的响应性、适应性和美观度,包括设定颜色、字体、间距、动画效果等。 5. **ECharts**:ECharts是由百度研发的一款开源JavaScript数据可视化库,能够支持多种图表类型,如折线图、柱状图、散点图等,并提供了丰富的交互特性。在大屏展示中,ECharts能够助力生成动态且交互式的数据...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值