emacs笔记


Linux

emacs gui进程放置到后台

EMACS=/usr/bin/emacs
GUI=0
ARGS="$@"
ARRAY=("-nw" "--no-window-system" "--batch" "--help")

for arg in $ARGS; do
    for keyword in "${ARRAY[@]}";do
        if [ $keyword = $arg ];then
            GUI=1
            break
        fi
    done
    if [ $GUI -eq 1 ]; then
        break
    fi
done

if [ $GUI -eq 1 ]; then
    $EMACS $ARGS
else
    $EMACS $ARGS &> /dev/null &
    # nohup $EMACS $ARGS &> /dev/null & disown
fi

Evil

粘贴替换的时候会复制替换的文本

(defun evil-paste-after-from-0 ()
  (interactive)
  (let ((evil-this-register ?0))
    (call-interactively 'evil-paste-after)))

(define-key evil-visual-state-map "p" 'evil-paste-after-from-0)

自动搜索已选中的字符

经常使用 evil 中的 =/= 进行搜索, 但有时候想要搜索已有的字符, 在 evil-visual-state 下选中某个字符,按 =/= 时自动把选中的字符填入待搜索项中

(use-package isearch
  :ensure nil
  :init
  (defun maple/evil-search-paste()
    (when (region-active-p)
      (isearch-yank-string
       (save-excursion
         (buffer-substring-no-properties
          (region-beginning) (1+ (region-end)))))
      (deactivate-mark)))
  :hook (isearch-mode . maple/evil-search-paste)
  :bind (:map isearch-mode-map
              ([remap isearch-delete-char] . isearch-del-char)))

evil-mc不忽略大小写

evil-mc 默认会通过evil-ex-search进行搜索,可以通过设置(setq evil-ex-search-case 'sensitive)来不忽略大小写, 但我只想在使用evil-mc时不忽略,其他时间忽略

;; ignore case in evil-mc
(add-hook 'evil-mc-before-cursors-created (lambda() (setq evil-ex-search-case 'sensitive)))
(add-hook 'evil-mc-after-cursors-deleted (lambda() (setq evil-ex-search-case 'smart)))

Font

设置中英文字体

;; 中英文表格对齐
(defvar emacs-english-font "DejaVu Sans Mono"
  "The font name of English.")
(defvar emacs-cjk-font "WenQuanYi Micro Hei Mono"
  "The font name for CJK.")
(defvar emacs-font-size-pair '(15 . 18)
  "Default font size pair for (english . chinese)")

(defvar emacs-font-size-pair-list
  '(( 5 .  6) (10 . 12)
    (13 . 16) (15 . 18) (17 . 20)
    (19 . 22) (20 . 24) (21 . 26)
    (24 . 28) (26 . 32) (28 . 34)
    (30 . 36) (34 . 40) (36 . 44))
  "This list is used to store matching (englis . chinese) font-size.")
(defun font-exist-p (fontname)
  "Test if this font is exist or not."
  (if (or (not fontname) (string= fontname ""))
      nil
    (if (not (x-list-fonts fontname)) nil t)))

(defun maple/set-font (english chinese size-pair)
  "Setup emacs English and Chinese font on x window-system."
  (if (font-exist-p english)
      (set-frame-font (format "%s:pixelsize=%d" english (car size-pair)) t))

  (if (font-exist-p chinese)
      (dolist (charset '(kana han symbol cjk-misc bopomofo))
        (set-fontset-font (frame-parameter nil 'font) charset
                          (font-spec :family chinese :size (cdr size-pair))))))
;; (add-hook 'ctbl:table-mode-hook
;;           (maple/set-font emacs-english-font emacs-cjk-font emacs-font-size-pair))

Ivy

指定目录或文件进行搜索

(defun maple/counsel-ag-file()
  (interactive)
  (counsel-ag nil (read-file-name "Search in file(s): ")))

查找当前目录以及子目录的某个文件

(defun maple/counsel-find-file()
  (interactive)
  (ivy-read "Find file: "
            (mapcar 'file-relative-name
                    (directory-files-recursively default-directory ""))
            :matcher #'counsel--find-file-matcher
            :action #'counsel-find-file-action
            :preselect (counsel--preselect-file)
            :require-match 'confirm-after-completion
            :history 'file-name-history
            :keymap counsel-find-file-map
            :caller 'counsel-find-file))

当选中单词时,swiper使用已选单词进行搜索

(defun maple/ivy-search-at-point (func)
  (let* ((region (region-active-p))
         (string (if (not region) ""
                   (buffer-substring-no-properties
                    (region-beginning) (region-end))))
         (ivy-initial-inputs-alist
          (list (cons func string))))
    (when region (deactivate-mark))
    (funcall func)))
(defun maple/swiper()
  (interactive)
  (maple/ivy-search-at-point 'swiper))

File

获取文件或目录的basename

(defun maple/basename (fname)
  (if (or (file-directory-p fname)
          (string-match "/$" fname))
      (let ((dirname (directory-file-name fname)))
        (file-name-nondirectory dirname))
    (file-name-nondirectory fname)))

Elisp

golang自动增加注释

因为flycheck使用了golint, flycheck总是显示代码没有注释的警告

exported method Raw should have comment or be unexported (go-golint)

也没找到什么方法来禁止它, 作为强迫症受不了,总不能一个一个去注释, 所以写了一个函数来自动注释整个文件的所有未注释函数:

(defun maple/go-auto-comment()
  (interactive)
  (unless (featurep 'imenu)
    (require 'imenu nil t))
  (let* ((imenu-auto-rescan t)
         (imenu-auto-rescan-maxout (if current-prefix-arg
                                       (buffer-size)
                                     imenu-auto-rescan-maxout))
         (items (imenu--make-index-alist t))
         (items (delete (assoc "*Rescan*" items) items)))
    (cl-mapcan
     (lambda(item)
       (cl-mapcan
        (if (string= (car item) "func")
            'maple/go-func-comment
          'maple/go-type-comment)
        (cdr item)))
     items)))

(defun maple/go-add-comment(func point)
  (save-excursion
    (goto-char point)
    (forward-line -1)
    (when (not (looking-at (concat "// " func)))
      (end-of-line) (newline-and-indent)
      (insert (concat "// " func " ..")))))

(defun maple/go-func-comment(f)
  (let ((func (car f)))
    (if (and (string-prefix-p "(" func)
             (string-match "[)] \\(.*\\)[(]\\(.*\\)[)]\\(.*\\)$" func))
        (maple/go-add-comment (match-string 1 func) (cdr f))
      (if (string-match "\\(.*\\)[(]\\(.*\\)[)]\\(.*\\)$" func)
          (maple/go-add-comment (match-string 1 func) (cdr f))
        (maple/go-add-comment (car f) (cdr f))))))

(defun maple/go-type-comment(f)
  (maple/go-add-comment (car f) (cdr f)))

相关配置将持续更新: init-go.el

增加到hook但仅调用一次

(defmacro maple/add-hook-once (hook f &optional append local)
  "Like `add-hook`, remove after call with HOOK F &OPTIONAL APPEND LOCAL."
  (let ((func (intern (format "maple/run-once-%s"
                              (symbol-name f)))))
    `(progn
       (defun ,func ()
         (remove-hook ',hook ',func ,local)
         (funcall ',f))
       (add-hook ',hook ',func ,append ,local))))

迭代并获取列表索引

(defmacro maple/dolist (spec &rest body)
 "Like dolist but get INDEX, SPEC &REST BODY."
 (declare (indent 1) (debug ((symbolp form &optional form) body)))
 `(let ((num 0))
     (dolist ,(cdr spec)
     (let ((,(car spec) num))
         ,@body
         (setq num (+ num 1))))))

这样就可以使用

(maple/dolist (index item '("aaa" "bbb"))
  (print index))

深拷贝function

https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Cells.html

(fset 'maple/put-text-property (symbol-function 'put-text-property))
Author: honmaple

NO CONTENTS

lin.jiang

风落花语风落天,花落风雨花落田.