Learning and applying coding style from Google (in Emacs)
今天李开复的博客转发了一条围脖,大意是:Google C++ Coding Style是最好的Coding Style,没有之一。
以前虽然经Paul提示过,但当时的我并没有提起足够的重视,现在重新看了一下,受益匪浅。
http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml Google C++ Style Guide
这个Style Guide不仅提示并规定了如何格式化代码,还对C++中的特性做了对比和使用建议。例如:
(1) 对于引用(reference)的参数,应该尽量使用const来做修饰,否则我们不知道程序中修改的值会不会有超出该函数的作用;
(2) 对于要修改值的参数,则提倡使用指针。
(3) 还有,对于构造函数Constructor,Google 认为应使用explicit关键字来修饰,这样防止编译器做隐式的类型转换,同时构造函数必须明确的写出来,即使是与default的形式是相同的。
(4) 对于头文件的引用,Google 建议使用Forward declaration(提前声明)来减少包含过多的文件次数
在这个Style Guide之中,还提到了一个有用的工具cpplint.py, 这个Python工具可以对照Google Style Guide去检查你的代码是否符合规范。我是一个Emacs fans,那么如何把Google Style Guide 和 我们的.emacs配置结合起来呢?
首先你需要下载这个文件: google-c-style.el。
之后考虑到我所在的小组要求Tab-indent是4个空格,并且要求用空格替代Tab,那么我们的.emacs配置如下:
(require 'cc-mode) (require 'google-c-style) (defun my-build-tab-stop-list (width) (let ((num-tab-stops (/ 80 width)) (counter 1) (ls nil)) (while (<= counter num-tab-stops) (setq ls (cons (* width counter) ls)) (setq counter (1+ counter))) (set (make-local-variable 'tab-stop-list) (nreverse ls)))) (defun my-c-mode-common-hook () (c-set-style "google") (setq tab-width 4) ;; change this to taste, this is what K&R uses :) (my-build-tab-stop-list tab-width) (setq c-basic-offset tab-width) (setq indent-tabs-mode nil) ;; force only spaces for indentation (local-set-key "\C-o" 'ff-get-other-file) (c-set-offset 'substatement-open 0) (c-set-offset 'arglist-intro c-lineup-arglist-intro-after-paren) ) ;; google sytle is defined in above function (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) (add-hook 'c++-mode-common-hook 'my-c-mode-common-hook)
如何配置.emacs里并加入cpplint功能呢?只需在.emacs里加入如下代码:
(defun cpplint () "check source code format according to Google Style Guide" (interactive) (compilation-start (concat "python ~/bin/cpplint.py " (buffer-file-name))))
我们只需要执行M-x cpplint就可以得到格式检查的结果。用C-x `,或者M-g n, M-g p可以上下切换。
另一个常用的功能是如何将多个源文件通过Emacs来调整格式的(batch indent source code)?
参考 Batch Indentation with Emacs,文中提到的方法可以用默认的代码风格来格式化源文件。
但我们的目标是用Google风格来格式话代码,那么只需要稍作改变:
~/bin/emacs-format-function
;;; File: emacs-format-file ;;; Stan Warford ;;; 17 May 2006 ;; from: http://www.cslab.pepperdine.edu/warford/BatchIndentationEmacs.html ;; Adopt by Xiaowei Zhan 2011 from .emacs (require 'google-c-style) (defun emacs-format-function () "Format the whole buffer." (setq tab-width 4) ;; change this to taste, this is what K&R uses :) (setq c-basic-offset tab-width) (c-set-offset 'substatement-open 0) ;; next line is strange, I copied it from .emacs, but it cannot find c-lineup-arglist-intro-after-paren ;; however, disable this line seems working as well. ;;(c-set-offset 'arglist-intro c-lineup-arglist-intro-after-paren) (indent-region (point-min) (point-max) nil) (untabify (point-min) (point-max)) (save-buffer) )
~/bin/my-indent
#!/bin/bash # File: my-indent # Opens a set of files in emacs and executes the emacs-format-function. # Assumes the function named emacs-format-function is defined in the # file named emacs-format-file. if [ $# == 0 ] then echo "my-indent requires at least one argument." 1>&2 echo "Usage: my-indent files-to-indent" 1>&2 exit 1 fi while [ $# -ge 1 ] do if [ -d $1 ] then echo "Argument of my-indent $1 cannot be a directory." 1>&2 exit 1 fi # Check for existence of file: ls $1 2> /dev/null | grep $1 > /dev/null if [ $? != 0 ] then echo "my-indent: $1 not found." 1>&2 exit 1 fi echo "Indenting $1 with emacs in batch mode" emacs -batch $1 -l ~/emacs/google-c-style.el -l ~/bin/emacs-format-file -f emacs-format-function echo shift 1 done exit 0 #from http://www.cslab.pepperdine.edu/warford/BatchIndentationEmacs.html
值得注意的是Google除了C++ Style Guide, 还提供JavaScript Style Guide, Objective-C Style Guide, and Python Style Guide。对这些语言感兴趣的朋友可以到Google Style Guide发掘。