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.
 
 
 

41 KiB

emacs init file

TODO Uniformize indentation

Introduction

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. In the end we use a few, but I plan to phase them out and replace them with git submodules

Files and dirs

Move Customize to a separate file

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

Add relevant dirs to load path [This is somewhat undesirable; I should uniformize the path-loading business at some point…]

  (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")))

Put autosave files (ie #foo#) and backup files (ie foo~) in ~/.emacs.d/. create the autosave dir if necessary, since emacs won't.

  (make-directory "~/.emacs.d/autosaves/" t)
  (make-directory "~/.emacs.d/backup/" t)

Themes

Use (my clone of) the solarized theme

  (add-to-list 'custom-theme-load-path "/home/jacopods/.emacs.d/emacs-color-theme-solarized")
  (load-theme 'solarized t)

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

  (set-face-font 'default "-xos4-hackminus-medium-r-normal--20-200-72-72-c-100-ISO10646-1")

Global settings

Cosmetics

Prefer a minimal appearance: no menu, toolbar or scroll-bars; no splash screens or messages

  (menu-bar-mode -1)
  (tool-bar-mode 0)
  (scroll-bar-mode -1)
  (setq inhibit-startup-screen t
        inhibit-startup-message t)

a blinking cursor keeps the gpu awake; add global hl-line mode to more easily spot the cursor

  (blink-cursor-mode 0)
  (set-default 'cursor-type 'box)
  (global-hl-line-mode t)

Set frame title

  (setq frame-title-format
     '((buffer-file-name "%f"
         (dired-directory dired-directory "%b")) " · emacs"));; · " (:eval (kde-current-activity-name)))) ;; "%S"))

Themed tooltips

(setq x-gtk-use-system-tooltips nil)

Set Fill-column to 78, which happens to be good for third-tiled frames and it also is a reasonable standard (almost 80)

  (setq default-fill-column 78)

Highlight sexp (apparently I am not even using this)

  ;(require 'highlight-sexps)

Mouseless

Disable mouse interaction with emacs

  (setq mouse-autoselect-window nil)
  (mouse-wheel-mode -1)
  (setq mouse-yank-at-point nil)
  (setq focus-follows-mouse nil)

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]

  (require 'disable-mouse)
  (global-disable-mouse-mode)

Window behavior

Prevent compilation window eating up other windows

   (setq compilation-scroll-output t
         compilation-window-height 12)

Prevent any automatic splitting to split vertically

  (setq split-width-threshold nil)

Scrolling

Scrolling setup

   (setq redisplay-dont-pause t
         scroll-margin 3
         scroll-step 1
         scroll-conservatively 10000
         scroll-preserve-screen-position 1)

TODO find out what this was actually meant to do

  (setq-default display-buffer-reuse-frames t)

Modeline

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

Coding system

Prefer the utf-8 coding system globally. This helps with the issue of magit not correctly staging hunks containing utf-8 characters. See [https://github.com/magit/magit/issues/32]

  (prefer-coding-system 'utf-8)

Mark handling

No transient mark is more flexible

(transient-mark-mode 0)

But of course we need to see the mark

(require 'visible-mark)
(visible-mark-mode t)
(global-visible-mark-mode t)

The following are some convenient bindings; notice that on my layout F13 and F14 are obtained by tapping the left and right shift respectively

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

Global bindings

Remove some supremely annoying bindings

  (global-unset-key (kbd "C-z"))
  (global-unset-key (kbd "C-x f"))
  (global-unset-key (kbd "<M-f4>")) ; rly?

Change {up,down}-list

  (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/

Add some opinionated bindings

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

Smart beginning-of-line

This is a relatively smart way to go back to the beginning of the line

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

Whitespace

Trailing whitespace is evil; get rid of it

  (setq-default show-trailing-whitespace t)
  (add-hook 'before-save-hook 'delete-trailing-whitespace)

Define what is whitespace during a search

     (setq search-whitespace-regexp "[ \t\r\n]+")

Tabs are evil; get rid of them

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

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

;     (setq show-paren-mode t)
  (require 'mic-paren)
  (paren-activate)

TODO find out if there are better options out there

Abbrevs

Set up abbrevs

   (setq-default abbrev-mode t)
   (read-abbrev-file "~/.abbrev_defs")
   (setq save-abbrevs t)

Spellcheck

Use flyspell

   (add-hook 'text-mode-hook 'flyspell-mode)
   (setq flyspell-use-meta-tab nil)

Fringe treatment

TODO try linum-relative

;      (require 'linum-relative)
;      (linum-relative-mode 1)

Add line numbers globally

;    (global-linum-mode 1)

Highlight also the linum in the fringe

;    (require 'hlinum)
;    (hlinum-activate)

Add marker for current line in the fringe (see [https://github.com/kyanagi/fringe-current-line])

   (require 'fringe-current-line)
   (global-fringe-current-line-mode 1)
   (setq fcl-fringe-bitmap 'right-triangle)

Turn on echo mode

Display unfinished commands in the echo area after the specified delay.

  (setq echo-keystrokes 0.10)

Disable completion buffer

Remove the completion buffer as soon as we get out of the minibuffer

  (add-hook 'minibuffer-exit-hook
            '(lambda ()
               (let ((buffer "*Completions*"))
                 (and (get-buffer buffer)
                      (kill-buffer buffer))) ))

Auto save on compile

  (setq compilation-ask-about-save nil)

Calendar

(add-hook 'calendar-load-hook
  (lambda ()
  (calendar-set-date-style 'european)))
;; first day of the week is monday instead of sunday:
(setq calendar-week-start-day 1)
(setq calendar-location-name "Toronto, ON Canada")
(setq calendar-latitude 43.7)
(setq calendar-longitude -79.4)

Use system proxy

     ;; Use system proxy
    (setq url-proxy-services '(("http" . "127.0.0.1:8118")))

Main major modes

org-mode

Require

Require the org package; I also occasionally use org-pomodoro

 (require 'org)
 (require 'org-pomodoro)

Hooks

Enable auto-fill-mode (see [https://www.gnu.org/software/emacs/manual/html_node/emacs/Auto-Fill.html]) honestly I do not see where I would not want to use this.

  (add-hook 'org-mode-hook (lambda ()
    (turn-on-auto-fill)))

Revert orgzly buffers on agenda refresh

  (advice-add 'org-agenda-redo :before 'org-revert-all-orgzly-buffers)

Agenda

Set the canonical binding for the agenda

 (global-set-key (kbd "C-c a") 'org-agenda)

Define agenda files: the main one is notes.org, but then I have a bunch of them on orgzly

  (setq org-agenda-files
  '("~/org/notes.org"
    "~/org/orgzly/work.org"
    "~/org/orgzly/hack.org"
    "~/org/orgzly/live.org"
    "~/org/orgzly/refile.org"))

Default to daily agenda

  (setq org-agenda-span 1)

Ideally I should tag some tasks as “break” tasks, which are suitable to be taken care of during a pomodoro break. Such tasks should be marked with tags :5m: and :20m: according to the estimate on the time it would take to take care of them

  (setq org-agenda-custom-commands
  '(
  ("a" "Main agenda"
  ((agenda "")
  (todo "NEXT|ONGOING")
  (tags-todo "hack")
  (tags-todo "5m")
  (todo "TODO")))
  ("h" "Agenda and Android tasks"
  ((agenda "")
  (tags-todo "Android")))
  ("5" "Agenda and Break tasks"
  ((agenda "")
  (tags-todo "5m")
  (tags-todo "20m")))))

Reverting stuff from orgzly

  (defun org-revert-all-orgzly-buffers ()
    "Revert all Org buffers that are sitting in orgzly
  Prompt for confirmation when there are unsaved changes.  Be sure
  you know what you are doing before letting this function
  overwrite your changes."
    (interactive)
    (message "Reverting Orgzly buffers…")
    (save-excursion
      (save-window-excursion
        (dolist (b (buffer-list))
          (when (and (with-current-buffer b (derived-mode-p 'org-mode))
                     (with-current-buffer b buffer-file-name)
                     (with-current-buffer b (string-match-p "orgzly" default-directory)))
            (with-current-buffer b (print buffer-file-name))
            (pop-to-buffer-same-window b)
            (revert-buffer t 'no-confirm)))
        (when (and (featurep 'org-id) org-id-track-globally)
          (org-id-locations-load)))))

Capture

Set default keybinding

  (global-set-key (kbd "C-c c") 'org-capture)

This is my capture template: it needs to be revised as I really do not use The Idea, journal and break entry

 (setq org-default-notes-file "~/org/notes.org")
 (setq org-capture-templates
'(("t" "TODO today" entry (file+headline "~/org/notes.org" "Tasks")
   "* TODO %?\n  SCHEDULED: %t" :clock-in t :clock-resume t)
  ("n" "TODO next" entry (file+headline "~/org/notes.org" "Tasks")
   "* NEXT %?\n  " :clock-in t :clock-resume t)
  ("T" "TODO" entry (file+headline "~/org/notes.org" "Tasks")
   "* TODO %?\n  %a" :clock-in t :clock-resume t)
  ("i" "Idea" entry (file+headline "~/org/notes.org" "Ideas")
   "* IDEA %?\n  %u" :clock-in t :clock-resume t	 )
  ("j" "Journal" entry (file+datetree "~/org/notes.org")
  "* %?\n%U\n" :clock-in t :clock-resume t)
  ("b" "Break" entry (file+datetree "~/org/notes.org")
  "* break %?\n" :clock-in t :clock-resume t)
  ("e" "Mail To" entry (file+headline "~/org/notes.org" "E-mails")
   "* DONE mailto:%?")
  ("r" "Reply to" entry (file+headline "~/org/notes.org" "E-mails")
   "* DONE mailto:%?")))

Source blocks

Add template for a source block in emacs-lisp. This is useful for writing the emacs init file in literate form

 (add-to-list 'org-structure-template-alist
'("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC"))

Fontify src blocks

  (setq org-src-fontify-natively t)

Clocking

 ;; Separate drawers for clocking and logs
 (setq org-drawers (quote ("PROPERTIES" "CLOCKBOOK")))
 ;; Save clock data and state changes and notes in the CLOCK drawer
 (setq org-clock-into-drawer "CLOCKBOOK")
 ;; Sometimes I change tasks I'm clocking quickly - this removes clocked tasks with 0:00 duration
 (setq org-clock-out-remove-zero-time-clocks t)
 ;; Clock out when moving task to a done state
 (setq org-clock-out-when-done t)

 (setq org-clock-persist 'history)

 (setq org-duration-format 'h:mm)
 (setq org-clock-clocktable-default-properties '(:maxlevel 2 :scope subtree))
 (org-clock-persistence-insinuate)

Tangle to different files

This is some some super-clever stuff. See [https://emacs.stackexchange.com/questions/39032/tangle-the-same-src-block-to-different-files]

(defun org-babel-tangle-collect-blocks-handle-tangle-list (&optional language tangle-file)
  "Can be used as :override advice for `org-babel-tangle-collect-blocks'.
Handles lists of :tangle files."
  (let ((counter 0) last-heading-pos blocks)
(org-babel-map-src-blocks (buffer-file-name)
(let ((current-heading-pos
  (org-with-wide-buffer
   (org-with-limited-levels (outline-previous-heading)))))
(if (eq last-heading-pos current-heading-pos) (cl-incf counter)
(setq counter 1)
(setq last-heading-pos current-heading-pos)))
(unless (org-in-commented-heading-p)
(let* ((info (org-babel-get-src-block-info 'light))
(src-lang (nth 0 info))
(src-tfiles (cdr (assq :tangle (nth 2 info))))) ; Tobias: accept list for :tangle
(unless (consp src-tfiles) ; Tobias: unify handling of strings and lists for :tangle
 (setq src-tfiles (list src-tfiles))) ; Tobias: unify handling
(dolist (src-tfile src-tfiles) ; Tobias: iterate over list
 (unless (or (string= src-tfile "no")
(and tangle-file (not (equal tangle-file src-tfile)))
(and language (not (string= language src-lang))))
   ;; Add the spec for this block to blocks under its
   ;; language.
   (let ((by-lang (assoc src-lang blocks))
(block (org-babel-tangle-single-block counter)))
 (setcdr (assoc :tangle (nth 4 block)) src-tfile) ; Tobias:
 (if by-lang (setcdr by-lang (cons block (cdr by-lang)))
   (push (cons src-lang (list block)) blocks)))))))) ; Tobias: just ()
;; Ensure blocks are in the correct order.
(mapcar (lambda (b) (cons (car b) (nreverse (cdr b)))) blocks)))

(defun org-babel-tangle-single-block-handle-tangle-list (oldfun block-counter &optional only-this-block)
  "Can be used as :around advice for `org-babel-tangle-single-block'.
If the :tangle header arg is a list of files. Handle all files"
  (let* ((info (org-babel-get-src-block-info))
(params (nth 2 info))
(tfiles (cdr (assoc :tangle params))))
(if (null (and only-this-block (consp tfiles)))
(funcall oldfun block-counter only-this-block)
(cl-assert (listp tfiles) nil
  ":tangle only allows a tangle file name or a list of tangle file names")
(let ((ret (mapcar
   (lambda (tfile)
(let (old-get-info)
(cl-letf* (((symbol-function 'old-get-info) (symbol-function 'org-babel-get-src-block-info))
   ((symbol-function 'org-babel-get-src-block-info)
    `(lambda (&rest get-info-args)
(let* ((info (apply 'old-get-info get-info-args))
   (params (nth 2 info))
   (tfile-cons (assoc :tangle params)))
  (setcdr tfile-cons ,tfile)
  info))))
(funcall oldfun block-counter only-this-block))))
   tfiles)))
(if only-this-block
 (list (cons (cl-caaar ret) (mapcar #'cadar ret)))
ret)))))

(advice-add 'org-babel-tangle-collect-blocks :override #'org-babel-tangle-collect-blocks-handle-tangle-list)
(advice-add 'org-babel-tangle-single-block :around #'org-babel-tangle-single-block-handle-tangle-list)

TODO split — LaTeX

Require

Load auctex, reftex and set up related hooks

 (load "auctex.el" nil t t)
 (require 'reftex)
 (add-hook 'LaTeX-mode-hook 'turn-on-reftex)

Set default TeX options

 (setq-default TeX-master nil)
 (setq TeX-auto-save t
TeX-parse-self t
TeX-insert-braces nil)

Appearance

No fontification for sub and superscripts

  (setq font-latex-fontify-script nil)

Default labels

 (setq LaTeX-equation-label "e_"
       LaTeX-section-label "s_"
       LaTeX-figure-label "f_")

Spell checking help

Do not spell-check inside the following commands. See [https://tex.stackexchange.com/questions/117204/skip-spelling-in-emacs-for-the-content-of-a-user-macro]

(setq ispell-tex-skip-alists
(list
(append
(car ispell-tex-skip-alists) ;tell ispell to ignore content of this:
'(("\\\\eqref"       ispell-tex-arg-end)
("\\\\cite"       ispell-tex-arg-end)
("\\\\author"       ispell-tex-arg-end)
("\\\\address"       ispell-tex-arg-end)
))
(cadr ispell-tex-skip-alists)))

Specialty functions

This function adds a pair of delimiters or surrounds the active region with the given delimiters.

TODO it breaks when there is no mark
  (defun add-delimiter (delim-begin delim-end r-begin r-end)
"Add the pair of delimiters given in delim at the ends of the
  region if it is activated"
(interactive "cBegin delimiter: \ncEnd delimiter: \nr")
(if (use-region-p)
(progn
 (save-excursion
   (goto-char r-end) (insert delim-end)
   (goto-char r-begin) (insert delim-begin)))
(progn
 (save-excursion
   (insert delim-end))
 (insert delim-begin))))

TODO Leftovers

 (setq TeX-fold-ellipsis " …")

 ;; I lost track of what does this guy do?
 (defun my-LaTeX-mode-dollars ()
   (font-lock-add-keywords
    nil
`((,(rx "$") (0 'success t)))
t))
 (add-hook 'LaTeX-mode-hook 'my-LaTeX-mode-dollars)

 (defun dabbrev-expand-helper ()
   (interactive)
   (call-interactively 'dabbrev-expand))

 (add-hook 'LaTeX-mode-hook
    (lambda ()
(turn-on-auto-fill)
(subword-mode)
(TeX-fold-mode 1)
(outline-minor-mode)
;; Move around commands in the Right Way™
(modify-syntax-entry ?\\ "w" LaTeX-mode-syntax-table)
(setq subword-forward-regexp "\\W*\\(\\([\\\\[:upper:]]*\\W?\\)[[:lower:][:digit:]]*\\)")
(setq subword-backward-regexp "\\(\\(\\W\\|[[:lower:][:digit:]]\\)\\([\\\\[:upper:]]+\\W*\\)\\|\\W\\w+\\)")
;; ;; FIXME: this breaks sourcepair for other modes.
;; (setq sourcepair-source-extensions '(".tex"))
;; (setq sourcepair-header-extensions '(".p.tex"))

(define-key LaTeX-mode-map (kbd "C-c C-v")
 (lambda (arg)
   (interactive "P")
   (insert "~")
   (if arg (TeX-insert-macro "eqref")
     (TeX-insert-macro "ref"))))
(define-key LaTeX-mode-map (kbd "C-M-<return>")
 (lambda (arg)
   (interactive "P")
   (if arg (LaTeX-insert-environment "align")
     (LaTeX-insert-environment "align*"))))

;; EXPERIMENTAL: try C-RETURN → DEL
;; (define-key LaTeX-mode-map (kbd "S-SPC") 'backward-delete-char-untabify) ;;(lambda() (interactive) (flash-hline)));;(message "Use C-SPC")));;'backward-delete-char-untabify)

;; EXPERIMENTAL: unbind return - NOTE it is important to unbind <return> and not RET. If we
;; unbind RET then C-m won't work either.
(define-key LaTeX-mode-map (kbd "<return>") (lambda() (interactive) (insert "\\")))
(define-key LaTeX-mode-map (kbd "S-<return>") (lambda() (interactive) (insert "|")))
;;(define-key LaTeX-mode-map (kbd "C-SPC") (lambda() (interactive) (insert "\\")))
(define-key LaTeX-mode-map (kbd "M-S-SPC") 'TeX-insert-braces)
(define-key LaTeX-mode-map (kbd "s-SPC") (lambda() (interactive) (insert "~")))

;; why this got dropped?
(define-key LaTeX-mode-map (kbd "C-c C-.") 'LaTeX-mark-environment)

;; Go with strict mode
 ;	    (define-key LaTeX-mode-map (kbd "_") (lambda() (interactive) (flash-hline) (message "Use C-c C-k")))
(define-key LaTeX-mode-map (kbd "M-_") (lambda() (interactive) (flash-hline) (message "Use C-c C-k")))
(define-key LaTeX-mode-map (kbd "C-c C-k") (lambda (r-begin r-end) (interactive "r") (add-delimiter "_{" "}" r-begin r-end)))
 ;	    (define-key LaTeX-mode-map (kbd "^") (lambda() (interactive) (flash-hline) (message "Use C-c C-i")))
(define-key LaTeX-mode-map (kbd "M-^") (lambda() (interactive) (flash-hline) (message "Use C-c C-i")))
(define-key LaTeX-mode-map (kbd "C-c C-i") (lambda (r-begin r-end) (interactive "r") (add-delimiter "^{" "}" r-begin r-end)))

(define-key LaTeX-mode-map (kbd "M-|") (lambda (r-begin r-end) (interactive "r") (add-delimiter "|" "|" r-begin r-end)))
(define-key LaTeX-mode-map (kbd "M-,") (lambda (r-begin r-end) (interactive "r") (add-delimiter ", " ", " r-begin r-end)))
(define-key LaTeX-mode-map (kbd "M-\"") (lambda (r-begin r-end) (interactive "r") (add-delimiter "“" "”" r-begin r-end)))

;; This is the rationale: C-M-SPC starts inline math C-M-RET starts display math
(define-key LaTeX-mode-map (kbd "C-M-SPC") (lambda (r-begin r-end) (interactive "r") (add-delimiter "$" "$" r-begin r-end)))
(define-key LaTeX-mode-map (kbd "C-c C-d")
 (lambda (arg r-begin r-end) (interactive "P\nr")
   (if arg
(add-delimiter "\\todo[inline]{" "}{}" r-begin r-end)
     (add-delimiter "\\todo{" "}{}" r-begin r-end))))
(define-key LaTeX-mode-map (kbd "C-M-d") 'kill-sexp)
(define-key LaTeX-mode-map (kbd "C-M-i") 'down-list) ;; -i stands for /in/
(define-key LaTeX-mode-map (kbd "C-M-o") 'up-list)	  ;; -o stands for /out/

(define-key LaTeX-mode-map (kbd "<f4>") (lambda() (interactive) (message "Use C-c C-c")))
(define-key LaTeX-mode-map (kbd "C-c C-c") (lambda() (interactive) (compile "make -k")) );;'make)

(define-key LaTeX-mode-map (kbd "=") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "≠") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd ">") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "<") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "≥") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "≤") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "⇒") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "∩") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "∪") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "∨") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "∧") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "×") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "⊂") 'insert-char-with-padding)
(define-key LaTeX-mode-map (kbd "⊃") 'insert-char-with-padding)

;; Force moves around to be more “semantic”
(define-key LaTeX-mode-map (kbd "C-v") 'forward-paragraph);(lambda() (interactive) (message "Command disabled")))
(define-key LaTeX-mode-map (kbd "M-v") 'backward-paragraph)
(define-key LaTeX-mode-map (kbd "C-S-v") 'backward-paragraph)
 ; (lambda() (interactive) (message "Command disabled")))
(define-key LaTeX-mode-map (kbd "<next>") (lambda() (interactive) (message "Command disabled")))
(define-key LaTeX-mode-map (kbd "<prior>") (lambda() (interactive) (message "Command disabled")))
))

 ;; this reimplements TeX-insert-braces to work with negative argument
 (defun TeX-insert-braces (arg)
   "Make a pair of braces around next ARG sexps and leave point inside.
 No argument is equivalent to zero: just insert braces and leave point
 between.

 If there is an active region, ARG will be ignored, braces will be
 inserted around the region, and point will be left after the
 closing brace."
   (interactive "P")
   (if (TeX-active-mark)
(progn
  (if (< (point) (mark))
(exchange-point-and-mark))
  (insert TeX-grcl)
  (save-excursion
    (goto-char (mark))
    (insert TeX-grop)))
(if (and arg (< arg 0))
  (progn
    (save-excursion
(backward-sexp (prefix-numeric-value (- 0 arg)))
(insert TeX-grop))
    (insert TeX-grcl))
(insert TeX-grop)
(save-excursion
(if arg (forward-sexp (prefix-numeric-value arg)))
(insert TeX-grcl)))))

 (defun TeX-back-insert-braces (arg)
   (interactive "P")
   (if arg (TeX-insert-braces (- 0 arg))
(insert TeX-grcl)))

 (defun insert-char-with-padding (arg)
   (interactive "*P")
   (if (string= (string (preceding-char)) " ") ()
(if (string= (string (preceding-char)) "\&") () (insert " ")))
   (self-insert-command (prefix-numeric-value arg))
   (if (string= (string (following-char)) " ") () (insert " ")) ;; decide what to do with the point
 )


 ;; this reimplements LaTeX-insert-environment to my taste
 ;;
 (defun LaTeX-insert-environment (environment &optional extra)
   "Insert LaTeX ENVIRONMENT with optional argument EXTRA."
   (let ((active-mark (and (TeX-active-mark) (not (eq (mark) (point)))))
  prefix content-start env-start env-end)
(when (and active-mark (< (mark) (point))) (exchange-point-and-mark))
;; Compute the prefix.
(when (and LaTeX-insert-into-comments (TeX-in-commented-line))
(save-excursion
  (beginning-of-line)
  (looking-at
   (concat "^\\([ \t]*" TeX-comment-start-regexp "+\\)+[ \t]*"))
  (setq prefix (match-string 0))))
;; What to do with the line containing point.
(cond
;; if the line is made of blanks, erase them and start on the same line
((save-excursion (beginning-of-line)
(looking-at (concat prefix "[ \t]*$")))
(delete-region (match-beginning 0) (match-end 0)))
;; if after the point there are only blanks, erase them and dont add extra newline
((looking-at "[ \t]*$")
(delete-horizontal-space)
(newline))
((TeX-looking-at-backward (concat "^" prefix "[ \t]*")
    (line-beginning-position))
(beginning-of-line)
(newline)
(beginning-of-line 0));; if we are at the beginning of the line (maybe with some spaces
((bolp)
(delete-horizontal-space)
(newline)
(beginning-of-line 0))
((eolp)
(delete-horizontal-space)
(newline)
)
(t
(delete-horizontal-space)
(newline 2)
(when prefix (insert prefix))
(beginning-of-line 0)))
;; What to do with the line containing mark.
(when active-mark
(save-excursion
  (goto-char (mark))
  (cond ((save-excursion (beginning-of-line)
    (or (looking-at (concat prefix "[ \t]*$"))
	(looking-at "[ \t]*$")))
  (delete-region (match-beginning 0) (match-end 0)))
 ((TeX-looking-at-backward (concat "^" prefix "[ \t]*")
	     (line-beginning-position))
  (beginning-of-line)
  (newline)
  (beginning-of-line 0))
 (t
  (delete-horizontal-space)
  (insert-before-markers "\n")
  (newline)
  (when prefix (insert prefix))))))
;; Now insert the environment.
(when prefix (insert prefix))
(setq env-start (point))
(insert TeX-esc "begin" TeX-grop environment TeX-grcl)
(indent-according-to-mode)
(when extra (insert extra))
(setq content-start (line-beginning-position 2))
(unless active-mark
(newline)
(when prefix (insert prefix))
(newline))
(when active-mark (goto-char (mark)))
(when prefix (insert prefix))
(insert TeX-esc "end" TeX-grop environment TeX-grcl "%")
(end-of-line 0)
(if active-mark
  (progn
    (or (assoc environment LaTeX-indent-environment-list)
 (LaTeX-fill-region content-start (line-beginning-position 2)))
    (set-mark content-start))
(indent-according-to-mode))
(save-excursion (beginning-of-line 2) (indent-according-to-mode))
(TeX-math-input-method-off)
(setq env-end (save-excursion
(search-forward
 (concat TeX-esc "end" TeX-grop
  environment TeX-grcl))
(match-beginning 0)))
;; The following apparently does not work.
;; (indent-region env-start env-end)
(fill-paragraph)
(run-hook-with-args 'LaTeX-after-insert-env-hooks
    environment env-start env-end)))


 (load "latex-compile-filters.el")

 ;; * add bibretrieve
 (byte-recompile-directory "~/.emacs.d/bibretrieve" 0)
 (load "bibretrieve")

TODO C and C++

Hooks

  (require 'doxymacs)

  (add-hook 'c-mode-hook (lambda ()
  (subword-mode)
  (doxymacs-mode)
  (define-key c-mode-map (kbd "C-c C-c") 'make)
  (define-key c++-mode-map (kbd "C-c C-c") 'make)))
  (add-hook 'c++-mode-hook (lambda ()
  (subword-mode)
  (doxymacs-mode)
  (define-key c-mode-map (kbd "C-c C-c") 'make)
  (define-key c++-mode-map (kbd "C-c C-c") 'make)))

TODO KDE integration

TODO cleanup and split

  (defun kde-current-activity ()
"Returns the current KDE activity"
(substring (shell-command-to-string "qdbus org.kde.ActivityManager /ActivityManager/Activities org.kde.ActivityManager.Activities.CurrentActivity") 0 -1)
  )

  (defun kde-current-activity-name ()
"Returns the name of the current KDE activity"
(substring (shell-command-to-string (concat "qdbus org.kde.ActivityManager /ActivityManager/Activities org.kde.ActivityManager.Activities.ActivityName " (kde-current-activity))) 0 -1))

  (defun X-window-id-belongs-to-activity (window-id activity)
(= (shell-command (concat "xprop -id " window-id " | grep  _KDE_NET_WM_ACTIVITIES | grep " activity ">/dev/null")) 0)
  )

  (defun select-frame-on-activity (activity)
(setq framelist (frame-list))
(setq done nil)
(while (and framelist (not done))
(setq cur (car framelist))
(setq cur-id (cdr (assq 'window-id (frame-parameters cur))))
(if cur-id (if (X-window-id-belongs-to-activity cur-id activity) (progn;
  (setq done 't) (select-frame cur)) ))
(setq framelist (cdr framelist)))
done
  )

  (defun select-X-frame ()
(setq framelist (frame-list))
(setq done nil)
(while (and framelist (not done))
(setq cur (car framelist))
(setq cur-id (cdr (assq 'window-id (frame-parameters cur))))
(if cur-id (progn;
 (setq done 't) (raise-frame cur)))
(setq framelist (cdr framelist)))
done
  )

This function is used to raise the frame associated to the current activity

TODO These entries should be added to the subtree once it is split

  (defun select-frame-on-current-activity ()
  (select-frame-on-activity (kde-current-activity)))

I prefer to keep one server for each KDE activity, so set the server name to be the name of the current activity

  (setq server-name (kde-current-activity-name))

TODO elisp

Replace last sexp

I use this a lot to evaluate (e.g.) quick computations in files

  (defun replace-last-sexp ()
(interactive)
(let ((value (eval (preceding-sexp))))
(kill-sexp -1)
(insert (format "%S" value))))
  (global-set-key (kbd "C-c C-x C-e") 'replace-last-sexp)

TODO qml

Load qml-mode

  (load "qml-mode.el" nil t t)
  (add-to-list 'auto-mode-alist '("\\.qml\\'" . qml-mode))

Specialties

flash-hline

This function is defined to help in training with new keybindings. It acts as a visual bell which flashes the current line. It is (arbitrarily) bound to F15 which is supposed to be triggered by some “illegal” key hit

    (defun flash-hline ()
    "Flash the current line to emph some mistake"
    (interactive)
   (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)

unfill-paragraph

This is authored by 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)))

Main packages

Magit

  (global-set-key (kbd "C-x C-g") 'magit-status)

smart-tab

This package is a gem: it allows to make tab work dwim

(require 'smart-tab)
(global-smart-tab-mode 1)

Outshine

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

helm

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

multiple-cursors

(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 "C-c <f13>") 'mc/mark-pop)
(global-set-key (kbd "C-c <f14>") 'mc/mark-pop)

avy

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

expand-region

This is an excellent package, although I do not use it that much I should find a better binding

 (require 'expand-region)
 (global-set-key (kbd "C-=") 'er/expand-region)

Atomic chrome

(require 'atomic-chrome)
(atomic-chrome-start-server)

TODO Phase out Package.el

Load package.el

  (require 'package)
  (add-to-list 'package-archives
 '("melpa-stable" . "http://stable.melpa.org/packages/") t)

Tidy-up

Save emacs-session files in appropriate directory

Save session files to the sessions directory so that they do not litter the .emacs.d base directory.

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

Finale

Fixup faces

This is really a workaround as I do not like either bold or italic. It needs to be at the end of the file since it sets the face for packages that have loaded in the meantime; yet it does not wark perfectly as some packages are still to be loaded (most notably magit)

;; (set-face-font 'default "-xos4-hackminus-medium-r-normal--20-200-72-72-c-100-ISO10646-1")

 (mapc
    (lambda (face)
(set-face-attribute face nil :weight 'normal)
(set-face-attribute face nil :slant 'normal))
    (face-list))

Start server

  (server-start)