最近用上了Emacs原生键位,感觉还行,就是突然写代码,也有一种轻松的感觉了。
请问你是如何使用Emacs的原生键位,我在外网上看到那些博主,用Emacs原生键位写代码的感觉不输evil键位,而且Evil还要改键什么的,我想的是直接换改Emacs原生键位。
有没有什么技巧,或者最佳实践?就是原生键位,对文档操作的,技巧。
感谢!
最近用上了Emacs原生键位,感觉还行,就是突然写代码,也有一种轻松的感觉了。
请问你是如何使用Emacs的原生键位,我在外网上看到那些博主,用Emacs原生键位写代码的感觉不输evil键位,而且Evil还要改键什么的,我想的是直接换改Emacs原生键位。
有没有什么技巧,或者最佳实践?就是原生键位,对文档操作的,技巧。
感谢!
我就是用原生的,基本不改键。Ctrl 在机械键盘上就用手掌外侧,小指根部的肌肉按,习惯后基本感觉不到Ctrl 的存在。
最近在 MacBook 上用的多,Ctrl 用大拇指按,大范围移动靠 avy(绑定了 C-;)以及触摸板像素滚动。台式机也用鼠标滚文档,为了保护手指,我不追求全键盘,让手指能够有休息时间。
M-j 绑定到了 join-line
,默认是M-^,不好按。
关于按键操作,直接用就行了,把官方的指南操作一遍。不熟悉的话,开始可以安装 which-key
。我现在连这个包也不用了,embark 这个包推荐使用,它也有查按键的功能。
其实很多时候会直接用 M-x 找命令,如果安装了 vertico + orderless 类似的包,找命令比按快捷键还要快。
请问下,Emacs的默认键位,有没有像Vim的那样的组合式操作,可以快速编辑文档的技巧。
我需要一个Emacs的编辑文档的操作指南,就是我不知道我用的这点键位就是Emacs Tutorial的键位教学,就是编辑功能的全部了吗。
能否有什么Emacs键位 编辑文档的文章推荐。
感谢!
按 C-h t
读一遍,尝试操作一下就好了。Emacs 的基本操作都在这里,不用很多时间就走完。也有中文版的,我忘记怎么开出来了。
还有忘记按键的话,也在按了前缀(比如 C-x)后按 ?键,弹出一个按键列表。
新手的话最好装一个 which-key
好的,其实我就是读的Tutorial,我以为 emacs还会有什么Tutorial之外的操作技巧。
感谢
其他技巧就后面慢慢积累了,可以多看看本论坛,很多人分享。
你可以在使用过程中,遇到具体的需求,不清楚了,来论坛先搜索,实在找不到答案的话,就开贴提问,一个帖子一个问题。应该有很多大佬可以帮到你。
原生键位上which-key,或者自定义hydra集合,常用的建议还是绑定C-x,另外默认如kill-ring kill-region什么的都要advise一翻才顺手。另外建议可以用colemak布局,跟emacs非常搭。另外还可以左边Alt和Ctrl互换,我用了近十年,告别小指疼。
Emacs
的原生键位本来就强于 vim
的那一套切换来切换去的模式按键,唯一的缺点是比较废小拇指。
自己用的时候实际上可以跟模式按键搭着使用,比如编辑的时候以 Emacs
按键为主,移动或者阅读代码的时候可以配合上模式按键,具体怎么搭还是要根据自己的实际情况来定。
text object相关的技巧,可以用evil的api(如evil-define-text-object
)写自己的text object.
这里有几个自定义text object的例子,
其他技巧就是拼插件了.可以从melpa上下载最多的插件看起,
最好是看插件官方文档和代码. 通用的入门教程不可能在每个插件上做深入讲解.
在用 Evil 之前,主要是通过 xcape 将 Ctrl 和 Space 合并成同一个按键。
然后是:
(global-set-key (kbd ", ,") (lambda () (interactive) (insert ",")))
(global-set-key (kbd ", SPC") (lambda () (interactive) (insert ", ")))
(global-set-key (kbd ", RET") (lambda () (interactive) (insert ",") (newline)))
将逗号接空格绑定为输入一个逗号和空格,因为绝大多数写代码的时候,输入了逗号后面都应该接空格或回车。
这样就多出非常多以逗号开头的键绑定可以用了。
God mode
右ctrl和大小写换下就好了,mac和win都这么搞了,省事不少
Meow + one-key,基本上不要同时多个键一起按,按顺序按就好了。
(defun meow-setup ()
(meow-motion-overwrite-define-key
'("j" . meow-next)
'("k" . meow-prev))
(meow-leader-define-key
;; SPC j/k will run the original command in MOTION state.
'("j" . "H-j")
'("k" . "H-k")
;; Use SPC (0-9) for digit arguments.
'("1" . meow-digit-argument)
'("2" . meow-digit-argument)
'("3" . meow-digit-argument)
'("4" . meow-digit-argument)
'("5" . meow-digit-argument)
'("6" . meow-digit-argument)
'("7" . meow-digit-argument)
'("8" . meow-digit-argument)
'("9" . meow-digit-argument)
'("0" . meow-digit-argument)
'("/" . meow-keypad-describe-key)
'("?" . meow-cheatsheet))
(meow-normal-define-key
'("0" . meow-expand-0)
'("9" . meow-expand-9)
'("8" . meow-expand-8)
'("7" . meow-expand-7)
'("6" . meow-expand-6)
'("5" . meow-expand-5)
'("4" . meow-expand-4)
'("3" . meow-expand-3)
'("2" . meow-expand-2)
'("1" . meow-expand-1)
'("-" . negative-argument)
'(";" . meow-reverse)
'("," . meow-inner-of-thing)
'("." . meow-bounds-of-thing)
'("[" . meow-beginning-of-thing)
'("]" . meow-end-of-thing)
'("a" . meow-append)
'("A" . meow-open-below)
'("b" . meow-back-word)
'("B" . meow-back-symbol)
'("c" . meow-change)
'("d" . meow-delete)
'("D" . meow-backward-delete)
'("e" . meow-next-word)
'("E" . meow-next-symbol)
'("f" . meow-find)
'("g" . meow-cancel-selection)
'("G" . meow-grab)
'("h" . meow-left)
'("H" . meow-left-expand)
'("i" . meow-insert)
'("I" . meow-open-above)
'("j" . meow-next)
'("J" . meow-next-expand)
'("k" . meow-prev)
'("K" . meow-prev-expand)
'("l" . meow-right)
'("L" . meow-right-expand)
'("m" . meow-join)
'("n" . meow-search)
'("o" . meow-block)
'("O" . meow-to-block)
'("p" . meow-yank)
'("q" . meow-quit)
'("Q" . meow-goto-line)
'("r" . meow-replace)
'("R" . meow-swap-grab)
'("s" . meow-kill)
'("t" . meow-till)
'("u" . undo)
'("U" . undo-redo)
;; '("u" . meow-undo)
;; '("U" . meow-undo-in-selection)
'("v" . meow-visit)
'("w" . meow-mark-word)
'("W" . meow-mark-symbol)
'("x" . meow-line)
'("X" . meow-goto-line)
'("y" . meow-save)
'("Y" . meow-sync-grab)
'("z" . meow-pop-selection)
'("'" . repeat)
'("<escape>" . mode-line-other-buffer)))
(add-hook 'after-init-hook 'meow-setup)
(meow-global-mode)
(setq meow-use-clipboard t)
(add-to-list 'meow-mode-state-list '(netease-cloud-music-mode . motion))
(add-to-list 'meow-mode-state-list '(osx-dictionary-mode . motion))
(add-to-list 'meow-mode-state-list '(stock-tracker-mode . motion))
(add-to-list 'meow-mode-state-list '(elfeed-show-mode . normal))
(add-to-list 'meow-mode-state-list '(elfeed-summary-mode . motion))
(add-to-list 'meow-mode-state-list '(helpful-mode . normal))
(add-to-list 'meow-mode-state-list '(calibredb-search-mode . motion))
(add-to-list 'meow-mode-state-list '(Info-mode-hook . motion))
;; (advice-add 'org-edit-special :after 'meow-insert)
(require 'one-key)
(setq one-key-popup-window nil)
(meow-leader-define-key '("a" . my/org-agenda))
(one-key-create-menu
"BIBTEX"
'((("a" . "Actions") . orb-note-actions)
(("o" . "open") . consult-bibtex-open-any)
(("e" . "entry") . consult-bibtex-show-entry)
(("n" . "note") . my/edit-notes)
(("x" . "extract annots") . my/extract-pdf-annots-to-ref-note))
t)
(meow-leader-define-key '("b" . one-key-menu-bibtex))
(one-key-create-menu
"DIRECTORY"
'((("c" . "Cloud") . (lambda () (interactive) (dired "~/Nextcloud/")))
(("d" . "Downloads") . (lambda () (interactive) (dired "~/Downloads/")))
(("p" . "Pictures") . (lambda () (interactive) (dired "~/Pictures/"))))
t)
(meow-leader-define-key '("d" . one-key-menu-directory))
(one-key-create-menu
"FILE"
'((("f" . "FINANCE") . one-key-menu-beancount)
(("r" . "recent") . consult-recent-file)
(("o" . "open") . one-key-menu-specific-file)
(("e" . "External") . xah-html-open-in-safari))
t)
(meow-leader-define-key '("f" . one-key-menu-file))
(one-key-create-menu
"SPECIFIC-FILE"
'((("b" . "Blog file") . (lambda () (interactive) (find-file "~/hugo-source/content-org/all-posts.org")))
(("I" . "README.org") . (lambda () (interactive) (find-file (expand-file-name "README.org" user-emacs-directory))))
(("i" . "Inbox") . (lambda () (interactive) (find-file (expand-file-name "daily/inbox.org" my-galaxy))))
(("r" . "rss") . (lambda () (interactive) (find-file (expand-file-name "main/elfeed.org" my-roam))))
(("g" . "gtd") . (lambda () (interactive) (find-file (expand-file-name "todos/org-gtd-tasks.org" my-galaxy))))
(("a" . "alipay") . (lambda () (interactive) (find-file (expand-file-name "alipay.bean" my-finance-year))))
(("m" . "Beancount main") . (lambda () (interactive) (find-file (expand-file-name "main.bean" my-finance)))))
t)
(one-key-create-menu
"ORG"
'((("c" . "Capture") . one-key-menu-org-capture)
(("d" . "Download") . one-key-menu-download)
(("p" . "Process") . org-gtd-process-inbox)
(("P" . "Pomodoro") . org-pomodoro)
(("l" . "cliplink") . org-cliplink)
(("i" . "ID") . org-id-get-create)
(("t" . "Transclusion") . one-key-menu-transclusion))
t)
(meow-leader-define-key '("o" . one-key-menu-org))
(one-key-create-menu
"DOWNLOAD"
'((("c" . "clipboard") . org-download-clipboard)
(("i" . "image") . org-download-image)
(("r" . "rename") . org-download-rename-at-point)
(("s" . "screenshot") . org-download-screenshot))
t)
(one-key-create-menu
"TRANSCLUSION"
'((("a" . "Add") . org-transclusion-add)
(("A" . "Add all") . org-transclusion-add-all)
(("r" . "Remove") . org-transclusion-remove)
(("R" . "Remove all") . org-transclusion-remove-all)
(("g" . "Refresh") . org-transclusion-refresh)
(("m" . "make") . org-transclusion-make-from-link)
(("o" . "Open") . org-transclusion-open-source)
(("e" . "Edit") . org-transclusion-live-sync-start))
t)
(one-key-create-menu
"ORG-CAPTURE"
'((("d" . "Diary") . (lambda () (interactive) (my/org-capture-shortcut "d")))
(("t" . "Today tasks") . (lambda () (interactive) (my/org-capture-shortcut "tt")))
(("T" . "Date tasks") . (lambda () (interactive) (my/org-capture-shortcut "td")))
(("i" . "Inbox") . (lambda () (interactive) (my/org-capture-shortcut "i")))
(("r" . "Random note") . (lambda () (interactive) (my/org-capture-shortcut "r")))
(("s" . "Code Snippet") . (lambda () (interactive) (my/org-capture-shortcut "s"))))
t)
(one-key-create-menu
"LANGUAGE"
'((("t" . "Translate") . gts-do-translate)
(("f" . "Fanyi Point") . fanyi-dwim2)
(("F" . "Fanyi Input") . fanyi-dwim)
(("d" . "Dictionary Point") . osx-dictionary-search-pointer)
(("D" . "Dictionary Input") . osx-dictionary-search-input)
(("t" . "Thesaurus") . powerthesaurus-lookup-dwim)
(("s" . "Style region") . smog-check)
(("S" . "Style buffer") . smog-check-buffer))
t)
(meow-leader-define-key '("l" . one-key-menu-language))
(one-key-create-menu
"ROAM"
'((("a" . "Alias") . one-key-menu-roam-alias)
(("b" . "Roam Buffer") . my/org-roam-buffer-turn-on-off)
(("c" . "Roam capture") . org-roam-capture)
(("d" . "Dailies") . one-key-menu-roam-dailies)
(("f" . "Node find") . org-roam-node-find)
(("i" . "Node insert") . org-roam-node-insert)
(("s" . "Search content") . bms/org-roam-rg-search)
(("t" . "Tags") . one-key-menu-roam-tags)
(("r" . "Ref") . one-key-menu-roam-ref)
(("u" . "UI") . one-key-menu-roam-ui))
t)
(meow-leader-define-key '("r" . one-key-menu-roam))
(one-key-create-menu
"ROAM-ALIAS"
'((("a" . "Add") . org-roam-alias-add)
(("r" . "Remove") . org-roam-alias-remove))
t)
(one-key-create-menu
"ROAM-DAILIES"
'((("t" . "Today") . org-roam-dailies-find-today)
(("y" . "Yesterday") . org-roam-dailies-find-yesterday)
(("d" . "Directory") . org-roam-dailies-find-directory)
(("j" . "Date") . org-roam-dailies-goto-date)
(("p" . "Past Diary") . my/history-morning-diary))
t)
(one-key-create-menu
"ROAM-REF"
'((("a" . "Add") . org-roam-ref-add)
(("f" . "Find") . org-roam-ref-find)
(("r" . "Remove") . org-roam-ref-remove))
t)
(one-key-create-menu
"ROAM-TAGS"
'((("a" . "Add") . org-roam-tag-add)
(("c" . "Completion") . org-roam-tag-completions)
(("r" . "Remove") . org-roam-tag-remove))
t)
(one-key-create-menu
"ROAM-UI"
'((("o" . "Open") . org-roam-ui-open)
(("l" . "Local") . org-roam-ui-node-local)
(("z" . "Zome") . org-roam-ui-node-zoom)))
(one-key-create-menu
"WINDOWS"
'((("d" . "Destroy") . kill-this-buffer)
(("h" . "Left") . windmove-left)
(("j" . "Down") . windmove-down)
(("k" . "Up") . windmove-up)
(("l" . "Right") . windmove-right)
(("e" . "Email") . mu4e)
(("r" . "RSS") . elfeed-summary)
(("t" . "Telega") . telega)
(("m" . "Message") . (lambda () (interactive) (switch-to-buffer "*Messages*")))
(("s" . "scratch") . (lambda () (interactive) (switch-to-buffer "*scratch*")))
(("u" . "Winner Undo") . winner-undo)
(("v" . "vundo") . vundo))
t)
(meow-leader-define-key '("w" . one-key-menu-windows))
(one-key-create-menu
"TOOLS"
'((("o" . "Outline") . consult-outline)
(("m" . "Menu") . my/imenu-list-on-off))
t)
(meow-leader-define-key '("t" . one-key-menu-tools))
(one-key-create-menu
"BLOG"
'((("h" . "Easy hugo") . easy-hugo)
(("n" . "New post") . easy-hugo-newpost)
(("g" . "Magit") . easy-hugo-magit)
(("p" . "note") . easy-hugo-preview)
(("t" . "Tags") . easy-hugo-complete-tags))
t)
模式化主要是增加了一个维度,解放了出来很多可以 map 的键。复杂场景下不可能沿用一套按键的,在一个场景下适用的按键在另一个场景下就显得格格不入。
正确的做法应该是场景化绑定或者说上下文绑定。在不同 buffer、window、文件类型… 甚至同一buffer 不同段落等各自有其特定含义(感觉是不是和 button、switch 等“现代”元素很像?),并尽量向语义化、易记易发现方面靠拢。
这样不可避免地带来一些困惑,这些困惑可能来自用户没有意识到 context 已经切换,可能来自默认绑定不符合用户期望… 这些困惑怎么解决?答案是感官反馈。比如把光标形状从指针换成细线/十字,背景色文字颜色,增加 panel、button 等…甚至 notification、beep 声等。这点上 vim/emacs 等很多人因为是自用的配置,不会过多去关注。
通用型应用为了照顾大多数,一般很少向用户强调 context 切换。但 context 切换这一事实是真实存在的,正如复杂性不可能凭空消失一样。当然,一些用户因为自身需求并不想 context 切换,也不想理解 context 切换。这是自身需求决定的,并没有高下之分。
但如果你想要你的应用如手术刀一般精确,你应该适应 context 切换,并尝试定制自己的工作流。
因为逗号用右手中指输入,是最轻松的一个非字母按键。
按下一个(组合)键,(选中)按下右键鼠标,点按 panel 中一个 button,滚动到 buffer 某 viewport,本质上都属于 context 切换。Emacs 在感官反馈呈现形式是很强的,可以深度定制极大地降低学习成本减少困惑。但是很多功能没有内置需要额外包,或者没有很方便的 ad-hoc override 输入方式,这点对比 Vim 通常只需要输入一行命令,多数配置都是内置 api 调用几乎没有自定义函数,非常易懂,这是它做得好的地方。
用了几年vim,最近才了解到 text object 这个概念,思路突然清晰了很多
最近发现用key-chord 设置成 空格和其他按键 的组合,突然感觉多了好多有用的按键。
text object? 就是yw, cw什么的吧,扩展到操作() {}之类? emacs也有类似的东西,有个easy-kill可以实现copy这些对象,easy-mark可以选中这些对象,然后可以执行vim的y/d/c之类的命令了。不过我还是习惯无脑expand region选中再操作。