Configuración de emacs a través de org-mode
Esta es mi configuración de emacs
, la cuál pongo a disposición para que todo
aquel que esté interesando pueda tomarla como referencia o usarla para su uso
propio. Esta configuración corresponde a lo que va en mi ~/.emacs.d/init.el
.
1 Instrucciones de intalación
Para hacer uso de esta configuración, necesitas lo siguiente:
- Una copia de este documento.
- Emacs 24 (> 24.3)
- Org-mode (> 8.2)
Algo que no puedo asegurar, es el correcto funcionamiento de esta configuración en otros sistemas operativos distintos de linux.
Una vez que tengas la copia de este documento, tu puedes copiarla en
~/.emacs.d/init.org
. Entonces dentro de emacs teclea M-x org-babel-load-file
.
M-x
significa Alt
y x
presionados al mismo tiempo, seguido de la Instrucción
org-babel-load-file
en el sub-buffer de emacs. Esto debería de evaluar todo el
código emacs-lisp
que se encuentra en este documento.
Si eventualmente hay cambios sobre el código de este documento, basta con presionar
C-c i
.
2 Repositorios
Lo primero es definir las fuentes de donde obtendremos nuestros paquetes. He definido 4 fuentes:
(require 'package) (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/") t) (add-to-list 'package-archives '("tromey" . "http://tromey.com/elpa/") t) (add-to-list 'package-archives '("elpa" . "http://elpa.gnu.org/packages/") t) (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
Una vez añadidos los repositorios de nuestros paquetes, hay que definir cuales van a ser los paquetes que vamos a utilizar y como los vamos a cargar de manera automática.
(package-initialize) (when (not package-archive-contents) (package-refresh-contents)) (defvar my-packages '(auto-package-update nyan-mode nyan-prompt rainbow-delimiters flymake column-enforce-mode diminish saveplace highlight-chars neotree auto-complete apropos-fn+var autopair yasnippet flycheck paredit magit ido-ubiquitous smex find-file-in-repository projectile auctex ac-math auto-complete-auctex xml-rpc metaweblog org2blog htmlize netrc tagedit deferred python-mode ipython jedi ein ein-mumamo clojure-mode clojure-mode-extra-font-locking cider web-mode php-mode coffee-mode markdown-mode markdown-mode+ ack cdlatex ob-sml jabber alert interleave )) (dolist (p my-packages) (when (not (package-installed-p p)) (package-install p)))
3 Interfaz gráfica
Algo que siempre me recriminan es la cuestión de que emacs se ve muy viejo. ¡El problema es qué ellos no saben que altamente configurable y personalizable!
Entonces, después de configurar hay que añadir los siguientes paquetes para comenzar a jugar con la interfaz de emacs.
(require 'flymake) (require 'nyan-mode) (require 'nyan-prompt) (require 'rainbow-delimiters) (require 'column-enforce-mode)
Establecemos el tamaño que tendrá al iniciar emacs.
(when window-system (set-frame-size (selected-frame) 80 36))
Establecemos una fuente agradable
(set-frame-font "Monofur 14")
Indicamos que queremos ver el número de lineas.
(global-linum-mode)
Indicamos que durante la edición podamos el número de linea y el número de columna en el que estamos trabajando
(setq column-number-mode t)
Cargamos los temas que vamos a aplicarle a emacs.
(add-to-list 'custom-theme-load-path "~/.emacs.d/temas") (add-to-list 'load-path "~/.emacs.d/temas") (load-theme 'tomorrow-night-bright t)
Indicamos que el título de la ventana va a ser el path del archivo que estamos editando en el buffer actual.
(setq-default frame-title-format "%b (%f)")
Una de las características que menos me gusta, es que el cursor se encuentre parpadeando, por lo que lo vamos a quitar. Así como que cada vez que hace una evaluación campaneé.
(blink-cursor-mode 0) (setq ring-bell-function 'ignore)
Indicamos que resalte la linea actual
(global-hl-line-mode 1)
Quéremos que resalte los paréntesis y sus matchs.
(show-paren-mode 1) (add-hook 'prog-mode-hook 'rainbow-delimiters-mode)
Inhabilitamos la barra de menús y de herramientas
(menu-bar-mode -1) (when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1) (tool-bar-mode -1))
Definimos una función para ingresar a pantalla completa.
(defun fullscreen () "TO-DO." (interactive) (set-frame-parameter nil 'fullscreen (if (frame-parameter nil 'fullscreen) nil 'fullboth))) (global-set-key [f11] 'fullscreen)
Quiero que me enseñe el estado de la batería de la laptop, así como la hora actual.
(display-battery-mode t) (display-time-mode)
Utilizamos a Nyan-Cat como indicador de la posición en el buffer.
(nyan-mode t) (nyan-start-animation) (setq nyan-wavy-trail t)
Limpiamos el mode-line
(defvar mode-line-cleaner-alist `((auto-complete-mode . " α") (yas/minor-mode . " υ") (paredit-mode . " π") (eldoc-mode . "") (column-enforce-mode . " 80") (abbrev-mode . "") (lisp-interaction-mode . " λ") (hi-lock-mode . "") (python-mode . " Π") (emacs-lisp-mode . " ε") (nxhtml-mode . " nx") (fundamental-mode . " F") (latex-mode . " Φ") (flycheck-mode . " Γ") (magit-auto-revert-mode . " gR") (yas-global-mode . " ψ") (yas-minor-mode . " ψ") (projectile-mode . " ρ")) "Una lista para 'clean-mode-line'.") (defun clean-mode-line () "TO-DO." (interactive) (loop for cleaner in mode-line-cleaner-alist do (let* ((mode (car cleaner)) (mode-str (cdr cleaner)) (old-mode-str (cdr (assq mode minor-mode-alist)))) (when old-mode-str (setcar old-mode-str mode-str)) (when (eq mode major-mode) (setq mode-name mode-str))))) (add-hook 'after-change-major-mode-hook 'clean-mode-line) (defalias 'flymake-report-status 'flymake-report-status-slim) (defun flymake-report-status-slim (e-w &optional status) "Show \"slim\" flymake status in mode line. E-W as. STATUS as." (when e-w (setq flymake-mode-line-e-w e-w)) (when status (setq flymake-mode-line-status status)) (let* ((mode-line " Φ")) (when (> (length flymake-mode-line-e-w) 0) (setq mode-line (concat mode-line ":" flymake-mode-line-e-w))) (setq mode-line (concat mode-line flymake-mode-line-status)) (setq flymake-mode-line mode-line) (force-mode-line-update)))
4 Edición
Agregamos todos los paquetes que vayamos a necesitar
(require 'saveplace) (require 'highlight-chars) (require 'neotree) (require 'auto-complete) (require 'autopair) (require 'yasnippet) (require 'flycheck) (require 'apropos) (require 'auto-complete-config) (require 'iso-transl) (require 'undo-tree)
Verificamos la sintaxis de código al vuelo.
(global-flycheck-mode t)
No usamos tabs duros.
(setq-default indent-tabs-mode nil)
Configuramos a emacs de tal forma que pueda compartir el clipboard con el sistema operativo.
(setq x-select-enable-clipboard t x-select-enable-primary t save-interprogram-paste-before-kill t apropos-do-all t mouse-yank-at-point t)
Configuramos la búsqueda en el buffer.
(global-set-key (kbd "C-s") 'isearch-forward-regexp) (global-set-key (kbd "C-r") 'isearch-backward-regexp) (global-set-key (kbd "C-M-s") 'isearch-forward) (global-set-key (kbd "C-M-r") 'isearch-backward)
Una característica que me gustaba de mis anteriores editores es el duplicar una linea de código.
(global-set-key "\C-c\C-d" "\C-a\C- \C-n\M-w\C-y")
Creamos respaldos automáticos y la posición donde te quedaste en cada uno de los archivos.
(setq backup-directory-alist `(("." . ,(concat user-emacs-directory "backups")))) (setq auto-save-default nil) (setq-default save-place t) (setq save-place-file (concat user-emacs-directory "places"))
Una buena práctica es evitar dejar espacios en blanco innecesarios. A continuación la configuración para quitar esos espacios al guardar.
(add-hook 'font-lock-mode-hook 'hc-highlight-trailing-whitespace) (add-hook 'LaTeX-mode-hook 'hc-highlight-trailing-whitespace) (add-hook 'latex-mode-hook 'hc-highlight-trailing-whitespace) (add-hook 'python-mode-hook 'hc-highlight-trailing-whitespace) (add-hook 'prog-mode-hook 'hc-highlight-trailing-whitespace) (add-hook 'prog-mode-hook (lambda () (add-to-list 'write-file-functions 'delete-trailing-whitespace))) (add-hook 'LaTeX-mode-hook (lambda () (add-to-list 'write-file-functions 'delete-trailing-whitespace))) (add-hook 'LaTeX-mode-hook (lambda () (add-to-list 'write-file-functions 'delete-blank-lines))) (add-hook 'prog-mode-hook (lambda () (add-to-list 'write-file-functions 'delete-blank-lines)))
Resaltado de caracteres a partir de la columna 80.
(add-hook 'LaTeX-mode-hook 'column-enforce-mode) (add-hook 'python-mode-hook 'column-enforce-mode) (add-hook 'prog-mode-hook 'column-enforce-mode)
Comentarios
;; Comentarios (defun toggle-comment-on-line () "Comenta o descomenta la línea actual." (interactive) (comment-or-uncomment-region (line-beginning-position) (line-end-position))) (global-set-key (kbd "C-;") 'toggle-comment-on-line)
Otros
(defun die-tabs () "Usa sólo 2 espacios para los tabs." (interactive) (set-variable 'tab-width 2) (mark-whole-buffer) (untabify (region-beginning) (region-end)) (keyboard-quit)) (global-set-key [f8] 'neotree-toggle) (put 'downcase-region 'disabled nil) (setq create-lockfiles nil) (setq inhibit-startup-message t) (defvar ack-history nil "History for the `ack' command.") (defun revert-buffer-no-confirm () "Revert buffer without confirmation." (interactive) (revert-buffer t t)) (global-set-key (kbd "C-c r") 'revert-buffer-no-confirm) (global-undo-tree-mode) (global-set-key (kbd "C-c _") 'undo-tree-visualize)
Autocompletado
(add-to-list 'ac-dictionary-directories "~/.emacs.d/custom/dict") (set-default 'ac-sources '(ac-source-abbrev ac-source-dictionary ac-source-yasnippet ac-source-words-in-buffer ac-source-words-in-same-mode-buffers ac-source-semantic)) (ac-config-default) (dolist (m '(c-mode c++-mode java-mode org-mode)) (add-to-list 'ac-modes m)) (global-auto-complete-mode t) ;; auto-complete mode extra settings (setq ac-auto-start 2) (setq ac-use-overriding-local-map nil) (setq ac-use-menu-map t) (setq ac-candidate-limit 20)
Paredit
(autoload 'enable-paredit-mode "paredit" "Turn on pseudo-structural editing of Lisp code." t) (add-hook 'emacs-lisp-mode-hook #'enable-paredit-mode) (add-hook 'eval-expression-minibuffer-setup-hook #'enable-paredit-mode) (add-hook 'ielm-mode-hook #'enable-paredit-mode) (add-hook 'lisp-mode-hook #'enable-paredit-mode) (add-hook 'lisp-interaction-mode-hook #'enable-paredit-mode) (add-hook 'scheme-mode-hook #'enable-paredit-mode) (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode) (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode) (add-hook 'ielm-mode-hook 'turn-on-eldoc-mode)
Soporte para org-mode
(require 'org) (define-key global-map "\C-cl" 'org-store-link) (define-key global-map "\C-ca" 'org-agenda) (setq org-log-done t) (setq org-agenda-files (list "~/org/alimentarias.org" "~/org/estacionamiento.org" "~/org/casa.org" "~/org/IngenieríaSoftware.org" "~/org/labsom.org" "~/org/todo.org")) (defvar count-words-buffer nil "*Number of words in the buffer.") (defun wicked/update-wc () "Whatever." (interactive) (setq count-words-buffer (number-to-string (count-words-buffer))) (force-mode-line-update)) (unless count-words-buffer (run-with-idle-timer 1 t 'wicked/update-wc)) (unless (memq 'count-words-buffer global-mode-string) (add-to-list 'global-mode-string "words: " t) (add-to-list 'global-mode-string 'count-words-buffer t)) (defun count-words-buffer () "Count the number of words in the current paragraph." (interactive) (save-excursion (goto-char (point-min)) (let ((count 0)) (while (not (eobp)) (forward-word 1) (setq count (1+ count))) count))) (defun wicked/org-update-checkbox-count (&optional all) "Update the checkbox statistics in the current section. This will find all statistic cookies like [57%] and [6/12] and update them with the current numbers. With optional prefix argument ALL, do this for the whole buffer." (interactive "P") (save-excursion (let* ((buffer-invisibility-spec (org-inhibit-invisibility)) (beg (condition-case nil (progn (outline-back-to-heading) (point)) (error (point-min)))) (end (move-marker (make-marker) (progn (or (outline-get-next-sibling) ;; (1) (goto-char (point-max))) (point)))) (re "\\(\\[[0-9]*%\\]\\)\\|\\(\\[[0-9]*/[0-9]*\\]\\)") (re-box "^[ \t]*\\(*+\\|[-+*]\\|[0-9]+[.)]\\) +\\(\\[[- X]\\]\\)") b1 e1 f1 c-on c-off lim (cstat 0)) (when all (goto-char (point-min)) (or (outline-get-next-sibling) (goto-char (point-max))) ;; (2) (setq beg (point) end (point-max))) (goto-char beg) (while (re-search-forward re end t) (setq cstat (1+ cstat) b1 (match-beginning 0) e1 (match-end 0) f1 (match-beginning 1) lim (cond ((org-on-heading-p) (or (outline-get-next-sibling) ;; (3) (goto-char (point-max))) (point)) ((org-at-item-p) (org-end-of-item) (point)) (t nil)) c-on 0 c-off 0) (goto-char e1) (when lim (while (re-search-forward re-box lim t) (if (member (match-string 2) '("[ ]" "[-]")) (setq c-off (1+ c-off)) (setq c-on (1+ c-on)))) (goto-char b1) (insert (if f1 (format "[%d%%]" (/ (* 100 c-on) (max 1 (+ c-on c-off)))) (format "[%d/%d]" c-on (+ c-on c-off)))) (and (looking-at "\\[.*?\\]") (replace-match "")))) (when (interactive-p) (message "Checkbox statistics updated %s (%d places)" (if all "in entire file" "in current outline entry") cstat))))) (defadvice org-update-checkbox-count (around wicked activate) "Fix the built-in checkbox count to understand headlines." (setq ad-return-value (wicked/org-update-checkbox-count (ad-get-arg 1))))