All Projects → coldnew → Coldnew Emacs

coldnew / Coldnew Emacs

coldnew's emacs config

Projects that are alternatives of or similar to Coldnew Emacs

Org Sidebar
A helpful sidebar for Org mode
Stars: ✭ 354 (+1006.25%)
Mutual labels:  emacs, org-mode
Anki Editor
Emacs minor mode for making Anki cards with Org
Stars: ✭ 453 (+1315.63%)
Mutual labels:  emacs, org-mode
Emacs4developers
A document to help developers to use Emacs as a developer
Stars: ✭ 430 (+1243.75%)
Mutual labels:  configuration, emacs
Zetteldeft
A Zettelkasten system! Or rather, some functions on top of the emacs deft package.
Stars: ✭ 284 (+787.5%)
Mutual labels:  emacs, org-mode
Memacs
What did I do on February 14th 2007? Visualize your (digital) life in Org-mode
Stars: ✭ 711 (+2121.88%)
Mutual labels:  emacs, org-mode
.emacs.d
🎉 Personal GNU Emacs configuration
Stars: ✭ 313 (+878.13%)
Mutual labels:  emacs, org-mode
Spacemacs
A community-driven Emacs distribution - The best editor is neither Emacs nor Vim, it's Emacs *and* Vim!
Stars: ✭ 21,906 (+68356.25%)
Mutual labels:  configuration, emacs
Mu4e Dashboard
A dashboard for mu4e (mu for emacs)
Stars: ✭ 259 (+709.38%)
Mutual labels:  emacs, org-mode
Emacs.dz
Awesome emacs config files
Stars: ✭ 886 (+2668.75%)
Mutual labels:  configuration, emacs
Org Noter
Emacs document annotator, using Org-mode
Stars: ✭ 671 (+1996.88%)
Mutual labels:  emacs, org-mode
Org Superstar Mode
Make org-mode stars a little more super
Stars: ✭ 271 (+746.88%)
Mutual labels:  emacs, org-mode
Org Super Agenda
Supercharge your Org daily/weekly agenda by grouping items
Stars: ✭ 829 (+2490.63%)
Mutual labels:  emacs, org-mode
Org Transclusion
(alpha) Emacs package to enable transclusion with Org Mode
Stars: ✭ 251 (+684.38%)
Mutual labels:  emacs, org-mode
Org Wiki
Wiki for Emacs org-mode built on top of Emacs org-mode.
Stars: ✭ 319 (+896.88%)
Mutual labels:  emacs, org-mode
Org Projectile
Manage org-mode TODOs for your projectile projects
Stars: ✭ 259 (+709.38%)
Mutual labels:  emacs, org-mode
Org Roam Server
A Web Application to Visualize the Org-Roam Database
Stars: ✭ 443 (+1284.38%)
Mutual labels:  emacs, org-mode
ox-ssh
SSH config export for org-mode
Stars: ✭ 33 (+3.13%)
Mutual labels:  configuration, org-mode
org-starter
Configure files and directories in Org mode more easily
Stars: ✭ 73 (+128.13%)
Mutual labels:  configuration, org-mode
Ox Hugo
A carefully crafted Org exporter back-end for Hugo
Stars: ✭ 591 (+1746.88%)
Mutual labels:  emacs, org-mode
Org Ql
An Org-mode query language, including search commands and saved views
Stars: ✭ 721 (+2153.13%)
Mutual labels:  emacs, org-mode

#+TITLE: coldnew's emacs #+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 num:nil tags:nil #+SETUPFILE: assets/readtheorg.setup

#+LINK: emacs https://www.gnu.org/s/emacs #+LINK: spaceemacs https://github.com/syl20bnr/spacemacs

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-emacs][https://travis-ci.org/coldnew/coldnew-emacs.svg?branch=master]]

  • Introduction

This is my emacs configuration, which is based on top of [[spacemacs][Spacemacs]].

You may find I already have another emacs configuration in [[https://github.com/coldnew/coldnew-emacs][here]], the main difference between this configuration and [[https://github.com/coldnew/coldnew-emacs][coldnew-emacs]] is that this config is fully depends on [[spacemacs][Spacemacs]], which means I'll reuse most settings provided by [[spacemacs][spacemacs]].

** 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 maintain opensource packages, I always install latest version of emacs via following command:

#+BEGIN_SRC sh :tangle no

change --HEAD to --devel for current development version

brew install emacs --HEAD --use-git-head --with-cocoa --with-gnutls --with-rsvg --with-imagemagick brew linkapps #+END_SRC

*** 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_SRC sh :tangle no USE="X gtk3 inotify xft imagemagick" emerge app-editors/emacs #+END_SRC

*** Building with script

My emacs configuration already shipped an update-to-date version of emacs based on git submodule, if your system can build emacs from source you can use my [[file:scripts/build-emacs.sh]] script to build latested emacs.

#+BEGIN_EXAMPLE ./scripts/build-emacs.sh #+END_EXAMPLE

Note that if your are building under =Mac OSX=, don't forget to install xcode tools:

#+BEGIN_SRC sh :tangle no xcode-select --install #+END_SRC

** Install or testing this config

  • First use git to download whole repo

    : git clone https://github.com/coldnew/coldnew-emacs.git

  • Then use git submodule to download the spacemacs

    #+BEGIN_EXAMPLE git submodule update --init --recursive #+END_EXAMPLE

  • To generate the =init.el=, jut type

    : make

  • If you do not put this repo on =~/.emacs.d=, you need to use following command to start emacs

    : emacs -q -l ~/coldnew-emacs/init.el

** Packages need to be installed 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

In Mac OSX, I use [[http://brew.sh/][homebrew]] to install opensource packages.

#+BEGIN_SRC sh :tangle no :noweb yes #brew install fasd #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 :noweb yes #emerge app-shells/fasd #emerge app-shells/aspell <> #+END_SRC

*** All platform

Some package like =npm= use the same rule to install in any platform, here list what I need to install.

#+BEGIN_SRC sh :tangle no :noweb yes <> #+END_SRC

  • Initialize 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.

** Use lexical binding

For some of my functions, and general coolness, =lexical binding= is a must. Without it, closures cannot be made for example.

This line needs to appear at the beginning of the file to work. Just to keep things looking nice I put it at the beginning of the file.

#+BEGIN_SRC emacs-lisp :padline no ;; -- lexical-binding: t -- #+END_SRC ** Make Emacs-26 compatible with Emacs-25

Emacs 26 introduce new =switch= bytecode which not contains in emacs-25, disable it so I can test both emacs-25 and emacs-26.

#+BEGIN_SRC emacs-lisp (setq byte-compile-cond-use-jump-table nil) #+END_SRC

** Use Common Lisp Extension

Some of my function may need the Common Lisp Extension, let's import libraries first.

#+BEGIN_SRC emacs-lisp (require 'cl-lib) ; built-in #+END_SRC

** Load extra builtin library

Add some extry buildin library I will use in my config file.

#+BEGIN_SRC emacs-lisp (require 'find-lisp) #+END_SRC

** Prevent load outdated .elc files

Since emacs 24.4, new option =load-prefer-newer= has been introduce, which make me never accidentally using outdated compiled files.

#+BEGIN_SRC emacs-lisp (setq load-prefer-newer t) #+END_SRC

** Setup user-emacs-directory variable :variable:

In 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

** Setup user-cache-directory variable :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.") ;; create the `user-cache-directory' if not exists (make-directory user-cache-directory t) #+END_SRC ** Setup user-modules-directory variable :variable:

Setup the modules directory to store some submodules and extra packages.

#+BEGIN_SRC emacs-lisp (defconst user-modules-directory (file-name-as-directory (concat user-emacs-directory "modules")) "My emacs storage area for modules.") #+END_SRC

** Setup user-ramdisk-directory variable :variable:

I specify a ramdisk path to make my emacs can save som temporary file to it. The ramdisk path should be =~/ramdisk=, if the directory not found, use =/tmp= as fallback.

#+BEGIN_SRC emacs-lisp (defconst user-ramdisk-directory (let ( (user-ramdisk ; ~/ramdisk/ (concat (getenv "HOME") "/ramdisk/"))) ;; if ~/ramdisk/ exist, use it (if (file-exists-p user-ramdisk) user-ramdisk ;; fallcack to system default ramdisk dir temporary-file-directory)) "My ramdisk path in system.") #+END_SRC

** Setup Load path

The variable =load-path= lists all the directories where Emacs should look for emacs-lisp files.

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 maintain by cask or elpa or spacemacs, you can skip following code.

#+BEGIN_SRC emacs-lisp (eval-and-compile ;; Add directories to emacs's `load-path' recursively. ;; if path does not exist, try to create directory. (let* ((my-lisp-dir (list (concat user-emacs-directory "elpa/") ; package installed by package.el (concat user-emacs-directory "local-lisp/") ; local lisp I used (concat user-emacs-directory "styles/"))) ; themes I used (sys-lisp-dir (cl-ecase system-type ; add some system site-lisp to load-path ((darwin) '("/usr/local/share/emacs/site-lisp/")) ((gnu/linux) '("/usr/share/emacs/site-lisp/")) (t nil))) ; FIXME: Add more platform support (lisp-dir (append my-lisp-dir sys-lisp-dir))) (dolist (lisp-path lisp-dir) (when (not (file-exists-p lisp-path)) (make-directory lisp-path t)) (let* ((default-directory lisp-path)) (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

** Personal Information :personal:

Some information about myself.

#+BEGIN_SRC emacs-lisp (setq user-full-name "Yen-Chin, Lee") (setq user-mail-address "[email protected]") #+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=.

I also disable some keys like =⌘-h= bypass to system in emacs-mac port.

#+BEGIN_SRC emacs-lisp (when (eq system-type 'darwin) (setq mac-option-modifier 'super) (setq mac-command-modifier 'meta)) #+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 ** Loading Modules

I think I'll write some dynamic module extension, which will save to =~/.emacs.d/modules=, use a helper script to help me load them.

#+BEGIN_SRC emacs-lisp ;; load the `load-modules.el' file which help me load external modulept (let ((script (concat user-modules-directory "load-modules.el"))) (when (file-exists-p script) (load script))) #+END_SRC

** Startup emacs server

Only start server mode if I'm not root

#+BEGIN_SRC emacs-lisp (unless (string-equal "root" (getenv "USER")) (require 'server) (unless (server-running-p) (server-start))) #+END_SRC

** Setup backup files

By default Emacs saves =BackupFiles= under the original name with a tilde == appended. Example: Editing README will result in README and README in the same directory.

This is primitive and boring.

I save my backup files to =~/.emacs.d/.cache/backup= and since is always ignore by version control system, it's a nice place to store backup files.

#+BEGIN_SRC emacs-lisp (let ((backup-dir (concat user-cache-directory "backup"))) ;; Move backup file to ~/.emacs.d/.cache/backup' (setq backup-directory-alist(("." . ,backup-dir))) ;; Makesure backup directory exist (when (not (file-exists-p backup-dir)) (make-directory backup-dir t))) #+END_SRC

Also setup some backup settings.

#+BEGIN_SRC emacs-lisp (setq delete-by-moving-to-trash nil) (setq version-control t) (setq kept-old-versions 10) (setq kept-new-versions 20) (setq delete-old-versions t) (setq backup-by-copying t) #+END_SRC

** Disable some default stuff

Some emacs feature is not really useful

*** Turn-off Alarm Bell

#+BEGIN_SRC emacs-lisp (setq ring-bell-function #'ignore) #+END_SRC

*** Clean scratch buffer messages

Leave me a clean scratch buffer and I'll be more happy :)

#+BEGIN_SRC emacs-lisp (setq initial-scratch-message "") #+END_SRC

*** Use visible bell instead of buzzer

#+BEGIN_SRC emacs-lisp (setq visible-bell t) #+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

** Method to load secret file :function:

Some of my password stored in a secret file with gnupg encrypt, I add this function here so I can inject some emacs-command which hass password/account setting.

#+BEGIN_SRC emacs-lisp (defun my/load-secret () "Load my secret setting include password... etc." (let ((secret "~/.secret.el.gpg")) (when (file-exists-p secret) (load-file secret)))) #+END_SRC

  • Package Management

The main package manager I use is emacs's =package.el=, it's really nice and easy to use.

** Add my extra package list

[[http://melpa.org][melpa]] contains many community packages that not contribute to emacs's elpa, we add it here.

I also add [[http://orgmode.org/elpa.html][org-mode elpa]] so I can use latest org-mode.

#+BEGIN_SRC emacs-lisp (eval-and-compile (require 'package) ; built-in

;; melpa
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/") t)

;; org
(add-to-list 'package-archives
             '("org" . "http://orgmode.org/elpa/") t)

;; For important compatibility libraries like cl-lib
(when (< emacs-major-version 24)
  (add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/"))))

#+END_SRC

** Initialize package.el

Before we start to use =package.el=, we need to initialize it 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. (eval-and-compile (when (< emacs-major-version 27) (package-initialize))) #+END_SRC

** Install use-package

The =use-package= macro allows you to isolate package configuration in your =.emacs= file in a way that is both performance-oriented and, well, tidy. I created it because I have over 80 packages that I use in Emacs, and things were getting difficult to manage. Yet with this utility my total load time is around 2 seconds, with no loss of functionality!

GitHub: https://github.com/jwiegley/use-package

#+BEGIN_SRC emacs-lisp (eval-and-compile (unless (package-installed-p 'use-package) (package-refresh-contents) (package-install 'use-package))) ; Installed by packages.el #+END_SRC

use-package now can only need once, just add it to compile time

#+BEGIN_SRC emacs-lisp (eval-when-compile (require 'use-package)) #+END_SRC

You can setup =use-package-always-ensure= variable to =t= if you want to make =use-package= auto install packages.

However, since we need to initialize =spacemacs= first, we need to setup this variable after spacemacs init.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref spacemacs-later-init ;; make `use-package' auto install non-installed packages. (when (require 'use-package-ensure) (setq use-package-always-ensure t)) #+END_SRC

Report details about loading and configuration.

#+BEGIN_SRC emacs-lisp (setq use-package-verbose t) #+END_SRC

The =:ensure-system-package= keyword allows you to ensure system binaries exist alongside your package declarations. We need to install =use-package-ensure-system-package= first.

#+BEGIN_SRC emacs-lisp (use-package use-package-ensure-system-package :ensure t) #+END_SRC

** Install straight

straight.el is next-generation, purely functional package manager for the Emacs hacker. It can integrated with [[https://github.com/jwiegley/use-package][use-package]] and install some packages from fork.

GitHub: https://github.com/raxod502/straight.el

#+BEGIN_SRC emacs-lisp (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) (bootstrap-version 5)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) #+END_SRC

** Install paradox

Project for modernizing Emacs' Package Menu. With improved appearance, mode-line information. Github integration, customizability, asynchronous upgrading, and more.

GitHub: https://github.com/Malabarba/paradox

#+BEGIN_SRC emacs-lisp (use-package paradox :ensure t) #+END_SRC

** Install some common libraries

Some common libraries I'll use in my personal's command or anything else.

#+BEGIN_SRC emacs-lisp (use-package f :ensure t) (use-package s :ensure t) (use-package dash :ensure t) (use-package noflet :ensure t) (use-package htmlize :ensure t) (use-package async :ensure t) #+END_SRC

  • Languages and Encodings

Add UTF8 at the front of the priority list for automatic detection.

#+BEGIN_SRC emacs-lisp (prefer-coding-system 'utf-8) #+END_SRC

Set up multilingual environment to use UTF-8.

#+BEGIN_SRC emacs-lisp (set-language-environment "UTF-8") #+END_SRC

Set default value of various coding systems to UTF-8.

#+BEGIN_SRC emacs-lisp (set-default-coding-systems 'utf-8) #+END_SRC

Use =C= as locale for display time info (Actually it will display English).

#+BEGIN_SRC emacs-lisp (setq system-time-locale "C") #+END_SRC

  • Built-in Packages

Some buildin packages need to add extra setups for my emacs setting.

Most of them are the cache file, I'll move them to =~/.emacs.d/.cache= directory.

** abbrev

#+BEGIN_SRC emacs-lisp (eval-after-load 'bookmark '(progn (setq abbrev-file-name (concat user-cache-directory "abbrev_defs")))) #+END_SRC

** eshell

Move eshell cache dir to =~/.emacs.d/.cache/eshell=

#+BEGIN_SRC emacs-lisp (eval-after-load 'eshell '(progn (setq eshell-directory-name (concat user-cache-directory "eshell"))))

(eval-after-load 'em-hist '(progn (setq eshell-history-file-name (expand-file-name "history" eshell-directory-name)))) #+END_SRC

** bookmark

#+BEGIN_SRC emacs-lisp (eval-after-load 'bookmark '(progn (setq bookmark-default-file (concat user-cache-directory "bookmarks")))) #+END_SRC

** idlwave

Major mode for editing IDL source files.

#+BEGIN_SRC emacs-lisp (eval-after-load 'idlwave '(progn (setq idlwave-config-directory (concat user-cache-directory "idlwave")))) #+END_SRC

** srecode

#+BEGIN_SRC emacs-lisp ;; change srecode cache file path (eval-after-load 'srecode '(progn (setq srecode-map-save-file (concat user-cache-directory "srecode-map.el")))) #+END_SRC

** request

#+BEGIN_SRC emacs-lisp (eval-after-load 'request '(progn (setq request-storage-directory (concat user-cache-directory "request")))) #+END_SRC

** nsm

#+BEGIN_SRC emacs-lisp (eval-after-load 'nsm '(progn (setq nsm-settings-file (concat user-cache-directory "network-security.data")))) #+END_SRC

** url

#+BEGIN_SRC emacs-lisp (eval-after-load 'url '(progn (setq url-configuration-directory (file-name-as-directory (concat user-cache-directory "url"))))) #+END_SRC

** startup

#+BEGIN_SRC emacs-lisp (eval-after-load 'startup '(progn (setq auto-save-list-file-prefix (cond ((eq system-type 'ms-dos) ;; MS-DOS cannot have initial dot, and allows only 8.3 names (file-name-as-directory (concat user-cache-directory "auto-save.list/_s"))) (t (file-name-as-directory (concat user-cache-directory "auto-save-list/.saves-"))))))) #+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.

** ag

[[https://github.com/Wilfred/ag.el][ag.el]] allows you to search using [[https://github.com/ggreer/the_silver_searcher][the_silver_searcher]] from inside Emacs. You can filter by file type, edit results inline, or find files.

GitHub: https://github.com/Wilfred/ag.el

#+BEGIN_SRC emacs-lisp (use-package ag :ensure t ;; only use this package when `the_silver_seacher' install in system. :ensure-system-package ag) #+END_SRC

*** Install System packages

To use [[https://github.com/Wilfred/ag.el][ag.el]] we also need to install [[https://github.com/ggreer/the_silver_searcher][the_silver_searcher]] in system.

**** Mac OSX

It's recommand to use [[http://brew.sh/][homebrew]] to install [[https://github.com/ggreer/the_silver_searcher][the_silver_searcher]] under Mac OSX.

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install the_silver_searcher #+END_SRC

**** Gentoo Linux

If you use Gentoo Linux, you can use portage to install it.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-gentoo emerge sys-apps/the_silver_searcher #+END_SRC

** ascii-art-to-unicode

Convert simple ASCII art drawings (and org-tables) to beautiful Unicode.

#+BEGIN_SRC emacs-lisp (use-package ascii-art-to-unicode :ensure t) #+END_SRC ** avy

=avy= is a GNU Emacs package for jumping to visible text using a char-based decision tree. See also [[https://github.com/winterTTr/ace-jump-mode][ace-jump-mode]] and [[https://github.com/Lokaltog/vim-easymotion][vim-easymotion]] - =avy= uses the same idea.

GitHub: https://github.com/abo-abo/avy

#+BEGIN_SRC emacs-lisp (use-package avy :ensure t) #+END_SRC

** bpr

This package provides logic for async process execution.

It's similar to =async-shell-command=, but:

  • =bpr= spawns processes asynchronously without displaying output buffers.
  • =bpr= shows progress messages for running processes in echo area.
  • =bpr= can display buffer with process output in case of errors.
  • =bpr= can use projectile for assigning process directory.
  • =bpr= can format process output (understands ansi escape codes).
  • it's possible to set different options for different processes.

=bpr= is very handy for running tests/builds, but you can run any processes with it.

GitHub: https://github.com/ilya-babanov/emacs-bpr

#+BEGIN_SRC emacs-lisp (use-package bpr :ensure t) #+END_SRC

** buffer-move

This file is for lazy people wanting to swap buffers without typing C-x b on each window. This is useful when you have :

#+begin_quote :tangle no

  you  have this

+--------------+-------------+ +--------------+-------------+ | | | | | | | #emacs | #gnus | | #gnus | .emacs | | | | | | | +--------------+-------------+ +--------------+-------------+ | | | | | .emacs | | #emacs | | | | | +----------------------------+ +----------------------------+

                                           and you want to have this

#+end_quote

With buffer-move, just go in #gnus, do =buf-move-left=, go to #emacs (which now should be on top right) and do =buf-move-down=.

GitHub: https://github.com/lukhas/buffer-move

#+BEGIN_SRC emacs-lisp (use-package buffer-move :ensure t) #+END_SRC

** calfw

Calfw - A calendar framework for Emacs.

GitHub: https://github.com/kiwanami/emacs-calfw

#+BEGIN_SRC emacs-lisp (use-package calfw :ensure t) #+END_SRC ** cbm

Cycle by major - Cycle through buffers with the same major-mode.

GitHub: https://github.com/akermu/cbm.el

#+BEGIN_SRC emacs-lisp (use-package cbm :ensure t) #+END_SRC

** crux

A Collection of Ridiculously Useful eXtensions for Emacs. crux bundles a few useful interactive commands to enhance your overall Emacs experience.

GitHub: https://github.com/bbatsov/crux

#+BEGIN_SRC emacs-lisp (use-package crux :ensure t) #+END_SRC

** carbon-now-sh.el

[[https://carbon.now.sh/][carbon-now-sh]] is a service that creates beautiful images of your code:

#+BEGIN_SRC emacs-lisp (use-package carbon-now-sh :ensure t) #+END_SRC

** darkroom

Remove visual distractions and focus on writing.

GitHub: https://github.com/capitaomorte/darkroom

#+BEGIN_SRC emacs-lisp (use-package darkroom :ensure t) #+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.

GitHub: https://github.com/steckerhalter/discover-my-major

#+BEGIN_SRC emacs-lisp (use-package discover-my-major :ensure t) #+END_SRC

** doxymacs

Doxygen is a system for extracting documentation from source code. It supports a variety of programming languages, human languages and output formats. You can find it at http://www.doxygen.org.

[[http://doxymacs.sourceforge.net/][doxymacs]] is emacs's wrapper for Doxygen.

#+BEGIN_SRC emacs-lisp (when (require 'doxymacs nil 'noerror) (add-hook 'prog-mode-hook '(lambda () (doxymacs-mode)))) #+END_SRC

*** Install System Packages

To use [[http://doxymacs.sourceforge.net/][doxymacs]] we also need to install it in system manually.

**** Mac OSX

For Mac OSX, just type

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install doxymacs #+END_SRC

**** Gentoo Linux

If you use Gentoo Linux, you can use following command to install this package

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-gentoo emerge app-shells/doxymacs #+END_SRC

** 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.

GitHub: https://github.com/editorconfig/editorconfig-emacs

#+BEGIN_SRC emacs-lisp (use-package editorconfig :ensure t :init (add-hook 'prog-mode-hook (editorconfig-mode 1)) (add-hook 'text-mode-hook (editorconfig-mode 1))) #+END_SRC

*** Install System Packages

Download the [[https://github.com/editorconfig/editorconfig-core-c][EditorConfig C Core]] and follow the instructions in the README and INSTALL files to install it.

This plugin also has a core library implemented in Emacs-Lisp, and fallback to it when no core executable is found.

You also can use OS's package manager to install it

**** Mac OSX

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install editorconfig #+END_SRC

**** Gentoo Linux

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-gentoo emerge app-text/editorconfig-core-c #+END_SRC

** esup

Benchmark Emacs Startup time without ever leaving your Emacs.

GitHub: https://github.com/jschaf/esup

#+BEGIN_SRC emacs-lisp (use-package esup :ensure t) #+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.

GitHub: https://github.com/purcell/exec-path-from-shell

#+BEGIN_SRC emacs-lisp (use-package exec-path-from-shell :ensure t :config (when (memq window-system '(mac ns x)) (exec-path-from-shell-initialize))) #+END_SRC

** expand-region :keybinding:

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 (use-package expand-region :ensure t :bind (("M-v" . er/expand-region))) #+END_SRC

** fancy-narrow

Emacs package to immitate [[http://bruce-connor.github.io/emacs-online-documentation/Fun%252Fnarrow-to-region.html][narrow-to-region]] with more eye-candy.

GitHub: https://github.com/Malabarba/fancy-narrow

#+BEGIN_SRC emacs-lisp (use-package fancy-narrow :ensure t) #+END_SRC

** focus

Focus provides =focus-mode= that dims the text of surrounding sections, similar to [[https://ia.net/writer][iA Writer's]] Focus Mode.

GitHub: https://github.com/larstvei/Focus

#+BEGIN_SRC emacs-lisp (use-package focus :ensure t) #+END_SRC

** fontawesome

Emacs [[http://fortawesome.github.io/Font-Awesome/][fontawesome]] utility.

GitHub: https://github.com/syohex/emacs-fontawesome

#+BEGIN_SRC emacs-lisp (use-package fontawesome :ensure t) #+END_SRC

** google-translate

This package allows to translate the strings using Google Translate service directly from GNU Emacs.

GitHub: https://github.com/atykhonov/google-translate

#+BEGIN_SRC emacs-lisp (use-package google-translate :ensure t) #+END_SRC

** goto-last-change

Move point through buffer-undo-list positions.

GitHub: https://github.com/camdez/goto-last-change.el

#+BEGIN_SRC emacs-lisp (use-package goto-last-change :ensure t) #+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.

GitHub: https://github.com/atykhonov/emacs-howdoi

#+BEGIN_SRC emacs-lisp (use-package howdoi :ensure t) #+END_SRC

** htmlize

#+BEGIN_SRC emacs-lisp (use-package htmlize :ensure t) #+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 (use-package hungry-delete :ensure t :config (global-hungry-delete-mode)) #+END_SRC ** hydra :keybinding:

This is a package for GNU Emacs that can be used to tie related commands into a family of short bindings with a common prefix - a Hydra.

GitHub: https://github.com/abo-abo/hydra

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package hydra :ensure t :config <>) #+END_SRC

*** Window Management

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref hydra-config (defhydra hydra-window () " Movement^^ ^Split^ ^Switch^ ^Resize^

h ← _v_ertical _b_uffer q X← jx horizontal _f_ind files w X↓ kz undo _a_ce 1 e X↑ lZ reset _s_wap r X→ _F_ollow _D_lt Other _S_ave max_i_mize SPC cancel _o_nly this _d_elete " ("h" windmove-left ) ("j" windmove-down ) ("k" windmove-up ) ("l" windmove-right ) ("q" hydra-move-splitter-left) ("w" hydra-move-splitter-down) ("e" hydra-move-splitter-up) ("r" hydra-move-splitter-right) ("b" helm-mini) ("f" helm-find-files) ("F" follow-mode) ("a" (lambda () (interactive) (ace-window 1) (add-hook 'ace-window-end-once-hook 'hydra-window/body))) ("v" (lambda () (interactive) (split-window-right) (windmove-right))) ("x" (lambda () (interactive) (split-window-below) (windmove-down))) ("s" (lambda () (interactive) (ace-window 4) (add-hook 'ace-window-end-once-hook 'hydra-window/body))) ("S" save-buffer) ("d" delete-window) ("D" (lambda () (interactive) (ace-window 16) (add-hook 'ace-window-end-once-hook 'hydra-window/body))) ("o" delete-other-windows) ("i" ace-maximize-window) ("z" (progn (winner-undo) (setq this-command 'winner-undo))) ("Z" winner-redo) ("SPC" nil))

;;(global-set-key (kbd "C-x w") 'hydra-window/body) #+END_SRC

*** Buffer Movement

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref hydra-config (defhydra hydra-movement () " ^Forward^ ^Backward^ ^Up^ ^Down^ ^Char^ ^^^^^^^^--------------------------------------------------- c: char ^^^^^^^^ n: scroll down p: scroll up " ("c" avy-goto-char) ;; others ("n" evil-scroll-page-down) ("p" evil-scroll-page-up) ) #+END_SRC

** iedit :keybinding:

[[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 (use-package iedit :ensure t :bind (("C-;" . iedit-mode))) #+END_SRC

** know-your-http-well

HTTP encodings, headers, media types, methods, relations and status codes, all summarized and linking to their specification.

GitHub: https://github.com/for-GET/know-your-http-well

#+BEGIN_SRC emacs-lisp (use-package know-your-http-well :ensure t) #+END_SRC

** kurecolor

A collection of color tools aimed at those working with (normal 6 digit) hex color codes, useful for CSS, Emacs themes, etc. etc.

View the presentation at https://github.com/emacsfodder/kurecolor

GitHub: https://github.com/emacsfodder/kurecolor

#+BEGIN_SRC emacs-lisp (use-package kurecolor :ensure t) #+END_SRC

** link-hint

=link-hint.el= is inspired by the link hinting functionality in vim-like browsers and browser plugins such as pentadactyl. It provides commands for using avy to open or copy "links."

GitHub: https://github.com/noctuid/link-hint.el

#+BEGIN_SRC emacs-lisp (use-package link-hint :ensure t) #+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 (use-package manage-minor-mode :ensure t) #+END_SRC

** mustache

A mustache templating library in Emacs Lisp.

GitHub: https://github.com/Wilfred/mustache.el

#+BEGIN_SRC emacs-lisp (use-package mustache :ensure t) #+END_SRC

** mwim :keybinding:

This Emacs package provides commands for moving to the beginning/end of code or line.

GitHub: https://github.com/alezost/mwim.el

#+BEGIN_SRC emacs-lisp (use-package mwim :ensure t :bind (("C-a" . mwim-beginning-of-code-or-line) ("C-e" . mwim-end-of-code-or-line))) #+END_SRC

** noflet

=noflet= is dynamic, local, advice for Emacs-Lisp code.

=noflet= also has an Emacs indentation function for =flet= like macros.

It's great for test code when you need to mock another function.

This is useful for definining functions that overide a base definition in some way. You get access to the original (before you re-defined it) function through a different name.

GitHub: https://github.com/nicferrier/emacs-noflet

#+BEGIN_SRC emacs-lisp (use-package noflet :ensure t) #+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.

GitHub: https://github.com/coldnew/pangu-spacing

#+BEGIN_SRC emacs-lisp (use-package pangu-spacing :ensure t :config ;; start pangu-spacing globally (global-pangu-spacing-mode 1) ;; Always insert `real' space in org-mode. (add-hook 'org-mode-hook '(lambda () (set (make-local-variable 'pangu-spacing-real-insert-separtor) t)))) #+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.

GitHub: https://github.com/zargener/emacs-password-genarator

#+BEGIN_SRC emacs-lisp (use-package password-generator :ensure t) #+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 (use-package rainbow-mode :ensure t) #+END_SRC

** restclient

This is a tool to manually explore and test HTTP REST webservices. Runs queries from a plain-text query sheet, displays results as a pretty-printed XML, JSON and even images.

GitHub: https://github.com/pashky/restclient.el

#+BEGIN_SRC emacs-lisp (use-package restclient :ensure t) #+END_SRC

** reveal-in-osx-finder

  • If =M-x reveal-in-osx-finder= is invoked in a file-associated buffer, it will open the folder enclosing the file in the OS X Finder. It will also highlight the file the buffer is associated with within the folder.

  • If =M-x reveal-in-osx-finder= is invoked in a dired buffer, it will open the current folder in the OS X Finder. It will also highlight the file at point if available.

  • If =M-x reveal-in-osx-finder= is invoked in a buffer not associated with a file, it will open the folder defined in the default-directory variable.

GitHub: https://github.com/kaz-yos/reveal-in-osx-finder

#+BEGIN_SRC emacs-lisp (use-package reveal-in-osx-finder :ensure t :when (eq system-type 'darwin)) #+END_SRC

** sicp

Reading sicp in emacs.

#+BEGIN_SRC emacs-lisp (use-package sicp :ensure t) #+END_SRC

** smartparens

Smartparens is a minor mode for dealing with pairs in Emacs.

GitHub: https://github.com/Fuco1/smartparens

#+BEGIN_SRC emacs-lisp (use-package smartparens :ensure t :config (smartparens-mode 1)) #+END_SRC ** spray

A speed reading mode for Emacs.

GitHub: https://github.com/ian-kelling/spray

#+BEGIN_SRC emacs-lisp (use-package spray :ensure t) #+END_SRC

** sprunge

Upload pastes to http://sprunge.us/

GitHub: https://github.com/tomjakubowski/sprunge.el

#+BEGIN_SRC emacs-lisp (use-package sprunge :ensure t) #+END_SRC

** string-inflection

underscore -> UPCASE -> CamelCase conversion of names.

GitHub: https://github.com/akicho8/string-inflection

#+BEGIN_SRC emacs-lisp (use-package string-inflection :ensure 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 (use-package sx :ensure t) #+END_SRC

** tldr

tldr is a collection of simplified and community-driven man pages.

GitHub: https://github.com/kuanyui/tldr.el

#+BEGIN_SRC emacs-lisp (use-package tldr :ensure t :config (setq tldr-directory-path (concat user-cache-directory "tldr/")) (setq tldr-saved-zip-path (concat user-cache-directory "tldr-source.zip"))) #+END_SRC

** undo-tree

Standard Emacs undo is kind of confusing. [[http://www.dr-qubit.org/emacs.php#undo-tree][undo-tree]] replaces this with a simpler tree structure. It also allows us to visualize the tree directly.

GitHub: https://github.com/emacsmirror/undo-tree

#+BEGIN_SRC emacs-lisp (use-package undo-tree :ensure t :config ;; Persistent undo-tree history across emacs sessions (let ((dir (file-name-as-directory (concat user-cache-directory "undo-tree")))) (setq undo-tree-history-directory-alist `(("." . ,dir)))) ;; Make undo-tree save history (setq undo-tree-auto-save-history t) ;; global enable undo-tree (global-undo-tree-mode)) #+END_SRC

** url-shortener

This package can convert long url to tiny url and expand tiny url to long url ,support:

  • bit.ly
  • goo.gl
  • dwz.cn
  • 126.am

GitHub: https://github.com/yuyang0/url-shortener

#+BEGIN_SRC emacs-lisp (use-package url-shortener :ensure t) #+END_SRC

** verify-url

[[https://github.com/lujun9972/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 (use-package verify-url :ensure t) #+END_SRC

** visual-regexp

visual-regexp for Emacs is like replace-regexp, but with live visual feedback directly in the buffer. Check out [[https://github.com/benma/visual-regexp-steroids.el/][visual-regexp-steroids]] if you want to use modern regular expressions instead of Emacs-style regular expressions.

GitHub: https://github.com/benma/visual-regexp.el

#+BEGIN_SRC emacs-lisp (use-package visual-regexp :ensure t) #+END_SRC

** webpaste

webpaste.el allows to paste whole buffers or parts of buffers to pastebin-like services. It supports more than one service and will failover if one service fails. More services can easily be added over time and prefered services can easily be configured.

Supported platform:

  • [X] ix.io
  • [X] dpaste.com
  • [X] sprunge.us
  • [X] dpaste.de
  • [ ] paste.pound-python.org
  • [ ] paste.debian.net
  • [ ] bpaste.net

GitHub: https://github.com/etu/webpaste.el

#+BEGIN_SRC emacs-lisp (use-package webpaste :ensure t) #+END_SRC

** which-key

which-key is a minor mode for Emacs that displays the key bindings following your currently entered incomplete command (a prefix) in a popup. For example, after enabling the minor mode if you enter C-x and wait for the default of 1 second the minibuffer will expand with all of the available key bindings that follow C-x (or as many as space allows given your settings). This includes prefixes like C-x 8 which are shown in a different face. Screenshots of what the popup will look like are included below. which-key started as a rewrite of [[https://github.com/kai2nenobu/guide-key][gude-key-mode]], but the feature sets have diverged to a certain extent.

GitHub: https://github.com/justbur/emacs-which-key

#+BEGIN_SRC emacs-lisp (use-package which-key :ensure t :config ;; enable globally (which-key-mode) ;; Hide/Modify some function prefix in which-key show menu (setq which-key-replacement-alist '(("Prefix Command" . "prefix") ("which-key-show-next-page" . "wk next pg") ("\calc-" . "") ; Hide "calc-" prefixes when listing M-x calc keys ("/body\\'" . "") ; Remove display the "/body" portion of hydra fn names ("modi/" . "m/") ; The car is intentionally not "\\modi/" to cover ; cases like hydra-toggle/modi/..'. ("\\hydra-" . "+h/") ("\org-babel-" . "ob/") ("\\my/" . "")))) #+END_SRC

** zzz-to-char :keybinding:

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 (use-package zzz-to-char :ensure t :bind (("M-z" . 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.

All my =commands= starts with =my/= prefix.

** 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 my/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 my/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 my/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 my/untabify-buffer () (interactive) (save-excursion (untabify (point-min) (point-max)))) #+END_SRC

*** Indent whole buffer

#+BEGIN_SRC emacs-lisp (defun my/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 my/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 my/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 my/quick-folding-source () "Use emacs buildin easy to folding code." (interactive) (set-selective-display (if selective-display nil 1))) #+END_SRC

*** Narrowing to code more wisely

ref: http://endlessparentheses.com/emacs-narrow-or-widen-dwim.html

#+BEGIN_SRC emacs-lisp (defun my/narrow-or-widen-dwim (p) "Widen if buffer is narrowed, narrow-dwim otherwise. Dwim means: region, org-src-block, org-subtree, or defun, whichever applies first. Narrowing to org-src-block actually calls `org-edit-src-code'.

With prefix P, don't widen, just narrow even if buffer is already narrowed." (interactive "P") (declare (interactive-only)) (cond ((and (buffer-narrowed-p) (not p)) (widen)) ((region-active-p) (narrow-to-region (region-beginning) (region-end))) ;; org-mode ((and (boundp 'org-src-mode) org-src-mode (not p)) (org-edit-src-exit)) ((derived-mode-p 'org-mode) ;; `org-edit-src-code' is not a real narrowing ;; command. Remove this first conditional if you ;; don't want it. (cond ((ignore-errors (org-edit-src-code)) (delete-other-windows)) ((ignore-errors (org-narrow-to-block) t)) (t (org-narrow-to-subtree)))) ;; latex-mode ((derived-mode-p 'latex-mode) (LaTeX-narrow-to-environment)) (t (narrow-to-defun)))) #+END_SRC

*** Convert file format between DOS and UNIX

Some of my partner's file are in DOS format, so I need command to convert buffer between dos format and unix format.

#+begin_src emacs-lisp (defun my/dos2unix () "Convert buffer file from dos file to unix file." (interactive) (set-buffer-file-coding-system 'undecided-unix 't) ) #+end_src

#+begin_src emacs-lisp (defun my/unix2dos () "Convert buffer file from unix file to dos file." (interactive) (set-buffer-file-coding-system 'undecided-dos 't)) #+end_src

** Edit (Insert/Remove) :edit:

*** 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: United Nations]]

#+BEGIN_SRC emacs-lisp (defun my/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 my/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 my/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 my/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 my/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 my/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 my/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)) ;; special hack for some modes (cond ((derived-mode-p 'verilog-mode) (verilog-auto)) ) (message "Indented whole buffer and clear whitespace and untabify.")))))) #+END_SRC

*** Copy and comments

#+BEGIN_SRC emacs-lisp (defun my/copy-and-comment () "Copy region and comment it." (interactive) (kill-ring-save (region-beginning) (region-end)) (comment-dwim nil)) #+END_SRC

** File Handle :file:

*** Reopen file as root

#+BEGIN_SRC emacs-lisp (defun my/file-reopen-as-root () (interactive) (when buffer-file-name (find-alternate-file (concat "/sudo:[email protected]:" buffer-file-name)))) #+END_SRC

*** Delete current buffer file

#+BEGIN_SRC emacs-lisp (defun my/delete-current-buffer-file () "Remove file connected to current buffer and kill buffer." (interactive) (let ((filename (buffer-file-name)) (buffer (current-buffer))) (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 my/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 my/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 my/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

*** Show current buffer-file information

#+BEGIN_SRC emacs-lisp (defun my/file-info () "Show current buffer information." (interactive) (if (buffer-file-name (current-buffer)) (progn (let* ((file-name (buffer-file-name (current-buffer))) (f-attr (file-attributes file-name)) (f-size (nth 7 f-attr)) ; ファイルサイズ (f-mode (nth 8 f-attr)) ; ファイル属性 (mes1 (format "file path: %s\n" file-name)) (mes2 (format "file size: %s byte\n" f-size)) (mes3 (format "file type: %s" f-mode)) (mess (concat mes1 mes2 mes3))) (message "%s" mess))) nil)) #+END_SRC

** Debug :debug:

*** Eval emacs buffer until error

A really nice command help me to find error on elisp buffer.

#+BEGIN_SRC emacs-lisp (defun my/eval-buffer-until-error () "Evaluate emacs buffer until error occured." (interactive) (goto-char (point-min)) (while t (eval (read (current-buffer))))) #+END_SRC

*** Display face found at the current point

#+BEGIN_SRC emacs-lisp (defun my/what-face (pos) "Display face found at the current point." (interactive "d") (let ((face (or (get-char-property (point) 'read-face-name) (get-char-property (point) 'face)))) (if face (message "Face: %s" face) (message "No face at %d" pos)))) #+END_SRC

*** Reload emacs init config

#+BEGIN_SRC emacs-lisp (defun my/reload-init () "Reload init.el file" (interactive) (load-file user-init-file)) #+END_SRC

** Window :window:

*** Switch to other window or split it

If other window does not exist, split it, else switch to it.

#+BEGIN_SRC emacs-lisp (defun my/other-window-or-split () "Switch to other window or split it." (interactive) (when (one-window-p) (split-window-horizontally)) (other-window 1)) #+END_SRC

*** Swap left/right windows

If I have two windows at left/right position, this command can help me change left-window to right-window.

#+BEGIN_SRC emacs-lisp (defun my/swap-window-positions () "*Swap the positions of this window and the next one." (interactive) (let ((other-window (next-window (selected-window) 'no-minibuf))) (let ((other-window-buffer (window-buffer other-window)) (other-window-hscroll (window-hscroll other-window)) (other-window-point (window-point other-window)) (other-window-start (window-start other-window))) (set-window-buffer other-window (current-buffer)) (set-window-hscroll other-window (window-hscroll (selected-window))) (set-window-point other-window (point)) (set-window-start other-window (window-start (selected-window))) (set-window-buffer (selected-window) other-window-buffer) (set-window-hscroll (selected-window) other-window-hscroll) (set-window-point (selected-window) other-window-point) (set-window-start (selected-window) other-window-start)) (select-window other-window))) #+END_SRC

  • Styles :style:

My own emacs, my own style :)

** General Setups

Some emacs's default UI feature setup.

*** Turn-off menu bar

The menu bar is one of the UI elements which work best with mouses.

#+BEGIN_SRC emacs-lisp (when (featurep 'menu-bar) (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 (when (featurep 'tool-bar) (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 (when (featurep 'scroll-bar) (scroll-bar-mode -1)) #+END_SRC

*** Turn-off startup screen

I don't want to enter the startup screen after initialize emacs.

#+BEGIN_SRC emacs-lisp (setq inhibit-startup-screen t) #+END_SRC

** Theme

Before use emacs's =load-theme= function, I advise it to make 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)) #+END_SRC

I always want to customize everything on my own, so I build my own emacs theme called =night-coldnew= and =day-coldnew=, you can find them at styles dir.

  • [[file:styles/coldnew-theme.el]]

    Basic utils and macros to define coldnew-theme.

  • [[file:styles/day-coldnew-theme.el]]

    My day theme.

  • [[file:styles/night-coldnew-theme.el]]

    My night theme.

#+BEGIN_SRC emacs-lisp (require 'day-coldnew-theme) (require 'night-coldnew-theme) (load-theme 'night-coldnew t nil) ; default use `night-coldnew-theme' #+END_SRC

** mode-line

#+BEGIN_SRC emacs-lisp (require 'coldnew-modeline-config)

;; (use-package spaceline :ensure t)

;; (use-package spaceline-all-the-icons ;; :after spaceline ;; :config ;; (spaceline-all-the-icons-theme) ;; ;; ;; (setq spaceline-all-the-icons-separators-type 'slant)) #+END_SRC

#+BEGIN_SRC emacs-lisp :tangle no ;; (use-package spaceline :ensure t)

;; (use-package spaceline-all-the-icons ;; :after spaceline ;; :config ;; (spaceline-all-the-icons-theme) ;; ;; ;; (setq spaceline-all-the-icons-separators-type 'slant)) (require 'org-timer)

(defface mode-line-read-only-face '((t (:foreground "#C82829" :bold t))) "face for mode-name-string in modeline." :group 'mode-line)

(defface mode-line-modified-face '((t (:inherit 'font-lock-function-name-face :bolt t))) "face for mode-name-string in modeline." :group'mode-lin)

(defface mode-line-mode-name-face '((t (:inherit font-lock-keyword-face))) "face for mode-name-string in modeline." :group 'mode-line)

(defface font-lock-escape-char-face '((((class color)) (:foreground "seagreen2"))) "highlight c escapes char like vim" :group 'font-lock-faces)

(defun my/org-timer-modeline () "Show org-timer' info in my custom mode-line." (if (or org-timer-mode-line-timer org-timer-countdown-timer (org-at-item-timer-p) ) ;; -org-timer-value-string' ;; - org-timer-set-mode-line' ;; -org-timer-mode-line-string' (propertize (concat ;; (all-the-icons-material "alarm_on" :v-adjust 0.05) (format "%s" org-timer-mode-line-string)) 'face 'font-lock-function-name-face) ""))

(defun my/org-clock-modeline () "Show org-clock info." (when org-clock-idle-timer ;; get [0:05] from `org-clock-get-clock-string' (propertize (concat ;; (all-the-icons-octicon "clock" :v-adjust 0.05) "clock: " (propertize " " 'face 'variable-pitch) (format "%s" (org-minutes-to-clocksum-string (org-clock-get-clocked-time)))) 'face 'font-lick-exit-face))

;; org-clock-today (show current org clock)
;; NOTE: this time is doubled on `org-clock'.
;; (:eval
;;  (when (and (org-clock-is-active) (active))
;;    (list
;;     (propertize (format" ⏰%s"org-clock-today-string)
;;                 'face'(:foreground"cyan")))
;;    ))
)

;; update org-clock timer in mode-line after `org-clock-out-hook'. ;; fix org-clock timer does not disappear after clock out. (add-hook 'org-clock-out-hook '(lambda () ;; (org-clock-update-mode-line) (setq org-mode-line-string nil) (force-mode-line-update)))

(defun mode-line-buffer-permissions () "Get buffer-file permissions." (when (buffer-file-name) (format "-%04o-" (file-modes (buffer-file-name)))))

(defun mode-line-major-mode () "Get major-mode name with << >>." (concat "<< " (propertize mode-name 'face 'mode-line-mode-name-face) " >>"))

(setq-default mode-line-format '((" " mode-line-mule-info ;; read-only or modified status (:eval (cond (buffer-read-only (propertize "RO" 'face 'mode-line-read-only-face)) ((buffer-modified-p) (propertize "**" 'face 'mode-line-modified-face)) (t "--"))) " " ;; (when (featurep 'evil) ;; (:eval (evil-mode-string))) " " mode-line-buffer-identification " " ;; (:eval (mode-line-buffer-permissions)) " " ;; major-mode name (:eval (mode-line-major-mode)) " " (:eval (my/org-timer-modeline)) " " (:eval (my/org-clock-modeline)) " " ;; line and column "(" (:eval (propertize "%02l" 'face 'font-lock-type-face)) "," (:eval (propertize "%02c" 'face 'font-lock-type-face)) ")"

               "   "
               (vc-mode vc-mode)
               "   "

               ;; (org-timer-mode-line-timer
               ;;  (:eval (format "<fc=%s><%s></fc>"
               ;;                 (let ((time (abs (floor (org-timer-seconds)))))
               ;;                   (cond
               ;;                    ((< time 30) "#ef2929")
               ;;                    ((< time 60) "#f57900")
               ;;                    (t "#8cc4ff")))
               ;;                 (substring (org-timer-value-string) 0 -1))))
               "   "
               ;; relative position, size of file
               "["
               (:eval (propertize "%p" 'face 'font-lock-constant-face)) ;; % above top
               "/"
               (:eval (propertize "%I" 'face 'font-lock-constant-face)) ;; size
               "] "

               )))

(force-mode-line-update) #+END_SRC

  • TODO Fonts

#+BEGIN_SRC emacs-lisp (defvar my/emacs-english-font "Monaco" "The font name of English.")

(defvar my/emacs-cjk-font "Hiragino Sans GB" "The font name for CJK.")

(defvar my/emacs-font-size-pair '(13 . 16) "Default font size pair for (english . chinese)")

(defun my/font-exist-p (fontname) "Test if this font is exist or not. This function only work on GUI mode, on terminal it just return nil since you can't set font for emacs on it." (if (or (not fontname) (string= fontname "") (not (display-graphic-p))) nil (if (not (x-list-fonts fontname)) nil t)))

(defun my/set-font (english chinese size-pair) "Setup emacs English and Chinese font on x window-system."

(if (my/font-exist-p english)
    (set-frame-font (format "%s:pixelsize=%d" english (car size-pair)) t))

(if (my/font-exist-p chinese)
    (dolist (charset '(kana han cjk-misc bopomofo))
      (set-fontset-font (frame-parameter nil 'font) charset
                        (font-spec :family chinese :size (cdr size-pair))))))

;; Setup font size based on my/emacs-font-size-pair (my/set-font my/emacs-english-font my/emacs-cjk-font my/emacs-font-size-pair)

(defvar my/emacs-font-size-pair-list '(( 5 . 6) (10 . 12) (13 . 16) (15 . 18) (17 . 20) (19 . 22) (20 . 24) (21 . 26) (24 . 28) (26 . 32) (28 . 34) (30 . 36) (34 . 40) (36 . 44)) "This list is used to store matching (english . chinese) font-size.")

(defun my/emacs-step-font-size (step) "Increase/Decrease emacs's font size." (let ((scale-steps my/emacs-font-size-pair-list)) (if (< step 0) (setq scale-steps (reverse scale-steps))) (setq my/emacs-font-size-pair (or (cadr (member my/emacs-font-size-pair scale-steps)) my/emacs-font-size-pair)) (when my/emacs-font-size-pair (message "emacs font size set to %.1f" (car my/emacs-font-size-pair)) (my/set-font my/emacs-english-font my/emacs-cjk-font my/emacs-font-size-pair))))

(defun my/increase-emacs-font-size () "Decrease emacs's font-size acording emacs-font-size-pair-list." (interactive) (my/emacs-step-font-size 1))

(defun my/decrease-emacs-font-size () "Increase emacs's font-size acording emacs-font-size-pair-list." (interactive) (my/emacs-step-font-size -1)) #+END_SRC

** Setup Keybinds :keybinding:

#+BEGIN_SRC emacs-lisp (bind-keys :map global-map ("C-=" . my/increase-emacs-font-size) ("C--" . my/decrease-emacs-font-size)) #+END_SRC

  • Minibuffer :minibuffer:

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (when (require 'minibuffer) ; buildin <>) #+END_SRC

** Make cursor in minibufer use bar shape

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref minibuffer-config ;; only use `bar' type of cursor shape (add-hook 'minibuffer-setup-hook '(lambda () (setq cursor-type 'bar))) #+END_SRC

** Some helper function to let me insert quick in minibuffer

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref minibuffer-config ;; define some helper function to insert to minibuffer quickly (defun my/minibuffer-insert (p) (kill-line 0) (insert p))

(defun my/minibuffer-switch-to-ramdisk () "Insert ramdisk path according to system type" (interactive) (my/minibuffer-insert user-ramdisk-directory))

(defun my/minibuffer-switch-to-home () "Insert $HOME path." (interactive) (my/minibuffer-insert (file-name-as-directory (getenv "HOME"))))

(defun my/minibuffer-switch-to-rootdir () "Insert / path." (interactive) (my/minibuffer-insert "/"))

(defun my/minibuffer-switch-to-tramp () "Insert /ssh:." (interactive) (my/minibuffer-insert "/ssh:")) #+END_SRC

** Save history of minibuffer :tangle no :noweb-ref minibuffer-config

When Savehist mode is enabled, minibuffer history is saved periodically and when exiting Emacs. When Savehist mode is enabled for the first time in an Emacs session, it loads the previous minibuffer history from ‘savehist-file’.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref minibuffer-config (use-package savehist :config (setq savehist-file (concat user-cache-directory "savehist.dat")) (savehist-mode 1)) #+END_SRC

** Increase Garbage Collector Value in minibuffer

By binding this temporarily to a large number, you can effectively prevent garbage collection during a part of the program. I increase the value when enter minibuffer, this will help to improve minibuffer speed with large package like helm, flx.

ref: http://bling.github.io/blog/2016/01/18/why-are-you-changing-gc-cons-threshold/

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref minibuffer-config (eval-after-load 'minibuffer '(progn (lexical-let ((default-threshold gc-cons-threshold)) (defun my/minibuffer-gc-setup-hook () (setq gc-cons-threshold most-positive-fixnum)) (add-hook 'minibuffer-setup-hook #'my/minibuffer-gc-setup-hook) ;; When exit, set back to default threshold (defun my/minibuffer-gc-exit-hook () (setq gc-cons-threshold default-threshold)) (add-hook 'minibuffer-exit-hook #'my/minibuffer-gc-exit-hook)))) #+END_SRC

** Setup Keybindings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref minibuffer-config (bind-keys :map minibuffer-local-map ("C-w" . backward-kill-word) ("M-p" . previous-history-element) ("M-n" . next-history-element) ("C-g" . minibuffer-keyboard-quit) ("M-t" . my/minibuffer-switch-to-ramdisk) ("M-h" . my/minibuffer-switch-to-home) ("M-/" . my/minibuffer-switch-to-rootdir) ("M-s" . my/minibuffer-switch-to-tramp)) #+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 (use-package evil :ensure t :config ;; enable evil-mode globally (evil-mode t) ;; some configs setup later <> ;; extra keybindings defined in `Keybinding' section <> <>) #+END_SRC

** Setup default state to insert-state

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-config ;; default state set to insert-state (setq evil-default-state 'insert) #+END_SRC

** Make insert-state the same as emacs-state

To me, vim's insert state is useless, so I mapping all my emacs keybinding to insert-state.

First, bind all emacs-state key to insert state

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-config (setcdr evil-insert-state-map nil) (define-key evil-insert-state-map (read-kbd-macro evil-toggle-key) 'evil-emacs-state) #+END_SRC

Make sure =ESC= key in insert-state will call =evil-normal-state=.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-config (define-key evil-insert-state-map [escape] 'evil-normal-state) #+END_SRC

We also need to make all emacs-state buffer become to insert-state.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-config (dolist (m evil-emacs-state-modes) (add-to-list 'evil-insert-state-modes m)) #+END_SRC

** evil-leader

Evil Leader provides the == feature from Vim that provides an easy way to bind keys under a variable prefix key. For an experienced Emacs User it is nothing more than a convoluted key map, but for a Evil user coming from Vim it means an easier start.

GitHub: https://github.com/cofi/evil-leader

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package evil-leader :ensure t :after evil :config ;; enable evil-leader globally (global-evil-leader-mode) ;; extra keybindings defined in `Keybinding' section <> ) #+END_SRC

** evil-surround

This package emulates [[https://github.com/tpope/vim-surround][surround.vim by Tim Pope]]. The functionality is wrapped into a minor mode.

GitHub: https://github.com/timcharper/evil-surround

#+BEGIN_SRC emacs-lisp (use-package evil-surround :ensure t :after evil :config (global-evil-surround-mode 1)) #+END_SRC

** evil-quickscope

This package emulates [[https://github.com/unblevable/quick-scope][quick_scope.vim by Brian Le]]. It highlights targets for evil-mode’s f,F,t,T keys, allowing for quick navigation within a line with no additional mappings.

GitHub: https://github.com/blorbx/evil-quickscope

#+BEGIN_SRC emacs-lisp (use-package evil-quickscope :ensure t :after evil :config (add-hook 'prog-mode-hook 'turn-on-evil-quickscope-always-mode)) #+END_SRC

** Displays tildes in the fringe on empty lines a la Vi

GitHub: https://github.com/syohex/vi-tilde-fringe

#+BEGIN_SRC emacs-lisp (use-package vi-tilde-fringe :ensure t :if window-system :config (global-vi-tilde-fringe-mode)) #+END_SRC

** Make terminal support evil's cursor shape change

This package changing cursor shape and color by evil state for evil-mode.

Supported terminal: xterm, gnome-terminal, iTerm, konsole.

GitHub: https://github.com/7696122/evil-terminal-cursor-changer

#+BEGIN_SRC emacs-lisp (use-package evil-terminal-cursor-changer :ensure t :if (not (display-graphic-p)) ; Only use this package when in terminal :config ;; cursor shape setting (setq evil-motion-state-cursor 'box) ; █ (setq evil-visual-state-cursor 'box) ; █ (setq evil-normal-state-cursor 'box) ; █ (setq evil-insert-state-cursor 'bar) ; ⎸ (setq evil-emacs-state-cursor 'hbar) ; _ ;; enable this package (evil-terminal-cursor-changer-activate)) #+END_SRC

  • Editor :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.

** Create minor-mode to controll all keybindings :keybinding:

#+begin_src emacs-lisp (defvar my-editor-map (make-keymap))

(define-minor-mode my-editor-mode "My editor minor mode." :init-value t :keymap my-editor-map)

(define-globalized-minor-mode global-my-editor-mode my-editor-mode (lambda () (if (not (minibufferp (current-buffer))) (my-editor-mode 1))))

;; Gloabal enable (global-my-editor-mode t) #+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

** Disable lock file

I don't want emacs create some temporary file like =.#-emacs-a08196=, disable it.

#+BEGIN_SRC emacs-lisp ;; https://www.emacswiki.org/emacs/LockFiles (when (version<= "24.3" emacs-version) (setq create-lockfiles nil)) #+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.

see: http://editorconfig.org/

#+BEGIN_SRC emacs-lisp (use-package editorconfig :ensure t :if (executable-find "editorconfig") :mode ("\.editorconfig\'" . conf-unix-mode)) #+END_SRC

*** Install System Packages

To use [[https://editorconfig.org][editorconfig]] we also need to install it in system manually.

**** Mac OSX

For Mac OSX, just type

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install editorconfig #+END_SRC

**** Gentoo Linux

If you use Gentoo Linux, you can use following command to install this package

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-gentoo emerge app-text/editorconfig-core-c #+END_SRC

** En/Decrypt files by EasyPG

#+BEGIN_SRC emacs-lisp (require 'epa-file) ; part of emacs ;; Enable epa, so I can use gnupg in emacs to en/decrypt file (epa-file-enable) ;; Control whether or not to pop up the key selection dialog. (setq epa-file-select-keys 0) ;; Cache passphrase for symmetric encryption. (setq epa-file-cache-passphrase-for-symmetric-encryption t) #+END_SRC

*** Install gnupg to system

For Mac OSX, just type

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install gpg #+END_SRC

Most Linux already shipped with gnupg, if you use Gentoo Linux, you can use following command to install it

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-gentoo emerge app-crypt/gnupg #+END_SRC

In my system, I always use =gpg2= instead of =gpg1=.

*** Make pinentry show on mini-buffer

For me, when enter password on gpg encrypt file, I always want the password input prompt show on minibuffer, so I need to add more setup on the gnupg.

First, put this in =~/.gnupg/gpg-agent.conf=

#+BEGIN_SRC sh :tangle no allow-emacs-pinentry allow-loopback-pinentry

(optional) setup timeout

pinentry-timeout 3 #+END_SRC

Then tell gpg-agent to load this configuration with =gpgconf= in a shell:

: gpgconf --reload gpg-agent

In your emacs, put this epa setup:

#+BEGIN_SRC emacs-lisp (require 'epa) ; built-in (setq epa-pinentry-mode 'loopback) #+END_SRC

All things done, let's start the =pinentry server=:

#+BEGIN_SRC emacs-lisp (use-package pinentry :ensure t :config ;; Start the Pinentry service (pinentry-start)) #+END_SRC

** Remote file editing

#+BEGIN_SRC emacs-lisp (use-package tramp :ensure t :init (setq tramp-persistency-file-name (concat user-cache-directory "tramp")) :config (setq tramp-default-method "rsync")) #+END_SRC

** Line Numbers

In most case, I'll make line numers display globally by =linum=.

#+BEGIN_SRC emacs-lisp (if (version<= "26.1" emacs-version) ;; emacs 26.1 has display-line-number-mode, which is written in C (progn (require 'display-line-numbers) ;; Only use line number in `prog-mode-hook' (add-hook 'prog-mode-hook #'display-line-numbers-mode)) ;; for emacs version less than 26, use linum instead (use-package linum :ensure t :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 ;; disble some mode with linum (use-package linum-off :ensure t :config (setq linum-disabled-mode-list '(eshell-mode shell-mode term-mode erc-mode compilation-mode woman-mode w3m-mode calendar-mode org-mode)))

;; for emacs 26.1 or above, we use display-line-number-mode' instead (when (version<= "26.1" emacs-version) ;; NOTE: overwrite display-line-numbers--turn-on (defun display-line-numbers--turn-on () "Turn ondisplay-line-numbers-mode'." (unless (or (minibufferp) ;; taken from linum.el (and (daemonp) (null (frame-parameter nil 'client))) ;; take code from `linum-off' (member major-mode linum-disabled-modes-list)) (display-line-numbers-mode)))) #+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 (use-package rainbow-delimiters :ensure t :config (add-hook 'prog-mode-hook #'rainbow-delimiters-mode)) #+END_SRC

** Save recent file info

#+BEGIN_SRC emacs-lisp (use-package recentf :ensure t :init (setq recentf-save-file (expand-file-name "recentf" user-cache-directory)) :config (recentf-mode 1)) #+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 (use-package highlight-numbers :ensure t :config ;; json-mode has it's own highlight numbers method (add-hook 'prog-mode-hook '(lambda() (if (not (derived-mode-p 'json-mode)) (highlight-numbers-mode))))) #+END_SRC

** Highlight escape charset

GitHub: https://github.com/dgutov/highlight-escape-sequences

#+BEGIN_SRC emacs-lisp (use-package highlight-escape-sequences :ensure t :config ;; Make face the same as builtin face (put 'font-lock-regexp-grouping-backslash 'face-alias 'font-lock-builtin-face) ;; Enable globally (hes-mode 1)) #+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

** Show vertical lines to guide indentation

GitHub: https://github.com/zk-phi/indent-guide

#+BEGIN_SRC emacs-lisp (use-package indent-guide :ensure t :config ;; Only show indent-guide in idle-time. (setq indent-guide-delay 0.1)) #+END_SRC

** Visualization of matching parens

#+BEGIN_SRC emacs-lisp (show-paren-mode 1) (setq show-paren-delay 0) ; no delay #+END_SRC

** Adapt to foreign indentation offsets

An Emacs minor mode that guesses the indentation offset originally used for creating source code files and transparently adjusts the corresponding settings in Emacs, making it more convenient to edit foreign files.

GitHub: https://github.com/jscheid/dtrt-indent

#+BEGIN_SRC emacs-lisp (use-package dtrt-indent :ensure t :config ;; enable dtrt-indent-mode globally (dtrt-indent-mode 1)) #+END_SRC

** Intelligently call whitespace-cleanup on save

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 (use-package whitespace-cleanup-mode :ensure t :config (add-hook 'prog-mode-hook 'whitespace-cleanup-mode)) #+END_SRC

** Make Firefox can call Emacs to edit textarea

Want to edit Firefox's textarea in emacs ?

First, you need to install [[https://addons.mozilla.org/zh-TW/firefox/addon/edit-with-emacs1][Edit with Emacs]] on Firefox.

Then, in emacs, add following code to install

#+BEGIN_SRC emacs-lisp (use-package edit-server :ensure t :config (edit-server-start)) #+END_SRC

** Setup TABS

#+BEGIN_SRC emacs-lisp (setq tab-always-indent 'complete) #+END_SRC

** Highlight symbols with overlay

#+BEGIN_SRC emacs-lisp (use-package symbol-overlay :ensure t :config (add-hook 'prog-mode-hook #'symbol-overlay-mode) ;; (global-set-key (kbd "M-i") 'symbol-overlay-put) (define-key symbol-overlay-map (kbd "p") 'symbol-overlay-jump-prev) ;; 次のシンボルへ (define-key symbol-overlay-map (kbd "n") 'symbol-overlay-jump-next) ;; 前のシンボルへ (define-key symbol-overlay-map (kbd "C-g") 'symbol-overlay-remove-all) ;; ハイライトキャンセル ) #+END_SRC

** TODO Scrolling

ref: https://www.reddit.com/r/emacs/comments/8sw3r0/finally_scrolling_over_large_images_with_pixel/

#+BEGIN_SRC emacs-lisp (setq mouse-wheel-scroll-amount '(1)) ; Distance in pixel-resolution to scroll each mouse wheel event. (setq mouse-wheel-progressive-speed nil) ; Progressive speed is too fast for me. #+END_SRC

** Use god-mode for entering commands withoud modifier keys :keybinding:

This is a global minor mode for entering Emacs commands without modifier keys. It's similar to Vim's separation of commands and insertion mode.

GitHub: https://github.com/chrisdone/god-mode

#+BEGIN_SRC emacs-lisp (use-package god-mode :ensure t :bind ("M-o" . god-local-mode) :config (bind-keys :map god-local-mode-map ("z" . repeat) ("i" . god-local-mode))) #+END_SRC

  • Buffer :buffer: ** Create scratch automatically

Sometimes I'll clean the =scratch= buffer by kill it, add following function to let emacs re-create it automatically.

#+BEGIN_SRC emacs-lisp ;; Create scratch automatically (run-with-idle-timer 1 t '(lambda () (unless (get-buffer "scratch") (with-current-buffer (get-buffer-create "scratch") (lisp-interaction-mode))))) #+END_SRC

** Make buffer names unique

The library uniquify overrides Emacs' default mechanism for making buffer names unique (using suffixes like <2>, <3> etc.) with a more sensible behaviour which use parts of the file names to make the buffer names distinguishable.

For instance, buffers visiting =/tmp/Makefile= and =/projects/coldnew/Makefile= would be named =Makefile|tmp= and =Makefile|coldnew=, respectively (instead of =Makefile= and =Makefile<2>=).

#+BEGIN_SRC emacs-lisp (use-package uniquify :ensure nil ; built-in :config ;; starting separator for buffer name components (setq uniquify-separator " • ") ;; rerationalize buffer names after a buffer has been killed. (setq uniquify-after-kill-buffer-p t) ;; ignore non file buffers (setq uniquify-ignore-buffers-re "^\*")) #+END_SRC

  • Bookmarks

** Visible bookmarks in buffer

This package provides visible, buffer local, bookmarks and the ability to jump forward and backward to the next bookmark.

GitHub: https://github.com/joodland/bm

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package bm :ensure t :demand t

:init
;; restore on load (even before you require bm)
(setq bm-restore-repository-on-load t)

:config
;; Allow cross-buffer 'next'
(setq bm-cycle-all-buffers t)

;; where to store persistant files: `~/.emacs.d/.cache/bm-repository'
(setq bm-repository-file (concat user-cache-directory "bm-repository"))

;; save bookmarks
(setq-default bm-buffer-persistence t)

;; Loading the repository from file when on start up.
(add-hook' after-init-hook 'bm-repository-load)

;; Restoring bookmarks when on file find.
(add-hook 'find-file-hooks 'bm-buffer-restore)

;; Saving bookmarks
(add-hook 'kill-buffer-hook #'bm-buffer-save)

;; Saving the repository to file when on exit.
;; kill-buffer-hook is not called when Emacs is killed, so we
;; must save all bookmarks first.
(add-hook 'kill-emacs-hook #'(lambda nil
                               (bm-buffer-save-all)
                               (bm-repository-save)))

;; The `after-save-hook' is not necessary to use to achieve persistence,
;; but it makes the bookmark data in repository more in sync with the file
;; state.
(add-hook 'after-save-hook #'bm-buffer-save)

;; Restoring bookmarks
(add-hook 'find-file-hooks   #'bm-buffer-restore)
(add-hook 'after-revert-hook #'bm-buffer-restore)

;; The `after-revert-hook' is not necessary to use to achieve persistence,
;; but it makes the bookmark data in repository more in sync with the file
;; state. This hook might cause trouble when using packages
;; that automatically reverts the buffer (like vc after a check-in).
;; This can easily be avoided if the package provides a hook that is
;; called before the buffer is reverted (like `vc-before-checkin-hook').
;; Then new bookmarks can be saved before the buffer is reverted.
;; Make sure bookmarks is saved before check-in (and revert-buffer)
(add-hook 'vc-before-checkin-hook #'bm-buffer-save))

#+END_SRC

** Set up default registers

In emacs, there's a =jump-to-register (C-x r j)= command which can quickly switch to the file you setup.

For more info, you can refer to: [[https://www.emacswiki.org/emacs/Registers][EmacsWiki: Registers]]

#+BEGIN_SRC emacs-lisp (dolist (r `( ;; emacs's config.org (?e (file . "/.emacs.d/init.org")) ;; tasks: todo (?t (file . "/Org/tasks/todo.org")) ;; tasks: personal (?p (file . "/Org/tasks/personal.org")) ;; tasks: work (?w (file . "/Org/tasks/work.org")) ;; Offilce docs (?W (file . "/Org/Weintek/index.org")) ;; My personal note (?n (file . "/Org/Note.org")) ;; blogging ideas (?b (file . "/Org/blog.org")) ;; Finance (?f (file . "/Org/finance/personal.org")) )) (set-register (car r) (cadr r))) #+END_SRC

** Setup Keybinding :keybinding:

#+BEGIN_SRC emacs-lisp (bind-keys :map my-editor-map ("C-x n" . bm-next) ("C-x p" . bm-previous) ("C-x ." . bm-toggle)) #+END_SRC

  • Helm :helm:

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package helm :ensure t :config <>) #+END_SRC

** Install System packages

Since [[https://github.com/emacs-helm/helm][helm]] integrate some external tool like [[https://www.gnu.org/software/global/][gtags]], [[http://cscope.sourceforge.net/][cscope]] ...etc. We need to install these tools to our system.

*** Mac OSX

It's recommand to use [[http://brew.sh/][homebrew]] to install [[https://github.com/ggreer/the_silver_searcher][the_silver_searcher]] under Mac OSX.

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install global brew install cscope #+END_SRC

*** Gentoo Linux

If you use Gentoo Linux, you can use portage to install it.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-gentoo emerge dev-util/cscope emerge dev-util/global #+END_SRC

** Basic setup

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref helm-config ;; load default helm setup (require 'helm-config) ;; enable helm globally (helm-mode 1) #+END_SRC ** Use fuzzy match in helm

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref helm-config ;; Use fuzzy match in helm (setq helm-M-x-fuzzy-match t) (setq helm-buffers-fuzzy-matching t) (setq helm-recentf-fuzzy-match t) #+END_SRC

** Make helm can select anything even not match

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref helm-config ;; 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) #+END_SRC

** helm-bm

GitHub: https://github.com/yasuyk/helm-bm

#+BEGIN_SRC emacs-lisp (use-package helm-bm :ensure t :after (helm)) #+END_SRC

** helm-cscope

=helm-cscope.el= is a helm interface for xcscope.el. You can search cscope database and narrow selection using helm interface.

Helm-cscope shares most functions with xcscope.el. It just provide =M-x helm-cscope-find-= commands as helm version alternatives for =M-x cscope-find-=

GitHub: https://github.com/alpha22jp/helm-cscope.el

#+BEGIN_SRC emacs-lisp (use-package helm-cscope :ensure t :after (helm) :config (add-hook 'c-mode-common-hook 'helm-cscope-mode)) #+END_SRC

** helm-dash

This package uses [[http://www.kapeli.com/dash][Dash]] docsets inside emacs to browse documentation. Here's an article explaining the basic usage of it.

It doesn't require Dash app.

GitHub: https://github.com/areina/helm-dash

#+BEGIN_SRC emacs-lisp (use-package helm-dash :ensure t :after (helm)) #+END_SRC

** helm-gtags

=helm-gtags.el= is GNU GLOBAL helm interface.

GitHub: https://github.com/syohex/emacs-helm-gtags

#+BEGIN_SRC emacs-lisp (use-package helm-gtags :ensure t :after (helm) :config (setq helm-gtags-ignore-case t) (setq helm-gtags-auto-update t) (setq helm-gtags-use-input-at-cursor t) (setq helm-gtags-pulse-at-cursor t) ;; add to following modes (add-hook 'c-mode-hook #'helm-gtags-mode) (add-hook 'c++-mode-hook #'helm-gtags-mode)) #+END_SRC

** helm-projectile

GitHub: https://github.com/bbatsov/helm-projectile

#+BEGIN_SRC emacs-lisp (use-package helm-projectile :ensure t :after (helm projectile) :config ;; make projectile use helm as completion system (setq projectile-completion-system 'helm) ;; start helm-projectile (helm-projectile-on) ;; helm-projectile-find-file is really slow, use cache here (setq projectile-enable-caching t)) #+END_SRC

** helm-swoop

List match lines to another buffer, which is able to squeeze by any words you input. At the same time, the original buffer's cursor is jumping line to line according to moving up and down the line list.

GitHub: https://github.com/ShingoFukuyama/helm-swoop

#+BEGIN_SRC emacs-lisp (use-package helm-swoop :ensure t :after (helm)) #+END_SRC

** helm-c-yasnippet

GitHub: https://github.com/emacs-jp/helm-c-yasnippet

#+BEGIN_SRC emacs-lisp (use-package helm-c-yasnippet :ensure t :after (helm yasnippet) :config (setq helm-yas-space-match-any-greedy t)) #+END_SRC

** helm-smex

#+BEGIN_SRC emacs-lisp (use-package helm-smex :ensure t :after (helm)) #+END_SRC

** Setup Helm Keybindings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref helm-config (bind-keys :map helm-map ("TAB" . helm-execute-persistent-action) ("" . helm-execute-persistent-action) ("C-w" . backward-kill-word) ("M-t" . my/minibuffer-switch-to-ramdisk) ("M-h" . my/minibuffer-switch-to-home) ("M-/" . my/minibuffer-switch-to-rootdir) ("M-s" . my/minibuffer-switch-to-tramp) ("M-v" . my/minibuffer-switch-to-vm) ("M-c" . my/minibuffer-switch-to-cluster) ("C-z" . helm-select-action)) #+END_SRC

  • Language Server :lsp:

#+BEGIN_SRC emacs-lisp (use-package lsp-mode :ensure t :init (setq lsp-inhibit-message nil ; you may set this to t to hide messages from message area lsp-eldoc-render-all nil lsp-highlight-symbol-at-point nil) )

(use-package company-lsp :after company :ensure t :config (add-hook 'java-mode-hook (lambda () (push 'company-lsp company-backends))) (setq company-lsp-enable-snippet t company-lsp-cache-candidates t) ;; (push 'java-mode company-global-modes) )

(use-package lsp-ui :ensure t :config (setq lsp-ui-sideline-enable t lsp-ui-sideline-show-symbol t lsp-ui-sideline-show-hover t lsp-ui-sideline-show-code-actions t lsp-ui-sideline-update-mode 'point))

(use-package company-lsp :after company :ensure t :config (add-hook 'java-mode-hook (lambda () (push 'company-lsp company-backends))) (setq company-lsp-enable-snippet t company-lsp-cache-candidates t) ;; (push 'java-mode company-global-modes) )

(use-package lsp-java :ensure t :requires (lsp-ui-flycheck lsp-ui-sideline) :init (setq lsp-java-server-install-dir (concat user-cache-directory "eclipse.jdt.ls/server/")) :config (add-hook 'java-mode-hook 'lsp-java-enable) (add-hook 'java-mode-hook 'flycheck-mode) (add-hook 'java-mode-hook 'company-mode) (add-hook 'java-mode-hook (lambda () (lsp-ui-flycheck-enable t))) (add-hook 'java-mode-hook 'lsp-ui-sideline-mode) (setq lsp-java--workspace-folders (list "/home/coldnew/Projects/brokerBSreport" "/home/coldnew/Projects/twse-captcha-solverdl" "/home/coldnew/Projects/twse-captcha-solverdl2" ))

                                      ;(add-hook 'java-mode-hook (lambda () (add-to-list 'lsp-java--workspace-folders (lsp-java--get-root))))
)

(use-package meghanada :ensure t :init (setq meghanada-server-install-dir (concat user-cache-directory "meghanada")) :config (add-hook 'java-mode-hook (lambda () ;; meghanada-mode on (meghanada-mode t) (flycheck-mode +1) (setq c-basic-offset 2) ;; use code format (add-hook 'before-save-hook 'meghanada-code-beautify-before-save))) (cond ((eq system-type 'windows-nt) (setq meghanada-java-path (expand-file-name "bin/java.exe" (getenv "JAVA_HOME"))) (setq meghanada-maven-path "mvn.cmd")) (t (setq meghanada-java-path "java") (setq meghanada-maven-path "mvn")))

)

#+END_SRC

  • Org :org:

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package org :ensure nil ; built-in :mode (("\.org\'" . org-mode) ("\.org_archive\'" . org-mode)) :config (setq org-url-hexify-p nil) <>) #+END_SRC

** Basic setup

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config ;; fontify source code (setq org-src-fontify-natively t) ;; Use current window when switch to source block (setq org-src-window-setup 'current-window) ;; Disable prompting to evaluate babel blocks (setq org-confirm-babel-evaluate nil) ;; Disable add validation link when export to HTML (setq org-html-validation-link nil) #+END_SRC

*** Indention setup

Always enable auto indent for org-mode.

#+BEGIN_SRC emacs-lisp (use-package org-indent :ensure nil ; build-in :after (org) :config ;; Enable `org-indent-mode' by default (add-hook 'org-mode-hook '(lambda () (org-indent-mode t)))) #+END_SRC

*** Pretty Bullets

Show org-mode bullets as UTF-8 characters.

GitHub: https://github.com/sabof/org-bullets

#+BEGIN_SRC emacs-lisp (use-package org-bullets :ensure t :after (org) :config (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))) #+END_SRC

*** Setup TODO keywords

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (setq org-todo-keywords '((sequence "TODO(t)" "|" "DONE(d)") (sequence "WAITING(w)" "|") (sequence "|" "CANCELED(c)"))) #+END_SRC

*** Enable word-wrap

Call =visual-line-mode= to have soft-wrap.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (add-hook 'org-mode-hook #'visual-line-mode) #+END_SRC

** Extend org-mode's easy templates

org-mode make it easy to insert blocks by typing =<s[TAB]= ...etc. I defined some extra easy-templates I need to use here.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config ;; NOTE: ;; After org-mode 9.2, we need to require `org-tempo' module ;; to make easy-template work (when (not (version< (org-version) "9.2")) (require 'org-tempo))

(add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp")) (add-to-list 'org-structure-template-alist '("S" . "src sh")) (add-to-list 'org-structure-template-alist '("p" . "src plantuml :file uml.png")) #+END_SRC

** Extend babel support languages :babel:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (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) (shell . t) (plantuml . t) (R . t) (ledger . t) (clojure . t))) ;; make dot work as graphviz-dot (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 :tangle no :noweb-ref org-config (setq org-link-abbrev-alist '(("google" . "http://www.google.com/search?q=") ; ex: [[google:hi emacs]] ("google-map" . "http://maps.google.com/maps?q=%s") ; ex: [[google-map:taiwan]] ("wiki" . "https://en.wikipedia.org/wiki/%s") ; ex: [[wiki:emacs]] )) #+END_SRC

** Capture and Agenda

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config ;; 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-directory "~/Org/tasks") ;; U all .org files in `org-directory' (setq org-agenda-files (find-lisp-find-files org-directory ".org$")) ;; (setq org-default-notes-file (f-join org-directory "tasks" "TODO.org"))

;; Always use `C-g' to exit agenda (add-hook 'org-agenda-mode-hook '(lambda () (local-set-key (kbd "C-g") 'org-agenda-exit)))

;; Use speed command to quick navigating (setq org-use-speed-commands t) ;; Log timestamp when done (setq org-log-done 'time) (setq org-capture-templates '(("t" "TODO" entry (file+headline "" "Tasks") "* TODO %?\n %i\n") ("n" "NOTE" entry (file+headline "" "Tasks") "* NOTE %?\n %i\n %a") ("l" "Links" entry (file+headline "" "Links") "* TODO %? 🔗\nSCHEDULED: <%<%Y-%m-%d %a>>\n %i\n %a") ("j" "Journal" entry (file+datetree "" "Journal") "* %?\nEntered on %U\n %i\n %a") )) #+END_SRC

** Deft for Note-taking

#+BEGIN_SRC emacs-lisp (use-package deft :ensure t :config ;; default use org-mode (setq deft-default-extension "org") ;; default directory set to /Org (setq deft-directory "/Org") ;; Do not make deft automatically save file (setq deft-auto-save-interval 0) ;; Recursive search (setq deft-recursive t)

;; setup an minor-mode to quickly kill all deft buffers
(define-minor-mode deft-note-mode "Deft notes" nil " Deft-Notes" nil)
(setq deft-text-mode 'deft-note-mode)

;; Quickly kill deft buffers
(defun my/kill-all-deft-notes ()
  (interactive)
  (save-excursion
    (let ((count 0))
      (dolist (buffer (buffer-list))
        (set-buffer buffer)
        (when (not (eq nil deft-note-mode))
          (setq count (1+ count))
          (kill-buffer buffer))))))

;; Enable/Disable defts
(defun deft-or-close ()
  (interactive)
  (if (or (eq major-mode 'deft-mode) (not (eq nil deft-note-mode)))
      (progn (my/kill-all-deft-notes) (kill-buffer "*Deft*"))
      (deft)))

(defun my/deft-practice ()
  "Use deft to quickly see my blog drafts."
  (interactive)
  (let ((deft-directory "~/Workspace/practice")
        (deft-extensions '("md" "org"))))
  (deft)))

#+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 :tangle no :noweb-ref org-config (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

** Crypt contents in org-mode

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (use-package org-crypt :ensure nil :config ;; Disable auto-save-mode' for org-mode buffer prior to decrypting an entry. (setq org-crypt-disable-auto-save t) ;; Auto encrypt when save file (org-crypt-use-before-save-magic) ;; Encrypt with tagname:secret' (setq org-crypt-tag-matcher "secret") ;; Prevent the `secret' tag inherit by child ;; (The child item still will be encrypt) (setq org-tags-exclude-from-inheritance (quote ("secret"))) ;; Use my own password to encrypt (setq org-crypt-key nil)) #+END_SRC

** Drag-and-drop image to your org-mode file

[[https://github.com/abo-abo/org-download][org-download]] will let you drag-and-drop image to your org-mode file easily.

GitHub: https://github.com/abo-abo/org-download

#+BEGIN_SRC emacs-lisp (use-package org-download :ensure t :config ;; add support to dired (add-hook 'dired-mode-hook 'org-download-enable)) #+END_SRC

** Integrate with redmine

GitHub: https://github.com/gongo/org-redmine

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (use-package org-redmine :ensure t :config ;; NOTE: in personal private setting (setq org-redmine-uri nil) (setq org-redmine-auth-api-key nil) (setq org-redmine-auth-password nil) ; ;; Advice org-remine function so it will load my private config (defadvice org-redmine-get-issue (before load-password activate) (my/load-secret)) (defadvice org-redmine-anything-show-issue-all (before load-password activate) (my/load-secret))) #+END_SRC

** Latex exporter

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package ox-latex :ensure nil ; part of `org' package :after (org) :config (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 *** Use xelatex for pdf generated

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-latex-config (setq org-latex-pdf-process (if (executable-find "latexmk") '("latexmk -pdflatex=xelatex -pdf -8bit -silent --shell-escape -f %f") '("xelatex -8bit -interaction nonstopmode --shell-escape %f" "xelatex -8bit -interaction nonstopmode --shell-escape %f"))) #+END_SRC

*** Add minted support

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-latex-config (add-to-list 'org-latex-packages-alist '("" "minted")) (setq org-latex-listings 'minted) (setq org-latex-minted-options '(("frame" "lines") ("fontsize" "\scriptsize") ("linenos" "true"))) #+END_SRC *** Article class

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-latex-config ;; To use this, add following to your org-mode file ;; ;; #+LaTeX_CLASS: article ;; (add-to-list 'org-latex-classes '("article" "\documentclass[12pt,a4paper]{article} \usepackage[T1]{fontenc} \usepackage{fontspec} \usepackage{xeCJK} \setCJKmainfont{Hiragino Sans GB W3} \XeTeXlinebreaklocale "zh" \XeTeXlinebreakskip = 0pt plus 1pt \usepackage{graphicx} \usepackage{tikz} \usepackage[bookmarks=true,colorlinks,urlcolor=blue]{hyperref} \defaultfontfeatures{Mapping=tex-text} \setmonofont[Scale=0.8]{Monaco} \usepackage{geometry} \usepackage{minted} \usemintedstyle{emacs} \geometry{a4paper, textwidth=6.5in, textheight=8in, marginparsep=10pt, marginparwidth=.6in} \pagestyle{plain} \linespread{1.5} \title{} [NO-DEFAULT-PACKAGES] [NO-PACKAGES]" ("\section{%s}" . "\section*{%s}") ("\subsection{%s}" . "\subsection*{%s}") ("\subsubsection{%s}" . "\subsubsection*{%s}") ("\paragraph{%s}" . "\paragraph*{%s}") ("\subparagraph{%s}" . "\subparagraph*{%s}") )) #+END_SRC

** Textile exporter

An Org Mode Exporter Backend For Textile.

GitHub: https://github.com/yashi/org-textile

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package ox-textile :ensure t :after (org)) #+END_SRC

** reStructuredText (RST) exporter

reStructuredText Back-End for Org Export Engine.

GitHub: https://github.com/masayuko/ox-rst

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package ox-rst :ensure t :after (org)) #+END_SRC

** Setup Org-mode Keybindings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (bind-keys :map org-mode-map ("M-p" . org-previous-visible-heading) ("M-n" . org-next-visible-heading) ("C-c a" . org-agenda) ("C-c c" . org-capture) ("C-c l" . org-store-link) ("C-c b" . org-metaleft) ("C-c f" . org-metaright) ("C-c p" . org-metaup) ("C-c n" . org-metadown) ("C-c i" . org-insert-link) ("C-c I" . org-toggle-inline-images) ("C-c %" . org-mark-ring-push) ("C-c &" . org-mark-ring-goto) ("C-c C-." . org-babel-remove-result-one-or-many)) #+END_SRC

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (bind-keys :map org-src-mode-map ("C-c C-c" . org-edit-src-exit)) #+END_SRC

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref org-config (bind-keys :map org-mode-map :prefix-map my-org-mode-map :prefix "M-m" ("n" . my/narrow-or-widen-dwim)) #+END_SRC

  • Programming Languages

** Prolog

#+BEGIN_SRC emacs-lisp (use-package prolog :ensure nil ; built-in :mode ("\.pl\'") :config ;; Use gnu-prolog (setq prolog-system 'gnu) ) #+END_SRC

** PlantUML :plantuml:

GitHub: https://github.com/skuro/plantuml-mode

#+BEGIN_SRC emacs-lisp (use-package plantuml-mode :ensure t :mode ("\.plantuml\'") :init ;; FIXME: setup plantuml jar path ;; FIXME: add org-mode support ) #+END_SRC

** Bison

[[https://www.gnu.org/software/bison/][Bison]] s a general-purpose parser generator that converts an annotated context-free grammar into a deterministic LR or generalized LR (GLR) parser employing LALR(1) parser tables. As an experimental feature, Bison can also generate IELR(1) or canonical LR(1) parser tables. Once you are proficient with Bison, you can use it to develop a wide range of language parsers, from those used in simple desk calculators to complex programming languages.

Bison is upward compatible with Yacc: all properly-written Yacc grammars ought to work with Bison with no change. Anyone familiar with Yacc should be able to use Bison with little trouble. You need to be fluent in C or C++ programming in order to use Bison. Java is also supported as an experimental feature.

#+BEGIN_SRC emacs-lisp (use-package bison-mode :ensure t :mode ("\.y\'" "\.l\'" "\.jison\'")) #+END_SRC

** Brainfuck

[[https://en.wikipedia.org/wiki/Brainfuck][Brainfuck]] is an [[https://en.wikipedia.org/wiki/Esoteric_programming_language][esoteric programming language]] created in 1993 by Urban Müller, and notable for its extreme minimalism.

The language consists of only eight simple commands and an [[https://en.wikipedia.org/wiki/Instruction_pointer][instruction pointer]]. While it is fully [[https://en.wikipedia.org/wiki/Turing-complete][Turing-complete]], it is not intended for practical use, but to challenge and amuse [[https://en.wikipedia.org/wiki/Programmers][programmers]].

The language's name is a reference to the slang term "brain fuck", which refers to things so complicated or unusual that they exceed the limits of one's understanding.

#+BEGIN_SRC emacs-lisp (use-package brainfuck-mode :ensure t :mode "\.bf\'") #+END_SRC

** GN

#+BEGIN_SRC emacs-lisp (use-package gn-mode :ensure t :mode (("BUILD.gn" . gn-mode) ("\.gni?\'" . gn-mode))) #+END_SRC

** Markdown

[[https://en.wikipedia.org/wiki/Markdown][Markdown]] is a lightweight markup language with plain text formatting syntax designed so that it can be converted to HTML and many other formats using a tool by the same name. Markdown is often used to format readme files, for writing messages in online discussion forums, and to create rich text using a plain text editor.

Here I use [[http://jblevins.org/projects/markdown-mode/][markdown-mode]] to help me integrate markdown with emacs, the README.md is bind to =gfm-mode= for github's markdown flavor.

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package markdown-mode :ensure t :commands (markdown-mode gfm-mode) :mode (("README\.md\'" . gfm-mode) ("\.md\'" . markdown-mode) ("\.markdown\'" . markdown-mode)) :init (setq markdown-command "multimarkdown") :config <>) #+END_SRC

*** Syntax highlighting on code blocks

[[http://jblevins.org/log/mmm][Syntax highlighting for code blocks in Emacs Markdown Mode]] give us some hint to use =mmm-mode= syntax highlight code block on markdown-mode.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref markdown-config ;; http://jblevins.org/log/mmm (use-package mmm-mode :ensure t :config (setq mmm-global-mode 'maybe) (setq mmm-parse-when-idle 't) (defun my/mmm-markdown-auto-class (lang &optional submode) "Define a mmm-mode class for LANG in markdown-mode' using SUBMODE. If SUBMODE is not provided, useLANG-mode' by default." (let ((class (intern (concat "markdown-" lang))) (submode (or submode (intern (concat lang "-mode")))) (front (concat "^" lang "[\n\r]+")) (back "^")) (mmm-add-classes (list (list class :submode submode :front front :back back))) (mmm-add-mode-ext-class 'markdown-mode nil class)))

;; Mode names that derive directly from the language name
(mapc 'my/mmm-markdown-auto-class
      '("awk" "bibtex" "c" "cpp" "css" "html" "latex" "lisp" "makefile"
        "markdown" "python" "r" "ruby" "sql" "stata" "xml" "js")))

#+END_SRC

*** Setup Markdown keybinding :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref markdown-config (bind-keys :map markdown-mode-map ("C-c i" . markdown-insert-link))

(bind-keys :map gfm-mode-map ("C-c i" . markdown-insert-link)) #+END_SRC

** NASM

#+BEGIN_SRC emacs-lisp (use-package nasm-mode :ensure t) #+END_SRC

** TOML

[[https://github.com/toml-lang/toml][TOML]] aims to be a minimal configuration file format that's easy to read due to obvious semantics. TOML is designed to map unambiguously to a hash table. TOML should be easy to parse into data structures in a wide variety of languages.

#+BEGIN_SRC emacs-lisp (use-package toml-mode :ensure t :mode "\.toml$") #+END_SRC

** YAML

[[https://en.wikipedia.org/wiki/YAML][YAML]] is a human-readable data serialization language. It is commonly used for configuration files, but could be used in many applications where data is being stored (e.g. debugging output) or transmitted (e.g. document headers). YAML targets many of the same communications applications as XML, but has taken a more minimal approach which intentionally breaks compatibility with SGML.

#+BEGIN_SRC emacs-lisp (use-package yaml-mode :ensure t :mode "\.yml$") #+END_SRC

** R

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package ess :ensure t :mode ("\.[rR]\'" . R-mode) :config <>) #+END_SRC

** QML

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package qml-mode :ensure t :mode "\.qml$" :config <>) #+END_SRC

*** indent-guide

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref qml-config (use-package indent-guide :ensure t :config (add-hook 'qml-mode-hook #'indent-guide-mode)) #+END_SRC

** Vala :vala:

Vala is a new programming language that allows modern programming techniques to be used to write applications that run on the GNOME runtime libraries, particularly GLib and GObject.

For more info about vala, please see: [[https://wiki.gnome.org/Projects/Vala/Tutorial][Vala Tutorial]]

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package vala-mode :ensure t :mode ("\.vala\'" "\.vapi\'") :config <>) #+END_SRC

** Verilog :verilog:

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package verilog-mode :mode ("\.v\'") :config <>) #+END_SRC

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref verilog-config (setq verilog-linter "verilator --lint-only") ;; https://github.com/flycheck/flycheck/issues/1250 (setq flycheck-verilog-verilator-executable "/usr/bin/verilator_bin") #+END_SRC

  • Configration Files

Since emacs not built-in all configration files syntax highlight support, we need to install manually.

** Docker

#+BEGIN_SRC emacs-lisp (use-package dockerfile-mode :ensure t :mode "Dockerfile\'") #+END_SRC

** SSH

#+BEGIN_SRC emacs-lisp (use-package ssh-config-mode :ensure t :mode ((".ssh/config\'" . ssh-config-mode) ("sshd?_config\'" . ssh-config-mode) ("known_hosts\'" . ssh-known-hosts-mode) ("authorized_keys\'" . ssh-authorized-keys-mode))) #+END_SRC

** Systemd

#+BEGIN_SRC emacs-lisp (use-package systemd :ensure t) #+END_SRC

** CMake

#+BEGIN_SRC emacs-lisp (use-package cmake-mode :ensure t :mode (("CMakeLists\.txt\'" . cmake-mode) ("\.cmake\'" . cmake-mode))) #+END_SRC

#+BEGIN_SRC emacs-lisp ;; cmake-font-lock: emacs font lock rules for CMake ;; https://github.com/Lindydancer/cmake-font-lock (use-package cmake-font-lock :ensure t :config (autoload 'cmake-font-lock-activate "cmake-font-lock" nil t) (add-hook 'cmake-mode-hook 'cmake-font-lock-activate)) #+END_SRC

#+RESULTS: : t

** Meson

#+BEGIN_SRC emacs-lisp (use-package meson-mode :ensure t :mode (("meson\.build\'" . meson-mode))) #+END_SRC

  • C/C++ Development

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package cc-mode :mode (("\.h\'" . c-mode) ("\.c\'" . c-mode) ("\.hpp\'" . c++-mode) ("\.cpp\'" . c++-mode)) :config <>) #+END_SRC

** C/C++ headers detect

*** Use regexp to find header is C++ header or not

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref cc-mode-config (add-to-list 'magic-mode-alist `(,(lambda () (and (string= (file-name-extension (or (buffer-file-name) "")) "h") (or (re-search-forward "#include <\w+>" magic-mode-regexp-match-limit t) (re-search-forward "\W\(class\|template\namespace\)\W" magic-mode-regexp-match-limit t) (re-search-forward "std::" magic-mode-regexp-match-limit t)))) . c++-mode)) #+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 :tangle no :noweb-ref cc-mode-config ;; (use-package dummy-h-mode ;; :ensure t ;; :mode "\.h$" ;; :config ;; (add-hook 'dummy-h-mode-hook ;; (lambda () ;; ;; use c-mode by default ;; (setq dummy-h-mode-default-major-mode 'c-mode) ;; ;; setup search limit ;; (setq dummy-h-mode-search-limit 60000)))) #+END_SRC

** ElDoc supports :eldoc:

#+BEGIN_SRC emacs-lisp (use-package c-eldoc :ensure t :config (add-hook 'c-mode-common-hook '(lambda () (setq c-eldoc-includes "pkg-config --cflags --libs -I./ -I../") (c-turn-on-eldoc-mode)))) #+END_SRC

** Highlight a few dangerous types in C/C++

[[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 (use-package cwarn :config (add-hook 'c-mode-common-hook '(lambda () (cwarn-mode 1)))) #+END_SRC

** Comment #if 0 #endif region

#+BEGIN_SRC emacs-lisp (defun my/cc-mode/highlight-if-0 () "highlight c/c++ #if 0 #endif macros" (setq cpp-known-face 'default) (setq cpp-unknown-face 'default) (setq cpp-known-writable 't) (setq cpp-unknown-writable 't) (setq cpp-edit-list '(("0" '(foreground-color . "gray") default both) ("1" default font-lock-comment-face both))) (cpp-highlight-buffer t))

;; Add to c/c++ mode (defun my/cc-mode/highlight-if-0-hook () (when (or (eq major-mode 'c++-mode) (eq major-mode 'c-mode)) (my/cc-mode/highlight-if-0))) (add-hook 'after-save-hook #'my/cc-mode/highlight-if-0-hook) #+END_SRC

** Use subword-mode for C/C++ project

In most C/C++ project, we naming variable in camelCase, subword-mode can help us treat =helloWorld= as two words.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref cc-mode-config ;; subword-mode, e.g., someThing is treated as two words (add-hook 'c-mode-common-hook '(lambda () (subword-mode 1))) #+END_SRC

** Auto pair parentheses with electric-pair

#+BEGIN_SRC emacs-lisp (add-hook 'c-mode-common-hook 'electric-pair-mode) #+END_SRC

** Add refactor function support

Semantic Refactor is a C/C++ refactoring tool based on Semantic parser framework.

GitHub: https://github.com/tuhdo/semantic-refactor

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref cc-mode-config (use-package srefactor :ensure t) #+END_SRC

** 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 :tangle no :noweb-ref cc-mode-config (use-package cff :ensure t) #+END_SRC

** Extra Syntax Highlight

Some syntax highlight may not support in default emacs, set it here.

*** Highlights stdint types

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

*** Modern C++ ~ C++17 font-lock highlighting

#+BEGIN_SRC emacs-lisp ;; adds font-lock highlighting for modern C++ upto C++17 ;; https://github.com/ludwigpacifici/modern-cpp-font-lock (use-package modern-cpp-font-lock :ensure t :hook (c++-mode . modern-c++-font-lock-mode)) #+END_SRC

** Coding Styles

Since C/C++ has too many coding styles, I need to set it up.

*** C **** General C Coding Style

I always use =linux coding style= for c language by default.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref cc-mode-config (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

**** Linux Kernel C Coding Style

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 :tangle no :noweb-ref cc-mode-config (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 tab-width 8) (setq c-basic-offset 8) (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++

Use my C++ coding style.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref cc-mode-config (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

** Extra commands for c/c++ development

*** kill the function in one command

#+BEGIN_SRC emacs-lisp (defun my/c-kill-defun () "Move backward to the beging of top level declaration and save this declaration to the kill-ring." (interactive) (save-excursion (kill-region (progn (c-beginning-of-defun) (point)) (progn (c-end-of-defun) (point))))) #+END_SRC

*** Use clang-format to format buffer

#+BEGIN_SRC emacs-lisp ;; clang-format: format C/C++ buffers using clang-format ;; https://github.com/emacsorphanage/clang-format (use-package clang-format :ensure t) #+END_SRC

** Setup C/C++ Keybinding

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref cc-mode-config (bind-keys :map c-mode-base-map ;;("C-c '" . my/narrow-or-widen-dwim) ("C-c C-c" . compile) ("C-c C-g" . gdb) ("C-c C-o" . cff-find-other-file))

;; Some keys may override global map add here (bind-keys :map c-mode-base-map ("M-." . helm-gtags-dwim) ("M-," . helm-gtags-pop-stack)) #+END_SRC

  • Lisp Development

Though =LISP= has many dialet, it still is the best programming language I ever met.

** Emacs Lisp

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package elisp-mode :ensure nil ; built-in :config <>) #+END_SRC

*** Interactive macro-expander for Emacs

=macrostep= is an Emacs minor mode for interactively stepping through the expansion of macros in Emacs Lisp source code. It lets you see exactly what happens at each step of the expansion process by pretty-printing the expanded forms inline in the source buffer, which is temporarily read-only while macro expansions are visible. You can expand and collapse macro forms one step at a time, and evaluate or instrument the expansions for debugging with Edebug as normal (but see “Bugs and known limitations”, below). Single-stepping through the expansion is particularly useful for debugging macros that expand into another macro form. These can be difficult to debug with Emacs’ built-in macroexpand, which continues expansion until the top-level form is no longer a macro call.

GitHub: https://github.com/joddie/macrostep

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (use-package macrostep :ensure t) #+END_SRC

*** Additional flavour to emacs-lisp programming

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 :tangle no :noweb-ref emacs-lisp-mode-config (use-package el-spice :ensure t) #+END_SRC

*** Add eldoc support :eldoc:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (use-package eldoc :ensure t :config (add-hook 'emacs-lisp-mode-hook '(lambda () ;; enable eldoc (turn-on-eldoc-mode) ;; fix for paredit if exist (eval-after-load 'paredit '(progn (eldoc-add-command 'paredit-backward-delete 'paredit-close-round)))))) #+END_SRC

*** Check paren on save

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (defun my/elisp/check-parens-on-save () "Run `check-parens' when the current buffer is saved." (add-hook 'after-save-hook #'check-parens nil 'make-it-local))

(add-hook 'emacs-lis-mode (lambda () (my/emacs-lisp/enable-check-parens-on-save))) #+END_SRC

*** On-the-fly evaluation/substitution of emacs lisp code

[[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 :tangle no :noweb-ref emacs-lisp-mode-config (use-package litable :ensure t :config ;; Save cache file to `user-cache-direcotry' (setq litable-list-file (concat user-cache-directory ".litable-lists.el")) ;; Enable litable-mode globally (litable-mode)) #+END_SRC

*** Syntax highlighting for Emacs' cl-lib

This library adds all of the familiar highlighting to =cl-lib= macros =(cl-defun, cl-loop, etc.)= that were originally provided for =cl=.

It's not simply throwing in all the symbols as keywords. They're being added using the same regular expressions that =cl= gets, so function names get highlighted with =cl-defun=, type names get highlighted with =cl-defstruct=, etc.

GitHub: https://github.com/skeeto/cl-lib-highlight

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (use-package cl-lib-highlight :ensure t :config (cl-lib-highlight-initialize)) #+END_SRC

*** Display ^L glyphs as horizontal lines

This Emacs library provides a global mode which displays ugly form feed characters as tidy horizontal rules.

GitHub: https://github.com/purcell/page-break-lines

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (use-package page-break-lines :ensure t :config ;; enable globally (global-page-break-lines-mode 1)) #+END_SRC

*** Remove *.elc when save

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (defun my/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 'my/remove-elc-on-save) #+END_SRC

*** Shows keyboard macros or latest interactive commands as emacs lisp.

GitHub: https://github.com/Silex/elmacro

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (use-package elmacro :ensure t :config (elmacro-mode)) #+END_SRC

*** Setup Emacs-Lisp Keybindings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref emacs-lisp-mode-config (bind-keys :map emacs-lisp-mode-map ;; ("C-c '" . my/narrow-or-widen-dwim) ) #+END_SRC

** Clojure

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package clojure-mode :ensure t :config <>) #+END_SRC

*** Install Clojure's building system: Leinigen

We don't need to install [[https://clojure.org][Clojure]] to our system directly, we just install the building system: [[http://leiningen.org/][Leinigen]].

[[http://leiningen.org/][Leinigen]] is a tool to help you automating Clojure projects.

**** Install Leinigen

To install it, you need to download the [[https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein][lein script]] (on on Windows [[https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein.bat][lein.bat]]) to your system, I always put it on =~/bin= folder.

#+BEGIN_SRC sh :tangle no mkdir -p ~/bin wget https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein -O ~/bin/lein && chmod +x $_ #+END_SRC

Don't forget change =lein= to executable script (=chmod +x=) and makre sure you =~/bin= is in your =$PATH= environment variables.

#+BEGIN_SRC sh :tangle no export PATH="~/bin:$PATH" #+END_SRC

After all things done, we can use [[http://leiningen.org/][Leinigen]] to create our first Clojure project:

: lein new hellowrold

[[http://leiningen.org/][Leinigen]] will create a sample project with this directory structure

#+BEGIN_EXAMPLE :tangle no . ├── CHANGELOG.md ├── LICENSE ├── README.md ├── doc │   └── intro.md ├── project.clj ├── resources ├── src │   └── hellowrold │   └── core.clj └── test └── hellowrold └── core_test.clj

6 directories, 7 files #+END_EXAMPLE

Just modify the =src/hellowrold/core.clj= like this

#+BEGIN_SRC clojure :tangle no (ns hellowrold.core)

(defn -main [] (println "Hello Clojure!!!")) #+END_SRC

Then use =lein run -m hello.core= to execute our main function

#+BEGIN_SRC sh :tangle no lein run -m hello.core Hello, Clojure!!! #+END_SRC

YA! Our first Clojure project is work :).

**** Setup your leinigen profiles

After we install leinigen, we need to add =cider-nrepl= and =refactor-nrepl= to your lein profile.

Create =~/.lein/profiles.clj= with following content:

#+BEGIN_SRC clojure :tangle no {:repl {:plugins [[cider/cider-nrepl "0.10.0-SNAPSHOT"] [refactor-nrepl "2.0.0-SNAPSHOT"]] :dependencies [[alembic "0.3.2"] [org.clojure/tools.nrepl "0.2.12"]]}} #+END_SRC

*** Install Clojure's building system: boot

[[http://boot-clj.com/][Boot]] is another building tool for Clojure.

**** Install Boot

To install it, you need to download the [[https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh][boot script]] to your system, I always put it on =~/bin= folder.

#+BEGIN_SRC sh :tangle no mkdir -p ~/bin curl -fsSLo ~/bin/boot https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh && chmod +x $_ #+END_SRC

Don't forget change =lein= to executable script (=chmod +x=) and makre sure you =~/bin= is in your =$PATH= environment variables.

#+BEGIN_SRC sh :tangle no export PATH="~/bin:$PATH" #+END_SRC

Now we can use =boot repl= to start clojure's repl for test

#+BEGIN_SRC sh :tangle no boot repl #+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 :tangle no :noweb-ref clojure-config (use-package cider :ensure t :after clojure-mode :config

;; Enable eldoc in Clojure buffers
(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)

;; Make cider not prompt to save the corresponding file when loading a buffer.
(setq cider-prompt-save-file-on-load nil)

;; 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)

;; Make `cider-jack-in-clojurescript' directly connect with figwheel
;; https://github.com/bhauman/lein-figwheel/wiki/Using-the-Figwheel-REPL-within-NRepl#leiningen
(setq cider-cljs-lein-repl
      "(do (require 'figwheel-sidecar.repl-api)
           (figwheel-sidecar.repl-api/start-figwheel!)
           (figwheel-sidecar.repl-api/cljs-repl))"))

#+END_SRC

*** Add refactor function support

GitHub: https://github.com/clojure-emacs/clj-refactor.el

#+BEGIN_SRC emacs-lisp (use-package clj-refactor :ensure t :after clojure-mode :config ;; Add clj-refactor to clojure-mode (add-hook 'clojure-mode-hook '(lambda () (clj-refactor-mode 1))) ;; Use `C-c C-x' as prefix (cljr-add-keybindings-with-prefix "M-m")) #+END_SRC

*** Search on Clojars more easily

This Emacs extension allows you to search for projects on clojars.org and copies your selection to the kill ring in a format suitable for your =project.clj=.

GitHub: https://github.com/joshuamiller/clojars.el

#+BEGIN_SRC emacs-lisp (use-package clojars :ensure t) #+END_SRC

*** Pretty Symbols

Pretty symbols for anonymous functions, set literals and partial, like =(λ [a] (+ a 5))=, =ƒ(+ % 5)=, =∈{2 4 6}= and =Ƥ=.

#+BEGIN_SRC emacs-lisp (defun my/clojure/fancify-symbols (mode) "Pretty symbols for Clojure's anonymous functions and sets, like (λ [a] (+ a 5)), ƒ(+ % 5), and ∈{2 4 6}." (font-lock-add-keywords mode `(("(\(fn\)[[[:space:]]" (0 (progn (compose-region (match-beginning 1) (match-end 1) "λ")))) ("(\(partial\)[[[:space:]]" (0 (progn (compose-region (match-beginning 1) (match-end 1) "Ƥ")))) ("(\(comp\)[[[:space:]]" (0 (progn (compose-region (match-beginning 1) (match-end 1) "∘")))) ("\(#\)(" (0 (progn (compose-region (match-beginning 1) (match-end 1) "ƒ")))) ("\(#\){" (0 (progn (compose-region (match-beginning 1) (match-end 1) "∈")))))))

(dolist (m '(clojure-mode clojurescript-mode clojurec-mode clojurex-mode cider-repl-mode)) (my/clojure/fancify-symbols m)) #+END_SRC

*** Interactive Commands :command:

Some interactive commands for clojure-mode.

**** Send S-Expression and evaluate it there

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref clojure-config (defun my/cider-send-and-evaluate-sexp () "Sends the s-expression located before the point or the active region to the REPL and evaluates it. Then the Clojure buffer is activated as if nothing happened." (interactive) (if (not (region-active-p)) (cider-insert-last-sexp-in-repl) (cider-insert-in-repl (buffer-substring (region-beginning) (region-end)) nil)) (cider-switch-to-repl-buffer) (cider-repl-closing-return) (cider-switch-to-last-clojure-buffer) (message "")) #+END_SRC

*** Setup Clojure Keybindings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref clojure-config (bind-keys :map clojure-mode-map ;; M-m . refactor command ("C-c C-f" . projectile-find-file) ("C-c M-c" . cider-connect) ("C-c M-j" . cider-jack-in) ("C-c '" . my/narrow-or-widen-dwim) ("C-c h" . clojure-cheatsheet) ("C-c C-k" . cider-load-buffer) ("C-x C-e" . cider-eval-last-sexp) ("C-c C-v" . my/cider-send-and-evaluate-sexp) ("C-c C-t" . projectile-toggle-between-implementation-and-test)) #+END_SRC

  • Blogging

I now use [[https://hexo.io][Hexo]] with my fork of [[http://github.com/coldnew/hexo-renderer-org][hexo-renderer-org]] for blogging, [[http://github.com/kuanyui/hexo.el][hexo.el]] is a nice plugin to control hexo blog post in Emacs.

However, I use my fork of [[https://github.com/coldnew/hexo.el][hexo.el]] since threre's some feature I want to but not exist in upstream.

#+BEGIN_SRC emacs-lisp ;; Use my fork of hexo.el, save to `modules/hexo.el' (add-to-list 'load-path (directory-file-name (concat user-modules-directory "hexo.el"))) #+END_SRC

#+BEGIN_SRC emacs-lisp (use-package hexo :ensure t :config

(defun hexo-weintek-note ()
  "Office note taking with hexo."
  (interactive)
  (hexo "~/Workspace/weintek-note/"))

(defun hexo-my-blog ()
  "My blog with hexo."
  (interactive)
  (hexo "~/Workspace/blog/"))

(defun hexo-my-draft ()
  "My blog draft with hexo."
  (interactive)
  (hexo "~/Workspace/draft/"))

(defun hexo-my-draft ()
  "My blog with hexo."
  (interactive)
  (hexo "~/Workspace/draft/"))
)

#+END_SRC

  • Window Management :window:

** Maximized window after emacs start

#+BEGIN_SRC emacs-lisp (modify-all-frames-parameters '((fullscreen . maximized))) #+END_SRC

  • File Management :dired:

** Setup Keybindings :keybinding:

#+BEGIN_SRC emacs-lisp (bind-keys :map dired-mode-map ("r" . widred-change-to-wdired-mode)) #+END_SRC

  • Version Control

** Disable all vc-mode feature

Emacs's builtin =vc-mode= is not really useful, and will make emacs slow when edit file over =sshfs=.

I disable all setting handled by vc-mode here since I only use git and don't want vc-mode bother with other version control system.

#+BEGIN_SRC emacs-lisp (setq vc-handled-backends nil) #+END_SRC

** Git

Magit is an interface to the version control system [[http://git-scm.com/][Git]], implemented as an [[http://www.gnu.org/software/emacs][Emacs]] package. Magit aspires to be a complete Git porcelain. While we cannot (yet) claim that Magit wraps and improves upon each and every Git command, it is complete enough to allow even experienced Git users to perform almost all of their daily version control tasks directly from within Emacs. While many fine Git clients exist, only Magit and Git itself deserve to be called porcelains.

GitHub: https://github.com/magit/magit

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package magit :ensure t :config <>) #+END_SRC

*** Setup default commit arguments

I always add =sign-off= to the commit and make magit verbose.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref magit-config (setq magit-commit-arguments '("--verbose" "--signoff")) #+END_SRC

*** Enable diff-highlight

If you use git in command line, you can turn on diff-highlight by following command

#+BEGIN_SRC sh :tangle no git config --global core.pager "diff-highlight | less --tabs=4 -RFX" #+END_SRC

With magit, we can use =M-x magit-toggle-diff-refine-hunk= or make it enable by default:

#+BEGIN_SRC emacs-lisp (setq magit-diff-refine-hunk 'all) #+END_SRC

*** Add support for git configuration files

#+BEGIN_SRC emacs-lisp (use-package gitconfig-mode :ensure t :mode (("/\.?git/?config\'" . gitconfig-mode) ("/\.gitmodules\'" . gitconfig-mode) ("/_gitconfig\'" . gitconfig-mode)) :config (add-hook 'gitconfig-mode-hook 'flyspell-mode)) #+END_SRC

*** Add support for gitignore files

#+BEGIN_SRC emacs-lisp (use-package gitignore-mode :ensure t :mode (("/\.gitignore\'" . gitignore-mode) ("/\.git/info/exclude\'" . gitignore-mode) ("/git/ignore\'" . gitignore-mode))) #+END_SRC

*** Add GitGutter on fringe

GitHub: https://github.com/syohex/emacs-git-gutter-fringe

#+BEGIN_SRC emacs-lisp (use-package git-gutter-fringe :ensure t :if window-system ; git-gutter-fringe only work on GUI :config ;; enable globally (git-gutter-mode)) #+END_SRC

  • TODO Spelling Check

flyspell ? ref: https://www.reddit.com/r/emacs/comments/8rxm7h/tip_how_to_better_manage_your_spelling_mistakes/?utm_content=title&utm_medium=hot&utm_source=reddit&utm_name=emacs

#+BEGIN_SRC emacs-lisp (use-package ispell :ensure t :config (cond ;; aspell ((executable-find "aspell") (setq ispell-program-name "aspell" ispell-dictionary "en_US" ispell-really-aspell t ispell-really-hunspell nil)) ;; hunspell ((executable-find "hunspell") (setq ispell-program-name "hunspell" ispell-really-aspell nil ispell-really-hunspell t))) ;; TODO: make flyspell recognize camel case ;; (add-hook 'prog-mode-hook 'flyspell-prog-mode) ;; (setq ispell-program-name "aspell") ;; (setq ispell-extra-args '("--sug-mode=ultra" "--lang=en_US" "--run-together" "--run-together-limit=5" "--run-together-min=2")) ) #+END_SRC

  • TODO abbrev

#+BEGIN_SRC emacs-lisp (use-package abbrev :defer 1 :ensure nil :custom (abbrev-file-name (concat user-cache-directory "abbrev_defs")) (abbrev-mode 1) :config (when (file-exists-p abbrev-file-name) (quietly-read-abbrev-file))) #+END_SRC

  • IDE Features

emacs has some IDE feature, add here.

** projectile

=Projectile= is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies(when feasible). For instance - finding project files has a portable implementation written in pure Emacs Lisp without the use of GNU find (but for performance sake an indexing mechanism backed by external commands exists as well).

GitHub: https://github.com/bbatsov/projectile

#+BEGIN_SRC emacs-lisp (use-package projectile :ensure t :config ;; FIX hange issue with tramp ;; see: https://github.com/bbatsov/prelude/issues/594 ;; (projectile-global-mode) (add-hook 'text-mode-hook 'projectile-mode) (add-hook 'prog-mode-hook 'projectile-mode) ;; save projectile-known-projects-file in cache folder (setq projectile-known-projects-file (concat user-cache-directory "projectile-bookmarks.eld")) (setq projectile-cache-file (concat user-cache-directory "projectile.cache")) ;; Enable projectile globally (projectile-global-mode)) #+END_SRC

*** Setup Keybindings :keinbinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-keybindings (evil-define-key 'insert my-editor-map (kbd "M-p f") 'projectile-find-file (kbd "M-p a") 'projectile-ag (kbd "M-p g") 'projectile-grep (kbd "M-p s") 'projectile-run-eshell) #+END_SRC

** semantic

#+BEGIN_SRC emacs-lisp (use-package semantic :ensure t :config (setq semanticdb-default-save-directory (concat user-cache-directory "semanticdb/"))

(global-semanticdb-minor-mode 1)
(global-semantic-idle-scheduler-mode 1)

(semantic-mode 1))

#+END_SRC

** GDB

#+BEGIN_SRC emacs-lisp (when (require 'gdb-mi) ;; Use many window in gdb (setq gdb-many-windows t) ;; Display source file containing the main routine at startup. ;; Also display the main routine in the disassembly buffer if present. (setq gdb-show-main t)) #+END_SRC

** realgud

A modular GNU Emacs front-end for interacting with external debuggers.

See https://github.com/rocky/emacs-dbgr/wiki/Debuggers-Supported for a list of debuggers supported.

A debugger can be run out of a comint process buffer, or you can use a =M-x realgud-track-mode= inside an existing shell, or eshell buffer.

GitHub: https://github.com/rocky/emacs-dbgr

#+BEGIN_SRC emacs-lisp (use-package realgud :ensure t) #+END_SRC

** cscope

#+BEGIN_SRC emacs-lisp (use-package xcscope :ensure t :config ;; Use gtas's cscope command (setq cscope-program "gtags-cscope") ;; basic setup (cscope-setup)) #+END_SRC

** flycheck

#+BEGIN_SRC emacs-lisp (use-package flycheck :ensure t :config ;; enable globally (global-flycheck-mode)) #+END_SRC

  • Completion :company:completion:

[[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.

GitHub: https://github.com/company-mode/company-mode

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package company :ensure t :config ;; enable globally (global-company-mode 1) ;; Do not show company menu until I trigger it (setq company-idle-delay nil) ;; some configuration add here by noweb <> ) #+END_SRC

** Completion C/C++ headers

#+BEGIN_SRC emacs-lisp (use-package company-c-headers :ensure t :after (company) :config (add-to-list 'company-backends 'company-c-headers)) #+END_SRC

** Fuzzy matching for company

#+BEGIN_SRC emacs-lisp (use-package company-flx :ensure t :after (company) :config (company-flx-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 (use-package company-statistics :ensure t :after (company) :config ;; save cache file to `user-cache-directory' (setq company-statistics-file (concat user-cache-directory "company-statistics-cache.el")) ;; start company-statictics-mode after init (add-hook 'after-init-hook 'company-statistics-mode)) #+END_SRC

** Documentation popup for company-mode

#+BEGIN_SRC emacs-lisp (use-package company-quickhelp :ensure t :after (company) :init (company-quickhelp-mode 1)) #+END_SRC

** Add icons support

Make company-mode more fancy with icons.

GitHub: https://github.com/sebastiencs/company-box

#+BEGIN_SRC emacs-lisp ;; NOTE: This package required emacs 26 (when (version<= "26.0" emacs-version) (use-package company-box :ensure t :after (company) :hook (company-mode . company-box-mode))) #+END_SRC

** Setup keybindings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref company-config (bind-keys :map company-active-map ("C-g" . company-abort) ("C-n" . company-select-next) ("C-s" . company-filter-candidates) ("C-p" . company-select-previous) ("TAB" . company-complete-selction) ("" . company-complete-selction))

(bind-keys :map company-search-map ("C-n" . company-select-next) ("C-p" . company-select-previous)) #+END_SRC

  • COMMENT YouCompleteMe :ycmd:

[[https://github.com/Valloric/ycmd][ycmd]] is a server that provides APIs for code-completion and other code-comprehension use-cases like semantic GoTo commands (and others). For certain filetypes, ycmd can also provide diagnostic errors and warnings.

** Building

My [[https://github.com/Valloric/ycmd][ycmd]] is cloned to =~/.emacs.d/modules/ycmd=, just run following command to build the ycmd server.

: ./build.py --all

** Generate .ycm_extra_conf.py for C/C++ project

[[https://github.com/Valloric/ycmd][ycmd]] looks for a =.ycmd_extra_conf.py= file in the directory of the opened file or in any directory setting in =ycmd-extra-conf-whitelist=, I use [[https://github.com/rdnetto/YCM-Generator][YCM-Generator]] to help me generate the config file.

#+BEGIN_SRC emacs-lisp (defun my/ycmd-generate-conf () "Generate .ycmd_extra_conf.py' for your project. Ths YCM-Generator is locate in~/.emacs.d/modules/YCM-Generator'." (interactive) (let* ((cmdfile (concat user-emacs-directory "modules/YCM-Generator/config_gen.py")) (proot (if (fboundp 'projectile-project-root) (projectile-project-root) (file-name-directory buffer-file-name))) (proot-ask (read-from-minibuffer "Project Directory: " proot)) (proc-buff (get-buffer-create"ycm-generator")))

  (with-current-buffer proc-buff
    (buffer-disable-undo proc-buff)
    (erase-buffer)

    (let* ((args (apply 'list proot-ask "-v"
                        '()))
           (program+args (append (list cmdfile) args))
           (proc (apply #'start-process "ycm-conf-generator" proc-buff program+args)))

      ;; TODO: error case ?
      )
    )))

#+END_SRC

** Basic setup

#+BEGIN_SRC emacs-lisp (use-package ycmd :ensure t :config ;; setup ycmd server path ~/.emacs.d/modules/ycmd/ycmd' (set-variable 'ycmd-server-command("python" ,(concat user-emacs-directory "modules/ycmd/ycmd"))) ;; When source in these place, load extra config `.ycm_extra_conf.py' (set-variable 'ycmd-extra-conf-whitelist '("/ramdisk" "/Workspace" "~/Weintek")) ;; start ycmd globally (add-hook 'after-init-hook #'global-ycmd-mode)) #+END_SRC

** Company completion backend integration

#+BEGIN_SRC emacs-lisp (use-package company-ycmd :ensure t :config (company-ycmd-setup)) #+END_SRC

** flycheck integration

#+BEGIN_SRC emacs-lisp (use-package flycheck-ycmd :ensure t :config (flycheck-ycmd-setup)) #+END_SRC

  • Snippets :yasnippet:

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package yasnippet :ensure t :mode ("emacs.+/snippets/" . snippet-mode) :config ;; enable yasnippet globally (yas-global-mode 1) ;; extra yasnipet configs <>) #+END_SRC

** Setup yasnippet prompt method

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref yasnippet-config (setq yas/prompt-functions '(yas-dropdown-prompt yas-completing-prompt yas-ido-prompt)) #+END_SRC

** Setup yasnippet snippet dirs

I put my snippets in =~/.emacs.d/snippets=, add it to =yas/snippet-dirs= to make yasnippet can find the snippets.

You can use =yas-new-snippet= to create your new snippet file.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref yasnippet-config (let ((my-snippet-dir (concat user-emacs-directory "snippets"))) (if (and (file-exists-p my-snippet-dir) (not (member my-snippet-dir yas/snippet-dirs))) (add-to-list 'yas/snippet-dirs my-snippet-dir))) #+END_SRC

** Prevent yasnippet conflict with term-mode

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref yasnippet-config (add-hook 'term-mode-hook (lambda() (yas-minor-mode -1))) #+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 :tangle no :noweb-ref yasnippet-config (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)) #+END_SRC

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:

#+BEGIN_SRC emacs-lisp :tangle no (setq emacs-lisp-mode-expand-alist '(("r" . "require"))) #+END_SRC

For c-mode, just do the same but change the relative major-mode-expand-alist like following

#+BEGIN_SRC emacs-lisp :tangle no (setq c-mode-expand-alist '(("i" . "include"))) #+END_SRC

  • Programming Languages

** arduino

#+BEGIN_SRC emacs-lisp (use-package arduino-mode :ensure t :mode ("\.pde\'" "\.ino\'")) #+END_SRC

** bash

#+BEGIN_SRC emacs-lisp (use-package flymake-shell :ensure t :config (add-hook 'sh-set-shell-hook 'flymake-shell-load)) #+END_SRC

** bitbake

#+BEGIN_SRC emacs-lisp (use-package bitbake :ensure t :mode ("\.bb\'" "\.bbappend\'")) #+END_SRC

** dts

#+BEGIN_SRC emacs-lisp (use-package dts-mode :ensure t :mode ("\.dts\'" "\.dtsi\'")) #+END_SRC

** dart

#+BEGIN_SRC emacs-lisp (use-package dart-mode :ensure t :mode ("\.dart\'") :config ;; enable analyzer support (setq dart-enable-analysis-server t) ;; add flycheck support (add-hook 'dart-mode-hook 'flycheck-mode)) #+END_SRC

** elixir

#+BEGIN_SRC emacs-lisp (use-package elixir-mode :ensure t) #+END_SRC

#+BEGIN_SRC emacs-lisp (use-package alchemist :ensure t) #+END_SRC

** gnuplot

A major mode for Emacs for interacting with Gnuplot

GitHub: https://github.com/bruceravel/gnuplot-mode

#+BEGIN_SRC emacs-lisp (use-package gnuplot :ensure t :commands gnuplot-mode :mode "\.gp$") #+END_SRC

** graphviz dot

#+BEGIN_SRC emacs-lisp (use-package graphviz-dot-mode :ensure t :mode "\.dot\'" :config ;; alias `dot-mode' to graphviz-dot-mode (defalias 'dot-mode 'graphviz-dot-mode)) #+END_SRC

** glsl

#+BEGIN_SRC emacs-lisp (use-package glsl-mode :ensure t :mode (("\.vs\'" . glsl-mode) ("\.fs\'" . glsl-mode) ("\.gs\'" . glsl-mode)) :config (setq glsl-other-file-alist '(("\.fs$" (".vs")) ("\.vs$" (".fs"))))) #+END_SRC

** javascript

#+BEGIN_SRC emacs-lisp (use-package js2-mode :ensure t :mode "\.js\'") #+END_SRC

#+BEGIN_SRC emacs-lisp (use-package js2-refactor :ensure t) #+END_SRC

*** Manage Node versions within Emacs

#+BEGIN_SRC emacs-lisp (use-package nvm :ensure t) #+END_SRC

*** Packages we need to install in system

To make emacs work with javascript more nicer, we need to install some packages in system.

**** tern

=tern= for auto-completion and documentation features:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-all npm install -g tern #+END_SRC

**** eslint

We also install =eslint= with babel and react support, to use =eslint= you need to add =.eslintrc= to your project, here's a good example: [[https://github.com/airbnb/javascript/blob/master/linters/.eslintrc][.eslintrc]] .

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-all npm install -g eslint babel-eslint eslint-plugin-react #+END_SRC

**** jsxhint

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-all npm install -g jsxhint #+END_SRC

ref: http://umi-uyura.hatenablog.com/entry/2015/05/13/214629

**** js-beautify

Finally, install =js-beautify= to do automatic code formatting:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-all npm install -g js-beautify #+END_SRC

Be sure to have the =e4x= option set to true on your =.jsbeautifyrc= here it is my configuration as an example:

#+BEGIN_SRC json :tangle no { "indent_size": 2, "indent_char": " ", "eol": "\n", "indent_level": 0, "indent_with_tabs": false, "preserve_newlines": true, "max_preserve_newlines": 2, "jslint_happy": false, "space_after_anon_function": false, "brace_style": "collapse", "keep_array_indentation": false, "keep_function_indentation": false, "space_before_conditional": true, "break_chained_methods": true, "eval_code": false, "unescape_strings": false, "wrap_line_length": 80, "wrap_attributes": "auto", "wrap_attributes_indent_size": 2, "e4x": true, "end_with_newline": true } #+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 (use-package import-js :ensure t) #+END_SRC

** json

#+BEGIN_SRC emacs-lisp (use-package json-mode :ensure t :mode "\.json\'") #+END_SRC

#+BEGIN_SRC emacs-lisp (use-package json-reformat :ensure t :commands json-reformat-region) #+END_SRC

#+BEGIN_SRC emacs-lisp (use-package flymake-json :ensure t :config (add-hook 'json-mode-hook (lambda () (flymake-json-load)))) #+END_SRC

** lua

#+BEGIN_SRC emacs-lisp (use-package lua-mode :ensure t :mode "\.lua$") #+END_SRC

** po

#+BEGIN_SRC emacs-lisp (use-package po-mode :ensure t :mode "\.po\'\|\.po\." :config

;; To use the right coding system automatically under Emacs 20 or newer,
;; also add:
(when (require 'po nil 'noerror)
  (modify-coding-system-alist 'file "\\.po\\'\\|\\.po\\."
                              'po-find-file-coding-system))
)

#+END_SRC

** php

#+BEGIN_SRC emacs-lisp (use-package php-mode :ensure t :mode "\.php\'") #+END_SRC

** python

#+BEGIN_SRC emacs-lisp (use-package python :mode (("SCons\(truct\|cript\)\'" . python-mode) ("DEPS" . python-mode))) #+END_SRC

** ruby

#+BEGIN_SRC emacs-lisp (use-package ruby-mode :ensure t :mode (("Gemfile\'" . ruby-mode) ("Kirkfile\'" . ruby-mode) ("Rakefile\'" . ruby-mode) ("Vagrantfile\'" . ruby-mode) ("\.builder\'" . ruby-mode) ("\.gemspec\'" . ruby-mode) ("\.irbrc\'" . ruby-mode) ("\.pryrc\'" . ruby-mode) ("\.rake\'" . ruby-mode) ("\.rjs\'" . ruby-mode) ("\.ru\'" . ruby-mode) ("\.rxml\'" . ruby-mode)) :config ;; We never want to edit Rubinius bytecode (add-to-list 'completion-ignored-extensions ".rbc")) #+END_SRC ** go

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package go-mode :ensure t :config <>) #+END_SRC

*** Auto completion support

#+BEGIN_SRC emacs-lisp :noweb-ref go-mode-config (use-package company-go :ensure t :config (defun my/setup-go-mode-company-go () "Hook for running on company-go" ;; we only want to use company-go - it's so accurate we won't need ;; any other completion engines (set (make-local-variable 'company-backends) '(company-go))) (add-hook 'go-mode-hook 'my/setup-go-mode-company-go)) #+END_SRC

*** Use gofmt fotmat codes before save

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref go-mode-config (defun my/setup-go-mode-gofmt-hook () ;; Use goimports instead of go-fmt (setq gofmt-command "goimports") ;; Call Gofmt before saving (add-hook 'before-save-hook 'gofmt-before-save)) (add-hook 'go-mode-hook 'my/setup-go-mode-gofmt-hook) #+END_SRC

*** Setup Go Keybinding :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref go-mode-config (bind-keys :map go-mode-map ("M-." . godef-jump)) #+END_SRC

** lua

#+BEGIN_SRC emacs-lisp (use-package lua-mode :ensure t :mode "\.lua$") #+END_SRC

** Haskell

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package haskell-mode :ensure t :mode "\.hs\'" :config <>) #+END_SRC

*** Setup Haskell Keybinding :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref haskell-config (bind-keys :map haskell-mode-map ;;("C-c '" . my/narrow-or-widen-dwim) ) #+END_SRC

** nxml

#+BEGIN_SRC emacs-lisp (use-package nxml-mode :ensure nil ; emacs built-in :mode (("\.plist\'" . nxml-mode) ("\.rss\'" . nxml-mode) ("\.svg\'" . nxml-mode) ("\.xml\'" . nxml-mode) ("\.xsd\'" . nxml-mode) ("\.xslt\'" . nxml-mode) ("\.pom$" . nxml-mode)) :config ;; Any file start with xml will be treat as nxml-mode (add-to-list 'magic-mode-alist '("<\?xml" . nxml-mode)) ;; Use nxml-mode instead of sgml, xml or html mode. (mapc (lambda (pair) (if (or (eq (cdr pair) 'xml-mode) (eq (cdr pair) 'sgml-mode)) (setcdr pair 'nxml-mode))) auto-mode-alist)) #+END_SRC

** GraphQL

#+BEGIN_SRC emacs-lisp (use-package graphql-mode :ensure t :init (setq graphql-url "http://localhost:7000/graphql")) #+END_SRC

  • iOS / Mac OSX Development

** Swift

#+BEGIN_SRC emacs-lisp (use-package swift-mode :ensure t) #+END_SRC

  • JVM / Android Development

Note that =Clojure= is setting in =LISP Development= section.

** Android

#+BEGIN_SRC emacs-lisp (use-package android-mode :ensure t :config (setq android-mode-sdk-dir (getenv "ANDROID_HOME"))) #+END_SRC

*** Integrate logcat with emacs

logcat interface for emacs based on android-mode.

GitHub: https://github.com/youngker/elogcat.el

#+BEGIN_SRC emacs-lisp (use-package elogcat :ensure t) #+END_SRC

** Scala

#+BEGIN_SRC emacs-lisp (use-package sbt-mode :ensure t :mode "\.sbt$") #+END_SRC

  • Rust Development

[[https://www.rust-lang.org/][Rust]] is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code (use-package rust-mode :mode "\.rs\'" :config <> ) #+END_SRC

** Install Rust

To get start with programming [[https://www.rust-lang.org/][Rust]], we need to install it.

Install Rust is really simple, just copy and paste following command line to your terminal (MacOSX, Linux)

: curl -sSf https://static.rust-lang.org/rustup.sh | sh

If you want to uninstall it, just use uninstall script =/usr/local/lib/rustlib/uninstall.sh=.

Now you can create a minimal example to test Rust, let's create =hello.rs=.

#+BEGIN_SRC rust :tangle no fn main() { print!("Hello Rust!!!"); } #+END_SRC

And use =rustc= to compile it.

: rustc hello.rs

After compile, we find a new file =hello= create, let's execute it.

#+BEGIN_EXAMPLE ./hello Hello Rust!!! #+END_EXAMPLE

That's all, let's start programming [[https://www.rust-lang.org/][Rust]].

** Auto-Completion for Rust

To do auto-completion, you need to install [[https://github.com/phildawes/racer][Racer]], a code completion tool for [[https://www.rust-lang.org/][Rust]]. The binary file will be install to =~/.cargo/bin/racer=.

: cargo install racer

We also need to download Rust source code to make [[https://github.com/phildawes/racer][Racer]] can parse it, just download it [[https://www.rust-lang.org/downloads.html][here]]. Or you can download it by =git=.

: git clone https://github.com/rust-lang/rust.git ~/Workspace/src/rust

After download source code, you can set =RUST_SRC_PATH= environment variable to make your emacs more portable, add following to your =~/.bashrc=.

#+BEGIN_SRC sh :tangle no export RUST_SRC_PATH=$HOME/Workspace/src/rust #+END_SRC

On emacs, we can use [[https://github.com/racer-rust/emacs-racer][emacs-racer]] as racer's wrapper.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref rust-mode-config (use-package racer :ensure t :config ;; Use cargo install racer' to install it (setq racer-cmd "~/.cargo/bin/racer") ;; Don't forget to download rust source code, I save it to$RUST_SRC_PATH' (setq racer-rust-src-path (getenv "RUST_SRC_PATH")) ;; Configure Emacs to activate racer when rust-mode starts (add-hook 'rust-mode-hook #'racer-mode) (add-hook 'racer-mode-hook #'eldoc-mode)) #+END_SRC

I also use [[http://company-mode.github.io/][company-mode]] as completion backend.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref rust-mode-config (use-package company-racer :ensure t :config (add-hook 'racer-mode-hook #'company-mode) ;; Setting up configurations when you load rust-mode (add-hook 'rust-mode-hook ;; Use company-racer in rust mode (lambda () (set (make-local-variable 'company-backends) (cons 'company-racer company-backends))))) #+END_SRC

** Syntax Checker

[[https://github.com/flycheck/flycheck-rust][flycheck-rust]] is [[https://github.com/flycheck/flycheck][flycheck]] backend for Rust, which can let use setup Rust more easily.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref rust-mode-config (use-package flycheck-rust :ensure t :config (add-hook 'flycheck-mode-hook #'flycheck-rust-setup)) #+END_SRC

From [[https://github.com/flycheck/flycheck-rust][flycheck-rust]]'s doc, there's something we should notice:

#+BEGIN_QUOTE Note: You must run cargo build initially to install all dependencies. If you add new dependencies to Cargo.toml you need to run cargo build again. Otherwise you will see spurious errors about missing crates. #+END_QUOTE

** Setup Rust Keybinding

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref rust-mode-config (bind-keys :map rust-mode-map ("M-." . racer-find-definition) ; Jump to method definition ("TAB" . racer-complete-or-indent) ; auto complete and intent ) #+END_SRC

  • LISP Development :lisp:

Though =LISP= has many dialet, it still is the best programming language I ever met.

** Plugins

Common setup for LISP development.

*** lispy

This package reimagines Paredit - a popular method to navigate and edit LISP code in Emacs.

GitHub: https://github.com/abo-abo/lispy

For more info to control lispy, please refer: http://oremacs.com/lispy/

#+BEGIN_SRC emacs-lisp (use-package lispy :ensure t :config

(defun my/up-list (&optional arg)
  "My special lisp moving stragedy."
  (interactive)
  (or arg (setq arg -1))
  (condition-case ex
      (up-list arg)
    ('error (progn
              (lispy-backward arg)
              (beginning-of-line)
              (up-list arg)))))

(defun my/down-list (&optional arg)
  "My special lisp moving stragedy."
  (interactive)
  (or arg (setq arg 1))
  (condition-case ex
      (down-list arg)
    ('error (progn
              (lispy-forward arg)
              (end-of-line)
              (down-list arg)))))

;; My special hack for lispy-mode
(defun my/lispy-mode ()
  (lispy-mode 1)
  ;; `M-m' is preserved for mode setting
  (define-key lispy-mode-map (kbd "M-m") nil)
  ;; `M-s' is for my search command, rebind to `C-c s'
  (define-key lispy-mode-map (kbd "M-s") nil)
  (define-key lispy-mode-map (kbd "C-c s") 'lispy-splice)
  ;; `[' and `]' just insert them
  (define-key lispy-mode-map (kbd "[") 'lispy-open-square)
  (define-key lispy-mode-map (kbd "]") 'lispy-close-square)
  ;; My special lisp moving cmd
  (define-key lispy-mode-map (kbd "C-M-f") 'my/down-list)
  (define-key lispy-mode-map (kbd "C-M-b") 'my/up-list))

;; Use projectile to find file
(setq lispy-visit-method 'projectile)

(add-hook 'emacs-lisp-mode-hook #'my/lispy-mode)
(add-hook 'lisp-interaction-mode-hook #'my/lispy-mode)
(add-hook 'clojure-mode-hook #'my/lispy-mode)
(add-hook 'scheme-mode-hook #'my/lispy-mode)
(add-hook 'lisp-mode-hook #'my/lispy-mode))

#+END_SRC *** indent-guide

#+BEGIN_SRC emacs-lisp (use-package indent-guide :ensure t :config (add-hook 'emacs-lisp-mode-hook #'indent-guide-mode) (add-hook 'lisp-interaction-mode-hook #'indent-guide-mode) (add-hook 'clojure-mode-hook #'indent-guide-mode) (add-hook 'scheme-mode-hook #'indent-guide-mode) (add-hook 'lisp-mode-hook #'indent-guide-mode)) #+END_SRC

*** Prettify symbols

Show lambda as λ.

#+BEGIN_SRC emacs-lisp (global-prettify-symbols-mode 1) #+END_SRC

** Scheme

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package scheme :mode ("\.scm\'" . scheme-mode) :config <>) #+END_SRC

#+BEGIN_SRC emacs-lisp (use-package racket-mode :ensure t :mode "\.rkt[dl]?\'") #+END_SRC

*** Use geiser to interaction wich scheme

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref scheme-config (use-package geiser :ensure t :init ;; On opening a scheme file, Geiser will try to guess its Scheme, ;; defaulting to the first in the list. Use `C-c C-s' to select the ;; implementation by hand (on a per file basis). (setq geiser-active-implementations '(guile chicken))) #+END_SRC

*** Setup Scheme Keybinding :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref scheme-config (bind-keys :map scheme-mode-map ;; ("C-c '" . my/narrow-or-widen-dwim) ) #+END_SRC

** Common Lisp

#+BEGIN_SRC emacs-lisp :noweb no-export (use-package lisp-mode :ensure nil ; built-in :mode "\.lisp\'" :config <>) #+END_SRC

*** Setup Common Lisp Keybinding :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref common-lisp-config (bind-keys :map lisp-mode-map ("C-c '" . my/narrow-or-widen-dwim)) #+END_SRC

** newlisp

#+BEGIN_SRC emacs-lisp (use-package newlisp-mode :ensure t) #+END_SRC

  • Web Development :web:

#+BEGIN_SRC emacs-lisp (use-package web-mode :ensure t :mode (("\.html?\'" . web-mode) ("\.ejs?\'" . web-mode))) #+END_SRC

** CSS :css:

#+BEGIN_SRC emacs-lisp (use-package css-mode :ensure t :mode "\.css\'") #+END_SRC

*** Add support for eldoc :eldoc:

#+BEGIN_SRC emacs-lisp (use-package css-eldoc :ensure t :config (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 (use-package less-css-mode :ensure t :mode ("\.less$" . less-css-mode)) #+END_SRC

** SCSS :css:scss:

#+BEGIN_SRC emacs-lisp (use-package scss-mode :ensure t :mode "\.scss\'" :config ;; 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 (use-package mustache-mode :mode "\.mustache$" :ensure t) #+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 (use-package emmet-mode :ensure t :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)))

#+END_SRC

  • Terminal Emulator :term:

** ansi-term

*** Close ansi-term buffer after exit

After the ansi-term process ends it should leaves a buffer.

#+BEGIN_SRC emacs-lisp (defadvice term-handle-exit (after kill-buffer-after-exit activate) "Kill the term buffer if the process finished." (kill-buffer (current-buffer))) #+END_SRC

** 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 (use-package sane-term :ensure t :config ;; shell to use for sane-term (setq sane-term-shell-command "/bin/bash") ;; sane-term will create first term if none exist (setq sane-term-initial-create t) ;; C-d' orexit' 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 :noweb no-export :exports code (use-package eshell :config ;; extra eshell configs <>) #+END_SRC

*** Use bash like prompt with color

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref eshell-config ;; 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) " # " " $ ")))) #+END_SRC

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref eshell-config ;; 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 :tangle no :noweb-ref eshell-config (setq eshell-visual-commands '("less" "tmux" "htop" "top" "bash" "zsh" "fish" "ssh" "tail" "vi" "vim" "screen" "less" "more" "lynx" "ncftp" "pine" "tin" "nmtui" "alsamixer"))

(setq eshell-visual-subcommands '(("git" "log" "diff" "show"))) #+END_SRC

*** Add autojump command

[[https://github.com/coldnew/eshell-autojump][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.

GitHub: https://github.com/coldnew/eshell-autojump

#+BEGIN_SRC emacs-lisp (use-package eshell-autojump :ensure t) #+END_SRC

*** Fish-like history autosuggestions in eshell

#+BEGIN_SRC emacs-lisp (use-package esh-autosuggest :hook (eshell-mode . esh-autosuggest-mode) :ensure t) #+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

*** Setup Keybindings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref eshell-config ;; FIXME: why this will still global-map ? ;; (bind-keys :map eshell-mode-map ;; ("C-u" . eshell-kill-input))

(add-hook 'eshell-mode-hook (lambda () (define-key eshell-mode-map (kbd "C-u") 'eshell-kill-input))) #+END_SRC

  • Window Management :window:

** winner-mode :winner:

#+BEGIN_SRC emacs-lisp (use-package winner ; builtin :config ;; I use my own keymap for winner-mode (setq winner-dont-bind-my-keys t) ;; Start winner-mode globally (winner-mode t)) #+END_SRC

** eyebrowse

=eyebrowse= is a global minor mode for Emacs that allows you to manage your window configurations in a simple manner, just like tiling window managers like i3wm with their workspaces do. It displays their current state in the modeline by default. The behaviour is modeled after [[http://ranger.nongnu.org/][ranger]], a file manager written in Python.

GitHub: https://github.com/wasamasa/eyebrowse

#+BEGIN_SRC emacs-lisp (use-package eyebrowse :ensure t :config ;; enable eyebrowse globally (eyebrowse-mode t)) #+END_SRC

** window-numbering

Numbered window shortcuts for Emacs.

Enable =window-numbering-mode= and use =M-1= through =M-0= to navigate.

If you want to affect the numbers, use window-numbering-before-hook or window-numbering-assign-func. For instance, to always assign the calculator window the number 9, add the following to your .emacs:

#+BEGIN_SRC emacs-lisp :tangle no (setq window-numbering-assign-func (lambda () (when (equal (buffer-name) "Calculator") 9))) #+END_SRC

GitHub: https://github.com/nschum/window-numbering.el

#+BEGIN_SRC emacs-lisp (use-package window-numbering :ensure t) #+END_SRC

  • Email ** bbdb :bbdb:

#+BEGIN_SRC emacs-lisp (use-package bbdb :ensure t :init (setq bbdb-file (concat user-cache-directory "bbdb")) :config (bbdb-initialize)) #+END_SRC

** mu4e :mu4e:

[[http://www.djcbsoftware.nl/code/mu][mu]] is really nice tool to help me read and search email in emacs.

GitHub: https://github.com/djcb/mu

#+BEGIN_SRC emacs-lisp :noweb no-export :exports code ;; setup loadpath later <>

(use-package mu4e :ensure nil ; this package can't be installed by elpa :config <>) #+END_SRC

*** Install mu4e to system

Since [[http://www.djcbsoftware.nl/code/mu][mu]] can't install via pacakge.el, you must install manually.

For Mac OSX, just type

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install mu --with-emacs --HEAD #+END_SRC

An don't forget to add =mu4e= to your emacs load-path

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-load-path (when (eq system-type 'darwin) (add-to-list 'load-path "/usr/local/share/emacs/site-lisp/mu/mu4e/")) #+END_SRC

If you use Gentoo Linux, you can use following command to install this package

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-gentoo USE="emacs" emerge net-mail/mu #+END_SRC

*** Install offlinimap

I use [[http://offlineimap.org/][offlineimap]] to help me fetch the email, we need to install it in system.

For Mac OSX, just type

#+BEGIN_SRC sh :tangle no :noweb-ref install-in-macosx brew install offlineimap #+END_SRC

If you use Gentoo Linux, you can use following command to install this package

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref install-in-gentoo emerge net-mail/offlineimap #+END_SRC

**** Make offlineimap get password from emacs

My email password is saved in =~/.authinfo.gpg=, which is encrypted by gnupg, since I prefer make =prompt for password dialog= show on my emacs, I let offlineimap get the emacs password via my emacs.

To achive this, you need add following conifg in =~/.offlineimaprc=

: pythonfile = ~/.offlineimap.py

Then create a file named =~/.offlineimap.py= with following code

#+begin_src python :tangle no #!/usr/bin/env python

import subprocess

def get_output(cmd): # Bunch of boilerplate to catch the output of a command: pipe = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) (output, errout) = pipe.communicate() assert pipe.returncode == 0 and not errout return output

def get_password_emacs(host, port): cmd = "emacsclient --eval '(offlineimap-get-password "%s" "%s")'" % (host,port) return get_output(cmd).strip().lstrip('"').rstrip('"') #+end_src

From =~/offlineimap.py=, we can see I use emacsclient call eslip function to get the password, so you also need to add =offlineimap-get-password= function in your ~/.emacs

#+begin_src emacs-lisp (defun offlineimap-get-password (host port) (require 'netrc) (let* ((netrc (netrc-parse (expand-file-name "~/.authinfo.gpg"))) (hostentry (netrc-machine netrc host port port))) (when hostentry (netrc-get hostentry "password")))) #+end_src

After all is done, add following line in =~/.offlineimaprc= and we can get password by emacs.

: remotepasseval = get_password_emacs("imap.gmail.com")

*** Basic mu4e setup

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-config ;; Use mu4e as default mail agent (setq mail-user-agent 'mu4e-user-agent) ;; Mail folder set to /Maildir (setq mu4e-maildir "/Maildir") ;; Fetch mail by offlineimap (setq mu4e-get-mail-command "offlineimap") ;; Fetch mail in 60 sec interval (setq mu4e-update-interval 60) ;; Setup default mu4e search result mails list, if I want to see ;; more, use M-x `mu4e-headers-toggle-full-search' to make mi4e show all mails (setq mu4e-headers-results-limit 1000) ;; Make mu4e does not show the "Indexing..." message (setq mu4e-hide-index-messages t) #+END_SRC

*** Use eww for html file render

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-config (use-package mu4e-contrib :ensure nil ; part of mu4e :config (setq mu4e-html2text-command 'mu4e-shr2text) ;; try to emulate some of the eww key-bindings (add-hook 'mu4e-view-mode-hook (lambda () (local-set-key (kbd "") 'shr-next-link) (local-set-key (kbd "") 'shr-previous-link)))) #+END_SRC

*** Setup send mail method

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-config ;; SMTP setup (setq message-send-mail-function 'smtpmail-send-it smtpmail-stream-type 'starttls starttls-use-gnutls t) ;; don't save messages to Sent Messages, Gmail/IMAP takes care of this (setq mu4e-sent-messages-behavior 'delete) #+END_SRC

*** Setup my email acount list

#+begin_src emacs-lisp :tangle no :noweb-ref mu4e-config (setq coldnew/mu4e-account-alist '(("Gmail" (mu4e-sent-folder "/Gmail/Sent") (mu4e-drafts-folder "/Gmail/Drafts") (mu4e-trash-folder "/Gmail/Trash") (user-mail-address "[email protected]") (smtpmail-smtp-server "smtp.gmail.com") (smtpmail-smtp-service 587) (smtpmail-smtp-user "[email protected]") (user-full-name "Yen-Chin, Lee") (mu4e-compose-signature "")))) #+end_src

Since I use list to store my account info, add foollowing function to setup default account.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-config (defun coldnew/mu4e-set-default-account (account) "Setup the default account based on coldnew/mu4e-account-alist." (let* ((account (cdr (assoc account coldnew/mu4e-account-alist)))) (when account (mapc #'(lambda (a) (set (car a) (if (stringp (cadr a)) (cadr a) (eval (cadr a))))) account))))

;; set Gmail to default (coldnew/mu4e-set-default-account "Gmail") #+END_SRC

Select my email account when sending email.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-config (defun coldnew/mu4e-set-account () "Set the account for composing a message." (interactive) (let* ((account (if mu4e-compose-parent-message (let ((maildir (mu4e-msg-field mu4e-compose-parent-message :maildir))) (string-match "/\(.*?\)/" maildir) (match-string 1 maildir)) (completing-read (format "Compose with account: (%s) " (mapconcat #'(lambda (var) (car var)) coldnew/mu4e-account-alist "/")) (mapcar #'(lambda (var) (car var)) coldnew/mu4e-account-alist) nil t nil nil (caar coldnew/mu4e-account-alist)))) (account-vars (cdr (assoc account coldnew/mu4e-account-alist)))) (if account-vars (mapc #'(lambda (var) (set (car var) (cadr var))) account-vars))))

(add-hook 'mu4e-compose-pre-hook 'coldnew/mu4e-set-account) #+END_SRC

*** Let mu4e fontify diff contents

I always use mu4e to read maliing-list, it's really nice to fontify diff contents.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-config (defun mu4e~view-fontify-diff () "Colorize diff message." (interactive) (let ((inhibit-read-only t)) (save-excursion (goto-char (point-min)) ;; consider only lines that heuristically look like a citation line... (while (re-search-forward "^\(\(\+\)[^+]\|\(-\)[^-]\)" nil t) (let ((cur-point (or (match-beginning 2) (match-beginning 3))) (color (if (match-beginning 2) "green" "deep pink"))) (end-of-line) (add-text-properties cur-point (point) `(face ((foreground-color . ,color)))))) (goto-char (point-min)) (while (re-search-forward "^\(\+\+\+\|---\)" nil t) (let ((cur-point (match-beginning 1))) (end-of-line) (add-text-properties cur-point (point) '(face ((weight . bold)))))))))

(add-hook 'mu4e-view-mode-hook 'mu4e~view-fontify-diff) #+END_SRC

*** Setup Keybinfings :keybinding:

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref mu4e-config (bind-keys :map mu4e-view-mode-map ("C-f" . evil-scroll-page-down) ("C-b" . evil-scroll-page-up)) #+END_SRC

  • IRC :irc:

I always use =ERC= as my irc client, which is bundle with emacs.

#+BEGIN_SRC emacs-lisp :noweb no-export

(use-package erc :ensure nil ; built-in :config ;;(use-package erc-notify) <>) #+END_SRC

** Basic setup

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref erc-config ;; set prompt to ->> (setq erc-prompt "->> ") ;; Encoding with utf-8 (setq erc-server-coding-system '(utf-8 . utf-8)) ;; column with is 100 (setq erc-fill-column 100) ;; Auto join irc server when erc start (erc-autojoin-mode t) ;; truncate too long line (erc-truncate-mode +1) ;; Interpret mIRC-style color commands in IRC chats (setq erc-interpret-mirc-color t) ;; Kill buffers for channels after /part (setq erc-kill-buffer-on-part t) ;; Kill buffers for private queries after quitting the server (setq erc-kill-queries-on-quit t) ;; Kill buffers for server messages after quitting the server (setq erc-kill-server-buffer-on-quit t) ;; open query buffers in the current window (setq erc-query-display 'buffer) (setq erc-save-buffer-on-part t) #+END_SRC

** Setup default irc room I want to join

#+begin_src emacs-lisp (setq erc-autojoin-channels-alist '( ;; english channel (".\.freenode.net" "#clojure" "#wayland" "#libhybris" "#webos-ports") (".\.mozilla.org" "#b2g" "#servo" "#rust") ;; Chinese channel (".*\.freenode.net" "#emacs.tw" "#cschat.tw" "#clojure.tw" "#lisp.tw"))) #+end_src

** Hide some sort of message

#+begin_src emacs-lisp (setq erc-hide-list '(;; notices "JOIN" "PART" "QUIT" "LEFT" "NICK" ;; robot "^j[a-z]*bot!" "^fussbot!")) #+end_src

** Add timestamp for messages

#+BEGIN_SRC emacs-lisp (erc-timestamp-mode 1) (setq erc-insert-timestamp-function 'erc-insert-timestamp-left) #+END_SRC

** Coloify user's nickname

#+BEGIN_SRC emacs-lisp (use-package erc-hl-nicks :ensure t) #+END_SRC

** Enable track-mode for erc

#+BEGIN_SRC emacs-lisp (eval-after-load 'erc '(progn ;; enable track-mode (erc-track-mode t) ;; do not track some type of message (setq erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT" "MODE" "324" "329" "332" "333" "353" "477")))) #+END_SRC

** Enable spell checking

#+BEGIN_SRC emacs-lisp (use-package erc-spelling :ensure nil ; built-in :config (progn (erc-spelling-mode 0))) #+END_SRC

** Autoaway setup

#+BEGIN_SRC emacs-lisp (use-package erc-autoaway :ensure nil ; built-in :config (progn (setq erc-auto-discard-away t) (setq erc-autoaway-idle-seconds 600) (setq erc-autoaway-use-emacs-idle t))) #+END_SRC

** Quick start/switch erc with one command :command:

#+BEGIN_SRC emacs-lisp (defun erc-start-or-switch () "Connect to IRC, if already connected, switch to active irc buffer." (interactive) (let ((irc-active-p (and (fboundp 'erc-buffer-list) (erc-buffer-list)))) ;; we track irc.freenode.net to make sure erc is already active (if irc-active-p (erc-track-switch-buffer 1) (progn ;; connect to irc server (erc-tls :server "irc.freenode.net" :port 6697 :nick erc-nick) (erc-tls :server "irc.debian.org" :port 6697 :nick erc-nick) (erc-tls :server "irc.mozilla.org" :port 6697 :nick erc-nick))))) #+END_SRC

  • Personal Finance 📒finance:

    I'm trying to use ledger as my personal finance system, here's a good reference:

    [[https://www.youtube.com/watch?v=cjoCNRpLanY&t=1736s][Conquering Your Finances with Emacs and Ledger]]

    #+BEGIN_SRC emacs-lisp :noweb no-export (use-package ledger-mode :ensure t

    :mode "\\.dat\\'"
    
    :init
    (setq ledger-clear-whole-transactions 1)
    
    :config
    (add-to-list 'evil-emacs-state-modes 'ledger-report-mode)
    
    <<ledger-config>>)
    

    #+END_SRC

  • Keybindings :keybinding:

** Global Keybinding

#+BEGIN_SRC emacs-lisp (bind-keys :map global-map ("C-x C-s" . my/save-buffer-always) ("M-g" . avy-goto-char-2)) #+END_SRC

Window Selection

#+BEGIN_SRC emacs-lisp (bind-keys :map global-map ("M-1" . select-window-1) ("M-2" . select-window-2) ("M-3" . select-window-3) ("M-4" . select-window-4) ("M-5" . select-window-5) ("M-6" . select-window-6) ("M-7" . select-window-7) ("M-8" . select-window-8) ("M-9" . select-window-9) ("M-0" . select-window-0)) #+END_SRC

** Normal State

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-keybindings (evil-define-key 'normal my-editor-map (kbd "C-x C-f") 'helm-find-files (kbd "C-x C-q") 'read-only-mode (kbd "C-x M-1") 'deft-or-close (kbd "C-x M-2") '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) #+END_SRC

** Insert State

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-keybindings (evil-define-key 'insert my-editor-map (kbd "") 'hungry-delete-backward (kbd "C-;") 'iedit-mode (kbd "C-d") 'hungry-delete-forward (kbd "C-l") 'hungry-delete-backward (kbd "C-n") 'evil-next-line (kbd "C-o") 'evil-execute-in-normal-state (kbd "C-p") 'evil-previous-line (kbd "C-v") 'set-mark-mode/rectangle-mark-mode (kbd "C-w") 'backward-kill-word (kbd "C-x C-f") 'helm-find-files (kbd "C-x C-i") 'my/indent-region-or-buffer-and-cleanup (kbd "C-x C-n") 'company-complete (kbd "C-x C-o") 'other-frame (kbd "C-x C-q") 'read-only-mode (kbd "C-x M-1") 'deft-or-close (kbd "C-x M-2") 'eshell (kbd "C-x M-3") 'mu4e (kbd "C-x M-4") 'erc-start-or-switch (kbd "C-x T") 'sane-term (kbd "C-x b") 'helm-buffers-list (kbd "C-x t") 'sane-term (kbd "C-x vl") 'magit-log (kbd "C-x vp") 'magit-push (kbd "C-x vs") 'magit-status (kbd "M-") 'insert-U200B-char (kbd "M-[") 'winner-undo (kbd "M-]") 'winner-redo (kbd "M-s") 'helm-occur (kbd "M-v") 'er/expand-region (kbd "M-x") 'helm-M-x (kbd "M-y") 'helm-show-kill-ring (kbd "M-y") 'helm-show-kill-ring (kbd "M-z") 'zzz-to-char (kbd "s-") 'insert-empty-line (kbd "s-") 'insert-U200B-char (kbd "C-M-;") 'avy-goto-char (kbd "C-x C-d") 'dired ;; (kbd "M-o") 'other-window ;; (kbd "TAB") 'yas/expand ) #+END_SRC

** Space State

For =space= state, I use evil-leader to achive this goal.

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-leader-keybindings (evil-leader/set-leader "") #+END_SRC

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-leader-keybindings (evil-leader/set-key "1" 'select-window-1 "2" 'select-window-2 "3" 'select-window-3 "4" 'select-window-4 "5" 'select-window-5 "6" 'select-window-6 "7" 'select-window-7 "8" 'select-window-8 "9" 'select-window-9 "0" 'select-window-0) #+END_SRC

** Ex Command

#+BEGIN_SRC emacs-lisp :tangle no :noweb-ref evil-ex-commands (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 :)

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].