All Projects → echosa → emacs.d

echosa / emacs.d

Licence: other
My personal emacs setup.

Programming Languages

emacs lisp
2029 projects

Projects that are alternatives of or similar to emacs.d

Emacs Gtd
Get Things Done with Emacs
Stars: ✭ 111 (+311.11%)
Mutual labels:  emacs-configuration, org-mode
.emacs.d
Vanilla, Evil, literate Emacs configuration
Stars: ✭ 62 (+129.63%)
Mutual labels:  evil, org-mode
Dmacs
Emacs Literate Configuration with borg
Stars: ✭ 74 (+174.07%)
Mutual labels:  emacs-configuration, org-mode
.emacs.d
🎉 Personal GNU Emacs configuration
Stars: ✭ 313 (+1059.26%)
Mutual labels:  emacs-configuration, org-mode
dotfiles
I showed you my source code, pls respond
Stars: ✭ 45 (+66.67%)
Mutual labels:  emacs-configuration, org-mode
Org Evil
Evil extensions for Org-mode.
Stars: ✭ 51 (+88.89%)
Mutual labels:  evil, org-mode
Writingwithemacs
Tips, Examples, and Resources for Writing with Emacs
Stars: ✭ 150 (+455.56%)
Mutual labels:  emacs-configuration, org-mode
doom-todo-ivy
Display all TODO and FIXME entries for a project or buffer in ivy. Extracted from doom-emacs.
Stars: ✭ 31 (+14.81%)
Mutual labels:  emacs-configuration, projectile
Evil Org Mode
Supplemental evil-mode keybindings to emacs org-mode
Stars: ✭ 241 (+792.59%)
Mutual labels:  evil, org-mode
Doom Emacs
An Emacs framework for the stubborn martian hacker
Stars: ✭ 12,774 (+47211.11%)
Mutual labels:  evil, emacs-configuration
my-emacs
My Emacs configuration
Stars: ✭ 35 (+29.63%)
Mutual labels:  emacs-configuration, org-mode
dotfiles
Personal config and utils for emacs, vim, tmux, i3, git, etc.
Stars: ✭ 29 (+7.41%)
Mutual labels:  emacs-configuration, org-mode
emacs-modified-windows
Mirror of the GitLab project Emacs Modified for Windows
Stars: ✭ 79 (+192.59%)
Mutual labels:  org-mode
knowledge-base
Personal Wiki
Stars: ✭ 16 (-40.74%)
Mutual labels:  org-mode
jcs-emacs
Emacs configuration works across all OSs
Stars: ✭ 37 (+37.04%)
Mutual labels:  emacs-configuration
ntangle
Command-line utility for Tangling of Org documents — programmed in Nim.
Stars: ✭ 56 (+107.41%)
Mutual labels:  org-mode
org-notes-style
A light CSS theme for Org mode HTML export
Stars: ✭ 20 (-25.93%)
Mutual labels:  org-mode
org-babel-eval-in-repl
Send and eval org-mode babel code blocks in various REPLs (therefore it's async)
Stars: ✭ 49 (+81.48%)
Mutual labels:  org-mode
nema
Nayuki's EMAcs distro
Stars: ✭ 19 (-29.63%)
Mutual labels:  emacs-configuration
preview-org-html-mode
Emacs minor mode for an (optionally) live preview of Org exports to HTML using Xwidgets.
Stars: ✭ 16 (-40.74%)
Mutual labels:  org-mode

Echosa’s Emacs Configuration

Introduction

Inspired by Sacha Chua, I have moved my Emacs configuration into an organized and descriptive org-mode file. What you are reading now is, in fact, my Emacs configuration file.

Well, sort of.

How this works is based around a part of org-mode called org-babel. org-babel allows org-mode to execute code that is embedded into a .org file. If you look at the actual init.el file that my Emacs loads, you’ll see that all it does is load the .org file containing my configuration (the one you’re reading now) and parse it through org-babel to execute only the blocks of elisp that make up the actual configuration, while ignoring the extra documentation and narrative, like this introduction section.

If you’re wondering about performance, org-babel doesn’t do this parse every time I open Emacs. Instead, it sees that I’m trying to load emacs-config.org and checks for the existence of emacs-config.el. If it doesn’t find that file, or finds an out of date version, only then does it parse the .org file to create a new .el file. This means there’s a bit of a slow startup the first time after the org-mode file is changes, but after that there’s no noticeable change in performance (at least on my machine). I have accounted for this one-off performance hit, however, by automatically regenerating emacs-config.el when I save emacs-config.org. You’ll see this later.

The only other source of major slowdown, usually only on the first run, is the installation of packages. On a fresh install of Emacs using this configuration, the first time Emacs is run org-babel parses the .org file and also installs all the external packages required by my config. This makes for a slow first-time startup, but the benefit is that all of the configuration, installation, and setup is done for me automatically. I don’t have to manually set anything up, which, when setting up other editors, can often take much longer than the first run of this config. Plus, it’s more work to have to manually set things up, so I’ll take a one-time slowdown in trade of automatically having my Emacs setup installed and ready for me.

Anyway, what follows is my actual Emacs configuration, embedded into a descriptive narrative.

Installation

Get from GitHub

First, you need to get the config from GitHub. I recommend actually cloning instead of just downloading a zip file, because a cloned repo will be easier to update.

First, delete, move, or rename your existing Emacs configuration (both the .emacs.d/ directory and your .emacs init file). Next, clone the repository into your home directory:

$ git clone [email protected]:echosa/emacs.d.git ~/.emacs.d

Start Emacs

Simply run Emacs and wait a bit! All the necessary packages will download and install automatically and everything will be configured. This is because of the use-package package’s :ensure flag. That flag tells Emacs to download and install the package if it is not already installed. Because of this, the first time you start Emacs make take a few seconds as all the packages are downloaded and installed. Subsequent starts will not take so long.

Configuration Maintenance

In order to make maintaining this config easier, I’ve made this echosa-export-config function which will export the proper emacs-config.el and README.org files when emacs-config.org is updated and saved.

(defun echosa-export-config ()
  (when (string= (buffer-name (current-buffer)) "emacs-config.org")
    (let ((org-file "~/.emacs.d/emacs-config.org")
          (elisp-file "~/.emacs.d/emacs-config.el")
          (readme-file "~/.emacs.d/README.org"))
      (org-babel-tangle-file org-file elisp-file "emacs-lisp")
      (copy-file org-file readme-file t)
      (message "Config export complete!"))))
(add-hook 'after-save-hook 'echosa-export-config)

Packages

External and third-party packages are great. They make adding new things to Emacs much nicer and less complicated.

Repositories

We need to set up the package repositories for Emacs’ package manager.

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

use-package

I’ve come to appreciate the use-package way of handling package management. Everything is nice, clean, and compact. Best of all, all setup for a package is self-contained within a use-package declaration, so no need to hunt through your whole config to find related parts (hooks in one place, key bindings in another, etc.)

Since I use use-package to install all the other packages, this is the only place where I pull in and use package.el. I only do that to ensure that use-package is installed and ready to go.

(require 'package)
(package-initialize)
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(eval-when-compile
  (require 'use-package))

General Setup

Here, I change some generic Emacs behavior. These are all things that aren’t tied to a specific mode or programming language. Most of these are self-explanatory. However, for more info, you can look them up with Emacs’ built-in help. That will do a better job of explaining that I can, plus there’s no need for me to reiterate it all here.

(temp-buffer-resize-mode 0)
(add-hook 'before-save-hook 'time-stamp)
(setq fill-column 80)
(setq scroll-conservatively 101)
(setq case-fold-search t)
(setq case-replace t)
(setq display-buffer-reuse-frames t)
(setq display-time-24hr-format nil)
(setq display-time-day-and-date t)
(setq large-file-warning-threshold nil)
(setq truncate-partial-width-windows nil)

Allow a to be used in dired to reuse the buffer instead of creating new buffers for every directory.

(put 'dired-find-alternate-file 'disabled nil)

Don’t load outdated complied files.

(setq load-prefer-newer t)

Make sure Emacs can find and run commands on the PATH.

(when (memq window-system '(mac ns x))
  (setenv "PATH" (concat "/usr/local/bin:" (getenv "PATH")))
  (setq exec-path (append '("/usr/local/bin") exec-path)))

Remember open files and buffers between sessions.

(desktop-save-mode 1)

Backup and Auto Save

I don’t like Emacs littering and leaving a bunch of temporary files all over the place, so here I tell it to keep all those files in one place.

(setq auto-save-file-name-transforms '((".*" "~/.emacs.d/.tmp/" nil)))
(setq auto-save-list-file-prefix "~/.emacs.d/.tmp/.saves-")
(setq backup-directory-alist '(("" . "~/.emacs.d/.tmp")))

Things I don’t want to see

Scroll bars

(when (fboundp 'toggle-scroll-bar) (toggle-scroll-bar nil))

Tool bar

(tool-bar-mode -1)

Menu bar

(menu-bar-mode -1)

Splash screen

It’s unnecessary, really.

(setq inhibit-startup-screen t)

Things I do want to see

Highlight current region/selection

(transient-mark-mode t)

Syntax highlighting

(global-font-lock-mode t)

Column number

(column-number-mode t)

Show matching parenthesis

(show-paren-mode t)

Blinking cursor

(setq blink-cursor-mode t)

Show empty lines

(setq indicate-empty-lines t)

Highlight the current light

(global-hl-line-mode 1)

Line Numbers

I like line numbers. They help quite a bit with moving around.

(global-display-line-numbers-mode)

Visible Bell

I don’t want to hear a blip every time I do something wrong, so I’m turning on the visible bell.

(setq visible-bell t)

Uniquify

If I have two buffers open with two files that have the same name, (e.g. two different README files from two different projects), Emacs will, by default, name the buffers README and README<1>. This is useless. Therefore, I turn on uniquify and use it to name buffers with the same file name based on their parent directories: README<projdir1> and README<projectdir2>.

(use-package uniquify
  :defer t
  :config
  (setq uniquify-buffer-name-style 'post-forward-angle-brackets))

Ido and Icomplete

Here I configure Ido and Icomplete. Ido gives improved file finding and buffer switching. Icomplete gives improved command execution with M-x.

(use-package icomplete
  :config
  (icomplete-mode))
(use-package ido
  :config
  (ido-mode 1)
  (ido-everywhere 1)
  (setq ido-enable-flex-matching t))

Evil

Update: At the moment, I have Evil disabled. I’m seeing how I get by without it. I might learn that I no longer need or want it. However, just in case, I leaving my config here, disabled through use-package. (Have I mentioned how awesome use-package is?)

Call me heathen if you wish, but I prefer Vim navigation keys. Also, I want Ido buffer switching and file finding when using Vim’s :b and :e.

Evil website

(use-package evil
  :disabled
  :ensure t
  :after (key-chord)
  :config
  (setq evil-default-cursor '(t))
  (evil-mode 1)
  (define-key evil-ex-map "b " 'ido-switch-buffer)
  (define-key evil-ex-map "e " 'ido-find-file)
  (key-chord-define evil-insert-state-map "jk" 'evil-normal-state)
  (key-chord-define evil-motion-state-map "jk" 'evil-normal-state)
  (key-chord-define evil-visual-state-map "jk" 'evil-normal-state)
  (key-chord-define evil-emacs-state-map "jk" 'evil-normal-state))

Using key-chord-mode, I have the vim equivalent of imap jk <Esc>, which allows me to use jk instead of Esc to get out of insert mode.

(use-package key-chord
  :disabled
  :ensure t
  :config
  (key-chord-mode 1))

To make things even easier, I set up a “leader key” of Space, so that I can type Space <letter> to run a command. For instance, Space x instead of M-x to execute commands.

(use-package evil-leader
  :disabled
  :ensure t
  :after (evil)
  :config
  (evil-leader/set-leader "<SPC>")
  (evil-leader/set-key "x" 'execute-extended-command)
  (evil-leader/set-key ":" 'eval-expression)
  (evil-leader/set-key "k" 'ido-kill-buffer)
  (evil-leader/set-key "p" 'projectile-commander)
  (evil-leader/set-key "d" 'dired)
  (evil-leader/set-key "e" 'er/expand-region)
  (evil-leader/set-key "m" 'mc/mark-more-like-this-extended)
  (evil-leader/set-key "s" 'string-inflection-toggle)
  (evil-leader/set-key "r" 'xref-find-definitions)
  (evil-leader/set-key "?" 'xref-find-references)
  (global-evil-leader-mode))

Let’s make sure we have “surround” support.

(use-package evil-surround
  :disabled
  :ensure t
  :config
  (global-evil-surround-mode 1))

Finally, there are some modes that I want to always be in Emacs mode instead of Evil.

Major modes:

(setq evil-emacs-state-modes
      '(archive-mode bbdb-mode bookmark-bmenu-mode bookmark-edit-annotation-mode browse-kill-ring-mode bzr-annotate-mode calc-mode cfw:calendar-mode completion-list-mode Custom-mode debugger-mode delicious-search-mode desktop-menu-blist-mode desktop-menu-mode doc-view-mode dvc-bookmarks-mode dvc-diff-mode dvc-info-buffer-mode dvc-log-buffer-mode dvc-revlist-mode dvc-revlog-mode dvc-status-mode dvc-tips-mode ediff-mode ediff-meta-mode efs-mode Electric-buffer-menu-mode emms-browser-mode emms-mark-mode emms-metaplaylist-mode emms-playlist-mode etags-select-mode fj-mode gc-issues-mode gdb-breakpoints-mode gdb-disassembly-mode gdb-frames-mode gdb-locals-mode gdb-memory-mode gdb-registers-mode gdb-threads-mode gist-list-mode git-rebase-mode gnus-article-mode gnus-browse-mode gnus-group-mode gnus-server-mode gnus-summary-mode google-maps-static-mode ibuffer-mode jde-javadoc-checker-report-mode magit-popup-mode magit-popup-sequence-mode magit-commit-mode magit-revision-mode magit-diff-mode magit-key-mode magit-log-mode magit-mode magit-reflog-mode magit-show-branches-mode magit-branch-manager-mode magit-stash-mode magit-status-mode magit-wazzup-mode magit-refs-mode mh-folder-mode monky-mode mu4e-main-mode mu4e-headers-mode mu4e-view-mode notmuch-hello-mode notmuch-search-mode notmuch-show-mode occur-mode org-agenda-mode package-menu-mode proced-mode rcirc-mode rebase-mode recentf-dialog-mode reftex-select-bib-mode reftex-select-label-mode reftex-toc-mode sldb-mode slime-inspector-mode slime-thread-control-mode slime-xref-mode sr-buttons-mode sr-mode sr-tree-mode sr-virtual-mode tar-mode tetris-mode tla-annotate-mode tla-archive-list-mode tla-bconfig-mode tla-bookmarks-mode tla-branch-list-mode tla-browse-mode tla-category-list-mode tla-changelog-mode tla-follow-symlinks-mode tla-inventory-file-mode tla-inventory-mode tla-lint-mode tla-logs-mode tla-revision-list-mode tla-revlog-mode tla-tree-lint-mode tla-version-list-mode twittering-mode urlview-mode vc-annotate-mode vc-dir-mode vc-git-log-view-mode vc-svn-log-view-mode vm-mode vm-summary-mode w3m-mode wab-compilation-mode xgit-annotate-mode xgit-changelog-mode xgit-diff-mode xgit-revlog-mode xhg-annotate-mode xhg-log-mode xhg-mode xhg-mq-mode xhg-mq-sub-mode xhg-status-extra-mode cider-repl-mode emacsagist-mode elfeed-show-mode elfeed-search-mode notmuch-tree term-mode xref--xref-buffer-mode))

Winner-mode

Winner-mode makes it really easy to handle window changes in Emacs. C-c left-arrow goes back to the previous window configuration (undo), and C-c right-arrow goes forward (redo). This is especially helpful for when a popup window ruins your layout. Simply C-c left-arrow to get back to where you were.

(use-package winner
  :defer 5
  :config
  (winner-mode 1))

pbcopy

Clipboard sharing. Copy in Emacs, paste in OS X, and vice versa.

pbcopy source

(use-package pbcopy
  :ensure t
  :defer t
  :config
  (turn-on-pbcopy))

Minibuffer

This little snippet adds eldoc support to the minibuffer. Requires Emacs 24.4 or later. Found on EndlessParenthesis.com.

(add-hook 'eval-expression-minibuffer-setup-hook #'eldoc-mode)

Expand Region

This package makes it easy to select regions based on various bounds: words, braces, etc.

(use-package expand-region
  :ensure t
  :bind (("C-=" . er/expand-region)))

Programming

General

Indent with 4 spaces, not a tab stop.

(setq-default c-basic-offset 4)
(setq-default tab-width 4)
(setq-default indent-tabs-mode nil)

Git

Magit is awesome.

(use-package magit
  :ensure t)

Show changes in the gutter/fringe.

(use-package git-gutter-fringe
  :ensure t
  :if window-system
  :config
  (global-git-gutter-mode))

(use-package git-gutter
  :ensure t
  :if (not window-system)
  :config
  (global-git-gutter-mode 1))

Projectile

Projectile is, quite simply and objectively, the shit. There’s no other way to put it. I consider it pretty much necessary for working with full projects (as opposed to individual, unrelated files).

Projectile on Github

(use-package projectile
  :ensure t
  :defer 5
  :init
  (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
  :config
  (projectile-global-mode))

Completion

Who doesn’t like a little auto-completion? I choose to use company instead of auto-complete (aka ac). This decision is based on lots of reading about both and comparing/trying out both.

(use-package company
  :ensure t
  :bind (("C-<tab>" . company-complete))
  :config
  (global-company-mode)
  (setq company-dabbrev-downcase nil)
  (setq company-dabbrev-ignore-case t))

Search

The Silver Searcher (ag) is awesome. Using it, Emacs is even more awesome! Also, with this installed, Projectile can use it, as well. What a perfect match!

This requires that you have The Silver Searcher installed on your computer.

(use-package ag
  :ensure t)

Paredit

If you write any form of Lisp and don’t use paredit, change that. It does so much for you and helps out in so many ways. I highly recommend it, even though it is quite weird (and, honestly, sometimes frustrating) at first.

Paredit website

Emacs Rocks episode on paredit

(use-package paredit
  :ensure t
  :defer t
  :hook ((emacs-lisp-mode clojure-mode) . paredit-mode))

PHP

Let’s start with adding basic PHP handling.

(use-package php-mode
  :ensure t
  :config
  (add-hook 'php-mode-hook 'flymake-mode)
  (add-hook 'php-mode-hook 'php-enable-symfony2-coding-style))

Next, let’s improve completion. This sets up ac-php to give better PHP specific completions with company.

(use-package company-php
  :ensure t)

(use-package ac-php
  :ensure t
  :after (php-mode company-php)
  :init
  (bind-key "C-c ]" 'ac-php-find-symbol-at-point php-mode-map)
  (bind-key "C-c [" 'ac-php-location-stack-back php-mode-map)
  :config
  (add-hook 'php-mode-hook
            '(lambda ()
               (require 'company-php)
               (company-mode t)
               (ac-php-core-eldoc-setup)
               (make-local-variable 'company-backends)
               (add-to-list 'company-backends 'company-ac-php-backend))))

Now, let’s set up php-cs-fixer so that it automatically fixes our PHP files on save.

Note that I have a config file for this set with M-x customize, not seen in this config.

(use-package php-cs-fixer
  :ensure t
  :config
  (require 'cl)
  (add-hook 'before-save-hook 'php-cs-fixer-before-save))

Of course, we want to be able to debug our PHP files. That’s where geben comes in.

Note that some geben config, like path mappings, I have done with M-x customize, so they do not appear in this file.

(use-package geben
  :ensure t
  :defer t)

Finally, let’s get a lot more detailed and IDE-like functionality with LSP in Emacs.

I currently have this disabled because it isn’t working properly.

(use-package lsp-mode
  :disabled
  :ensure t
  :commands lsp
  :init
  (add-hook 'php-mode-hook #'lsp)
)

(use-package lsp-ui
  :disabled
  :ensure t
  :commands lsp-ui-mode)

(use-package company-lsp
  :disabled
  :ensure t
  :commands company-lsp)

JavaScript

The built-in JS support in Emacs is lacking.

(use-package js2-mode
  :ensure t
  :defer t
  :mode "\\.js\\'")

(use-package json-mode
  :ensure t
  :defer t
  :mode "\\.json\\'")

Web

As far as I can tell, web-mode is the best mode for dealing with web files like HTML, Twig, etc.

(use-package web-mode
  :ensure t
  :mode (("\\.html\\'" . web-mode)
        ("\\.twig\\'" . web-mode)))

YAML

Syntax highlighting for YAML files is nice, too.

(use-package yaml-mode
  :ensure t
  :mode "\\.ya?ml\\'")

Clojure

The ultimate experience for Clojure development: cider!

(use-package cider
  :ensure t)

Org-mode

This customizes org-mode a bit. For instance, I like my org files to have auto-fill turned on.

(defun my-org-mode-hook ()
  (auto-fill-mode))
(add-hook 'org-mode-hook 'my-org-mode-hook)

Fun Packages

Encouragement

(use-package encourage-mode
  :ensure t
  :config
  (encourage-mode t))

Miscellaneous Functions

Toggle Window Split

This is a quite useful function that will change a frame with two horizontal windows into a frame with two vertical windows and vice versa.

;; http://www.emacswiki.org/emacs/ToggleWindowSplit
(defun toggle-window-split ()
  (interactive)
  (if (= (count-windows) 2)
      (let* ((this-win-buffer (window-buffer))
             (next-win-buffer (window-buffer (next-window)))
             (this-win-edges (window-edges (selected-window)))
             (next-win-edges (window-edges (next-window)))
             (this-win-2nd (not (and (<= (car this-win-edges)
                                         (car next-win-edges))
                                     (<= (cadr this-win-edges)
                                         (cadr next-win-edges)))))
             (splitter
              (if (= (car this-win-edges)
                     (car (window-edges (next-window))))
                  'split-window-horizontally
                'split-window-vertically)))
        (delete-other-windows)
        (let ((first-win (selected-window)))
          (funcall splitter)
          (if this-win-2nd (other-window 1))
          (set-window-buffer (selected-window) this-win-buffer)
          (set-window-buffer (next-window) next-win-buffer)
          (select-window first-win)
          (if this-win-2nd (other-window 1))))))
(define-key ctl-x-4-map "t" 'toggle-window-split)

Individual Customization

Any customization that is machine specific or does not belong in git can go in custom.el. This file is ignored from git and is where all changes from M-x customize are saved.

(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerror)

Theme

I set my theme through M-x customize. That way, it doesn’t require changes to this init file.

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