Personal Website

My Web: MindEchoes.com

Sunday, February 19, 2012

Extendiendo NINJA-IDE Symbols y Code Locator

NINJA-IDE posee 2 features que pueden ser muy comodas para navegar el código, una de ellas es el "Symbols Explorer" y la otra el "Code Locator".

El "Symbols Explorer" nos permite poder visualizar a simple vista como se encuentra compuesto el archivo (clases, funciones, atributos):


Y el "Code Locator" (Ctrl+K), que personalmente es una que uso MUCHISIMO, nos permite con un par de teclas saltar a cualquier archivo, definición de clase, atributo o método en cualquiera de todos los archivos de nuestro árbol de proyectos. Al ingresar el nombre de lo que estamos buscando, dicha búsqueda ni siquiera tiene que ser la palabra exacta, sino simplemente puede ser una parte del nombre (ya sea esta parte caracteres del principio, medio, etc).
A su vez, esta feature tiene ciertos filtros que pueden aplicarse para hacer más precisa la búsqueda:


Puede suceder que tengamos en todos nuestros proyectos cosas que tengan nombres similares, o cualquier tipo de situación que haga que el filtrado por ahí nos de muchos resultados, entonces el Code Locator nos permite combinar estos pre-filtros para poder ser más especificos en nuestra búsqueda siempre yendo de lo general a lo particular, por ejemplo:
  • Se podría querer buscar una función que contenga la palabra jump, pero solo si esta contenida en la clase Editor del archivo editor.py, de esta forma podriamos escribir en el campo de búsqueda algo del estilo: "@ed<e>jump"
  •  También podriamos evitar especificar el archivo y decir que solo queremos ver los métodos de determinada clase, para lo cual podes filtrar primero por Clase (<) y luego elegimos a que clase aplicar el filtro por funciones (>):
 (filtrado por clases)
(filtrado por funciones de la clase seleccionada)

  • También existe la opción de filtrar por el contenido del archivo actual con "." y luego sobre ese resultado aplicar el resto de los filtros para ver las funciones del archivo actual, las clases, las funciones de determinada clase, etc.

PERO estas 2 features mencionadas, como NINJA-IDE es un IDE especialmente diseñado para Python solo funcionan con Python, PERO (otra vez) como NINJA-IDE puede ser fácilmente extendido para soportar nuevas funcionalidades, podemos hacer que estas mismas features sirvan para cualquier otro lenguaje con el que estemos trabajando, por ejemplo:

Supongamos que queremos usar el explorador de símbolos y el code locator para un proyecto donde estamos trabajando con Ruby y nos gustaria tener estas features para los archivos escritos en ruby. Bueno, para soportar ambas features solo tenemos que escribir un Plugin que cree un Handler para los símbolos de determinada extensión y hacer que ese handler reimplemente un método que devuelva una estructura de diccionario ya definida.

{
     'attributes':
         {name: line, name: line},
     'functions':
         {name: line, name: line},
     'classes':
         {
         name: (line, {
                     'attributes': {name: line},
                     'function': {name: line}}
             )
         }
}


Para ver un ejemplo concreto de como quedaría el Plugin, acá dejo el código (ACLARACIÓN: no programo en Ruby así que las expresiones regulares para identificar las clases y métodos obviamente pueden no ser las mejores y cubrir todos los casos, pero es un ejemplo que arme en un rato nomás para mostrar lo fácil que sería hacer esto)




# -*- coding: utf-8 *-*

import re

from ninja_ide.core import plugin
from ninja_ide.core import plugin_interfaces


EXTENSION = 'rb'


class RubySymbols(plugin.Plugin):

    def initialize(self):
        self.explorer_s = self.locator.get_service('explorer')
        # Set a project handler for NINJA-IDE Plugin
        self.explorer_s.set_symbols_handler(EXTENSION,
            RubySymbolsHandler())


class RubySymbolsHandler(plugin_interfaces.ISymbolsHandler):

    def __init__(self):
        class_ = r'^(\s)*class(\s)+(\w)+.*'
        function_ = r'^(\s)*def(\s)+((\w)+(\.)*)+(\s)*(\(.)*'
        self.patClass = re.compile(class_)
        self.patFunction = re.compile(function_)
        self.patIndent = re.compile('^\s+')

    def obtain_symbols(self, source):
        """Returns a dict with the ruby symbols for sources."""
        source = source.split('\n')
        symbols = {}
        classes = {}
        functions = {}
        last_class = ''
        clazz_indent = 0
        for nro, line in enumerate(source):
            space = self.patIndent.match(line)
            if space is not None:
                indent = len(space.group())
            else:
                indent = 0

            if self.patClass.match(line):
                clazzname = line.split()[1]
                classes[clazzname] = (nro + 1, {'functions': {}})
                last_class = clazzname
                clazz_indent = indent
            elif self.patFunction.match(line):
                funcname = line.split()[1].split('(')[0]
                if indent > clazz_indent and last_class != '':
                    class_data = classes[last_class][1]
                    class_data['functions'][funcname] = nro + 1
                else:
                    last_class = ''
                    clazz_indent = 0
                    functions[funcname] = nro + 1
        if classes:
            symbols['classes'] = classes
        if functions:
            symbols['functions'] = functions
        return symbol
Y ese es todo el código necesario para que NINJA-IDE soporte el Symbols Explorer y Code Locator para Ruby, y tengamos resultados como estos para un archivo como este:
Symbols Explorer:

Code Locator:

Todo el proyecto de este plugin se puede encontrar en: RubySymbols
Y para ver documentación de como escribir Plugins para NINJA-IDE: Plugins Tutorial

Wednesday, February 1, 2012

Instalar NINJA-IDE desde PPA

Hace mucho que no escribía en el blog y ya me estaba sintiendo muy culpable... así que quería dejar un post cortito como para volver y el fin de semana voy a postear un mini tutorial de como escribir plugins que extiendan la capacidad del explorador de simbolos y el Code Locator de NINJA-IDE para otros lenguajes.


Al asunto!
Si sos un afortunado usuario de Ubuntu, podes instalar NINJA-IDE desde PPA, con los beneficios que eso incluye: ACTUALIZACIONES!!
Si tenes NINJA-IDE instalado desde PPA, cada vez que se actualicen dichos PPAs, te van a llegar actualizaciones de NINJA-IDE junto a las actualizaciones de Ubuntu, por ende no hace falta que esperes a que hagamos releases de las distintas versiones, etc, etc.

Para instalar NINJA-IDE desde PPA los pasos son (el primer paso de agregar el ppa, hay 2 opciones de las cuales se puede elegir):

$ sudo apt-add-repository ppa:ninja-ide-developers/ninja-ide
(Este PPA genera paquetes cada ciertos tiempos con la inclusión de nuevas features o bug fixes y se considera que el código es realmente muy estable)

$ sudo apt-add-repository ppa:ninja-ide-developers/daily
(Este PPA es actualizado cada día con el código que sea introducido en el repositorio de desarrollo de NINJA-IDE, por ende tiene siempre los ultimos cambios y se pueden probar las features apenas salen... lo que implica también que pueda haber bugs, pero nunca se sube código a repositorio que imposibilite a un usuario poder seguir trabajando con NINJA-IDE)

$ sudo apt-get update
$ sudo apt-get install ninja-ide



Recibiendo actualizaciones de NINJA-IDE: