You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
495 lines
17 KiB
495 lines
17 KiB
# -*- fill-column:78 -*- |
|
#+TITLE: emacs init file |
|
#+AUTHOR: Jacopo De Simoi |
|
#+EMAIL: jacopods@math.utoronto.ca |
|
#+OPTIONS: *:t ::t |
|
|
|
* TODO Look at tangling at |
|
[http://thewanderingcoder.com/2015/02/literate-emacs-configuration/] |
|
|
|
although I'd rather do something like a local variable evaluation such as |
|
# -*- eval: (add-hook 'before-save-hook 'org-icalendar-export-to-ics nil t) -*- |
|
Or makefile approach |
|
[https://emacs.stackexchange.com/questions/27126/is-it-possible-to-org-bable-tangle-an-org-file-from-the-command-line] |
|
|
|
See also [http://orgmode.org/manual/Extracting-source-code.html#Extracting-source-code] |
|
|
|
|
|
* Some remarks and comments |
|
** ~setq~ vs ~setq-default~ |
|
Some variables are buffer-local, others are not; for non buffer-local |
|
variables the two commands are equivalent; for the buffer-local variables, |
|
setq acts on the current buffer, whereas setq-default sets the default |
|
value of the variable for buffers that do not have a local value. |
|
|
|
:source: [https://stackoverflow.com/a/18173666] |
|
|
|
** Why not ~package.el~ |
|
it is convenient, but it is not git-based; ~borg.el~ is promising, but it is |
|
way complicated; I can do everything by hand as soon as it is neatly |
|
~org~-anized |
|
|
|
* Files and dirs |
|
Move ~Customize~ to a separate file |
|
#+BEGIN_SRC emacs-lisp |
|
(setq custom-file "~/.emacs.d/custom.el") |
|
(load custom-file 'noerror) |
|
#+END_SRC |
|
Add relevant dirs to load path [This is somewhat undesirable; I should |
|
uniformize the path-loading business at some point…] |
|
#+BEGIN_SRC emacs-lisp |
|
(let ((default-directory "~/.emacs.d/")) |
|
(normal-top-level-add-subdirs-to-load-path) |
|
(normal-top-level-add-to-load-path '("fringe-helper.el" |
|
"multiple-cursors.el" |
|
"expand-region.el" |
|
"dash.el"))) |
|
#+END_SRC |
|
Put autosave files (ie #foo#) and backup files (ie foo~) in ~/.emacs.d/. |
|
create the autosave dir if necessary, since emacs won't. |
|
#+BEGIN_SRC emacs-lisp |
|
(make-directory "~/.emacs.d/autosaves/" t) |
|
(make-directory "~/.emacs.d/backup/" t) |
|
#+END_SRC |
|
|
|
* Themes |
|
Use (my clone of) the solarized theme |
|
#+BEGIN_SRC emacs-lisp |
|
(add-to-list 'custom-theme-load-path "/home/jacopods/.emacs.d/emacs-color-theme-solarized") |
|
(load-theme 'solarized t) |
|
#+END_SRC |
|
Use patched terminus font (this overrides the settings in Customize, but I |
|
never could it to work otherwise). See the special treatment later on for |
|
dealing with bold weight. To avoid flickering one should also set the font |
|
in .Xresources |
|
#+BEGIN_SRC emacs-lisp |
|
(set-face-font 'default "-xos4-hackminus-medium-r-normal--20-200-72-72-c-100-ISO10646-1") |
|
#+END_SRC |
|
|
|
* Global settings |
|
** Cosmetics |
|
Prefer a minimal appearance: no menu, toolbar or scroll-bars; no |
|
splash screens or messages |
|
#+BEGIN_SRC emacs-lisp |
|
(menu-bar-mode -1) |
|
(tool-bar-mode 0) |
|
(scroll-bar-mode -1) |
|
(setq inhibit-startup-screen t |
|
inhibit-startup-message t) |
|
#+END_SRC |
|
a blinking cursor keeps the gpu awake; add global hl-line mode to more |
|
easily spot the cursor |
|
#+BEGIN_SRC emacs-lisp |
|
(blink-cursor-mode 0) |
|
(set-default 'cursor-type 'box) |
|
(global-hl-line-mode t) |
|
#+END_SRC |
|
Set frame title |
|
#+BEGIN_SRC emacs-lisp |
|
(setq frame-title-format |
|
'((buffer-file-name "%f" |
|
(dired-directory dired-directory "%b")) " · emacs"));; · " (:eval (kde-current-activity-name)))) ;; "%S")) |
|
#+END_SRC |
|
Themed tooltips |
|
#+BEGIN_SRC emacs-lisp |
|
(setq x-gtk-use-system-tooltips nil) |
|
#+END_SRC |
|
Set Fill-column to ~78~, which happens to be good for third-tiled frames |
|
and it also is a reasonable standard (almost 80) |
|
#+BEGIN_SRC emacs-lisp |
|
(setq default-fill-column 78) |
|
#+END_SRC |
|
** Mouseless |
|
Disable mouse interaction with emacs |
|
#+BEGIN_SRC emacs-lisp |
|
(setq mouse-autoselect-window nil) |
|
(mouse-wheel-mode -1) |
|
(setq mouse-yank-at-point nil) |
|
(setq focus-follows-mouse nil) |
|
#+END_SRC |
|
*** TODO Find out what of the above is necessary given the disable-mouse mode below |
|
Use the ~disable-mouse~ package by Steve Purcell available at |
|
[https://github.com/purcell/disable-mouse] |
|
#+BEGIN_SRC emacs-lisp |
|
(require 'disable-mouse) |
|
(global-disable-mouse-mode) |
|
#+END_SRC |
|
** Window behavior |
|
Prevent compilation window eating up other windows |
|
#+BEGIN_SRC emacs-lisp |
|
(setq compilation-scroll-output t |
|
compilation-window-height 12) |
|
#+END_SRC |
|
Prevent any automatic splitting to split vertically |
|
#+BEGIN_SRC emacs-lisp |
|
(setq split-width-threshold nil) |
|
#+END_SRC |
|
** Scrolling |
|
Scrolling setup |
|
#+BEGIN_SRC emacs-lisp |
|
(setq redisplay-dont-pause t |
|
scroll-margin 3 |
|
scroll-step 1 |
|
scroll-conservatively 10000 |
|
scroll-preserve-screen-position 1) |
|
#+END_SRC |
|
|
|
*** TODO find out what this was actually meant to do |
|
#+BEGIN_SRC emacs-lisp |
|
(setq-default display-buffer-reuse-frames t) |
|
#+END_SRC |
|
|
|
** Modeline |
|
#+BEGIN_SRC emacs-lisp |
|
(setq-default mode-line-modified '(:eval (if (buffer-modified-p) "●" "·"))) ;still needs some improvements, |
|
;does not report Readonly state |
|
(setq-default mode-line-remote '(:eval (let ((s (format-mode-line "%@"))) |
|
(cond |
|
((equal s "-") "·") ((equal s "@") "@") (t s))))) |
|
|
|
(defvar wilder-buffer-vc-mode-line |
|
'("%b" (vc-mode (:propertize |
|
;; Strip the backend name from the VC status information |
|
(:eval (let* ((backend (downcase (symbol-name (vc-backend (buffer-file-name))))) |
|
(branch (substring vc-mode (+ (length backend) 2))) |
|
(s (substring vc-mode (+ (length backend) 1) (+ (length backend) 2))) |
|
(status (cond ((equal s "-") "") ((equal s ":") "!") (t s)))) |
|
(concat "·" branch status))) |
|
face font-lock-comment-face)))) |
|
(put 'wilder-buffer-vc-mode-line 'risky-local-variable t) |
|
|
|
(defvar wilder-position |
|
'("[%p,%I] " )) |
|
|
|
(put 'wilder-position 'risky-local-variable t) |
|
|
|
(setq-default mode-line-format |
|
'("%e" |
|
mode-line-front-space |
|
mode-line-mule-info |
|
mode-line-client |
|
mode-line-modified |
|
mode-line-remote |
|
mode-line-frame-identification |
|
wilder-buffer-vc-mode-line " " |
|
wilder-position " " |
|
mode-line-modes |
|
mode-line-misc-info |
|
mode-line-end-spaces)) |
|
#+END_SRC |
|
** Mark handling |
|
No transient mark is more flexible |
|
#+BEGIN_SRC emacs-lisp |
|
(transient-mark-mode 0) |
|
#+END_SRC |
|
But of course we need to /see/ the mark |
|
#+BEGIN_SRC emacs-lisp |
|
(require 'visible-mark) |
|
(visible-mark-mode t) |
|
(global-visible-mark-mode t) |
|
#+END_SRC |
|
|
|
The following are some convenient bindings; notice that on my layout F13 and |
|
F14 are obtained by tapping the left and right shift respectively |
|
#+BEGIN_SRC emacs-lisp |
|
(global-set-key (kbd "<f13>") 'set-mark-command) |
|
(global-set-key (kbd "<f14>") 'set-mark-command) |
|
|
|
(defun jump-to-mark () |
|
"Jumps to the local mark, respecting the `mark-ring' order. |
|
This is the same as using \\[set-mark-command] with the prefix argument." |
|
(interactive) |
|
(set-mark-command 1)) |
|
(global-set-key (kbd "<M-f13>") 'jump-to-mark) |
|
(global-set-key (kbd "<M-f14>") 'jump-to-mark) |
|
|
|
(defun just-activate-mark () |
|
(interactive) |
|
(activate-mark)) |
|
(global-set-key (kbd "<S-f13>") 'just-activate-mark) |
|
(global-set-key (kbd "<S-f14>") 'just-activate-mark) |
|
#+END_SRC |
|
** Global bindings |
|
Remove some supremely annoying bindings |
|
#+BEGIN_SRC emacs-lisp |
|
(global-unset-key (kbd "C-z")) |
|
(global-unset-key (kbd "C-x f")) |
|
(global-unset-key (kbd "<M-f4>")) ; rly? |
|
#+END_SRC |
|
Change {up,down}-list |
|
#+BEGIN_SRC emacs-lisp |
|
(global-unset-key (kbd "C-M-u")) |
|
(global-unset-key (kbd "C-M-d")) |
|
(global-set-key (kbd "C-M-i") 'down-list) ;; -i stands for /in/ |
|
(global-set-key (kbd "C-M-o") 'up-list) ;; -o stands for /out/ |
|
#+END_SRC |
|
Add some opinionated bindings |
|
#+BEGIN_SRC emacs-lisp |
|
(global-set-key (kbd "C-M-d") 'kill-sexp) |
|
(global-set-key (kbd "C-M-<backspace>") 'backward-kill-sexp) |
|
(global-set-key (kbd "C-x k") 'kill-this-buffer) |
|
(global-set-key (kbd "C-S-v") 'scroll-down-command) |
|
#+END_SRC |
|
** Smart beginning-of-line |
|
This is a relatively smart way to go back to the beginning of the line |
|
#+BEGIN_SRC emacs-lisp |
|
(defun smart-line-beginning () |
|
"Move point to the beginning of text on the current line; if that |
|
is already the current position of point, then move it to the |
|
beginning of the line." |
|
(interactive) |
|
(let ((pt (point))) |
|
(beginning-of-line-text) |
|
(when (eq pt (point)) |
|
(beginning-of-line)))) |
|
(global-set-key (kbd "C-a") 'smart-line-beginning) |
|
#+END_SRC |
|
** Whitespace |
|
Trailing whitespace is evil; get rid of it |
|
#+BEGIN_SRC emacs-lisp |
|
(setq-default show-trailing-whitespace t) |
|
(add-hook 'before-save-hook 'delete-trailing-whitespace) |
|
#+END_SRC |
|
Define what is whitespace during a search |
|
#+BEGIN_SRC emacs-lisp |
|
(setq search-whitespace-regexp "[ \t\r\n]+") |
|
#+END_SRC |
|
Tabs are evil; get rid of them |
|
#+BEGIN_SRC emacs-lisp |
|
(setq c-basic-offset 4) |
|
(setq tab-width 4) |
|
(setq indent-tabs-mode nil) |
|
#+END_SRC |
|
*** TODO Have a look at ws-trim.el |
|
It is conf'ble to avoid removing whitespace from lines that were not |
|
modified; sounds like a good idea for git |
|
[ftp://ftp.lysator.liu.se/pub/emacs/ws-trim.el] |
|
|
|
** Show matching parens |
|
Use mic-paren for paren-highlighting |
|
#+BEGIN_SRC emacs-lisp |
|
; (setq show-paren-mode t) |
|
(require 'mic-paren) |
|
(paren-activate) |
|
#+END_SRC |
|
*** TODO find out if there are better options out there |
|
** Abbrevs |
|
Set up abbrevs |
|
#+BEGIN_SRC emacs-lisp |
|
(setq-default abbrev-mode t) |
|
(read-abbrev-file "~/.abbrev_defs") |
|
(setq save-abbrevs t) |
|
#+END_SRC |
|
** Spellcheck |
|
Use flyspell |
|
#+BEGIN_SRC emacs-lisp |
|
(add-hook 'text-mode-hook 'flyspell-mode) |
|
(setq flyspell-use-meta-tab nil) |
|
#+END_SRC |
|
** Fringe treatment |
|
*** TODO try linum-relative |
|
#+BEGIN_SRC emacs-lisp |
|
(require 'linum-relative) |
|
(linum-relative-mode 1) |
|
#+END_SRC |
|
Add line numbers globally |
|
#+BEGIN_SRC emacs-lisp |
|
(global-linum-mode 1) |
|
#+END_SRC |
|
Highlight also the linum in the fringe |
|
#+BEGIN_SRC emacs-lisp |
|
(require 'hlinum) |
|
(hlinum-activate) |
|
#+END_SRC |
|
Add marker for current line in the fringe (see |
|
[https://github.com/kyanagi/fringe-current-line]) |
|
#+BEGIN_SRC emacs-lisp |
|
;; (require 'fringe-current-line) |
|
;; (global-fringe-current-line-mode 1) |
|
;; (setq fcl-fringe-bitmap 'right-triangle) |
|
#+END_SRC |
|
|
|
** Turn on echo mode |
|
Display unfinished commands in the echo area after the specified delay. |
|
#+BEGIN_SRC emacs-lisp |
|
(setq echo-keystrokes 0.10) |
|
#+END_SRC |
|
** Disable completion buffer |
|
Remove the completion buffer as soon as we get out of the minibuffer |
|
#+BEGIN_SRC emacs-lisp |
|
(add-hook 'minibuffer-exit-hook |
|
'(lambda () |
|
(let ((buffer "*Completions*")) |
|
(and (get-buffer buffer) |
|
(kill-buffer buffer))) )) |
|
#+END_SRC |
|
** Auto save on compile |
|
#+BEGIN_SRC emacs-lisp |
|
(setq compilation-ask-about-save nil) |
|
#+END_SRC |
|
* Main packages |
|
** Magit |
|
Set main binding |
|
#+BEGIN_SRC emacs-lisp |
|
(global-set-key (kbd "C-x C-g") 'magit-status) |
|
#+END_SRC |
|
** Outshine |
|
#+BEGIN_SRC emacs-lisp |
|
(require 'outshine) |
|
(add-hook 'outline-minor-mode-hook 'outshine-hook-function) |
|
(setq outshine-use-speed-commands t) |
|
(defvar outline-minor-mode-prefix "\M-#") |
|
(eval-after-load 'outshine '(define-key outline-minor-mode-map (kbd "C-M-i") nil)) |
|
;; (add-hook 'sh-mode-hook 'outline-minor-mode) |
|
#+END_SRC |
|
** helm |
|
#+BEGIN_SRC emacs-lisp |
|
(require 'helm-config) |
|
(helm-mode 1) |
|
(global-set-key (kbd "M-x") 'helm-M-x) |
|
(global-set-key (kbd "C-x C-f") 'helm-find-files) |
|
(global-set-key (kbd "C-x b") 'helm-mini) |
|
(global-set-key (kbd "C-x C-b") 'helm-mini) |
|
(global-set-key (kbd "M-y") 'helm-show-kill-ring) |
|
(define-key helm-map (kbd "C-h") nil) |
|
(define-key helm-find-files-map (kbd "C-h") nil) |
|
(define-key helm-find-files-map (kbd "C-<backspace>") nil) |
|
#+END_SRC |
|
** multiple-cursors |
|
#+BEGIN_SRC emacs-lisp |
|
(require 'multiple-cursors) |
|
(define-key mc/keymap (kbd "<return>") nil) |
|
|
|
(global-set-key (kbd "C->") 'mc/mark-next-like-this) |
|
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this) |
|
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this) |
|
|
|
(global-set-key (kbd "H-.") 'mc/mark-next-like-this) |
|
(global-set-key (kbd "H-,") 'mc/mark-previous-like-this) |
|
(global-set-key (kbd "<H-f13>") 'mc/mark-pop) |
|
(global-set-key (kbd "<H-f14>") 'mc/mark-pop) |
|
(global-set-key (kbd "H-#") 'mc/insert-numbers) |
|
#+END_SRC |
|
** avy |
|
#+BEGIN_SRC emacs-lisp |
|
(global-set-key (kbd "C-c SPC") 'avy-goto-word-or-subword-1) |
|
(global-set-key (kbd "M-s") 'avy-goto-word-or-subword-1) |
|
(global-set-key (kbd "M-g M-g") 'avy-goto-line) |
|
(global-set-key (kbd "M-g g") 'avy-goto-line) |
|
#+END_SRC |
|
** Atomic chrome |
|
#+BEGIN_SRC emacs-lisp |
|
;;(require 'atomic-chrome) |
|
;;(atomic-chrome-start-server) |
|
#+END_SRC |
|
* Leftovers |
|
#+BEGIN_SRC emacs-lisp |
|
;; * include other files |
|
(load "init-latex.el") |
|
(load "init-org.el") |
|
(load "init-c++.el") |
|
(load "init-elisp.el") |
|
(load "init-kde-integration.el") |
|
|
|
;; KDE stuff |
|
|
|
(load "qml-mode.el" nil t t) |
|
(add-to-list 'auto-mode-alist '("\\.qml\\'" . qml-mode)) |
|
#+END_SRC |
|
|
|
** DONE find out how kde-emacs makes “make” actually work |
|
I need to keep this up until I realize what I need to make “make” work |
|
Please notice that kde-emacs forces the menu to show; |
|
|
|
#+BEGIN_SRC emacs-lisp |
|
;; (require 'kde-emacs) |
|
;; (menu-bar-mode -1) |
|
#+END_SRC |
|
** Leftovers |
|
#+BEGIN_SRC emacs-lisp |
|
;; * smart-tab-mode |
|
(require 'smart-tab) |
|
(global-smart-tab-mode 1) |
|
(global-set-key (kbd "C-j") 'smart-tab) ;; try this; I never use C-j for goto-line |
|
|
|
;; * load expand-region |
|
|
|
(require 'expand-region) |
|
(global-set-key (kbd "C-=") 'er/expand-region) |
|
|
|
;; * construct emacs-session so with session-id |
|
(defun emacs-session-filename (session-id) |
|
"Construct a filename to save the session in based on SESSION-ID. |
|
If the directory ~/.emacs.d exists, we make a filename in there, otherwise |
|
a file in the home directory." |
|
(let ((basename (concat "sessions/session." session-id)) |
|
(emacs-dir user-emacs-directory)) |
|
(expand-file-name (if (file-directory-p emacs-dir) |
|
(concat emacs-dir basename) |
|
(concat "~/.emacs-" basename))))) |
|
|
|
;; * Time stamps |
|
;; write |
|
;; Time-stamp: <> |
|
;; in your file and save it to see time stamps at work. |
|
;; Other time stamp format: "%a %b %e, %Y %l:%M %p" |
|
(add-hook 'write-file-hooks 'time-stamp) |
|
(setq time-stamp-active t) |
|
(setq time-stamp-format "%:a %02d %:b %:y, %02H:%02M:%02S, %u") |
|
(setq european-calendar-style 't) |
|
;; first day of the week is monday instead of sunday: |
|
(setq calendar--week--start--day 1) |
|
|
|
;; * toorg |
|
(require 'highlight-sexps) |
|
|
|
(require 'package) |
|
(add-to-list 'package-archives |
|
'("melpa-stable" . "http://stable.melpa.org/packages/") t) |
|
|
|
;; (eval-after-load 'tramp '(setenv "SHELL" "/bin/bash")) |
|
|
|
;; Use system proxy |
|
(setq url-proxy-services '(("http" . "127.0.0.1:8118"))) |
|
|
|
(defun flash-hline () |
|
(let ((fg (face-foreground 'default)) |
|
(bg (face-background 'hl-line))) |
|
(set-face-background 'hl-line fg) |
|
(run-with-timer |
|
0.1 nil (lambda () |
|
(set-face-background 'hl-line "#303030") )))) |
|
|
|
(global-set-key (kbd "<f15>") 'flash-hline) |
|
|
|
|
|
;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph |
|
(defun unfill-paragraph (&optional region) |
|
"Takes a multi-line paragraph and makes it into a single line of text." |
|
(interactive (progn (barf-if-buffer-read-only) '(t))) |
|
(let ((fill-column (point-max)) |
|
;; This would override `fill-column' if it's an integer. |
|
(emacs-lisp-docstring-fill-column t)) |
|
(fill-paragraph nil region))) |
|
|
|
(defun select-frame-on-current-activity () |
|
(select-frame-on-activity (kde-current-activity)) |
|
) |
|
|
|
;; * start server named after kde activity name |
|
(setq server-name (kde-current-activity-name)) |
|
;; mmh |
|
;; (set-face-font 'default "-xos4-hackminus-medium-r-normal--20-200-72-72-c-100-ISO10646-1") ; |
|
;; Why is the above needed down here? |
|
;; |
|
;; Because it sets the face for packages that have loaded in the meantime; |
|
;; it does not wark perfectly as some packages are still to be loaded |
|
;; (most notably magit) |
|
|
|
(mapc |
|
(lambda (face) |
|
(set-face-attribute face nil :weight 'normal) |
|
(set-face-attribute face nil :slant 'normal)) |
|
(face-list)) |
|
(server-start) |
|
#+END_SRC
|
|
|