首先抛开 lsp
这里面有两个问题:
- tab 的设置,
- cc-mode (c/c+±mode 继承自 cc-mode) 缩进的设置
tab 设置
tab 的设置主要是两方面:
- tab 字符的宽度
- 是否要将 tab 换成空格
下面是全局默认设置
(setq-default tab-width 4) ;; 表示一个 tab 4个字符宽
(setq-default indent-tabs-mode nil) ;; nil 表示将 tab 替换成空格
cc-mode 的缩进设置
定义代码的各个部分如何缩进一般叫缩进风格 。
cc-mode 定义了一个缩进风格列表 c-style-alist
,里面预制了一些缩进风格,比如 gnu ,k&r 等
我们可以通过 M-x c-set-style
设置当前 buffer 的风格。
c-default-style
定义了默认使用的缩进风格,不进行任何配置的情况下,默认值为:
((java-mode . "java")
(awk-mode . "awk")
(other . "gnu"))
即 java-mode 用 java 风格,awk-mode 用 awk 风格,其它 mode(c/c++ 等) 用 gnu 风格。
如果我们想在 c/c++ 中默认用 k&r 风格,只需要修改这个变量
(add-to-list 'c-default-style '(c++-mode . "k&r"))
(add-to-list 'c-default-style '(c-mode . "k&r"))
如果预制的缩进风格不满足要求,我们可以定义自己的缩进风格,然后将它加到 c-style-alist
中。
emacs 的缩进风格格式如下:
(STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
STYLE-STRING
是风格名称,BASE-STYLE
是可选的,表示继承某个已有的风格,
后面就是指定在这种风格下某个变量的值。如:
(setq my-style '("my-style"
"stroustrup"
(indent-tabs-mode . nil)))
上面就是定义一个名为 my-style
的风格,继承自 stroustrup
,使用这个风格时
indent-tabs-mode
为 nil
,即将 tab 替换成空格。
有一个特殊的变量 c-offsets-alist
,这个列表定义了所有语法元素符号的缩进,如
class
缩进几个字符,public
缩进几个字符。
如果 my-style
只继承自 stroustrup
效果就是下面这样的:
namespace test {
namespace {
int a = 0;
}
class Test final {
public:
void Hello();
};
}
如果我们想要内部 namespace 不缩进,我们就可以继承自 stroustrup
的基础上修改内部 namespace 的缩进
(setq my-style '("my-style"
"stroustrup"
(indent-tabs-mode . nil)
(c-basic-offset . 4)
(c-offsets-alist
(innamespace . -))))
innamespace
就是控制内部 namespace ,-
表示 innamespace
的缩进是 c-basic-offset
的 -1 倍
c-basic-offset
的值是 4
,innamespace
的缩进就是 0
即 c-basic-offset + (-1 * c-basic-offset)
设置后效果就从上面变成下面这样:
namespace test {
namespace {
int a = 0;
}
class Test final {
public:
void Hello();
};
}
如果我们想让 public:
缩进两个字符
(setq my-style '("my-style"
"stroustrup"
(indent-tabs-mode . nil)
(c-basic-offset . 4)
(c-offsets-alist
(innamespace . -)
(access-label . /)))
/
代表 c-basic-offset
的 -0.5 倍,即 c-basic-offset + (-0.5 * c-basic-offset)
可以通过 c-fallback-style
看哪些语法元素可以定义缩进
相关文档:CC Mode Manual
emacs 不推荐直接改 c-style-alist
,而是通过 c-add-style
增加缩进风格,所以最后的配置可以这样写:
(c-add-style "my-style"
'("stroustrup"
(indent-tabs-mode . nil)
(c-basic-offset . 4)
(c-offsets-alist
(innamespace . -))
))
(add-to-list 'c-default-style '(c++-mode . "my-style"))
(add-to-list 'c-default-style '(c-mode . "my-style"))