Skip to content

Latest commit

 

History

History
1408 lines (1156 loc) · 45 KB

config.org

File metadata and controls

1408 lines (1156 loc) · 45 KB

Emacs config using org-mode

Global Settings

User Info

My full name and mail address

(setq user-full-name    "WisdomFusion")
(setq user-mail-address "[email protected]")

Declare global variables

;; global variables
(defconst *is-mac-p* (eq system-type 'darwin))
(defconst *is-win-p* (eq system-type 'windows-nt))

load-path

The variable `load-path’ lists all the directories where Emacs should look for Elisp files.

;; load path
(add-to-list 'load-path "~/.emacs.d/config.el")
;;(let* ((my-lisp-dir "~/.emacs.d/site-lisp/")
;;       (default-directory my-lisp-dir))
;;  (setq load-path (cons my-lisp-dir load-path))
;;  (normal-top-level-add-subdirs-to-load-path))

exec-path

(when *is-mac-p*
  ;; PATH env and exec-path
  ;; difference between exec-path and PATH.
  ;; The value of environment variable “PATH” is used by emacs
  ;; when you are running a shell in emacs, similar to when you
  ;; are using a shell in a terminal.
  ;; The exec-path is used by emacs itself to find programs it
  ;; needs for its features, such as spell checking, file
  ;; compression, compiling, grep, diff, etc. Original from
  ;; http://ergoemacs.org/emacs/emacs_env_var_paths.html
  (setenv "PATH"
          (concat (getenv "PATH")
           ":/opt/local/bin:/usr/local/bin:/Library/TeX/texbin"))
  (setq exec-path
        (append exec-path
         '("/opt/local/bin" "/usr/local/bin" "Library/TeX/texbin"))))

ELPA

ELPA is the Emacs Lisp Package Archive, now included in Emacs 24.

(require 'package)

;; international elpa
;; (setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
;;                          ("melpa" . "https://melpa.org/packages/")
;;                          ("org" . "http://orgmode.org/elpa/")))

;; elpa from tuna.tsinghua.edu.cn
(setq package-archives '(("gnu"   . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
                         ("Melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")
                         ("melpa-stable" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa-stable/")
                         ("org" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")))

;; (package-initialize)
(unless package--initialized (package-initialize t))

(defvar wf-packages
  '(auctex
    company
    diff-hl
    diminish
    expand-region
    undo-tree
    volatile-highlights
    projectile
    helm
    helm-fuzzy
    helm-projectile
    htmlize
    flycheck
    fill-column-indicator
    markdown-mode
    magit
    move-text
    hl-todo
    paredit
    rainbow-mode
    powerline
    solarized-theme
    doom-themes
    material-theme
    smart-mode-line
    smartparens
    which-key
    yaml-mode
    zop-to-char
    yasnippet)
  "A list of packages to ensure are installed at launch.")

(defun wf-packages-installed-p ()
  "Check if all packages are installed."
  (seq-every-p #'package-installed-p wf-packages))

(defun wf-install-packages ()
  "Install all packages listed in `wf-packages'."
  (unless (wf-packages-installed-p)
    ;; Check for new packages
    (message "%s" "Refreshing packages...")
    (package-refresh-contents)
    (message "%s" "DONE")
    ;; Install the missing packages
    (dolist (package wf-packages)
      (when (not (package-installed-p package))
        (package-install package)))))

(wf-install-packages)

;; config changes made through the customize UI will be stored here
(setq custom-file (expand-file-name "custom.el" wf-my-dir))

;; load the personal settings (this includes `custom-file')
(when (file-exists-p wf-my-dir)
  (message "Loading personal configuration files in %s..." wf-my-dir)
  (mapc 'load (directory-files wf-my-dir 't "^[^#\.].*el$")))

;; diminish keeps the modeline tidy
(require 'diminish)

Fonts and Encoding

;; unicad -  Universal Charset Auto Detector
;; Http://www.emacswiki.org/emacs/Unicad
(require 'unicad nil 'noerror)

;; enforce utf-8 as the default coding system
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-language-environment 'utf-8)
;; backwards compatibility as default-buffer-file-coding-system
;; is deprecated in 23.2.
(if (boundp 'buffer-file-coding-system)
    (setq-default buffer-file-coding-system 'utf-8)
  (setq default-buffer-file-coding-system 'utf-8))
;; Treat clipboard input as UTF-8 string first; compound text next, etc.
(setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING))

(define-coding-system-alias 'UTF-8 'utf-8)

(setq system-time-locale "C")

;; fonts settings
(when window-system
  (if *is-mac-p*
      (progn
        ; English Font
        (set-face-attribute 'default nil :font "Menlo 14")
        ; CJK Font
        (dolist (charset '(kana han symbol cjk-misc bopomofo))
          (set-fontset-font (frame-parameter nil 'font)
                            charset
                            (font-spec :family "PingFang SC" :size 16)))))
  (if *is-win-p*
      (progn
        (set-face-attribute 'default nil :font "Fira Code 11")
        (dolist (charset '(kana han symbol cjk-misc bopomofo))
          (set-fontset-font (frame-parameter nil 'font)
                            charset
                            (font-spec :family "Microsoft YaHei" :size 18))))))


(setq-default line-spacing 4)

(mapc (lambda (face)
        (set-face-attribute face nil :weight 'normal :underline nil))
      (face-list))

UI Settings

 (when (fboundp 'tool-bar-mode)
      (tool-bar-mode -1))

 (menu-bar-mode -1)
 (tooltip-mode -1)
 (scroll-bar-mode -1)

 ;; the blinking cursor is nothing, but an annoyance
 (blink-cursor-mode -1)

 ;; disable the annoying bell ring
 (setq ring-bell-function 'ignore)

 ;; disable startup screen
 (setq inhibit-startup-screen t)

 ;; emacs title
 (setq frame-title-format '("%f [%m]"))

 ;; set fill-column
 (setq default-fill-column 78)
 (turn-off-auto-fill)

 ;; whitespace-mode config
 (require 'whitespace)
 (setq whitespace-line-column 78) ;; limit line length
 (setq whitespace-style '(face tabs empty trailing lines-tail))
 ;; (setq-default show-trailing-whitespace t)
 (add-to-list 'write-file-functions 'delete-trailing-whitespace)

 ;; fill-column-indicator
 (define-globalized-minor-mode global-fci-mode fci-mode (lambda () (fci-mode 1)))
 (global-fci-mode 1)
 (setq fci-rule-width 1)
 (setq fci-rule-color "darkblue")
 (setq fci-rule-column 78)

 ;; themes
 ;; https://melpa.org/#/?q=theme&sort=downloads&asc=false
 ;; (load-theme 'material t)
 ;; (load-theme 'material-light t)
 ;; (load-theme 'solarized-dark t)
 ;; (load-theme 'solarized-light t)

 (require 'doom-themes)
 ;; Global settings (defaults)
 (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
	doom-themes-enable-italic t) ; if nil, italics is universally disabled
 ;; Load the theme (doom-one, doom-molokai, etc); keep in mind that each
 ;; theme may have their own settings.
 (load-theme 'doom-one t)
 ;; (load-theme 'doom-one-light t)
 ;; (load-theme 'doom-vibrant t)
 ;; Enable flashing mode-line on errors
 (doom-themes-visual-bell-config)
 ;; Enable custom neotree theme
 (doom-themes-neotree-config)  ; all-the-icons fonts must be installed!

 (mouse-wheel-mode t)

 ;; nice scrolling
 (setq scroll-margin 1
	scroll-step 1
	scroll-conservatively 100000
	scroll-preserve-screen-position 1)

 ;; clean mode line
 (defvar mode-line-cleaner-alist
   `((abbrev-mode    . "")
     (company-mode   . "")
     (undo-tree-mode . "")
     (eldoc-mode     . "")
     (paredit-mode   . " π")
     ;; Major modes
     (dired-mode            . "dir")
     (lisp-interaction-mode . "λ")
     (cperl-mode            . "pl")
     (python-mode           . "py")
     (ruby-mode             . "rb")
     (emacs-lisp-mode       . "el")
     (typescript-mode       . "ts")
     (javascript-mode       . "js")
     (js-mode               . "js")
     (js2-mode              . "js")))
 (defun clean-mode-line ()
   (interactive)
   (cl-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)

 ;; display time on mode-line
 (setq display-time-day-and-date t)
 (setq display-time-format "%m/%d %H:%M")           ; 11/10 15:26
 ;; (setq display-time-format "%a %d %b %I:%M %p")  ; Fri 10 Nov 3:26 PM
 ;; (setq display-time-format "%a %d %b %H:%M")     ; Fri 10 Nov 15:26
 (display-time)

 ;; mode line settings
 (line-number-mode t)
 (global-display-line-numbers-mode)
 (column-number-mode t)
 (size-indication-mode t)
 (global-hl-line-mode t) ; highlight current line
 ;; (global-visual-line-mode t)

 (require 'volatile-highlights)
 (volatile-highlights-mode t)
 (diminish 'volatile-highlights-mode)

 (require 'powerline)
 (powerline-default-theme)

 (require 'smart-mode-line)
 (setq sml/no-confirm-load-theme t)
 ;; delegate theming to the currently active theme
 (setq sml/theme nil)
 (add-hook 'after-init-hook #'sml/setup)

 ;; show available keybindings after you start typing
 (require 'which-key)
 (which-key-mode 1)

 ;; tramp, for sudo access
 (require 'tramp)
 ;; keep in mind known issues with zsh - see emacs wiki
 (setq tramp-default-method "ssh")

 ;; frame demostration
 (defun set-frame-size-according-to-resolution ()
   (interactive)
   (when window-system
     (if (> (x-display-pixel-width) 1280)
	  (add-to-list 'default-frame-alist (cons 'width 120))
	(add-to-list 'default-frame-alist (cons 'width 80)))
     ;; for the height, subtract a couple hundred pixels
     ;; from the screen height (for panels, menubars and
     ;; whatnot), then divide by the height of a char to
     ;; get the height we want
     (add-to-list 'default-frame-alist
		   (cons 'height (/ (- (x-display-pixel-height) 200) (frame-char-height))))))
 (set-frame-size-according-to-resolution)

 (when window-system
   ;; frame postition
   (setq initial-frame-alist '((top . 0) (left . 200))))

 ;;(add-to-list 'default-frame-alist '(fullscreen . maximized))

Editor Settings

;; quiet, please! No dinging!
(setq visible-bell t)
(setq ring-bell-function (lambda () t))

;; get rid of the default messages on startup
(setq initial-scratch-message nil)
(setq inhibit-startup-message t)
(setq inhibit-startup-echo-area-message t)

;; text-mode default
(setq initial-major-mode 'text-mode)
(add-hook 'text-mode-hook 'abbrev-mode)

;; make the last line end in a carriage return
(setq require-final-newline t)
;; will disallow creation of new lines when you press the "arrow-down key"
;; at end of the buffer
(setq next-line-add-newlines t)

(setq x-select-enable-clipboard t)  ; use clipboard

;; kill-ring and other settings
(setq kill-ring-max 1024)
(setq max-lisp-eval-depth 40000)
(setq max-specpdl-size 10000)
(setq undo-outer-limit 5000000)
(setq message-log-max t)
(setq eval-expression-print-length nil)
(setq eval-expression-print-level nil)
(setq global-mark-ring-max 1024)
(setq history-delete-duplicates t)
(setq tab-always-indent 'complete)   ; smart tab behaviar - indent or complete
(setq-default indent-tabs-mode nil)  ; use space instead of tab
(setq default-tab-width 4)

;; search whitespace regexp
(setq search-whitespace-regexp ".*?")

;; disable line wrap
(setq default-truncate-lines nil)
;; make side by side buffers function the same as the main window
(setq truncate-partial-width-windows nil)
;; Add F12 to toggle line wrap
(global-set-key (kbd "<f12>") 'toggle-truncate-lines)

;; get rid of yes-or-no questions - y or n is enough
(fset 'yes-or-no-p 'y-or-n-p)
;; confirm on quitting emacs
(setq confirm-kill-emacs 'yes-or-no-p)

;; sentence-end
(setq sentence-end
      "\\([。!?]\\|……\\|[.?!][]\"')}]*\\($\\|[ \t]\\)\\)[ \t\n]*")
(setq sentence-end-double-space nil)

;; recursive minibuffers
(setq enable-recursive-minibuffers t)

;; follow-mode allows easier editing of long files
(follow-mode t)

;; show matched parentheses
(show-paren-mode t)
;; highlight just brackets
(setq show-paren-style 'parenthesis)
;; highlight entire bracket expression
                                        ;(setq show-paren-style 'expression)
;; highlight brackets if visible, else entire expression
                                        ;(setq show-paren-style 'mixed)
;; typing any left bracket automatically insert the right matching bracket
;; new feature in Emacs 24
(electric-pair-mode t)
;; setting for auto-close brackets for electric-pair-mode
;; regardless of current major mode syntax table
(setq electric-pair-pairs '(
                            (?\" . ?\")
                            (?\{ . ?\})
                            ))

;; smart tab behavior - indent or complete
(setq tab-always-indent 'complete)

;; smart pairing for all
(require 'smartparens-config)
(setq sp-base-key-bindings 'paredit)
(setq sp-autoskip-closing-pair 'always)
(setq sp-hybrid-kill-entire-symbol nil)
(sp-use-paredit-bindings)

(show-smartparens-global-mode +1)

;; paredit-mode
(autoload 'enable-paredit-mode "paredit"
  "Turn on pseudo-structural editing of Lisp code."
  t)
(add-hook 'emacs-lisp-mode-hook       'enable-paredit-mode)
(add-hook 'lisp-mode-hook             'enable-paredit-mode)
(add-hook 'lisp-interaction-mode-hook 'enable-paredit-mode)
(add-hook 'scheme-mode-hook           'enable-paredit-mode)

;; meaningful names for buffers with the same name
(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)
(setq uniquify-separator "/")
(setq uniquify-after-kill-buffer-p t)    ; rename after killing uniquified
(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers

;; mouse avoidance
;; banish, exile, jump, animate,
;; cat-and-mouse, proteus
(mouse-avoidance-mode 'animate)
(auto-image-file-mode)
(global-font-lock-mode t)   ; syntax
(transient-mark-mode t)     ; highlight mark area
(setq shift-select-mode t)  ; hold shift to mark area
(delete-selection-mode t)   ; overwrite selection

;; enable some figures
(put 'set-goal-column 'disabled nil)
(put 'narrow-to-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)

;; store all backup and autosave files in the tmp dir
(setq backup-directory-alist
      `((".*" . ,temporary-file-directory)))
(setq auto-save-file-name-transforms
      `((".*" ,temporary-file-directory t)))

;; autosave the undo-tree history
(setq undo-tree-history-directory-alist
      `((".*" . ,temporary-file-directory)))
(setq undo-tree-auto-save-history t)

;; undo-tree
(when (require 'undo-tree nil 'noerror)
  (global-undo-tree-mode 1)
  (defalias 'redo 'undo-tree-redo)
  (global-set-key (kbd "C-z") 'undo)
  (global-set-key (kbd "C-S-z") 'redo))

;; saveplace remembers your location in a file when saving files
(setq save-place-file (expand-file-name "saveplace" wf-my-savefile-dir))
;; activate it for all buffers
(save-place-mode 1)

;; savehist keeps track of some history
(require 'savehist)
(setq savehist-additional-variables
      ;; search entries
      '(search-ring regexp-search-ring)
      ;; save every minute
      savehist-autosave-interval 60
      savehist-file (expand-file-name "savehist" wf-my-savefile-dir))
(savehist-mode 1)

;; recent files
(require 'recentf)
(setq recentf-save-file (expand-file-name "recentf" wf-my-savefile-dir)
      recentf-max-saved-items 500
      recentf-max-menu-items 60
      ;; disable recentf-cleanup on Emacs start, because it can cause
      ;; problems with remote files
      recentf-auto-cleanup 'never)

(recentf-mode 1)

;; bookmarks
(require 'bookmark)
(setq bookmark-default-file (expand-file-name "bookmarks" wf-my-savefile-dir)
      bookmark-save-flag 1)

;; ido-mode is like magic pixie dust!
(ido-mode t)
(setq ido-enable-prefix nil
      ido-enable-flex-matching t
      ido-auto-merge-work-directories-length nil
      ido-create-new-buffer 'always
      ido-use-filename-at-point 'guess
      ido-use-virtual-buffers t
      ido-handle-duplicate-virtual-buffers 2
      ido-max-prospects 10
      ido-save-directory-list-file (expand-file-name "idohist" wf-my-savefile-dir))

;; projectile is a project management mode
(require 'projectile)
(setq projectile-cache-file (expand-file-name "projectile.cache" wf-my-savefile-dir))
(setq projectile-mode-line
      '(:eval (format " Proj[%s]" (projectile-project-name))))
(projectile-global-mode t)

(global-set-key (kbd "M-%") 'anzu-query-replace)
(global-set-key (kbd "C-M-%") 'anzu-query-replace-regexp)

;; use shift + arrow keys to switch between visible buffers
(require 'windmove)
(windmove-default-keybindings)

;; to prevent error like:
;; "help-setup-xref: Symbol's value as variable is void: help-xref-following"
(require 'help-mode)

(require 'htmlize)

;; diminish keeps the modeline tidy
(require 'diminish)

(setq make-backup-files nil)  ; stop creating those backup~ files
(setq auto-save-default nil)  ; stop creating those #auto-save# files
(setq backup-by-copying t)
(setq dired-recursive-deletes 'always)
(setq dired-recursive-copies  'top)
(setq delete-by-moving-to-trash t)  ; delete to trach

;; revert buffers automatically when underlying files are changed externally
(global-auto-revert-mode t)

(require 'expand-region)

;; enable some really cool extensions like C-x C-j(dired-jump)
(require 'dired-x)

;; ediff - don't start another frame
(require 'ediff)
(setq ediff-window-setup-function 'ediff-setup-windows-plain)

;; clean up obsolete buffers automatically
(require 'midnight)

(defadvice exchange-point-and-mark (before deactivate-mark activate compile)
  "When called with no active region, do not activate mark."
  (interactive
   (list (not (region-active-p)))))

(require 'tabify)
(defmacro with-region-or-buffer (func)
  "When called with no active region, call FUNC on current buffer."
  `(defadvice ,func (before with-region-or-buffer activate compile)
     (interactive
      (if mark-active
          (list (region-beginning) (region-end))
        (list (point-min) (point-max))))))

(with-region-or-buffer indent-region)
(with-region-or-buffer untabify)

;; enable winner-mode to manage window configurations
(winner-mode +1)

;; diff-hl
(global-diff-hl-mode +1)
(add-hook 'dired-mode-hook 'diff-hl-dired-mode)

;; re-builder
(require 're-builder)
(setq reb-re-syntax 'string)

(defun reb-query-replace (to-string)
  "Replace current RE from point with `query-replace-regexp'."
  (interactive
   (progn (barf-if-buffer-read-only)
          (list (query-replace-read-to (reb-target-binding reb-regexp)
                                       "Query replace"  t))))
  (with-current-buffer reb-target-buffer
    (query-replace-regexp (reb-target-binding reb-regexp) to-string)))

(defun reb-beginning-of-buffer ()
  "In re-builder, move target buffer point position back to beginning."
  (interactive)
  (set-window-point (get-buffer-window reb-target-buffer)
                    (with-current-buffer reb-target-buffer (point-min))))

(defun reb-end-of-buffer ()
  "In re-builder, move target buffer point position back to beginning."
  (interactive)
  (set-window-point (get-buffer-window reb-target-buffer)
                    (with-current-buffer reb-target-buffer (point-max))))
;; end of re-builder

;; ibuffer
(when (require 'ibuffer nil 'noerror)
  (global-set-key (kbd "C-x C-b") 'ibuffer)
  (setq ibuffer-saved-filter-groups
        (quote (("default"
                 ("dired" (mode . dired-mode))
                 ("perl"  (mode . cperl-mode))
                 ("erc"   (mode . erc-mode))
                 ("planner"
                  (or
                   (name . "^\\*Calendar\\*$")
                   (name . "^diary$")
                   (mode . muse-mode)))
                 ("emacs"
                  (or
                   (name . "^\\*scratch\\*$")
                   (name . "^\\*Messages\\*$")))
                 ("gnus"
                  (or
                   (mode . message-mode)
                   (mode . bbdb-mode)
                   (mode . mail-mode)
                   (mode . gnus-group-mode)
                   (mode . gnus-summary-mode)
                   (mode . gnus-article-mode)
                   (name . "^\\.bbdb$")
                   (name . "^\\.newsrc-dribble"))))))))
(add-hook 'ibuffer-mode-hook
          (lambda ()
            (ibuffer-switch-to-saved-filter-groups "default")))

(eval-after-load "diff-mode"
  '(progn
     (set-face-foreground 'diff-added "green4")
     (set-face-foreground 'diff-removed "red3")))

;; Get around the emacswiki spam protection
(eval-after-load "oddmuse"
  '(add-hook 'oddmuse-mode-hook
             (lambda ()
               (unless (string-match "question" oddmuse-post)
                 (setq oddmuse-post (concat "uihnscuskc=1;" oddmuse-post))))))

User Defined Functions

(defun wf-kill-other-buffers ()
  "Kill all other buffers."
  (interactive)
  (mapc 'kill-buffer
        (delq (current-buffer) (buffer-list))))

(defun wf-kill-dired-buffers ()
  "Kill all dired buffers."
  (interactive)
  (mapc (lambda (buffer)
          (when (eq 'dired-mode (buffer-local-value 'major-mode buffer))
            (kill-buffer buffer)))
        (buffer-list)))

(defun wf-local-comment-auto-fill ()
  (set (make-local-variable 'comment-auto-fill-only-comments) t)
  (auto-fill-mode t))

(defun wf-pretty-lambdas ()
  (font-lock-add-keywords
   nil `(("(?\\(lambda\\>\\)"
          (0 (progn (compose-region (match-beginning 1) (match-end 1)
                                    ,(make-char 'greek-iso8859-7 107))
                    nil))))))

(add-hook 'prog-mode-hook 'wf-local-comment-auto-fill)
(add-hook 'prog-mode-hook 'wf-pretty-lambdas)

(defun wf-prog-mode-hook ()
  (run-hooks 'prog-mode-hook))

(defun wf-untabify-buffer ()
  (interactive)
  (untabify (point-min) (point-max)))

(defun wf-indent-buffer ()
  (interactive)
  (indent-region (point-min) (point-max)))

(defun wf-cleanup-buffer ()
  "Perform a bunch of operations on the whitespace content of a buffer."
  (interactive)
  (wf-indent-buffer)
  (wf-untabify-buffer)
  (delete-trailing-whitespace))

(defun wf-eol-conversion (new-eol)
  "Specify new end-of-line conversion NEW-EOL for the buffer's file
   coding system. This marks the buffer as modified.
   specifying `unix', `dos', or `mac'."
  (interactive "SEnd-of-line conversion for visited file: \n")
  ;; Check for valid user input.
  (unless (or (string-equal new-eol "unix")
              (string-equal new-eol "dos")
              (string-equal new-eol "mac"))
    (error "Invalid EOL type, %s" new-eol))
  (if buffer-file-coding-system
      (let ((new-coding-system (coding-system-change-eol-conversion
                                buffer-file-coding-system new-eol)))
        (set-buffer-file-coding-system new-coding-system))
    (let ((new-coding-system (coding-system-change-eol-conversion
                              'undecided new-eol)))
      (set-buffer-file-coding-system new-coding-system)))
  (message "EOL conversion now %s" new-eol))

;; Commands

(defun wf-eval-and-replace ()
  "Replace the preceding sexp with its value."
  (interactive)
  (backward-kill-sexp)
  (condition-case nil
      (prin1 (eval (read (current-kill 0)))
             (current-buffer))
    (error (message "Invalid expression")
           (insert (current-kill 0)))))

(defun wf-lorem ()
  "Insert a lorem ipsum."
  (interactive)
  (insert "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do "
          "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim"
          "ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut "
          "aliquip ex ea commodo consequat. Duis aute irure dolor in "
          "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
          "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
          "culpa qui officia deserunt mollit anim id est laborum."))

(defun wf-insert-date ()
  "Insert a time-stamp according to locale's date and time format."
  (interactive)
  (insert (format-time-string "%c" (current-time))))

(defun wf-pairing-bot ()
  "If you can't pair program with a human, use this instead."
  (interactive)
  (message (if (y-or-n-p "Do you have a test for that? ") "Good." "Bad!")))

(defun wf-align-repeat (start end regexp)
  "Repeat alignment with respect to the given regular expression."
  (interactive "r\nsAlign regexp: ")
  (align-regexp start end
                (concat "\\(\\s-*\\)" regexp) 1 1 t))

;; swap lines
;; just like org-metaup/org-metadown
(defun wf-swap-line-up ()
  "Swap the current line with the line above."
  (interactive)
  (transpose-lines 1)
  (beginning-of-line -1))

(defun wf-swap-line-down ()
  "Swap current line with the line below."
  (interactive)
  (beginning-of-line 2)
  (transpose-lines 1)
  (beginning-of-line 0))

;; cut, copy, yank

;;(defadvice kill-region (before slick-cut activate compile)
;;  "When called interactively with no active region, kill a single line instead."
;;  (interactive
;;   (if mark-active
;;       (list (region-beginning) (region-end))
;;     (list (line-beginning-position) (line-beginning-position 2)))))

;;(defadvice kill-ring-save (before slick-copy activate compile)
;;  "When called interactively with no active region, copy a single line instead."
;;  (interactive
;;   (if mark-active
;;       (list (region-beginning) (region-end))
;;     (message "Copied line")
;;     (list (line-beginning-position) (line-beginning-position 2)))))

;; Emacs 24.4 introduces a new advice system. While defadvice still works,
;; there is a chance that it might be deprecated in favor of the new system
;; in future versions of Emacs. To prepare for that, you might want to use
;; updated versions of slick-cut and slick-copy:

(defun slick-cut (beg end)
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (list (line-beginning-position) (line-beginning-position 2)))))
(advice-add 'kill-region :before #'slick-cut)

(defun slick-copy (beg end)
  (interactive
   (if mark-active
       (list (region-beginning) (region-end))
     (message "Copied line")
     (list (line-beginning-position) (line-beginning-position 2)))))
(advice-add 'kill-ring-save :before #'slick-copy)

Modes

Major modes for coding: lisp, elisp, f2e, php, perl, etc.

shell

(add-hook 'shell-mode-hook
  (lambda ()
    (define-key shell-mode-map (kbd "<M-up>") 'comint-previous-input)
    (define-key shell-mode-map (kbd "<M-down>") 'comint-next-input)))

company

(require 'company)

(setq company-idle-delay 0.5)
(setq company-tooltip-limit 10)
(setq company-minimum-prefix-length 2)
;; invert the navigation direction if the the completion popup-isearch-match
;; is displayed on top (happens near the bottom of windows)
(setq company-tooltip-flip-when-above t)

(global-company-mode 1)

helm

;; helm
(require 'helm)

(global-set-key (kbd "M-x") 'helm-M-x)

(setq helm-completion-style 'helm-fuzzy)
(setq completion-styles '(flex))

(setq helm-recentf-fuzzy-match t)
(setq helm-buffers-fuzzy-matching t)
(setq helm-locate-fuzzy-match t)
(setq helm-M-x-fuzzy-match t)
(setq helm-semantic-fuzzy-match t)
(setq helm-imenu-fuzzy-match t)
(setq helm-apropos-fuzzy-match t)
(setq helm-lisp-fuzzy-completion t)
(setq helm-mode-fuzzy-match t)
(setq helm-completion-in-region-fuzzy-match t)
(setq helm-candidate-number-limit 20)
(setq helm-split-window-in-side-p t)

;; The default "C-x c" is quite close to "C-x C-c", which quits Emacs.
;; Changed to "C-c h". Note: We must set "C-c h" globally, because we
;; cannot change `helm-command-prefix-key' once `helm-config' is loaded.
(global-set-key (kbd "C-c h") 'helm-command-prefix)
(global-unset-key (kbd "C-x c"))

;; helm everywhere

(require 'helm-eshell)

(global-set-key (kbd "M-x") 'helm-M-x)
(global-set-key (kbd "C-x C-m") 'helm-M-x)
(global-set-key (kbd "M-y") 'helm-show-kill-ring)
(global-set-key (kbd "C-x b") 'helm-mini)
(global-set-key (kbd "C-x C-b") 'helm-buffers-list)
(global-set-key (kbd "C-x C-f") 'helm-find-files)
(global-set-key (kbd "C-h f") 'helm-apropos)
(global-set-key (kbd "C-h r") 'helm-info-emacs)
(global-set-key (kbd "C-h C-l") 'helm-locate-library)

;; use helm to list eshell history
(add-hook 'eshell-mode-hook
          #'(lambda ()
              (substitute-key-definition 'eshell-list-history 'helm-eshell-history eshell-mode-map)))

(helm-mode 1)

;; enable Helm version of Projectile with replacment commands
(helm-projectile-on)

Lisp

slime

;; slime
(when *hack-slime-p*
  (if *is-mac-p*
    (progn
     (setq inferior-lisp-program "sbcl")
     (load (expand-file-name "~/quicklisp/slime-helper.el"))))
  (if *is-win-p*
    (progn
      (setq inferior-lisp-program "sbcl")
      (load "C:\\quicklisp\\slime-helper.el"))))

emacs-lisp

;;; emacs-lisp-mode
;; now '-' is not considered a word-delimiter
(add-hook 'emacs-lisp-mode-hook
          '(lambda ()
             (modify-syntax-entry ?- "w")))

cperl-mode

cperl-mode is a more advanced mode for programming Perl than the default Perl Mode.

;;; cperl-mode

(defalias 'perl-mode 'cperl-mode)

(mapc (lambda (pair)
        (if (eq (cdr pair) 'perl-mode)
            (setcdr pair 'cperl-mode)))
      (append auto-mode-alist interpreter-mode-alist))

;; customizing cperl-mode
(defun wf-cperl-mode-init ()
  (setq cperl-font-lock t
        cperl-electric-keywords t
        cperl-indent-level 4
        cperl-indent-parens-as-block t
        cperl-clobber-lisp-bindings t
        cperl-close-paren-offset -4
        cperl-continued-brace-offset -4
        cperl-continued-statement-offset 4
        cperl-extra-newline-before-brace t
        cperl-brace-offset -4
        cperl-label-offset -2
        cperl-lazy-help-time 3
        cperl-tab-always-indent t
        cperl-electric-lbrace-space t
        cperl-electric-parens nil
        cperl-electric-linefeed nil
        cperl-electric-keywords nil
        cperl-extra-newline-before-brace nil
        cperl-extra-newline-before-brace-multiline nil
        cperl-invalid-face nil)

  (set-face-background 'cperl-array-face nil)
  (set-face-background 'cperl-hash-face nil))

(define-abbrev-table 'global-abbrev-table
  '(("pdbg"   "use Data::Dumper qw( Dumper );" nil 1)
    ("phbp"   "#!/usr/bin/env perl -w"         nil 1)
    ("pusc"   "use Smart::Comments;\n\n### "   nil 1)
    ("putm"   "use Test::More 'no_plan';"      nil 1)))

(add-hook 'cperl-mode-hook
          (lambda ()
            (wf-cperl-mode-init)
            (local-set-key (kbd "C-h f") 'cperl-perldoc)))

XML

(require 'nxml-mode)

(push '("<\\?xml" . nxml-mode) magic-mode-alist)

;; pom files should be treated as xml files
(add-to-list 'auto-mode-alist '("\\.pom$" . nxml-mode))

(setq nxml-child-indent 4)
(setq nxml-attribute-indent 4)
(setq nxml-auto-insert-xml-declaration-flag nil)
(setq nxml-bind-meta-tab-to-complete-flag t)
(setq nxml-slash-auto-complete-flag t)

org-mode

Org mode is for keeping notes, maintaining TODO lists, planning projects, and authoring documents with a fast and effective plain-text system.

(require 'org)
(require 'remember)
(require 'org-mouse)
(require 'org-tempo)

(org-indent-mode -1)

;; I want files with the extension ".org" to open in org-mode.
(add-to-list 'auto-mode-alist
             '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))

;; Some basic keybindings.
(global-set-key "\C-cl" 'org-store-link)
(global-set-key "\C-ca" 'org-agenda)
(global-set-key "\C-cr" 'org-remember)

;; a basic set of keywords to start out
(setq org-todo-keywords
      '((sequence "TODO(t)" "STRT(s)" "|" "DONE(d)")
        (sequencep "WAIT(w@/!)" "|" "CANL(c@/!)")))

(setq org-todo-keyword-faces
      '(("TODO" :foreground "orange red" :weight bold)
        ("STRT" :foreground "cyan" :weight bold)
        ("DONE" :foreground "lime green" :weight bold)
        ("WAIT" :foreground "orange" :weight bold)
        ("CANL" :foreground "dim gray" :weight bold)))

;; I use org's tag feature to implement contexts.
(setq org-tag-alist '(("WORK" . ?w)
                      ("HOME" . ?h)
                      ("SERV" . ?s)
                      ("PROJ" . ?p)))

;; I put the archive in a separate file, because the gtd file will
;; probably already get pretty big just with current tasks.
(setq org-archive-location "%s_archive::")

(defun org-summary-todo (n-done n-not-done)
  "Switch entry to DONE when all subentries are done, to TODO otherwise."
  (let (org-log-done org-log-states)   ; turn off logging
    (org-todo (if (= n-not-done 0) "DONE" "TODO"))))

(add-hook 'org-after-todo-statistics-hook 'org-summary-todo)

LaTeX and AUCTEX

;; AucTeX

(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)
;;(add-hook 'LaTeX-mode-hook 'visual-line-mode)
(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
(add-hook 'LaTeX-mode-hook 'turn-on-reftex)
(setq reftex-plug-into-AUCTeX t)
(setq TeX-PDF-mode t)

(setq latex-mode-hook
      '(lambda ()
         (turn-off-auto-fill)))

(autoload 'reftex-mode    "reftex" "RefTeX Minor Mode" t)
(autoload 'turn-on-reftex "reftex" "RefTeX Minor Mode" t)

(add-hook 'LaTeX-mode-hook
          (lambda ()
            (setq TeX-auto-untabify t       ; remove all tabs before saving
                  TeX-engine 'xetex         ; use xelatex default
                  TeX-global-PDF-mode t)    ; PDF mode enable, not plain
            (add-to-list 'TeX-command-list
                         '("XeLaTeX" "%'xelatex --synctex=1%(mode)%' %t"
                           TeX-run-TeX nil t))
            (setq TeX-command-default "XeLaTeX")
            (setq LaTeX-command "latex -synctex=1")
            (setq TeX-source-correlate-mode t)
            (setq TeX-source-correlate-start-server t)
            (setq TeX-source-correlate-method 'synctex)
            (add-to-list 'TeX-expand-list '("%u" skim-make-url))

            (when *is-win-p*
              ;; SumatraPDF Options:
              ;; Set inverse search command-line
              ;; "C:\emacs\bin\emacsclientw.exe" -n +%l "%f"
              ;; formerly, I could set inverse search in emacs directly like this:
              ;; (mode-io-correlate " -forward-search %b %n -inverse-search \"emacsclientw --no-wait +%%l \\\"%%f\\\"\" ")
              ;; this does not work anymore :/
              (setq TeX-view-program-list
                    '(("SumatraPDF" ("\"C:/emacs/bin/SumatraPDF.exe\" -reuse-instance"
                                     (mode-io-correlate " -forward-search %b %n ") " %o"))))
              (setq TeX-view-program-selection
                    '((output-pdf "SumatraPDF"))))

            (when *is-mac-p*
              ;; cat ~/.latexmkrc
              ;;
              ;; $pdflatex = 'pdflatex -interaction=nonstopmode -synctex=1 %O %S';
              ;; $pdf_previewer = 'open -a skim';
              ;; $clean_ext = 'bbl rel %R-blx.bib %R.synctex.gz';
              ;;
              ;; This perfectly allows to compile with latexmk as default on C-c C-c and C-c C-v opens Skim at the current line which is nicely highlighted.
              ;; With CMD + shift + click in the .pdf, one can then jump back to the corresponding paragraph in the .tex file.
              ;; Thanks to `(server-start)'.
              ;;
              (setq TeX-view-program-list
                    '(("Skim" "/Applications/Skim.app/Contents/SharedSupport/displayline -b -g %n %o %b")))
              (setq TeX-view-program-selection
                    '((output-pdf "Skim"))))

            (setq TeX-clean-confirm nil)
            (setq TeX-save-query nil)
            (imenu-add-menubar-index)
            (auto-composition-mode 1)
            (outline-minor-mode 1)
            (setq TeX-show-compilation nil)
            (define-key LaTeX-mode-map (kbd "TAB") 'TeX-complete-symbol)))

;; http://www.cs.berkeley.edu/~prmohan/emacs/latex.html
(defun skim-make-url ()
  "Skim PDF Viewer"
  (concat
   (TeX-current-line)
   " "
   (expand-file-name (funcall file (TeX-output-extension) t)
                     (file-name-directory (TeX-master-file)))
   " "
   (buffer-file-name)))

(require 'reftex)
(add-hook 'LaTeX-mode-hook 'turn-on-reftex)
(setq reftex-plug-into-AUCTeX t)
(setq reftex-enable-partial-scans t)
(setq reftex-save-parse-info t)
(setq reftex-use-multiple-selection-buffers t)
(autoload 'reftex-mode "reftex"
  "RefTeX Minor Mode" t)
(autoload 'turn-on-reftex "reftex"
  "RefTeX Minor Mode" nil)
(autoload 'reftex-citation "reftex-cite"
  "Make citation" nil)
(autoload 'reftex-index-phrase-mode
  "reftex-index" "Phrase mode" t)

markdown-mode

(autoload 'markdown-mode "markdown-mode"
   "Major mode for editing Markdown files" t)
(add-to-list 'auto-mode-alist '("\\.text\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))

Key Bindings

;; resolve conflict with Windows IME
(when window-system
  (global-set-key (kbd "M-SPC") 'set-mark-command))

;; when in macOS, alt is alt, command is meta
(when (string-equal system-type 'darwin)
  (setq mac-option-key-is-meta nil)
  (setq mac-command-key-is-meta t)
  (setq mac-command-modifier 'meta)
  (setq mac-option-modifier nil))

;; Align your code in a pretty way.
(global-set-key (kbd "C-x \\") 'align-regexp)

;; Increase and decrease font size
(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)

;; Start eshell or switch to it if it's active
(global-set-key (kbd "C-x m") 'eshell)

;; Start a new eshell even if one is active
(global-set-key (kbd "C-x M") (lambda () (interactive) (eshell t)))

;; Start a regular shell
(global-set-key (kbd "C-x M-m") 'shell)

;; replace zap-to-char functionality with the more powerful zop-to-char
(global-set-key (kbd "M-z") 'zop-up-to-char)
(global-set-key (kbd "M-Z") 'zop-to-char)

;; (global-set-key (kbd "<f2>") 'kill-region)
;; (global-set-key (kbd "<f3>") 'kill-ring-save)
;; (global-set-key (kbd "<f4>") 'yank)

;; (global-set-key (kbd "C-M-h") 'backward-kill-word)

;; C-k               kill-line
;; C-0 C-k           kill line backword
;; C-a, C-k, C-k     kill-whole-line in another way
;; kill-whole-line
(global-set-key (kbd "M-9") 'kill-whole-line)

;; kill lines backward
(global-set-key (kbd "C-<backspace>") (lambda ()
                                        (interactive)
                                        (kill-line 0)
                                        (indent-according-to-mode)))

(global-set-key (kbd "C-c q") 'join-line)

;; Activate occur easily inside isearch
(define-key isearch-mode-map (kbd "C-o")
  (lambda () (interactive)
    (let ((case-fold-search isearch-case-fold-search))
      (occur (if isearch-regexp isearch-string
               (regexp-quote isearch-string))))))

;; Completion that uses many different methods to find options.
(global-set-key (kbd "M-/") 'hippie-expand)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "C-c n") 'wf-cleanup-buffer)
(global-set-key (kbd "C-c C-k") 'wf-kill-other-buffers)
(global-set-key (kbd "C-c C-d") 'wf-kill-dired-buffers)
(global-set-key (kbd "C-<f10>") 'menu-bar-mode)

;; Use regex searches by default.
(global-set-key (kbd "C-s") 'isearch-forward-regexp)
(global-set-key (kbd "C-r") 'isearch-backward-regexp)
(global-set-key (kbd "M-%") 'query-replace-regexp)
(global-set-key (kbd "C-M-s") 'isearch-forward)
(global-set-key (kbd "C-M-r") 'isearch-backward)
(global-set-key (kbd "C-M-%") 'query-replace)
(global-set-key (kbd "M-<f12>") 'recentf-open-files)

(global-set-key (kbd "C-=") 'er/expand-region)

;; Jump to a definition in the current file. (Protip: this is awesome.)
(global-set-key (kbd "C-x C-i") 'imenu)

;; Make the sequence "C-c g" execute the 'goto-line' command,
;; which prompts for a line number to jump to.
(global-set-key (kbd "C-c C-g") 'goto-line)

;; Make the sequence "C-x w" execute the 'what-line' command,
;; which prints the current line number in the echo area.
(global-set-key (kbd "C-c C-w") 'what-line)

(global-set-key (kbd "C-c j") 'avy-goto-word-or-subword-1)
(global-set-key (kbd "s-.") 'avy-goto-word-or-subword-1)

(global-set-key (kbd "C-c e")    'wf-eval-and-replace)
(global-set-key (kbd "<M-up>")   'wf-swap-line-up)
(global-set-key (kbd "<M-down>") 'wf-swap-line-down)

;; 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-liks-this)
(global-set-key (kbd "C-c C-<")     'mc/mark-all-like-this)

Misc

Abbrev

Define some words abbreviation.

;; my personal abbreviations
(define-abbrev-table 'global-abbrev-table
  '(
    ;; my info
    ("8eml" "[email protected]")

    ;; math/unicode symbols
    ("8inf"  "")
    ("8luv"  "")
    ("8smly" "")

    ;; tech
    ("8wp" "Wikipedia")
    ("8ms" "Microsoft")
    ("8go" "Google")
    ("8qt" "QuickTime")
    ("8it" "IntelliType")
    ("8msw" "Microsoft Windows")
    ("8win" "Windows")
    ("8ie" "Internet Explorer")
    ("8ps" "PowerShell")
    ("8mma" "Mathematica")
    ("8js" "JavaScript")
    ("8vb" "Visual Basic")
    ("8yt" "YouTube")
    ("8ge" "Google Earth")
    ("8ff" "Firefox")

    ;; normal english words
    ("8alt" "alternative")
    ("8char" "character")
    ("8def" "definition")
    ("8bg" "background")
    ("8kb" "keyboard")
    ("8ex" "example")
    ("8kbd" "keybinding")
    ("8env" "environment")
    ("8var" "variable")
    ("8ev" "environment variable")
    ("8cp" "computer")

    ;; emacs regex
    ("8num" "\\([0-9]+?\\)")
    ("8str" "\\([^\"]+?\\)\"")
    ("8curly" "\\([^”]+?\\)”")
    ))

;; stop asking whether to save newly added abbrev when quitting emacs
(setq save-abbrevs nil)

;; turn on abbrev mode
(abbrev-mode 1)

Alias

Use some alias to shorten commands.

; shortening of often used commands

(defalias 'ff 'toggle-frame-fullscreen)
(defalias 'fm 'toggle-frame-maximized)

(defalias 'qrr 'query-replace-regexp)
(defalias 'rebq 'reb-query-replace)
(defalias 'lml 'list-matching-lines)
(defalias 'dml 'delete-matching-lines)
(defalias 'dnml 'delete-non-matching-lines)
(defalias 'dws 'delete-trailing-whitespace)
(defalias 'sl 'sort-lines)
(defalias 'rr 'reverse-region)
(defalias 'rs 'replace-string)

(defalias 'g 'grep)
(defalias 'gf 'grep-find)
(defalias 'fd 'find-dired)

(defalias 'rb 'revert-buffer)

(defalias 'sb 'speedbar)
(defalias 'cc 'calc)
(defalias 'sh 'shell)
(defalias 'ps 'powershell)
(defalias 'fb 'flyspell-buffer)
(defalias 'sbc 'set-background-color)
(defalias 'rof 'recentf-open-files)
(defalias 'lcd 'list-colors-display)

; elisp
(defalias 'eb 'eval-buffer)
(defalias 'er 'eval-region)
(defalias 'ed 'eval-defun)
(defalias 'lf 'load-file)
(defalias 'eis 'elisp-index-search)

; major modes
(defalias 'hm 'html-mode)
(defalias 'tm 'text-mode)
(defalias 'om 'org-mode)
(defalias 'elm 'emacs-lisp-mode)
(defalias 'ssm 'shell-script-mode)

; minor modes
(defalias 'wsm 'whitespace-mode)
(defalias 'gwsm 'global-whitespace-mode)
(defalias 'dsm 'desktop-save-mode)
(defalias 'acm 'auto-complete-mode)
(defalias 'vlm 'visual-line-mode)