Emacs es mi editor de texto preferido (realmente soy fanatico de EMACS), lo uso continuamente en el trabajo y en casa. Es un editor muy potente, totalmente personalizable, pero dificil de aprender, eso si: una vez superada la curva es toda una herramienta de edición.
Aun así tiene sus cosillas, por ejemplo: la funcionalidad de autoguardado tiene un pequeño (d)efecto lateral realmente feo. Por cada fichero que hayas editado te crea un fichero con el mismo nombre añadiendole un ~ al final del nombre del fichero. Al final acabas con miles de ficheros acabados en ~ por el disco duro, además puedes cometer errores si usas algún sistema de versiones de ficheros al añadir directorios con estos ficheros si olvidas que emacs lo genera.
Además muchos de nosotros ni siquiera necesitamos esta funcionalidad. Yo llevo el autoguardado de serie, como si fuera un cron que se ejecutase cada minuto, de mis tiempos de estudiante de instituto en los que hacias trabajos con word. Si se iba la luz podías perder una tarde de trabajo. Creo recordar que en mi ordenador el autoguardado no venia activado por defecto.
Adjunto a continuación mi archivo .emacs (hay varias cositas adicionales que he configurado, para poder compilar mis programas más rapidamente).
Entre algunas cosas, es que he puesto teclas parecidas a las de Word para manejar EMACS.
;; -*- mode: emacs-lisp -*-
(add-to-list ‘load-path “~/.emacs.d”)
;; Set paper size
(if (or (string-match “XEmacs” emacs-version)
(string-match “20.” emacs-version))
(setq ps-paper-type ‘a4)
(setq ps-paper-type ‘ps-a4))
;; Make ?, ? and such work
(set-language-environment ’spanish)
(set-terminal-coding-system ‘iso-latin-1)
;; Save space
;(menu-bar-mode nil)
;; Activate highlight in search and replace
(setq search-highlight t)
(setq query-replace-highlight t)
;; we want fontification in all modes
(global-font-lock-mode t t)
;; maximum possible fontification
(setq font-lock-maximum-decoration t)
;; Provide templates for new files
(auto-insert-mode t)
;; Abbrevs
; Use C-xaig to correct common typos
; (setq abbrev-file-name “~/emacs/abbrev_defs”)
(if (file-exists-p abbrev-file-name)
(quietly-read-abbrev-file))
;; Activate template autocompletion
(set-default ‘abbrev-mode t)
;; Bell instead of annoying beep
(setq visible-bell t)
;;;turn off the bell http://www.emacswiki.org/cgi-bin/wiki?AlarmBell
(setq ring-bell-function ‘ignore)
;; Do not add empty lines at the end of our file if we press down key
(setq next-line-add-newlines nil)
;; When in text (or related mode) break the lines at 80 chars
(setq fill-column 77)
;; Highlight matching parentheses. Very useful for coding.
(show-paren-mode 1)
;; Automatically reload files after they’ve been modified
;; (typically in Visual C++)
(global-auto-revert-mode 1)
;; Highlight regions for cutting or copying
(setq transient-mark-mode t)
;; Enter changes lines and auto-indents the new line
(add-hook ‘c-mode-hook
‘(lambda ()
(define-key c-mode-map “\C-m” ‘newline-and-indent)))
(add-hook ‘c++-mode-hook
‘(lambda ()
(define-key c++-mode-map “\C-m” ‘newline-and-indent)))
(add-hook ‘vhdl-mode-hook
‘(lambda ()
(define-key vhdl-mode-map “\C-m” ‘newline-and-indent)))
;; Use abbreviations of previously entered phrases, press control enter to choose
(define-key global-map [(control return)] ‘dabbrev-expand)
;; Helper for compilation. Close the compilation window if
;; there was no error at all.
(defun compilation-exit-autoclose (status code msg)
;; If M-x compile exists with a 0
(when (and (eq status ‘exit) (zerop code))
;; then bury the *compilation* buffer, so that C-x b doesn’t go there
(bury-buffer)
;; and delete the *compilation* window
(delete-window (get-buffer-window (get-buffer “*compilation*”))))
;; Always return the anticipated result of compilation-exit-message-function
(cons msg code))
;; Specify my function (maybe I should have done a lambda function)
(setq compilation-exit-message-function ‘compilation-exit-autoclose)
;; =============== Split window and start a shell in second window =============
;; follow-mode allows easier editing of long files
;;(follow-mode t)
;; want two windows at startup
;; (split-window-vertically)
;; move to other window
;; (other-window 1)
;; start a shell
;;(shell)
;; move back to first window
;; (other-window 1)
;; ===== Set the highlight current line minor mode =====
;; In every buffer, the line which contains the cursor will be fully
;; highlighted
;(global-hl-line-mode 1)
;; ===== Set standard indent to 2 rather that 4 =======
(setq standard-indent 2)
; No sangra si estamos en literales
(setq c-tab-always-indent “other”)
; Espacios en vez de tabuladores
(setq-default indent-tabs-mode nil)
;; ========== Line by line scrolling ==================
;; This makes the buffer scroll by only a single line when the up or
;; down cursor keys push the cursor (tool-bar-mode) outside the
;; buffer. The standard emacs behaviour is to reposition the cursor in
;; the center of the screen, but this can make the scrolling confusing
(setq scroll-step 1)
;; ========== Support Wheel Mouse Scrolling ==========
(mouse-wheel-mode t)
;; ========== Prevent Emacs from making backup files ==========
(setq make-backup-files nil)
;disable backup
(setq backup-inhibited t)
;change prefix of auto-save files
(setq auto-save-list-file-prefix “~/.emacs-saves/.saves-”)
;disable auto save
(setq auto-save-default nil)
;; ========== Enable Line and Column Numbering ==========
;; Show line-number in the mode line
(line-number-mode 1)
;; Show column-number in the mode line
(column-number-mode 1)
;; ===== Function to delete a line =====
;; First define a variable which will store the previous column position
(defvar previous-column nil “Save the column position”)
;; Define the nuke-line function. The line is killed, then the newline
;; character is deleted. The column which the cursor was positioned at is then
;; restored. Because the kill-line function is used, the contents deleted can
;; be later restored by usibackward-delete-char-untabifyng the yank commands.
(defun nuke-line()
“Kill an entire line, including the trailing newline character”
(interactive)
;; Store the current column position, so it can later be restored for a more
;; natural feel to the deletion
(setq previous-column (current-column))
;; Now move to the end of the current line
(end-of-line)
;; Test the length of the line. If it is 0, there is no need for a
;; kill-line. All that happens in this case is that the new-line character
;; is deleted.
(if (= (current-column) 0)
(delete-char 1)
;; This is the ‘else’ clause. The current line being deleted is not zero
;; in length. First remove the line by moving to its start and then
;; killing, followed by deletion of the newline character, and then
;; finally restoration of the column position.
(progn
(beginning-of-line)
(kill-line)
(delete-char 1)
(move-to-column previous-column))))
;;=============================================================================
;; * Set Variables & Rebind keys
;;=============================================================================
;; Commands to make my programming environment nice
(global-set-key [f1] ‘help-command)
(global-set-key [f2] ‘undo)
(global-set-key [f3] ‘isearch-repeat-forward)
(global-set-key [f4] ‘replace-string)
(global-set-key [f5] ‘compile)
(global-set-key [f6] ‘next-error)
(global-set-key [f7] ‘other-window)
(global-set-key [f8] ‘enlarge-window)
(global-set-key [f9] ’speedbar-get-focus)
(global-set-key [f11] ‘delete-other-windows)
(global-set-key [f12] ‘nuke-line)
(global-set-key [kp-prior] ’scroll-down) ; [PgUp]
(global-set-key [prior] ’scroll-down) ; [PgUp]
(global-set-key [kp-next] ’scroll-up) ; [PgDn]
(global-set-key [next] ’scroll-up) ; [PgDn]
(global-set-key “\M-g” ‘goto-line)
;; home and end – needed for emacs
(global-set-key [home] ‘beginning-of-line)
(global-set-key [end] ‘end-of-line)
(global-set-key “\C-cd” ‘delete-region)
(global-set-key “\C-ca” ‘copy-region-as-kill)
(global-set-key “\C-cv” ‘yank)
(global-set-key “\C-cx” ‘kill-region)
(global-set-key [delete] ‘delete-char)
(global-set-key [(meta delete)] ‘(lambda () (interactive) (backward-or-forward-kill-word -1)))
(global-set-key [(alt delete)] ‘(lambda () (interactive) (backward-or-forward-kill-word -1)))
;; to get the scroll wheel work
(global-set-key [(button5)] ‘(lambda () (interactive) (scroll-up 3)))
(global-set-key [(button4)] ‘(lambda () (interactive) (scroll-down 3)))
(global-set-key [(shift button5)] ‘(lambda () (interactive) (scroll-up-command)))
(global-set-key [(shift button4)] ‘(lambda () (interactive) (scroll-down-command)))
(global-set-key [(control button5)] ‘(lambda () (interactive) (scroll-up-command)))
(global-set-key [(control button4)] ‘(lambda () (interactive) (scroll-down-command)))
(global-set-key [(mouse-5)] ‘(lambda () (interactive) (scroll-up 3)))
(global-set-key [(mouse-4)] ‘(lambda () (interactive) (scroll-down 3)))
(global-set-key [(shift mouse-5)] ‘(lambda () (interactive) (scroll-up)))
(global-set-key [(shift mouse-4)] ‘(lambda () (interactive) (scroll-down)))
(global-set-key [(control mouse-5)] ‘(lambda () (interactive) (scroll-up)))
(global-set-key [(control mouse-4)] ‘(lambda () (interactive) (scroll-down)))
;==========Now we add color themes support===============
(when window-system
(require ‘color-theme)
;;(load-file “~/.emacs.d/color-theme-blue.el”)
(color-theme-dark-blue2)
)
;; ======================Modes for EMACs=========================
;; make text-mode default
(setq default-major-mode ‘text-mode)
(add-hook ‘c++-mode-hook ‘turn-on-auto-fill)
(add-hook ‘c-mode-hook ‘turn-on-auto-fill)
(add-hook ‘vhdl-mode ‘turn-on-auto-fill)
;;;
;;; VHDL mode
;;;
(autoload ‘vhdl-mode “vhdl-mode” “VHDL Editing Mode” t);
(setq auto-mode-alist (append ‘((”\\.vhd$” . vhdl-mode)) auto-mode-alist))
(setq auto-mode-alist (append ‘((”\\.vhdl$” . vhdl-mode)) auto-mode-alist))
(add-hook ‘vhdl-mode-hook
‘(lambda ()
;;vhdl-electric enables templates
(setq vhdl-electric-mode nil)
(setq vhdl-stutter t)
(setq vhdl-compiler ‘v-system)
(setq vhdl-upper-case-keywords nil)
(setq vhdl-basic-offset 4)
(setq vhdl-comment-level 2)
(setq comment-column 40)
(setq end-comment-column 79)
(setq vhdl-keywords-colorize t)
(setq vhdl-signals-colorize nil)
(setq vhdl-default-colors nil)
(setq vhdl-print-two-column t)
(setq vhdl-print-with-fonts t)
(setq vhdl-print-with-colors nil)
(setq font-lock-keywords-case-fold-search t)
(setq vhdl-index-menu t)
(setq vhdl-sourcefile-menu t)
(setq vhdl-list-indent t)
(setq vhdl-empty-lines t)
(setq indent-tabs-mode nil)
(setq vhdl-zero “‘0′”)
(setq vhdl-one “‘1′”)
(setq vhdl-date-scientific-format nil)
))
;;turn off vhdl templates
(add-hook ‘vhdl-mode-hook (function (lambda () (abbrev-mode nil))))
;; ===============Adding C/C++ templates hooked into C/C++ mode=================
;; This is a way to hook tempo into cc-mode
(defvar c-tempo-tags nil
“Tempo tags for C mode”)
(defvar c++-tempo-tags nil
“Tempo tags for C++ mode”)
;;; C-Mode Templates and C++-Mode Templates (uses C-Mode Templates also)
(require ‘tempo)
(setq tempo-interactive t)
(add-hook ‘c-mode-hook ‘(lambda ()
(local-set-key [f11] ‘tempo-complete-tag)))
(add-hook ‘c-mode-hook ‘(lambda ()
(tempo-use-tag-list ‘c-tempo-tags)
))
(add-hook ‘c++-mode-hook ‘(lambda ()
(tempo-use-tag-list ‘c-tempo-tags)
(tempo-use-tag-list ‘c++-tempo-tags)
))
;;; Preprocessor Templates (appended to c-tempo-tags)
(tempo-define-template “c-include”
‘(”include <” r “.h>” > n
)
“include”
“Insert a #include <> statement”
‘c-tempo-tags)
(tempo-define-template “c-ifdef”
‘(”ifdef ” (p “ifdef-clause: ” clause) > n> p n
“#else /* !(” (s clause) “) */” n> p n
“#endif /* ” (s clause)” */” n>
)
“ifdef”
“Insert a #ifdef #else #endif statement”
‘c-tempo-tags)
(tempo-define-template “c-ifndef”
‘(”ifndef ” (p “ifndef-clause: ” clause) > n
“#define ” (s clause) n> p n
“#endif /* ” (s clause)” */” n>
)
“ifndef”
“Insert a #ifndef #define #endif statement”
‘c-tempo-tags)
;;; C-Mode Templates
(tempo-define-template “c-if”
‘(> “if (” (p “if-clause: ” clause) “)” n>
“{” > n>
> r n
“}” > n>
)
“if”
“Insert a C if statement”
‘c-tempo-tags)
(tempo-define-template “c-else”
‘(> “else” n>
“{” > n>
> r n
“}” > n>
)
“else”
“Insert a C else statement”
‘c-tempo-tags)
(tempo-define-template “c-if-else”
‘(> “if (” (p “if-clause: ” clause) “)” n>
“{” > n
> r n
“}” > n
“else” > n
“{” > n>
> r n
“}” > n>
)
“ifelse”
“Insert a C if else statement”
‘c-tempo-tags)
(tempo-define-template “c-while”
‘(> “while (” (p “while-clause: ” clause) “)” > n>
“{” > n
> r n
“}” > n>
)
“while”
“Insert a C while statement”
‘c-tempo-tags)
(tempo-define-template “c-for”
‘(> “for (” (p “for-clause: ” clause) “)” > n>
“{” > n
> r n
“}” > n>
)
“for”
“Insert a C for statement”
‘c-tempo-tags)
(tempo-define-template “c-for-i”
‘(> “for (” (p “variable: ” var) ” = 0; ” (s var)
” < “(p “upper bound: ” ub)”; ” (s var) “++)” > n>
“{” > n
> r n
“}” > n>
)
“fori”
“Insert a C for loop: for(x = 0; x < ..; x++)”
‘c-tempo-tags)
(tempo-define-template “c-main”
‘(> “int main(int argc, char *argv[])” > n>
“{” > n>
> r n
> “return 0 ;” n>
> “}” > n>
)
“main”
“Insert a C main statement”
‘c-tempo-tags)
(tempo-define-template “c-if-malloc”
‘(> (p “variable: ” var) ” = (”
(p “type: ” type) ” *) malloc (sizeof(” (s type)
“) * ” (p “nitems: ” nitems) “) ;” n>
> “if (” (s var) ” == NULL)” n>
> “error_exit (\”" (buffer-name) “: ” r “: Failed to malloc() ” (s var) ” \”) ;” n>
)
“ifmalloc”
“Insert a C if (malloc…) statement”
‘c-tempo-tags)
(tempo-define-template “c-if-calloc”
‘(> (p “variable: ” var) ” = (”
(p “type: ” type) ” *) calloc (sizeof(” (s type)
“), ” (p “nitems: ” nitems) “) ;” n>
> “if (” (s var) ” == NULL)” n>
> “error_exit (\”" (buffer-name) “: ” r “: Failed to calloc() ” (s var) ” \”) ;” n>
)
“ifcalloc”
“Insert a C if (calloc…) statement”
‘c-tempo-tags)
(tempo-define-template “c-switch”
‘(> “switch (” (p “switch-condition: ” clause) “)” n>
“{” > n>
“case ” (p “first value: “) “:” > n> p n
“break;” > n> p n
“default:” > n> p n
“break;” > n
“}” > n>
)
“switch”
“Insert a C switch statement”
‘c-tempo-tags)
(tempo-define-template “c-case”
‘(n “case ” (p “value: “) “:” > n> p n
“break;” > n> p
)
“case”
“Insert a C case statement”
‘c-tempo-tags)
;;;C++-Mode Templates
(tempo-define-template “c++-class”
‘(”class ” (p “classname: ” class) p n “{” n “public:” n>
(s class) “();”
(indent-for-comment) “the default constructor” n>
(s class)
“(const ” (s class) “&rhs);”
(indent-for-comment) “the copy constructor” n>
(s class)
“& operator=(const ” (s class) “&rhs);”
(indent-for-comment) “the assignment operator” n>
n> “// the default address-of operators” n>
“// “(s class)
“* operator&() { return this; };” n>
“// const “(s class)
“* operator&() const { return this; };” n
n > “~” (s class) “();”
(indent-for-comment) “the destructor” n n>
p n
“protected:” n> p n
“private:” n> p n
“};\t// end of class ” (s class) n>
)
“class”
“Insert a class skeleton”
‘c++-tempo-tags)
;; ================= Templates when creating new files ========================
;; auto-insert for .pl and .cgi
(load-library “autoinsert”)
(define-auto-insert “\\.pl$” ‘perl-auto-insert)
(defun perl-auto-insert ()
(progn
(insert “#! /usr/bin/perl\nuse warnings;\nuse strict;\n”)
(insert “use Carp;\n\n”)
(insert “use FindBin ();\n”)
(insert “use Data::Dumper;\n$Data::Dumper::Indent = 1;\n”)
(insert “$Data::Dumper::Sortkeys = 1;\n\n”)
(insert “use lib $FindBin::Bin;\n\n”)
)
)
(define-auto-insert “\\.cgi$” ‘cgi-auto-insert)
(defun cgi-auto-insert ()
(progn
(insert “#! /usr/bin/perl\nuse warnings;\nuse strict;\n\n”)
(insert “use CGI ();\n”)
(insert “use CGI::Carp qw(fatalsToBrowser);\n”)
(insert “use HTML::Template::Compiled;\n”)
(insert “use FindBin ();\n”)
(insert “use lib $FindBin::Bin;\n\n”)
(insert “my $filename = ‘template.tmpl’;\n”)
(insert “my $cssUrl = ’style.css’;\n\n”);
(insert “my $cgi = CGI->new();\nmy %params = $cgi->Vars();\n\n”)
(insert “print $cgi->header( -type => ‘text/html’, -expires => ‘+3s’ );\n”)
(insert “my $constructorParams = { filename => $filename,\n”)
(insert “ path => \”$FindBin::Bin/templates\”,\n”)
(insert “ # die_on_bad_params => 0,\n”)
(insert “ };\n\n”)
(insert “my $template = &Template\n”)
(insert “ ( $cgi, $constructorParams,\n”)
(insert “ {\n SELF_URL => $ENV{SCRIPT_NAME},\n”)
(insert “ CSS_URL => $cssUrl,\n } );\n\n”)
(insert “print $template->output();\n\n”)
(insert “# print $cgi->start_html(’title’);\n\n\n”)
(insert “# print $cgi->end_html();\n\n”)
(insert “# ————————————————————\n”)
(insert “sub Template {\n”)
(insert “ my( $cgi, $constructorParams, $htmlParams ) = @_;\n\n”)
(insert “ my $template = HTML::Template::Compiled->new( %$constructorParams );\n”)
(insert “ $template->param( %$htmlParams ) if ref $htmlParams;\n\n”)
(insert “ return $template;\n”)
(insert “} # Template\n”)
(insert “# ————————————————————\n”)
)
)
(add-hook ‘find-file-hooks ‘auto-insert)
(desktop-load-default)
(desktop-read)
;;===================== Functions defined by user =============================
;;Convert DOS cr-lf to UNIX newline
(defun dos2unix () (interactive) (goto-char (point-min))
(while (search-forward “\r” nil t) (replace-match “”)))
;;Convert UNIX newline to DOS cr-lf
(defun unix2dos () (interactive) (goto-char (point-min))
(while (search-forward “\n” nil t) (replace-match “\r\n”)))