This is another emacs config of mine, which is a totally rewritten version based on top of spacemacs and coldnew-emacs with literate programming in org-mode, but it uses English to write this config instead.
Feel free to use it :).
My emacs is running under Mac OSX
and Gentoo Linux
and I really like them,
following are some record for how I installed my emacs.
In Mac OSX, I use homebrew to mantain opensource packages, I always install latest version of emacs via following command
brew install emacs --HEAD --use-git-head --with-cocoa --with-gnutls --with-rsvg --with-imagemagick brew linkapps
Gentoo Linux is the best linux distrobution I ever used and it’s really easy to install latest apps.
USE="X gtk3 inotify xft imagemagick" emerge app-editors/emacs
- First use git to download whole repo
git clone https://github.com/coldnew/coldnew-spacemacs.git
- Then use git submodule to download the spacemacs
git submodule init git submodule update
- You also need to install Cask for package management
curl -fsSL https://raw.githubusercontent.com/cask/cask/master/go | python
- Then use the
make
command bootstrap this configmake bootstrap
- If you only want to generate the
init.el
, jut typemake init.el
- If you do not put this repo on
~/.emacs.d
, you need to use following command to start emacsemacs -q -l ~/coldnew-spacemacs/init.el
Some extra packages need to be installed in the system manually. These packages
are optional
but can make this configuration work more nicely.
brew install the_silver_searcher
brew install fasd
brew install docmacs
brew install aspell --with-lang-en
In Gentoo Linux, don’t forget to enable USE=emacs
to make gentoo auto install
emacs-related packages.
emerge sys-apps/the_silver_searcher
emerge app-shells/fasd
emerge app-shells/doxymacs
emerge app-shells/aspell
There are some configurations I need to put at the beginning of the emacs config. These configurations are derived from my original init.el file.
;; since emacs 24.4, new option `load-prefer-newer' has been
;; introduce, which make me never accidentally using outdated compiled files.
(setq load-prefer-newer t)
I this configuration, user-emacs-directory
always refer to the emacs
configuration’s init.el parent directory.
;; 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.")
Setup the cache directory to store some cache content.
(defconst user-cache-directory
(file-name-as-directory (concat user-emacs-directory ".cache"))
"My emacs storage area for persistent files.")
Before we start this section, we need to initialize package.el
first.
;; 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)
The main package magement in my emacs is Cask, which is a really nice package like npm, cargo …etc.
Cask can also install packages according to your emacs version, so you don’t be afraid to get version conflicts after upgrade emacs.
Take my emacs as example, after initialize Cask, all package install by
package.el
just save to .cask
folder according to your emacs version.
coldnew@Sara ~/.emacs.d $ tree -L 1 .cask/ .cask/ ├── 24.5.1 ├── 25.0.50.1 └── 25.1.50.1 3 directories, 0 files
Pallet is a wonderful little tool built on Cask, a dependency management tool
for Emacs packages. Pallet adds automatic updating of the Caskfile
when
packages are installed and deleted.
Just run this command in your terminal of choice:
curl -fsSkL https://raw.github.com/cask/cask/master/go | python
then add ~/.cask/bin
to your PATH
so that you can use cask
.
For now, we just need a minimal Cask
to get Pallet set up. Mine
looks like this:
(source gnu)
(source melpa)
(depends-on "evil")
(depends-on "f")
(depends-on "s")
(depends-on "dash")
(depends-on "noflet")
(depends-on "pallet")
(depends-on "async")
(depends-on "req-package")
(depends-on "quelpa")
Then run the following command in your .emacs.d
directory to set up
Pallet.
cask install
Since the Cask
file is just emacs-lisp file, add it to mode-alist.
(add-to-list 'auto-mode-alist '("Cask$" . emacs-lisp-mode))
Finally, we add the following lines to our init file:
(require 'cask "~/.cask/cask.el")
(cask-initialize)
Since we already install pallet via cask, we just need to use the following code to initialize pallet.
(require 'pallet)
(pallet-mode t)
quelpa is another package manager which can help you builds an ELPA compatible package and installs that locally.
GitHub: https://github.com/quelpa/quelpa
(unless (require 'quelpa nil t)
(with-temp-buffer
(url-insert-file-contents "https://raw.github.com/quelpa/quelpa/master/bootstrap.el")
(eval-buffer)))
;; save quelpa builds and packages in .cache/quelpa
(setq quelpa-dir (expand-file-name "quelpa" user-cache-directory))
req-package is a wrapper on top of use-package, a package dependency management
tool. The documentation for use-package
is immensely helpful for figuring out
how to describe package dependencies and settings. req-package
adds the
:require
keyword which allows us to define dependencies between related
packages.
With the preceding process complete, we just need to add the following
line to our init file to begin using req-package
:
(require 'req-package)
To start loading packages in right order, we need to added following in the last of emacs config.
(req-package-finish)
You can take a look at End of configuration section.
The variable load-path
lists all the directories where Emacs should look for
Elisp files.
Though I use Cask
as package management in my emacs, some local packages like
my own theme or others can’t fetch by elpa need to add to load-path, this will
help emacs find them.
Following are my method to add directories to load-path recursively
, this
function also create directory to prevent directory not exist.
If you don’t have any local elisp and all packages is mantain by cask or elpa or spacemacs, you can skip following code.
;; Add directories to emacs's `load-path' recursively.
;; if path does not exist, create directory.
(let* ((lisp-dir '("local-lisp/" "theme/")))
(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)))))
Spacemacs is an emacs starterkit focus on Evil, which emulate vim keymap on Emacs.
I make my emacs on top of spacemacs since I also use vim keymap.
In my config file, the original ~/.spacemacs
file has moved to
~/.emacs.d/spacemacs.d/init.el
, I also advice spacemacs funtion to
prevent orphan packages deleted by spacemacs.
After all spacemacs init done, switch back to *scratch*
buffer.
Latest spacemacs can setup SPACEMACSDIR
to load customize spacemacs init.el
file.
(setenv "SPACEMACSDIR" (concat user-emacs-directory "spacemacs.d"))
I use Cask
to handle all packages, spacemacs should do nothing here.
;; Make spacemacs not remove my packages.
(defadvice configuration-layer/delete-orphan-packages (around null-func activate)
"Overwrite the spacemacs's `configuration-layer/delete-orphan-packages'
to make it not remove any orphan packages.")
Since my spacemacs is installed as submodule, it’s no need to check for newer version, I’ll handle this myself.
(defadvice spacemacs/check-for-new-version (around null-func activate)
"Overwrite the spacemacs's `spacemacs/check-for-new-version' to
makt it useless since I use git submodule to bundle spacemacs with my emacs.")
The original spacemacs is suggest to clone it to ~/.emacs.d
, I really not like
this. Instead, I move it to ~/.emacs.d/modules/spacemacs
so I can use org-mode
with literature writing.
;; Make a fake entry point for spacemacs, also modify the
;; `user-emacs-directory' temporary to mislead spacemacs real emacs
;; directory.
(require 'f)
(let* ((spacemacs-dir
(directory-file-name (f-join user-emacs-directory "modules" "spacemacs")))
(spacemacs-init
(concat (file-name-as-directory spacemacs-dir) "init.el"))
(user-emacs-directory (file-name-directory spacemacs-init)))
;; Initial spacemacs, our emacs run on top of it
(load spacemacs-init))
spacemacs is really awesome, but there’s something I don’t like.
(global-hl-line-mode -1)
;; After spacemacs loading finished, switch back to `*scratch*' buffer
;; and make sure it's in `lisp-interaction-mode'
(switch-to-buffer "*scratch*")
(with-current-buffer (get-buffer-create "*scratch*")
(lisp-interaction-mode))
I don’t like the ido-mode
.
(ido-mode -1)
I really hate spacemacs default echo the helm input in header line, it’s really annoying.
(setq helm-echo-input-in-header-line nil)
(remove-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe)
Most setup I want to use is done by spacemacs, but I still keep some basic setup here, some are not set or just keep for backward compability.
;; Only start server mode if I'm not root
(unless (string-equal "root" (getenv "USER"))
(require 'server)
(unless (server-running-p) (server-start)))
Under Mac OSX, I always bind Caps lock
as Control key, and make the Command
key as ALT
key like I done in Linux.
The Option
key will be setup as Super
.
We also disable some keys like ⌘-h
bypass to system in emacs-mac port.
(setq mac-option-modifier 'super)
(setq mac-command-modifier 'meta)
(setq mac-pass-command-to-system nil)
(when (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))
Most of my config is written in this file, it’s no need to tracking the emacs’s custom-setting.
I move the file to cache-dir and make git ignore it.
(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))
(when (require 'async nil 'noerror)
;; 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" 'ignore "init.el"))))
;; Add to hook
(add-hook 'after-save-hook 'tangle-init))
The menu bar is one of the UI elements which work best with mouses.
(menu-bar-mode -1)
I never use the tool bar, it’s really no need.
(tool-bar-mode -1)
I hate the blinking cursor actually, it’s really annoying.
(blink-cursor-mode -1)
Actually when you familier with emacs, you don’t need to use scroll-bar anymore.
(scroll-bar-mode -1)
Emacs starts out asking for you to type yes or no with most important questions.
Just let me use y
or n
with no RET
required an I’m quite happy.
(defalias 'yes-or-no-p 'y-or-n-p)
Since current Emacs default run on UTF-8, it’s no need to setup the encoding.
For language, though Traditional Chinese is my mothertone, I still prefer use
en_US
to display time info.
(prefer-coding-system 'utf-8)
(setq system-time-locale "en_US")
Some buildin packages not loaded by emacs, load it here.
(req-package cl-lib)
(req-package htmlize)
Most of emacs packages do not need many configs or just provide commands/functions to use, I put them here.
4clojure.el let you open and evaluate 4clojure questions.
(req-package 4clojure)
Ascii provides a way to display ASCII code on a window, that is, display in another window an ASCII table highlighting the current character code.
(req-package ascii
:init (progn
;; ascii-toggle
(defun ascii-toggle ()
"Toggle ascii-mode."
(interactive)
(if (not (ascii-off)) (ascii-on)))
;; alias ascii to ascii-toggle
(defalias 'ascii 'ascii-toggle)))
Convert simple ASCII art drawings (and org-tables) to beautiful Unicode.
(req-package ascii-art-to-unicode)
iedit let you edit multiple regions in the same way simultaneously.
GitHub: https://github.com/victorhge/iedit
(req-package iedit)
pangu-spcing is an minor-mode to auto add space
between Chinese and English
characters. Note that these white-space characters are not really added to the
contents, it just like to do so.
(req-package pangu-spacing
:init
(progn
;; 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)))))
SX is a full featured Stack Exchange mode for GNU Emacs 24+. Using the official API, it provides a versatile experience for the Stack Exchange network within Emacs itself.
(req-package sx :require sx-load)
hungry-delete borrows hungry deletion from cc-mode
, which will causes deletion
to delete all whitespace in the direction you are deleting.
(req-package hungry-delete
:init (global-hungry-delete-mode))
rainbow-mode s a minor mode for Emacs which displays strings representing colors with the color they represent as background.
(req-package rainbow-mode)
(req-package doxymacs
:config
(add-hook 'prog-mode-hook '(lambda () (doxymacs-mode))))
password-generator provides simple functions to create passwords and insert them inside buffer immediately.
(req-package password-generator)
discover-my-major make you discover key bindings and their meaning for the current Emacs major mode.
(req-package discover-my-major)
howdoi is a way to query Stack Overflow directly from the Emacs and get back the most upvoted answer to the first question that comes up for that query.
(req-package howdoi)
exec-path-from-shell is A GNU Emacs library to ensure environment variables inside Emacs look the same as in the user’s shell.
Ever find that a command works in your shell, but not in Emacs?
This happens a lot on OS X, where an Emacs instance started from the GUI inherits a default set of environment variables.
This library works solves this problem by copying important environment variables from the user’s shell: it works by asking your shell to print out the variables of interest, then copying them into the Emacs environment.
(req-package exec-path-from-shell
:init (when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))
manage-minor-mode let you manage your minor-mode on the dedicated interface buffer.
(req-package manage-minor-mode)
GitHub: https://github.com/nicferrier/emacs-noflet
(req-package noflet)
A mustache templating library in Emacs Lisp.
GitHub: https://github.com/Wilfred/mustache.el
(req-package mustache)
Manage your minor-mode on the dedicated interface buffer.
GitHub: https://github.com/ShingoFukuyama/manage-minor-mode
(req-package manage-minor-mode)
Expand region increases the selected region by semantic units. Just keep pressing the key until it selects what you want.
GitHub: https://github.com/magnars/expand-region.el
(req-package expand-region)
verify-url is a little tool that used to find out invalid urls in the buffer or region.
Use M-x verify-url
to find invalid urls in current buffer.
After executed command, you can use verify-url/next-invalid-url
to goto next
invalid-url or verify-url/previous-invalid-url
to goto previous one.
GitHub: https://github.com/lujun9972/verify-url
(req-package verify-url)
This package provides two new commands: zzz-to-char
and zzz-up-to-char
which
work like built-ins zap-to-char and zap-up-to-char, but allow you quickly select
exact character you want to “zzz” to.
The commands are minimalistic and often work like built-in ones when there is
only one occurrence of target character (except they automatically work in
backward direction too). You can also specify how many characters to scan from
each side of point, see zzz-to-char-reach
.
This package uses avy as backend.
GitHub: https://github.com/mrkkrp/zzz-to-char
(req-package zzz-to-char)
In emacs, we can use M-x
to execute interactive commands, I
implement some of them to make my emacs more easy to use.
Sometimes I just want to kill all buffers, this command will kill all
of them and make *scratch*
buffer alone.
(defun nuke-all-buffers ()
"Kill all buffers, leaving *scratch* only."
(interactive)
(mapcar (lambda (x) (kill-buffer x)) (buffer-list))
(delete-other-windows))
The default command save-buffer will not really save file when it untouched, use this command can let me force save file even if file is not modified.
(defun 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)))
<U200B>
character is a zero width space character
which is nice to
use under org-mode.
For more info, please see: suggestion for org-emphasis-regexp-components: *U*nited *N*ations
(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 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)))))))
Actually this command is the same as chmod +x
but it doesn’t use any shell
command, it use emacs’s logior function to change file attribute.
I only make owener
can has executable permission, not change it for gourp or
others user.
(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))
A really nice command help me to find error on elisp buffer.
(defun eval-buffer-until-error ()
"Evaluate emacs buffer until error occured."
(interactive)
(goto-char (point-min))
(while t (eval (read (current-buffer)))))
I always use dark theme for coding, moe-theme is a good start point, it’s bright and has good default faces for most modes. It also has dark and light versions, which is convenient.
However, I always want to customize everything on my own, so I rebuild another
emacs theme called coldnew-theme-night
and coldnew-theme-day
, you can find
them at theme/coldnew-theme.el.
Before use emacs’s load-theme
function, I advise it to it fully
unload previous theme before loading a new one.
;; 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)
(req-package minibuffer
:config
(progn
;; Make cursor in minibufer use bar shape
(add-hook 'minibuffer-setup-hook '(lambda () (setq cursor-type 'bar)))))
Some general purpose keybinding I famillier with.
(define-key minibuffer-local-map (kbd "C-w") 'backward-kill-word)
(define-key minibuffer-local-map (kbd "M-p") 'previous-history-element)
(define-key minibuffer-local-map (kbd "M-n") 'next-history-element)
(define-key minibuffer-local-map (kbd "C-g") 'minibuffer-keyboard-quit)
Some shortcuts let me access system path more easily.
(add-hook
'minibuffer-setup-hook
'(lambda ()
;; switch to tmp dir
(define-key minibuffer-local-map
(kbd "M-t") '(lambda()
(interactive)
(let ((dir (if (eq system-type 'darwin)
"/Volumes/ramdisk/" "/tmp/")))
(kill-line 0) (insert dir))))
;; switch to home dir
(define-key minibuffer-local-map
(kbd "M-h") '(lambda() (interactive) (kill-line 0)
(insert (file-name-as-directory (getenv "HOME")))))
;; other with C-x prefix to prevent conflict with helm
(define-key minibuffer-local-map
(kbd "C-x r") '(lambda() (interactive) (kill-line 0) (insert "/")))
;; More easy for tramp connect
(define-key minibuffer-local-map
(kbd "C-x s") '(lambda() (interactive) (kill-line 0) (insert "/ssh:")))
))
Why emacs config has an editor section, doesn’t means emacs is not an editor ? Yes, Emacs is an OS :)
I put some editor/IDE relative functions and packages here.
In most case, I’ll make line numers display globally by linum
.
(req-package linum :init (global-linum-mode 1))
Disable line number in some mode, for example, since org-mode
can
has many lines, it’s not recommand to enable linum-mode.
I use linum-off
to disable some mode.
(req-package linum-off
:config
(progn
(setq linum-disabled-mode-list
'(eshell-mode shell-mode term-mode erc-mode compilation-mode
woman-mode w3m-mode calendar-mode org-mode
))))
By default, Emacs will not update the contents of open buffers when a file changes on disk. This is inconvenient when switching branches in Git - as you’d risk editing stale buffers.
This problem can be solved by:
(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
rainbow-delimiters is a “rainbow parentheses”-like mode which highlights delimiters such as parentheses, brackets or braces according to their depth. Each successive level is highlighted in a different color. This makes it easy to spot matching delimiters, orient yourself in the code, and tell which statements are at a given depth.
(req-package rainbow-delimiters
:config
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
Though I am really familier with emacs, I still like some vim command.
(req-package evil
:require (undo-tree)
:init (evil-mode t)
:config
(progn
;; default state set to insert-state
(setq evil-default-state 'insert)
;; Bind all emacs-state key to insert state
(setcdr evil-insert-state-map nil)
(define-key evil-insert-state-map
(read-kbd-macro evil-toggle-key) 'evil-emacs-state)
;; Make sure `ESC' in insert-state will call `evil-normal-state'
(define-key evil-insert-state-map [escape] 'evil-normal-state)
;; Make all emacs-state buffer become to insert-state
(dolist (m evil-emacs-state-modes)
(add-to-list 'evil-insert-state-modes m))
))
EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs. The EditorConfig project consists of a file format for defining coding styles and a collection of text editor plugins that enable editors to read the file format and adhere to defined styles. EditorConfig files are easily readable and they work nicely with version control systems.
(req-package editorconfig)
(req-package epa-file
:init (epa-file-enable)
:config
(progn
;; 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
:config
(progn
(setq tramp-default-method "rsync")))
This Emacs library minor mode will intelligently call whitespace-cleanup
before
buffers are saved.
whitespace-cleanup
is a handy function, but putting it in before-save-hook
for every buffer is overkill, and causes messy diffs when editing third-party
code that did not initially have clean whitespace.
Additionally, whitespace preferences are often project-specific, and it’s
inconvenient to set up before-save-hook
in a .dir-locals.el
file.
whitespace-cleanup-mode
is a minor mode which calls whitespace-cleanup
before saving the current buffer, but only if the whitespace in the buffer was
initially clean. It determines this by quickly checking to see if
whitespace-cleanup
would have any effect on the buffer.
GitHub: https://github.com/purcell/whitespace-cleanup-mode
(req-package whitespace-cleanup-mode
:init (add-hook 'prog-mode-hook 'whitespace-cleanup-mode))
highlight-numbers
is an Emacs minor mode that highlights numeric literals in
source code.
GitHub: https://github.com/Fanael/highlight-numbers
(req-package highlight-numbers
:init
;; 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)))))
GitHub: https://github.com/dgutov/highlight-escape-sequences
(req-package highlight-escape-sequences
:config
(progn
;; Make face the same as builtin face
(put 'font-lock-regexp-grouping-backslash 'face-alias 'font-lock-builtin-face)
;; Add extra modes
(add-to-list 'hes-simple-modes 'c-mode)
(add-to-list 'hes-simple-modes 'c++-mode)
;; 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 projectile
:interpreter ("projectile" . projectil-mode))
Company is a text completion framework for Emacs. The name stands for “complete anything”. It uses pluggable back-ends and front-ends to retrieve and display completion candidates.
(req-package company
:init (global-company-mode 1)
:config (setq company-idle-delay nil))
(req-package company-c-headers
:require company
:init (add-to-list 'company-backends 'company-c-headers))
(req-package company-quickhelp
:require company
:init (company-quickhelp-mode 1))
Company-statistics is a global minor mode built on top of the in-buffer completion system company-mode. The idea is to keep a log of a certain number of completions you choose, along with some context information, and use that to rank candidates the next time you have to choose — hopefully showing you likelier candidates at the top of the list.
GitHub: https://github.com/company-mode/company-statistics
(req-package company-statistics
:config
(progn
(setq company-statistics-file (concat user-cache-directory
"company-statistics-cache.el"))
(add-hook 'after-init-hook 'company-statistics-mode)))
(add-hook
'company-mode-hook
'(lambda()
(define-key company-active-map (kbd "C-g") 'company-abort)
(define-key company-active-map (kbd "C-n") 'company-select-next)
(define-key company-active-map (kbd "C-p") 'company-select-previous)
(define-key company-active-map (kbd "TAB") 'company-complete-selection)
(define-key company-active-map (kbd "<tab>") 'company-complete-selection)))
(req-package yasnippet
:init (yas-global-mode 1)
:mode ("emacs.+/snippets/" . snippet-mode)
:config
(progn
(setq yas/prompt-functions '(yas-dropdown-prompt
yas-completing-prompt
yas-ido-prompt))
(setq yas/snippet-dirs (concat user-emacs-directory "snippets"))))
I really like org-mode’s easy-template
function, so I implement one called
major-mode-expand
which will let you use easy-template like function in any
major-mode.
(eval-after-load 'yasnippet
'(progn
(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))
))
Take emacs-lisp-mode as example, if I want to use <r
and press TAB
then yasnippet will expand the command, just add following code:
(setq emacs-lisp-mode-expand-alist '(("r" . "require")))
For c-mode, just do the same but change the relative major-mode-expand-alist like following
(setq c-mode-expand-alist '(("i" . "include")))
Sometimes I’ll clean the *scratch*
buffer by kill it, add following function
to let emacs re-create it automatically.
;; 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 helm
:require helm-config
:init (helm-mode 1)
:config
(progn
;; 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)
))
(add-hook
'helm-mode-hook
'(lambda()
;; use TAB to complete helm
(define-key helm-map (kbd "TAB") 'helm-execute-persistent-action)
(define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-w") 'backward-kill-word)))
(req-package org
:require (org-crypt)
:mode (("\\.org\\'" . org-mode)
("\\.org_archive\\'" . org-mode))
:config
(progn
;; Always enable auto indent mode
(setq org-indent-mode t)
;; 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)))
(eval-after-load 'org
'(progn
;; 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 'org
'(progn
(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"))
))
(eval-after-load 'org
'(progn
(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)
))
(add-to-list 'org-src-lang-modes '("dot" . graphviz-dot))
))
An abbreviated link looks like
[[linkword:tag][description]]
(setq org-link-abbrev-alist
'(("google" . "http://www.google.com/search?q=")
("google-map" . "http://maps.google.com/maps?q=%s")
))
see: http://emacs.stackexchange.com/questions/450/intelligent-spell-checking-in-org-mode
(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"))
))
(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" "$" "$$" "\\(" "\\[")))
(add-hook
'org-mode-hook
'(lambda()
(define-key org-mode-map (kbd "C-c b") 'org-metaleft)
(define-key org-mode-map (kbd "C-c f") 'org-metaright)
(define-key org-mode-map (kbd "C-c p") 'org-metaup)
(define-key org-mode-map (kbd "C-c p") 'org-metadown)
(define-key org-mode-map (kbd "C-c i") 'org-insert-link)
(define-key org-mode-map (kbd "C-c I") 'org-toggle-inline-images)))
(req-package flymake-shell
:require (flymake shell)
:config (add-hook 'sh-set-shell-hook 'flymake-shell-load))
(req-package batch-mode :mode "\\.bat\\'")
(req-package cc-mode
:mode
(("\\.h\\'" . c-mode)
("\\.c\\'" . c-mode)
("\\.hpp\\'" . c++-mode)
("\\.cpp\\'" . c++-mode))
:config
(progn
;; use regexp to check if it's C++ header
(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))
))
(req-package c-eldoc
:config
(progn
(add-hook 'c-mode-common-hook
'(lambda ()
(setq c-eldoc-includes "`pkg-config gtk+-3.0 --cflags --libs` -I./ -I../")
(c-turn-on-eldoc-mode)))))
cwarn-mode is a minor mode that ca highlight a few dangerous types in C/C++.
By default it highlights:
- Semicolons right after conditions and loops (e.g.
if (x == y);
) - Assignments in tests (e.g.
if (x = y) {
) - Functions with reference parameters (e.g.
void funct(string &p) {
)
(req-package cwarn
:init (add-hook 'c-mode-common-hook '(lambda () (cwarn-mode 1))))
dummy-h-mode is an major-mode to help switch major mode to c/c++/objc-mode on .h file.
GitHub: https://github.com/yascentur/dummy-h-mode-el
(req-package dummy-h-mode
:require cc-mode
:mode "\\.h$"
:config
(progn
(add-hook 'dummy-h-mode-hook
(lambda ()
(setq dummy-h-mode-default-major-mode 'c-mode)))
(add-hook 'dummy-h-mode-hook
(lambda ()
(setq dummy-h-mode-search-limit 60000)))))
Extra hightlight for stdint.h
(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))))
cpputils-cmake is a nice tool for cmake project.
GitHub: https://github.com/redguardtoo/cpputils-cmake
(req-package cpputils-cmake
:require (flymake flycheck)
:config
(progn
(add-hook 'c-mode-common-hook
(lambda ()
(when (derived-mode-p 'c-mode 'c++-mode)
(cppcm-reload-all))))))
This extension allows to quickly switch between header and a source file with
the same name located in the directory tree or repository. It is an alternatife
to ff-find-other-file
.
GitHub: https://github.com/fourier/cff
(req-package cff
:config
(progn
(add-hook 'c++-mode-hook
'(lambda ()
(define-key c-mode-base-map (kbd "M-o") 'cff-find-other-file)))
(add-hook 'c-mode-hook
'(lambda ()
(define-key c-mode-base-map (kbd "M-o") 'cff-find-other-file)))))
I always use linux coding style
for c language by default.
(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)))
As part of Linux Kernel developer, I add linux-kernel
coding style rule, which
use tabs
as indent and follow linux kernel development rules. Use following
code to make emacs switch to linux-kernel
style automatically when enter linux
kernel directories.
This coding style is document in https://www.kernel.org/doc/Documentation/CodingStyle.
(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)
Use my C++ coding style.
(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)
))
;; C
(add-hook
'c-mode-hook
'(lambda()
(define-key helm-map (kbd "C-c C-o") 'ff-find-other-file)))
;; C++
(add-hook
'c++-mode-hook
'(lambda()
(define-key helm-map (kbd "C-c C-o") 'ff-find-other-file)))
(req-package cmake-font-lock
:require (cmake-mode)
:init (add-hook 'cmake-mode-hook 'cmake-font-lock-activate))
(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 go-mode
:mode "\\.go$"
:config
(progn
;; Use gofmt to format code before save
(add-hook 'before-save-hook 'gofmt-before-save)))
(req-package graphviz-dot-mode
:init (defalias 'dot-mode 'graphviz-dot-mode))
(req-package malabar-mode
:mode "\\.java$")
(req-package gradle-mode
:mode "\\.gradle$")
(req-package js2-mode
:init (setq js2-highlight-level 3)
:mode "\\.js$")
import-js
is a tool to automatically import dependencies in your JavaScript
project. Use it in Vim or Emacs by placing your cursor on a variable and hit
<leader>j (Vim)
, or (M-x) import-js-import (Emacs)
.
GitHub: https://github.com/trotzig/import-js
(req-package import-js)
(req-package json-reformat :commands json-reformat-region)
(req-package flymake-json :require flymake)
(req-package json-mode
:require flymake-json
:mode ("\\.json$" . json-mode)
:init (add-hook 'json-mode-hook (lambda () (flymake-json-load))))
(req-package markdown-mode
:mode "\\.\\(md\\|markdown\\)\\'")
(req-package jinja2-mode)
(req-package qml-mode
:init (add-to-list 'auto-mode-alist '("\\.qml$" . qml-mode)))
(req-package ruby-mode
:mode (("Rakefile\\'" . ruby-mode)
("\\.rake$" . ruby-mode)
("\\.gemspec$" . ruby-mode)
("\\.rb$'" . ruby-mode)
("\\.ru$" . ruby-mode)
("Gemfile$" . ruby-mode)
("Guardfile$" . ruby-mode))
:config
(progn
;; We never want to edit Rubinius bytecode
(add-to-list 'completion-ignored-extensions ".rbc")
))
(req-package rake)
rust-mode is a major emacs-mode for editing Rust source code.
(req-package rust-mode
:mode "\\.rs\\'")
(req-package scala-mode
:mode (("\\.scala$" . scala-mode)))
(req-package sbt-mode
:mode (("\\.sbt$" . sbt-mode)))
(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))
:init (add-hook 'ssh-config-mode-hook 'turn-on-font-lock))
(req-package nxml-mode
:mode (("\\.pom$" . nxml-mode))
:config
(progn
;; 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
:mode "\\.yml$")
Though LISP
has many dialet, it still is the best programming language I ever
met.
(req-package eldoc
:init
(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))))))
el-spice is a minor mode that provides additional configuration to make programming in Emacs Lisp more enjoyable.
GitHub: https://github.com/vedang/el-spice
(req-package el-spice)
litable keeps a list of pure functions as a safeguard for unwanted evaluations.
A function must first be accepted into this list (using M-x litable-accept-as-pure
)
before it can be evaluated on-the-fly.
You should take care of what function you accept as pure to avoid any unfortunate accidents. Also, note that the pure functions list persists across sessions.
GitHub: https://github.com/Fuco1/litable
(req-package litable :init (litable-mode))
(req-package hl-defined
:config
(add-hook 'emacs-lisp-mode-hook 'hdefd-highlight-mode)
(add-hook 'lisp-interaction-mode-hook 'hdefd-highlight-mode))
(req-package highlight-cl
:init
(add-hook 'emacs-lisp-mode-hook
'(lambda ()
(highlight-cl-add-font-lock-keywords))))
(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 clojure-mode
:require (clojure-mode-extra-font-locking flycheck-clojure)
:mode "\\.\\(clj\\|boot\\|cljx\\|edn\\|cljs\\|cljs.hl\\)\\'")
https://github.com/clojure-emacs/clj-refactor.el
(req-package clj-refactor
:config
(progn
;; 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 "C-c C-x")))
cider is a Clojure Interactive Development Environment that Rocks for Emacs
(req-package cider
:require (cider-decompile cider-eval-sexp-fu eldoc)
:config
(progn
;; Enable eldoc in Clojure buffers
(eval-after-load 'eldoc
'(progn
(add-hook 'cider-mode-hook #'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)
;; Toggle between test and implementation, instead of showing test report buffer.
(eval-adter-load 'projectile
(define-key cider-mode-map (kbd "C-c C-t") 'projectile-toggle-between-implementation-and-test))
))
latest-clojure-libraries helps to looks up the latest version of clojure libraries on clojars/maven and automatically populates the buffer with the appropriate dependency vector. Optionally uses pomegranate to load the dependency directly into your running nrepl.
To use this plugin, you need to edit your ~/.lein/profiles.clj
:plugins vector
to include [lein-ancient "0.5.1"]
and optionally add
[com.cemerick/pomegranate "0.2.0"]
to your :dependencies vector if you want
the feature which automatically adds the library to your classpath without
restarting the repl.
After all step done, use M-x latest-clojure-libraries-insert-dependency
to
insert latest clojure libraries to your project.
GitHub: https://github.com/AdamClements/latest-clojure-libraries
(req-package latest-clojure-libraries)
(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)))
Sometimes we will use mustache as template system, mustache-mode is a nice helper.
GitHub: https://github.com/mustache/emacs
(req-package mustache-mode :mode "\\.mustache$")
emmet-mode is a fork of zencoding-mode which add minor mode providing support for Zen Coding by producing HTML from CSS-like selectors.
GitHub: https://github.com/smihica/emmet-mode
(req-package emmet-mode
:config
(progn
;; Following mode support emmet-mode
(add-hook 'html-mode-hook 'emmet-mode)
(add-hook 'sgml-mode-hook 'emmet-mode)
(add-hook 'nxml-mode-hook 'emmet-mode)
(add-hook 'css-mode-hook 'emmet-mode)
;; Move cursor between quotes after expand
(add-hook 'emmt-mode-hook
'(lambda()
(setq emmet-move-cursor-between-quotes t)))
;; Make tab can also expand emmt instead of use yasnippet directly
(define-key emmt-mode-keymap (kbd "TAB") 'emmt-expand-yas)
(define-key emmt-mode-keymap (kbd "<tab>") 'emmt-expand-yas)))
Ansi Term with sane options and the ability to cycle/create terms.
GitHub: https://github.com/adamrt/sane-term
(req-package sane-term
:config
(progn
;; 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)))
eshell is not really a system shell, it’s written in pure lisp. What I like is it fully integrated with emacs.
(req-package eshell
:init
;; move eshell cache dir to ~/.emacs.d/.cache
(setq eshell-directory-name (concat user-cache-directory "eshell")))
(eval-after-load 'eshell
'(progn
;; 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)))
(eval-after-load 'eshell
'(progn
(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
(progn
(setq multi-eshell-shell-function '(eshell))
(setq multi-eshell-name "*eshell*")))
Eshell Autojump is an autojump like command written in pure elisp,
which add a j
command to let you jump to folder you has been access.
(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
(progn
;; I use my own keymap for winner-mode
(setq winner-dont-bind-my-keys t)
;; Start winner-mode globally
(winner-mode t)))
(req-package gitconfig-mode
: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)))
https://github.com/itsjeyd/git-wip-timemachine
(req-package git-wip-timemachine)
(add-hook
'magit-mode-hook
'(lambda()
(define-key magit-mode-map (kbd "C-g") 'magit-mode-quit-window)))
(req-package cedet
:config
(progn
(setq ede-project-placeholder-cache-file (concat user-cache-directory "ede-projects.el"))
(setq semanticdb-default-save-directory (concat user-cache-directory "semanticdb"))
(setq srecode-map-save-file (concat user-cache-directory "srecode-map.el"))
))
Create my minor-mode to control all keybindings
(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)
spacemacs reserve the SPC-o
for user setup theirs own keymap, I think I should add something here :(
(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 C-s") 'save-buffer-always
(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
(kbd "C--") 'text-scale-decrease
(kbd "C-=") 'text-scale-increase
)
(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 C-s") 'save-buffer-always
(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--") 'text-scale-decrease
(kbd "C-x t") 'sane-term
(kbd "C-x T") 'sane-term
)
(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)
Oh YA!! We finish loading emacs configuration :)
However, since we use req-package
for loading and installing packages, be sure
to execute following line to send req-package
on its merry way.
(req-package-finish)
In the end of configuration, I’ll load my private config from ~/.personal.el
,
which contains something like password or account settings.
(let ((secret "~/.personal.el"))
(when (file-exists-p secret) (load-file secret)))
Following link is refrence for my emac config.
[1]
https://github.com/r0man/.emacs.d/blob/master/init.el.org
[2]
https://github.com/bodil/emacs.d
[3]
https://github.com/mgalgs/.emacs.d
[4]
https://raw.githubusercontent.com/sbisaacson/literate-emacs/master/README.org
[5]
https://github.com/jhenahan/emacs.d/blob/master/emacs-init.org
[6]
https://ryuslash.org/dotfiles/emacs/init.html
[7]
http://www.wisdomandwonder.com/wordpress/wp-content/uploads/2014/03/C3F.org_.txt