From 0370bdcff16e8008d73dc1677205ff433f9f495e Mon Sep 17 00:00:00 2001 From: drymer Date: Thu, 10 Nov 2016 12:57:53 +0100 Subject: [PATCH] =?UTF-8?q?A=C3=B1adir=20configuraci=C3=B3n=20de=20emacs,?= =?UTF-8?q?=20licencia=20y=20mejora=20instalaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 15 + README.md | 23 +- README.org | 12 +- emacs.d/capture | 22 + emacs.d/demacs | 10 + emacs.d/init-literate.org | 2121 +++++++++++++++++++++++++++++++++++++ emacs.d/init.el | 21 + i3/config | 4 +- instala.sh | 78 +- 9 files changed, 2278 insertions(+), 28 deletions(-) create mode 100644 LICENSE create mode 100755 emacs.d/capture create mode 100755 emacs.d/demacs create mode 100644 emacs.d/init-literate.org create mode 100644 emacs.d/init.el diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dec4cf0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +Author:: drymer +Copyright:: Copyright (c) 2016, drymer + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or (at +your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/README.md b/README.md index 7cea4df..c659e0e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,15 @@ -# dotfiles +
+

Índice

+
+ +
+
+ + + +# dotfiles Este repositorio contiene los siguientes archivos y directorios: @@ -15,8 +26,12 @@ Este repositorio contiene los siguientes archivos y directorios: - `scripts`: varios scripts para i3blocks y i3 -- El directorio `mutt` que contiene archivos de configuración y scripts para neomutt, offlineimap, abook y notmuch. Los nombres de los archivos son lógicos, por lo que no requieren explicación. Se puede leer más sobre el tema en este [articulo](https://daemons.cf/posts/neomutt-offlineimap-notmuch-abook-sustituyendo-a-los-gestores-de-correo-monstruosos/index.html). +- El directorio `mutt`, que contiene archivos de configuración y scripts para neomutt, offlineimap, abook y notmuch. Los nombres de los archivos son lógicos, por lo que no requieren explicación. Se puede leer más sobre el tema en este [articulo](https://daemons.cf/posts/neomutt-offlineimap-notmuch-abook-sustituyendo-a-los-gestores-de-correo-monstruosos/index.html). -- El directorio `qutebrowser` que contiene archivos de configuración para qutebrowser. Incluye el script para capturar links en `org-mode` y para reproducir videos. +- El directorio `qutebrowser`, que contiene archivos de configuración para qutebrowser. Incluye el script para capturar links en `org-mode` y para reproducir videos. -Ver ayuda con `bash instala.sh`. +- El directorio `emacs.d`, que contiene archivos de configuración de emacs. Incluye el script para capturar links de de `qutebrowser` y el script para usar emacs. + +Uso: + + ./instala.sh {all, X, i3, tmux, qutebrowser, emacs} diff --git a/README.org b/README.org index 8f73312..6c70d45 100644 --- a/README.org +++ b/README.org @@ -15,8 +15,14 @@ Este repositorio contiene los siguientes archivos y directorios: + =scripts=: varios scripts para i3blocks y i3 -- El directorio =mutt= que contiene archivos de configuración y scripts para neomutt, offlineimap, abook y notmuch. Los nombres de los archivos son lógicos, por lo que no requieren explicación. Se puede leer más sobre el tema en este [[https://daemons.cf/posts/neomutt-offlineimap-notmuch-abook-sustituyendo-a-los-gestores-de-correo-monstruosos/index.html][articulo]]. +- El directorio =mutt=, que contiene archivos de configuración y scripts para neomutt, offlineimap, abook y notmuch. Los nombres de los archivos son lógicos, por lo que no requieren explicación. Se puede leer más sobre el tema en este [[https://daemons.cf/posts/neomutt-offlineimap-notmuch-abook-sustituyendo-a-los-gestores-de-correo-monstruosos/index.html][articulo]]. -- El directorio =qutebrowser= que contiene archivos de configuración para qutebrowser. Incluye el script para capturar links en =org-mode= y para reproducir videos. +- El directorio =qutebrowser=, que contiene archivos de configuración para qutebrowser. Incluye el script para capturar links en =org-mode= y para reproducir videos. -Ver ayuda con =bash instala.sh=. +- El directorio =emacs.d=, que contiene archivos de configuración de emacs. Incluye el script para capturar links de de =qutebrowser= y el script para usar emacs. + +Uso: + +#+BEGIN_SRC bash :results raw +./instala.sh {all, X, i3, tmux, qutebrowser, emacs} +#+END_SRC diff --git a/emacs.d/capture b/emacs.d/capture new file mode 100755 index 0000000..68bc208 --- /dev/null +++ b/emacs.d/capture @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# windows: bind Y spawn mintty --nopin -w hide -e C:\\cygwin\\usr\\local\\bin\\capture.py {url};; yank -t +# gnu/linux: bind Y yank -t;; spawn capture {url} +# +# (setq org-capture-templates +# ... +# ("w" "Marcadors" entry (file "~/org/web.org") +# "* %x\n %U\n %c" +# :empty-lines 1) +# ... +# )) + + +from urllib import quote +from sys import argv, exit +from subprocess import call + +url = quote(argv[1], safe='') + +call(['emacsclient', 'org-protocol:/capture:/w/' + url]) diff --git a/emacs.d/demacs b/emacs.d/demacs new file mode 100755 index 0000000..4c21039 --- /dev/null +++ b/emacs.d/demacs @@ -0,0 +1,10 @@ +#!/bin/bash + +USERID=`id -u` +if [[ ! -e /tmp/emacs$USERID/server ]] +then + emacs --daemon + emacsclient -c -n -e '(load-file "/tmp/powerline.el")' -e "(org-agenda-list)" +else + emacsclient -c -n -e "(org-agenda-list)" +fi diff --git a/emacs.d/init-literate.org b/emacs.d/init-literate.org new file mode 100644 index 0000000..126bf6d --- /dev/null +++ b/emacs.d/init-literate.org @@ -0,0 +1,2121 @@ +#+STARTUP: indent + +* Tabla de contenido :TOC_5_org: +:PROPERTIES: +:CUSTOM_ID: Tabla de contenido :TOC_5_org: +:END: + - [[Acerca de este documento][Acerca de este documento]] + - [[Configuración Genérica][Configuración Genérica]] + - [[Iniciar paquetes elpa/melpa/marmalade][Iniciar paquetes elpa/melpa/marmalade]] + - [[Asegurarse de que use-package y el-get estan instalados y los inicializa][Asegurarse de que use-package y el-get estan instalados y los inicializa]] + - [[Moverse por el buffer][Moverse por el buffer]] + - [[Establecer nombre y correo][Establecer nombre y correo]] + - [[Abrir cómo buffer inicial][Abrir cómo buffer inicial]] + - [[Iniciar cómo servidor][Iniciar cómo servidor]] + - [[Auto-guardado][Auto-guardado]] + - [[Modo por defecto][Modo por defecto]] + - [[Acepta 'y' o 'n' cuando pide 'yes' o 'no'][Acepta 'y' o 'n' cuando pide 'yes' o 'no']] + - [[Lenguaje por defecto en emacs y org-mode][Lenguaje por defecto en emacs y org-mode]] + - [[Moverse por ventanas con shift][Moverse por ventanas con shift]] + - [[Helm][Helm]] + - [[Buscar más eficazmente en Helm][Buscar más eficazmente en Helm]] + - [[ivy-mode][ivy-mode]] + - [[Seguir enlaces simbólicos][Seguir enlaces simbólicos]] + - [[Emparejar parentesis y otros][Emparejar parentesis y otros]] + - [[Mantener lista de buffers recientes][Mantener lista de buffers recientes]] + - [[Guardar el layout tal cómo está][Guardar el layout tal cómo está]] + - [[No truncar líneas][No truncar líneas]] + - [[Programación][Programación]] + - [[Auto identación][Auto identación]] + - [[Auto completado][Auto completado]] + - [[Magit][Magit]] + - [[Aviso de errores con flycheck][Aviso de errores con flycheck]] + - [[Insertar licencia][Insertar licencia]] + - [[Borrar espacios sobrantes][Borrar espacios sobrantes]] + - [[Usar ssh con tramp][Usar ssh con tramp]] + - [[Golden Ratio][Golden Ratio]] + - [[Abrir enlaces en el navegador por defecto][Abrir enlaces en el navegador por defecto]] + - [[Terminal][Terminal]] + - [[Cambiar de ventana más comodamente][Cambiar de ventana más comodamente]] + - [[undo-tree][undo-tree]] + - [[Sobreescribir al seleccionar texto][Sobreescribir al seleccionar texto]] + - [[Imenu][Imenu]] + - [[imenu-list][imenu-list]] + - [[Aspecto][Aspecto]] + - [[Tema cyberpunk][Tema cyberpunk]] + - [[Powerline modificada][Powerline modificada]] + - [[Formato de las columnas de númeracion][Formato de las columnas de númeracion]] + - [[Ventana limpia][Ventana limpia]] + - [[UTF-8][UTF-8]] + - [[Tipo de fuente][Tipo de fuente]] + - [[Partir buffers de manera más bonita][Partir buffers de manera más bonita]] + - [[Scroll][Scroll]] + - [[Configuración por modos][Configuración por modos]] + - [[JSON][JSON]] + - [[Haskel][Haskel]] + - [[Markdown][Markdown]] + - [[python][python]] + - [[web-mode][web-mode]] + - [[DockerFile][DockerFile]] + - [[kivy-mode][kivy-mode]] + - [[gnu-social-mode][gnu-social-mode]] + - [[po-mode][po-mode]] + - [[org-mode][org-mode]] + - [[Definir fuente de el-get][Definir fuente de el-get]] + - [[Agenda][Agenda]] + - [[Definir archivos de la agenda][Definir archivos de la agenda]] + - [[Definir archivo de notas para org-capture][Definir archivo de notas para org-capture]] + - [[Estados de los objetos de las listas][Estados de los objetos de las listas]] + - [[Refile][Refile]] + - [[Caldav][Caldav]] + - [[Configuración del calendario][Configuración del calendario]] + - [[calfw][calfw]] + - [[Tareas repetitivas][Tareas repetitivas]] + - [[Cambiar el formato de CLOCKTABLE][Cambiar el formato de CLOCKTABLE]] + - [[Edición, diseño y varios][Edición, diseño y varios]] + - [[Atajos de teclado][Atajos de teclado]] + - [[Definir lenguajes que entiende babel][Definir lenguajes que entiende babel]] + - [[Asteriscos bonitos][Asteriscos bonitos]] + - [[Seguir links][Seguir links]] + - [[Exportar Markdown][Exportar Markdown]] + - [[Configuracion de bloques de código][Configuracion de bloques de código]] + - [[Elementos de marcado][Elementos de marcado]] + - [[Quitar confirmación al evaluar código][Quitar confirmación al evaluar código]] + - [[Añadir imágenes in-line][Añadir imágenes in-line]] + - [[org2blog][org2blog]] + - [[org2nikola][org2nikola]] + - [[Notas a pie de página][Notas a pie de página]] + - [[toc-org][toc-org]] + - [[Cifrar archivos][Cifrar archivos]] + - [[Generar id para cabeceras de manera dinámica][Generar id para cabeceras de manera dinámica]] + - [[Hábitos][Hábitos]] + - [[org-protocol][org-protocol]] + - [[Empareja simbolos de marcado y paréntesis][Empareja simbolos de marcado y paréntesis]] + - [[Más profundidad en imenu][Más profundidad en imenu]] + - [[Capturas de notas][Capturas de notas]] + - [[Comandos de Agenda][Comandos de Agenda]] + - [[Funciones personalizadas][Funciones personalizadas]] + - [[Recargar todos los buffers abiertos][Recargar todos los buffers abiertos]] + - [[Insertar cabeceras para org-mode][Insertar cabeceras para org-mode]] + - [[Insertar bloque src para org-mode][Insertar bloque src para org-mode]] + - [[Insertar org-entities][Insertar org-entities]] + - [[Añadir soporte para editar archivos en docker][Añadir soporte para editar archivos en docker]] + - [[Insertar fecha de hoy][Insertar fecha de hoy]] + - [[Abrir eshell aquí][Abrir eshell aquí]] + - [[Devolver enlaces][Devolver enlaces]] + +* Acerca de este documento +:PROPERTIES: +:CUSTOM_ID: Acerca de este documento +:END: +Este documento está hecho en org-mode y es a la vez la explicación de todo lo que hay en mi configuración de emacs y la propia configuración de emacs. Esto se logra mediante la programación literaria, un concepto bastante molón de programación. + +Mi idea es que termine siendo más o menos un tutorial de emacs, extendido con los articulos del blog. A ver como sale. El documento estará en este git. + +#+BEGIN_SRC sh :results code + cat ~/.emacs.d/init.el +#+END_SRC + +#+RESULTS: +#+BEGIN_SRC emacs-lisp :tangle no + ;; Antes que nada, quitamos del path el org-mode que viene con emacs, por que es viejo + (dolist (val load-path) + (if (string-match "lisp\/org" val) + (progn + (setq org-viejo val) + (delete val load-path) + ) + ) + ) + + ;; Se añade la ruta del org-mode nuevo + (add-to-list 'load-path (concat user-emacs-directory "el-get/org-mode-maint/lisp/")) + + ;; Se intenta cargar el org-mode más nuevo. Si falla, vuelve a añadir al path la versión vieja para poder cargar el fichero de configuración + (unless (require 'org nil 'noerror) + (add-to-list 'load-path org-viejo) + ) + + ;; Se carga la configuración pública y la privada + (org-babel-load-file (concat user-emacs-directory "init-literate.org")) + (org-babel-load-file (concat user-emacs-directory "private-literate.org")) +#+END_SRC + +Estas lineas cargan =org-mode= y mediante =org-babel= coge todos los bloques de lisp que hay en =init-literate.org= y los junta todos en =init-literate.el=, que luego carga cómo la configuración cómo tal. El archivo =private-literate.org= es, como su nombre indica, privado. Tengo mi contraseña de GNU Social y la de mi nextcloud. + +PD: =init-literate.org= está [[http://daemons.cf/wp-content/init-literate.org][aquí]]. +* Configuración Genérica +:PROPERTIES: +:CUSTOM_ID: Configuración Genérica +:END: +En esta sección se tocará la configuración que tenga que ver con el manejo general de emacs. Yo suelo arrancar emacs usando un script que llamo =demacs=. En el llamo a emacs en modo demonio para que quede corriendo en segundo plano y luego abro =emacsclient=. Que ventajas tiene esto? Si por lo que sea petan las X, emacs sigue corriendo, por ejemplo. O que puedo no tener ninguna ventana de emacs abierta y aún así no perder las ventanas que hay en ellas. O mejor aún, que puedo usarlo desde terminal como editor de mutt. + +El script que uso es el siguiente: + +#+BEGIN_SRC sh :results code :exports results +cat `which demacs` +#+END_SRC + +#+RESULTS: +#+BEGIN_SRC sh +#!/bin/bash + +USERID=`id -u` +if [[ ! -e /tmp/emacs$USERID/server ]] +then + emacs-24.5 --daemon + emacsclient -c -n -e '(load-file "/tmp/powerline.el")' -e "(org-agenda-list)" +else + emacsclient -c -n -e "(org-agenda-list)" +fi +#+END_SRC + +Me gusta que nada más abrirlo, me muestre la agenda, por eso está el =(org-agenda-list)=. El =load-file= al fichero del powerline es debido a que emacs al lanzarse en modo demonio, es como si se lanzase en modo terminal, por lo que hay ciertos paquetes que los carga como tal. Y dado que el powerline que uso es un poco especialito, si no se arranca desde la gui, se ve feo. Por ello la primera vez que se ejecute el =emacsclient=, evalua el powerline. +** Iniciar paquetes elpa/melpa/marmalade +:PROPERTIES: +:CUSTOM_ID: Iniciar paquetes elpa/melpa/marmalade +:END: +Ahora mismo el repositorio de marmalade está comentado por que da un error al usarlo con https. Uso el de ojab.ru, que es un proxy a marmalade. +#+BEGIN_SRC emacs-lisp + (setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/") + ;;("marmalade" . "https://marmalade-repo.org/packages/") + ("marmalade" . "https://ojab.ru/marmalade/") + ("melpa" . "https://melpa.org/packages/"))) + (package-initialize) + + ;; Actualiza la lista de paquetes + (unless package-archive-contents + (package-refresh-contents)) +#+END_SRC +** Asegurarse de que use-package y el-get estan instalados y los inicializa +:PROPERTIES: +:CUSTOM_ID: Asegurarse de que use-package y el-get estan instalados y los inicializa +:END: +#+BEGIN_SRC emacs-lisp + ;; Comprueba si use-package está instalado, sinó lo instala desde los repositorios + (unless (require 'use-package nil 'noerror) + (package-install 'use-package) + ) + + (require 'use-package) + + ;; Añade la ruta de el-get + (add-to-list 'load-path (concat user-emacs-directory "el-get/el-get/")) + + ;; Comprueba si el-get está instalado, sinó lo instala desde un gist + (unless (require 'el-get nil 'noerror) + ;; comprobar si existe el fichero a descargar, si existe no lo descarga + (if (not (file-exists-p "/tmp/el-get-install.el")) + (url-copy-file "https://raw.githubusercontent.com/dimitri/el-get/master/el-get-install.el" "/tmp/el-get-install.el")) + (load-file "/tmp/el-get-install.el") + ) + + (use-package el-get) +#+END_SRC +** Moverse por el buffer +:PROPERTIES: +:CUSTOM_ID: Moverse por el buffer +:END: +Subir y bajar párrafos: +#+BEGIN_SRC emacs-lisp + (global-set-key "\M-p" 'backward-paragraph) + (global-set-key "\M-n" 'forward-paragraph) +#+END_SRC +** Establecer nombre y correo +:PROPERTIES: +:CUSTOM_ID: Establecer nombre y correo +:END: +Al exportar en org-mode, por ejemplo, coge estos valores. +#+BEGIN_SRC emacs-lisp +(setq user-full-name "drymer" + user-mail-address "drymer [ EN ] autistici.org") +#+END_SRC +** Abrir cómo buffer inicial +:PROPERTIES: +:CUSTOM_ID: Abrir cómo buffer inicial +:END: +#+BEGIN_SRC emacs-lisp + (setq initial-buffer-choice "~/Documentos/org/index.org") +#+END_SRC +** Iniciar cómo servidor +:PROPERTIES: +:CUSTOM_ID: Iniciar cómo servidor +:END: +De este modo puedo usar =emacsclient= desde la terminal y la sesión de =emacs= existente. +#+BEGIN_SRC emacs-lisp + (server-start) +#+END_SRC +** Auto-guardado +:PROPERTIES: +:CUSTOM_ID: Auto-guardado +:END: +Es bastante molesto que te vaya dejando la mierda por ahí, mejor en un directorio conjunto. +#+BEGIN_SRC emacs-lisp + (defvar backup-dir (expand-file-name (concat user-emacs-directory "backup/"))) + (defvar autosave-dir (expand-file-name (concat user-emacs-directory "backup/"))) + (setq backup-directory-alist (list (cons ".*" backup-dir))) + (setq auto-save-list-file-prefix autosave-dir) + (setq auto-save-file-name-transforms `((".*" ,autosave-dir t))) + (setq tramp-backup-directory-alist backup-directory-alist) + (setq tramp-auto-save-directory autosave-dir) +#+END_SRC +** Modo por defecto +:PROPERTIES: +:CUSTOM_ID: Modo por defecto +:END: +Al abrir un archivo o bufer sin algún modo asociado, se abrirá en modo texto. +#+BEGIN_SRC emacs-lisp + (setq major-mode 'text-mode) +#+END_SRC +** Acepta 'y' o 'n' cuando pide 'yes' o 'no' +:PROPERTIES: +:CUSTOM_ID: Acepta 'y' o 'n' cuando pide 'yes' o 'no' +:END: +#+BEGIN_SRC emacs-lisp + (fset 'yes-or-no-p 'y-or-n-p) +#+END_SRC +** Lenguaje por defecto en emacs y org-mode +:PROPERTIES: +:CUSTOM_ID: Lenguaje por defecto en emacs y org-mode +:END: +#+BEGIN_SRC emacs-lisp + (setq current-language-environment "Spanish") + (setq org-export-default-language "es") +#+END_SRC +** Moverse por ventanas con shift +:PROPERTIES: +:CUSTOM_ID: Moverse por ventanas con shift +:END: +No funciona en =org-mode=. +#+BEGIN_SRC emacs-lisp + (when (fboundp 'windmove-default-keybindings) + (windmove-default-keybindings)) +#+END_SRC +** Helm +:PROPERTIES: +:CUSTOM_ID: Helm +:END: +Copiado del git de helm. Esta es una configuración bastante mínima. Más información por [[http://daemons.cf/categories/helm/][aquí]]. Ahora mismo no está activo en mi configuración. + +#+name:helm +#+BEGIN_SRC emacs-lisp :tangle no +(require 'helm) +(require 'helm-config) + +(global-set-key (kbd "C-c h") 'helm-command-prefix) +(global-unset-key (kbd "C-x c")) + +(define-key helm-map (kbd "") 'helm-execute-persistent-action) +(define-key helm-map (kbd "C-i") 'helm-execute-persistent-action) +(define-key helm-map (kbd "C-z") 'helm-select-action) + +(global-set-key (kbd "M-y") 'helm-show-kill-ring) +(global-set-key (kbd "C-x b") 'helm-mini) +(global-set-key (kbd "C-x C-f") 'helm-find-files) +(global-set-key (kbd "M-x") 'helm-M-x) + +(helm-mode 1) + +(require 'helm-descbinds) +(helm-descbinds-mode) +#+END_SRC +*** Buscar más eficazmente en Helm +:PROPERTIES: +:CUSTOM_ID: Buscar más eficazmente en Helm +:END: +Más información en [[http://daemons.cf/posts/cosillas-de-emacs-buscar-en-el-buffer/][este articulo]]. Desactivado actualmente. + +#+name:buscar-helm +#+BEGIN_SRC emacs-lisp :tangle no + (global-ace-isearch-mode +1) + (custom-set-variables + '(ace-isearch-input-length 7) + '(ace-isearch-jump-delay 0.25) + '(ace-isearch-function 'avy-goto-char) + '(ace-isearch-use-jump 'printing-char)) +#+END_SRC +** ivy-mode +:PROPERTIES: +:CUSTOM_ID: ivy-mode +:END: +Ivy es más liviano que helm, aunque más simple. Más información [[https://daemons.cf/posts/migrar-de-helm-a-ivy/][aquí]]. + +#+name:ivy-mode +#+BEGIN_SRC emacs-lisp + (unless (require 'ivy nil 'noerror) + (sleep-for 5)) + + (use-package ivy + :init + ;; Añade los buffers de bookmarks y de recentf + (setq ivy-use-virtual-buffers t) + ;; Muestra las coincidencias con lo que se escribe y la posicion en estas + (setq ivy-count-format "(%d/%d) ") + ;; Un mejor buscador + (setq ivy-re-builders-alist + '((read-file-name-internal . ivy--regex-fuzzy) + (t . ivy--regex-plus))) + ;; No se sale del minibuffer si se encuentra un error + (setq ivy-on-del-error-function nil) + ;; ivy mete el simbolo ^ al ejecutar algunas ordenes, así se quita + (setq ivy-initial-inputs-alist nil) + ;; Dar la vuelta a los candidatos + (setq ivy-wrap t) + ;; Ver la ruta de los ficheros virtuales + (setq ivy-virtual-abbreviate 'full) + ;; Asegurarse de que están smex y flx + (use-package smex :ensure t) + (use-package flx :ensure t) + (use-package diminish :ensure t) + :config + (ivy-mode 1) + :diminish ivy-mode + :ensure t + ) + + + (use-package counsel + :bind ( + ;; Sustituir M-x + ("M-x" . counsel-M-x) + ;; Sustituir imenu + ("C-c b" . counsel-imenu) + ;; Sustituir find-file + ("C-x C-f" . counsel-find-file) + ;; Sustituir describe-function + ("C-h f" . counsel-describe-function) + ;; Sustituir describe-variable + ("C-h v" . counsel-describe-variable) + ;; Sustituir descbinds + ("C-h b" . counsel-descbinds) + ;; Sustituye helm-show-kill-ring + ("M-y" . counsel-yank-pop) + ) + :config + ;; usar ffap + (setq counsel-find-file-at-point t) + :ensure t + ) + + (use-package swiper + :bind ( + ;; Sustituir isearch + ("C-s" . swiper) + ("C-r" . swiper) + ) + :ensure t + ) +#+END_SRC + +** Seguir enlaces simbólicos +:PROPERTIES: +:CUSTOM_ID: Seguir enlaces simbólicos +:END: +#+BEGIN_SRC emacs-lisp + (setq vc-follows-symlinks t) +#+END_SRC + +** Emparejar parentesis y otros +:PROPERTIES: +:CUSTOM_ID: Emparejar parentesis y otros +:END: +Empareja () [] {} y "". +#+BEGIN_SRC emacs-lisp + (electric-pair-mode 1) +#+END_SRC +** Mantener lista de buffers recientes +:PROPERTIES: +:CUSTOM_ID: Mantener lista de buffers recientes +:END: +Al usar ivy o helm y ejecutar =switch-buffer= (C-x b) se pueden ver los buffers que se han abierto recientemente si se tiene recentf activo. + +#+BEGIN_SRC emacs-lisp + (setq recentf-max-saved-items 30) + (setq recentf-max-menu-items 20) + (recentf-mode 1) +#+END_SRC +** Guardar el layout tal cómo está +:PROPERTIES: +:CUSTOM_ID: Guardar el layout tal cómo está +:END: +No está activo. +#+BEGIN_SRC emacs-lisp :tangle no + (desktop-save-mode 1) +#+END_SRC +** No truncar líneas +:PROPERTIES: +:CUSTOM_ID: No truncar líneas +:END: +#+BEGIN_SRC emacs-lisp + (setq truncate-lines nil) +#+END_SRC +** Programación +:PROPERTIES: +:CUSTOM_ID: Programación +:END: +*** Auto identación +:PROPERTIES: +:CUSTOM_ID: Auto identación +:END: +#+BEGIN_SRC emacs-lisp + (global-set-key (kbd "RET") 'newline-and-indent) +#+END_SRC +*** Auto completado +:PROPERTIES: +:CUSTOM_ID: Auto completado +:END: +Tiene como dependencia popup. +#+BEGIN_SRC emacs-lisp + (use-package auto-complete + :init + (use-package auto-complete-config + :init + (use-package popup + :ensure t + ) + ) + :config + (ac-config-default) + :ensure t + ) +#+END_SRC +*** Magit +:PROPERTIES: +:CUSTOM_ID: Magit +:END: +#+BEGIN_SRC emacs-lisp + (use-package magit + :bind + ("C-x g" . magit-status) + :config + ; usar un wrapper que torifica git + (setq magit-git-executable "/usr/local/bin/tgit") + :ensure t + ) +#+END_SRC + +El wrapper es el siguiente: +#+BEGIN_SRC sh :results code :exports results +cat `which tgit` +#+END_SRC + +#+RESULTS: +#+BEGIN_SRC sh +#!/bin/bash + +torify git "$@" +#+END_SRC + +*** Aviso de errores con flycheck +:PROPERTIES: +:CUSTOM_ID: Aviso de errores con flycheck +:END: +Solo me interesa para python-mode. +#+BEGIN_SRC emacs-lisp + (use-package flycheck + :config + (setq flycheck-global-modes '(python-mode)) + (global-flycheck-mode) + :diminish flycheck-mode + :ensure t + ) +#+END_SRC + +Necesita pylint para funcionar mejor, por lo que hay que configurarlo minimamente. +#+BEGIN_SRC sh :tangle no +# Lo instalamos +sudo pip install pylint +# Creamos archivo de configuración +pylint --generate-rcfile > ~/.pylintrc +#+END_SRC + +Si no se quiere que aparezcan ciertos errores, se busca el código de estos en [[http://pylint-messages.wikidot.com/all-codes][esta web]] y se añade a la variable =disabled= del archivo de configuración. + +Los que yo he desactivado son los siguientes: + +#+BEGIN_SRC sh :results code :export results +grep "^disable=" ~/.pylintrc +#+END_SRC + +#+RESULTS: +#+BEGIN_SRC sh +disable=setslice-method,delslice-method,nonzero-method,long-builtin,coerce-method,old-division,reload-builtin,filter-builtin-not-iterating,oct-method,old-ne-operator,parameter-unpacking,execfile-builtin,import-star-module-level,no-absolute-import,standarderror-builtin,round-builtin,unicode-builtin,getslice-method,apply-builtin,reduce-builtin,cmp-method,buffer-builtin,metaclass-assignment,file-builtin,indexing-exception,suppressed-message,backtick,dict-view-method,map-builtin-not-iterating,unpacking-in-except,old-octal-literal,using-cmp-argument,raw_input-builtin,coerce-builtin,input-builtin,old-raise-syntax,long-suffix,dict-iter-method,intern-builtin,print-statement,useless-suppression,hex-method,raising-string,cmp-builtin,range-builtin-not-iterating,unichr-builtin,basestring-builtin,xrange-builtin,zip-builtin-not-iterating,next-method-called,C0111,W0702,R0201,W0223,R0913,R0914,C0103,R0902,W0703,R0912 +#+END_SRC +*** Insertar licencia +:PROPERTIES: +:CUSTOM_ID: Insertar licencia +:END: +#+BEGIN_SRC emacs-lisp + (add-to-list 'el-get-sources '(:name xlicense-github + :type github + :pkgname "jtimberman/xlicense-el" + )) + + (if (not (el-get-package-installed-p 'xlicense-github)) + (el-get 'sync 'xlicense-github) + ) + + (use-package xlicense + :load-path "el-get/xlicense-github" + :init + (setq license-directory (concat user-emacs-directory "el-get/xlicense-github/licenses/")) + ) +#+END_SRC + +** Borrar espacios sobrantes +:PROPERTIES: +:CUSTOM_ID: Borrar espacios sobrantes +:END: +Al guardar, borrar los que sobren de cada linea despues de el último carácter. +#+BEGIN_SRC emacs-lisp + (add-hook 'before-save-hook 'delete-trailing-whitespace) +#+END_SRC +** Usar ssh con tramp +:PROPERTIES: +:CUSTOM_ID: Usar ssh con tramp +:END: +Por defecto usa scp, que es muy lento. Así se usará ssh. +#+BEGIN_SRC emacs-lisp + (setq tramp-default-method "ssh") +#+END_SRC +** Golden Ratio +:PROPERTIES: +:CUSTOM_ID: Golden Ratio +:END: +Gestiona las ventanas abiertas modificando el tamaño para hacerlo aceptable. Ignora los buffers concretados en la variable =golden-ratio-exclude-buffer-regexp=. + +#+name:golden-ratio +#+BEGIN_SRC emacs-lisp + (use-package golden-ratio + :config + ;; (defun init/no-golden-ratio-for-buffers (bufname) + ;; "Disable golden-ratio if BUFNAME is the name of a visible buffer." + ;; (and (get-buffer bufname) (get-buffer-window bufname 'visible))) + ;; (defun init/no-golden-ratio () + ;; "Disable golden-ratio for guide-key popwin buffer." + ;; (or (init/no-golden-ratio-for-buffers " *undo-tree*") + ;; (init/no-golden-ratio-for-buffers " *undo-tree Diff*") + ;; )) + + ;; (add-to-list 'golden-ratio-inhibit-functions + ;; 'init/no-golden-ratio) + + (golden-ratio-mode t) + (setq golden-ratio-exclude-buffer-regexp '("undo-tree" "help" "diff" "calendar" "messages")) + :diminish golden-ratio-mode + :ensure t + ) +#+END_SRC + +** Abrir enlaces en el navegador por defecto +:PROPERTIES: +:CUSTOM_ID: Abrir enlaces en el navegador por defecto +:END: +Para establecer un navegador por defecto, hay ejecutar: + +#+BEGIN_SRC sh :tangle no + xdg-settings set default-web-browser qutebrowser.desktop +#+END_SRC + +En general, cada navegador te lo crea. En el caso de qutebrowser esto no fue así, por lo que tuve que copiar el de firefox en =/usr/share/applications/qutebrowser.desktop= que contiene: + +#+BEGIN_SRC sh :results output :export results +cat /usr/share/applications/qutebrowser.desktop +#+END_SRC + +#+RESULTS: +#+begin_example +[Desktop Entry] +Exec=qutebrowser --target tab-bg-silent %u +Icon=qutebrowser +Type=Application +Categories=Network; +Name=qutebrwoser +GenericName=Web Browser +GenericName[af]=Web Blaaier +GenericName[ar]=متصفح ويب +GenericName[az]=Veb Səyyahı +GenericName[bg]=Браузър +GenericName[bn]=ওয়েব ব্রাউজার +GenericName[br]=Furcher ar Gwiad +GenericName[bs]=WWW Preglednik +GenericName[ca]=Fullejador web +GenericName[cs]=WWW prohlížeč +GenericName[cy]=Porydd Gwe +GenericName[da]=Browser +GenericName[de]=Web-Browser +GenericName[el]=Περιηγητής Ιστού +GenericName[eo]=TTT-legilo +GenericName[es]=Navegador web +GenericName[et]=Veebilehitseja +GenericName[eu]=Web arakatzailea +GenericName[fa]=مرورگر وب +GenericName[fi]=WWW-selain +GenericName[fo]=Alnótsfar +GenericName[fr]=Navigateur web +GenericName[gl]=Navegador Web +GenericName[he]=דפדפן אינטרנט +GenericName[hi]=वेब ब्राउज़र +GenericName[hr]=Web preglednik +GenericName[hu]=Webböngésző +GenericName[is]=Vafri +GenericName[it]=Browser Web +GenericName[ja]=ウェブブラウザ +GenericName[ko]=웹 브라우저 +GenericName[lo]=ເວັບບຣາວເຊີ +GenericName[lt]=Žiniatinklio naršyklė +GenericName[lv]=Web Pārlūks +GenericName[mk]=Прелистувач на Интернет +GenericName[mn]=Веб-Хөтөч +GenericName[nb]=Nettleser +GenericName[nds]=Nettkieker +GenericName[nl]=Webbrowser +GenericName[nn]=Nettlesar +GenericName[nso]=Seinyakisi sa Web +GenericName[pa]=ਵੈਬ ਝਲਕਾਰਾ +GenericName[pl]=Przeglądarka WWW +GenericName[pt]=Navegador Web +GenericName[pt_BR]=Navegador Web +GenericName[ro]=Navigator de web +GenericName[ru]=Веб-браузер +GenericName[se]=Fierpmádatlogan +GenericName[sk]=Webový prehliadač +GenericName[sl]=Spletni brskalnik +GenericName[sr]=Веб претраживач +GenericName[sr@Latn]=Veb pretraživač +GenericName[ss]=Ibrawuza yeWeb +GenericName[sv]=Webbläsare +GenericName[ta]=வலை உலாவி +GenericName[tg]=Тафсиргари вэб +GenericName[th]=เว็บบราวเซอร์ +GenericName[tr]=Web Tarayıcı +GenericName[uk]=Навігатор Тенет +GenericName[uz]=Веб-браузер +GenericName[ven]=Buronza ya Webu +GenericName[vi]=Trình duyệt Web +GenericName[wa]=Betchteu waibe +GenericName[xh]=Umkhangeli zincwadi we Web +GenericName[zh_CN]=网页浏览器 +GenericName[zh_TW]=網頁瀏覽器 +GenericName[zu]=Umcingi we-Web +MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml;x-scheme-handler/http;x-scheme-handler/https; +X-KDE-StartupNotify=true +#+end_example + +La configuración necesaria para emacs es la siguiente: + +#+BEGIN_SRC emacs-lisp + (setq browse-url-browser-function 'browse-url-xdg-open) +#+END_SRC + +** Terminal +:PROPERTIES: +:CUSTOM_ID: Terminal +:END: +Establecer shell. +#+BEGIN_SRC emacs-lisp + (setq explicit-shell-file-name "/bin/bash") + (setq shell-file-name explicit-shell-file-name) + (setenv "SHELL" shell-file-name) + (add-hook 'comint-output-filter-functions 'comint-strip-ctrl-m) +#+END_SRC +** Cambiar de ventana más comodamente +:PROPERTIES: +:CUSTOM_ID: Cambiar de ventana más comodamente +:END: +#+BEGIN_SRC emacs-lisp + (use-package switch-window + :ensure t + :bind ("C-x o" . switch-window) + ) +#+END_SRC +** undo-tree +:PROPERTIES: +:CUSTOM_ID: undo-tree +:END: +Visualiza los cambios hechos con un arbol. Además, cuando se tira para atras y se hace un cambio, los primeros siguen accesibles. +#+BEGIN_SRC emacs-lisp + (use-package undo-tree + :diminish undo-tree-mode + :ensure t + :config + (global-undo-tree-mode) + (setq undo-tree-visualizer-timestamps t) + ) +#+END_SRC +** Sobreescribir al seleccionar texto +:PROPERTIES: +:CUSTOM_ID: Sobreescribir al seleccionar texto +:END: +No está activo. +#+BEGIN_SRC emacs-lisp :tangle no + (delete-selection-mode t) +#+END_SRC +** Imenu +:PROPERTIES: +:CUSTOM_ID: Imenu +:END: +Imenu sirver para crear menus de archivos, habitualmente usando las cabeceras. +*** imenu-list +:PROPERTIES: +:CUSTOM_ID: imenu-list +:END: +Muestra imenu en un buffer lateral. No está activo. +#+BEGIN_SRC emacs-lisp :tangle no + (use-package imenu-list + :ensure t + :bind ("C-'" . imenu-list-minor-mode) + :config (setq imenu-list-auto-resize nil) + ) +#+END_SRC + +* Aspecto +:PROPERTIES: +:CUSTOM_ID: Aspecto +:END: +** Tema cyberpunk +:PROPERTIES: +:CUSTOM_ID: Tema cyberpunk +:END: +#+BEGIN_SRC emacs-lisp + (use-package cyberpunk-theme + :config (load-theme 'cyberpunk t) + :ensure t + :init (custom-set-variables + '(custom-safe-themes + (quote + ("71ecffba18621354a1be303687f33b84788e13f40141580fa81e7840752d31bf" default))) + )) +#+END_SRC +** Powerline modificada +:PROPERTIES: +:CUSTOM_ID: Powerline modificada +:END: +Lo siguiente lo he cogido de la configuración de [[https://ogbe.net/emacsconfig.html][Dennis Ogbe]], modificando sólo los colores (creo). +#+BEGIN_SRC emacs-lisp :tangle /tmp/powerline.el + (use-package powerline + :ensure t + :config + (progn (setq powerline-default-separator 'contour) + (setq powerline-height 25)) + (setq powerline-default-separator-dir '(right . left)) + + ;; first reset the faces that already exist + (set-face-attribute 'mode-line nil + :foreground (face-attribute 'default :foreground) + :family "Fira Sans" + :weight 'bold + :background (face-attribute 'fringe :background)) + (set-face-attribute 'mode-line-inactive nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :background (face-attribute 'fringe :background) + :family "Fira Sans" + :weight 'bold + :box `(:line-width -2 :color ,(face-attribute 'fringe :background))) + (set-face-attribute 'powerline-active1 nil + :background "gray30") + (set-face-attribute 'powerline-inactive1 nil + :background (face-attribute 'default :background) + :box `(:line-width -2 :color ,(face-attribute 'fringe :background))) + + ;; these next faces are for the status indicator + ;; read-only buffer + (make-face 'mode-line-read-only-face) + (make-face 'mode-line-read-only-inactive-face) + (set-face-attribute 'mode-line-read-only-face nil + :foreground (face-attribute 'default :foreground) + :inherit 'mode-line) + (set-face-attribute 'mode-line-read-only-inactive-face nil + :foreground (face-attribute 'default :foreground) + :inherit 'mode-line-inactive) + + ;; modified buffer + (make-face 'mode-line-modified-face) + (make-face 'mode-line-modified-inactive-face) + (set-face-attribute 'mode-line-modified-face nil + :foreground (face-attribute 'default :background) + :background "#729FCF" + :inherit 'mode-line) + (set-face-attribute 'mode-line-modified-inactive-face nil + :foreground (face-attribute 'default :background) + :background "#729FCF" + :inherit 'mode-line-inactive) + + ;; unmodified buffer + (make-face 'mode-line-unmodified-face) + (make-face 'mode-line-unmodified-inactive-face) + (set-face-attribute 'mode-line-unmodified-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'mode-line) + (set-face-attribute 'mode-line-unmodified-inactive-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'mode-line-inactive) + + ;; the remote indicator + (make-face 'mode-line-remote-face) + (make-face 'mode-line-remote-inactive-face) + (set-face-attribute 'mode-line-remote-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :background (face-attribute 'default :background) + :inherit 'mode-line) + (set-face-attribute 'mode-line-remote-inactive-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :background (face-attribute 'default :background) + :inherit 'mode-line-inactive) + + ;; the current file name + (make-face 'mode-line-filename-face) + (make-face 'mode-line-filename-inactive-face) + (set-face-attribute 'mode-line-filename-face nil + :foreground "#729FCF" + :background (face-attribute 'default :background) + :inherit 'mode-line) + (set-face-attribute 'mode-line-filename-inactive-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :background (face-attribute 'default :background) + :inherit 'mode-line-inactive) + + ;; the major mode name + (make-face 'mode-line-major-mode-face) + (make-face 'mode-line-major-mode-inactive-face) + (set-face-attribute 'mode-line-major-mode-face nil + :foreground (face-attribute 'default :foreground) + :inherit 'powerline-active1) + (set-face-attribute 'mode-line-major-mode-inactive-face nil + :box `(:line-width -2 :color ,(face-attribute 'fringe :background)) + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'powerline-inactive1) + + ;; the minor mode name + (make-face 'mode-line-minor-mode-face) + (make-face 'mode-line-minor-mode-inactive-face) + (set-face-attribute 'mode-line-minor-mode-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'powerline-active1) + (set-face-attribute 'mode-line-minor-mode-inactive-face nil + :box `(:line-width -2 :color ,(face-attribute 'fringe :background)) + :foreground (face-attribute 'powerline-inactive1 :background) + :inherit 'powerline-inactive1) + + ;; the position face + (make-face 'mode-line-position-face) + (make-face 'mode-line-position-inactive-face) + (set-face-attribute 'mode-line-position-face nil + :background (face-attribute 'default :background) + :inherit 'mode-line) + (set-face-attribute 'mode-line-position-inactive-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :background (face-attribute 'default :background) + :inherit 'mode-line-inactive) + + ;; the 80col warning face + (make-face 'mode-line-80col-face) + (make-face 'mode-line-80col-inactive-face) + (set-face-attribute 'mode-line-80col-face nil + :background "#729FCF" + :foreground (face-attribute 'default :background) + :inherit 'mode-line) + (set-face-attribute 'mode-line-80col-inactive-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :background (face-attribute 'default :background) + :inherit 'mode-line-inactive) + + ;; the buffer percentage face + (make-face 'mode-line-percentage-face) + (make-face 'mode-line-percentage-inactive-face) + (set-face-attribute 'mode-line-percentage-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'mode-line) + (set-face-attribute 'mode-line-percentage-inactive-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'mode-line-inactive) + + ;; the directory face + (make-face 'mode-line-shell-dir-face) + (make-face 'mode-line-shell-dir-inactive-face) + (set-face-attribute 'mode-line-shell-dir-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'powerline-active1) + (set-face-attribute 'mode-line-shell-dir-inactive-face nil + :foreground (face-attribute 'font-lock-comment-face :foreground) + :inherit 'powerline-inactive1) + + (defpowerline dennis-powerline-narrow + (let (real-point-min real-point-max) + (save-excursion + (save-restriction + (widen) + (setq real-point-min (point-min) real-point-max (point-max)))) + (when (or (/= real-point-min (point-min)) + (/= real-point-max (point-max))) + (propertize (concat (char-to-string #x2691) " Narrow") + 'mouse-face 'mode-line-highlight + 'help-echo "mouse-1: Remove narrowing from the current buffer" + 'local-map (make-mode-line-mouse-map + 'mouse-1 'mode-line-widen))))) + + (defpowerline dennis-powerline-vc + (when (and (buffer-file-name (current-buffer)) vc-mode) + (if window-system + (let ((backend (vc-backend (buffer-file-name (current-buffer))))) + (when backend + (format "%s %s: %s" + (char-to-string #xe0a0) + backend + (vc-working-revision (buffer-file-name (current-buffer)) backend))))))) + + (setq-default + mode-line-format + '("%e" + (:eval + (let* ((active (powerline-selected-window-active)) + + ;; toggle faces between active and inactive + (mode-line (if active 'mode-line 'mode-line-inactive)) + (face1 (if active 'powerline-active1 'powerline-inactive1)) + (face2 (if active 'powerline-active2 'powerline-inactive2)) + (read-only-face (if active 'mode-line-read-only-face 'mode-line-read-only-inactive-face)) + (modified-face (if active 'mode-line-modified-face 'mode-line-modified-inactive-face)) + (unmodified-face (if active 'mode-line-unmodified-face 'mode-line-unmodified-inactive-face)) + (position-face (if active 'mode-line-position-face 'mode-line-position-inactive-face)) + (80col-face (if active 'mode-line-80col-face 'mode-line-80col-inactive-face)) + (major-mode-face (if active 'mode-line-major-mode-face 'mode-line-major-mode-inactive-face)) + (minor-mode-face (if active 'mode-line-minor-mode-face 'mode-line-minor-mode-inactive-face)) + (filename-face (if active 'mode-line-filename-face 'mode-line-filename-inactive-face)) + (percentage-face (if active 'mode-line-percentage-face 'mode-line-percentage-inactive-face)) + (remote-face (if active 'mode-line-remote-face 'mode-line-remote-inactive-face)) + (shell-dir-face (if active 'mode-line-shell-dir-face 'mode-line-shell-dir-inactive-face)) + + ;; get the separators + (separator-left (intern (format "powerline-%s-%s" + (powerline-current-separator) + (car powerline-default-separator-dir)))) + (separator-right (intern (format "powerline-%s-%s" + (powerline-current-separator) + (cdr powerline-default-separator-dir)))) + + ;; the right side + (rhs (list + (dennis-powerline-vc minor-mode-face 'r) + (funcall separator-right face1 position-face) + (powerline-raw " " position-face) + (powerline-raw (char-to-string #xe0a1) position-face) + (powerline-raw " " position-face) + (powerline-raw "%4l" position-face 'r) + ;; display a warning if we go above 80 columns + (if (>= (current-column) 80) + (funcall separator-right position-face 80col-face) + (powerline-raw (char-to-string #x2502) position-face)) + (if (>= (current-column) 80) + (powerline-raw "%3c" 80col-face 'l) + (powerline-raw "%3c" position-face 'l)) + (if (>= (current-column) 80) + (powerline-raw " " 80col-face) + (powerline-raw " " position-face)) + (if (>= (current-column) 80) + (funcall separator-left 80col-face percentage-face) + (funcall separator-left position-face percentage-face)) + (powerline-raw " " percentage-face) + (powerline-raw "%6p" percentage-face 'r))) + + ;; the left side + (lhs (list + ;; this is the modified status indicator + (cond (buffer-read-only + (powerline-raw " " read-only-face)) + ((buffer-modified-p) + ;; do not light up when in an interactive buffer. Set + ;; ML-INTERACTIVE? in hooks for interactive buffers. + (if (not (bound-and-true-p ml-interactive?)) + (powerline-raw " " modified-face) + (powerline-raw " " unmodified-face))) + ((not (buffer-modified-p)) + (powerline-raw " " unmodified-face))) + (cond (buffer-read-only + (powerline-raw (concat (char-to-string #xe0a2) " ") read-only-face 'l)) + ((buffer-modified-p) + (if (not (bound-and-true-p ml-interactive?)) + (powerline-raw (concat (char-to-string #x2621) " ") modified-face 'l) + (powerline-raw (concat (char-to-string #x259e) " ") unmodified-face 'l))) + ((not (buffer-modified-p)) + (powerline-raw (concat (char-to-string #x26c1) " ") unmodified-face 'l))) + (cond (buffer-read-only + (funcall separator-right read-only-face filename-face)) + ((buffer-modified-p) + (if (not (bound-and-true-p ml-interactive?)) + (funcall separator-right modified-face filename-face) + (funcall separator-right unmodified-face filename-face))) + ((not (buffer-modified-p)) + (funcall separator-right unmodified-face filename-face))) + ;; remote indicator + (when (file-remote-p default-directory) + (powerline-raw (concat " " (char-to-string #x211b)) remote-face)) + ;; filename and mode info + (powerline-buffer-id filename-face 'l) + (powerline-raw " " filename-face) + (funcall separator-left filename-face major-mode-face) + ;; do not need mode info when in ansi-term + (unless (bound-and-true-p show-dir-in-mode-line?) + (powerline-major-mode major-mode-face 'l)) + (unless (bound-and-true-p show-dir-in-mode-line?) + (powerline-process major-mode-face 'l)) + ;; show a flag if in line mode in terminal + (when (and (bound-and-true-p show-dir-in-mode-line?) (term-in-line-mode)) + (powerline-raw (concat (char-to-string #x2691) " Line") major-mode-face)) + (powerline-raw " " major-mode-face) + ;; little trick to move the directory name to the mode line + ;; when inside of emacs set SHOW-DIR-IN-MODE-LINE? to enable + (if (bound-and-true-p show-dir-in-mode-line?) + (when (not (file-remote-p default-directory)) + (powerline-raw (shorten-directory default-directory 45) + shell-dir-face)) + (powerline-minor-modes minor-mode-face 'l)) + (unless (bound-and-true-p show-dir-in-mode-line?) + (dennis-powerline-narrow major-mode-face 'l))))) + + ;; concatenate it all together + (concat (powerline-render lhs) + (powerline-fill face1 (powerline-width rhs)) + (powerline-render rhs))))))) + + (defvar-local hidden-mode-line-mode nil) + (define-minor-mode hidden-mode-line-mode + "Minor mode to hide the mode-line in the current buffer." + :init-value nil + :global t + :variable hidden-mode-line-mode + :group 'editing-basics + (if hidden-mode-line-mode + (setq hide-mode-line mode-line-format + mode-line-format nil) + (setq mode-line-format hide-mode-line + hide-mode-line nil)) + (force-mode-line-update) + ;; Apparently force-mode-line-update is not always enough to + ;; redisplay the mode-line + (redraw-display) + (when (and (called-interactively-p 'interactive) + hidden-mode-line-mode) + (run-with-idle-timer + 0 nil 'message + (concat "Hidden Mode Line Mode enabled. " + "Use M-x hidden-mode-line-mode to make the mode-line appear.")))) +#+END_SRC + +#+RESULTS: + +** Formato de las columnas de númeracion +:PROPERTIES: +:CUSTOM_ID: Formato de las columnas de númeracion +:END: +Por defecto no se activan, hay que hacerlo a mano con =M-x linum-mode=. +#+BEGIN_SRC emacs-lisp + (setq linum-format "%4d \u2502 ") +#+END_SRC +** Ventana limpia +:PROPERTIES: +:CUSTOM_ID: Ventana limpia +:END: +Sin scroll bar, menu bar ni tool bar. +#+BEGIN_SRC emacs-lisp + (tool-bar-mode -1) + (scroll-bar-mode -1) + (menu-bar-mode -1) +#+END_SRC +** UTF-8 +:PROPERTIES: +:CUSTOM_ID: UTF-8 +:END: +#+BEGIN_SRC emacs-lisp + (prefer-coding-system 'utf-8) + (set-default-coding-systems 'utf-8) + (set-terminal-coding-system 'utf-8) + (set-keyboard-coding-system 'utf-8) + (setq x-select-request-type '(UTF8_STRING COMPOUND_TEXT TEXT STRING)) +#+END_SRC +** Tipo de fuente +:PROPERTIES: +:CUSTOM_ID: Tipo de fuente +:END: +#+BEGIN_SRC emacs-lisp + (custom-set-faces '(default ((t (:family "DejaVu Sans Mono" :foundry "unknown" :slant normal :weight normal :height 107 :width normal))))) +#+END_SRC +** Partir buffers de manera más bonita +:PROPERTIES: +:CUSTOM_ID: Partir buffers de manera más bonita +:END: +#+BEGIN_SRC emacs-lisp + (add-to-list 'default-frame-alist '(height . 40)) + (add-to-list 'default-frame-alist '(width . 90)) +#+END_SRC +** Scroll +:PROPERTIES: +:CUSTOM_ID: Scroll +:END: +Similar a la manera de vim. No tengo claro en que se diferencia, pero me gusta cómo funciona. +#+BEGIN_SRC emacs-lisp + (setq scroll-step 1 + scroll-conservatively 10000) + + (setq scroll-margin 80 + scroll-conservatively 3000 + scroll-up-aggressively 0.02 + scroll-down-aggressively 0.02) +#+END_SRC + +* Configuración por modos +:PROPERTIES: +:CUSTOM_ID: Configuración por modos +:END: +** JSON +:PROPERTIES: +:CUSTOM_ID: JSON +:END: +Los archivos cuyo nombre termine por los mencionados abajo, usarán =json-mode=. +#+BEGIN_SRC emacs-lisp + (use-package json-mode + :mode "\\.json\\'" + :ensure t) +#+END_SRC + +** Haskel +:PROPERTIES: +:CUSTOM_ID: Haskel +:END: +Lo usé un tiempo para xmonad, pero ya no está activo. +#+BEGIN_SRC emacs-lisp :eval no :tangle no + (use-package haskell-mode + :config + (add-hook 'haskell-mode-hook 'turn-on-haskell-doc-mode) + (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation) + (add-hook 'haskell-mode-hook 'haskell-font-lock-symbols t) + (put 'downcase-region 'disabled nil) + :ensure t + ) +#+END_SRC +** Markdown +:PROPERTIES: +:CUSTOM_ID: Markdown +:END: +Cargar =markdown-mode=, usar utf-8 al exportar y asociar el modo a las extensiones ".md" y ".markdown". +#+BEGIN_SRC emacs-lisp + (use-package markdown-mode + :init + (setq markdown-xhtml-header-content "") + :mode "\\.md\\'" + :ensure t + ) + #+END_SRC +** python +:PROPERTIES: +:CUSTOM_ID: python +:END: +Carga el modo =python-mode.el=, que no es el que trae emacs por defecto, activa la identación inteligente y establece la version de python 3. +#+BEGIN_SRC emacs-lisp + (unless (require 'ivy nil 'noerror) + (sleep-for 5)) + + (use-package python-mode + :init + (setq py-smart-indentation t) + (setq py-shell-name "/usr/local/bin/python3") + (setq py-python-command "python3") + :ensure t + ) +#+END_SRC + +Carga el pep8. Se ejecuta con =M-x pep8=. Hay que instalar el paquete =pep8= mediante =pip=. + +#+BEGIN_SRC emacs-lisp + (use-package pep8 + :ensure t) +#+END_SRC + +Este paquete muestra una ralla que marca los 79 carácteres, para cumplir con el pep8. +#+BEGIN_SRC emacs-lisp + (use-package fill-column-indicator + :init + (setq fci-rule-color "purple") + (setq fci-rule-column 79) + (add-hook 'python-mode-hook 'fci-mode) + :ensure t + ) +#+END_SRC + +Configura el =virtualenv= y el =virtualenvwrapper=. +#+BEGIN_SRC emacs-lisp + (use-package virtualenvwrapper + :init + (setq venv-location "~/.env/") + (venv-initialize-eshell) + (venv-initialize-interactive-shells) + :ensure t + ) +#+END_SRC + +** web-mode +:PROPERTIES: +:CUSTOM_ID: web-mode +:END: +No lo he mirado mucho ya que apenas lo uso, es un copia-pega. +#+BEGIN_SRC emacs-lisp + (defun my-setup-php () + (web-mode) + (make-local-variable 'web-mode-code-indent-offset) + (make-local-variable 'web-mode-markup-indent-offset) + (make-local-variable 'web-mode-css-indent-offset) + (setq web-mode-code-indent-offset 4) + (setq web-mode-css-indent-offset 2) + (setq web-mode-markup-indent-offset 2)) + + (add-to-list 'auto-mode-alist '("\\.php$" . my-setup-php)) + + (setq web-mode-ac-sources-alist + '(("css" . (ac-source-words-in-buffer ac-source-css-property)) + ("php" . (ac-source-[/]words-in-buffer + ac-source-words-in-same-mode-buffers + ac-source-dictionary)))) + + (add-to-list 'auto-mode-alist '("\\.php$" . my-setup-php)) +#+END_SRC +** DockerFile +:PROPERTIES: +:CUSTOM_ID: DockerFile +:END: +Editar archivos DockerFile. + +#+BEGIN_SRC emacs-lisp + (use-package dockerfile-mode + :mode "Dockerfile\\'" + :ensure t) +#+END_SRC +** kivy-mode +:PROPERTIES: +:CUSTOM_ID: kivy-mode +:END: +Si el paquete no está instalado, lo instala mediante el-get. +#+BEGIN_SRC emacs-lisp + (use-package kivy-mode + :mode "\\.kv\\'" + :ensure t + ) +#+END_SRC +** gnu-social-mode +:PROPERTIES: +:CUSTOM_ID: gnu-social-mode +:END: +No está activo. + +#+name:gnusocial-mode +#+BEGIN_SRC emacs-lisp :tangle no + (add-to-list 'el-get-sources '(:name gnu-social-mode + :description "gnu-social client" + :type github + :pkgname "bashrc/gnu-social-mode" + ) + ) + + (if (not (el-get-package-installed-p 'gnu-social-mode)) + (el-get 'sync 'gnu-social-mode) + ) + + (use-package gnu-social-mode + :load-path "el-get/gnu-social-mode/" + :init + (setq gnu-social-server-textlimit 140 + gnu-social-server "quitter.se" + gnu-social-username "drymer" + gnu-social-password "Cosas Nazis, Peter" + gnu-social-new-dents-count 1 + gnu-social-status-format "%i %s, %@:\n %h%t\n\n" + gnu-social-statuses-count 200 + ) + ) +#+END_SRC +** po-mode + +:PROPERTIES: +:CUSTOM_ID: po-mode +:END: +#+name: po-mode +#+BEGIN_SRC emacs-lisp + (use-package po-mode + :ensure t + :config + ;; Fuente: https://www.emacswiki.org/emacs/PoMode + (defun po-wrap () + "Filter current po-mode buffer through `msgcat' tool to wrap all lines." + (interactive) + (if (eq major-mode 'po-mode) + (let ((tmp-file (make-temp-file "po-wrap.")) + (tmp-buf (generate-new-buffer "*temp*"))) + (unwind-protect + (progn + (write-region (point-min) (point-max) tmp-file nil 1) + (if (zerop + (call-process + "msgcat" nil tmp-buf t (shell-quote-argument tmp-file))) + (let ((saved (point)) + (inhibit-read-only t)) + (delete-region (point-min) (point-max)) + (insert-buffer tmp-buf) + (goto-char (min saved (point-max)))) + (with-current-buffer tmp-buf + (error (buffer-string))))) + (kill-buffer tmp-buf) + (delete-file tmp-file))))) + ) +#+END_SRC +** org-mode +:PROPERTIES: +:CUSTOM_ID: org-mode +:END: +*** Definir fuente de el-get +:PROPERTIES: +:CUSTOM_ID: Definir fuente de el-get +:END: +Se usa la rama =maint= del repositorio git. Primero se comprueba si está instalado, de no ser así se instalará. Tardará un buen rato. +#+BEGIN_SRC emacs-lisp + ;; Cutre-codigo para quitar del path el org de emacs para que no se lie al cargar de nuevo el modo + (dolist (val load-path) + (if (string-match "lisp\/org" val) + (delete val load-path) + ) + ) + + (add-to-list 'el-get-sources '(:name org-mode-maint + :website "http://orgmode.org/" + :description "Org-mode is for keeping notes, maintaining ToDo lists, doing project planning, and authoring with a fast and effective plain-text system." + :type git + :url "git://orgmode.org/org-mode.git" + :branch "maint" + :load-path ("." "lisp/") + )) + + (if (not (el-get-package-installed-p 'org-mode-maint)) + (el-get 'sync 'org-mode-maint) + ) +#+end_src + +*** Agenda +:PROPERTIES: +:CUSTOM_ID: Agenda +:END: +**** Definir archivos de la agenda +:PROPERTIES: +:CUSTOM_ID: Definir archivos de la agenda +:END: +#+BEGIN_SRC emacs-lisp + (setq org-agenda-files '("~/Documentos/org/index.org" "~/Documentos/org/archive_index.org" "~/Documentos/org/notas.org")) +#+END_SRC +**** Definir archivo de notas para org-capture +:PROPERTIES: +:CUSTOM_ID: Definir archivo de notas para org-capture +:END: +#+BEGIN_SRC emacs-lisp + (setq org-default-notes-file "~/Documentos/org/notas.org") +#+END_SRC +**** Estados de los objetos de las listas +:PROPERTIES: +:CUSTOM_ID: Estados de los objetos de las listas +:END: +Todas las secuencias anteriores al símbolo =|= son tareas que no se consideran terminadas, al contrario de las que estan después de este. + +Los estados que tienen el símbolo =@= son los que, al escogerlos, abren un buffer preguntando si se quiere añadir alguna nota respecto al cambio de estado. Las que tienen el símbolo =!=, en cambio, crean una estampa de tiempo, para dejar constancia de cuando se ha cambiado a ese estado. +#+BEGIN_SRC emacs-lisp + (setq org-todo-keywords + '((sequence "TODO(t)" "NEXT(n)" "IN-PROGRESS(p@/!)" "WAITING(w@/!)" "|" "DONE(d!)" "CANCELED(c@)"))) +#+END_SRC +**** Refile +:PROPERTIES: +:CUSTOM_ID: Refile +:END: +Mover un arbol debajo de otro del mismo fichero o de los archivos de las agendas. +#+BEGIN_SRC emacs-lisp + (setq org-refile-targets '((nil :maxlevel . 10) (org-agenda-files . (:maxlevel . 4)))) +#+END_SRC +**** Caldav +:PROPERTIES: +:CUSTOM_ID: Caldav +:END: +Lo tengo funcionando con owncloud. Si no está instalado, lo instala con el-get. Esta parte no es real, como son cosas "sensibles", van en un fichero a parte. Pero seria algo así: +#+BEGIN_SRC emacs-lisp :eval no :tangle no + (unless (require 'org-caldav nil 'noerror) + (el-get-install 'org-caldav)) + + (use-package org-caldav + :init + (setq org-caldav-url "http://caldav.ejemplo/") + (setq org-caldav-calendar-id "org") + (setq org-caldav-files '("~/Documentos/org/index.org" "~/Documentos/org/archive_index.org" "~/Documentos/org/notas.org")) + (setq org-caldav-inbox '(id "c14f-42fe-a358-648240e73991")) + (setq org-caldav-save-directory "~/Documentos/org/") + ) +#+END_SRC + +Esto es un workaround para un bug raro de url-cookie: +#+BEGIN_SRC emacs-lisp + ;; source http://emacs.stackexchange.com/questions/5469/invalid-date-01-jan-2055 + (defun url-cookie-expired-p (cookie) + "Return non-nil if COOKIE is expired." + (let ((exp (url-cookie-expires cookie))) + (and (> (length exp) 0) + (condition-case () + (> (float-time) (float-time (date-to-time exp))) + (error nil))))) +#+END_SRC +**** Configuración del calendario +:PROPERTIES: +:CUSTOM_ID: Configuración del calendario +:END: +#+BEGIN_SRC emacs-lisp + (setq org-icalendar-timezone "Europe/Madrid") +#+END_SRC +**** calfw +:PROPERTIES: +:CUSTOM_ID: calfw +:END: +Paquete para ver las tareas de =org-mode= en un formato de calendario más típico. Los arrays son sólo traducciones. Si el paquete no está instalado, lo instala mediante el-get. Ahora mismo no lo tengo activo. +#+BEGIN_SRC emacs-lisp :tangle no :eval no + (if (not (el-get-package-installed-p 'calfw)) + (el-get 'sync 'calfw) + ) + + (use-package calfw + :config + (setq cfw:org-overwrite-default-keybinding t) + (setq calendar-week-start-day 1) + (setq calendar-month-name-array + ["Gener" "Febrer" "Març" "Abril" "Maig" "Juny" + "Juliol" "Agost" "Septembre" "Octubre" "Novembre" "Decembre"]) + (setq calendar-day-name-array + ["Diumenge" "Dilluns" "Dimarts" "Dimecres" "Dijous" "Divendres" "Dissabte"]) + ) +#+END_SRC +**** Tareas repetitivas +:PROPERTIES: +:CUSTOM_ID: Tareas repetitivas +:END: +Las tareas marcadas para repetirse, al marcarlas cómo DONE vuelven al estado TODO y añade un timestamp del dia y la hora. +#+BEGIN_SRC emacs-lisp + (setq org-log-repeat 'time) +#+END_SRC +**** Cambiar el formato de CLOCKTABLE +:PROPERTIES: +:CUSTOM_ID: Cambiar el formato de CLOCKTABLE +:END: +Por defecto, al pasar de las 24 horas dedicadas, lo mostrará cómo 1d. Con el siguiente snippet, seguirá mostrando horas. +#+BEGIN_SRC emacs-lisp + (setq org-time-clocksum-format + '(:hours "%d" :require-hours t :minutes ":%02d" :require-minutes t)) +#+END_SRC +*** Edición, diseño y varios +:PROPERTIES: +:CUSTOM_ID: Edición, diseño y varios +:END: +**** Atajos de teclado +:PROPERTIES: +:CUSTOM_ID: Atajos de teclado +:END: +=org-iswitchb= muestra todos los buffers de =org-mode= abiertos. +#+BEGIN_SRC emacs-lisp + ; (define-key global-map "\C-cl" 'org-store-link) + ; (define-key global-map "\C-ci" 'org-insert-link) + (define-key global-map "\C-ca" 'org-agenda) + (define-key global-map "\C-cc" 'org-capture) + (define-key global-map "\C-cS" 'org-caldav-sync) +#+END_SRC +**** Definir lenguajes que entiende babel +:PROPERTIES: +:CUSTOM_ID: Definir lenguajes que entiende babel +:END: +#+BEGIN_SRC emacs-lisp + (org-babel-do-load-languages + 'org-babel-load-languages + '((dot . t) + (emacs-lisp . t) + (gnuplot . t) + (latex . t) + (ledger . t) + (python . t) + (shell . t) + (sql . t) + (sqlite . t))) +#+END_SRC + +#+RESULTS: + +**** Asteriscos bonitos +:PROPERTIES: +:CUSTOM_ID: Asteriscos bonitos +:END: +Requerir el paquete y activarlo sólo cuando se abra un buffer de =org-mode=. +#+BEGIN_SRC emacs-lisp +(unless (require 'org-bullets nil 'noerror) +(sleep-for 5)) + (use-package org-bullets + :init + (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1))) + :ensure t + ) +#+END_SRC +**** Seguir links +:PROPERTIES: +:CUSTOM_ID: Seguir links +:END: +Presionando tanto RET cómo TAB. +#+BEGIN_SRC emacs-lisp + (setq org-return-follows-link t) + (setq org-tab-follows-link t) +#+END_SRC +**** Exportar Markdown +:PROPERTIES: +:CUSTOM_ID: Exportar Markdown +:END: +#+BEGIN_SRC emacs-lisp + (use-package ox-md) +#+END_SRC + +**** Configuracion de bloques de código +:PROPERTIES: +:CUSTOM_ID: Configuracion de bloques de código +:END: +La primera linea formatea el código cómo si se tratase de código nativo, la segunda indenta acorde al código. +#+BEGIN_SRC emacs-lisp + (setq org-src-fontify-natively t) + (setq org-src-tab-acts-natively t) + (setq org-babel-python-command "python3") +#+END_SRC + +**** Elementos de marcado +:PROPERTIES: +:CUSTOM_ID: Elementos de marcado +:END: +La primera línea esconde los símbolos y aplica el marcado, y la segunda cambia el color a los elementos de marcado que empiezan por =. +#+BEGIN_SRC emacs-lisp + (setq org-hide-emphasis-markers t) + (add-to-list 'org-emphasis-alist '("=" (:foreground "cyan"))) +#+END_SRC +**** Quitar confirmación al evaluar código +:PROPERTIES: +:CUSTOM_ID: Quitar confirmación al evaluar código +:END: +Cada vez que se evalua código de un bloque, pide que se confirme. Con el siguiente código, no lo hará. +#+BEGIN_SRC emacs-lisp + (setq org-confirm-babel-evaluate nil) +#+END_SRC +**** Añadir imágenes in-line +:PROPERTIES: +:CUSTOM_ID: Añadir imágenes in-line +:END: +#+BEGIN_SRC emacs-lisp + (org-display-inline-images t t) +#+END_SRC +**** org2blog +:PROPERTIES: +:CUSTOM_ID: org2blog +:END: +No está cargado ni configurado, lo mantengo por si acaso. Para publicar articulos con marcado =org-mode= en wordpress. +#+BEGIN_SRC emacs-lisp :eval no :tangle no + (defun org2web-add-keys() + (local-set-key "n" (quote org2blog/wp-new-entry)) + (local-set-key "p" (quote org2blog/wp-post-buffer))) + + (add-hook 'org2blog/wp-mode-hook 'org2web-add-keys) + + (require 'org2blog-autoloads) + +;; habia un bug raro que hace que tengas que tener dos blogs puestos + (setq org2blog/wp-blog-alist + '(("blog" + :url "http://blog.net/xmlrpc.php" + :username "drymer" + :default-title "Hola Mundo" + :tags-as-categories nil) + ("my-blog" + :url "http://username.server.com/xmlrpc.php" + :username "admin"))) + + (setq org2blog/wp-use-sourcecode-shortcode nil) +#+END_SRC +**** org2nikola +:PROPERTIES: +:CUSTOM_ID: org2nikola +:END: +Sirve para publicar en =nikola= con marcado =org-mode=. Si no está instalado, lo instala mediante el-get. [[https://daemons.cf/posts/nikola-emacs-gestionar-un-blog-de-contenido-esttico/][Más información (o no)]]. + +#+BEGIN_SRC emacs-lisp + (add-to-list 'el-get-sources '(:name org2nikola + :website "https://github.com/redguardtoo/org2nikola.git" + :description "Export org into HTML used by static blog generator nikola." + :type git + :url "https://github.com/redguardtoo/org2nikola.git" + :load-path ("./") + )) + + (if (not (el-get-package-installed-p 'org2nikola)) + (el-get 'sync 'org2nikola) + ) +#+END_SRC + +Las funciones cutres son mías, si me animo algún día las mejoraré. + +#+name:org2nikola +#+BEGIN_SRC emacs-lisp + ;; Se instala el htmlize de melpa, el de org-mode es demasiado viejo + (use-package htmlize :ensure t) + + (use-package org2nikola + :load-path "el-get/org2nikola/" + :config + (setq org2nikola-output-root-directory "~/Documentos/blog/") + (setq org2nikola-use-verbose-metadata t) + + (defun blog/build () + "Construye la web." + (interactive) + (compile (concat "source ~/.env/blog/bin/activate; cd " org2nikola-output-root-directory "; bash scripts/construir.sh; deactivate") t)) + + (defun blog/serve () + "Sirve la web en un servidor web interno." + (interactive) + (compile (concat "source ~/.env/blog/bin/activate; cd " org2nikola-output-root-directory "; qutebrowser --target tab-bg-silent http://localhost:8000 2> /dev/null &; nikola serve; deactivate;") t)) + + (defun blog/clean () + "Borra la carpeta output para empezar de cero." + (interactive) + (compile (concat "source ~/.env/blog/bin/activate; cd " org2nikola-output-root-directory "; nikola clean; deactivate")) t) + + (defun blog/deploy () + "Despliega la web al momento preguntando por el nombre del commit." + (interactive) + (compile (concat "source ~/.env/blog/bin/activate; cd " org2nikola-output-root-directory "; nikola deploy; deactivate;") t)) + + (defun blog/autodeploy () + "Despliega la web automáticamente el día designado." + (interactive) + (insert + (compile (concat "/usr/local/bin/programa-post " (org-read-date))))) + + (defun blog/url-post () + "Devuelve el enlace del articulo en el que esté el cursor." + (interactive) + (setq url (concat "https://daemons.cf/posts/" + (cdr (car (org-entry-properties (point) "post_slug"))))) + (message url) + (kill-new url) + ) + + (defun blog/url-config () + "Devuelve el enlace de la parte de la configuración en la que esté el cursor." + (interactive) + (setq url (concat "https://daemons.cf/stories/mi-configuracin-de-emacs/#" + (cdr (car (org-entry-properties (point) "CUSTOM_ID"))))) + (message url) + (kill-new url) + ) + ) +#+END_SRC +**** Notas a pie de página +:PROPERTIES: +:CUSTOM_ID: Notas a pie de página +:END: +Prefiero que aparezcan las notas debajo del arbol en el que se ha tomado. +#+BEGIN_SRC emacs-lisp +(setq org-footnote-section nil) +#+END_SRC +**** toc-org +:PROPERTIES: +:CUSTOM_ID: toc-org +:END: +Ando trasteando toc-org para crear tablas de contenido exportables en org-mode. Aún no está listo. + +#+BEGIN_SRC emacs-lisp + (use-package toc-org + :ensure t + :init + (add-hook 'org-mode-hook 'toc-org-enable) + ) +#+END_SRC +*** Cifrar archivos +:PROPERTIES: +:CUSTOM_ID: Cifrar archivos +:END: +#+BEGIN_SRC emacs-lisp + (use-package epa-file + :init + (epa-file-enable) + ) + #+END_SRC +*** Generar id para cabeceras de manera dinámica +:PROPERTIES: +:CUSTOM_ID: Generar id para cabeceras de manera dinámica +:END: + +A diferencia de la función de writequit, esta establece el título como custom\under{}id. +#+BEGIN_SRC emacs-lisp + ;; Fuente: https://writequit.org/articles/emacs-org-mode-generate-ids.html + ;; requerir libreria de ayuda + (require 'org-id) + + ;; función que creará los id + (defun eos/org-custom-id-get (&optional pom create prefix) + "Get the CUSTOM_ID property of the entry at point-or-marker POM. + If POM is nil, refer to the entry at point. If the entry does + not have an CUSTOM_ID, the function returns nil. However, when + CREATE is non nil, create a CUSTOM_ID if none is present + already. PREFIX will be passed through to `org-id-new'. In any + case, the CUSTOM_ID of the entry is returned." + (interactive) + (org-with-point-at pom + (let ((id (org-entry-get nil "CUSTOM_ID"))) + (cond + ((and id (stringp id) (string-match "\\S-" id)) + id) + (create + (setq id (org-get-heading)) + (org-entry-put pom "CUSTOM_ID" id) + (org-id-add-location id (buffer-file-name (buffer-base-buffer))) + id))))) + + (defun eos/org-add-ids-to-headlines-in-file () + "Add CUSTOM_ID properties to all headlines in the + current file which do not already have one." + (interactive) + (org-map-entries (lambda () (eos/org-custom-id-get (point) 'create)))) + #+END_SRC +*** Hábitos +:PROPERTIES: +:CUSTOM_ID: Hábitos +:END: +#+BEGIN_SRC emacs-lisp + (use-package org-habit + :init + (add-to-list 'org-modules 'org-habit) + :config + (setq org-habit-preceding-days 7 + org-habit-following-days 0 + org-habit-graph-column 80 + org-habit-show-habits-only-for-today t + org-habit-show-all-today t) + ) +#+END_SRC +*** org-protocol +:PROPERTIES: +:CUSTOM_ID: org-protocol +:END: +#+BEGIN_SRC emacs-lisp +(use-package org-protocol) +#+END_SRC +*** Empareja simbolos de marcado y paréntesis +:PROPERTIES: +:CUSTOM_ID: Empareja simbolos de marcado y paréntesis +:END: +#+BEGIN_SRC emacs-lisp + (modify-syntax-entry ?/ "(/" org-mode-syntax-table) + (modify-syntax-entry ?* "(*" org-mode-syntax-table) + (modify-syntax-entry ?_ "(_" org-mode-syntax-table) + (modify-syntax-entry ?= "(=" org-mode-syntax-table) +#+END_SRC +*** Más profundidad en imenu +:PROPERTIES: +:CUSTOM_ID: Más profundidad en imenu +:END: +#+BEGIN_SRC emacs-lisp + (setq org-imenu-depth 9) +#+END_SRC +*** Capturas de notas +:PROPERTIES: +:CUSTOM_ID: Capturas de notas +:END: +#+BEGIN_SRC emacs-lisp + (setq org-capture-templates + '(("s" "Tasca Simple" entry (file+headline "~/Documentos/org/notas.org" "Notes") + "* TODO %? \n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n") + + ("b" "Idea per article" entry (file "~/Documentos/blog/Articulos/articulos.org" "Blog") + "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n") + + ("p" "Personal" entry (file+headline "~/Documentos/org/index.org" "Personal") + "* TODO %? \n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n") + + ("t" "Treball" entry (file+headline "~/Documentos/org/index.org" "Treball") + "* TODO %? \n:PROPERTIES:\n:CREATED: %u\n:END:\nSCHEDULED: %(org-insert-time-stamp (org-read-date nil t \"+0d\"))\n") + + ("w" "Marcadors" entry (file "~/Documentos/org/web.org") + "* %x\n %U\n %c" + :empty-lines 1) + + ("v" "Relacionat amb els VPS / chustaserver" entry (file+headline "~/Documentos/org/index.org" "VPS") + "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n") + )) + + (setq org-capture-templates + (append org-capture-templates + '(("o" "Ordinadors") + ("og" "General" entry (file+headline "~/Documentos/org/index.org" "General") + "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n") + + ("oi" "isso-gnusocial" entry (file+headline "~/Documentos/org/index.org" "isso-gnusocial") + "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n") + + ("or" "gnusrss" entry (file+headline "~/Documentos/org/index.org" "gnusrss") + "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n") + + ("oj" "jabbergram" entry (file+headline "~/Documentos/org/index.org" "jabbergram") + "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n") + + ("os" "SimpleUpload" entry (file+headline "~/Documentos/org/index.org" "SimpleUpload") + "* TODO %?\n:PROPERTIES:\n:CREATED: %u\n:END:\n") + ))) +#+END_SRC +*** Comandos de Agenda +:PROPERTIES: +:CUSTOM_ID: Comandos de Agenda +:END: + +#+name:custom-commands +#+BEGIN_SRC emacs-lisp + (setq org-agenda-custom-commands + '(("b" . "Blog") + ("bi" "Idees per article" ((todo "TODO|IN-PROGRESS" ((org-agenda-files '("~/Documentos/blog/Articulos/articulos.org")))))) + ("bp" "Articles llestos per a publicar" ((todo "READY|PROGRAMMED" ((org-agenda-files '("~/Documentos/blog/Articulos/articulos.org")))))) + ("p" . "Projectes Personals") + ("pp" "Projectes Personals" tags-todo "projectes") + ("pg" "General" tags-todo "general") + ("pi" "isso-gnusocial" tags-todo "issoGnusocial") + ("pr" "gnusrss" tags-todo "gnusrss") + ("pj" "jabbergram" tags-todo "jabbergram") + ("v" "Relacionat amb els VPS / chustaserver" tags-todo "vps") + ("w" "Webs" tags "" ((org-agenda-files '("~/Documentos/org/web.org")))) + ) + ) +#+END_SRC + +* Funciones personalizadas +:PROPERTIES: +:CUSTOM_ID: Funciones personalizadas +:END: +** Recargar todos los buffers abiertos +:PROPERTIES: +:CUSTOM_ID: Recargar todos los buffers abiertos +:END: +Es útil cuando los archivos se suelen sincronizar y se deja el pc abierto. Los archivos que esten abiertos y hayan cambiado, se refrescaran. +#+BEGIN_SRC emacs-lisp + (defun reload-all-buffers () + "Recargar todos los buffers abiertos." + (interactive) + (dolist (buf (buffer-list)) + (with-current-buffer buf + (when (and (buffer-file-name) (file-exists-p (buffer-file-name)) (not (buffer-modified-p))) + (revert-buffer t t t) ))) + (message "Refreshed open files.")) +#+END_SRC +** Insertar cabeceras para org-mode +:PROPERTIES: +:CUSTOM_ID: Insertar cabeceras para org-mode +:END: +#+name:insertar-cabeceras +#+BEGIN_SRC emacs-lisp + (defun insert-header-org-mode (language) + "Make a template at point." + (interactive + (let ((languages '("Generic" "HTML" "LaTeX" ))) + (list (ido-completing-read "To which export: " languages)) + ) + ) + + (when (string= language "Generic") + (progn + (insert (format "#+TITLE:\n")) + (insert (format "#+AUTHOR:\n")) + (insert (format "#+LANGUAGE: es \n")) + (insert (format "#+OPTIONS: toc:1\n")) + (insert (format "#+TOC: headlines 3\n")) + (insert (format "#+STARTUP: indent\n\n")) + ) + ) + + (when (string= language "HTML") + (progn + (insert (format "#+TITLE:\n")) + (insert (format "#+AUTHOR:\n")) + (insert (format "#+LANGUAGE: ca\n")) + (insert (format "#+OPTIONS: toc:1\n")) + (insert (format "#+TOC: headlines 3\n")) + (insert (format (concat "#+SETUPFILE: " user-emacs-directory "/css/org-html-themes/setup/theme-readtheorg.setup\n\n"))) + ) + ) + + (when (string= language "LaTeX") + (progn + (insert (format "#+Title:\n")) + (insert (format "#+Author:\n")) + (insert (format "#+LANGUAGE: es\n")) + (insert (format "#+LATEX_CLASS: article\n")) + (insert (format "#+LATEX_CLASS_OPTIONS: [spanish,a4paper]\n")) + (insert (format "#+LATEX_HEADER: \\usepackage{color}\n")) + (insert (format "#+LATEX_HEADER: \\usepackage[spanish]{babel}\n\n")) + + ) + ) + ) +#+END_SRC +** Insertar bloque src para org-mode +:PROPERTIES: +:CUSTOM_ID: Insertar bloque src para org-mode +:END: +Además, funciona tanto sin ninguna región activa cómo con esta. De haber región activa, la envuelve. + +#+name:insertar-bloque +#+BEGIN_SRC emacs-lisp + (defun insert-org-src-block (choice) + "Insert src code blocks." + (interactive + (if (org-at-table-p) + (call-interactively 'org-table-rotate-recalc-marks) + (let ((choices '("emacs-lisp" "python" "shell" "css" "ledger" "latex" "lisp" "sqlite"))) + (list (ido-completing-read "Source code type: " choices))))) + + (cond + ((region-active-p) + (let ((start (region-beginning)) + (end (region-end))) + (progn + (goto-char end) + (insert "\n#+END_SRC\n") + (goto-char start) + (insert (format "#+BEGIN_SRC %s\n" choice))) + ) + ) + + (t + (insert (format "#+BEGIN_SRC %s\n" choice)) + (save-excursion (insert "\n#+END_SRC"))))) +#+END_SRC +** Insertar org-entities +:PROPERTIES: +:CUSTOM_ID: Insertar org-entities +:END: +Más información [[http://daemons.cf/posts/cosillas-de-emacs-escapar-simbolos-al-usar-usar-marcado-en-org-mode][aquí]]. + +#+name:insertar-entidades +#+BEGIN_SRC emacs-lisp + (setq org-pretty-entities t) + + (defun modi/org-entity-get-name (char) + "Return the entity name for CHAR. For example, return \"ast\" for *." + (let ((ll (append org-entities-user + org-entities)) + e name utf8) + (catch 'break + (while ll + (setq e (pop ll)) + (when (not (stringp e)) + (setq utf8 (nth 6 e)) + (when (string= char utf8) + (setq name (car e)) + (throw 'break name))))))) + + (defun modi/org-insert-org-entity-maybe (orig-fun &rest args) + "When the universal prefix C-u is used before entering any character, + insert the character's `org-entity' name if available." + (let ((pressed-key (char-to-string (elt (this-single-command-keys) 0))) + entity-name) + (when (and (listp args) (eq 4 (car args))) + (setq entity-name (modi/org-entity-get-name pressed-key)) + (when entity-name + (setq entity-name (concat "\\" entity-name "{}")) + (insert entity-name) + (message (concat "Inserted `org-entity' " + (propertize entity-name + 'face 'font-lock-function-name-face) + " for the symbol " + (propertize pressed-key + 'face 'font-lock-function-name-face) + ".")))) + (when (null entity-name) + (apply orig-fun args)))) + + (advice-add 'org-self-insert-command :around #'modi/org-insert-org-entity-maybe) +#+END_SRC +** Añadir soporte para editar archivos en docker +:PROPERTIES: +:CUSTOM_ID: Añadir soporte para editar archivos en docker +:END: +Usar del siguiente modo: =/docker:drunk_bardeen:/etc/passwd=. Sacado de la [[https://www.emacswiki.org/emacs/TrampAndDocker][wiki]] de emacs. Se puede usar el siguiente alias en bash para ver el nombre del container en ejecución: + +#+BEGIN_SRC sh :eval no :tangle no +alias dname="docker ps | perl -we 'use strict; $_ = <>; m/^(.*)NAMES/ or die; my $offset = length($1); while(<>) {substr($_, 0, $offset, q()); chomp; for(split m/\\W+/) {print qq($_:\n)} }'" +#+END_SRC + +Desactivado de momento, no tengo =docker= en este pc. + +#+name:docker-tramp +#+BEGIN_SRC emacs-lisp :eval no :tangle no +(push + (cons + "docker" + '((tramp-login-program "docker") + (tramp-login-args (("exec" "-it") ("%h") ("/bin/bash"))) + (tramp-remote-shell "/bin/sh") + (tramp-remote-shell-args ("-i") ("-c")))) + tramp-methods) + +(defadvice tramp-completion-handle-file-name-all-completions + (around dotemacs-completion-docker activate) + "(tramp-completion-handle-file-name-all-completions \"\" \"/docker:\" returns + a list of active Docker container names, followed by colons." + (if (equal (ad-get-arg 1) "/docker:") + (let* ((dockernames-raw (shell-command-to-string "docker ps | perl -we 'use strict; $_ = <>; m/^(.*)NAMES/ or die; my $offset = length($1); while(<>) {substr($_, 0, $offset, q()); chomp; for(split m/\\W+/) {print qq($_:\n)} }'")) + (dockernames (cl-remove-if-not + #'(lambda (dockerline) (string-match ":$" dockerline)) + (split-string dockernames-raw "\n")))) + (setq ad-return-value dockernames)) + ad-do-it)) +#+END_SRC +** Insertar fecha de hoy +:PROPERTIES: +:CUSTOM_ID: Insertar fecha de hoy +:END: +#+BEGIN_SRC emacs-lisp + (defun insert-todays-date(arg) + (interactive "P") + (insert (if arg (format-time-string "%d-%m-%Y") + (format-time-string "%d-%m-%Y") + ) + ) + ) +#+END_SRC +** Abrir eshell aquí +:PROPERTIES: +:CUSTOM_ID: Abrir eshell aquí +:END: +Sacada de la web Howardism. +#+BEGIN_SRC emacs-lisp +(defun eshell-here () + "Opens up a new shell in the directory associated with the +current buffer's file. The eshell is renamed to match that +directory to make multiple eshell windows easier." + (interactive) + (let* ((parent (if (buffer-file-name) + (file-name-directory (buffer-file-name)) + default-directory)) + (height (/ (window-total-height) 3)) + (name (car (last (split-string parent "/" t))))) + (split-window-vertically (- height)) + (other-window 1) + (eshell "new") + (rename-buffer (concat "*eshell: " name "*")) + + (insert (concat "ls")) + (eshell-send-input))) +#+END_SRC +** Devolver enlaces +:PROPERTIES: +:CUSTOM_ID: Devolver enlaces +:END: +No le servirá de mucho a nadie, lo uso para copiar en el portapapeles las direcciones de un articulo de mi web. + +#+BEGIN_SRC emacs-lisp +#+END_SRC diff --git a/emacs.d/init.el b/emacs.d/init.el new file mode 100644 index 0000000..6954ea3 --- /dev/null +++ b/emacs.d/init.el @@ -0,0 +1,21 @@ +;; Antes que nada, quitamos del path el org-mode que viene con emacs, por que es viejo +(dolist (val load-path) + (if (string-match "lisp\/org" val) + (progn + (setq org-viejo val) + (delete val load-path) + ) + ) + ) + +;; Se añade la ruta del org-mode nuevo +(add-to-list 'load-path (concat user-emacs-directory "el-get/org-mode-maint/lisp/")) + +;; Se intenta cargar el org-mode más nuevo. Si falla, vuelve a añadir al path la versión vieja para poder cargar el fichero de configuración +(unless (require 'org nil 'noerror) + (add-to-list 'load-path org-viejo) + ) + +;; Se carga la configuración pública y la privada +(org-babel-load-file (concat user-emacs-directory "init-literate.org")) +(org-babel-load-file (concat user-emacs-directory "private-literate.org")) diff --git a/i3/config b/i3/config index 4ffabb1..2a3544d 100644 --- a/i3/config +++ b/i3/config @@ -187,6 +187,8 @@ exec --no-startup-id bash ~/.i3/scripts/autolock.sh exec --no-startup-id parcellite # Move programs to workspace +assign [title="emacs@netbook"] $ws1 +assign [title="emacs-24.5@netbook"] $ws1 assign [class="(?i)firefox"] $ws2 assign [class="(?i)tor"] $ws2 assign [class="(?i)qutebrowser"] $ws2 @@ -195,8 +197,6 @@ assign [title="mutt"] $ws9 assign [class="(?i)keepassx"] $ws5 assign [class="(?i)mumble"] $ws8 assign [title="bittorrent"] $ws3 -assign [title="emacs-24.5-with-x11@slacky"] $ws1 -assign [title="emacs@netbook"] $ws1 assign [title="Steam"] $ws7 assign [class="(?i)mpv"] $ws8 diff --git a/instala.sh b/instala.sh index 3591800..f430e4a 100755 --- a/instala.sh +++ b/instala.sh @@ -1,42 +1,82 @@ +#!/bin/bash + +# +# Author:: drymer +# Copyright:: Copyright (c) 2016, drymer +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + if [[ $1 = "all" ]] then - for file in `ls | grep -v "README\|instala.sh"` - do - cp -r $(pwd)/$file $HOME/.$file - done + bash instala.sh X + bash instala.sh i3 + bash instala.sh tmux + bash instala.sh qutebrowser + bash instala.sh emacs elif [[ $1 = "X" ]] then - cp $(pwd)/Xdefaults $HOME/.Xdefaults - cp $(pwd)/Xmodmap $HOME/.Xmodmap + ln -sf $(pwd)/Xdefaults $HOME/.Xdefaults + ln -sf $(pwd)/Xmodmap $HOME/.Xmodmap elif [[ $1 = "i3" ]] then - cp -r $(pwd)/i3 $HOME/.i3 - cp $(pwd)/i3/i3blocks.conf $HOME/.i3blocks.conf + ln -sf $(pwd)/i3 $HOME/.i3 + ln -sf $(pwd)/i3/i3blocks.conf $HOME/.i3blocks.conf elif [[ $1 = "mutt" ]] then - cp -r $(pwd)/mutt $HOME/.mutt - cp $(pwd)/mutt/muttrc.example $HOME/.muttrc - cp $(pwd)/mutt/offlineimaprc.example $HOME/.offlineimaprc + ln -sf $(pwd)/mutt $HOME/.mutt + ln -sf $(pwd)/mutt/muttrc.example $HOME/.muttrc + ln -sf $(pwd)/mutt/offlineimaprc.example $HOME/.offlineimaprc elif [[ $1 = "tmux" ]] then - cp $(pwd)/tmux.conf $HOME/.tmux.conf + ln -sf $(pwd)/tmux.conf $HOME/.tmux.conf elif [[ $1 = "qutebrowser" ]] then mkdir -p $HOME/.config/qutebrowser/ - cp -r $(pwd)/qutebrowser/*.conf $HOME/.config/qutebrowser/ + ln -sf $(pwd)/qutebrowser/{qutebrowser.conf,keys.conf} $HOME/.config/qutebrowser/ echo "Necesito permiso de superusuaria para copiar los archivos hosts, capture y umpv a su sitio." - sudo cp $(pwd)/qutebrowser/{capture,umpv} /usr/local/bin/ - sudo cp $(pwd)/qutebrwoser/hosts/ /etc/hosts + sudo ln -sf $(pwd)/qutebrowser/{capture,umpv} /usr/local/bin/ + sudo ln -sf $(pwd)/qutebrwoser/hosts/ /etc/hosts + +elif [[ $1 = "emacs" ]] +then + EMACSDIR="$HOME/.emacs.d" + mkdir -p $EMACSDIR + cp $(pwd)/emacs.d/{init.el,init-literate.org} $EMACSDIR + # crear private-literate.org si no existe para que no se queje init.el + if [[ ! -e $EMACSDIR/private-literate.org ]] + then + echo -e "* Vacio\n#+BEGIN_SRC emacs-lisp\n#+END_SRC" > $EMACSDIR/private-literate.org + fi + + echo "Instalando paquetes de emacs." + emacs -Q --batch --eval "(ignore-errors (load-file \""$EMACSDIR/"init.el\"))" + emacs -Q --batch --eval "(ignore-errors (load-file \""$EMACSDIR/"init-literate.el\"))" + emacs -Q --batch --eval '(ignore-errors (load-file "/tmp/powerline.el"))' + + # Por algun motivo al compilar desde el-get mete una ruta incorrecta en org-loaddefs.el + find $EMACSDIR -name 'org-loaddefs.el' | xargs sed -i "s,org-mode-maint/lisp/,,g" + echo "Necesito permiso de superusuario para copiar los scripts capture y demacs en /usr/local/bin/." + sudo ln -sf $(pwd)/emacs.d/{capture,demacs} /usr/local/bin/ elif [[ $1 = "" ]] then - echo "bash instala.sh {all, X, i3, tmux, qutebrowser}" - + echo "./instala.sh {all, X, i3, tmux, qutebrowser, emacs}" else - echo "No existe ese parámetro. Escoge: {all, X, i3, tmux, qutebrowser}" - + echo "No existe ese parámetro. Escoge: {all, X, i3, tmux, qutebrowser, emacs}" fi