https://github.com/coldnew/coldnew-spacemacs
My spacemacs config (based on coldnew-emacs)
https://github.com/coldnew/coldnew-spacemacs
Last synced: over 1 year ago
JSON representation
My spacemacs config (based on coldnew-emacs)
- Host: GitHub
- URL: https://github.com/coldnew/coldnew-spacemacs
- Owner: coldnew
- Created: 2015-02-03T01:14:28.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2015-12-30T05:47:21.000Z (over 10 years ago)
- Last Synced: 2025-01-15T12:14:33.558Z (over 1 year ago)
- Language: Emacs Lisp
- Homepage:
- Size: 509 KB
- Stars: 49
- Watchers: 9
- Forks: 6
- Open Issues: 2
-
Metadata Files:
- Readme: README.org
Awesome Lists containing this project
README
#+TITLE: coldnew's emacs config
#+AUTHOR: Yen-Chin, Lee
#+email: coldnew.tw at gmail.com
#+DESCRIPTION: A literate programming style exposition of my Emacs configuration
#+LANGUAGE: en
#+STARTUP: overview indent align
#+BABEL: :cache yes
#+OPTIONS: ^:nil
#+PROPERTY: header-args :comments link
# Badge
[[http://www.gnu.org/licenses/gpl-3.0.txt][https://img.shields.io/badge/license-GPL_3-green.svg?dummy]]
[[https://travis-ci.org/coldnew/coldnew-spacemacs][https://travis-ci.org/coldnew/coldnew-spacemacs.svg?branch=master]]
* Introduction
This is another emacs config of mine, which is a totally rewritten version
based on top of [[https://github.com/syl20bnr/spacemacs][spacemacs]] and [[https://github.com/coldnew/coldnew-emacs][coldnew-emacs]] with [[http://en.wikipedia.org/wiki/Literate_programming][literate programming]]
in [[http://orgmode.org/][org-mode]], but it uses English to write this config instead.
Feel free to use it :).
** Install emacs
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.
*** Mac OSX
In Mac OSX, I use [[http://brew.sh/][homebrew]] to mantain opensource packages, I always install latest
version of emacs via following command
#+BEGIN_EXAMPLE
brew install emacs --HEAD --use-git-head --with-cocoa --with-gnutls --with-rsvg --with-imagemagick
brew linkapps
#+END_EXAMPLE
*** Gentoo Linux
[[https://www.gentoo.org/][Gentoo Linux]] is the best linux distrobution I ever used and it's really easy to install latest apps.
#+BEGIN_EXAMPLE
USE="X gtk3 inotify xft imagemagick" emerge app-editors/emacs
#+END_EXAMPLE
** Install or testing this config
- 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 [[https://github.com/cask/cask][Cask]] for package management
: curl -fsSL https://raw.githubusercontent.com/cask/cask/master/go | python
- Then use the =make= command bootstrap this config
: make bootstrap
- If you only want to generate the =init.el=, jut type
: make init.el
- If you do not put this repo on =~/.emacs.d=, you need to use following
command to start emacs
: emacs -q -l ~/coldnew-spacemacs/init.el
** Packages need to install in system (Optional)
Some extra packages need to be installed in the system manually. These packages
are =optional= but can make this configuration work more nicely.
*** Mac OSX
#+BEGIN_SRC sh :tangle no
brew install the_silver_searcher
brew install fasd
brew install docmacs
brew install aspell --with-lang-en
#+END_SRC
*** Gentoo Linux
In Gentoo Linux, don't forget to enable ~USE=emacs~ to make gentoo auto install
emacs-related packages.
#+BEGIN_SRC sh :tangle no
emerge sys-apps/the_silver_searcher
emerge app-shells/fasd
emerge app-shells/doxymacs
emerge app-shells/aspell
#+END_SRC
* Initialization Emacs
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.
** load prefer newer
#+BEGIN_SRC emacs-lisp
;; 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)
#+END_SRC
** change the user-emacs-directory
I this configuration, =user-emacs-directory= always refer to the emacs
configuration's init.el parent directory.
#+BEGIN_SRC emacs-lisp
;; 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.")
#+END_SRC
** define user-cache-directory variable
Setup the cache directory to store some cache content.
#+BEGIN_SRC emacs-lisp
(defconst user-cache-directory
(file-name-as-directory (concat user-emacs-directory ".cache"))
"My emacs storage area for persistent files.")
#+END_SRC
* Package Management
Before we start this section, we need to initialize =package.el= first.
#+BEGIN_SRC emacs-lisp
;; 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)
#+END_SRC
The main package magement in my emacs is [[https://github.com/cask/cask][Cask]], which is a really nice package
like npm, cargo ...etc.
[[https://github.com/cask/cask][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 [[https://github.com/cask/cask][Cask]], all package install by
=package.el= just save to =.cask= folder according to your emacs version.
#+BEGIN_EXAMPLE
coldnew@Sara ~/.emacs.d $ tree -L 1 .cask/
.cask/
├── 24.5.1
├── 25.0.50.1
└── 25.1.50.1
3 directories, 0 files
#+END_EXAMPLE
** Cask and Pallet
[[https://github.com/rdallasgray/pallet][Pallet]] is a wonderful little tool built on [[https://github.com/cask/cask][Cask]], a dependency management tool
for Emacs packages. Pallet adds automatic updating of the =Caskfile= when
packages are installed and deleted.
*** Installing Cask
Just run this command in your terminal of choice:
#+BEGIN_SRC sh :tangle no
curl -fsSkL https://raw.github.com/cask/cask/master/go | python
#+END_SRC
then add =~/.cask/bin= to your =PATH= so that you can use =cask=.
*** Creating a Caskfile :caskfile:
For now, we just need a minimal =Cask= to get Pallet set up. Mine
looks like this:
#+BEGIN_SRC emacs-lisp :tangle (if (file-exists-p "Cask") "no" "Cask")
(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")
#+END_SRC
Then run the following command in your =.emacs.d= directory to set up
[[https://github.com/rdallasgray/pallet][Pallet]].
#+BEGIN_SRC sh :tangle no
cask install
#+END_SRC
Since the =Cask= file is just emacs-lisp file, add it to mode-alist.
#+BEGIN_SRC emacs-lisp
(add-to-list 'auto-mode-alist '("Cask$" . emacs-lisp-mode))
#+END_SRC
*** Initialize Cask
Finally, we add the following lines to our init file:
#+BEGIN_SRC emacs-lisp
(require 'cask "~/.cask/cask.el")
(cask-initialize)
#+END_SRC
*** Initialize Pallet
Since we already install pallet via cask, we just need to use the following code
to initialize pallet.
#+BEGIN_SRC emacs-lisp
(require 'pallet)
(pallet-mode t)
#+END_SRC
** quelpa
[[https://github.com/quelpa/quelpa][quelpa]] is another package manager which can help you builds an ELPA compatible
package and installs that locally.
GitHub: https://github.com/quelpa/quelpa
#+BEGIN_SRC emacs-lisp
(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))
#+END_SRC
** req-package
[[https://github.com/edvorg/req-package][req-package]] is a wrapper on top of [[https://github.com/jwiegley/use-package][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.
*** Initialize req-package
With the preceding process complete, we just need to add the following
line to our init file to begin using =req-package=:
#+BEGIN_SRC emacs-lisp
(require 'req-package)
#+END_SRC
*** Start loading packages in right order
To start loading packages in right order, we need to added following in the last
of emacs config.
#+BEGIN_SRC emacs-lisp :tangle no
(req-package-finish)
#+END_SRC
You can take a look at [[*End%20of%20configuration][End of configuration]] section.
* Load Path
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.
#+BEGIN_SRC emacs-lisp
;; 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)))))
#+END_SRC
* Spacemacs
[[https://github.com/syl20bnr/spacemacs][Spacemacs]] is an emacs starterkit focus on [[https://gitorious.org/evil/pages/Home][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.
** Load basic spacemacs configuration file
Latest spacemacs can setup =SPACEMACSDIR= to load customize spacemacs init.el
file.
#+BEGIN_SRC emacs-lisp
(setenv "SPACEMACSDIR" (concat user-emacs-directory "spacemacs.d"))
#+END_SRC
** Overwrite spacemacs function to let it not remove my packages
I use =Cask= to handle all packages, spacemacs should do nothing here.
#+BEGIN_SRC emacs-lisp
;; 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.")
#+END_SRC
** Spacemacs no need to check newer version
Since my spacemacs is installed as submodule, it's no need to check for newer
version, I'll handle this myself.
#+BEGIN_SRC emacs-lisp
(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.")
#+END_SRC
** Load spacemacs
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.
#+BEGIN_SRC emacs-lisp
;; 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))
#+END_SRC
** Some function should execute after loading spacemacs-init.
spacemacs is really awesome, but there's something I don't like.
*** Disable global highlight by default
#+BEGIN_SRC emacs-lisp
(global-hl-line-mode -1)
#+END_SRC
*** switch back to `*scratch*' buffer after loading spacemacs finished
#+BEGIN_SRC emacs-lisp
;; 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))
#+END_SRC
*** Not use ido-mode
I don't like the =ido-mode=.
#+BEGIN_SRC emacs-lisp
(ido-mode -1)
#+END_SRC
*** Move helm input in minibuffer
I *really* hate spacemacs default echo the helm input in header line, it's
really annoying.
#+BEGIN_SRC emacs-lisp
(setq helm-echo-input-in-header-line nil)
(remove-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe)
#+END_SRC
* Basic setup
Most setup I want to use is done by [[https://github.com/syl20bnr/spacemacs][spacemacs]], but I still keep some basic setup
here, some are not set or just keep for backward compability.
** Startup emacs server
#+BEGIN_SRC emacs-lisp
;; Only start server mode if I'm not root
(unless (string-equal "root" (getenv "USER"))
(require 'server)
(unless (server-running-p) (server-start)))
#+END_SRC
** Under Mac OSX use Command key as ALT
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.
#+BEGIN_SRC emacs-lisp
(setq mac-option-modifier 'super)
(setq mac-command-modifier 'meta)
(setq mac-pass-command-to-system nil)
#+END_SRC
** Don't ask me when close emacs with process is running
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** Don't ask me when kill process buffer
#+BEGIN_SRC emacs-lisp
(setq kill-buffer-query-functions
(remq 'process-kill-buffer-query-function
kill-buffer-query-functions))
#+END_SRC
** Save custom-file as cache
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.
#+BEGIN_SRC emacs-lisp
(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))
#+END_SRC
** Async rebuild init.el after save
#+BEGIN_SRC emacs-lisp
(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))
#+END_SRC
** Turn-off menu bar
The menu bar is one of the UI elements which work best with mouses.
#+BEGIN_SRC emacs-lisp
(menu-bar-mode -1)
#+END_SRC
** Turn-off tool bar
I never use the tool bar, it's really no need.
#+BEGIN_SRC emacs-lisp
(tool-bar-mode -1)
#+END_SRC
** Turn-off blinking cursor
I hate the blinking cursor actually, it's really annoying.
#+BEGIN_SRC emacs-lisp
(blink-cursor-mode -1)
#+END_SRC
** Turn-off scroll bar
Actually when you familier with emacs, you don't need to use scroll-bar anymore.
#+BEGIN_SRC emacs-lisp
(scroll-bar-mode -1)
#+END_SRC
** Ask for y or n, not yes or no
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.
#+BEGIN_SRC emacs-lisp
(defalias 'yes-or-no-p 'y-or-n-p)
#+END_SRC
* Languages and Encodings
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.
#+BEGIN_SRC emacs-lisp
(prefer-coding-system 'utf-8)
(setq system-time-locale "en_US")
#+END_SRC
* Buildin Packages :buildin:
Some buildin packages not loaded by emacs, load it here.
** cl-lib
#+BEGIN_SRC emacs-lisp
(req-package cl-lib)
#+END_SRC
** htmlize :htmlize:
#+BEGIN_SRC emacs-lisp
(req-package htmlize)
#+END_SRC
* External Packages :packages:
Most of emacs packages do not need many configs or just provide
commands/functions to use, I put them here.
** 4clojure
[[https://github.com/losingkeys/4clojure.el][4clojure.el]] let you open and evaluate [[http://www.4clojure.com/][4clojure]] questions.
#+BEGIN_SRC emacs-lisp
(req-package 4clojure)
#+END_SRC
** ascii
[[http://www.emacswiki.org/emacs/AsciiMode][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.
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** ascii-art-to-unicode
Convert simple ASCII art drawings (and org-tables) to beautiful Unicode.
#+BEGIN_SRC emacs-lisp
(req-package ascii-art-to-unicode)
#+END_SRC
** iedit
[[https://github.com/victorhge/iedit][iedit]] let you edit multiple regions in the same way simultaneously.
GitHub: https://github.com/victorhge/iedit
#+BEGIN_SRC emacs-lisp
(req-package iedit)
#+END_SRC
** pangu-spacing
[[https://github.com/coldnew/pangu-spacing][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.
#+BEGIN_SRC emacs-lisp
(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)))))
#+END_SRC
** sx
[[https://github.com/vermiculus/sx.el/][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.
#+BEGIN_SRC emacs-lisp
(req-package sx :require sx-load)
#+END_SRC
** hungry-delete
[[https://github.com/nflath/hungry-delete][hungry-delete]] borrows hungry deletion from =cc-mode=, which will causes deletion
to delete all whitespace in the direction you are deleting.
#+BEGIN_SRC emacs-lisp
(req-package hungry-delete
:init (global-hungry-delete-mode))
#+END_SRC
** rainbow-mode
[[https://julien.danjou.info/projects/emacs-packages][rainbow-mode]] s a minor mode for Emacs which displays strings representing colors
with the color they represent as background.
#+BEGIN_SRC emacs-lisp
(req-package rainbow-mode)
#+END_SRC
** doxymacs
#+BEGIN_SRC emacs-lisp
(req-package doxymacs
:config
(add-hook 'prog-mode-hook '(lambda () (doxymacs-mode))))
#+END_SRC
** password-generator
[[https://github.com/zargener/emacs-password-genarator][password-generator]] provides simple functions to create passwords and insert them
inside buffer immediately.
#+BEGIN_SRC emacs-lisp
(req-package password-generator)
#+END_SRC
** discover-my-major
[[https://github.com/steckerhalter/discover-my-major][discover-my-major]] make you discover key bindings and their meaning for the
current Emacs major mode.
#+BEGIN_SRC emacs-lisp
(req-package discover-my-major)
#+END_SRC
** howdoi
[[https://github.com/atykhonov/emacs-howdoi][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.
#+BEGIN_SRC emacs-lisp
(req-package howdoi)
#+END_SRC
** exec-path-from-shell
[[https://github.com/purcell/exec-path-from-shell][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.
#+BEGIN_SRC emacs-lisp
(req-package exec-path-from-shell
:init (when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))
#+END_SRC
** manage-minor-mode
[[https://github.com/ShingoFukuyama/manage-minor-mode][manage-minor-mode]] let you manage your minor-mode on the dedicated interface
buffer.
#+BEGIN_SRC emacs-lisp
(req-package manage-minor-mode)
#+END_SRC
** noflet
GitHub: https://github.com/nicferrier/emacs-noflet
#+BEGIN_SRC emacs-lisp
(req-package noflet)
#+END_SRC
** mustache :mustache:
A mustache templating library in Emacs Lisp.
GitHub: https://github.com/Wilfred/mustache.el
#+BEGIN_SRC emacs-lisp
(req-package mustache)
#+END_SRC
** manage-minor-mode
Manage your minor-mode on the dedicated interface buffer.
GitHub: https://github.com/ShingoFukuyama/manage-minor-mode
#+BEGIN_EXAMPLE
(req-package manage-minor-mode)
#+END_EXAMPLE
** expand-region
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
#+BEGIN_SRC emacs-lisp
(req-package expand-region)
#+END_SRC
** verify-url
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
#+BEGIN_SRC emacs-lisp
(req-package verify-url)
#+END_SRC
** zzz-to-char
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
#+BEGIN_SRC emacs-lisp
(req-package zzz-to-char)
#+END_SRC
* Interactive Commands :command:
In emacs, we can use =M-x= to execute interactive commands, I
implement some of them to make my emacs more easy to use.
** Buffers :buffer:
*** Kill all buffers except *scratch* buffer
Sometimes I just want to kill all buffers, this command will kill all
of them and make =*scratch*= buffer alone.
#+BEGIN_SRC emacs-lisp
(defun nuke-all-buffers ()
"Kill all buffers, leaving *scratch* only."
(interactive)
(mapcar (lambda (x) (kill-buffer x)) (buffer-list))
(delete-other-windows))
#+END_SRC
*** Make emacs can always save buffers (even if file is not modified)
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.
#+BEGIN_SRC emacs-lisp
(defun save-buffer-always ()
"Save the buffer even if it is not modified."
(interactive)
(set-buffer-modified-p t)
(save-buffer))
#+END_SRC
*** Abort minibuffer recursive edit
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
*** Make buffer untabify
#+BEGIN_SRC emacs-lisp
(defun untabify-buffer ()
(interactive)
(save-excursion
(untabify (point-min) (point-max))))
#+END_SRC
*** Indent whole buffer
#+BEGIN_SRC emacs-lisp
(defun indent-whole-buffer ()
"Indent whole buffer."
(interactive)
(save-excursion
(indent-region (point-min) (point-max))))
#+END_SRC
*** Remove buffers trailing whitespace and untabify
#+BEGIN_SRC emacs-lisp
(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))))
#+END_SRC
*** Replace the preceding sexp with its value
#+BEGIN_SRC emacs-lisp
(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)))))
#+END_SRC
*** Quick folding source block
#+BEGIN_SRC emacs-lisp
(defun quick-folding-source ()
"Use emacs buildin easy to folding code."
(interactive)
(set-selective-display
(if selective-display nil 1)))
#+END_SRC
** Edit (Insert/Remove)
*** Insert U200B char
== character is a =zero width space character= which is nice to
use under org-mode.
For more info, please see: [[https://lists.gnu.org/archive/html/emacs-orgmode/2012-09/msg00155.html][suggestion for org-emphasis-regexp-components: *U*nited *N*ations]]
#+BEGIN_SRC emacs-lisp
(defun insert-U200B-char ()
"Insert char, this character is nice use in org-mode."
(interactive)
(insert "\ufeff"))
#+END_SRC
*** Insert empty line after current line
#+BEGIN_SRC emacs-lisp
(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))
#+END_SRC
*** Insert lorem ipsum
#+BEGIN_SRC emacs-lisp
(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."))
#+END_SRC
*** Delete word
#+BEGIN_SRC emacs-lisp
(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))))
#+END_SRC
*** Backward delete word
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
*** Set mark or expand region
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
*** Indent region/buffer and cleanup
#+BEGIN_SRC emacs-lisp
(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."))))))
#+END_SRC
** File Handle
*** Reopen file as root
#+BEGIN_SRC emacs-lisp
(defun file-reopen-as-root ()
(interactive)
(when buffer-file-name
(find-alternate-file
(concat "/sudo:root@localhost:"
buffer-file-name))))
#+END_SRC
*** Delete current buffer file
#+BEGIN_SRC emacs-lisp
(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)))))
#+END_SRC
*** Rename current Buffer and file
#+BEGIN_SRC emacs-lisp
(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)))))))
#+END_SRC
*** Add executable attribute to file
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.
#+BEGIN_SRC emacs-lisp
(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"))))
#+END_SRC
*** Clone current file to new one
#+BEGIN_SRC emacs-lisp
(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))
#+END_SRC
** Debug
*** Eval emacs buffer until error
A really nice command help me to find error on elisp buffer.
#+BEGIN_SRC emacs-lisp
(defun eval-buffer-until-error ()
"Evaluate emacs buffer until error occured."
(interactive)
(goto-char (point-min))
(while t (eval (read (current-buffer)))))
#+END_SRC
* Theme :theme:
I always use dark theme for coding, [[https://github.com/kuanyui/moe-theme.el][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 [[file: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.
#+BEGIN_SRC emacs-lisp
;; 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)
#+END_SRC
* Minibuffer :minibuffer:
#+BEGIN_SRC emacs-lisp
(req-package minibuffer
:config
(progn
;; Make cursor in minibufer use bar shape
(add-hook 'minibuffer-setup-hook '(lambda () (setq cursor-type 'bar)))))
#+END_SRC
** Setup keybindings :keybinding:
Some general purpose keybinding I famillier with.
#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC
Some shortcuts let me access system path more easily.
#+BEGIN_SRC emacs-lisp
(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:")))
))
#+END_SRC
* Editors :editor:
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.
** Line Numbers :linum:
In most case, I'll make line numers display globally by =linum=.
#+BEGIN_SRC emacs-lisp
(req-package linum :init (global-linum-mode 1))
#+END_SRC
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.
#+BEGIN_SRC emacs-lisp
(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
))))
#+END_SRC
** Keeping files in sync
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:
#+BEGIN_SRC emacs-lisp
(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
#+END_SRC
** Colorfy delimters
[[https://github.com/Fanael/rainbow-delimiters][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.
#+BEGIN_SRC emacs-lisp
(req-package rainbow-delimiters
:config
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
#+END_SRC
** Vim Emulation :evil:
Though I am really familier with emacs, I still like some vim command.
#+BEGIN_SRC emacs-lisp :noweb no-export :exports code
(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))
))
#+END_SRC
** Add support for editorconfig :editorconfig:
[[http://editorconfig.org/][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.
#+BEGIN_SRC emacs-lisp
(req-package editorconfig)
#+END_SRC
** En/Decrypt files by EasyPG
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** Remote file editing :tramp:
#+BEGIN_SRC emacs-lisp
(req-package tramp
:config
(progn
(setq tramp-default-method "rsync")))
#+END_SRC
** Intelligently call whitespace-cleanup on save :whitespace:
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
#+BEGIN_SRC emacs-lisp
(req-package whitespace-cleanup-mode
:init (add-hook 'prog-mode-hook 'whitespace-cleanup-mode))
#+END_SRC
** Highlight numbers
=highlight-numbers= is an Emacs minor mode that highlights numeric literals in
source code.
GitHub: https://github.com/Fanael/highlight-numbers
#+BEGIN_SRC emacs-lisp
(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)))))
#+END_SRC
** Highlight escape charset
GitHub: https://github.com/dgutov/highlight-escape-sequences
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** Highlight FIXME, TODO
#+begin_src emacs-lisp
(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)
#+end_src
** Project management with projectile
#+BEGIN_SRC emacs-lisp
(req-package projectile
:interpreter ("projectile" . projectil-mode))
#+END_SRC
** Completion with Company mode :company:
[[http://company-mode.github.io/][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.
#+BEGIN_SRC emacs-lisp
(req-package company
:init (global-company-mode 1)
:config (setq company-idle-delay nil))
#+END_SRC
*** Completion C/C++ headers
#+BEGIN_SRC emacs-lisp
(req-package company-c-headers
:require company
:init (add-to-list 'company-backends 'company-c-headers))
#+END_SRC
*** Add quickhelp in company-mode
#+BEGIN_SRC emacs-lisp
(req-package company-quickhelp
:require company
:init (company-quickhelp-mode 1))
#+END_SRC
*** Sort completion candidates by previous completion choices
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
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
*** Setup keybindings :keybinding:
#+BEGIN_SRC emacs-lisp
(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 "") 'company-complete-selection)))
#+END_SRC
** Snippet handle by yasnippet :yasnippet:
#+BEGIN_SRC emacs-lisp
(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"))))
#+END_SRC
*** Implement org-mode's easy-template like function
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.
#+BEGIN_SRC emacs-lisp
(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 \"") 'helm-execute-persistent-action)
(define-key helm-map (kbd "C-w") 'backward-kill-word)))
#+END_SRC
* Org :org:
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** Capture and Agenda
#+BEGIN_SRC emacs-lisp
(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)))
))
#+END_SRC
** Extend org-mode's easy templates
#+BEGIN_SRC emacs-lisp
(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"))
))
#+END_SRC
** Extend babel support languages
#+BEGIN_SRC emacs-lisp
(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))
))
#+END_SRC
** Setup link abbreviations
[[https://www.gnu.org/software/emacs/manual/html_node/org/Link-abbreviations.html][Link abbreviations]]
An abbreviated link looks like
: [[linkword:tag][description]]
#+BEGIN_SRC emacs-lisp
(setq org-link-abbrev-alist
'(("google" . "http://www.google.com/search?q=")
("google-map" . "http://maps.google.com/maps?q=%s")
))
#+END_SRC
** Make spell-checking tool ignore some org-mode section
see: http://emacs.stackexchange.com/questions/450/intelligent-spell-checking-in-org-mode
#+BEGIN_SRC emacs-lisp
(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"))
))
#+END_SRC
** Latex Export
#+BEGIN_SRC emacs-lisp
(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" "$" "$$" "\\(" "\\[")))
#+END_SRC
** Setup keybindings :keybinding:
#+BEGIN_SRC emacs-lisp :noweb yes :results silent
(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)))
#+END_SRC
* Programming Languages
** Bash :bash:
#+BEGIN_SRC emacs-lisp
(req-package flymake-shell
:require (flymake shell)
:config (add-hook 'sh-set-shell-hook 'flymake-shell-load))
#+END_SRC
** Batch :bat:
#+BEGIN_SRC emacs-lisp
(req-package batch-mode :mode "\\.bat\\'")
#+END_SRC
** C / C++ :cpp:
#+BEGIN_SRC emacs-lisp
(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))
))
#+END_SRC
*** Add eldoc support for C/C++ :eldoc:
#+BEGIN_SRC emacs-lisp
(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)))))
#+END_SRC
*** Highlight a few dangerous types in C/C++ :cwarn:
[[http://www.emacswiki.org/emacs/CWarnMode][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) {~)
#+BEGIN_SRC emacs-lisp
(req-package cwarn
:init (add-hook 'c-mode-common-hook '(lambda () (cwarn-mode 1))))
#+END_SRC
*** Use dummy-h-mode to help detect header's major mode
[[https://github.com/yascentur/dummy-h-mode-el][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
#+BEGIN_SRC emacs-lisp
(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)))))
#+END_SRC
*** Extra highlight keywords for C/C++
Extra hightlight for =stdint.h=
#+BEGIN_SRC emacs-lisp
(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))))
#+END_SRC
*** Syntax check and code-completion with CMake project :cmake:
[[https://github.com/redguardtoo/cpputils-cmake][cpputils-cmake]] is a nice tool for cmake project.
GitHub: https://github.com/redguardtoo/cpputils-cmake
#+BEGIN_SRC emacs-lisp
(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))))))
#+END_SRC
*** Emacs extension allowing quick switch between header and source file in C/C++
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
#+BEGIN_SRC emacs-lisp
(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)))))
#+END_SRC
*** C language coding style
I always use =linux coding style= for c language by default.
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
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.
#+BEGIN_SRC emacs-lisp
(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 $" 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)
#+END_SRC
*** C++ language coding style
Use my C++ coding style.
#+BEGIN_SRC emacs-lisp
(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)
))
#+END_SRC
*** Setup keybindings :keybinding:
#+BEGIN_SRC emacs-lisp
;; C
(add-hook
'c-mode-hook
'(lambda()
(define-key helm-map (kbd "C-c C-o") 'ff-find-other-file)))
#+END_SRC
#+BEGIN_SRC emacs-lisp
;; C++
(add-hook
'c++-mode-hook
'(lambda()
(define-key helm-map (kbd "C-c C-o") 'ff-find-other-file)))
#+END_SRC
** CMake :c:cpp:
#+BEGIN_SRC emacs-lisp
(req-package cmake-font-lock
:require (cmake-mode)
:init (add-hook 'cmake-mode-hook 'cmake-font-lock-activate))
#+END_SRC
** GLSL :glsl:
#+BEGIN_SRC emacs-lisp
(req-package glsl-mode
:mode (("\\.vs\\'" . glsl-mode)
("\\.fs\\'" . glsl-mode)
("\\.gs\\'" . glsl-mode))
:config (setq glsl-other-file-alist '(("\\.fs$" (".vs"))
("\\.vs$" (".fs")))))
#+END_SRC
** Go :golang:
#+BEGIN_SRC emacs-lisp
(req-package go-mode
:mode "\\.go$"
:config
(progn
;; Use gofmt to format code before save
(add-hook 'before-save-hook 'gofmt-before-save)))
#+END_SRC
** Graphviz :graphviz:
#+BEGIN_SRC emacs-lisp
(req-package graphviz-dot-mode
:init (defalias 'dot-mode 'graphviz-dot-mode))
#+END_SRC
** Java :java:
#+BEGIN_SRC emacs-lisp
(req-package malabar-mode
:mode "\\.java$")
(req-package gradle-mode
:mode "\\.gradle$")
#+END_SRC
** javascript :javascript:
#+BEGIN_SRC emacs-lisp
(req-package js2-mode
:init (setq js2-highlight-level 3)
:mode "\\.js$")
#+END_SRC
*** Simplify importing JS modules
=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
=j (Vim)=, or =(M-x) import-js-import (Emacs)=.
GitHub: https://github.com/trotzig/import-js
#+BEGIN_SRC emacs-lisp
(req-package import-js)
#+END_SRC
** Json :javascript:json:
#+BEGIN_SRC emacs-lisp
(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))))
#+END_SRC
** Markdown :markdown:
#+BEGIN_SRC emacs-lisp
(req-package markdown-mode
:mode "\\.\\(md\\|markdown\\)\\'")
#+END_SRC
** Python :python:
#+BEGIN_SRC emacs-lisp
(req-package jinja2-mode)
#+END_SRC
** QML :qml:qt:
#+BEGIN_SRC emacs-lisp
(req-package qml-mode
:init (add-to-list 'auto-mode-alist '("\\.qml$" . qml-mode)))
#+END_SRC
** Ruby :ruby:
#+BEGIN_SRC emacs-lisp
(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")
))
#+END_SRC
#+BEGIN_SRC emacs-lisp
(req-package rake)
#+END_SRC
** Rust :rust:
[[https://github.com/rust-lang/rust-mode][rust-mode]] is a major emacs-mode for editing Rust source code.
#+BEGIN_SRC emacs-lisp
(req-package rust-mode
:mode "\\.rs\\'")
#+END_SRC
** scala :scala:
#+BEGIN_SRC emacs-lisp
(req-package scala-mode
:mode (("\\.scala$" . scala-mode)))
(req-package sbt-mode
:mode (("\\.sbt$" . sbt-mode)))
#+END_SRC
** SSH Config :ssh:
#+BEGIN_SRC emacs-lisp
(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))
#+END_SRC
** XML :xml:
#+BEGIN_SRC emacs-lisp
(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)
))
#+END_SRC
** YAML :yaml:
#+BEGIN_SRC emacs-lisp
(req-package yaml-mode
:mode "\\.yml$")
#+END_SRC
* LISP Development :lisp:
Though =LISP= has many dialet, it still is the best programming language I ever
met.
** Emacs Lisp :elisp:
*** Add eldoc support :eldoc:
#+BEGIN_SRC emacs-lisp
(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))))))
#+END_SRC
*** Additional flavour to emacs-lisp programming :el@spice:
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
#+BEGIN_SRC emacs-lisp
(req-package el-spice)
#+END_SRC
*** On-the-fly evaluation/substitution of emacs lisp code :litable:
[[https://github.com/Fuco1/litable][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
#+BEGIN_SRC emacs-lisp
(req-package litable :init (litable-mode))
#+END_SRC
*** Highlight defined symbols
#+BEGIN_SRC emacs-lisp :tangle no
(req-package hl-defined
:config
(add-hook 'emacs-lisp-mode-hook 'hdefd-highlight-mode)
(add-hook 'lisp-interaction-mode-hook 'hdefd-highlight-mode))
#+END_SRC
*** Highlight functions or macros belone to cl.el
#+BEGIN_SRC emacs-lisp
(req-package highlight-cl
:init
(add-hook 'emacs-lisp-mode-hook
'(lambda ()
(highlight-cl-add-font-lock-keywords))))
#+END_SRC
*** Remove *.elc when save
#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC
** Clojure :clojure:
#+BEGIN_SRC emacs-lisp
(req-package clojure-mode
:require (clojure-mode-extra-font-locking flycheck-clojure)
:mode "\\.\\(clj\\|boot\\|cljx\\|edn\\|cljs\\|cljs.hl\\)\\'")
#+END_SRC
*** Add refactor function support
https://github.com/clojure-emacs/clj-refactor.el
#+BEGIN_SRC emacs-lisp
(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")))
#+END_SRC
*** Use cider for interactive development
[[https://github.com/clojure-emacs/cider][cider]] is a Clojure Interactive Development Environment that Rocks for Emacs
#+BEGIN_SRC emacs-lisp
(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))
))
#+END_SRC
*** Insert libraries in project more easily
[[https://github.com/AdamClements/latest-clojure-libraries][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
#+BEGIN_SRC emacs-lisp
(req-package latest-clojure-libraries)
#+END_SRC
* Web Development :web:
#+BEGIN_SRC emacs-lisp
(req-package web-mode
:mode (("\\.html?\\'" . web-mode)
("\\.ejs?\\'" . web-mode)))
#+END_SRC
** CSS :css:
#+BEGIN_SRC emacs-lisp
(req-package css-mode :mode "\\.css\\'")
#+END_SRC
*** Add support for eldoc :eldoc:
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** Less :less:
#+BEGIN_SRC emacs-lisp
(req-package less-css-mode
:init (add-to-list 'auto-mode-alist '("\\.less$" . less-css-mode))
:mode "\\.less$")
#+END_SRC
** SCSS :css:scss:
#+BEGIN_SRC emacs-lisp
(req-package scss-mode
:mode "\\.scss\\'"
:config
(progn
;; dont' build scss to css after save file
(setq scss-compile-at-save nil)))
#+END_SRC
** mustache :mustache:
Sometimes we will use [[https://mustache.github.io/][mustache]] as template system, [[https://github.com/mustache/emacs][mustache-mode]] is a nice
helper.
GitHub: https://github.com/mustache/emacs
#+BEGIN_SRC emacs-lisp
(req-package mustache-mode :mode "\\.mustache$")
#+END_SRC
** Use emmet-mode to add Zen Coding support
[[https://github.com/smihica/emmet-mode][emmet-mode]] is a fork of [[https://github.com/rooney/zencoding][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
#+BEGIN_SRC emacs-lisp :tangle no
(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 "") 'emmt-expand-yas)))
#+END_SRC
* Terminal Emulator :term:
** Sane Term
Ansi Term with sane options and the ability to cycle/create terms.
GitHub: https://github.com/adamrt/sane-term
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
** Eshell :eshell:
eshell is not really a system shell, it's written in pure lisp. What I
like is it fully integrated with emacs.
#+BEGIN_SRC emacs-lisp
(req-package eshell
:init
;; move eshell cache dir to ~/.emacs.d/.cache
(setq eshell-directory-name (concat user-cache-directory "eshell")))
#+END_SRC
*** Use bash like prompt with color
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
*** Use ansi-term to render visual commands
#+BEGIN_SRC emacs-lisp
(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")))
))
#+END_SRC
*** Support for multi-eshell instance
#+BEGIN_SRC emacs-lisp
(req-package multi-eshell
:require eshell
:config
(progn
(setq multi-eshell-shell-function '(eshell))
(setq multi-eshell-name "*eshell*")))
#+END_SRC
*** Add autojump command
[[http://www.emacswiki.org/emacs/EshellAutojump][Eshell Autojump]] is an [[https://github.com/joelthelion/autojump][autojump]] like command written in pure elisp,
which add a =j= command to let you jump to folder you has been access.
#+BEGIN_SRC emacs-lisp
(req-package eshell-autojump :require eshell)
#+END_SRC
*** Eshell commands setup
**** ..
#+BEGIN_SRC emacs-lisp
(defun eshell/.. (&optional level)
"Go up LEVEL directories"
(interactive)
(let ((level (or level 1)))
(eshell/cd (make-string (1+ level) ?.))
(eshell/ls)))
#+END_SRC
**** clear
#+BEGIN_SRC emacs-lisp
(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))))
#+END_SRC
**** emacs
#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC
**** unpack
#+BEGIN_SRC emacs-lisp
(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))))
#+END_SRC
* Window Management :window:
** Maximized window after emac start
#+BEGIN_SRC emacs-lisp
(modify-all-frames-parameters '((fullscreen . maximized)))
#+END_SRC
** winner-mode :winner:
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
* Version Control
** Git :git:
*** Add suport for git configuration files
#+BEGIN_SRC emacs-lisp
(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)))
#+END_SRC
*** Use git-wip to view your WIP commit
https://github.com/itsjeyd/git-wip-timemachine
#+BEGIN_SRC emacs-lisp
(req-package git-wip-timemachine)
#+END_SRC
*** Setup keybindings :keybinding:
#+BEGIN_SRC emacs-lisp :noweb yes :results silent
(add-hook
'magit-mode-hook
'(lambda()
(define-key magit-mode-map (kbd "C-g") 'magit-mode-quit-window)))
#+END_SRC
* Cedet :cedet:
#+BEGIN_SRC emacs-lisp
(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"))
))
#+END_SRC
* Keybinding :keybinding:
Create my minor-mode to control all keybindings
#+begin_src emacs-lisp
(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)
#+end_src
** Spacemacs Map
spacemacs reserve the =SPC-o= for user setup theirs own keymap, I think I should add something here :(
** Normal State
#+BEGIN_SRC emacs-lisp
(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
)
#+END_SRC
** Insert State
#+BEGIN_SRC emacs-lisp
(evil-define-key 'insert coldnew-editor-map
(kbd "") '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-") 'insert-U200B-char
(kbd "M-[") 'winner-undo
(kbd "M-]") 'winner-redo
(kbd "M-s") 'helm-occur
(kbd "s-") 'insert-empty-line
(kbd "s-") '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
)
#+END_SRC
** Ex Command
#+BEGIN_SRC emacs-lisp
(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)
#+END_SRC
* End of configuration
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.
#+BEGIN_SRC emacs-lisp
(req-package-finish)
#+END_SRC
In the end of configuration, I'll load my private config from =~/.personal.el=,
which contains something like password or account settings.
#+BEGIN_SRC emacs-lisp
(let ((secret "~/.personal.el"))
(when (file-exists-p secret) (load-file secret)))
#+END_SRC
* Reference
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
~[8]~ https://github.com/howardabrams/dot-files