我的感觉是:
tab 鼠标/GUI 友好;helm/ivy 键盘/终端友好。
tab 用视觉定位,所以相邻 tabs 切换很直观,但相隔远了按键跟不上眼睛,需要鼠标操作;helm/ivy 用关键字定位,所以不惧远近,但也可以免搜索一键切换前/后/最近的 buffer。
用 tab "被迫"养成控制 tabs 数量的习惯;用 helm/ivy 则眼不见为净。
tab 排列顺序跟文件打开先后有关,可以手动辅助调整;helm/ivy 则会根据使用频度来调整 buffer 顺序(如果 tab 也根据频度调整,视觉感受估计不太好)
综合各位的观点,我打算把 tab 纳入配置。这样当我单手操作/只读文件的时候,可以用 tab 来切换(以前都是开一个 sublime text)。不过无论 awesome-tab 还是 centaur-tabs 都跟 helm 冲突(ema2159/centaur-tabs#110 ),M-x
一片空白:
3 个赞
wd1
2021 年8 月 10 日 02:20
65
哇,这个看着超厉害的。我现在使用 doom emacs 习惯使用 ivy,之前试过切换到 embark 就费了好大劲,最后还是不爽又换回来了。没有勇气换 snails。。
snails是重新实现的helm简化版,只专注于搜索和回车,没有多余的乱七八糟功能,性能也好,也好维护。
用舒服就一直舒服,不会像helm那样配置复杂,最后没法维护。
它可以像vscode那样性感弹出小窗口,也可以像helm那样弹出底部窗口。
可以用 tab-line-mode,27在之后自带功能,我这个性能不错,比较轻量。
如果括号不匹配还请见谅:
(use-package tab-bar
:if(> emacs-major-version 26)
:config
(require 'tab-line)
(require 'projectile)
(tab-bar-mode -1)
(global-tab-line-mode t)
;; set a local variable to boost performance
(defvar buffer-project-name "~")
(make-local-variable 'buffer-project-name)
(defun my/update-buf-proj-name()
(if (projectile-project-p)
(setq-local buffer-project-name (projectile-project-name))
(setq-local buffer-project-name "other")))
;; update local variable when major mode changes
(add-hook 'after-change-major-mode-hook 'my/update-buf-proj-name)
(defun my/tab-line-buffer-group (buffer)
(interactive)
(with-current-buffer buffer
(cond
((s-match "scratch" (buffer-name)) "Scratch")
((string= major-mode "eshell-mode") "Eshell")
((string= major-mode "dired-mode") "Dir")
((string= major-mode "ranger-mode") "Dir")
((string= major-mode "vterm-mode") "vTerm")
((s-match "Customize" (buffer-name)) "Customize")
((s-match "magit:" (buffer-name)) "Magit")
((s-match "magit " (buffer-name)) "Magit others")
((s-match "magit-" (buffer-name)) "Magit others")
((string= (s-left 1 (buffer-name)) "*") "Utilities")
;; group buffers using projectile
((boundp 'buffer-project-name) buffer-project-name)
(major-mode (format-mode-line mode-name))
(t "other"))))
(setq tab-line-tabs-buffer-group-function #'my/tab-line-buffer-group)
(setq tab-line-tabs-function #'tab-line-tabs-buffer-groups)
)
3 个赞
wd1
2021 年8 月 11 日 02:28
69
好像写了点代码配合 persp-mode 基本实现了我的需要。。先凑合用着吧。。
写的时候发现这个 centaur-tabs-buffer-groups
居然是不停的运行的。。我移动光标他也执行。。难怪会慢。。。还好我也没多少逻辑。。
(defun wd/get-buffer-persp-group (buffer)
(let* ((name))
(dolist (persp (persp-persps))
(if persp
(if (persp-contain-buffer-p buffer persp)
(setq name (safe-persp-name persp)))))
name
))
(defun centaur-tabs-buffer-groups ()
(list
(cond
((or (string-equal "*" (substring (buffer-name) 0 1))
(memq major-mode '(magit-process-mode
magit-status-mode
magit-diff-mode
magit-log-mode
magit-file-mode
magit-blob-mode
magit-blame-mode
)))
"Emacs")
;; ((derived-mode-p 'eshell-mode)
;; "EShell")
;; ((derived-mode-p 'emacs-lisp-mode)
;; "Elisp")
;; ((derived-mode-p 'dired-mode)
;; "Dired")
((memq major-mode '(org-mode org-agenda-mode diary-mode))
"OrgMode")
(t
(let ((name (wd/get-buffer-persp-group (current-buffer))))
(if name
name
;;(centaur-tabs-get-group-name (current-buffer))
"Other"
)
)))))
我是把window当tab用的,在一个显示器/frame里面,合适的window数是1~4,最多4个可以满足大概70%的需求,短时间内不用切换buffer,剩下的情况就只能切了。
好处是,在这70%的情况里,我可以直接看buffer内容来选择一个buffer/window,这不比看tab条或ivy的buffer列表香?
分window的问题是每个window相对于只有一个的window要小一些,我觉得 [偶尔maximize再返回] 能无痛解决这个问题。
;; from https://gist.github.com/3402786
(defun toggle-maximize-window ()
"Maximize window."
(interactive)
(if (and (= 1 (length (window-list)))
(assoc ?_ register-alist))
(jump-to-register ?_)
(progn
(window-configuration-to-register ?_)
(delete-other-windows))))
当然还要保存window layout,eyebrowse简单好用,persp我记得有“不同的workspace能看到的open buffer是不同的”功能,很反直觉。
2 个赞
wd1
2021 年8 月 14 日 01:08
72
讲道理在写一个局部的功能的时候(20分钟),4个window应该足够了,但是工作中会碰到项目的convention是一个功能要拆好几个文件的情况(硬要mvc,硬要interface+class),我有两种勉强能避免不断调起ivy的practice:
使用alternate-buffer-back-and-forth
命令,把比如.model
和.sql
文件贴到一个window的正反两面,这样我一个frame的buffer容量能增加到4*2=8个。
开两个window layout,SPC l TAB
来回切,适用于“抄个项目,被抄的项目放一个layout,我的抄出来的放一个”这种情况。
(defun alternate-buffer (&optional window)
"Switch back and forth between current and last buffer in the
current window."
(interactive)
(let ((current-buffer (window-buffer window)))
;; if no window is found in the windows history, `switch-to-buffer' will
;; default to calling `other-buffer'.
(switch-to-buffer
(cl-find-if (lambda (buffer)
(not (eq buffer current-buffer)))
(mapcar #'car (window-prev-buffers window))))))
3 个赞