emacs中使用elisp替换选中区域的字符串

Grey

-- mode: org; mode: visual-line --

emacs中使用elisp替换选中区域的字符串

这一个功能依然是来自于李杀的网站,是一个简单的emacs lisp例子。我现在掌握的emacslisp的内容不是很多,可能在这个基础上不好立马改出可以利用的功能,先以分析为主。

示范代码解读

(defun replace-greek-region ()
  "Replace “alpha” to “α” and other greek letters in current region."
  (interactive)
  (let (
        (p1 (region-beginning))
        (p2 (region-end)))
    (save-restriction
      (narrow-to-region p1 p2)
      (goto-char (point-min))
      (while (search-forward " alpha" nil t)
        (replace-match " α" nil t))
      (goto-char (point-min))
      (while (search-forward " beta" nil t)
        (replace-match " β" nil t))
      (goto-char (point-min))
      (while (search-forward " gamma" nil t)
        (replace-match " γ" nil t)))))

  • 跟前面看过的例子一样,这个依然是一个交互式命令。
  • let,之前在common lisp中多少接触过,相当于引入了局部静态变量。这样,p1、p2两个点可以用来标记一个区块的初始位置。
  • narrow-to-region,这个是引入的新的函数,需要先看一下,这个概念对理解后面的save-restriction函数有帮助。先看一下函数的帮助信息:

939_emacs中使用elisp替换选中区域的字符串_p2p
这个函数的功能其实可以类比说,如果一个文件比较大,我想处理其中的部分文本,我可以用这个函数圈定一个区块,类似于剪切出来了一样。这样,处理的时候会避免对其他部分的影响。但是操作之后可能会出现其他部分看似消失一样的现象,需要用winden来处理令其显示。如果在复杂处理中,则可以使用下面的save-restriction来自动保存以及恢复选中区域以外的信息。

  • save-restriction,这个是引入的新的函数。具体的功能如下:

939_emacs中使用elisp替换选中区域的字符串_emacs_02

  • point-min,获取当前缓冲区的最小位置,这里配合goto-char的功能应该是要跳转到区块的最前面。
  • search-forward,帮助描述如下:

search-forward is an interactive built-in function in ‘C source code’.

It is bound to <find>.

(search-forward STRING &optional BOUND NOERROR COUNT)

Search forward from point for STRING. Set point to the end of the occurrence found, and return point. An optional second argument bounds the search; it is a buffer position. The match found must not end after that position. A value of nil means search to the end of the accessible portion of the buffer. Optional third argument, if t, means if fail just return nil (no error). If not nil and not t, move to limit of search and return nil. Optional fourth argument COUNT, if a positive number, means to search for COUNT successive occurrences. If COUNT is negative, search backward, instead of forward, for -COUNT occurrences. A value of nil means the same as 1. With COUNT positive, the match found is the COUNTth one (or first, if COUNT is 1 or nil) in the buffer located entirely after the origin of the search; correspondingly with COUNT negative.

Search case-sensitivity is determined by the value of the variable ‘case-fold-search’, which see.

See also the functions ‘match-beginning’, ‘match-end’ and ‘replace-match’.
 

  • replace-match,帮助信息如下:

replace-match is a built-in function in ‘C source code’.

(replace-match NEWTEXT &optional FIXEDCASE LITERAL STRING SUBEXP)

Replace text matched by last search with NEWTEXT. Leave point at the end of the replacement text.

If optional second arg FIXEDCASE is non-nil, do not alter the case of the replacement text. Otherwise, maybe capitalize the whole text, or maybe just word initials, based on the replaced text. If the replaced text has only capital letters and has at least one multiletter word, convert NEWTEXT to all caps. Otherwise if all words are capitalized in the replaced text, capitalize each word in NEWTEXT.

If optional third arg LITERAL is non-nil, insert NEWTEXT literally. Otherwise treat ‘\’ as special: ‘\&’ in NEWTEXT means substitute original matched text. ‘’ means substitute what matched the Nth ‘...939_emacs中使用elisp替换选中区域的字符串_文本处理_03’. If Nth parens didn’t match, substitute nothing. ‘\\’ means insert one ‘\’. ‘\?’ is treated literally (for compatibility with ‘query-replace-regexp’). Any other character following ‘\’ signals an error. Case conversion does not apply to these substitutions.

If optional fourth argument STRING is non-nil, it should be a string to act on; this should be the string on which the previous match was done via ‘string-match’. In this case, ‘replace-match’ creates and returns a new string, made by copying STRING and replacing the part of STRING that was matched (the original STRING itself is not altered).

The optional fifth argument SUBEXP specifies a subexpression; it says to replace just that subexpression with NEWTEXT, rather than replacing the entire matched text. This is, in a vague sense, the inverse of using ‘’ in NEWTEXT; ‘’ copies subexp N into NEWTEXT, but using N as SUBEXP puts NEWTEXT in place of subexp N. This is useful only after a regular expression search or match, since only regular expressions have distinguished subexpressions.

  • 这样,综合总结上面的代码含义:首先是选中区域做备份以及恢复准备,接下来针对选中的内容进行搜索替换处理。由于替换是替换上次搜索到的内容,因此每次只能够完成一个替换。这样,如果区块有多个可以搜索到的对象,需要多次搜索替换。替换一直处理到搜不到为止。类似的处理,一共处理了三个。

后续规划

在我个人的工具应用中,文本处理是一个很常用的功能。类似的功能可以辅助实现一个区域编辑的功能。但是,这个在spacemacs中似乎是有了其他的方案了,不过,类似的实现机理还是可以借由这次的学习总结一下。

小结

文本处理或者字符串处理是我日常工作中的频繁使用点,后续逐渐积累类似的功能,应该可以在一定程度上在emacs中完成脚本所实现的功能。