Yukang's Page

Emacs自虐

2010-08-21

无意中用了一下C#,发现VS下面有一个功能还是非常好的,就是每次按下回车键盘的时候,都可以把刚刚输入的那行代码自动排版一下,

看起来要清晰一些。比如

int a=0;                       ==>  int a = 0;
struct Node p=&node; ==> struct Node p = &node;
a+=b; ==> a += b;
int p=&a; ==> int p = &a;
int a=b+c+d+f; ==> int a = b + c + d + f;
for(a=0,b=0;a<10;a++) ==> for(a = 0, b=0; a< 10; a++)
if(a==b) ==> if(a == b)
if(pbuf!=0) ==> if(a != b)
fwrite(buf,1,size,fp); ==> fwrite(buf, 1, size, fp);
printf(“%d %s\n”,len,buf); ==> printf(“%d %s\n”, len, buf); //引号内的不变,引号外的”,”后面加空格
if(p>=allocbuf&&p<buf+size) ==> if(p >= allocbuf && p < buf + size)
return (b!=0)?gcd_ver2(b,a%b):a; ==> return (b != 0) ? gcd_ver2(b, a % b) : a;


同时要注意的情况,还有些情况下我不想让符号两边加空格:

#include <stdio.h>       //< > 两边不加

printf(“%d%d%d\n”,n,m,k);//这个%两边不加 检测是否在引号内部
a++; //不加空格
int p; //不加空格
return manip(
this); //这个两边不加 找到前面或者后面是否为(
strcpy(mode,“w+”); //引号里面的不变 检测是否在引号内部


我以前写代码习惯都不加空格,感觉不加要写得快一些,可是这不是个很好的习惯。linux下有indent这样的工具,不过是针对于最后完成的源程序来排版。在写程序的过程中像赋值操作符两边加上空格会显得比较清晰,Emacs里面好像还没这么个插件,那我来折腾一下自己写了一个。原来还是比较复杂的。应该好好学学正则表达式,这就是一个正则匹配和替换的过程。呜,括号看得头都晕呼呼的,不过还好,最终有这么一个东西用起来比较顺手了。

首先定一个关键字和替换列表:

(setq beautifly-line-list
‘(
(“+” . “ + “)
(“-“ . “ - “)
(“=” . “ = “)
( . “ “)
(“/“ . “ / “)
(“%” . “ % “)
(“<” . “ < “)
(“>” . “ > “)
(“,” . “, “)
(“+=” . “ += “)
(=” . “ = “)
(“/=” . “ /= “)
(“%=” . “ %= “)
(“==” . “ == “)))


一个用来测试dest是否为上面关键字的函数,后面用char-after来获取一个point的字符,对应的是asci码。

(defun test-valid(dest)
(interactive)
(if(or (equal dest 43)
(equal dest 45)
(equal dest 42)
(equal dest 47)
(equal dest 37)
(equal dest 62)
(equal dest 60)) ;;<
t
nil))

;;打印出当前位置的字符 调试用
(defun print-pos-char ()
(interactive)
(setq value (char-after (point)))
(print value))

;;从point-pos位置开始 到这一行的尾部,检测是否有”,即检测是否在” “内部
(defun test-in-quote (point-pos)
(interactive)
(move-end-of-line 1)
(setq end-pos (point))
(goto-char point-pos)
(setq ret-value nil)
(if (search-forward “\”” end-pos t)
(setq ret-value t)
)
(goto-char point-pos)
ret-value)

;;这个函数先调用我的排版函数,然后调用原来的new-line-and-indent
(defun my-new-line-and-beautyfly ()
(interactive)
(beautifly-line)
(newline-and-indent))

;;在my-c-mode-common-hook下面加上这么一句,表示把回车键绑定在上面那个函数上。
(define-key c-mode-base-map [(return)] ‘my-new-line-and-beautyfly)


下面就剩下这两个函数了,写的太过复杂,可惜不会用高级一点的正则表达式,所以显得不好看。其想法比较简单,按照上面那个列表,一次查找,我要找一个两员操作符,其两边都是空格,在其两边加上空格,注意排除掉++,—操作。然后识别+=,-=,*=等符号,再两边加上空格。用起来还可以。逐渐写了些elisp,感觉特别适合自底向上的方式进行,通过一些小函数,逐步累积成一个功能,再最后只用一个上层函数来调用这个功能。每个小函数除了返回结果不改变函数外的其他变量(无副作用)。同时写一个小的函数可以马上写一个测试函数,保证其正确无误。

最后bueatifly_line的代码有点点长,不贴咯。

使用微信打赏

若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏

扫描二维码,分享此文章