No description, website, or topics provided.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
readme.org

readme.org

Emacs

Package locations

Sources

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

Custom local path

(add-to-list 'load-path "/home/m/.emacs.d/personal/packages/")

Edit Emacs

Assuming this file is located outside ~/.emacs.d for backup purposes, copy this file back when it gets saved.

(defun m/onsave_emacs()
  
  (let (
        (m/pwd "/home/m/auricio/boot/emacs/emacs.org") ;; editing path
        (m/emacsd "/home/m/.emacs.d/")) ;; load path
    
    (when (string= buffer-file-name m/pwd)
      (copy-file m/pwd m/emacsd t)
      (message (concat "Copied to " m/emacsd)))))

(add-hook 'after-save-hook 'm/onsave_emacs)

Whenever I save my personal theme, which I keep in an org-mode document, tangle and recompile it, copy it back to a place recognized by custom-theme-load-path, and load back the theme into existance.

(add-to-list 'custom-theme-load-path "/home/m/.emacs.d/personal/theme/")

(defun m/onsave_theme()
  
  (let (
        (m/themepath "/home/m/auricio/boot/emacs/theme/") ;; editing path
        (m/themename "personal") ;; theme name
        (m/themenameload 'personal) ;; argument to load-theme
        (m/themeload "/home/m/.emacs.d/personal/theme/") ;; load path
        )

        (when (string= buffer-file-name (concat m/themepath m/themename "-theme.org"))
          (org-babel-tangle-file
           (concat m/themepath m/themename "-theme.org")
           (concat m/themepath m/themename "-theme.el"))
          (byte-recompile-directory m/themepath)
          (copy-directory m/themepath m/themeload nil nil t)
          (load-theme m/themenameload t)
          (message "Reloaded Theme")))
          )
    
(add-hook 'after-save-hook 'm/onsave_theme)
    

Basic look

Load theme

(load-theme 'personal t)

Remove basic visual elements

(setq inhibit-splash-screen t) ;; No intro
(tool-bar-mode -1) ;; No toolbar
(menu-bar-mode -99) ;; No menubar
(setq visible-bell 1) ;; No bells
(set-scroll-bar-mode nil) ;; No vertical scrollbar
(setq horizontal-scroll-bar-mode nil) ;; No horizontal scrollbar
(setq-default line-number-mode nil)
(setq-default mode-line-format " ") ;; The simplest modeline

Display words like you would expect in a modern editor

;; UTF-8
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq default-buffer-file-coding-system 'utf-8)
;; Wrap words
(global-visual-line-mode t)
;; Highlight the cursor line
(global-hl-line-mode 1)
(setq-default cursor-type 'box)
;; Line spacing
(setq-default line-spacing 3)

Have a huge fringe for visual comfort

(fringe-mode '(40 . 40))

Some visual elements are specific to writing, programming or temporary buffers, so I classify these.

(setq 
 m/writing_modes
 '(
   org-mode-hook
   pollen-mode-hook
   )
 m/programming_modes
 '(
   js-mode-hook
   python-mode-hook
   html-mode-hook
   c-mode-hook
   css-mode-hook
   ruby-mode-hook
   sh-mode-hook
   kotlin-mode-hook
   racket-mode-hook
   conf-mode-hook
   text-mode-hook
   fundamental-mode-hook
   emacs-lisp-mode-hook
   )
 m/temporary_modes
 '(
   lisp-interaction-mode-hook
   Man-mode-hook
   ))

A header for every type of buffer

(defun m/orgmodeheader ()
  (if (string-match-p ".*\\.org\-." (buffer-name))
      (nth 0 (split-string (nth 1 (split-string (buffer-name) ".org-")) "-"))
    (nth 0 (split-string (file-name-nondirectory (buffer-file-name)) "\\."))))
;; Display filename without extension or org-mode title or header name (in an indirect buffer)
(defun m/headerclean ()
  (setq header-line-format
        '("     "
	  (:eval (m/orgmodeheader))
	  )))
;; Display filename
(defun m/headerfilename()
  (setq header-line-format
	'("     "
	  (:eval (file-name-nondirectory (buffer-file-name)))
	  )))
;; Display buffer name
(defun m/headerbuffername ()
  (setq header-line-format
	'("     "
	  (:eval (buffer-name))
	  )))
;; Apply header to modes
(defun m/header-apply (modes header)
  (dolist (m/mode modes)
    (add-hook m/mode header)))
;; Apply
(m/header-apply m/writing_modes 'm/headerclean)
(m/header-apply m/programming_modes 'm/headerfilename)
(m/header-apply m/temporary_modes 'm/headerbuffername)

Line numbers only for programming buffers

(setq linum-format "  %d ")
;; Disable line numbers
(defun m/islinum(modes linumstate)
  (cond
   ((= linumstate 0)
    (dolist (m/mode modes)
      (add-hook m/mode (lambda ()
                         (linum-mode 0)))))
   ((= linumstate 1)
    (dolist (m/mode modes)
      (add-hook m/mode (lambda ()
                         (linum-mode 1)))))))

;; Apply
(m/islinum m/writing_modes 0)
(m/islinum m/temporary_modes 0)
(m/islinum m/programming_modes 1)

Edit buffers

Write over the selected range

(delete-selection-mode 1)

Move cursor up and down

(global-set-key (kbd "<up>") 'previous-line)
(global-set-key (kbd "<down>") 'next-line)
(setq-default line-move-visual nil)
(global-set-key (kbd "<end>") 'end-of-line)
(global-set-key (kbd "<home>") 'beginning-of-line)

Scroll up and down

;; Mouse scrolling
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))
(setq mouse-wheel-progressive-speed nil)
(setq mouse-wheel-follow-mouse 't)
(setq scroll-step 1)
;; Keyboard scrolling
(defun m/scrolldown ()
  (interactive)
  (scroll-up 1))
(defun m/scrollup ()
  (interactive)
  (scroll-down 1))
;; Keys to scroll
(global-set-key [(next)] 'm/scrolldown)
(global-set-key [(prior)]   'm/scrollup)

Undo

(global-set-key (kbd "C-z") 'undo)

Select all

(global-set-key (kbd "C-a")  'mark-whole-buffer)
(define-key org-mode-map [(control a)] 'mark-whole-buffer)

Search

(with-eval-after-load 'helm-regexp
  (setq helm-source-occur
        (helm-make-source "Occur" 'helm-source-multi-occur :follow 1)))

(define-key global-map (kbd "C-s") 'helm-occur)

Avoid automatic backup files

(setq make-backup-files nil)
(setq auto-save-default nil)
(setq create-lockfiles nil)

Revert buffer when changed on disk

(global-auto-revert-mode 1)

Window operations

Resize this window

(defhydra m/windowresize (:hint nil)
  "← ↑ → ↓"
  ("<left>" (shrink-window-horizontally 10))
  ("<right>" (enlarge-window-horizontally 10))
  ("<up>" (enlarge-window 10))
  ("<down>" (shrink-window 10))
  ("q" nil)
  )
(global-set-key (kbd "M-r") 'm/windowresize/body)

Kill this buffer

(global-set-key (kbd "C-x k") 'kill-this-buffer)

Navigate buffers

Move focus to other displayed windows

(global-set-key (kbd "M-s-<left>")  'windmove-left)
(global-set-key (kbd "M-s-<right>") 'windmove-right)
(global-set-key (kbd "M-s-<up>")    'windmove-up)
(global-set-key (kbd "M-s-<down>")  'windmove-down)

Cycle through work buffers in order of recency

;; Set swbuff
(require 'swbuff)
(setq swbuff-recent-buffers-first t)
(setq swbuff-separator " · ")
;; Exclude these buffers
(setq swbuff-exclude-buffer-regexps
      '("^ "
        "^\\*Messages\\*$"
        "^\\*Buffer List\\*$"
        "^\\*Backtrace\\*$"
        "^\\*Warnings\\*$"
        "^\\*WoMan-Log\\*$"
        "^\\*Compile-Log\\*$"
        "^\\*tramp/.+\\*$"
        "^\\*Faces\\*$"
        "^\\*evil-marks\\*$"
        "^\\*evil-registers\\*$"
        "^\\*Shell Command Output\\*$"
        "^\\*helm[- ].+\\*$"
        "^\\*magit\\(-\\w+\\)?: .+$"
        "^\\*irc\\..+\\*$"))
;; Keys to cycle
(global-set-key [(C-next)] 'swbuff-switch-to-next-buffer)
(global-set-key [(C-prior)]   'swbuff-switch-to-previous-buffer)

Go straight to a desired buffer

;; Set helm
(require 'helm)
(require 'helm-config)
(helm-mode 1)
(setq helm-full-frame nil)
(setq helm-split-window-in-side-p t)
(setq helm-split-window-default-side 'below)
;; Avoid buffer details
(setq helm-buffer-details-flag 'nil)
;; Exclude these buffers
(setq helm-boring-buffer-regexp-list
      '("\\*helm"
        "\\*helm-mode"
        "\\*Echo Area"
        "\\*Minibuf"
        "\\ *code-conversion-work\\*"
        "org-src-fontification.+"
        "\\*helm-mode.+"
        "\\*Compile-Log"
        "\\*Org-Babel Error"))
;; Keys to navigate
(global-set-key (kbd "M-SPC") 'helm-mini)

Go straight to a set of bookmarks

(global-set-key (kbd "C-M-SPC") 'helm-filtered-bookmarks)

Open new buffer

(global-set-key (kbd "C-x C-f") 'helm-find-files)

Manage sessions

Save buffer list

(desktop-save-mode 1)

Save cursor state

(require 'saveplace)
(setq-default save-place t)

Discover functions

Search all interactive functions in a context

(define-key global-map (kbd "<menu>") 'helm-M-x)

Search the web

Google selection by C-c / RET RET, opens on Firefox

(google-this-mode 1)

Search Wikipedia for a selection by M-s M-w, opens on eww

(setq eww-search-prefix "https://en.m.wikipedia.org/w/index.php?search=")

Org mode

Headings

Display heading trees like modern outlines

;; Indent headings
(setq org-startup-indented t)
;; Only show one bullet per heading
(setq org-hide-leading-stars t)
;; Show pretty bullets
(add-hook 'org-mode-hook (lambda ()
                           (require 'org-bullets)
                           (org-bullets-mode 1)
                           (setq org-bullets-bullet-list '( "·" "·" "·" "·" "·"))))
;; Don't display any special symbol if the heading is collapsed
(setq org-ellipsis " ")
;; Separate collapsed headings by one line
(setq org-cycle-separator-lines 1)
;; Apply heading background to the whole line
(setq org-fontify-whole-heading-line t)

Cycle through headings

(define-key org-mode-map [(control shift down)]  'outline-next-visible-heading)
(define-key org-mode-map [(control shift up)]  'outline-previous-visible-heading)

Move straight to any heading or link to it

;; Link to a heading
(defun m/orgheadinglink (marker)
  (with-current-buffer (marker-buffer marker)
    (let (
          (heading-name
           (save-excursion
             (goto-char
              (marker-position marker))
             (nth 4 (org-heading-components))))
          (file-name
           (buffer-file-name)))
      (with-helm-current-buffer
        (org-insert-link
         file-name
         (concat "file:" file-name "::*" heading-name)
         (concat "" heading-name)))
      )))
;; Set actions for helm headings list
(setq helm-org-headings-actions '(
                                  ("Go to" . helm-org-goto-marker) ;; default go to
                                  ("Insert link" . m/orgheadinglink) ;; available link to
                                  ))
;; Headings in the list are displayed along with their path 
(setq helm-org-format-outline-path t)
;; Key to list
(define-key org-mode-map (kbd "C-/") 'helm-org-in-buffer-headings)

Make a buffer from current heading to focus

(setq org-indirect-buffer-display 'current-window)
(defun m/orgfocus ()
  (interactive)
  (let ((current-prefix-arg 4))
    (call-interactively #'org-tree-to-indirect-buffer)))
(define-key org-mode-map (kbd "<insert>") 'm/orgfocus)

Source blocks

Apply a different font between text and blocks

(add-hook 'org-mode-hook (lambda ()
                           (variable-pitch-mode)))

Syntax highlight and don’t unnecessarily indent source blocks

(setq org-src-fontify-natively t)
(setq-default org-edit-src-content-indentation 0)

Display pretty block begin and end lines

(setq-default prettify-symbols-alist '(
				       ("#+TITLE:". "")
				       (":PROPERTIES:" . ":")
				       ("#+BEGIN_SRC" . "λ") 
				       ("#+END_SRC" . "")
				       ("#+RESULTS:" . "»")
				       (":END:" . "")
				       (":RESULTS:" . "")
				       ("#+NAME:" . "")
				       ("#+BEGIN_EXAMPLE" . "~")
				       ("#+END_EXAMPLE" . "~")
				       ("#+TBLFM:" . "")
				       ))
(add-hook 'org-mode-hook (lambda ()
			   (prettify-symbols-mode)))

Setup languages and headers for Babel

;; Languages
(org-babel-do-load-languages
 'org-babel-load-languages '(
                             (emacs-lisp . t)
                             (shell . t)
                             (python . t)
                             ))
;; Default headers
;; Shell
(setq org-babel-default-header-args:sh '((:results . "verbatim drawer replace")))
;; Python
(setq org-babel-python-command "python3")
(setq org-babel-default-header-args:python '((:results . "verbatim drawer replace output")))

Create blocks by completion, edit source blocks in the same window, evaluate them without confirmation Block completion works by pressing < the template key and TAB

;; Completion templates
(setq org-structure-template-alist '(
                                     ("n" "#+NAME: ?")
                                     ("t" "#+TBLFM: ?")
                                     ("s" "#+BEGIN_SRC ? \n\n#+END_SRC")
                                     ("e" "#+BEGIN_EXAMPLE \n?\n#+END_EXAMPLE")
                                     ("q" "#+BEGIN_QUOTE \n?\n#+END_QUOTE")
                                     ("v" "#+BEGIN_VERSE \n?\n#+END_VERSE")
                                     ("V" "#+BEGIN_VERBATIM \n?\n#+END_VERBATIM")
                                     ("c" "#+BEGIN_CENTER \n?\n#+END_CENTER")
                                     ("l" "#+BEGIN_EXPORT latex \n?\n#+END_EXPORT")
                                     ("L" "#+LaTeX: ")
                                     ("h" "#+BEGIN_EXPORT html \n?\n#+END_EXPORT")
                                     ("H" "#+HTML: ")
                                     ("a" "#+BEGIN_EXPORT ascii \n?\n#+END_EXPORT")
                                     ("A" "#+ASCII: ")
                                     ("i" "#+INDEX: ?")
                                     ("I" "#+INCLUDE: %file ?")
                                     ))
;; Edit block in the same window
(setq org-src-window-setup 'current-window)
;; Evaluate without confirmation
(setq org-confirm-babel-evaluate nil)
;; Set header arguments inside property drawers and have these affect all nested blocks
(setq org-use-property-inheritance t)

Prose

Simple visual and navigation tweaks

(setq org-hide-emphasis-markers t) ;; Hide markers
(setq org-support-shift-select 'always) ;; Select with shift
(setq org-return-follows-link t) ;; Follow links with Enter
(setq browse-url-browser-function 'browse-url-xdg-open) ;; Open web links in Firefox
(setq org-tags-column 0) ;; Tag positions

Italize easily

(defun orgitalic ()
  (interactive)
  (org-emphasize ?/))
(define-key org-mode-map [(shift return)] 'orgitalic)

Receive text from outside Emacs

To receive text from Firefox I listen to messages through Emacs server and org-protocol, and process them through org-capture.

Listen to messages

(server-start)
(require 'org-protocol)

Put text in an ordered list inside a predefined document and heading, including its source, don’t bother with editing or confirming afterwards

(defun m/capturewebclip ()
  (let (
        (m/clips "/home/m/auricio/write/clips/web.org")
        )
    (with-current-buffer (find-file-noselect m/clips)
      (setq fragments
            (org-map-entries
             (lambda ()
               (nth 4 (org-heading-components)))
             "+fragment"
             'file)))
    (if (= (length fragments) 0)
        (setq this-fragment "1")
      (setq this-fragment (number-to-string (+ 1 (string-to-number (car (last fragments)))))))
    (message this-fragment)
    ))

(setq org-capture-templates
      '(("x" ;; code
         "Web" ;; name
         entry ;; type
         (file+headline ;; under a heading
          "/home/m/auricio/write/clips/web.org" ;; what file
          "Fragments") ;; what heading
         "\n* %(m/capturewebclip) :fragment:\n %i\n%:link" ;; what text
         :immediate-finish t :jump-to-captured nil))) ;; don't wait for confirmation

I can’t extend this process to taking notes from books. Books are usually distributed as PDFs and:

  1. I couldn’t find a PDF reader I can have the Emacs server interact with
  2. Text from PDFs usually requires post-processing

Therefore I decided to circunvent org-capture and just copy text with minimal automatic post-processing inside an ordered list in the current buffer.

;; Insert clipboard text inside the last heading in an ordered list, replace all line endings with spaces
(defun m/capturepdf ()
  (interactive)
  (setq fragments
        (org-map-entries
         (lambda ()
           (nth 4 (org-heading-components)))
         "+fragment" 'file))
  (if (= (length fragments) 0)
      (setq last-fragment "1")
    (setq last-fragment
          (number-to-string
           (+ 1 
              (string-to-number
               (car (last fragments)))))))
  (org-insert-heading-after-current)
  (insert last-fragment)
  (insert
   "\n"
   (replace-regexp-in-string
    "\n" " "
    (current-kill 0)))
  (org-set-tags-to "fragment")
  )
;; Key
(define-key org-mode-map (kbd "M-v") 'frompdf)

Find information across multiple org documents

Define what documents are interesting

(setq m/interesting
      (list
       "/home/m/auricio/write/clips/web.org"
       "/home/m/auricio/write/clips/1.org"
       "/home/m/auricio/write/writing/datos.org"
       "/home/m/auricio/write/writing/internet.org"
       "/home/m/auricio/write/writing/socialchoice.org"
       "/home/m/auricio/write/writing/android.org"
       "/home/m/auricio/write/read/notes/Hofstadter_Godel-Escher-Bach.org"
       "/home/m/auricio/write/read/notes/Osterhammel-The_Transformation_of_the_World.org"
       "/home/m/auricio/write/read/notes/Pinker_Enlightenment_Now.org"
       "/home/m/auricio/write/read/notes/read.org"))

Full text search

;; Setup org-rifle
(require 'helm-org-rifle)
;; What files to search
(defun m/riflesearch()
  (interactive)
  (helm-org-rifle-files m/interesting))
;; Key to search
(global-set-key (kbd "C-x /") 'm/riflesearch)

Search only headings

(setq org-agenda-files m/interesting)
(global-set-key (kbd "C-M-/") 'helm-org-agenda-files-headings)

Store and use citations

Where to store citations

(require 'org-ref)
(setq bibtex-completion-bibliography "~/auricio/write/writing/bib/ref.bib"
      bibtex-completion-library-path "~/auricio/write/writing/bib/ref.bib"
      bibtex-completion-notes-path "~/auricio/write/writing/bib/helm-bibtex-notes"
      reftex-default-bibliography '("~/auricio/write/writing/bib/ref.bib")
      org-ref-bibliography-notes "~/auricio/write/writing/bib/notes.org"
      org-ref-default-bibliography '("~/auricio/write/writing/bib/ref.bib")
      org-ref-pdf-directory "~/auricio/write/read/bib/")

Store citations with C-c C-b inside the Bibtex document Copy references to citations with helm-bibtex

;; Modify helm-source-bibtex so that copying references is the default option
(setq helm-source-bibtex
      (helm-build-sync-source "BibTeX entries"
	:header-name (lambda (name)
		       (format "%s%s: " name (if helm-bibtex-local-bib " (local)" "")))
	:candidates 'helm-bibtex-candidates
	:filtered-candidate-transformer 'helm-bibtex-candidates-formatter
	:action (helm-make-actions
		 "Insert reference"           'helm-bibtex-insert-reference
		 "Open PDF, URL or DOI"       'helm-bibtex-open-any
		 "Open URL or DOI in browser" 'helm-bibtex-open-url-or-doi
		 "Insert citation"            'helm-bibtex-insert-citation
		 "Insert BibTeX key"          'helm-bibtex-insert-key
		 "Insert BibTeX entry"        'helm-bibtex-insert-bibtex
		 "Attach PDF to email"        'helm-bibtex-add-PDF-attachment
		 "Edit notes"                 'helm-bibtex-edit-notes
		 "Show entry"                 'helm-bibtex-show-entry
		 "Add PDF to library"         'helm-bibtex-add-pdf-to-library)))

Modify bibtex-completion-insert-reference so that references are not broken into multiple lines

(defun bibtex-completion-insert-reference (keys)
  "Insert a reference for each selected entry."
  (let* ((refs (--map
		(concat "\n- " (bibtex-completion-apa-format-reference it))
                keys)))
    (insert (replace-regexp-in-string "\n" "" (s-join "" refs)))))

Dired

Open in current directory

(global-set-key (kbd "C-x C-d") 'dired-jump)

Display a simple list

(require 'dired-details)
(dired-details-install)
(setq dired-details-hidden-string "")

Sort directories first

(setq dired-listing-switches "-al --group-directories-first")

Filter list

(define-key dired-mode-map (kbd "/") 'dired-narrow)

Go up and down the filesystem

(define-key dired-mode-map (kbd "M-<left>")
  (lambda ()
    (interactive)
    (find-alternate-file "..")))
(define-key dired-mode-map (kbd "M-<right>") 'dired-find-alternate-file)

Delete directories without confirmation

(setq dired-recursive-deletes 'always)

Default external applications

(require 'openwith)
(setq openwith-associations '(
                              ("\\.pdf\\'" "evince" (file))
                              ("\\.jpg\\'" "feh" (file))
                              ("\\.djvu\\'" "evince" (file))))
(openwith-mode t)
;; Necessary to display images in org-mode if openwith is activated
(defadvice org-display-inline-images
    (around handle-openwith
            (&optional include-linked refresh beg end) activate compile)
  (if openwith-mode
      (progn
        (openwith-mode -1)
        ad-do-it
        (openwith-mode 1))
    ad-do-it))
;; Open EPUBs inside Emacs
(add-to-list 'auto-mode-alist '("\\.epub\\'" . nov-mode))

Programming

Rainbow delimiters are convenient to locate yourself inside a nested structure, I find them useful in most modes

;; What modes
(setq m/rainbow_modes
      (append
       m/programming_modes
       '(pollen-mode-hook
         lisp-interaction-mode-hook)))
;; Apply
(defun m/rainbow (modes)
  (dolist (m/mode modes)
    (add-hook m/mode #'rainbow-delimiters-mode)))
(m/rainbow m/rainbow_modes)

Setup auto-complete

(ac-config-default)
(setq ac-auto-start nil)
(define-key ac-mode-map (kbd "M-TAB") 'auto-complete)

Search all files within a directory. Press C-c C-f to go directly to results under the cursor (helm-follow-mode)

(require 'ag)
(global-set-key (kbd "M-.") 'helm-do-ag)

In javascript, use js2-mode with eslint if possible

;; Use js2
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
;; Clean display
(setq-default js-indent-level 2)
(setq-default js2-basic-indent 2)
(setq-default js2-basic-offset 2)
(setq-default js2-auto-indent-p t)
(setq-default js2-cleanup-whitespace t)
(setq-default js2-indent-on-enter-key t)
(setq js2-mode-show-parse-errors nil)
(setq js2-mode-show-strict-warnings nil)
;; Use eslint if found in node_modules
(defun m/js2eslint ()
  (let* ((root (locate-dominating-file
                (or (buffer-file-name) default-directory)
                "node_modules"))
         (eslint (and root
                      (expand-file-name "node_modules/eslint/bin/eslint.js"
                                        root))))
    (when (and eslint (file-executable-p eslint))
      (setq-local flycheck-javascript-eslint-executable eslint))))
(add-hook 'flycheck-mode-hook #'m/js2eslint)
;; Simple comments
(defun m/js2comments ()
  (setq comment-start "//"
        comment-end ""
        comment-style 'indent))
(add-hook 'js2-mode-hook #'m/js2comments)