每次打开emacs都会生成*scratch*
这个buffer,为了避免这个问题,我们可以在init.el
里加上(kill-buffer "*scratch*")
。
但是有时有需要写一写临时的代码段,比如想写点elisp或python验证某些想法,又不得不建一个临时buffer。
这段代码能解决这个问题:
(defun kermit/create-scratch-buffer ()
(interactive)
(let* ((buf-name (read-from-minibuffer "scratch buffer name: "))
(mode-suffix (read-from-minibuffer "scratch mode suffix: "))
(buf (generate-new-buffer (concat "*scratch-" buf-name "*"))))
(switch-to-buffer buf)
(dolist (e auto-mode-alist)
(let ((mode-regex (car e)))
(if (string-match mode-regex (concat "." mode-suffix))
(funcall (cdr (assoc mode-regex auto-mode-alist))))))
(setq buffer-offer-save t)))
输入编程语言的后缀名比如(el, py),就可以创建任意编程语言的临时buffer。
结合一个扩展state,可以快速创建,切换到这个临时buffer。
(defun kermit/get-buffer-by-regex (regex)
"Get buffer by regex"
(let ((buffers (mapcar (function buffer-name) (buffer-list)))
(target nil))
(dolist (buffername buffers)
(if (string-match-p regex buffername)
(setq target buffername)))
target))
(state-define-state
scratch
:key "s"
:in (string-match "^\*scratch-" (buffer-name))
:exist (kermit/get-buffer-by-regex "^\*scratch-")
:switch (switch-to-buffer (kermit/get-buffer-by-regex "^\*scratch-"))
:create (kermit/create-scratch-buffer))
2 个赞
M-xswitch-to-buffer
RET*.py
不是很简单吗?
直接把 scratch 改成 org-mode 不是更快么……
1 个赞
直接创建的buffer,默认是Fundmental mode
,不是很方便(可以设置init-major-mode,但是也不很灵活)。
噢,我忘了已经把快捷键映射到 helm-mini
了,有了 helm 就可以在创建临时 buffer 的时候,识别后缀名,自动启用 major-mode。无需额外的方法/快捷键。
;; 绑定在C-xC-v上,切换成*scratch* 中,若已经在*scratch*中,则切换成上一个buffer
;;;###autoload
(defun switch-to-scratch-buffer ()
"Toggle between *scratch* buffer and the current buffer.
If the *scratch* buffer does not exist, create it."
(interactive)
(let ((scratch-buffer-name "*scratch*")
(prev-major-mode major-mode)
)
(if (equal (buffer-name (current-buffer)) scratch-buffer-name)
(switch-to-buffer (other-buffer))
(with-current-buffer
(switch-to-buffer scratch-buffer-name)
(when (functionp prev-major-mode) (funcall prev-major-mode ))
(when (equal major-mode 'fundamental-mode )(emacs-lisp-mode))
(goto-char (point-max))))))
当前是org-mode ,通过这个命令切换到scratch 后 scratch变成org-mode
1 个赞
我的命令补全是ido和smex,helm确实能做更多。
我自己类似的实现是新建一个能继承上一个buffer的major-mode的buffer,这样的好处是能有多个buffer存放不同的临时代码,不同major-mode工程之间相互独立,而且某些特殊的不能继承major-mode(比如ess-mode)还可以指定为另外一种major-mode。
(defvar yxl-buffer-inherit-whitelist '(latex-mode
markdown-mode
org-mode
R-mode
python-mode
emacs-lisp-mode)
"modes that are allowed when calling yxl-buffer-inherit")
(defvar yxl-buffer-inherit-special-alist '((ess-mode . R-mode)
(inferior-ess-mode . R-mode)))
(defun yxl-buffer--translate-major-mode ()
"Check if current `major-mode' is in `yxl-buffer-inherit-special-alist',
if true use the translated major-mode, else use original major-mode."
(let* ((curr-mode major-mode)
(curr-mode-sp (cdr (assoc curr-mode
yxl-buffer-inherit-special-alist))))
(if curr-mode-sp curr-mode-sp
curr-mode)))
(defun yxl-buffer-inherit (&optional buf-name)
"Create a new buffer \"untitled\" which inherits the major-mode
of the previous buffer, if the major-mode is listed in
`yxl-buffer-inherit-whitelist'; otherwise use `initial-major-mode'."
(interactive)
(unless buf-name (setq buf-name "untitled"))
(let* ((curr-mode (yxl-buffer--translate-major-mode))
(newbuf (generate-new-buffer-name buf-name)))
(switch-to-buffer newbuf)
(if (member curr-mode yxl-buffer-inherit-whitelist)
(funcall curr-mode)
(funcall initial-major-mode))))
完整代码在github。
这个想法很不错,赞一个,不过我不用ivy,我想我可以这样来实现你的想法
(defun next-same-major-mode-buffer ()
(interactive)
(let ((same-major-mode major-mode)
(i 0))
(next-buffer)
(while (< i 50)
(let ((cur-major-mode major-mode))
(if (eq same-major-mode cur-major-mode)
(setq i 100)
(progn
(next-buffer)
(setq i (1+ i))))))))
(defun prev-same-major-mode-buffer ()
(interactive)
(let ((same-major-mode major-mode)
(i 0))
(previous-buffer)
(while (< i 50)
(let ((cur-major-mode major-mode))
(if (eq same-major-mode cur-major-mode)
(setq i 100)
(progn
(previous-buffer)
(setq i (1+ i))))))))
(global-set-key (kbd "C-x ]") 'next-same-major-mode-buffer)
(global-set-key (kbd "C-x [") 'prev-same-major-mode-buffer)
每次要切换到其他mode就用ido切换。
递归版
;;; recursive version
(defun recursive-version/next ()
(interactive)
(let ((same-major-mode major-mode))
(recur-next same-major-mode)))
(defun recur-next (same-major-mode)
(next-buffer)
(unless (eq same-major-mode major-mode)
(recur-next same-major-mode)))
我是根据每天的日期在固定的位置创建一个类似于2017-05-19-note.org和2017-05-19-scratch.org的文件,前者用来做笔记,后者用来记一些乱七八糟的东西。
这样的好处是所有东西都可以根据时间归档。比如可能有时候粘贴了一些命令。忘了。可以直接过来ag一下。