domingo 19 de febrero de 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

miércoles 1 de febrero de 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:

lunes 21 de noviembre de 2011

Como Postear Codigo en Blogger

Esto puede servir para postear código en Blogger o en cualquier otro asumo.
En el post anterior me puse a hacer la típica búsqueda de como hacer para postear código en blogger, porque cada vez que tuve que hacerlo lo hice de una u otra forma, pero nunca me dejo conforme y además siempre me olvidaba como era...
Y esta vez estuve un rato buscando, hasta que dije: " Y POR QUÉ NO COPIO A MI AMIGO PASTE.UBUNTU ?

Entonces, cree mi paste, y después me puse a ver el código que generaba a ver que onda, copié la parte del html que me interesaba y me agregue el css en mi documento (con algunas modificaciones minimas en mi caso para que se adapte mejor a mi configuracion de Blogger, pero también se podría hacer simplemente como a continuación).

Entonces, para postear código en Blogger, hay que entrar a la edición en HTML, y solo pegar este código:


<link rel="stylesheet" type="text/css" charset="utf-8" media="screen" 
href="http://paste.ubuntu.com/static/pastebin.css">

<div class="paste">
<table class="pastetable"><tbody>
<tr><td class="code"><div class="paste">

<pre>#INSERT CODE HERE!
</pre>
</div>
</td></tr>
</tbody></table>
</div>


Y listo!!
Reemplacen obviamente el "#INSERT CODE HERE!" por su código y ya esta!!

Descargar Archivos random de Wikipedia

Este es un script que acabo de hacer porque tenemos que conseguir más de 5000 articulos para un trabajo de la facultad, donde tenemos que implementar un motor de busqueda sobre documentos, y para conseguir la base de documentos y con cierto formato que sea parseable que mejor que wikipedia.
Entonces para poder bajar una buena cantidad de documentos hice (seguramente podría mejorarse):



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

import os
import random
import urllib

from BeautifulSoup import BeautifulSoup


class Browser(urllib.FancyURLopener):
    version = ('Mozilla/5.0 (Windows; U; Windows NT 5.1; it; '
               'rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11')


def read_page(link):
    browser = Browser()
    page = browser.open(link)
    return page.read()


AZ = [chr(c) for c in xrange(65, 91)]
az = [chr(c) for c in xrange(97, 123)]

#http://es.wikipedia.org/wiki/Wikipedia:%C3%8Dndice_alfab%C3%A9tico
combinations = [unicode(pageA + pagea) for pageA in AZ for pagea in az]
combinations += [unicode(pageA + pageA) for pageA in AZ for pagea in AZ]

path_save = '/home/gato/Desktop/wiki'
base_url = 'http://es.wikipedia.org/wiki/Especial:Todas'
wiki_url = 'http://es.wikipedia.org'

for page in combinations:
    print 'COMBINATION:', page
    url = os.path.join(base_url, page)
    soup = soup = BeautifulSoup(read_page(url))
    links = soup.findAll('a', {"class": "mw-redirect"})
    length = len(links) - 1
    indexes = [random.randint(0, length) for i in xrange(8)]
    indexes = list(set(indexes))
    for index in indexes:
        filename = os.path.basename(links[index]['href']) + '.html'
        wiki_page = wiki_url + links[index]['href']
        print wiki_page
        content = read_page(wiki_page)
        with open(os.path.join(path_save, filename), 'w') as f:
            f.write(content)
        print 'Saved:', filename

martes 18 de octubre de 2011

Algunas cosas que podrias no saber de Unity

Hace unos días, junto con el release, me pase a Ubuntu 11.10, y a diferencia de Ubuntu 11.04 no tenemos la opción de usar el escritorio clásico de Gnome2, lo que si se puede hacer llegado el caso es usar gnome shell (pero en mi caso al menos funcionaba muy lento gnome shell... tengo entendido que en otros casos funciona muy bien).

Unity es en parte una reinvención del escritorio, un nuevo "paradigma" por decir de una forma, y a primera vista a quienes venimos acostumbrados con gnome2 nos puede parecer que nos faltan cosas, o sentir cierta resistencia al cambio.
Por ese motivo quise hacer un post, porque ahora un par de días después de haberlo empezado a usar ya la verdad que me siento cómodo y varias de esas cosas que me resultaba que me faltaban, pude encontrar que simplemente estaban presentes de otra forma.


Primero que nada nos vamos a encontrar que la tradicional barra en la parte inferior de la pantalla donde veiamos las aplicaciones abiertas (para quienes teniamos esa barra) ya no esta más, y ahora tenemos una barra de launchers al costado izquierdo del escritorio, que a primera instancia pareceria ser como una especie de Dock, pero tiene varios detalles a tener en cuenta.

Primero que nada, todas los launchers que figuran se pueden quitar, o agregar nuevos simplemente presionando el boton derecho sobre los existentes o las aplicaciones que están corriendo y elegir la opción "Keep in launcher" (en inglés).

Que otra información nos brinda este launcher??




Podemos ver que sobre aquellas aplicaciones que se encuentren abiertas, vamos a tener una especie de flechita ">" sobre el lado izquierdo del icono.
Ahora, si nos fijamos bien vamos a ver que de los iconos que se muestran arriba, hay 2 (Home Folder, Ubuntu Software Center) que tiene la flechita ">" como si estuviera rellena, eso es porque esas aplicaciones se encuentran abiertas sobre el escritorio en el que me encuentro en ese momento:


Y también podemos observar que sobre el icono de "Home Folder" tenemos a su vez una flecha "<" sobre el lateral derecho del icono, esto nos indica que esa es la ventana que tiene actualmente el foco.

Otra cosa acerca del launcher, es que si mantenemos presionada la tecla Super unos segundos (esa que tiene un logo que se parece a otro sistema operativo... no se bien cual :P)
Nos aparece un numero/letra sobre cada icono con el que podemos acceder de forma directa apretando sobre el:

Si nos fijamos sobre el icono de Chromium (2) hay 2 flechitas, eso es porque hay 2 instancias de Chromium abiertas, en este caso si mantenemos apretado Super+2 (2: en este caso para acceder a Chromium), nos va a llevar a la última instancia que obtuvo el foco, pero si no soltamos Super y volvemos a presionar 2, nos muestra todas las instancias de esa aplicación abierta y con las flechas del teclado o el mouse podemos elegir a cual darle el foco:



Después tenemos algunas funciones tradicionales como ver todos los escritorios con Super+S:


Y ver todas las aplicaciones abiertas con Super+W:



Ahora más detalles nuevos:
Unity nos permite acceder de forma fácil y rápida a las aplicaciones todo a través del teclado, si bien tenemos los launchers que son de fácil acceso para el mouse, podemos buscar cualquier aplicación (se encuentre o no en el launcher) presionando una Super+A:


Quizás algunos extrañen el menu de Aplicaciones (como me pasaba a mi), pero esto esta pensado para que el usuario en realidad escriba a que quiere acceder de manera intuitiva y las aplicaciones se vayan filtrando en base a lo que escribe. Si se presta atención, se puede ver que no solo muestra las aplicaciones instaladas, sino que también las aplicaciones que estarían relacionadas a nuestra busqueda y por ahí nos interesaría instalar.
Por ejemplo, si yo quisiera buscar para jugar al Ajedrez, pero actualmente no tengo ningun juego de Ajedrez instalado, el resultado que me mostraría sería el siguiente:


Pero si por el contrario queremos un acceso más general, ya sea a aplicaciones, carpetas, archivos, etc.
Podemos simplemente presionar "Super" y nos aparece otra opción de búsqueda, la cual filtra sobre todas las categorías antes mencionadas:


Y de todas formas sino, para aquellos que estemos muy acostumbrados a otra herramienta, siempre podemos instalar el famoso "Synapse" (o derivados) para el mismo tipo de funcionalidad:


Ahora en cuanto a los famosos indicadores que muchos soliamos tener en la barra superior del escritorio (para temperatura, etc), también los tenemos presentes en Ubuntu 11.10, nomás que los podemos encontrar de otra forma.
Principalmente yo agregue 2:


- Indicador del clima (que se puede instalar directamente desde el Ubuntu Software Center): indicator-wheater
- ClassicMenu (un indicador para ver el menu tradicional), a mi me pasa que a veces estoy buscando una aplicación, pero no recuerdo ni cerca cual era su nombre, pero si en que categoría la podria encontrar, y para eso me venia de 10 el menu tradicional de Aplicaciones.


Pueden consultar más de estos indicadores acá: Ask Ubuntu

Y por último, un detalle que al principio me producía ciertas trabas, es el hecho de que Alt+Tab ahora itera sobre todas las aplicaciones abiertas sin importar en que escritorio esten, y en mi caso yo suele trabajar mucho desplazandome a un escritorio y cambiar de aplicación sobre las que tengo ahí abiertas mientras trabajo en ese escritorio. Bueno, esto podemos solucionarlo instalando CompizConfig Settings Manager:

sudo apt-get install compizconfig-settings-manager

Y luego activando el Ring-Switcher y clickeando la opción del Ring-Switcher para decirle que itere solo sobre las aplicaciones en el Escritorio actual.
A su vez, varias cosas de Unity, como el tiempo de algunos efectos, la cantidad de escritorios, etc, podemos configurarlo usando el mismo CompizConfig Settings Manager (de manera mas user-friendly, en lugar de ir a usar gconf-editor... que también tendriamos que instalarlo).



Y eso es todo por ahora!


------------------------------------------------------------------------------

19 de Octubre del 2011:

Y me faltó agregar que amo la fuente UbuntuMono!!!!!

jueves 13 de octubre de 2011

Mas Mails que da gusto recibir

Otro mail que te alegra el día :P recibido a través de Github (donde probablemente estemos migrando ninja-ide dentro de poco).

Mail de: v3ss0n
Asunto: BEST Python IDE Ever!
Today is 1st day i tried and I am immidiately fall in love!
This is Bestest , not best Python IDE i ever tried!
Fast , Lightweight , Responsive thats all i am asking for and you guys make it right!
This repo is not updated right? Which one is most updated? I want to use latetest code !


Ahora a seguir trabajando en la versión 2.0 para poder liberarla con todas las features y mejoras que queremos lograr!! :D

BTW, la consola Python incluida en NINJA-IDE (si lo utilizan desde repositorio) ya posee autocompletado!

jueves 22 de septiembre de 2011

Aniversario NINJA-IDE

Hoy se cumple 1 año desde que comenzamos con el proyecto, y más felices no podríamos estar, se han logrado muchísimas cosas, y mañana además vamos a estar liberando la versión 2.0-Beta en la PyConAr, junto a un nuevo rediseño del sitio web, acorde al nuevo logo y estética que el diseñador que se sumo al equipo le dio!!

Acá dejo un vídeo que hicimos para el aniversario: