Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
850 lines (683 sloc) 31.7 KB

Gernal packages configurations


Auto complete using company-mode


  ;; Turn on auto complete.
;;  (require 'auto-complete-config)       

(use-package company
  :defer t
  :config (add-hook 'prog-mode-hook 'company-mode))

Manage the dash package


(use-package dash
  :defer t)

Config the backups


;;(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
(setq backup-directory-alist '(("." . (expand-file-name "backups" user-emacs-directory))))

Save files


(setq delete-old-versions -1)
(setq version-control t)
(setq vc-make-backup-files t)
(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/auto-save-list/" t)))
;;(setq auto-save-file-name-transforms '((".*" (expand-file-name "auto-save-list" user-emacs-directory) t)))

Save history

保存历史记录 From

;;(setq savehist-file "~/.emacs.d/savehist")
(setq savehist-file (expand-file-name "savehist" user-emacs-directory))
(savehist-mode 1)
(setq history-length t)
(setq history-delete-duplicates t)
(setq savehist-save-minibuffer-history 1)
(setq savehist-additional-variables


Key bindings configuration for Macros

Key bindings for Macros

Table 1: Org-mode快捷键
C-x ( 开始录制宏
  C-x ) 结束录制宏
  C-x e 使用宏
  C-u 重复使用宏,C-u 100 C-x e重复100次
  M-x name-last-kbd-macro 保存宏,可以在其它地方通过M-x调用此保存好的宏



;; setting for tramp
(setq tramp-default-method "ssh")

;; config for caching password for 36000s
(setq password-cache-expiry 36000)

DONE Winner mode - undo and redo window configuration

  • State "DONE" from "" [2016-05-29 Sun 07:02]

winner-mode lets you use C-c <left> and C-c <right> to switch between window configurations. This is handy when something has popped up a buffer that you want to look at briefly before returning to whatever you were working on. When you're done, press C-c <left>.

(use-package winner
  :defer t)

DONE Mode line format

  • State "DONE" from "" [2016-05-29 Sun 07:02]

Display a more compact mode line

(use-package smart-mode-line
  :defer t)

DONE Undo tree

  • State "DONE" from "" [2016-05-29 Sun 07:02]

Allow us to visually walk through the changes you've made, undo back to a certain point (or redo), and go down different branches. Shot key binding: (C-x u)

(use-package undo-tree
  :defer t
  :diminish undo-tree-mode
    (setq undo-tree-visualizer-timestamps t)
    (setq undo-tree-visualizer-diff t)))

DONE Help - guide key

  • State "DONE" from "" [2016-05-29 Sun 07:02]

This library is very helpful, we can use it to help us remember or find the shot key binding. It will pops up a mini-buffer to show us the shot-key when we typed first part with a shot delay. (guide-key) 包可以帮助我们查看操作的快捷键,对于一些不太常用的快捷键想不起来的时候,可以输入快捷键的前缀后,暂停一下,Emacs即会弹出一个子窗口,列出当前前缀下可以选择的快捷键,及其函数名称。以方便我们进行查找。

(use-package guide-key
  :defer t
  :diminish guide-key-mode
  (setq guide-key/guide-key-sequence '("C-x r" "C-x 4" "C-c"))
  (guide-key-mode 1)))  ; Enable guide-key-mode

DONE Encoding configruation

  • State "DONE" from "" [2016-05-29 Sun 07:03]

This configuration from:

(prefer-coding-system 'utf-8)
(when (display-graphic-p)
  (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)))


  • State "DONE" from "" [2016-05-29 Sun 07:03]


(use-package helm
  :defer t
  :diminish helm-mode
    (require 'helm-config)
    (setq helm-candidate-number-limit 100)
    ;; From
    (setq helm-idle-delay 0.0 ; update fast sources immediately (doesn't).
          helm-input-idle-delay 0.01  ; this actually updates things
                                        ; reeeelatively quickly.
          helm-yas-display-key-on-candidate t
          helm-quick-update t
          helm-buffers-fuzzy-matching t
          helm-recentf-fuzzy-match t
          helm-buffers-fuzzy-matching t
          helm-M-x-fuzzy-match t
          helm-mode-fuzzy-match t
          helm-completion-in-region-fuzzy-match t
          helm-recentf-fuzzy-match t
          helm-semantic-fuzzy-match t
          helm-imenu-fuzzy-match t
          helm-apropos-fuzzy-match t
          helm-lisp-fuzzy-completion t
          helm-M-x-requires-pattern nil
          helm-autoresize-mode 1 ;; resize the window
          helm-autoresize-max-height 40 ;; make the max height as 40% percent of current frame height
          helm-ff-skip-boring-files t)
  :bind (("C-c h" . helm-mini)
         ("C-x c a" . helm-apropos)
         ("C-x C-b" . helm-buffers-list)
         ("C-x b" . helm-buffers-list)
         ("M-y" . helm-show-kill-ring)         ("M-x" . helm-M-x)
         ("C-x c o" . helm-occur)
         ("C-x c s" . helm-swoop)
         ("C-x c y" . helm-yas-complete)
         ("C-x c Y" . helm-yas-create-snippet-on-region)
         ("C-x c b" .  helm-do-grep-book-notes)
         ("C-x c i" . helm-org-in-buffer-headings)
         ("C-x c SPC" . helm-all-mark-rings)))
;(ido-mode -1) ;; Turn off ido mode in case I enabled it accidentally

(use-package helm-descbinds
  :defer t
  :bind (("C-x c b" . helm-descbinds)
         ("C-x c w" . helm-descbinds)))

;; Use helm to browse my notes files
(defvar book-notes-directory "~/workspace/github/work-notes")
(defun helm-do-grep-book-notes ()
  "Search my book notes."
  (helm-do-grep-1 (list book-notes-directory)))

DONE Helm-swoop

  • State "DONE" from "" [2016-05-29 Sun 07:03]

    ;; setting for helm-swoop

    ;; (use-package helm-swoop :defer t :bind (("C-S-s" . helm-swoop) ("M-i" . helm-swoop) ("M-s s" . helm-swoop) ("M-s M-s" . helm-swoop) ("M-I" . helm-swoop-back-to-last-point) ("C-c M-i" . helm-multi-swoop) ("C-x M-i" . helm-multi-swoop-all) ) :config (progn ;; When doing isearch, hand the word over to helm-swoop (define-key isearch-mode-map (kbd "M-i") 'helm-swoop-from-isearch) ;; From helm-swoop to helm-multi-swoop-all (define-key helm-swoop-map (kbd "M-i") 'helm-multi-swoop-all-from-helm-swoop) ;; Move up and down like isearch (define-key helm-swoop-map (kbd "C-r") 'helm-previous-line) (define-key helm-swoop-map (kbd "C-s") 'helm-next-line) (define-key helm-multi-swoop-map (kbd "C-r") 'helm-previous-line) (define-key helm-multi-swoop-map (kbd "C-s") 'helm-next-line)

    ) )

    ;; Save buffer when helm-multi-swoop-edit complete (setq helm-multi-swoop-edit-save t)

    ;; If this value is t, split window inside the current window (setq helm-swoop-split-with-multiple-windows nil)

    ;; Split direcion. 'split-window-vertically or 'split-window-horizontally (setq helm-swoop-split-direction 'split-window-vertically)

    ;; If nil, you can slightly boost invoke speed in exchange for text color (setq helm-swoop-speed-or-color nil)

    ;; ;; Go to the opposite side of line from the end or beginning of line (setq helm-swoop-move-to-line-cycle t)

    ;; Optional face for line numbers ;; Face name is helm-swoop-line-number-face (setq helm-swoop-use-line-number-face t)

DONE Snippets

  • State "DONE" from "" [2016-05-29 Sun 07:04]


(use-package yasnippet
  :defer t
  :diminish yas-minor-mode
  :init (yas-global-mode)
    (add-hook 'hippie-expand-try-functions-list 'yas-hippie-try-expand)
    (setq yas-key-syntaxes '("w_" "w_." "^ "))
    ;;(setq yas-installed-snippets-dir "~/emacs.d-new/yasnippet-snippets")
    (setq yas-installed-snippets-dir (expand-file-name "yasnippet-snippets" user-emacs-directory))
    (setq yas-expand-only-for-last-commands nil)
    (yas-global-mode 1)
    (bind-key "\t" 'hippie-expand yas-minor-mode-map)
    (add-to-list 'yas-prompt-functions 'shk-yas/helm-prompt)))

(defun shk-yas/helm-prompt (prompt choices &optional display-fn)
  "Use helm to select a snippet. Put this into `yas/prompt-functions.'"
  (setq display-fn (or display-fn 'identity))
  (if (require 'helm-config)
      (let (tmpsource cands result rmap)
        (setq cands (mapcar (lambda (x) (funcall display-fn x)) choices))
        (setq rmap (mapcar (lambda (x) (cons (funcall display-fn x) x)) choices))
        (setq tmpsource
               (cons 'name prompt)
               (cons 'candidates cands)
               '(action . (("Expand" . (lambda (selection) selection))))
        (setq result (helm-other-buffer '(tmpsource) "*helm-select-yasnippet"))
        (if (null result)
            (signal 'quit "user quit!")
          (cdr (assoc result rmap))))

(setq default-cursor-color "gray")
(setq yasnippet-can-fire-cursor-color "purple")

;; It will test whether it can expand, if yes, cursor color -> green.
(defun yasnippet-can-fire-p (&optional field)
  (setq yas--condition-cache-timestamp (current-time))
  (let (templates-and-pos)
    (unless (and yas-expand-only-for-last-commands
                 (not (member last-command yas-expand-only-for-last-commands)))
      (setq templates-and-pos (if field
                                    (narrow-to-region (yas--field-start field)
                                                      (yas--field-end field))
    (and templates-and-pos (first templates-and-pos))))

(defun my/change-cursor-color-when-can-expand (&optional field)
  (when (eq last-command 'self-insert-command)
    (set-cursor-color (if (my/can-expand)

(defun my/can-expand ()
  "Return true if right after an expandable thing."
  (or (abbrev--before-point) (yasnippet-can-fire-p)))

                                        ; As pointed out by Dmitri, this will make sure it will update color when needed.
(remove-hook 'post-command-hook 'my/change-cursor-color-when-can-expand)

(defun my/insert-space-or-expand ()
  "For binding to the SPC SPC keychord."
  (condition-case nil (or (my/hippie-expand-maybe nil) (insert "  "))))

(defun my/hippie-expand-maybe (arg)
  "Try to expand text before point, using multiple methods.
The expansion functions in `hippie-expand-try-functions-list' are
tried in order, until a possible expansion is found.  Repeated
application of `hippie-expand' inserts successively possible
With a positive numeric argument, jumps directly to the ARG next
function in this list.  With a negative argument or just \\[universal-argument],
undoes the expansion."
  (interactive "P")
  (require 'hippie-exp)
  (if (or (not arg)
          (and (integerp arg) (> arg 0)))
      (let ((first (or (= he-num -1)
                       (not (equal this-command last-command)))))
        (if first
              (setq he-num -1)
              (setq he-tried-table nil)))
        (if arg
            (if (not first) (he-reset-string))
          (setq arg 0))
        (let ((i (max (+ he-num arg) 0)))
          (while (not (or (>= i (length hippie-expand-try-functions-list))
                          (apply (nth i hippie-expand-try-functions-list)
                                 (list (= he-num i)))))
            (setq i (1+ i)))
          (setq he-num i))
        (if (>= he-num (length hippie-expand-try-functions-list))
            (progn (setq he-num -1) nil)
          (if (and hippie-expand-verbose
                   (not (window-minibuffer-p)))
              (message "Using %s"
                       (nth he-num hippie-expand-try-functions-list)))))
    (if (and (>= he-num 0)
             (eq (marker-buffer he-string-beg) (current-buffer)))
          (setq he-num -1)
          (if (and hippie-expand-verbose
                   (not (window-minibuffer-p)))
              (message "Undoing expansions"))))))

DONE Edit-list

  • State "DONE" from "" [2016-05-29 Sun 07:04]

M-x edit-list makes it easier to edit an Emacs Lisp list. \#+ombegin_src emacs-lisp :tangle yes (use-package edit-list

:defer t

:commands edit-list)


DONE Zap to isearch

  • State "DONE" from "" [2016-05-29 Sun 07:04]

From Steve Purcell, who linked to

(defun zap-to-isearch (rbeg rend)
  "Kill the region between the mark and the closest portion of
the isearch match string. The behaviour is meant to be analogous
to zap-to-char; let's call it zap-to-isearch. The deleted region
does not include the isearch word. This is meant to be bound only
in isearch mode.  The point of this function is that oftentimes
you want to delete some portion of text, one end of which happens
to be an active isearch word. The observation to make is that if
you use isearch a lot to move the cursor around (as you should,
it is much more efficient than using the arrows), it happens a
lot that you could just delete the active region between the mark
and the point, not include the isearch word."
  (interactive "r")
  (when (not mark-active)
    (error "Mark is not active"))
  (let* ((isearch-bounds (list isearch-other-end (point)))
         (ismin (apply 'min isearch-bounds))
         (ismax (apply 'max isearch-bounds))
    (if (< (mark) ismin)
        (kill-region (mark) ismin)
      (if (> (mark) ismax)
          (kill-region ismax (mark))
        (error "Internal error in isearch kill function.")))

(define-key isearch-mode-map [(meta z)] 'zap-to-isearch)


  • State "WAITING" from "" [2016-05-30 Mon 20:36]


(use-package smartparens
  (require 'smartparens-config)
  (setq sp-autoescape-string-quote nil)
  (--each '(css-mode-hook
    (add-hook it 'turn-on-smartparens-mode))




(use-package expand-region
  ;; Don't use expand-region fast keys
  (setq expand-region-fast-keys-enabled nil)

  ;; Show expand-region command used
  (setq er--show-expansion-message t)


Key bindings for Expand-region

;; Expand region (increases selected region by semantic units)
(global-set-key (kbd "C-'") 'er/expand-region)



;; add smart swap buffers in multi-windows
(use-package swap-buffers
  (global-set-key (kbd "C-x 5") 'swap-buffers)

Multiple cursors mode

Multiple cursor是一个非常强大的多位置同时编辑的编辑模式,文档可参考: 这里有一个介绍详细的视频:


(use-package multiple-cursors
  :defer t
   (("C-c m t" . mc/mark-all-like-this)
    ("C-c m m" . mc/mark-all-like-this-dwim)
    ("C-c m l" . mc/edit-lines)
    ("C-c m e" . mc/edit-ends-of-lines)
    ("C-c m a" . mc/edit-beginnings-of-lines)
    ("C-c m n" . mc/mark-next-like-this)
    ("C-c m p" . mc/mark-previous-like-this)
    ("C-c m s" . mc/mark-sgml-tag-pair)
    ("C-c m d" . mc/mark-all-like-this-in-defun)))
(use-package phi-search
  :defer t)
(use-package phi-search-mc
  :defer t
  :config (phi-search-mc/setup-keys))
(use-package mc-extras
  :defer t
  :config (define-key mc/keymap (kbd "C-. =") 'mc/compare-chars))

Short-key binding

;; add multi cursors:
;;(require 'multiple-cursors)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)

(global-set-key (kbd "C-S-c C-e") 'mc/edit-ends-of-lines)
(global-set-key (kbd "C-S-c C-a") 'mc/edit-beginnings-of-lines)

TODO Wgrep

Wgrep是一个可以允许我们在grep模式下进行直接修改的工具,可以允许我们批量添加上Multiple cursors,然后进行批量修改的工具。在快速修改文件时非常方便,类似于sed的批量匹配,批量修改。

;;; 未配置详细操作,暂时不使用
(use-package wgrep)




(use-package tabbar)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Interactive Functions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun tabbar-select-end-tab ()
  "Select end tab of current tabset."
  (tabbar-select-beg-tab t))

(defun tabbar-select-beg-tab (&optional backward type)
  "Select beginning tab of current tabs.
If BACKWARD is non-nil, move backward, otherwise move forward.
TYPE is default option."
  (let* ((tabset (tabbar-current-tabset t))
         (ttabset (tabbar-get-tabsets-tabset))
         (cycle (if (and (eq tabbar-cycle-scope 'groups)
                         (not (cdr (tabbar-tabs ttabset))))
         selected tab)
    (when tabset
      (setq selected (tabbar-selected-tab tabset))
      (setq tabset (tabbar-tabs tabset)
            tab (car (if backward (last tabset) tabset)))
      (tabbar-click-on-tab tab type))))

(defun tabbar-backward-tab-other-window (&optional reversed)
  "Move to left tab in other window.
Optional argument REVERSED default is move backward, if reversed is non-nil move forward."
  (other-window 1)
  (if reversed
  (other-window -1))

(defun tabbar-forward-tab-other-window ()
  "Move to right tab in other window."
  (tabbar-backward-tab-other-window t))

;;; Code:

(defcustom tabbar-hide-header-button t
  "Hide header button at left-up corner.
Default is t."
  :type 'boolean
  :set (lambda (symbol value)
         (set symbol value)
         (if value
              tabbar-scroll-left-help-function nil ;don't show help information
              tabbar-scroll-right-help-function nil
              tabbar-help-on-tab-function nil
              tabbar-home-help-function nil
              tabbar-buffer-home-button (quote (("") "")) ;don't show tabbar button
              tabbar-scroll-left-button (quote (("") ""))
              tabbar-scroll-right-button (quote (("") "")))))
  :group 'tabbar)

(defun tabbar-filter (condp lst)
  (delq nil
        (mapcar (lambda (x) (and (funcall condp x) x)) lst)))

(defun tabbar-filter-buffer-list ()
   (lambda (x)
     (let ((name (format "%s" x)))
        (not (string-prefix-p "*epc" name))
        (not (string-prefix-p "*helm" name))
        (not (string-prefix-p "*Messages*" name))
   (delq nil
         (mapcar #'(lambda (b)
                      ;; Always include the current buffer.
                      ((eq (current-buffer) b) b)
                      ((buffer-file-name b) b)
                      ((char-equal ?\  (aref (buffer-name b) 0)) nil)
                      ((buffer-live-p b) b)))

(setq tabbar-buffer-list-function 'tabbar-filter-buffer-list)

(defvar tabbar-ruler-projectile-tabbar-buffer-group-calc nil
  "Buffer group for projectile.  Should be buffer local and speed up calculation of buffer groups.")
(defun tabbar-ruler-projectile-tabbar-buffer-groups ()
  "Return the list of group names BUFFER belongs to.
    Return only one group for each buffer."

  (if tabbar-ruler-projectile-tabbar-buffer-group-calc
      (symbol-value 'tabbar-ruler-projectile-tabbar-buffer-group-calc)
    (set (make-local-variable 'tabbar-ruler-projectile-tabbar-buffer-group-calc)

          ((or (get-buffer-process (current-buffer)) (memq major-mode '(comint-mode compilation-mode))) '("Term"))
          ((string-equal "*" (substring (buffer-name) 0 1)) '("Misc"))
          ((condition-case err
             (error nil)) (list (projectile-project-name)))
          ((memq major-mode '(emacs-lisp-mode python-mode emacs-lisp-mode c-mode c++-mode makefile-mode lua-mode vala-mode)) '("Coding"))
          ((memq major-mode '(javascript-mode js-mode nxhtml-mode html-mode css-mode)) '("HTML"))
          ((memq major-mode '(org-mode calendar-mode diary-mode)) '("Org"))
          ((memq major-mode '(dired-mode)) '("Dir"))
          (t '("Main"))))
    (symbol-value 'tabbar-ruler-projectile-tabbar-buffer-group-calc)))

(defun tabbar-ruler-group-by-projectile-project()
  "Group by projectile project."
  (setq tabbar-buffer-groups-function 'tabbar-ruler-projectile-tabbar-buffer-groups))

;; group by projectile

Key binding

;; -----------------------------------------
;; start tabbar-mode
;; -----------------------------------------
(global-set-key (kbd "C-c t") 'tabbar-mode)
;; Tabbar, following is default key binding, no need to set again
;;(global-set-key (kbd "C-c <C-left>") 'tabbar-forward-tab)
;;(global-set-key (kbd "C-c <C-right>") 'tabbar-backward-tab)
;;(global-set-key (kbd "C-c <C-up>") 'tabbar-forward-group)
;;(global-set-key (kbd "C-c <C-down>") 'tabbar-backward-group)



(use-package perspective
  ;; Enable perspective mode
    (persp-mode t)
    ;; TODO: implement persp-last as before-advice on persp-switch (?)

    (defmacro custom-persp (name &rest body)
      `(let ((initialize (not (gethash ,name perspectives-hash)))
             (current-perspective persp-curr))
         (persp-switch ,name)
         (when initialize ,@body)
         (setq persp-last current-perspective)))

    ;; Jump to last perspective
    (defun custom-persp-last ()
      (persp-switch (persp-name persp-last)))

    (define-key persp-mode-map (kbd "C-x p -") 'custom-persp-last)




;; Use C-f during file selection to switch to regular find-file
(ido-mode t)
;;(ido-everywhere t)
(setq ido-enable-flex-matching t)
(setq ido-use-filename-at-point nil)
(setq ido-auto-merge-work-directories-length 0)
(setq ido-use-virtual-buffers t)

Multiple Major Mode


(use-package mmm-mode
  ;;(require 'mmm-auto)
  (setq mmm-global-mode 'buffers-with-submode-classes)
  (setq mmm-submode-decoration-level 2)

You can’t perform that action at this time.