;; -*- lexical-binding: t -*- (setq load-prefer-newer t) ;; We set `user-emacs-directory' here so we can use command-line ;; switch different emacs configuration like following: ;; ;; emacs -q -l ~/coldnew-spacemacs/init.el (defconst user-emacs-directory (file-name-directory (or load-file-name (buffer-file-name))) "My emacs config directory.") (defconst user-cache-directory (file-name-as-directory (concat user-emacs-directory ".cache")) "My emacs storage area for persistent files.") ;; create the `user-cache-directory' if not exists (make-directory user-cache-directory t) (defconst user-ramdisk-directory (let ((ramdisk "/Volumes/ramdisk/") (user-ramdisk ; ~/ramdisk/ (concat (getenv "HOME") "/ramdisk/")) (tmp "/tmp/")) (if (eq system-type 'darwin) ramdisk ;; if ~/ramdisk/ exist, use it (if (file-exists-p user-ramdisk) user-ramdisk ;; fallcack to system default ramdisk dir temporary-file-directory))) "My ramdisk path in system.") (defun my/load-secret () "Load my secret setting include password... etc." (let ((secret "~/.secret.el.gpg")) (when (file-exists-p secret) (load-file secret)))) ;; This must come before configurations of installed packages. ;; Don't delete this line. If you don't want it, just comment it out by adding a ;; semicolon to the start of the line. You may delete these explanatory ;; comments. (package-initialize) (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/")) (add-to-list 'auto-mode-alist '("Cask$" . emacs-lisp-mode)) (require 'cask "~/.cask/cask.el") (cask-initialize) (require 'pallet) (pallet-mode t) (require 'use-package) ; Installed by Cask ;; Auto install non-installed packages. ;; (setq use-package-always-ensure t) (require 'req-package) (require 'paradox) ; Installed by Cask ;; Add directories to emacs's `load-path' recursively. ;; if path does not exist, create directory. (let* ((lisp-dir '("local-lisp/" "themes/"))) (dolist (lisp-path lisp-dir) (when (not (file-exists-p lisp-path)) (make-directory (concat user-emacs-directory lisp-path) t)) (let* ((load-dir (concat user-emacs-directory lisp-path)) (default-directory load-dir)) (setq load-path (append (let ((load-path (copy-sequence load-path))) (append (copy-sequence (normal-top-level-add-to-load-path '("."))) (normal-top-level-add-subdirs-to-load-path))) load-path))))) ;;;; add some system site-lisp to my load-path ;; Mac OSX (when (equal system-type 'darwin) (let ((default-directory "/usr/local/share/emacs/site-lisp/")) (normal-top-level-add-subdirs-to-load-path))) ;; Linux (when (equal system-type 'gnu/linux) (let ((default-directory "/usr/share/emacs/site-lisp/")) (normal-top-level-add-subdirs-to-load-path))) ;; load the `load-modules.el' file which help me load external modulept (let ((script (concat user-emacs-directory "modules/load-modules.el"))) (when (file-exists-p script) (load script))) (setq user-full-name "Yen-Chin, Lee") (setq user-mail-address "coldnew.tw@gmail.com") ;; Only start server mode if I'm not root (unless (string-equal "root" (getenv "USER")) (require 'server) (unless (server-running-p) (server-start))) (setq mac-option-modifier 'super) (setq mac-command-modifier 'meta) (setq mac-pass-command-to-system nil) (require 'noflet) (defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate) "Prevent annoying \"Active processes exist\" query when you quit Emacs." (noflet ((process-list ())) ad-do-it)) (setq kill-buffer-query-functions (remq 'process-kill-buffer-query-function kill-buffer-query-functions)) (setq-default custom-file (concat user-cache-directory "custom.el")) ;; load custom-file only when file exist (when (file-exists-p custom-file) (load-file custom-file)) (require 'async) ; Installed by Cask ;; If I'm edit my init.org, async generate init.el when save. (defun tangle-init () "If the current buffer is 'init.org' the code-blocks are tangled." (let ((buffer-name "async-make-init.el")) (when (equal (buffer-file-name) (expand-file-name (concat user-emacs-directory "init.org"))) ;; If previous building buffer exist, discard it ;; (when (get-buffer (concat "*" buffer-name "*")) ;; (kill-buffer (concat "*" buffer-name "*"))) ;; build with `make init.el' command (async-start-process buffer-name "make" '(lambda (result) (message "Re-Generate init.el")) "init.el")))) ;; Add to hook (add-hook 'after-save-hook 'tangle-init) (setq auto-save-list-file-prefix (concat user-cache-directory "auto-save-list/.saves-")) (setq auto-save-interval 100) (setq auto-save-timeout 60) (setq auto-save-visited-file-name nil) (setq delete-auto-save-files t) (let ((backup-dir (concat user-cache-directory "backup"))) ;; Move backup file to `~/.emacs.d/.cache/backup' (setq backup-directory-alist `(("." . ,backup-dir))) ;; Makesure backup directory exist (when (not (file-exists-p backup-dir)) (make-directory backup-dir t))) (setq delete-by-moving-to-trash nil) (setq version-control t) (setq kept-old-versions 10) (setq kept-new-versions 20) (setq delete-old-versions t) (setq backup-by-copying t) (when (featurep 'menu-bar) (menu-bar-mode -1)) (when (featurep 'tool-bar) (tool-bar-mode -1)) (blink-cursor-mode -1) (when (featurep 'scroll-bar) (scroll-bar-mode -1)) (setq inhibit-startup-screen t) (blink-cursor-mode -1) (setq ring-bell-function #'ignore) (setq initial-scratch-message "") (setq visible-bell t) (defalias 'yes-or-no-p 'y-or-n-p) (prefer-coding-system 'utf-8) (setq system-time-locale "en_US") (eval-after-load 'bookmark '(progn (setq bookmark-default-file (concat user-cache-directory "bookmarks")))) (eval-after-load 'dilwave '(progn (setq idlwave-config-directory (concat user-cache-directory "idlwave")))) ;; change srecode cache file path (eval-after-load 'srecode '(progn (setq srecode-map-save-file (concat user-cache-directory "srecode-map.el")))) (eval-after-load 'request '(progn (setq request-storage-directory (concat user-cache-directory "request")))) (eval-after-load 'nsm '(progn (setq nsm-settings-file (concat user-cache-directory "network-security.data")))) (eval-after-load 'url '(progn (setq url-configuration-directory (file-name-as-directory (concat user-cache-directory "url"))))) (req-package ag :if (executable-find "ag")) (req-package ascii :config (defun ascii-toggle () "Toggle ascii-mode." (interactive) (if (not (ascii-off)) (ascii-on))) ;; alias ascii to ascii-toggle (defalias 'ascii 'ascii-toggle)) (req-package ascii-art-to-unicode) (req-package avy) (req-package buffer-move) (req-package bpr) (req-package calfw) (req-package cbm) (req-package crux) (req-package darkroom) (req-package discover-my-major) (when (require 'doxymacs nil 'noerror) (add-hook 'prog-mode-hook '(lambda () (doxymacs-mode)))) (req-package esup) (req-package exec-path-from-shell :config (when (memq window-system '(mac ns x)) (exec-path-from-shell-initialize))) (req-package expand-region :bind (("M-v" . er/expand-region))) (req-package fancy-narrow) (req-package focus) (req-package google-translate) (req-package howdoi) (req-package htmlize) (req-package hungry-delete :config (global-hungry-delete-mode)) (req-package hydra :config (defhydra hydra-window () " Movement^^ ^Split^ ^Switch^ ^Resize^ ---------------------------------------------------------------- _h_ ← _v_ertical _b_uffer _q_ X← _j_ ↓ _x_ horizontal _f_ind files _w_ X↓ _k_ ↑ _z_ undo _a_ce 1 _e_ X↑ _l_ → _Z_ reset _s_wap _r_ X→ _F_ollow _D_lt Other _S_ave max_i_mize _SPC_ cancel _o_nly this _d_elete " ("h" windmove-left ) ("j" windmove-down ) ("k" windmove-up ) ("l" windmove-right ) ("q" hydra-move-splitter-left) ("w" hydra-move-splitter-down) ("e" hydra-move-splitter-up) ("r" hydra-move-splitter-right) ("b" helm-mini) ("f" helm-find-files) ("F" follow-mode) ("a" (lambda () (interactive) (ace-window 1) (add-hook 'ace-window-end-once-hook 'hydra-window/body))) ("v" (lambda () (interactive) (split-window-right) (windmove-right))) ("x" (lambda () (interactive) (split-window-below) (windmove-down))) ("s" (lambda () (interactive) (ace-window 4) (add-hook 'ace-window-end-once-hook 'hydra-window/body))) ("S" save-buffer) ("d" delete-window) ("D" (lambda () (interactive) (ace-window 16) (add-hook 'ace-window-end-once-hook 'hydra-window/body))) ("o" delete-other-windows) ("i" ace-maximize-window) ("z" (progn (winner-undo) (setq this-command 'winner-undo))) ("Z" winner-redo) ("SPC" nil)) ;;(global-set-key (kbd "C-x w") 'hydra-window/body) (defhydra hydra-movement () " ^Forward^ ^Backward^ ^Up^ ^Down^ ^Char^ ^^^^^^^^--------------------------------------------------- _c_: char ^^^^^^^^ _n_: scroll down _p_: scroll up " ("c" avy-goto-char) ;; others ("n" evil-scroll-page-down) ("p" evil-scroll-page-up) ) ;;(global-set-key (kbd "C-x m") 'hydra-movement/body) (defhydra hydra-font-setup () " Font Size^^ ---------------------------------------------------------------- _=_ ↑ _\-_ ↓ " ("=" text-scale-increase) ("-" text-scale-decrease)) (defhydra hydra-window-buffer (:color red :hint nil) " ^Window^ ^Buffer^ ^Frame^ ^^^^^^^^--------------------------------------------------- ^hjkl^: move _p_: previous _u_: winner undo ....../ \-. . _s_: split below _n_: next _r_: winner redo .-/ ( o\.// _v_: split right _b_: switch _w_: revert all | ... \./\---' _c_: delete this _;_: last ^ ^ |.|| |.|| _o_: delete other _K_: kill current ^ ^ ^^^^^^^^ " ("w" revert-all-buffers :color blue) ("u" winner-undo) ("r" winner-redo) ("h" windmove-left) ("j" windmove-down) ("k" windmove-up) ("l" windmove-right) ("p" previous-buffer) ("n" next-buffer) ("b" ido-switch-buffer) (";" mode-line-other-buffer :color blue) ("s" split-window-below) ("v" split-window-right) ("K" kill-this-buffer) ("c" delete-window) ("o" delete-other-windows :color blue) ;; ("H" hydra-move-splitter-left) ;; ("J" hydra-move-splitter-down) ;; ("K" hydra-move-splitter-up) ;; ("L" hydra-move-splitter-right) ("q" nil)) (global-set-key (kbd "C-x w") 'hydra-window-buffer/body)) (req-package iedit :bind (("C-;" . iedit-mode))) (req-package know-your-http-well) (req-package kurecolor) (req-package lentic) (req-package link-hint) (req-package manage-minor-mode) (req-package mustache) (req-package mwim :bind (("C-a" . mwim-beginning-of-code-or-line) ("C-e" . mwim-end-of-code-or-line))) (req-package moedict) (req-package noflet) (req-package nand2tetris :require (company company-nand2tetris nand2tetris-assembler) :if (file-exists-p "~/Workspace/nand2tetris") :config (setq nand2tetris-core-base-dir "~/Workspace/nand2tetris")) (req-package pangu-spacing :config ;; start pangu-spacing globally (global-pangu-spacing-mode 1) ;; Always insert `real' space in org-mode. (add-hook 'org-mode-hook '(lambda () (set (make-local-variable 'pangu-spacing-real-insert-separtor) t)))) (req-package password-generator :defer t) (req-package rainbow-mode) (req-package reveal-in-osx-finder :when (eq system-type 'darwin)) (req-package smartparens :require smartparens-config :config (smartparens-mode 1)) (req-package spray) (req-package sicp) (req-package string-inflection) (req-package sx :require sx-load) (req-package tldr :init (setq tldr-directory-path (concat user-cache-directory "tldr/")) (setq tldr-saved-zip-path (concat user-cache-directory "tldr-source.zip"))) (req-package travis) (req-package url-shortener) (req-package verify-url) (req-package which-key :config ;; enable globally (which-key-mode) ;; Hide/Modify some function prefix in which-key show menu (setq which-key-description-replacement-alist '(("Prefix Command" . "prefix") ("which-key-show-next-page" . "wk next pg") ("\\`calc-" . "") ; Hide "calc-" prefixes when listing M-x calc keys ("/body\\'" . "") ; Remove display the "/body" portion of hydra fn names ("modi/" . "m/") ; The car is intentionally not "\\`modi/" to cover ; cases like `hydra-toggle/modi/..'. ("\\`hydra-" . "+h/") ("\\`org-babel-" . "ob/") ("\\`my/" . "")))) (req-package xkcd :init (setq xkcd-cache-dir (concat user-cache-directory "xkcd/")) (when (not (file-directory-p xkcd-cache-dir)) (make-directory xkcd-cache-dir :parents))) (req-package zzz-to-char :bind (("M-z" . zzz-to-char))) (defun nuke-all-buffers () "Kill all buffers, leaving *scratch* only." (interactive) (mapcar (lambda (x) (kill-buffer x)) (buffer-list)) (delete-other-windows)) (defun my/save-buffer-always () "Save the buffer even if it is not modified." (interactive) (set-buffer-modified-p t) (save-buffer)) (defun minibuffer-keyboard-quit () "Abort recursive edit. In Delete Selection mode, if the mark is active, just deactivate it; then it takes a second \\[keyboard-quit] to abort the minibuffer." (interactive) (if (and delete-selection-mode transient-mark-mode mark-active) (setq deactivate-mark t) (when (get-buffer "*Completions*") (delete-windows-on "*Completions*")) (abort-recursive-edit))) (defun untabify-buffer () (interactive) (save-excursion (untabify (point-min) (point-max)))) (defun indent-whole-buffer () "Indent whole buffer." (interactive) (save-excursion (indent-region (point-min) (point-max)))) (defun cleanup-buffer () "Perform a bunch of operations on the whitespace content of a buffer." (interactive) (save-excursion (delete-trailing-whitespace) (indent-region (point-min) (point-max)) (untabify (point-min) (point-max)))) (defun 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 quick-folding-source () "Use emacs buildin easy to folding code." (interactive) (set-selective-display (if selective-display nil 1))) (defun my/narrow-or-widen-dwim (p) "Widen if buffer is narrowed, narrow-dwim otherwise. Dwim means: region, org-src-block, org-subtree, or defun, whichever applies first. Narrowing to org-src-block actually calls `org-edit-src-code'. With prefix P, don't widen, just narrow even if buffer is already narrowed." (interactive "P") (declare (interactive-only)) (cond ((and (buffer-narrowed-p) (not p)) (widen)) ((region-active-p) (narrow-to-region (region-beginning) (region-end))) ;; org-mode ((derived-mode-p 'org-mode) ;; `org-edit-src-code' is not a real narrowing ;; command. Remove this first conditional if you ;; don't want it. (cond ((ignore-errors (org-edit-src-code)) (delete-other-windows)) ((ignore-errors (org-narrow-to-block) t)) (t (org-narrow-to-subtree)))) ;; latex-mode ((derived-mode-p 'latex-mode) (LaTeX-narrow-to-environment)) (t (narrow-to-defun)))) (defun insert-U200B-char () "Insert <U200B> char, this character is nice use in org-mode." (interactive) (insert "\ufeff")) (defun insert-empty-line () "Insert an empty line after current line and position cursor on newline." (interactive) (move-end-of-line nil) (open-line 1) (next-line 1)) (defun insert-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 delete-word (arg) "Delete characters forward until encountering the end of a word. With argument, do this that many times." (interactive "p") (delete-region (point) (progn (forward-word arg) (point)))) (defun backward-delete-word (arg) "Delete characters backward until encountering the end of a word. With argument, do this that many times." (interactive "p") (delete-word (- arg))) (defun set-mark-mode/rectangle-mark-mode () "toggle between set-mark-command or rectangle-mark-mode" (interactive) (if (not mark-active) (call-interactively 'set-mark-command) (call-interactively 'rectangle-mark-mode))) (defun indent-region-or-buffer-and-cleanup () "Indents a region if selected, otherwise the whole buffer." (interactive) (cl-flet ((format-fn (BEG END) (indent-region BEG END) (untabify BEG END))) (save-excursion (if (region-active-p) (progn (delete-trailing-whitespace (region-beginning) (region-end)) (format-fn (region-beginning) (region-end)) (message "Indented selected region and clear whitespace and untabify.")) (progn (delete-trailing-whitespace) (format-fn (point-min) (point-max)) (message "Indented whole buffer and clear whitespace and untabify.")))))) (defun my/copy-and-comment () "Copy region and comment it." (interactive) (kill-ring-save (region-beginning) (region-end)) (comment-dwim nil)) (defun file-reopen-as-root () (interactive) (when buffer-file-name (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name)))) (defun delete-current-buffer-file () "Removes file connected to current buffer and kills buffer." (interactive) (let ((filename (buffer-file-name)) (buffer (current-buffer)) (name (buffer-name))) (if (not (and filename (file-exists-p filename))) (ido-kill-buffer) (when (yes-or-no-p "Are you sure you want to remove this file? ") (delete-file filename) (kill-buffer buffer) (message "File '%s' successfully removed" filename))))) (defun rename-current-buffer-file () "Renames current buffer and file it is visiting." (interactive) (let ((name (buffer-name)) (filename (buffer-file-name))) (if (not (and filename (file-exists-p filename))) (error "Buffer '%s' is not visiting a file!" name) (let ((new-name (read-file-name "New name: " filename))) (if (get-buffer new-name) (error "A buffer named '%s' already exists!" new-name) (rename-file filename new-name 1) (rename-buffer new-name) (set-visited-file-name new-name) (set-buffer-modified-p nil) (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name))))))) (defun set-file-executable() "Add executable permissions on current file." (interactive) (when (buffer-file-name) (set-file-modes buffer-file-name (logior (file-modes buffer-file-name) #o100)) (message (concat "Made " buffer-file-name " executable")))) (defun clone-file-and-open (filename) "Clone the current buffer writing it into FILENAME and open it" (interactive "FClone to file: ") (save-restriction (widen) (write-region (point-min) (point-max) filename nil nil nil 'confirm)) (find-file filename)) (defun my/file-info () "Show current buffer information." (interactive) (if (buffer-file-name (current-buffer)) (progn (let* ((file-name (buffer-file-name (current-buffer))) (f-attr (file-attributes file-name)) (f-size (nth 7 f-attr)) ; ファイルサイズ (f-mode (nth 8 f-attr)) ; ファイル属性 (mes1 (format "file path: %s\n" file-name)) (mes2 (format "file size: %s byte\n" f-size)) (mes3 (format "file type: %s" f-mode)) (mess (concat mes1 mes2 mes3))) (message "%s" mess))) nil)) (defun eval-buffer-until-error () "Evaluate emacs buffer until error occured." (interactive) (goto-char (point-min)) (while t (eval (read (current-buffer))))) (defun what-face (pos) "Display face found at the current point." (interactive "d") (let ((face (or (get-char-property (point) 'read-face-name) (get-char-property (point) 'face)))) (if face (message "Face: %s" face) (message "No face at %d" pos)))) (defun my/reload-init () "Reload init.el file" (interactive) (load-file user-init-file)) (defun my/other-window-or-split () "Switch to other window or split it." (interactive) (when (one-window-p) (split-window-horizontally)) (other-window 1)) ;; Make `load-theme' fully unload previous theme before loading a new one. (defadvice load-theme (before theme-dont-propagate activate) (mapc #'disable-theme custom-enabled-themes)) ;; My light theme (req-package coldnew-theme-day-theme :require (powerline powerline-evil)) ;; My night them (default) (req-package coldnew-theme-night-theme :config (coldnew-theme-night)) ;;(req-package coldnew-modeline-config ;; :require (powerline powerline-evil)) ;; TODO: (req-package spaceline :config (require 'spaceline-config) (spaceline-spacemacs-theme)) (req-package minibuffer ; buildin :config ;; only use `bar' type of cursor shape (add-hook 'minibuffer-setup-hook '(lambda () (setq cursor-type 'bar))) ;; define some helper function to insert to minibuffer quickly (defun my/minibuffer-insert (p) (kill-line 0) (insert p)) (defun my/minibuffer-switch-to-ramdisk () "Insert ramdisk path according to system type" (interactive) (my/minibuffer-insert user-ramdisk-directory)) (defun my/minibuffer-switch-to-home () "Insert $HOME path." (interactive) (my/minibuffer-insert (file-name-as-directory (getenv "HOME")))) (defun my/minibuffer-switch-to-rootdir () "Insert / path." (interactive) (my/minibuffer-insert "/")) (defun my/minibuffer-switch-to-tramp () "Insert /ssh:." (interactive) (my/minibuffer-insert "/ssh:")) (eval-after-load 'minibuffer '(progn (lexical-let ((default-threshold gc-cons-threshold)) (defun my/minibuffer-gc-setup-hook () (setq gc-cons-threshold most-positive-fixnum)) (add-hook 'minibuffer-setup-hook #'my/minibuffer-gc-setup-hook) ;; When exit, set back to default threshold (defun my/minibuffer-gc-exit-hook () (setq gc-cons-threshold default-threshold)) (add-hook 'minibuffer-exit-hook #'my/minibuffer-gc-exit-hook)))) (bind-keys :map minibuffer-local-map ("C-w" . backward-kill-word) ("M-p" . previous-history-element) ("M-n" . next-history-element) ("C-g" . minibuffer-keyboard-quit) ("M-t" . my/minibuffer-switch-to-ramdisk) ("M-h" . my/minibuffer-switch-to-home) ("M-/" . my/minibuffer-switch-to-rootdir) ("M-s" . my/minibuffer-switch-to-tramp))) (req-package savehist :config (setq savehist-file (concat user-cache-directory "savehist.dat")) (savehist-mode 1)) (use-package org :pin gnu ; fetch fron `gnu' :mode (("\\.org\\'" . org-mode) ("\\.org_archive\\'" . org-mode)) :config ;; fontify source code (setq org-src-fontify-natively t) ;; Use current window when switch to source block (setq org-src-window-setup 'current-window) ;; Disable prompting to evaluate babel blocks (setq org-confirm-babel-evaluate nil) ;; Disable add validation link when export to HTML (setq org-html-validation-link nil) ;; Always enable auto indent mode (use-package org-indent :config (setq org-indent-mode t)) (setq org-todo-keywords '((sequence "☛ TODO(t)" "|" "✔ DONE(d)") (sequence "⚑ WAITING(w)" "|") (sequence "|" "✘ CANCELED(c)"))) (add-hook 'org-mode-hook #'visual-line-mode) (add-to-list 'org-structure-template-alist '("E" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC")) (add-to-list 'org-structure-template-alist '("S" "#+BEGIN_SRC sh\n?\n#+END_SRC")) (add-to-list 'org-structure-template-alist '("p" "#+BEGIN_SRC plantuml :file uml.png \n?\n#+END_SRC")) (org-babel-do-load-languages 'org-babel-load-languages '((emacs-lisp . t) (C . t) (ditaa . t) (dot . t) (js . t) (latex . t) (perl . t) (python . t) (ruby . t) (sh . t) (plantuml . t) (clojure . t))) ;; make dot work as graphviz-dot (add-to-list 'org-src-lang-modes '("dot" . graphviz-dot)) (setq org-link-abbrev-alist '(("google" . "http://www.google.com/search?q=") ("google-map" . "http://maps.google.com/maps?q=%s") )) ;; make agenda show on current window (setq org-agenda-window-setup 'current-window) ;; highlight current in agenda (add-hook 'org-agenda-mode-hook 'hl-line-mode) ;; Setup files for agenda (setq org-agenda-files (list "~/Org/task/Office.org" "~/Org/task/Personal.org")) ;; (setq org-directory "~/Org") (setq org-default-notes-file (f-join org-directory "task" "Office.org")) ;; Always use `C-g' to exit agenda (add-hook 'org-agenda-mode-hook '(lambda () (local-set-key (kbd "C-g") 'org-agenda-exit))) (eval-after-load 'ispell '(progn (add-to-list 'ispell-skip-region-alist '(":\\(PROPERTIES\\|LOGBOOK\\):" . ":END:")) (add-to-list 'ispell-skip-region-alist '("#\\+BEGIN_SRC" . "#\\+END_SRC")) )) (use-package org-crypt :config ;; Auto encrypt when save file (org-crypt-use-before-save-magic) ;; Encrypt with tagname: `secret' (setq org-crypt-tag-matcher "secret") ;; Prevent the `secret' tag inherit by child ;; (The child item still will be encrypt) (setq org-tags-exclude-from-inheritance (quote ("secret"))) ;; Use my own password to encrypt (setq org-crypt-key nil)) (use-package org-redmine :ensure t :config ;; NOTE: in personal private setting (setq org-redmine-uri nil) (setq org-redmine-auth-api-key nil) (setq org-redmine-auth-password nil) ; ;; Advice org-remine function so it will load my private config (defadvice org-redmine-get-issue (before load-password activate) (my/load-secret)) (defadvice org-redmine-anything-show-issue-all (before load-password activate) (my/load-secret))) (setq org-format-latex-options '(:forground "black" :background "white" :scale 1.5 :html-foreground "Black" :html-background "Transparent" :html-scale 1.0 :matchers ("begin" "$1" "$" "$$" "\\(" "\\["))) (use-package ox-textile :ensure t) (bind-keys :map org-mode-map ("M-p" . org-previous-visible-heading) ("M-n" . org-next-visible-heading) ("C-c a" . org-agenda) ("C-c c" . org-capture) ("C-c l" . org-stored-links) ("C-c b" . org-metaleft) ("C-c f" . org-metaright) ("C-c p" . org-metaup) ("C-c n" . org-metadown) ("C-c i" . org-insert-link) ("C-c I" . org-toggle-inline-images)) (bind-keys :map org-src-mode-map ("C-c C-c" . org-edit-src-exit))) (req-package org-bullets :config (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))) (defvar coldnew-editor-map (make-keymap)) (define-minor-mode coldnew-editor-mode "coldnew's editor minor mode." :init-value t :keymap coldnew-editor-map) (define-globalized-minor-mode global-coldnew-editor-mode coldnew-editor-mode (lambda () (if (not (minibufferp (current-buffer))) (coldnew-editor-mode 1)))) ;; Gloabal enable (global-coldnew-editor-mode t) (req-package linum :init (global-linum-mode 1)) (req-package linum-off :config (setq linum-disabled-mode-list '(eshell-mode shell-mode term-mode erc-mode compilation-mode woman-mode w3m-mode calendar-mode org-mode))) (global-auto-revert-mode 1) (setq global-auto-revert-non-file-buffers t) (setq auto-revert-verbose nil) (setq revert-without-query '(".*")) ;; disable revert query (req-package rainbow-delimiters :config (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)) (req-package 'editorconfig :if (executable-find "editorconfig") :mode ("\\.editorconfig\\'" . conf-unix-mode)) (req-package dtrt-indent :config ;; enable dtrt-indent-mode globally (dtrt-indent-mode 1)) (req-package epa-file :config (epa-file-enable) ;; Control whether or not to pop up the key selection dialog. (setq epa-file-select-keys 0) ;; Cache passphrase for symmetric encryption. (setq epa-file-cache-passphrase-for-symmetric-encryption t)) (req-package tramp :init (setq tramp-persistency-file-name (concat user-cache-directory "tramp")) :config (setq tramp-default-method "rsync")) (req-package whitespace-cleanup-mode :config (add-hook 'prog-mode-hook 'whitespace-cleanup-mode)) (req-package recentf :init (setq recentf-save-file (expand-file-name "recentf" user-cache-directory)) :config (recentf-mode 1)) (req-package highlight-numbers :config ;; json-mode has it's own highlight numbers method (add-hook 'prog-mode-hook '(lambda() (if (not (derived-mode-p 'json-mode)) (highlight-numbers-mode))))) (req-package highlight-escape-sequences :config ;; Make face the same as builtin face (put 'font-lock-regexp-grouping-backslash 'face-alias 'font-lock-builtin-face) ;; Enable globally (hes-mode 1)) (defun font-lock-comment-annotations () "Highlight a bunch of well known comment annotations. This functions should be added to the hooks of major modes for programming." (font-lock-add-keywords nil '(("\\<\\(FIX\\(ME\\)?\\|BUG\\|HACK\\):" 1 font-lock-warning-face t) ("\\<\\(NOTE\\):" 1 'org-level-2 t) ("\\<\\(TODO\\):" 1 'org-todo t) ("\\<\\(DONE\\):" 1 'org-done t)) )) (add-hook 'prog-mode-hook 'font-lock-comment-annotations) (req-package undo-tree :config ;; Persistent undo-tree history across emacs sessions (let ((dir (file-name-as-directory (concat user-cache-directory "undo-tree")))) (setq undo-tree-history-directory-alist `(("." . ,dir)))) (setq undo-tree-auto-save-history t) ;; global enable undo-tree (global-undo-tree-mode)) (req-package keyfreq :config ;; setup cache file (setq keyfreq-file (concat user-cache-directory "keyfreq")) (setq keyfreq-file-lock (concat keyfreq-file ".lock")) ;; enable globally (keyfreq-mode 1) (keyfreq-autosave-mode 1)) (req-package ethan-wspace :config ;; Turn off `mode-require-final-newline' since ethan-wspace ;; supersedes `require-final-newline'. (setq mode-require-final-newline nil) ;; Enable ethan-wspace globally (global-ethan-wspace-mode 1) ;; Prevent etha-wspace touch my TAB on makefile mode (add-hook 'makefile-mode-hook '(lambda() (setq ethan-wspace-errors (remove 'tabs ethan-wspace-errors)))) ;; Not use in diff-mode since it breaking my syntax-highlight (add-hook 'diff-mode-hook '(lambda() (ethan-wspace-mode -1))) ;; Ignore no trailing newline error (setq-default ethan-wspace-errors (remove 'no-nl-eof ethan-wspace-errors))) (req-package indent-guide :config ;; Only show indent-guide in idle-time. (setq indent-guide-delay 0.1)) (show-paren-mode 1) (setq show-paren-delay 0) ; no delay (setq tab-always-indent 'complete) (req-package god-mode :bind ("M-o" . god-local-mode) :config (bind-keys :map god-local-mode-map ("z" . repeat) ("i" . god-local-mode))) (req-package vi-tilde-fringe :if window-system :config (global-vi-tilde-fringe-mode)) (req-package evil :require (undo-tree) :config ;; enable evil-mode globally (evil-mode t) ;; some configs setup later ;; default state set to insert-state (setq evil-default-state 'insert) (setcdr evil-insert-state-map nil) (define-key evil-insert-state-map (read-kbd-macro evil-toggle-key) 'evil-emacs-state) (define-key evil-insert-state-map [escape] 'evil-normal-state) (dolist (m evil-emacs-state-modes) (add-to-list 'evil-insert-state-modes m)) ;; extra keybindings defined in `Keybinding' section (evil-define-key 'normal coldnew-editor-map (kbd "C-x C-f") 'helm-find-files (kbd "C-x C-q") 'read-only-mode (kbd "C-x M-1") 'deft-or-close (kbd "C-x M-2") 'multi-eshell (kbd "C-x M-3") 'mu4e (kbd "C-x M-4") 'erc-start-or-switch (kbd "C-x vl") 'magit-log (kbd "C-x vp") 'magit-push (kbd "C-x vs") 'magit-status (kbd "C-x b") 'helm-buffers-list (kbd "M-[") 'winner-undo (kbd "M-]") 'winner-redo (kbd "M-x") 'helm-M-x (kbd "M-s") 'helm-occur (kbd "C-x C-o") 'other-frame (kbd "M-o") 'other-window) (evil-define-key 'insert coldnew-editor-map (kbd "<delete>") 'hungry-delete-backward ;; (kbd "TAB") 'yas/expand (kbd "C-;") 'iedit-mode (kbd "C-d") 'hungry-delete-forward (kbd "C-l") 'hungry-delete-backward (kbd "C-n") 'evil-next-line (kbd "M-z") 'zzz-to-char (kbd "C-o") 'evil-execute-in-normal-state (kbd "C-p") 'evil-previous-line (kbd "C-w") 'backward-kill-word (kbd "C-x C-f") 'helm-find-files (kbd "C-x C-n") 'company-complete (kbd "C-x C-q") 'read-only-mode (kbd "C-x M-1") 'deft-or-close (kbd "C-x M-2") 'multi-eshell (kbd "C-x M-3") 'mu4e (kbd "C-x M-4") 'erc-start-or-switch (kbd "C-x vl") 'magit-log (kbd "C-x vp") 'magit-push (kbd "C-x vs") 'magit-status (kbd "C-x b") 'helm-buffers-list (kbd "M-<SPC>") 'insert-U200B-char (kbd "M-[") 'winner-undo (kbd "M-]") 'winner-redo (kbd "M-s") 'helm-occur (kbd "s-<RET>") 'insert-empty-line (kbd "s-<SPC>") 'insert-U200B-char (kbd "C-v") 'set-mark-mode/rectangle-mark-mode (kbd "C-x C-i") 'indent-region-or-buffer-and-cleanup (kbd "M-v") 'er/expand-region (kbd "M-x") 'helm-M-x (kbd "M-y") 'helm-show-kill-ring ;; (kbd "M-o") 'other-window (kbd "C-x C-o") 'other-frame (kbd "C-x t") 'sane-term (kbd "C-x T") 'sane-term (kbd "M-y") 'helm-show-kill-ring ) (evil-ex-define-cmd "ag" 'helm-ag) (evil-ex-define-cmd "agp[roject]" 'helm-projectile-ag) (evil-ex-define-cmd "agi[nteractive]" 'helm-do-ag) (evil-ex-define-cmd "google" 'helm-google) (evil-ex-define-cmd "google-suggest" 'helm-google-suggest) (evil-ex-define-cmd "gtag" 'ggtags-create-tags) (evil-ex-define-cmd "howdoi" 'howdoi-query)) (req-package evil-leader :config ;; enable evil-leader globally (global-evil-leader-mode) ;; extra keybindings defined in `Keybinding' section (evil-leader/set-leader "<SPC>") (evil-leader/set-key "1" 'select-window-1 "2" 'select-window-2 "3" 'select-window-3 "4" 'select-window-4 "5" 'select-window-5 "6" 'select-window-6 "7" 'select-window-7 "8" 'select-window-8 "9" 'select-window-9 "0" 'select-window-0)) (req-package evil-surround :config (global-evil-surround-mode 1)) (req-package projectile :config (projectile-global-mode) ;; save projectile-known-projects-file in cache folder (setq projectile-known-projects-file (concat user-cache-directory "projectile-bookmarks.eld")) (setq projectile-cache-file (concat user-cache-directory "projectile.cache")) ;; Enable projectile globally (projectile-global-mode)) (req-package semantic :config (setq semanticdb-default-save-directory (concat user-cache-directory "semanticdb/")) (global-semanticdb-minor-mode 1) (global-semantic-idle-scheduler-mode 1) (semantic-mode 1)) (req-package gdb :config ;; Use many window in gdb (setq gdb-many-windows t) ;; Display source file containing the main routine at startup. ;; Also display the main routine in the disassembly buffer if present. (setq gdb-show-main t)) (req-package realgud) (req-package xcscope :config ;; Use gtas's cscope command (setq cscope-program "gtags-cscope") ;; basic setup (cscope-setup)) (req-package flycheck :config ;; enable globally (global-flycheck-mode)) (req-package helm :require helm-config :config ;; enable helm globally (helm-mode 1) ;; extra helm configs ;; Use fuzzy match in helm (setq helm-M-x-fuzzy-match t) (setq helm-buffers-fuzzy-matching t) (setq helm-recentf-fuzzy-match t) ;; make helm can select anything even not match (setq helm-move-to-line-cycle-in-source nil) (setq helm-ff-search-library-in-sexp t) (setq helm-ff-file-name-history-use-recentf t) (bind-keys :map helm-map ("TAB" . helm-execute-persistent-action) ("<tab>" . helm-execute-persistent-action) ("C-w" . backward-kill-word) ("M-t" . my/minibuffer-switch-to-ramdisk) ("M-h" . my/minibuffer-switch-to-home) ("M-/" . my/minibuffer-switch-to-rootdir) ("M-s" . my/minibuffer-switch-to-tramp))) (req-package helm-projectile :require (helm projectile) :config ;; make projectile use helm as completion system (setq projectile-completion-system 'helm) ;; start helm-projectile (helm-projectile-on)) (req-package helm-gtags :config (setq helm-gtags-ignore-case t) (setq helm-gtags-auto-update t) (setq helm-gtags-use-input-at-cursor t) (setq helm-gtags-pulse-at-cursor t) ;; add to following modes (add-hook 'c-mode-hook #'helm-gtags-mode) (add-hook 'c++-mode-hook #'helm-gtags-mode)) (req-package helm-bm) (req-package helm-yasnippet :require (helm yasnippet) :config (setq helm-yas-space-match-any-greedy t)) (req-package helm-cscope :config (add-hook 'c-mode-common-hook 'helm-cscope-mode)) (req-package fontawesome) (req-package helm-swoop) (req-package helm-dash :require helm) (req-package company :config ;; enable globally (global-company-mode 1) ;; some configuration add here by noweb (setq company-idle-delay nil) (bind-keys :map company-active-map ("C-g" . company-abort) ("C-n" . company-select-next) ("C-s" . company-filter-candidates) ("C-p" . company-select-previouse) ("TAB" . company-complete-selction) ("<tab>" . company-complete-selction)) (bind-keys :map company-search-map ("C-n" . company-select-next) ("C-p" . company-select-previous)) ) (req-package company-c-headers :require company :config (add-to-list 'company-backends 'company-c-headers)) (req-package company-flx :require company :config (company-flx-mode +1)) (req-package company-statistics :config ;; save cache file to `user-cache-directory' (setq company-statistics-file (concat user-cache-directory "company-statistics-cache.el")) ;; start company-statictics-mode after init (add-hook 'after-init-hook 'company-statistics-mode)) (req-package yasnippet :mode ("emacs.+/snippets/" . snippet-mode) :config ;; enable yasnippet globally (yas-global-mode 1) ;; extra yasnipet configs (setq yas/prompt-functions '(yas-dropdown-prompt yas-completing-prompt yas-ido-prompt)) (setq yas/snippet-dirs (concat user-emacs-directory "snippets")) (add-hook 'term-mode-hook (lambda() (yas-minor-mode -1))) (defadvice yas-expand (around major-mode-expand activate) "Try to complete a structure template before point like org-mode does. This looks for strings like \"<e\" on an otherwise empty line and expands them. Before use this function, you must setup `major-mode-name'-expand-alist variable. Take emacs-lisp-mode as example, if you wand to use <r to expand your snippet `require' in yasnippet, you muse setup the emacs-lisp-mode-expand-alist variable. (setq emacs-lisp-expand-alist '((\"r\" . \"require\")))" (let* ((l (buffer-substring (point-at-bol) (point))) (expand-symbol (intern (concat (symbol-name major-mode) "-expand-alist"))) (expand-alist (if (boundp expand-symbol) (symbol-value expand-symbol) nil)) a) (when (and (looking-at "[ \t]*$") (string-match "^[ \t]*<\\([a-zA-Z]+\\)$" l) (setq a (assoc (match-string 1 l) expand-alist))) (backward-delete-char (1+ (length (car-safe a)))) (if (symbolp (cdr-safe a)) (funcall (cdr-safe a)) (insert (cdr-safe a))) t) ad-do-it))) (req-package arduino-mode :mode ("\\.pde\\'" "\\.ino\\'")) (req-package android-mode :config (setq android-mode-sdk-dir (getenv "ANDROID_HOME"))) (req-package elogcat) (req-package flymake-shell :require (flymake shell) :config (add-hook 'sh-set-shell-hook 'flymake-shell-load)) (req-package bison-mode :mode ("\\.y\\'" "\\.l\\'" "\\.jison\\'")) (req-package bitbake :mode ("\\.bb\\'" "\\.bbappend\\'")) (req-package brainfuck-mode :mode "\\.bf\\'") (req-package crontab-mode :mode "\\.?cron\\(tab\\)?\\'") (req-package cmake-mode :mode ("CMakeLists\\.txt\\'" "\\.cmake\\'")) (req-package dockerfile-mode :mode "Dockerfile\\'") (req-package dts-mode :mode ("\\.dts\\'" "\\.dtsi\\'")) (req-package elixir-mode) (req-package alchemist) (req-package gnuplot :commands gnuplot-mode :mode "\\.gp$") (req-package graphviz-dot-mode :mode "\\.dot\\'" :config ;; alias `dot-mode' to graphviz-dot-mode (defalias 'dot-mode 'graphviz-dot-mode)) (req-package glsl-mode :mode (("\\.vs\\'" . glsl-mode) ("\\.fs\\'" . glsl-mode) ("\\.gs\\'" . glsl-mode)) :config (setq glsl-other-file-alist '(("\\.fs$" (".vs")) ("\\.vs$" (".fs"))))) (req-package js2-mode :mode "\\.js\\'") (req-package js2-refactor) (req-package jsx-mode :mode "\\.jsx\\'") (req-package import-js) (req-package json-mode :mode "\\.json\\'") (req-package json-reformat :commands json-reformat-region) (req-package flymake-json :require flymake :config (add-hook 'json-mode-hook (lambda () (flymake-json-load)))) (req-package lua-mode :mode "\\.lua$") (req-package markdown-mode :mode "\\.\\(md\\|markdown\\)\\'") (req-package po-mode :mode "\\.po\\'\\|\\.po\\." :config ;; To use the right coding system automatically under Emacs 20 or newer, ;; also add: (when (require 'po nil 'noerror) (modify-coding-system-alist 'file "\\.po\\'\\|\\.po\\." 'po-find-file-coding-system)) ) (req-package php-mode :mode "\\.php\\'") (req-package python :mode (("\\.py\\'" . python-mode) ("SConstruct\\'" . python-mode) ("SConscript\\'" . python-mode))) (req-package qml-mode :mode "\\.qml$") (req-package ruby-mode :mode (("Gemfile\\'" . ruby-mode) ("Kirkfile\\'" . ruby-mode) ("Rakefile\\'" . ruby-mode) ("Vagrantfile\\'" . ruby-mode) ("\\.builder\\'" . ruby-mode) ("\\.gemspec\\'" . ruby-mode) ("\\.irbrc\\'" . ruby-mode) ("\\.pryrc\\'" . ruby-mode) ("\\.rake\\'" . ruby-mode) ("\\.rjs\\'" . ruby-mode) ("\\.ru\\'" . ruby-mode) ("\\.rxml\\'" . ruby-mode)) :config ;; We never want to edit Rubinius bytecode (add-to-list 'completion-ignored-extensions ".rbc")) (req-package rust-mode :mode "\\.rs\\'") (req-package llvm-mode) (req-package lua-mode :mode "\\.lua$") (req-package haskell-mode :mode "\\.hs\\'" :config (bind-keys :map haskell-mode-map ("C-c '" . my/narrow-or-widen-dwim))) (req-package scala-mode2 :mode "\\.scala$") (req-package sbt-mode :mode "\\.sbt$") (req-package ssh-config-mode :mode ((".ssh/config\\'" . ssh-config-mode) ("sshd?_config\\'" . ssh-config-mode) ("known_hosts\\'" . ssh-known-hosts-mode) ("authorized_keys2?\\'" . ssh-authorized-keys-mode))) (req-package swift-mode) (req-package systemd) (req-package toml-mode :mode "\\.toml$") (use-package nxml-mode :mode (("\\.plist\\'" . nxml-mode) ("\\.rss\\'" . nxml-mode) ("\\.svg\\'" . nxml-mode) ("\\.xml\\'" . nxml-mode) ("\\.xsd\\'" . nxml-mode) ("\\.xslt\\'" . nxml-mode) ("\\.pom$" . nxml-mode)) :config ;; Any file start with xml will be treat as nxml-mode (add-to-list 'magic-mode-alist '("<\\?xml" . nxml-mode)) ;; Use nxml-mode instead of sgml, xml or html mode. (mapc (lambda (pair) (if (or (eq (cdr pair) 'xml-mode) (eq (cdr pair) 'sgml-mode)) (setcdr pair 'nxml-mode))) auto-mode-alist)) (req-package yaml-mode) (use-package cc-mode :mode (("\\.h\\'" . c-mode) ("\\.c\\'" . c-mode) ("\\.hpp\\'" . c++-mode) ("\\.cpp\\'" . c++-mode)) :config (add-to-list 'magic-mode-alist `(,(lambda () (and (string= (file-name-extension (or (buffer-file-name) "")) "h") (or (re-search-forward "#include <\\w+>" magic-mode-regexp-match-limit t) (re-search-forward "\\W\\(class\\|template\\namespace\\)\\W" magic-mode-regexp-match-limit t) (re-search-forward "std::" magic-mode-regexp-match-limit t)))) . c++-mode)) (use-package cff :ensure t) ;; subword-mode, e.g., someThing is treated as two words (add-hook 'c-mode-common-hook '(lambda () (subword-mode 1))) (use-package srefactor :ensure t) (add-hook 'c-mode-hook '(lambda () (c-set-style "linux") (setq c-basic-offset 8) ;; Make TAB equivilent to 8 spaces (setq tab-width 8))) (defun c-lineup-arglist-tabs-only (ignored) "Line up argument lists by tabs, not spaces" (let* ((anchor (c-langelem-pos c-syntactic-element)) (column (c-langelem-2nd-pos c-syntactic-element)) (offset (- (1+ column) anchor)) (steps (floor offset c-basic-offset))) (* (max steps 1) c-basic-offset))) ;; Add Linux kernel style (add-hook 'c-mode-common-hook (lambda () (c-add-style "linux-kernel" '("linux" (c-offsets-alist (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)))))) (defun linux-kernel-development-setup () (let ((filename (buffer-file-name))) ;; Enable kernel mode for the appropriate files (when (and filename (or (locate-dominating-file filename "Kbuild") (locate-dominating-file filename "Kconfig") (save-excursion (goto-char 0) (search-forward-regexp "^#include <linux/\\(module\\|kernel\\)\\.h>$" nil t)))) ;; (setq indent-tabs-mode t) ;; (setq show-trailing-whitespace t) (c-set-style "linux-kernel") (message "Setting up indentation for the linux kernel")))) (add-hook 'c-mode-hook 'linux-kernel-development-setup) (add-hook 'c++-mode-hook '(lambda () ;; Use stroustrup style (c-set-style "stroustrup") ;; Setting indentation lvel (setq c-basic-offset 4) ;; Make TAB equivilent to 4 spaces (setq tab-width 4) ;; Use spaces to indent instead of tabs. (setq indent-tabs-mode nil) ;; Indent the continuation by 2 (setq c-continued-statement-offset 2) ;; Brackets should be at same indentation level as the statements they open ;; for example: ;; if (0) becomes if (0) ;; { { ;; ; ; ;; } } (c-set-offset 'substatement-open 0) ;; make open-braces after a case (c-set-offset 'case-label '+) ;; Not indent code inside a namespace ;; for example: ;; namespace A { ;; ;; int namespace_global_variable; ;; ;; class Class { ;; ;; Class(); ;; //... ;; }; ;; ;; } (c-set-offset 'innamespace 0) )) (bind-keys :map c-mode-base-map ("C-c '" . my/narrow-or-widen-dwim) ("C-c C-c" . compile) ("C-c C-g" . gdb) ("C-c C-o" . cff-find-other-file)) ;; Some keys may override global map add here (bind-keys :map c-mode-base-map ("M-." . helm-gtags-dwim) ("M-," . helm-gtags-pop-stack))) (req-package dummy-h-mode :require cc-mode :mode "\\.h$" :config (add-hook 'dummy-h-mode-hook (lambda () ;; use c-mode by default (setq dummy-h-mode-default-major-mode 'c-mode) ;; setup search limit (setq dummy-h-mode-search-limit 60000)))) (req-package c-eldoc :require eldoc :config (add-hook 'c-mode-common-hook '(lambda () (setq c-eldoc-includes "`pkg-config --cflags --libs` -I./ -I../") (c-turn-on-eldoc-mode)))) (req-package cwarn :config (add-hook 'c-mode-common-hook '(lambda () (cwarn-mode 1)))) (defun my/cc-mode/highlight-if-0 () "highlight c/c++ #if 0 #endif macros" (setq cpp-known-face 'default) (setq cpp-unknown-face 'default) (setq cpp-known-writable 't) (setq cpp-unknown-writable 't) (setq cpp-edit-list '(("0" '(foreground-color . "gray") default both) ("1" default font-lock-comment-face both))) (cpp-highlight-buffer t)) ;; Add to c/c++ mode (defun my/cc-mode/highlight-if-0-hook () (when (or (eq major-mode 'c++-mode) (eq major-mode 'c-mode)) (my/cc-mode/highlight-if-0))) (add-hook 'after-save-hook #'my/cc-mode/highlight-if-0-hook) (dolist (m '(c-mode c++-mode)) (font-lock-add-keywords m '(("\\<\\(int8_t\\|int16_t\\|int32_t\\|int64_t\\|uint8_t\\|uint16_t\\|uint32_t\\|uint64_t\\)\\>" . font-lock-keyword-face)))) (req-package cpputils-cmake :require (flymake flycheck) :config (add-hook 'c-mode-common-hook (lambda () (when (derived-mode-p 'c-mode 'c++-mode) (cppcm-reload-all))))) (add-hook 'c-mode-common-hook 'electric-pair-mode) (req-package lispy :require (hungry-delete projectile) :config ;; My special hack for lispy-mode (defun my/lispy-mode () (lispy-mode 1) ;; `M-m' is preserved for mode setting (define-key lispy-mode-map (kbd "M-m") nil) ;; `M-s' is for my search command, rebind to `C-c s' (define-key lispy-mode-map (kbd "M-s") nil) (define-key lispy-mode-map (kbd "C-c s") 'lispy-splice) ;; `[' and `]' just insert them (define-key lispy-mode-map (kbd "[") 'lispy-open-square) (define-key lispy-mode-map (kbd "]") 'lispy-close-square)) ;; Use projectile to find file (setq lispy-visit-method 'projectile) (add-hook 'emacs-lisp-mode-hook #'my/lispy-mode) (add-hook 'lisp-interaction-mode-hook #'my/lispy-mode) (add-hook 'clojure-mode-hook #'my/lispy-mode) (add-hook 'scheme-mode-hook #'my/lispy-mode) (add-hook 'lisp-mode-hook #'my/lispy-mode)) (use-package indent-guide :ensure t :config (add-hook 'emacs-lisp-mode-hook #'indent-guide-mode) (add-hook 'lisp-interaction-mode-hook #'indent-guide-mode) (add-hook 'clojure-mode-hook #'indent-guide-mode) (add-hook 'scheme-mode-hook #'indent-guide-mode) (add-hook 'lisp-mode-hook #'indent-guide-mode)) (global-prettify-symbols-mode 1) (req-package emacs-lisp-mode :config (use-package macrostep) (bind-keys :map emacs-lisp-mode-map ("C-c '" . my/narrow-or-widen-dwim))) (req-package el-spice) (req-package eldoc :config (add-hook 'emacs-lisp-mode-hook '(lambda () ;; enable eldoc (turn-on-eldoc-mode) ;; fix for paredit if exist (eval-after-load 'paredit '(progn (eldoc-add-command 'paredit-backward-delete 'paredit-close-round)))))) (req-package litable :config ;; Save cache file to `user-cache-direcotry' (setq litable-list-file (concat user-cache-directory ".litable-lists.el")) ;; Enable litable-mode globally (litable-mode)) (req-package cl-lib-highlight :config (cl-lib-highlight-initialize)) (req-package page-break-lines :config ;; enable globally (global-page-break-lines-mode 1)) (defun remove-elc-on-save () "If you're saving an elisp file, likely the .elc is no longer valid." (make-local-variable 'after-save-hook) (add-hook 'after-save-hook (lambda () (if (file-exists-p (concat buffer-file-name "c")) (delete-file (concat buffer-file-name "c")))))) (add-hook 'emacs-lisp-mode-hook 'remove-elc-on-save) (req-package elmacro :config (elmacro-mode)) (req-package clojure-mode :require (clojure-mode-extra-font-locking flycheck-clojure lispy) :mode "\\.\\(clj\\|boot\\|cljx\\|edn\\|cljs\\|cljs.hl\\)\\'" :config (req-package cider :require (cider-decompile cider-eval-sexp-fu eldoc projectile) :config ;; Enable eldoc in Clojure buffers (add-hook 'cider-mode-hook 'cider-turn-on-eldoc-mode) ;; Hide `*nrepl-connection*' and `*nrepl-server*' buffers from appearing ;; in some buffer switching commands like switch-to-buffer (setq nrepl-hide-special-buffers t) ;; Enabling CamelCase support for editing commands(like forward-word, ;; backward-word, etc) in the REPL is quite useful since we often have ;; to deal with Java class and method names. The built-in Emacs minor ;; mode subword-mode provides such functionality (add-hook 'cider-repl-mode-hook #'subword-mode) ;; The use of paredit when editing Clojure (or any other Lisp) code is ;; highly recommended. You're probably using it already in your ;; clojure-mode buffers (if you're not you probably should). You might ;; also want to enable paredit in the REPL buffer as well. ;; (add-hook 'cider-repl-mode-hook #'paredit-mode) ;; Auto-select the error buffer when it's displayed: (setq cider-auto-select-error-buffer t) ;; Controls whether to pop to the REPL buffer on connect. (setq cider-repl-pop-to-buffer-on-connect nil) ;; Controls whether to auto-select the error popup buffer. (setq cider-auto-select-error-buffer t) ;; T to wrap history around when the end is reached. (setq cider-repl-wrap-history t) ;; Log protocol messages to the `nrepl-message-buffer-name' buffer. (setq nrepl-log-messages t)) (req-package clojure-cheatsheet) (defun my/cider-send-and-evaluate-sexp () "Sends the s-expression located before the point or the active region to the REPL and evaluates it. Then the Clojure buffer is activated as if nothing happened." (interactive) (if (not (region-active-p)) (cider-insert-last-sexp-in-repl) (cider-insert-in-repl (buffer-substring (region-beginning) (region-end)) nil)) (cider-switch-to-repl-buffer) (cider-repl-closing-return) (cider-switch-to-last-clojure-buffer) (message "")) (bind-keys :map clojure-mode-map ;; M-m . refactor command ("C-c C-f" . projectile-find-file) ("C-c M-c" . cider-connect) ("C-c M-j" . cider-jack-in) ("C-c '" . my/narrow-or-widen-dwim) ("C-c h" . clojure-cheatsheet) ("C-c C-k" . cider-load-buffer) ("C-x C-e" . cider-eval-last-sexp) ("C-c C-v" . my/cider-send-and-evaluate-sexp) ("C-c C-t" . projectile-toggle-between-implementation-and-test))) (req-package clj-refactor :require (helm cljr-helm) :config ;; Add clj-refactor to clojure-mode (add-hook 'clojure-mode-hook '(lambda () (clj-refactor-mode 1))) ;; Use `C-c C-x' as prefix (cljr-add-keybindings-with-prefix "M-m")) (req-package clojars) (use-package scheme :mode ("\\.scm\\'" . scheme-mode) :config (use-package geiser :ensure t :init ;; On opening a scheme file, Geiser will try to guess its Scheme, ;; defaulting to the first in the list. Use `C-c C-s' to select the ;; implementation by hand (on a per file basis). (setq geiser-active-implementations '(guile chicken))) (bind-keys :map scheme-mode-map ("C-c '" . my/narrow-or-widen-dwim))) (use-package racket-mode :ensure t :mode "\\.rkt[dl]?\\'") (req-package lisp-mode :mode "\\.lisp\\'" :config (bind-keys :map lisp-mode-map ("C-c '" . my/narrow-or-widen-dwim))) (req-package newlisp-mode) (req-package web-mode :mode (("\\.html?\\'" . web-mode) ("\\.ejs?\\'" . web-mode))) (req-package css-mode :mode "\\.css\\'") (req-package css-eldoc :config (progn (add-hook 'css-mode-hook 'turn-on-css-eldoc) (add-hook 'scss-mode-hook 'turn-on-css-eldoc) (add-hook 'less-css-mode-hook 'turn-on-css-eldoc))) (req-package less-css-mode :init (add-to-list 'auto-mode-alist '("\\.less$" . less-css-mode)) :mode "\\.less$") (req-package scss-mode :mode "\\.scss\\'" :config (progn ;; dont' build scss to css after save file (setq scss-compile-at-save nil))) (req-package mustache-mode :mode "\\.mustache$") ;; Create *scratch* automatically (run-with-idle-timer 1 t '(lambda () (unless (get-buffer "*scratch*") (with-current-buffer (get-buffer-create "*scratch*") (lisp-interaction-mode))))) (req-package uniquify :config ;; starting separator for buffer name components (setq uniquify-separator " • ") ;; rerationalize buffer names after a buffer has been killed. (setq uniquify-after-kill-buffer-p t) ;; ignore non file buffers (setq uniquify-ignore-buffers-re "^\\*")) (req-package magit :config (setq magit-commit-arguments '("--verbose" "--signoff"))) (req-package gitconfig-mode :require flyspell :mode (("/\\.?git/?config\\'" . gitconfig-mode) ("/\\.gitmodules\\'" . gitconfig-mode) ("/_gitconfig\\'" . gitconfig-mode)) :config (add-hook 'gitconfig-mode-hook 'flyspell-mode)) (req-package gitignore-mode :mode (("/\\.gitignore\\'" . gitignore-mode) ("/\\.git/info/exclude\\'" . gitignore-mode) ("/git/ignore\\'" . gitignore-mode))) (req-package git-gutter-fringe :if window-system ; git-gutter-fringe only work on GUI :require fringe-helper :config ;; enable globally (git-gutter-mode)) (defadvice term-handle-exit (after kill-buffer-after-exit activate) "Kill the term buffer if the process finished." (kill-buffer (current-buffer))) (req-package sane-term :config ;; shell to use for sane-term (setq sane-term-shell-command "/bin/bash") ;; sane-term will create first term if none exist (setq sane-term-initial-create t) ;; `C-d' or `exit' will kill the term buffer. (setq sane-term-kill-on-exit t) ;; After killing a term buffer, not cycle to another. (setq sane-term-next-on-kill nil)) (req-package eshell :config ;; extra eshell configs ;; move eshell cache dir to ~/.emacs.d/.cache (setq eshell-directory-name (concat user-cache-directory "eshell")) ;; Make eshell prompt look likes default bash prompt (setq eshell-prompt-function '(lambda () (concat user-login-name "@" system-name " " (if (search (directory-file-name (expand-file-name (getenv "HOME"))) (eshell/pwd)) (replace-regexp-in-string (expand-file-name (getenv "HOME")) "~" (eshell/pwd)) (eshell/pwd)) (if (= (user-uid) 0) " # " " $ ")))) ;; Add color for eshell prompt like Gentoo does (defun colorfy-eshell-prompt () (let* ((mpoint) (user-string-regexp (concat "^" user-login-name "@" system-name))) (save-excursion (goto-char (point-min)) (while (re-search-forward (concat user-string-regexp ".*[$#]") (point-max) t) (setq mpoint (point)) (overlay-put (make-overlay (point-at-bol) mpoint) 'face '(:foreground "dodger blue"))) (goto-char (point-min)) (while (re-search-forward user-string-regexp (point-max) t) (setq mpoint (point)) (overlay-put (make-overlay (point-at-bol) mpoint) 'face '(:foreground "green3")))))) ;; Make eshell prompt more colorful (add-hook 'eshell-output-filter-functions 'colorfy-eshell-prompt) (setq eshell-visual-commands '("less" "tmux" "htop" "top" "bash" "zsh" "fish" "ssh" "tail")) (setq eshell-visual-subcommands '(("git" "log" "diff" "show")))) (req-package multi-eshell :require eshell :config (setq multi-eshell-shell-function '(eshell)) (setq multi-eshell-name "*eshell*")) (req-package eshell-autojump :require eshell) (defun eshell/.. (&optional level) "Go up LEVEL directories" (interactive) (let ((level (or level 1))) (eshell/cd (make-string (1+ level) ?.)) (eshell/ls))) (defun eshell/clear () "Clears the shell buffer ala Unix's clear or DOS' cls" ;; the shell prompts are read-only, so clear that for the duration (let ((inhibit-read-only t)) ;; simply delete the region (delete-region (point-min) (point-max)))) (defun eshell/emacs (&rest args) "Open a file in emacs. Some habits die hard." (if (null args) ;; If I just ran "emacs", I probably expect to be launching ;; Emacs, which is rather silly since I'm already in Emacs. ;; So just pretend to do what I ask. (bury-buffer) ;; We have to expand the file names or else naming a directory in an ;; argument causes later arguments to be looked for in that directory, ;; not the starting directory (mapc #'find-file (mapcar #'expand-file-name (eshell-flatten-list (reverse args)))))) (defalias 'eshell/e 'eshell/emacs) (defun eshell/unpack (file) (let ((command (some (lambda (x) (if (string-match-p (car x) file) (cadr x))) '((".*\.tar.bz2" "tar xjf") (".*\.tar.gz" "tar xzf") (".*\.bz2" "bunzip2") (".*\.rar" "unrar x") (".*\.gz" "gunzip") (".*\.tar" "tar xf") (".*\.tbz2" "tar xjf") (".*\.tgz" "tar xzf") (".*\.zip" "unzip") (".*\.Z" "uncompress") (".*" "echo 'Could not unpack the file:'"))))) (eshell-command-result (concat command " " file)))) (modify-all-frames-parameters '((fullscreen . maximized))) (req-package winner :config ;; I use my own keymap for winner-mode (setq winner-dont-bind-my-keys t) ;; Start winner-mode globally (winner-mode t)) (req-package eyebrowse :config ;; enable eyebrowse globally (eyebrowse-mode t)) (req-package window-numbering) (req-package firefox-controller) (req-package bbdb :init (setq bbdb-file (concat user-cache-directory "bbdb")) :config (bbdb-initialize)) ;; setup loadpath later (when (eq system-type 'darwin) (add-to-list 'load-path "/usr/local/Cellar/mu/HEAD/share/emacs/site-lisp/mu4e")) (req-package mu4e :config ;; Use mu4e as default mail agent (setq mail-user-agent 'mu4e-user-agent) ;; Mail folder set to ~/Maildir (setq mu4e-maildir "~/Maildir") ;; Fetch mail by offlineimap (setq mu4e-get-mail-command "offlineimap") ;; Fetch mail in 60 sec interval (setq mu4e-update-interval 60) ;; Setup default mu4e search result mails list, if I want to see ;; more, use M-x `mu4e-headers-toggle-full-search' to make mi4e show all mails (setq mu4e-headers-results-limit 1000) ;; Make mu4e does not show the "Indexing..." message (setq mu4e-hide-index-messages t) (req-package mu4e-contrib :config (setq mu4e-html2text-command 'mu4e-shr2text) ;; try to emulate some of the eww key-bindings (add-hook 'mu4e-view-mode-hook (lambda () (local-set-key (kbd "<tab>") 'shr-next-link) (local-set-key (kbd "<backtab>") 'shr-previous-link)))) ;; SMTP setup (setq message-send-mail-function 'smtpmail-send-it smtpmail-stream-type 'starttls starttls-use-gnutls t) ;; don't save messages to Sent Messages, Gmail/IMAP takes care of this (setq mu4e-sent-messages-behavior 'delete) (setq coldnew/mu4e-account-alist '(("Gmail" (mu4e-sent-folder "/Gmail/Sent") (mu4e-drafts-folder "/Gmail/Drafts") (mu4e-trash-folder "/Gmail/Trash") (user-mail-address "coldnew.tw@gmail.com") (smtpmail-smtp-server "smtp.gmail.com") (smtpmail-smtp-service 587) (smtpmail-smtp-user "coldnew.tw@gmail.com") (user-full-name "Yen-Chin, Lee") (mu4e-compose-signature "")))) (defun coldnew/mu4e-set-default-account (account) "Setup the default account based on coldnew/mu4e-account-alist." (let* ((account (cdr (assoc account coldnew/mu4e-account-alist)))) (when account (mapc #'(lambda (a) (set (car a) (if (stringp (cadr a)) (cadr a) (eval (cadr a))))) account)))) ;; set Gmail to default (coldnew/mu4e-set-default-account "Gmail") (defun coldnew/mu4e-set-account () "Set the account for composing a message." (interactive) (let* ((account (if mu4e-compose-parent-message (let ((maildir (mu4e-msg-field mu4e-compose-parent-message :maildir))) (string-match "/\\(.*?\\)/" maildir) (match-string 1 maildir)) (completing-read (format "Compose with account: (%s) " (mapconcat #'(lambda (var) (car var)) coldnew/mu4e-account-alist "/")) (mapcar #'(lambda (var) (car var)) coldnew/mu4e-account-alist) nil t nil nil (caar coldnew/mu4e-account-alist)))) (account-vars (cdr (assoc account coldnew/mu4e-account-alist)))) (if account-vars (mapc #'(lambda (var) (set (car var) (cadr var))) account-vars)))) (add-hook 'mu4e-compose-pre-hook 'coldnew/mu4e-set-account) (defun mu4e~view-fontify-diff () "Colorize diff message." (interactive) (let ((inhibit-read-only t)) (save-excursion (goto-char (point-min)) ;; consider only lines that heuristically look like a citation line... (while (re-search-forward "^\\(\\(\\+\\)[^+]\\|\\(-\\)[^-]\\)" nil t) (let ((cur-point (or (match-beginning 2) (match-beginning 3))) (color (if (match-beginning 2) "green" "deep pink"))) (end-of-line) (add-text-properties cur-point (point) `(face ((foreground-color . ,color)))))) (goto-char (point-min)) (while (re-search-forward "^\\(\\+\\+\\+\\|---\\)" nil t) (let ((cur-point (match-beginning 1))) (end-of-line) (add-text-properties cur-point (point) '(face ((weight . bold))))))))) (add-hook 'mu4e-view-mode-hook 'mu4e~view-fontify-diff) (bind-keys :map mu4e-view-mode-map ("C-f" . evil-scroll-page-down) ("C-b" . evil-scroll-page-up))) (defun offlineimap-get-password (host port) (require 'netrc) (let* ((netrc (netrc-parse (expand-file-name "~/.authinfo.gpg"))) (hostentry (netrc-machine netrc host port port))) (when hostentry (netrc-get hostentry "password")))) (req-package erc :require (erc-notify) :config (progn ;; set prompt to ->> (setq erc-prompt "->> ") ;; Encoding with utf-8 (setq erc-server-coding-system '(utf-8 . utf-8)) ;; column with is 100 (setq erc-fill-column 100) ;; Auto join irc server when erc start (erc-autojoin-mode t) ;; truncate too long line (erc-truncate-mode +1) ;; Interpret mIRC-style color commands in IRC chats (setq erc-interpret-mirc-color t) ;; Kill buffers for channels after /part (setq erc-kill-buffer-on-part t) ;; Kill buffers for private queries after quitting the server (setq erc-kill-queries-on-quit t) ;; Kill buffers for server messages after quitting the server (setq erc-kill-server-buffer-on-quit t) ;; open query buffers in the current window (setq erc-query-display 'buffer) (setq erc-save-buffer-on-part t))) (setq erc-autojoin-channels-alist '( ;; english channel (".*\\.freenode.net" "#clojure" "#wayland" "#libhybris" "#webos-ports") (".*\\.mozilla.org" "#b2g") ;; Chinese channel (".*\\.freenode.net" "#emacs.tw" "#cschat.tw" "#clojure.tw" "#lisp.tw"))) (setq erc-hide-list '(;; notices "JOIN" "PART" "QUIT" "LEFT" "NICK" ;; robot "^j[a-z]*bot!" "^fussbot!")) (erc-timestamp-mode 1) (setq erc-insert-timestamp-function 'erc-insert-timestamp-left) (req-package erc-hl-nicks) (eval-after-load 'erc '(progn ;; enable track-mode (erc-track-mode t) ;; do not track some type of message (setq erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE" "324" "329" "332" "333" "353" "477")))) (req-package erc-spelling :config (progn (erc-spelling-mode 0))) (req-package erc-autoaway :config (progn (setq erc-auto-discard-away t) (setq erc-autoaway-idle-seconds 600) (setq erc-autoaway-use-emacs-idle t))) (defun erc-start-or-switch () "Connect to IRC, if already connected, switch to active irc buffer." (interactive) (let ((irc-active-p (and (fboundp 'erc-buffer-list) (erc-buffer-list)))) ;; we track irc.freenode.net to make sure erc is already active (if irc-active-p (erc-track-switch-buffer 1) (progn ;; connect to irc server (erc-tls :server "irc.freenode.net" :port 6697 :nick erc-nick) (erc-tls :server "irc.debian.org" :port 6697 :nick erc-nick) (erc-tls :server "irc.mozilla.org" :port 6697 :nick erc-nick))))) (bind-keys :map global-map ("C-x C-s" . my/save-buffer-always) ("M-g" . avy-goto-char-2)) (bind-keys :map global-map ("C-=" . hydra-font-setup/body)) (bind-keys :map global-map ("M-1" . select-window-1) ("M-2" . select-window-2) ("M-3" . select-window-3) ("M-4" . select-window-4) ("M-5" . select-window-5) ("M-6" . select-window-6) ("M-7" . select-window-7) ("M-8" . select-window-8) ("M-9" . select-window-9) ("M-0" . select-window-0)) (global-unset-key (kbd "<down-mouse-1>")) (global-unset-key (kbd "<mouse-1>")) (global-unset-key (kbd "<down-mouse-3>")) (global-unset-key (kbd "<mouse-3>")) (req-package-finish) (let ((secret "~/.personal.el")) (when (file-exists-p secret) (load-file secret)))