没有扩展名的文件怎么设定Spacemacs打开时采用的模式?fundmental模式怎么设置自动有行号?

问题一:

现在打开.inp、.out等扩展名或者没有扩展名的文件时,Spacemacs默认用fundmental模式,从网上找到可以在user-init 添加如下配置:但如果文件没有扩展名,请问怎么设置?

(add-to-list 'auto-mode-alist '("\\.inp\\'" . text-mode))

问题二:

我现在的配置默认情况下:fundmental模式没有行号,text-mode有行号。 如果在配置中添加:

  ;; 显示行号
  (global-linum-mode)
  (setq column-number-mode t)

所有的buffer都会有行号,但很多mode会有两列行号。

请问怎么单独设置各种mode的行号?

谢谢大家!

关于第一个问题,我的配置:

;; Use text mode for file that doesn't have an extension.
(add-to-list 'auto-mode-alist '("/[^./]*\\'" . text-mode))
;; Use conf-mode for dotfiles.
(add-to-list 'auto-mode-alist '("/\\.[^/]*\\'" . conf-mode))
1 个赞

Emacs 26 以后不要用 (global-linum-mode),这就是你会有两排行号的原因。用 (global-display-line-numbers-mode)。你这网上抄的配置都过时了。

用 mode hook,比如 prog-mode (所有编程用的 mode) 可以用

(add-hook 'prog-mode-hook 'display-line-numbers-mode)
2 个赞

非常感谢,第一个问题已按您的方法解决。

谢谢,请问fundmental mode怎么设置默认带行号?

  (global-display-line-numbers-mode)
  (add-hook 'prog-mode-hook 'display-line-numbers-mode)
  (add-hook 'fundamental-mode-hook 'display-line-numbers-mode)
  (add-hook 'fundamental-mode 'display-line-numbers-mode)

我在user-config 中添加了上面几行后,fundmental mode还是默认不显示行号。

设计上,用户不应该定制 fundmental mode,因为会影响所有 mode。所以它没有 hook。

所以有两种方法:

  1. 开全局,再选不要的关闭
  2. 把新建文件关联到其它 mode,对其它 mode 的 hook 定制
2 个赞

没有扩展名的,可以定制magic-mode-alist

(add-to-list 'magic-mode-alist '((some-fn . text-mode))

1 个赞

1. 不一定非得扩展名/后缀名,前缀、中缀或者全名都可以作为判断依据,例如:

(add-to-list 'auto-mode-alist ("\\`Makefile\\'" . makefile-mode))

甚至路径也可以用来作为判断依据:

(add-to-list 'auto-mode-alist '("md/readme" . markdown-mode))
(add-to-list 'auto-mode-alist '("org/readme" . org-mode))

2. 在文件第一行指定模式:

// test_c -*- mode: c; -*-

3. 通过 file local variable (M-x add-file-local-variable)指定模式:


;; Local Variables:
;; mode: c
;; End:
;; test_c ends here

4. 通过 dir local variable (M-x add-dir-local-variable)指定模式。

这种方式稍复杂,最好对文件加载过程有一定了解,否则可能导致死循环,参考:请教怎样用 .dir-locals.el 来设置一个目录下的文件的 major mode 为 conf-mode? - #2,来自 cireu

5. magic-mode-alistauto-mode-alist 之后的另一道防线。它有两种形式:

5.1 (regex . mode-function)

regex 匹配文件头部内容,例如 shebang 和二进制文件的魔法数字:

;; This regexp matches shebang expressions like `#!/usr/bin/env boot'
(add-to-list 'magic-mode-alist '("#!.*boot\\s-*$" . clojure-mode))
;; "Make `macho-mode' get called automatically for binaries.
(add-to-list 'magic-mode-alist '("\xFE\xED\xFA\xCE" . macho-mode))
5.2 (match-function . mode-function)

match-function 提供更高的自由度,可以做更多的事,例如检查文件内容特征:

(add-to-list 'magic-mode-alist (cons #'spacemacs//javascript-jsx-file-p 'rjsx-mode))
(defun spacemacs//javascript-jsx-file-p ()
  "Enable rjsx mode by using magic-mode-alist."
  (when buffer-file-name
    (and (member (file-name-extension buffer-file-name) '("js" "jsx"))
         (re-search-forward "\\(^\\s-*import React\\|\\( from \\|require(\\)[\"']react\\)"
                            magic-mode-regexp-match-limit t)
         (save-excursion
           (goto-char (match-beginning 1))
           (let ((sexp (syntax-ppss)))
             ;; not inside string or comment
             (not (or (nth 3 sexp)
                      (nth 4 sexp))))))))
10 个赞

感谢大神,原来还能这样用,这样解决了一个困扰我好久的问题,我把php当作html模板语言用,默认用php-mode,当发现php文件里会包含很多htm的内容就回到行首加上-*-web-*-以使用web-mode

其实应该做成自动识别文件内容判断是用web-mode还是php-mode是最好的,现在加上去了,做成了打开文件时判断里面有doctype html就用web-mode,否则不用

(add-to-list 'magic-mode-alist '("\\(.\\|\n\\)*doctype html" . web-mode))

但这样又对所有文件都生效了,任何文件有doctype htm都会用web-mode,有没有办法能做成只对.php后缀名的文件打开时做这个检测,而其它文件不影响

实现你的 match-function

另外,我觉得你的正则表达式 "\\(.\\|\n\\)*doctype html" 匹配条件可能太宽松了,字符串或注释当中如果存在 doctype html 也会被匹配到。

仿写了一段, doctype html确实大宽松了,把<!>也加上,忽略注释中的字符这个不知道怎么搞定

(add-to-list 'magic-mode-alist (cons #'my-php-to-web-mode 'web-mode))
(defun my-php-to-web-mode()
  "php文件打开时检查html字符转为使用web-mode"
  (when buffer-file-name
    (and (member (file-name-extension buffer-file-name) '("php" "inc"))
         (re-search-forward "\\(^\\s-*<!doctype html>\\)" magic-mode-regexp-match-limit t)
          )))

M-x re-builder 调试正则表达式。