作者: xilbert

  • 1 字符串类
  • 2 hook类函数
  • 3 用来高亮的函数
  • 4 编译类函数
  • 5 将这些函数串起来

1 字符串类

string-match 函数: 用指定的正则表达式去匹配字符串,将匹配的结果放到 match-data中。(match-data 用于存储emacs中字符串模式匹配中的匹配结果) 让我们看一个例子吧!

例 1:

? View Code LISP
1
2
3
(setq mystr "The quick fox jumped quickly.")
(string-match "\\(qu\\)\\(ick\\)"mystr)   =>副作用:将匹配结果存储到match-data中

这条语句的意思是:用\(qu\)\(ick\) 模式对mystr进行搜索,将匹配的结果存储,并且也存储分组1\(qu\) 和分组2 \(ick\)的匹配结果。

那么怎么取出匹配的结果呢? 答案是使用 match-string

? View Code LISP
1
2
3
(match-string 0 mystr)      =>结果为quick,也就是模式匹配的结果
(match-string 1 mystr)      =>结果为qu   ,也就是第一个分组的匹配结果
(match-string 2 mystr)      =>结果为ick  ,也就是第二个分组的匹配结果

string-match 是用正则表达式去搜索字符串的,如果你想替换字符串,那怎么办呢? 那就要用到replace-regexp-in-string。

replace-regexp-in-string 函数:

用指定的正则表示式对字符串去搜索,将搜索到的模式用指定的字符串对原字符串进行替换。这个函数是非破坏性的,不会将你的原字符串破坏,函数返回的结果就是替换结果。
例1 :
假如你想将”d:/gnu/” 替换为”d:\\gnu\\” ,你可以这样写:

? View Code LISP
(replace-regexp-in-string "/" "\\\\" "d:/gnu/")

那么为什么将替代字符串写成\\\\,而不是\\ ? 实际上在emacs的正则表示式中,\\\\才代表一个\,而emacs的普通字符串中\\代表\ 。

问题1:emacs 的正则表示达式中\太多了,能不能用个函数将\(hello\) 转化为\\(hello\\) ?
答案 :我也想知道!在emacs 中,我还没找到哪个函数能将“\(hello\)”转化为”\\(hello\\)”,这是字符串转义的缘故。我只能用一个比较拙劣的方法来帮助我写emacs style regexp ——用一段perl代码:

? View Code PERL
1
2
3
4
5
#!/usr/bin/perl
print "please input a raw regexp ,i will generic a emacs style regexp\n";
$str =<STDIN>;
$str =~ s/\\/\\\\/g;
print $str;

问题2:如果你想将^ . * $ 等特殊字符作为普通字符,你不想手动写成^ ,\\. 等形式,有什么办法帮助你吗?
答 :用 regexp-quote 函数。 例:(regexp-quote “^”) 自动生成”^”

问题3:如果你想用正则表达式表达搜索”hello” 或”world” ,你不想手动写成”hello\\|world”,有无简化的办法?
答: regexp-opt 可以办到。 例:(regexp-opt ‘(“hello” “world”)) 输出了”\\(?:hello\\|world\\)”

让我们再次回到replace-regexp-in-string函数来,它的功能真的很强大,替代字符串中还可以引用分组
例2 : (replace-regexp-in-string “\\(hello\\)\\(world\\)” “\\2\\1″ “helloworld”)
这个表达式的意思是:用\(hello\)\(world\)模式对“helloworld”进行搜索,将搜索到的结果用“\\2\\1”进行替换。函数返回了”worldhello”

2 hook类函数

emacs 中存在大量的hook ,有emacs-lisp-mode-hook ,c-mode-hook 等,基本上一个mode就提供了一个hook 。那么hook的本质是什么,我们能不能设计一个自己的hook ? 实际上,hook 是一个elisp 表,这个表中存放着要被调用的函数的符号(或代码)。
让我们用一个例子说明一下吧!

? View Code LISP
1
2
3
4
5
6
7
8
(defvar myhook nil) ;;定义myhook为空表
(add-hook 'myhook '(lambda ()(insert "fun1 was called ")))  ;;将这个匿名函数1加入到myhook表中去(add-hook 'myhook '(lambda ()(insert "fun2 was called "))) ;;将匿名函数2加入myhook表中去(run-hooks 'myhook) ;; =>执行这条语句会在光标后插入fun2 was called fun1 was called

那么为什么会先执行匿名函数2呢,而不是匿名函数1呢?这是因为add-hook 会将函数插入到myhook列表的头部,并且run-hooks 是从myhook头执行到尾的,因此匿名函数2会先执行。
那么这样设计有什么好处呢?好处是比较明显的,比如用户执行了(add-hook ‘c-mode-hook ‘myfun),其中myfun是要修改了c-mode中的某个变量值的,但不巧的是,系统在此之前就执行了(add-hook ‘c-mode-hook ‘firstfun),并且firstfun也要设置这个变量的值。那么通过这样设计,你的修改将不会成功(因为你的修改会被系统的系统覆盖),这样就保证了用户不能随意地改变mode的状态,保证了系统的稳定性。

既然知道了hook就是一个表,那么我们也就可以用操作列表的方式来操作它了。

? View Code LISP
1
2
3
(setq myhook (cdr myhook))      ;; =>丢弃myhook中的第一个函数
(setq myhook (reverse myhook))  ;; =>将myhook反转,改变函数执行的顺序
(setq myhook nil)               ;; =>将myhook清空

3 用来高亮的函数

1、hi-lock-set-pattern 函数
它的作用为在当前buffer中对匹配的模式应用用户指定的face
我之前在text-mode 中打开outline-minor-mode,结果标题没有被高亮,经千辛万苦终于将问题解决,这得益于hi-lock-set-pattern函数。我是这样设置的:
先定义一些face ,如下:

? View Code LISP
1
2
3
4
5
6
7
8
9
10
11
(defface cyan-face'((t :foreground "cyan"))"我自定义的cyan face")(defface yellow-face'((t :foreground "yellow"))"我自定义的yellow face")(defface magenta-face'((((class color)) :foreground "magenta"))"我自定义的magenta face")

这些face 都是从ahei-face.el中的,那里面还有许多其他的face。

然后然加入下面的代码,让outline-minor-mode启动时执行hi-lock-set-pattern,将标题高亮。

? View Code LISP
1
2
3
4
5
(add-hook 'outline-minor-mode-hook'(lambda ()(hi-lock-set-pattern "^\\*[^*]*?$" 'cyan-face)(hi-lock-set-pattern "^\\*\\*[^*]*?$" 'yellow-face)(hi-lock-set-pattern "^\\*\\*\\*[^*]*?$" 'magenta-face)))

2、hi-lock-unface-buffer
既然有高亮的函数,就应该有取消高亮的函数,它就是hi-lock-unface-buffer了

4 编译类函数

complie 函数非常强大,它的参数是个编译命令字符串,它会执行这个编译命令,执行完后会打开一个buffer,其主模式为compilation-mode。如果编译出错,会在它打开的buffer中输出出现错误的行数,这时就可以通过点击鼠标跳转到发生错误的代码处。如果编译成功,则会输出编译结果。
我们可以这样设置编译命令:

? View Code LISP
1
2
3
4
(compile "gcc hello.c")
(compile "c++ hello.cpp")
(compile "perl hello.pl")
(compile "d:/python/python25.exe hello.py")

5 将这些函数串起来

下面我会用一个例子将上面所讲的大部分函数串起来。
需求 :我想实现按f5就能编译当前buffer,并且要有错误定位功能,支持的语言可以添加(不要修改已经写好的代码)
实际环境:window xp ,cygwin
由于使用的是cygwin,调用gcc 时,gcc 需要cygwin类型的路径
这是emacs 给出的路径类型: d:/gnu/
在cygwin下是 :/cygdirve/d/gnu

实现:

? View Code LISP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
;;这个函数就是用来转换路径的
(defun change-to-cygwin-style-path (emacs-style-path-on-w32)(let ((full-path emacs-style-path-on-w32))(replace-regexp-in-string "\\(\\w+?\\):\\(\\w*\\)" "/cygdrive/\\1\\2" full-path)))
(change-to-cygwin-style-path (buffer-file-name))(defvar my-compile-hook nil);;这是主函数,按f5执行此函数
(defun my-compile-main-fun ()(interactive)(run-hooks  'my-compile-hook));;这个函数用来编译现在用得到的语言写的代码,以后如果要用到其他语言,可以写个函数,然后加入到my-compile-hook中去。
(defun orginal-compile-fun ()(let ((mode major-mode)(compstr nil))(cond ((eq mode 'c-mode)(setq compstr (concat "gcc -std=\"c99\" " (change-to-cygwin-style-path (buffer-file-name)))))((eq mode 'c++-mode)(setq compstr (concat "c++  " (change-to-cygwin-style-path (buffer-file-name)))))((eq mode 'emacs-lisp-mode)(emacs-lisp-byte-compile))((eq mode 'python-mode)(setq compstr (concat "python " (buffer-file-name))))((or (eq mode 'cperl-mode) (eq mode 'perl-mode))(setq compstr (concat "D:/Perl/bin/perl.exe " (buffer-file-name)))))(save-buffer)(if compstr (compile compstr))))
;;将orginal-compile-fun加入my-compile-hook中
(add-hook 'my-compile-hook 'orginal-compile-fun);;将my-compile-main-fun 绑定到f5上
(global-set-key [(f5)] 'my-compile-main-fun)

如果有一天,你要用octave 语言,你可以这样扩展:

? View Code LISP
1
2
3
4
5
(add-hook 'my-compile-hook '(lambda ()(if (eq major-mode 'octave-mode)(progn(save-buffer)(compile (concat "octave --silent " (buffer-file-name)))))))

使用hook机制是不是很方便呀,这样就不用去修改orginal-compile-fun的代码了。

ps:不知不觉罗嗦了这么多,其实我写这篇文章的目的有两个:1、是给初学emacs lisp的人介绍一下emacs字符串的操作和hook的机理以及强大的compile函数,希望有点用处。2、希望高手们也分享一下自己觉得很强大的emacs lisp 函数。

介绍一些Emacs功能强大的函数相关推荐

  1. 视频编辑软件有哪些?介绍几种功能强大的编辑软件

    视频编辑软件有哪些呢?如果我们录制了一段视频,但是其中包含了一些无用或者不太好的片段,我们就需要进行视频修剪,剪掉这些片段,让视频更加精炼.通过修剪视频素材,我们可以将一些不必要的部分去掉,保留最有价 ...

  2. 介绍一款功能强大的步进电机控制驱动芯片TMC5240

    步进电机由于具有控制简单,良好的速度和位置控制被大量用在工业自动化.医疗设备.仪器仪表.实验室自动化.办公自动化.智能家居......等众多行业,实现让步进电机转起来相对容易很多,但是在应用中简单的转 ...

  3. 这是一款功能强大的开源 Python 绘图库

    今天给大家分享一篇可视化干货,介绍的是功能强大的开源 Python 绘图库 Plotly,教你如何用超简单的(甚至只要一行!)代码,绘制出更棒的图表. 我之前一直守着 matplotlib 用的原因, ...

  4. 分享一款功能强大的win7免费语音朗读软件

    很多时候我们常常要对着电脑看上一整天,眼镜什么的也都会觉得很疲劳,所以在工作的空挡我们还是需要注意休息一下,然而我还还可以使用一种办法,就是让需要查阅的文件用语音朗读出来,我们就可以用耳朵听,让眼镜休 ...

  5. php强大的函数,PHP中一些功能强大却很少使用的函数

    本文主要介绍了PHP中功能强大却很少使用的函数,结合实例形式总结分析了php中非常实用的几个函数,包括函数的调用.注册.调用.判断等操作技巧.需要的朋友可以参考下,希望对大家有所帮助. 具体如下: c ...

  6. Visual Studio Code,一款功能强大且轻巧的免费代码集成编辑器介绍

    Visual Studio Code - 编辑器+代码理解+调试 下载 软件官网下载地址 初步环境设置 基本设置 功能介绍 1. 界面友好 代码阅读 代码编辑 下载 软件官网下载地址 链接: http ...

  7. java sendmessage函数_功能强大的SendMessage函数

    功能强大的SendMessage函数 分类:计算机等级 | 更新时间:2016-07-08| 来源:转载 Windows API(应用程序接口)是Windows系列软件为程序开发人员提供的火力强大的& ...

  8. python有vlookup的功能么,vlookup函数功能非常强大,那在Python中如何实现?

    vlookup函数功能非常强大,那在Python中如何实现? vlookup函数功能非常强大,那在Python中如何实现? 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原 ...

  9. android联想功能介绍,在Android世界中联想推出了功能强大的手机Z5 Pro GT

    在Android世界中,联想推出了功能强大的手机Z5 Pro GT.它已经引入了许多强大的规范.顺便说一句,这部手机中提供的RAM数量不存在于其他任何人中.但是在功能方面,除了Oneplus 6T之外 ...

最新文章

  1. ASP.NET MVC 学习1
  2. DELL服务器安装过程中出现的ERROR及解决方案
  3. 【pmcaff】社交媒体时代,村姑如何找到真爱?
  4. (十七)java版spring cloud+spring boot 社交电子商务平台-spring+springmvc+kafka分布式消息中间件集成方案...
  5. IOS学习笔记二十一(NSDictionary、NSMutableDictionary)
  6. python中自带的模块_python中的模块详解
  7. python win32ui_Python创建普通菜单示例【基于win32ui模块】
  8. html button跳转页面_HTML跳转到页面指定位置的几种方法
  9. eclise去连接mysql,Eclipse如何连接MySQL
  10. 第三章 Python丰富的数据类型
  11. python各种库下载地址:
  12. 推荐系统-利用用户行为数据
  13. 阳春三月,再送32本书,快来快来!
  14. 简单解释:STM32参考手册的地址偏移和复位值
  15. HTML5在vivo手机适配问题
  16. CSS中的text-overflow属性详解 (控制文字在一行显示,超出部分加省略号)
  17. PowerDesigner如何导出表到word的方法
  18. 华硕x450vb黑苹果系统拯救与安装
  19. digitalLogic_逻辑门和基本公式@同或和异或的关系
  20. hdfs - balancer学习

热门文章

  1. Nessus安装使用及自动化说明
  2. Altium Designer 详细图文教程
  3. 习题5-6 使用函数输出水仙花数 (20分)
  4. FIT2CLOUD飞致云发布开源Linux面板项目1Panel
  5. 人均劳动生产率的计算方法_劳动生产率应该如何计算
  6. STM32MP157驱动开发——多点电容触摸屏驱动
  7. 20230318解决编译友善之臂的RK3399的Android7.1.2的ninja_wrapper出错
  8. 机器视觉实用工具集NO.4——颜色查找可视化工具,在HSV、LAB、RGB三个颜色空间轻松进行颜色查找
  9. DM数据库数据守护集群搭建
  10. android 9.0跳过“未知来源”进行安装应用