Oct 29 2009

iswitchb

Tag: basicoverdrive @ 10:51 pm

Iswitchb significa «Interactive Switch Buffer» que es un modo interactivo que facilita manejo de múltiples buffers. Para activarlo debemos añadir a nuestro .emacs las siguientes líneas:

;;============================================================
;; iswitchb mode
;;============================================================
(require ‘iswitchb)
(iswitchb-mode)

Aunque también podemos agregar excepciones para que ignore algunos buffers que puede no interesarnos, éstas son las excepciones típicas, aunque todo dependerá de cada uno, y ésta es una decisión que debe tomar el usuario final:

;;============================================================
;; iswitchb ignores
;;============================================================
(add-to-list ‘iswitchb-buffer-ignore «^ «)
(add-to-list ‘iswitchb-buffer-ignore «*Messages*»)
(add-to-list ‘iswitchb-buffer-ignore «*ECB»)
(add-to-list ‘iswitchb-buffer-ignore «*Buffer»)
(add-to-list ‘iswitchb-buffer-ignore «*Completions»)
(add-to-list ‘iswitchb-buffer-ignore «*ftp «)
(add-to-list ‘iswitchb-buffer-ignore «*bsh»)
(add-to-list ‘iswitchb-buffer-ignore «*jde-log»)
(add-to-list ‘iswitchb-buffer-ignore «^[tT][aA][gG][sS]$»)

Cuando pulsemos «C-x b» para cambiar de buffer, aparecerá un listado de bufferes abiertos a los cuales podemos acceder, por defecto accederemos al buffer que aparece en primer lugar y resaltado de un color distinto. Si queremos acceder a dicho buffer tan sólo debemos pulsar ENTER como lo hacíamos de manera habitual. Si por el contrario lo que queremos es acceder a otro buffer de la lista, podemos pulsar C-s para ir al siguiente buffer o C-r para ir al buffer anterior, y repetir este proceso tantas veces como necesitemos.

Cuando pulsamos «C-x b» para cambiar de buffer, existe otra forma de acceder a un buffer sin necesidad de recorrer dicha lista si es demasiado extensa por ejemplo. Podemos escribir parte del nombre del buffer al cual queramos acceder, por lo que iswitchb ignorará aquellos buffers que no contengan el patrón buscado, acelerando así el proceso y acortando la lista tanto como se pueda, lo cual acelerará el proceso bastante.

También es posible usar las teclas de flecha (comunmente conocidas como arrow keys) en lugar de C-s y C-r que puede resultar un poco incomodo para los que no estén acostumbrados. Para ello deberemos añadir las siguientes líneas en nuestro .emacs:

(defun iswitchb-local-keys ()
(mapc (lambda (K)
(let* ((key (car K)) (fun (cdr K)))
(define-key iswitchb-mode-map (edmacro-parse-keys key) fun)))
‘((«<right>» . iswitchb-next-match)
(«<left>» . iswitchb-prev-match)
(«<up>» . ignore )
(«<down>» . ignore ))))

(add-hook ‘iswitchb-define-mode-map-hook ‘iswitchb-local-keys)

Existe la posibilidad de combinar iswitchb con icicles y otras opciones, para poder acceder a los menus de manera cíclica, la cual no considero fundamental, debido a que dichos listados pueden ser demasiado largos y puede ser una odisea tener que ir moviéndose elemento por elemento hasta acceder al item deseado, a excepción de si se filtra escribiendo parte de la cadena


Oct 29 2009

JDEE (Java Development Environment for Emacs)

Tag: basicoverdrive @ 8:21 pm

JDEE (Java Development Environment for Emacs) es un add-on que permite a Emacs comprender el sistema de creación, edición, debugging y documentación del lenguaje Java. Es necesario tener CEDET instalado (explicado en un artículo anterior) también requiere elib (Emacs Lisp Library), JDK (Java Development Kit o herramientas equivalentes; compilador, máquina virtual, debugger, librerías de clases, etc) y un entorno de shell como Bash, también es recomendado tener instalado y configurado ECB (explicado en el artículo anterior).

Básicamente JDEE incluye:

  • Un menú específico para JDEE (compilar, ejecutar, debuggear, construir, navegación, proyecto, ayuda).
  • Highlighting.
  • Auto indentación.
  • Enlaces a código de los errores de compilación.
  • Debugging a nivel de código fuente.
  • Navegación específica para el código fuente.
  • Soporte para makefiles.
  • Generación de código automática.
  • Intérprete de código fuente en Java.

Como la instalación de CEDET ya la hemos explicado en artículos anteriores, pasaremos a explicar como instalar la biblioteca ELisp, Elib (aquí se puede ver la documentación completa sobre ello):

Una vez descargado el fuente debemos ejecutar make && make install fijándonos bien donde se instala o bien indicándolo nosotros mismos mediante los modificadores mediante el configure o bien editando directamente el Makefile tales como:

Entrada en el makefile / Valor típico / Descripción:

  • prefix suele tomar el valor /usr/local e indica el directorio donde se encuentra shared.
  • datadir suele tomar el valor $(prefix)/share e indica el directorio principal donde se encuentra Emacs.
  • locallisppath suele tomar el valor $(datadir)/emacs/site-lisp e indica donde se deben instalar los ficheros Lisp locales.
  • ELIBDIR suele tomar el valor $(locallisppath)/elib e indica donde irán los ficheros Lisp de Elib.
  • EMACS suele tomar el valor /usr/bin/emacs e indica cuál es el binario con que se lanza emacs.

Una vez instaladas todas las dependencias de emacs para poder usar JDEE, podemos proceder a la instalación del mismo. A nuestro .emacs ahora debemos añadirle las siguientes líneas:

;; Minimal setup required to run the JDEE
;; Debug option to enable a backtrace when a problem occurs
(setq debug-on-error t)

;; Include the path to the JDEE and its required packages
(add-to-list ‘load-path (expand-file-name «/usr/local/emacs/site-lisp/jde/lisp»))
(add-to-list ‘load-path (expand-file-name «/usr/local/emacs/site-lisp/semantic»))
(add-to-list ‘load-path (expand-file-name «/usr/local/emacs/site-lisp/speedbar»))
(add-to-list ‘load-path (expand-file-name «/usr/local/emacs/site-lisp/eieio»))
(add-to-list ‘load-path (expand-file-name «/usr/local/emacs/site-lisp/elib»))

;; Defer loading JDEE until you open a Java file
(setq defer-loading-jde nil)

(if defer-loading-jde

(progn

(autoload ‘jde-mode «jde» «JDE mode.» t)

(setq auto-mode-alist

(append

‘((«\\.java'» . jde-mode))

auto-mode-alist)))

(require ‘jde))

;; Set basic indentation for Java source files of 2 spaces
(add-hook ‘jde-mode-hook ‘(lambda () setq c-basic-offset 2)))

;; Set up to run bash as its primary shell (important for JDEE env)
(setq shell-file-name «bash»)
(setq shell-command-switch «-c»)
(setq explicit-shell-file-name shell-file-name)
(setenv «SHELL» shell-file-name)
(setq explicit-sh-args ‘(«-login» «-i»))
(if (boundp ‘w32-quote-process-args)

(setq w32-quote-process-args ?\»)) ;; Include only for MS Windows

A partir de aquí la compilación de los ficheros lisp de JDEE no es requerida, pero sí aconsejable para ganar tiempo. Para realizar esto, debemos lanzar emacs y una vez dentro ejecutaremos M-x jde-compile-jde, sólo es necesario compilarlo una vez obviamente.

Registrar las Java Tools es también un paso opcional, pero es interesante para cuando se tienen múltiples versiones de JDK instaladas. Para registrar un JDK será necesario ejecutar M-x customize-variable y desde ahí configurar la variable jde-jdk-registry, donde podemos seleccionar INS de insert para añadir un nuevo número de versión y path para el JDK. Este proceso puede ser repetido tantas veces como JDK queramos registrar, es importante presionar el boton «State» para guardar los cambios para futuros usos, así como presionar el botón «Finish« para esta primera vez antes de cerrar el buffer. Una vez hayamos registrado las JDK deseadas podemos cambiar la versión activa mediante M-x customize-variable y editar la variable jde-jdk, la cuál mostrará un prompt con la lista de JDK registradas.

Se ha comprobado que en algunos casos las JDK dan problemas a la hora de compilarla, el problema típico suele ser que no se encuentra el fichero tools.jar, en ese caso deberíamos editar la variable jde-global-classpath e incluir dicho fichero. Una configuración típica podría ser esta (variable valor):

jde-global-classpath /usr/local/j2se:.

jde-jdk-registry Version = 1.4.2

Path = /usr/local/j2se

Ahora veamos que keystrokes y utilidades hemos ganado teniendo JDEE funcionando correctamente: previamente teníamos comandos soportados por M-x java-mode tal que:

M-a y M-e: para moverse por los comandos java.
M-C-\ : indenta una región y tienen en cuenta las excepciones para realizar una alineación especial.

Hay más de ellos, todos relacionados con el modo c++. Ahora tenemos otras ciertas ventajas, tales como:

C-c C-v C-. : ‘jde-complete‘; muestra el listado de posibles opciones (incluida para toda la API de Java). La lista de opciones es completada mediante la viariable jde-global-path (que es posible configurar) dándole el valor deseado, sino tomará el del CLASSPATH.
(sin keystroke asociada) : ‘jde-browse-class-at-point‘; Lanza el navegador de clases.

Para la generación de código tenemos:

C-c C-v C-l : ‘jde-gen-println‘ ; muestra un prompt para imprimir el contenido e inserta System.out.println().
C-c C-v C-z : ‘jde-import-find-and-import‘; importa automaticamente los imports requeridos al inicio del fichero.
C-c C-v i : ‘jde-wiz-implement-interface‘; muestra un prompt para añadir el nombre de la interfaz a implementar, añade los imports necesarios, así como los requeridos para los argumentos de los métodos. Además de ello provee de skeletons comentados para cada metodo de la interfaz.

Además de ello permite generar getters y setters mediante la creación de una lista de atributos y ejecutando el wizard. También se puede usar el wizard para actualizar dichos getters y setters en el caso de que se haya añadido o eliminado alguno.

Para la compilación y ejecución de programas tenemos:

C-c C-v C-c ; compila el buffer actual. Si existen errores es posible moverse por dicho buffer de errores, pulsar intro, y el cursor automáticamente saltará al error referido en el código.
(sin keystroke asociada) : ‘jde-ant-build‘; compila mediante ant, para más información mirar la sección de Help de las variables comenzadas por jde-ant.
C-c C-v C-r : »; ejecuta el buffer actual abriendo un buffer nuevo con cualquier salida (output) que tenga dicho programa.

Para ejecutar proyectos grandes es conveniente editar las variables jde-run-working-directory que indica dónde comenzará la ejecución y jde-run-applications-class que indica el nombre de la clase que contiene el método main() a ejecutar.

Los siguientes keystrokes son útiles en caso de encontrar backtraces en el caso de ocurrir alguna excepción:

C-c C-v C-[ ; ir al siguiente método del stacktrace.
C-c C-v C-] ; ir al anterior método del stacktrace.

Los keystrokes referentes a debugging mediante JDB (Java Debugger) son:

(sin keystroke asociada): ‘jde-jdb‘; lanza jdb.
C-c C-a C-s ; siguiente paso (comando JDB es step)
C-c C-a C-n ; siguiente sentencia (comando JDB es next)
C-c C-a C-c ; continua (comando JDB es cont)
C-c C-a C-b ; toggle breakpoint (comando JDB es stop in, stop at, clear)
C-c C-a C-p ; imprime una expresión (comando JDB es print)
C-c C-a C-d ; vuelca un objeto (comando JDB es dump)

Las ventajas que nos ofrece JDB desde emacs es que podemos interactuar directamente con el debugger accediendo al buffer *debug*.

Nota: se debe tener en cuenta que las clases han debido ser compiladas con soporte para debugging, esto es mediante el parámetro -g para el comando javac, para ello con JDEE deberemos haber editado la variable jde-compile-option-debug.

JDEE es inmenso, por lo que si queremos una referencia completa sobre todo el potencial del mismo deberemos acceder a la web oficial de JDEE.


Oct 28 2009

Emacs TAGS, ETAGS, GNU/make, Automake y Autoconf

Tag: basicoverdrive @ 10:47 pm

Préviamente hemos comentado en otros artículos algunas opciones de usar Emacs como IDE para muchos de los lenguajes de programación que conocemos, y así poder usar un mismo entorno para todos ellos sin necesidad de ir cambiando, con el consiguiente tiempo perdido que ello conlleva.

Comentamos en artículos anteriores el usar el c-mode, con los keystrokes habituales y más útiles. También comentamos el uso de CEDET como un conjunto de utilidades destinadas a este fin. Aquí comentaremos el uso de algunas técnicas específicas para hacer de emacs un entorno cómodo para el desarrollo en c, y algunas otras que son generales a todos o la mayoría de lenguajes.

Comentar que desde emacs tenemos funciones (algunas mapeadas y otras no) referentes a TAGS y ETAGS. La diferencia entre TAGS y ETAGS básicamente es que el formato de TAGS es un formato general que puede ser interpretado por distintas herramientas, mientras que ETAGS es específico de emacs. Comentar que existen más posibilidades desde emacs para trabajar con TAGS tales como Icicles, EtagsSelect, Vtags, etc.

El comando etags puede ser usado desde consola para crear el fichero de ETAGS para un directorio tan sólo ejecutando el comando:

etags *.c *.h

O bien para todo el árbol y subdirectorios del mismo y común para c y c++ mediante:

find . | egrep ‘\.(h|c|hpp|cpp)$’ | etags –

Antes de comenzar a explicar como usar ETAGS en emacs, debemos decir que es recomendable tener tres herramientas básicas instaladas (que por norma general vienen en cualquier distribución de GNU moderna: GNU/make, autoconf y automake. Realmente no es necesaria la instalación de autoconf ni automake, pero decir que es interesante, debido a que automake genera los ETAGS automáticamente, y autoconf es una dependencia de automake. Antes de continuar daré una noción básica de ejemplo para trabajar con Makefiles.

Aquí podemos ver un ejemplo de Makefile lo más simple posible para un sólo fichero .c:

main.o : main.c

gcc -c main.c

Aquí otro ejemplo esta vez con dos ficheros .c:

main : main.o foo.o

gcc main.o foo.o -o main

main.o : main.c

gcc -c main.c

foo.o : foo.c

gcc -c foo.c

Aquí otro ejemplo esta vez usando cabeceras propias .h:

all : main.o list.o stack.

gcc main.o list.o stack.o -o main

clean :

rm main.o list.o stack.o

list.o : list.c list.h

gcc -c list.c

stack.o : stack.c stack.h

gcc -c stack.c

main.o : main.c list.h list.c stack.h stack.c

gcc -c main.c

Éste último ejemplo se suele simplificar usando variables que se refieren a la lista de argumentos usados y al listado de objetos útil para cuando se tienen bastantes ficheros y parámetros para el compilador, tal que así:

.SUFFIXES: .o .c

.c.o:

$(CC) -c $(CFLAGS) $<

CC = @gcc

CFLAGS = -W -Wall -ansi -pedantic -Wbad-function-cast \

-Wcast-align -Wcast-qual -Wchar-subscripts -Winline \

-Wmissing-prototypes -Wnested-externs -Wpointer-arith \

-Wredundant-decls -Wshadow -Wstrict-prototypes -Wwrite-strings

SRC = main.c list.c list.h stack.c stack.h circular.c circular.h double.c double.h queue.c queue.h tree.c tree.h avl.c avl.h

OBJ = main.o list.o stack.o circular.o double.o queue.o tree.o avl.o

all: $(OBJ)

$(CC) $(CFLAGS) $(OBJ) -o main

clean:

$(RM) $(OBJ) main

list.o: list.c list.h

$(CC) $(CFLAGS) -c list.c

stack.o: stack.c stack.h

$(CC) $(CFLAGS) -c stack.c

circular.o: circular.c circular.h

$(CC) $(CFLAGS) -c circular.c

double.o: double.c double.h

$(CC) $(CFLAGS) -c double.c

queue.o: queue.c queue.h

$(CC) $(CFLAGS) -c queue.c

tree.o: tree.c tree.h

$(CC) $(CFLAGS) -c tree.c

avl.o: avl.c avl.h

$(CC) $(CFLAGS) -c avl.c

main.o: $(SRC)

$(CC) $(CFLAGS) -c main.c

Obviamente para éste último ejemplo deberemos tener el código organizado tal que así:

  • En las cabeceras (.h) deberemos incluir todas las macros, definición de tipos y prototipos de funciones.
  • En los fuentes que se refieran a parte de la librería creada (todos los .c excepto main.c) debemos incluir los includes correspondientes necesarios de la libc, así como el include específico donde se implementen las funciones a las que hacíamos referencia en los .h, es decir incluir list.h en list.c, stack.h en stack.c, etc. En dichos fuentes también debemos incluir la implementación de cada función declarada por su correspondiente .h (implementar los prototipos de funciones que veíamos en list.h, en list.c, declarar los prototipos de funciones que veíamos en stack.h, en stack.c, etc).
  • En el fuente principal o que use dicha librería (compuesta por cabeceras o .h) debemos incluir cada .h (tanto de la libc que necesitemos entre <> como los de nuestra librería propia entre «» para cada .h). Acto seguido podremos usar aquí cualquier función declarada en nuestros .h e implementada en nuestros .c.

Sabiendo el ABC de Makefiles y como trabajar con múltiples ficheros .c y .h propios y/o ajenos a nuestro proyecto, ya podemos proceder a continuar con la herramienta GNU/Make, para interpretar makefiles y así poder construir el build mediante el comando make. La herramienta Automake, que además soporta ETAGS y por lo tanto nos permitirá crear dicho fichero de símbolos al realizar el make automático, y Autoconf, herramienta y dependencia necesaria para poder trabajar con Automake. Además de ello podemos utilizar un bootstrap para generar el Makefile.am y así tener todo el proceso automatizado desde el principio. Es decir que todo este entramado quedaría algo así (donde -> implica que genera, crea y/o procesa):

(./bootstrap) -genera-> ./configure

Makefile.am -genera-> Makefile.in (mediante automake)

Makefile.in -genera-> Makefile (mediante ./configure)

En el caso de querer crear un tarball para distribuir el paquete, se aconseja inlcuir el configure, para evitar obligar a instalar dependencias como automake y autoconf en los ordenadores donde se distribuya, sólo requerirá GNU/make.

El bootstrap (extraído del proyecto GNU PDF) debe tener un formato tal que así:

#!/bin/sh
# $Id: bootstrap,v 1.6 2007/11/08 02:19:09 jemarch Exp $
# Created 2003-08-29, Karl Berry.  Public domain.

if test «x$1» = x-n; then
chicken=true
echo «Ok, playing chicken; not actually running any commands.»
else
chicken=
fi

echo «Bootstrapping the GNU PDF Library with:»

# This overwrites lots of files with older versions.
# I keep the newest versions of files common between distributions up to
# date in CVS (see util/srclist.txt), because it’s not trivial for every
# developer to do this.
#cmd=»autoreconf –verbose –force –install –include=m4″

: ${AUTORECONF=autoreconf}
: ${ACLOCAL=aclocal}
: ${LIBTOOLIZE=libtoolize}
: ${AUTOHEADER=autoheader}
: ${AUTOMAKE=automake}
: ${AUTOCONF=autoconf}

# So instead:
cmd=»$AUTORECONF -i»
echo »  $cmd»
$chicken eval $cmd || exit 1

echo
echo «Now run configure with your desired options, for instance:»
echo »  ./configure CFLAGS=-g»
echo

Modificándolo y adaptándolo a las necesidades de cada uno. En caso de no tener las herramientas GNU/make, automake y/o autoconf instaladas pueden descargarse e instalarse de la siguiente manera:

Para descargar la última versión de GNU/make (manual):

cvs -z3 -d:ext:anonymous@cvs.savannah.gnu.org:/sources/make co make

Para descargar la última versión de Autoconf (manual):

cvs -d :pserver:anonymous@pserver.git.sv.gnu.org:/autoconf.git co -d autoconf HEAD

Para descargar la última versión de Automake (manual):

cvs -d :pserver:anonymous@pserver.git.sv.gnu.org:/automake.git checkout -d automake HEAD

Los paquetes pueden ser actualizados mediante cvs update para obtener la última versión.

Como Automake soporta y crea los ETAGS automáticamente, podemos aprovecharnos de esto en nuestro entorno emacs. Tenemos las siguientes funciones referentes a ETAGS:

M-. : ‘find-tag‘; busca un símbolo dado.
M-* : ‘pop-tag-mark‘; devuelve el cursor al punto de comienzo de búsqueda de símbolos.
(sin keystroke asociada) : ‘tags-search‘; busca un símbolo.
(sin keystroke asociada) : ‘tags-query-replace‘; reemplaza un símbolo.
(sin keystroke asociada) : ‘tags-apropos‘; busca un símbolo o parte de él.
(sin keystroke asociada) : ‘list-tags‘; lista los símbolos de un fichero.
M-, ó M-0 M-. : ‘tags-loop-continue‘; se desplaza al siguiente símbolo buscado.
C-u – M-. ; se desplaza al anterior símbolo buscado.
C-u M-. ; se desplaza al siguiente símbolo buscado.
C-x 4 . : ‘find-tag-other-window’; busca un símbolo dado y crea una nueva ventana para ello.
C-u 5 . : ‘find-tag-other-frame’; busca un símbolo dado y crea un nuevo frame para ello.
M-/ ; autocompleta mediante dabbrev (teniendo en cuenta los ETAGS).
M-/ M-/ (o más repeticiones); autocomplea con la segunda, tercera, etc… opción.

Cuando nos referimos a un símbolo nos referimos al nombre de funciones, variables, constantes o macros.

Para más información sobre como mantener programas de un tamaño considerable, se puede leer en el manual de emacs «how to maintain large programs».