emacs 配置总结

目录

1. emacs

1.1. org-mode

1.1.1. 配置 org-protocol

org-protocol 可以捕获外部程序的内容, 如浏览器的数据可以发送至 org-roam 配置文件:

(require 'org-roam-protocol)
配置 linux xdg

建立 ~/.local/share/applications/org-protocol.desktop :

[Desktop Entry]
Name=Org-Protocol
Exec=emacsclient %u
Icon=emacs-icon
Type=Application
Terminal=false
MimeType=x-scheme-handler/org-protocol

配置 xdg-mime

xdg-mime default org-protocol.desktop x-scheme-handler/org-protocol

测试

open org-protocol://roam-ref\?template=r\&ref=test\&title=this

1.1.2. 配置org 导出makedown

参考链接:org 导出md 在init-local.el 内添加:

(with-eval-after-load 'org
(add-to-list 'org-export-backends 'md))

1.1.3. 配置 org-roam 日志模板

添加配置:

(setq org-roam-dailies-capture-templates
      '(("d" "default" entry
         "* %?"
         :target (file+head "%<%Y-%m-%d>.org"
                            "#+TITLE: %<%Y-%m-%d>\n#+AUTHOR: [[https://xiliuya.github.io/][xiliuya]]\n#+EMAIL: xiliuya@163.com\n#+LANGUAGE: zh-CN\n#+HTML_HEAD: <link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/org.css\"/>\n#+OPTIONS: todo:nil num:3 H:4 ^:nil pri:t\n#+TAGS:  { 糟糕(1) 凑合(2) 不错(3) 很好(4) 极品(5) }\n#+COLUMNS: %10ITEM %10PRIORITY %15TODO %65TAGS"
                            )
         :unnarrowed t)))
配合 yas 使用模板

新建了一个 tem 模板, 可以直接将内容补全

# -*- mode: snippet -*-
# name: temp
# key: tem
# --
工作
** 配置emacs
$0
** Lisp 学习
* 娱乐
** TODO 看电影 题材任意
** TODO 欣赏音乐
** TODO 读诗
** TODO 看一个任意题材的TED演讲 并记录

1.1.4. 配置 org-roam 关联笔记

相关链接: org-roam 配置 经过翻阅官方的文档进行以下配置, 加入 init-local.el :

(require-package 'org-roam)
(require-package 'org-roam-ui)

(global-set-key (kbd "C-c n l")  'org-roam-buffer-toggle)
(global-set-key (kbd "C-c n g") 'org-roam-graph)
(global-set-key (kbd "C-c n i") 'org-roam-node-insert)
(global-set-key (kbd "C-c n c") 'org-roam-capture)
(global-set-key (kbd "C-c n j") 'org-roam-dailies-capture-today)

(global-set-key (kbd "C-c n d") 'org-id-get-create)

(setq org-roam-directory "~/myday")
(setq org-roam-node-display-template
      (concat "${title:*} "
              (propertize "${tags:10}" 'face 'org-tag)))
(org-roam-db-autosync-mode)
;; If using org-roam-protocol
(require 'org-roam-protocol)


(setq find-file-visit-truename t)

(setq org-roam-ui-sync-theme t
      org-roam-ui-follow t
      org-roam-ui-update-on-save t
      org-roam-ui-open-on-start t)
基本使用

通过 M-x org-id-get-create 给现有的小标题生成一个 node id. 通过 M-x org-roam-db-sync 刷新数据库. 通过 M-x org-roam-ui-mode 启动一个本地服务器, 并打开一个浏览器窗口.

功能理解

一款酷炫的插件, 可以简单而美观的管理众多的笔记. 基于 org-mode 简化新建日志的步骤. 便于梳理笔记形成可视化图像. 极大简化了查找笔记的时间成本. 易于翻阅加深记忆.

1.1.5. org-roam 添加快捷键

原先已配置了相关快捷键, 现在多加几个, 需要的键绑定 org-roam-node-findorg-roam-capture 区别在于打开的方式不同.

(global-set-key (kbd "C-c n f") 'org-roam-node-find)
(global-set-key (kbd "C-c n u") 'org-roam-ui-open)

1.1.6. 配置 org-modern-mode

org-modern 是一个 org-mode 美化插件 通过在配置文件加入:

;;; 配置 org-modern
(add-hook 'org-mode-hook 'org-modern-mode)

1.1.7. 配置org-mode 导出样式

org-mode 导出markdown 格式, 再通过jekyll 转换为html 静态页面的过程过于繁琐. 而且效果并不美观. 故而直接使用org 配置css导出html .

参考链接: emacs-china 官方手册相关页: org-mode

TITLE: 主页
HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://gongzhitaao.org/orgcss/org.css"/>

建立yasnippet模板:

# -*- mode: snippet -*-
# name: css for html export
# key: css
# --
#+TITLE: ${1:`(file-name-base buffer-file-name)`}
#+OPTIONS: toc:nil num:3 H:4 ^:nil pri:t
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://gongzhitaao.org/orgcss/org.css"/>

$0

1.1.8. 配置 org-mode 导出头

加入配置:

;; 配置 html 导出头
(setq org-html-head "<link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/org.css\"/>")

隐藏 todo 需要配置 options: todo:nil

1.1.9. 配置 emacs org-download

参考文档: org-mode 中愉快地嵌入图片 参考大佬配置: tumashu

  • 使用快捷键 C-c s s 进行截图插入
  • 使用快捷键 C-c s c 进行剪贴板插入
;;; org-download 配置
(require 'org-download)
;;;(setq org-download-screenshot-method "flameshot gui --raw >%s")
(setq org-download-screenshot-method "grim -g \"$(slurp)\" %s")
;;;(setq org-download-method 'directory)

;;; 屏蔽默认的图片保存, 直接保存到 ./images/xxx.png
(setq-default org-download-heading-lvl nil)
(setq-default org-download-image-dir "./images")
;;; 屏蔽默认的插入头
(defun dummy-org-download-annotate-function (link)
  "" )
(setq org-download-annotate-function
      #'dummy-org-download-annotate-function)
;;; 取消默认的显示图片
(setq org-download-display-inline-images nil)

;;; 定义快捷键
(define-key org-mode-map (kbd "C-c s s") #'org-download-screenshot)
(define-key org-mode-map (kbd "C-c s c") #'org-download-clipboard)

1.1.10. 配置 mpv 插件

是一个 nognu 的包 可以在 emacs 调用命令 以窗口的形式播放视频.

1.1.11. 配置 org-mpv-notes

安装后无需配置直接可以通过插入 mpv: 链接 在 org 内插入视频. (但是,只是以文件链接的形式导出) 如下所示: mpv 西部往事BD中英双字.mp4 通过: org-mpv-notes-insert-note 插入时间戳及笔记 通过光标停在下方笔记并执行: org-mpv-notes-this-timestamp 插入时间戳 注意时间戳不分文件,只是跳转到对应时间.

mpv
开启会自动打开 mpv

通过在配置文件内加入:

  ;;; 配置 org-mpv-mode
(with-eval-after-load 'org-mpv-notes
  (define-minor-mode org-mpv-notes
    "Org minor mode for Note taking alongside audio and video.
  Uses mpv.el to control mpv process"
    :keymap `((,(kbd "M-n i") . mpv-insert-playback-position)
              (,(kbd "M-n M-i") . org-mpv-notes-insert-note)
              (,(kbd "M-n u") . mpv-revert-seek)
              (,(kbd "M-n s") . org-mpv-notes-save-screenshot)
              (,(kbd "M-n o") . org-mpv-notes-open)
              (,(kbd "M-n k") . mpv-kill)
              (,(kbd "M-n t") . org-mpv-notes-this-timestamp)
              (,(kbd "M-n M-s") . org-mpv-notes-screenshot-ocr))
    (if org-mpv-notes
        ()
      (mpv-kill))))

(add-hook 'org-mode-hook 'org-mpv-notes)

1.1.12. 配置 org 使用 prose-mode

只需要 hook 到 org-mode-hook ,期间修复 flyspell-mode 报错 Can’t find Hunspell dictionary 当打开时,不必要的 writeroom-mode 干扰了使用. 经过研究 writeroom-mode 本来就为了排除干扰,删除了 hook 建议手动启动使用

;;(add-hook 'org-mode-hook 'prose-mode)

1.1.13. 配置 org 任务管理颜色

  • 默认配置 通过设定 org-todu-keywords 配置默认任务管理.加入以下配置颜色:

    ;;; 配置 todo 颜色
    (setq org-todo-keyword-faces '(("TODO" . "red")
                                   ("NEXT" . "yellow")
                                   ("DONE" . "green")))
    
  • org-modern 使用 org-modern 时的显示. 根据备注配置无效,通过 org-modern/issues/76 配置颜色,颜色参考:颜色中英文对照 .加入配置:

    ;;; 配置 org-modern-todo 配色
    
    (setq org-modern-todo-faces
          '(("TODO" :foreground "silver" :inverse-video t)
            ("NEXT" :foreground "white" :inverse-video t)
            ;;("DONE" :foreground "gray" :inverse-video t)
            ("PROJECT" :foreground "violet" :inverse-video t)
            ("CANCELLED" :foreground "tan" :inverse-video t)
            ))
    

1.1.14. 配置 org-transclusion

不做过多配置,只加入包 require-package

1.1.15. 使用 org-transclusion

链接头

通过在链接前加入: #+transclude: 得到一个 transclude 链接. :only-contents 仅嵌入内容 :exclude-elements 排除某些元素 :src python 嵌入文件到代码块 :src python :rest ":session :results value" 代码块额外的参数. :lines 3-5 嵌入第 3-5 行 :level 资产价值

基本操作
  • org-transclusion-mode 自动应用到当前 buffer
  • org-transclusion-add-all 将所有 #+transclude: 链接转换为嵌入内容
  • org-transclude-add 将当前链接转换为嵌入内容
  • org-transclude-remove 取消嵌入内容的显示
  • org-transclude-remove-all 取消当前 buffer 所有嵌入内容的显示
  • org-transclusion-make-from-link 将光标所在的普通链接转换为 #+transclude: 链接并输出到 buffer 最后一行(实际上只是加了个头)
  • org-transclude-refresh 刷新当前 buffer 所有嵌入内容的改动
  • org-transclude-live-sync-start 进入同步嵌入内容的改动(不支持代码块)
  • org-transclude-live-sync-exit 退出同步嵌入内容的改动

1.1.16. 转换 org-roam 链接为 org-transclude 嵌入块

暂时不考虑递归,由于复制到 buffer 后仍是不可读字符. 定义如下函数:

;;; org 导出到 html , 并将 org-roam-node 转换为 org-transclude 块
(defun xiliuya/org-roam-to-html ()
  "Export org to html covert org-roam-node to org-transclude."
  (interactive)
  (goto-char (point-min))
  (while (search-forward "[[id:" nil t)
    (progn (replace-match "\n#+transclude: [[id:")
           ;;(org-transclusion-add)
           ))
  (org-transclusion-add-all)
  (org-html-export-to-html)
  (org-transclusion-remove-all)
  (goto-char (point-min))
  (sit-for 1)
  (while (search-forward "\n#+transclude: [[id:" nil t)
    (replace-match "[[id:"))
  )
;;(xiliuya/org-roam-to-html)

1.1.17. org-mode 中文表格显示优化

通过使用 valign-mode 自动对齐字体,暂时不加入 hook

1.2. evil

1.2.1. 配置evil jk 返回正常模式

vi/ vim/ evil 自带快捷键: C-[ . 可以从 插入模式 切换回 正常模式 . 但是有些不便. 简单的配置键绑定:

(local-set-key (kbd "jk") 'evil-normal-state))

可以在当前buffer 执行 C-x C-e 后使用. 但无法在add-hook 中使用,而global-set-key 不支持(kbd "jk"). 通过论坛, 查找到了方案: emacs-china. 可以用 evil-escape 插件实现.

安装 evil-escape
M-x package-install RET evil-escape RET
配置 evil-escape

加入配置:

(with-eval-after-load 'evil
  (evil-escape-mode))
(setq-default evil-escape-key-sequence "jk")
(setq-default evil-escape-delay 0.2)

1.2.2. 配置evil 正常模式下 org TAB

;;; 配置org-mode 下正常模式的 tab 切换
(define-key evil-normal-state-map (kbd "<tab>") 'org-cycle)

1.2.3. 配置 evil 插入模式快捷键

参照论坛大佬配置: 参考链接: evil 键绑定调整

(defun maple/define-key (keymap key def &rest bindings)
  "Define multi keybind with KEYMAP KEY DEF BINDINGS."
  (interactive)
  (while key
    (define-key keymap key def)
    (setq key (pop bindings)
          def (pop bindings))))

(maple/define-key evil-insert-state-map
                  (kbd "M-h") (kbd "<left>")
                  (kbd "M-l") (kbd "<right>")
                  (kbd "M-j") (kbd "<down>")
                  (kbd "M-k") (kbd "<up>"))

为了与 vim 一致使用上述绑定. 同时因为pyim 绑定与 M-j 冲突已经换为 M-'

1.2.4. 配置 evil-ex 自定义 cmd

可以通过 evil-ex 定义一个在命令模式下执行的命令:

  • 使用 :k 调用 kill-this-buffer

    (evil-ex-define-cmd "k[illbuffer]" 'kill-this-buffer)
    

1.3. auto-insert

1.3.1. 配置auto-insert模板

参考链接: Emacs 模板 经过对比发现emacswiki 较为清晰易于使用 链接: autoinsert emacswiki 使用 github 上找到的模板: 模板链接: jaypei/exz-conf 通过在 init-local.el 加入:

;;; 使用auto-insert
(add-hook 'find-file-hook 'auto-insert)
(add-hook 'find-file-hook #'yas-minor-mode)
(setq user-full-name "xiliuya")
;;; (auto-insert-mode 1)
(defun my/autoinsert-yas-expand()
  "Replace text in yasnippet template."
  (yas-expand-snippet (buffer-string) (point-min) (point-max)))
(custom-set-variables
 '(auto-insert 'other)
 '(auto-insert-directory "~/.emacs.d/templates/")
 '(auto-insert-alist '(
                       (("\\.\\([Hh]\\|hh\\|hpp\\)\\'"
                         . "C / C++ header")
                        . ["template.h" c++-mode my/autoinsert-yas-expand])
                       (("\\.\\([cC]\\|cc\\|cpp\\)\\'"
                         . "C++ source")
                        . ["template.c" my/autoinsert-yas-expand])
                       (("\\.rs\\'"
                         . "Rust source")
                        . ["template.rs" my/autoinsert-yas-expand])
                       (("\\.sh\\'"
                         . "Shell script")
                        . ["template.sh" my/autoinsert-yas-expand])
                       (("\\.el\\'" . "Emacs Lisp")
                        . ["template.el" my/autoinsert-yas-expand])
                       (("\\.pl\\'"
                         . "Perl script")
                        . ["template.pl" my/autoinsert-yas-expand])
                       (("\\.pm\\'"
                         . "Perl module")
                        . ["template.pm" my/autoinsert-yas-expand])
                       (("\\.py\\'"
                         . "Python script")
                        . ["template.py" my/autoinsert-yas-expand])
                       (("\\.go\\'"
                         . "Go source")
                        . ["template.go" my/autoinsert-yas-expand])
                       (("[mM]akefile\\'"
                         . "Makefile")
                        . ["Makefile" my/autoinsert-yas-expand])
                       (("\\.tex\\'"
                         . "TeX/LaTeX")
                        . ["template.tex" my/autoinsert-yas-expand]))))

由于 purcell 配置里go 并没有默认配置 所以go 的模板配置不生效 通过加入 (add-hook 'find-file-hook #'yas-minor-mode) 解决

1.3.2. 优化 auto-insert

由于自动插入的 email 地址不正确.通过以下加入设置:

(setq user-mail-address "xiliuya@163.com")

1.4. yasnippet

1.4.1. 配置yasnippet

yasnippt 是一个代码模板系统. 可以和eglot 配合使用. 配置好可以极大加快代码速度.

配置文件

可以参考链接: eglot github . 在init-local.el 加入:

(add-hook 'prog-mode-hook #'yas-minor-mode)
(with-eval-after-load 'yasnippet
  (yas-global-mode 1))
新建一个模板.

通过 M-x yas-new-snippet 例如在 c-mode 中建立了一个: 输入name 字符串后使用TAB 会变成It's xiliuya 的模板 (仅限于输入非代码时)

# -*- mode: snippet -*-
# name:name
# key:name
# --
It's xiliuya
复制模板

将 github 上的模板文件夹: snippets 复制到 ~/.emacs.d/snippets/ . 模板链接 : yun63

1.4.2. yas 快捷添加 org-src 代码块

使用 C-c & C-n 定义一个新的快捷插入片段

  • src_shell key sh_
  • src_python key py_
  • src_lisp key elisp_
  • dot key dot_

1.4.3. 调整 yasnippet 模板

删除 yasnippet-snippets 包已有的模板 保留自定义的几个有用的模板

1.4.4. 修复 prog-mode 下 yas 功能

由于在沙盒内测试并无异常 经过逐个关闭 minor mode 测试后 得出冲突的模式:

Symbol-Overlay minor mode

已经向 symbol-overlay 提交 issues

解决方案

通过修改 prog-mode-hook

(remove-hook 'prog-mode-hook 'symbol-overlay-mode)

1.5. eglot

1.5.1. 将 eglot 加入配置使其打开c文件后启动

已加入init-local.el 使用 (add-hook 'prog-mode-hook 'eglot-ensure) 配置hook 了该模式下所有的环境

1.5.2. 查看使用eglot

通过阅读文档 官方readme: eglot 得到M-. M-, 跳转代码 当未进入插入模式时 可以使用C-] 跳转 进入后使用M-, 返回

1.5.3. 重新配置eglot

删除旧配置

(add-hook 'prog-mode-hook 'eglot-ensure)

eglot 依赖外部的lsp server, 所以手动配置add-hook 模式比较合适

(add-hook 'python-mode-hook 'eglot-ensure)
(add-hook 'c-mode-common-hook 'eglot-ensure)
(add-hook 'rust-mode-hook 'eglot-ensure)

1.5.4. 当打开el 文件后eglot 报错

放弃原先的pr 因为使用时会不生效 原因不明 直接使用add-hook 时 打开el 报错 el 环境已足够完善, 不需要eglot. 经过实验是由于eglot 没有找到lsp server

1.5.5. 配置 eglot 快捷键

参考链接:Eglot for Better Programming 根据参考的链接结合已有配置 如 flymake-goto-next-error flymake-goto-prev-error . 已经分别绑定到了 C-c ! nC-c ! p

只需要在配置中加上 eglot-rename 快捷键就足够了, 作为补充配置了 eglot-format 的快捷键. ( 这两个都很好玩 )

(with-eval-after-load 'eglot
  (define-key eglot-mode-map (kbd "C-c e r") #'eglot-rename)
  (define-key eglot-mode-map (kbd "C-c e f") #'eglot-format))

1.6. erc

1.6.1. 配置 erc 使用

经过多次的粗心大意 终于按照 官方方案 成功连到irc 但是好像不能正常查看消息 是我太浮躁了 根据官网的教程 erc-sasl 下载文件并在 init-local.el 加入以下内容:

;;; 配置 erc
(require 'erc-backend)
(require 'erc-sasl)
(add-to-list 'erc-sasl-server-regexp-list "irc\\.libera\\.chat")
(with-eval-after-load 'erc
  (defun erc-login ()
    "Perform user authentication at the IRC server. (PATCHED)"
    (erc-log (format "login: nick: %s, user: %s %s %s :%s"
                     (erc-current-nick)
                     (user-login-name)
                     (or erc-system-name (system-name))
                     erc-session-server
                     erc-session-user-full-name))
    (if erc-session-password
        (erc-server-send (format "PASS %s" erc-session-password))
      (message "Logging in without password"))
    (when (and (featurep 'erc-sasl) (erc-sasl-use-sasl-p))
      (erc-server-send "CAP REQ :sasl"))
    (erc-server-send (format "NICK %s" (erc-current-nick)))
    (erc-server-send
     (format "USER %s %s %s :%s"
             ;; hacked - S.B.
             (if erc-anonymous-login erc-email-userid (user-login-name))
             "0" "*"
             erc-session-user-full-name))
    (erc-update-mode-line))
  )
(setq erc-autojoin-channels-alist
      '((Libera.Chat "#libera" "#list" "#linux" "$emacs")))


;; (erc-tls :server "irc.libera.chat" :port 6697 :nick "xiliuya"
;;          :full-name "xiliuya"
;;          :password "")

1.7. sdcv

1.7.1. 配置 espeak 朗读

修改配置

在 init-local.el 加入如下配置:

;;; 配置修复 espeak 使用时出现的白屏
(with-eval-after-load 'sdcv
  (defun sdcv-search-simple (&optional word)
    "search word simple translate result."
    (funcall
     sdcv-popup-function
     (sdcv-filter
      (shell-command-to-string
       (mapconcat #'identity
                  (cons "sdcv" (sdcv-search-with-dictionary-args
                                (or word (sdcv-region-or-word))
                                sdcv-dictionary-simple-list))
                  " "))))

    ;; pronounce the word (add by me)
    (when sdcv-word-pronounce
      ;; `sleep-for', `sit-for'.
      (sit-for 0.8)
      (sdcv-pronounce-word word)
      )
    )
  )

调试的代码:

;; 下方是调试信息 不加入配置
;; (setq sdcv-word-pronounce 'nil)
;; (setq sdcv-word-pronounce 't)

;; (defun sdcv-search-pointer+ ()
;;   "translate current point word.
;; and show information use tooltip.
;; but this function use a simple dictionary list."
;;   (interactive)
;;   (let ((word (sdcv-region-or-word)))
;;     ;; display simple translate result.
;;     (sdcv-search-simple word)
;;     (sit-for 1)
;;     (sdcv-pronounce-word word)
;;     ))
实际分析

由于 sleep-for 函数的未知原因导致, 使用 sit-for 可以解决 建议多看一些备注信息, 有时可以快速排查问题

1.8. pyim

1.8.1. 使用pyim 并体验

成功使用 并正常的输入汉字 可在终端运行正常 使用M-j 进行中英文切换 普通时先输入字母 再通过快捷键唤醒 配置了半角字符 为默认字符

1.8.2. 修改 pyim 的选词框

使用默认值就可以只需要安装 posframe 包. 配置加入

(require-package 'posframe)

1.8.3. 修复 pyim 在 prog-mode 下的bug

经过测试禁用了 symbol-overlay 后不再出现输入框消失和输入字符出现问题了.

1.9. EAF

1.9.1. CANCELED 尝试使用 EAF

经过测试没有预期的美好与简洁, 由于wayland 支持不好已经放弃使用.

(add-to-list 'load-path "~/.emacs.d/site-lisp/emacs-application-framework/")
(require 'eaf)
(require 'eaf-browser)
(require 'eaf-pdf-viewer)
(require 'eaf-demo)

1.10. 优化

1.10.1. CANCELED 优化 emacs 启动时间

查看 benchmarking 信息

通过 M-x sanityinc/require-time 查看启动时间详情

问题

问题主要在 org-mode 暂时没有较好的解决方案 按照时间排序输出如下:

start_time Feature Time
83036.907 ol-gnus 2618.484
83079.567 gnus-sum 2073.966
83354.692 gnus-group 1536.641
83401.804 gnus-start 1443.971
2241.952 init-local 1282.597
83490.073 gnus-int 910.991
83533.981 message 822.331
优化
  • init-elpa

    修改镜像源配置内容:

    (with-eval-after-load 'init-elpa
      ...)
    ;;; 配置源在 init-elpa 加载后覆盖
    

1.10.2. 配置 emacs 窗口录制 GIF

修改相关项目 el gif-screen 修改后的代码: gif-screen-wayland

  • 使用快捷键 <f12> 开始录制
  • 使用快捷键 C-<f12> 暂停录制
  • 使用快捷键 <f12> 停止录制

由于通过 args 传递 swaymsg 字符串很长, 且会报错(已经过转义). 无法正常输出的窗口焦点坐标内容, 通过制作 shell 脚本更为通用简单 文件自动保存到 ~/Videos/emacs/ 目录下

添加 shell 脚本
swaymsg -t get_tree | jq -j '.. | select(.type?) | select(.focused).rect | "\(.x),\(.y) \(.width)x\(.height)"'

链接:

ln -s /home/xiliuya/myday/daily/swayfocuse.sh ~/.local/bin/swayfocuse
grim -g "$(swayfocuse)" $*

链接:

ln -s /home/xiliuya/myday/daily/grimfocuse ~/.local/bin/grimfocuse
配置快捷键
;;; 配置 gif 截图
(require 'gif-screencast)
(with-eval-after-load 'gif-screencast
  (define-key gif-screencast-mode-map (kbd "C-<f12>") 'gif-screencast-toggle-pause)
  (define-key gif-screencast-mode-map (kbd "<f12>") 'gif-screencast-stop)
  (global-set-key (kbd "<f12>") 'gif-screencast)
  )

1.10.3. 尝试其他 gif 方案

我想我 鬼迷心窍了 竟然执着于用复杂的方法实现简单的功能 感觉到了讽刺, 不过我也得到了一个,用不同的方式去实现另一件事情的方法. 原先方法的劣势:

  • 由于记录依靠 pre-commond-hook= 所以某些(im)的操作无法捕获
  • 没有完全的记录所有画面, 导致显示的操作与录制后有所区别

暂时不换, 经过了测试, 使用原先的方式稍微要优于以下的两种:

  • 体积大小的原因同等时间 gif 大小 20MB/300KB
  • gif 不如直接录屏的 mp4

旧的方式 : 配置 emacs 窗口录制 GIF

使用截图脚本截取

由于并不好用用作参考不做研究.

i=0
for ((i=0 ;i<1000;i++))
do
    if (( $i < 10 ));then
        swayvkshot -o "0"$i.png -g "$(swayfocuse)"
    else
        swayvkshot -o $i.png -g  "$(swayfocuse)"
    fi
done
echo "done"
使用录制屏幕截取

经过了实验生成的文件会很大,不太建议使用 启动录制:

wf-recorder -g "$(swayfocuse)" -f /tmp/tmp.mp4 &

关闭录制:

pkill --signal SIGINT wf-recorder &&
    sleep 0.5 &&
    TIME_N="$(date "+%y%m%d_%H%M%S")"
ffmpeg -i /tmp/tmp.mp4 ~/Videos/out_${TIME_N}.gif &&
    gifsicle --optimize=3 -b ~/Videos/out_${TIME_N}.gif &&
    if [ -f /tmp/tmp.mp4 ]; then
        echo "删除 /tmp/tmp.mp4 文件"
        rm -f /tmp/tmp.mp4
    else
        echo "文件不存在"
    fi

配置软链接:

ln -s /home/xiliuya/myday/daily/recorder_start.sh ~/.local/bin/gif_start
ln -s /home/xiliuya/myday/daily/recorder_stop.sh ~/.local/bin/gif_stop

1.10.4. 配置 编译命令

配置编译成功后,隐藏弹窗:
;;; 配置编译成功后,隐藏弹窗
(defun notify-compilation-result(buffer msg)
  "Notify that the compilation is finished,
  close the *compilation* buffer if the compilation is successful,
  and set the focus back to Emacs frame"

  (if (string-match "^finished" msg)
      (progn
        ;;(delete-windows-on buffer)
        ;;(bury-buffer buffer)
        ;;(kill-buffer buffer)
        (switch-to-prev-buffer (xiliuya/find-buffer (window-list) "*compilation*") 'bury )
        (tooltip-show "\n Compilation Successful :-) \n "))
    (tooltip-show "\n Compilation Failed :-( \n "))
  )

(defun xiliuya/find-buffer (w-list str)
  "Find a window-list buffer with full buffer name"

  (if (null w-list)
      nil
    (if (string-match (buffer-name (window-buffer (car w-list))) str)
        (car w-list)
      ;;(window-buffer (car w-list))
      (xiliuya/find-buffer (cdr w-list) str)
      )
    )
  ;;(setq w (car w-list))
  )
;;(xiliuya/find-buffer (window-list) "*scratch*")
(add-to-list 'compilation-finish-functions
             'notify-compilation-result)
配置 c-mode 编译命令
;;; 配置 c-mode 编译命令
(add-hook 'c-mode-hook
          (lambda ()
            (unless (file-exists-p "Makefile")
              (set (make-local-variable 'compile-command)
                   ;; emulate make's .c.o implicit pattern rule, but with
                   ;; different defaults for the CC, CPPFLAGS, and CFLAGS
                   ;; variables:
                   ;; $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $<
                   (let ((file (file-name-nondirectory buffer-file-name)))
                     (format "%s -o %s %s %s %s"
                             ;;(format "%s -c -o %s.o %s %s %s"
                             (or (getenv "CC") "gcc")
                             (file-name-sans-extension file)
                             (or (getenv "CPPFLAGS") "-DDEBUG=9")
                             (or (getenv "CFLAGS") "-ansi -pedantic -Wall -g")
                             file))))))

1.10.5. 将 buffer 内容复制到缓存buffer内

(defun my-copy-buffer ()
  (interactive)
  (get-buffer-create "mybuffer")
  (copy-to-buffer "mybuffer" (point-min) (point-max))
  )

1.11. 修复

1.11.1. 修复 flyspell-mode 报错 Can’t find Hunspell dictionary

安装 ispell 即可 由于 hunspell 较为麻烦暂时不考虑使用

1.11.2. 修复 org 模式下的代码执行

purcell 解决了该问题

1.11.3. 修复 org-mode 以外的 evil-tab

由于上次的配置干扰了其他的模式下 evil tab 的使用(如编辑代码时多按了一个 tab) 配置evil 正常模式下 org TAB 测试当前主模式代码:

(when (memq major-mode '(org-mode))
  (progn (message "hello"))
  )

替换配置文件:

(defun my/evil-org-tab ()
  "Run org-cycle When in org-mode "
  (interactive)
  (when (memq major-mode '(org-mode))
    ;;;(progn (message "hello"))
    (org-cycle)
    )
  )
(define-key evil-normal-state-map (kbd "<tab>") 'my/evil-org-tab)

1.11.4. 修复 prog-mode 下 yas 功能

由于在沙盒内测试并无异常 经过逐个关闭 minor mode 测试后 得出冲突的模式:

Symbol-Overlay minor mode

已经向 symbol-overlay 提交 issues

解决方案

通过修改 prog-mode-hook

(remove-hook 'prog-mode-hook 'symbol-overlay-mode)

1.11.5. 修复 org-transclusion 报错 No content found with "id:

参考: issues/138 . 通过执行 M-x org-roam-update-org-id-locations 更新 roam 就能正常使用.

1.11.6. 修复 pyim 在 prog-mode 下的bug

经过测试禁用了 symbol-overlay 后不再出现输入框消失和输入字符出现问题了.

作者: xiliuya

Created: 2023-01-02 一 22:43