就是在文件头部插入:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
两行
(eval-after-load 'autoinsert
'(define-auto-insert '(python-mode . "python utf-8 encode")
'("Description: "
"#!/usr/bin/env python" \n
"# -*- coding: utf-8 -*-" \n)))
(auto-insert-mode) ;;; Adds hook to find-files-hook
假如愿意自己动手的话:
(defun chunyang-python-insert-shebang ()
(when (and (eq major-mode 'python-mode)
(bobp) (eobp))
(insert "#!/usr/bin/env python # -*- coding: utf-8 -*-\n")))
(add-hook 'find-file-hook #'chunyang-python-insert-shebang)
autoinsert 和 hook 的问题在于
我更习惯使用 snippet
# -*- mode: snippet -*-
# name: bang
# key: !
# --
#!/usr/bin/env python
$0
只需按 !<TAB>
两个键也不是很麻烦,而且可以根据场景定义不同的 shebang 参数 (在同一个 mode 下)
其实我用的也是snippet
:
# -*- mode: snippet -*-
# name: bomb
# key: !
# --
#!/usr/bin/env python3
# # -*- coding: utf-8 -*-
# author:Samray <[email protected]>
$0
只是提问的同学说:
如何在新建python时自动插入 shebang?
我默认是在所有的 python 都插入 shebang 了
结合auto-insert与yasnippet 模版
;; 利用yasnipet模版,在创新新文件时,自动在文件中插入相应的模版
(autoload 'yas-expand-snippet "yasnippet")
(defun my-autoinsert-yas-expand()
"Replace text in yasnippet template."
(yas-expand-snippet (buffer-string) (point-min) (point-max)))
;;; auto-insert
(setq-default auto-insert-directory (concat user-emacs-directory "auto-insert-template/"))
(unless noninteractive (auto-insert-mode 1)) ;;; Adds hook to find-files-hook
(setq-default auto-insert-query nil) ;;; If you don't want to be prompted before insertion
(define-auto-insert "\\.el$" ["el-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.erl$" ["erl-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.hrl$" ["hrl-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.c$" ["c-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.cpp$" ["c++-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.cc$" ["c++-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.cs$" ["csharp-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.org$" ["org-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.tex$" ["tex-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.py$" ["py-auto-insert" my-autoinsert-yas-expand])
(define-auto-insert "\\.go$" ["go-auto-insert" my-autoinsert-yas-expand])
;; (define-auto-insert "\\.org$" "org-auto-insert")
(provide 'conf-yas-auto-insert)
然后在 .emacs.d/auto-insert-template/py-auto-insert 内 插入你想要的模版内容就行 如
# -*- coding:utf-8 -*-
__author__ = '`user-login-name`'
可以参考我的一些配置
判断下文件是否为空就够了,Auto Insert 就是这么做的,退一步讲,的确不要的话,一个 Undo 就能行了。不过这是用户需求和习惯的问题,谈不上好坏。比如我既不用 auto-insert-mode
也不用 snippet,我手打。
https://www.gnu.org/software/emacs/manual/html_node/autotype/Executables.html
看了下上面的文档,貌似在进入 sh-mode
时,会自动调用 executable-set-magic
填写 shebang。但是实际测试时又没有,不知道哪里的问题?
executable-set-magic
被调用是在sh-set-shell
函数里面,而sh-set-shell
函数在
sh-mode-map
里默认绑定在C-c :上。
不过,在sh-mode
开启的时候,会自动运行
;; Parse or insert magic number for exec, and set all variables depending
;; on the shell thus determined.
(sh-set-shell
(cond ((save-excursion
(goto-char (point-min))
(looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)"))
(match-string 2))
((not buffer-file-name) sh-shell-file)
;; Checks that use `buffer-file-name' follow.
((string-match "\\.m?spec\\'" buffer-file-name) "rpm")
((string-match "[.]sh\\>" buffer-file-name) "sh")
((string-match "[.]bash\\>" buffer-file-name) "bash")
((string-match "[.]ksh\\>" buffer-file-name) "ksh")
((string-match "[.]mkshrc\\>" buffer-file-name) "mksh")
((string-match "[.]t?csh\\(rc\\)?\\>" buffer-file-name) "csh")
((string-match "[.]zsh\\(rc\\|env\\)?\\>" buffer-file-name) "zsh")
((equal (file-name-nondirectory buffer-file-name) ".profile") "sh")
(t sh-shell-file))
nil nil)
sh-set-shell
的3个参数分别是 shell
, no-query-flag
, insert-flag
。
所以可以看到,在打开sh-mode
的时候是不会插入shebang
的。
同时又有一个变量executable-insert
会影响shebang
的更新:
executable-insert |
description |
---|---|
nil |
Do nothing. |
t |
Insert or update magic number. |
other |
Insert or update magic number, but mark as unmodified. |
所以想自动更新shebang
,有几种方式:
M-x
运行executable-set-magic
手工更新 (python-mode
下同样适用)sh-set-shell
sh-shell
这个local variable
来间接达到调用sh-set-shell
advice
机制自己动手修改sh-set-shell
的逻辑注: executable-set-magic
同时也会让文件加上x
执行权限,除非它被executable-magicless-file-regexp
这个正则匹配到了。
@Youmu 多谢解释,那看来最方便的方式还是 yasnippet,然后加上
(add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)
这样脚本就能自动加上执行权限了。