文本编辑器X 使用技巧Emacs

Emacs 有什么奇技淫巧?

问题描述

例如我目前使用内置的CLOCK来作时间日志.
地铁风
不会撸程序的设计狮不是好科研狗

奇淫技巧是吧?翻了翻我的 .emacs…

首先当然是 nyan nyan nyan… 当前 window 的 modeline 上显示一个小图片~~

;; Add a small image to the mode line for current window~~
(defconst active-modeline-image
  (create-image my-active-modeline-image 'png nil
                                 :ascent 'center))
(defconst mode-line-img
  (propertize (make-string my-active-modeline-image-width #x20)
              'display active-modeline-image))

(defvar my-current-win nil)
(defun set-current-window (windows)
  (when (not (minibuffer-window-active-p (frame-selected-window)))
    (setq my-current-win (selected-window))))
(add-function :before pre-redisplay-function #'set-current-window)

(add-hook 'after-init-hook
          (lambda ()
            (setq-default
             mode-line-format
             (append mode-line-format
                     `((:eval
                        (if (eq my-current-win (get-buffer-window))
                            ,mode-line-img)))))))

把一些特定的词显示成其他特定字符。这玩意的标准用法是这样的:

注意图中的 lambda. 这个实现使用了 font lock. 好像 24.4 里增加了专门实现这个的函数……

;; Replace stuff like `lambda', `->' with actual unicode chars.
(defun unicode-symbol (name)
  "Translate a symbolic name for a Unicode character -- e.g., LEFT-ARROW
  or GREATER-THAN into an actual Unicode character code. "
  (decode-char 'ucs (case name
                      ('lambda #X03BB)
                      ;; other subs...
)))

(defun substitute-pattern-with-unicode (pattern symbol)
  "Add a font lock hook to replace the matched part of PATTERN with the 
  Unicode symbol SYMBOL looked up with UNICODE-SYMBOL."
  (interactive)
  (font-lock-add-keywords
   nil `((,pattern (0 (progn (compose-region (match-beginning 1) (match-end 1)
                                             ,(unicode-symbol symbol))
                             nil))))))

(defun substitute-patterns-with-unicode (patterns)
  "Call SUBSTITUTE-PATTERN-WITH-UNICODE repeatedly."
  (mapcar #'(lambda (x)
              (substitute-pattern-with-unicode (car x)
                                               (cdr x)))
          patterns))

“智能”选择使用 cua 块和 multi-cursor: 如果当前有选区,用 multi-cursor, 没有就用 cua 块选,好用到令人发指。

(defun cua-or-multicursor ()
  (interactive)
  (if (use-region-p)
      (mc/edit-lines)
    (cua-rectangle-mark-mode)))
;; http://emacs.stackexchange.com/a/9916/514
(eval-after-load "multiple-cursors-core"
  (lambda ()
     (add-to-list 'mc--default-cmds-to-run-once 'cua-or-multicursor)))

对当前的 cua 选区加和,妈妈再也不用担心我不会写 awk 了~~

(defun sum-cua-rectangle ()
  ;; Treat the content of current cua rectangle as numbers, and
  ;; calculate sum.
  (interactive)
  (message
   (number-to-string
    (reduce (lambda (x y) (+ x y))
            (mapcar (lambda (n) (string-to-number n))
                    (cua--extract-rectangle))))))

在 modeline 上显示缩减版 modes 信息。Modes 什么的最占地方了…… 效果见第一张图下面的 modeline.

;; Shorter modeline
(defvar mode-line-cleaner-alist
  '((auto-complete-mode . "α")
    ;; Major modes
    (lisp-interaction-mode . "λ")
    )
  "Alist for `clean-mode-line'.
When you add a new element to the alist, keep in mind that you
must pass the correct minor/major mode symbol and a string you
want to use in the modeline *in lieu of* the original.")

(defun clean-mode-line ()
  (interactive)
  (loop for cleaner in mode-line-cleaner-alist
        do (let* ((mode (car cleaner))
                 (mode-str (cdr cleaner))
                 (old-mode-str (cdr (assq mode minor-mode-alist))))
             (when old-mode-str
                 (setcar old-mode-str mode-str))
               ;; major mode
             (when (eq mode major-mode)
               (setq mode-name mode-str)))))

(add-hook 'after-change-major-mode-hook 'clean-mode-line)

你们知道 Emacs 启动显示的那个图片是可以换的吧?设一下 fancy-splash-image 这个变量就可以了,不知道为什么从来没见人换过……

确保某个包已经安装,如果没有的话就装之。

(defun ensure-package-installed (&rest packages)
  "Assure every package is installed, ask for installation if it’s not.
 a list of installed packages or nil for every skipped package."
  (mapcar
   (lambda (package)
     ;; (package-installed-p 'evil)
     (if (package-installed-p package)
         nil
       (if (y-or-n-p (format "Package %s is missing. Install it? " package))
           (package-install package)
         package)))
   packages))

然后就可以这样了:

(ensure-package-installed
 'linum 'whitespace 'company 'company-jedi 'web-mode 'magit 'helm
 'helm-gtags 'multiple-cursors 'yasnippet 'auctex
 'smart-mode-line 'ggtags 'rainbow-delimiters)

|====================== ERC 分割线???======================|

其他回答里好像有人提到了 ERC?

……

……

……

……

神器啊!!!!!!!!!!!!!!!!!!!!!!!!!话说大家都是混哪个频道的啊?认识认识呗~~

一键连接所有频道:

(defconst irc-channels
  '(("freenode.net" "#ubuntu-cn" "#archlinux-cn" "#emacs.tw"
     ;; "#geekhack"
     )
    ("oftc.net" "#arch-cn" "#njulug" "#wormux-cn" "#emacs-cn")
    ("esper.net" "#minecraft-cn")))
(ignore-errors (setq erc-autojoin-channels-alist irc-channels))

(defun erc-start ()
  (interactive)
  (erc :server "irc.freenode.net" :port 6667 :nick irc-nick
       :password irc-password :full-name irc-full-name)
  (erc-tls :server "irc.oftc.net" :port 6697 :nick irc-nick
           :password irc-password :full-name irc-full-name)
  (erc-tls :server "irc.esper.net" :port 6697 :nick irc-nick
           :password irc-password :full-name irc-full-name))

然后你们知道 ERC 退出频道的时候是可以选遗言的吧?……么?

(setq erc-quit-reason-various-alist
      '(("dinner" "Having dinner...")
        ("z" "Zzz...")
        ("^$" yow)))
(setq erc-quit-reason 'erc-quit-reason-various)

ERC 可以自定义 irc command… 比如这样:

(defun erc-cmd-THINK (&rest line)
  (let ((text
         (concat ".oO{ "
                 (erc-trim-string (mapconcat 'identity line " "))
                 " }")))
    (erc-send-action (erc-default-target) text)))

效果大概是这样:

#porn> /think Time to eat...
* MetroWind .oO{ Time to eat... }

还有这个命令:

(defun erc-cmd-SLAP (&rest nick)
  (if (not (equal '() nick))
      (erc-send-action
       (erc-default-target)
       (concat "slaps " (car nick)
               " with Peskin's Introduction to QFT."))))

效果是这样:

#porn> /slap ChanServ
* MetroWind slaps ChanServ with Peskin's Introduction to QFT.

还有这个:

(defun erc-cmd-SHOWOFF (&rest ignore)
  "Show off implementation"
  (let* ((chnl (erc-buffer-list))
         (srvl (erc-buffer-list 'erc-server-buffer-p))
         (memb (apply '+ (mapcar (lambda (chn)
                                   (with-current-buffer chn
                                     (1- (length (erc-get-channel-user-list)))))
                                 chnl)))
         (show (format "is connected to %i networks and talks in %i chans to %i ppl overall :>"
                       (length srvl)
                       (- (length chnl) (length srvl))
                       memb)))
    (erc-send-action (erc-default-target) show)))

效果:

#porn> /showoff
* MetroWind is connected to 3 networks and talks in 8 chans to 184 ppl overall :>

难道我会告诉你这个命令会刷屏这个秘密么~~

;; Say hi to everyone, use with CAUTION!!
(defun erc-cmd-HI ()
  (defun hi-to-nicks (nick-list)
    (if (eq nick-list '())
        nil
      (erc-send-message (concat "Hi, " (car nick-list)))
      (sleep-for 1)
      (hi-to-nicks (cdr nick-list))))

  (let ((nicks (erc-get-channel-nickname-list)))
    (hi-to-nicks nicks)))

嗯,效果就不放了,刚刚被轰出频道了。

像什么声音提醒啦,Mac 消息中心提醒啦(要程序么?我有:

MetroWind/mini-notifier · GitHub

),h4x0r 啦,发送 lisp 以及运行结果啦,都太普通了,一点都不好玩~~

最后是广告时间:我的颜色主题

MetroWind/emacs-flatui-theme · GitHub
52 赞同 7 感谢 71 收藏 10 条已备份评论 发布于 2015-08-18 知乎原页 ↗

评论 10

很有意思!
我常在freenode的#archlinux-cn出没。 另外也挂在#emacs, #physics等等。
0 赞