Advertisement
Guest User

Completer

a guest
Jul 27th, 2010
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.33 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3.  
  4. import gtk
  5. import os
  6.  
  7. COMMANDS = {
  8.     ':cp'   : True,
  9.     ':mcp'  : True,
  10.     ':mv'   : True,
  11.     ':mmv'  : True,
  12.     ':rm'   : False,
  13.     ':mrm'  : False,
  14.     ':q'    : False,
  15.     'pyar'  : False,
  16.     'python': False,
  17. }
  18.  
  19. class Main:
  20.  
  21.     def __init__(self):
  22.         self.entry = gtk.Entry()
  23.  
  24.         self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
  25.         self.window.connect('key-press-event', self.on_key_press)
  26.         self.window.connect('delete-event', gtk.main_quit)
  27.         self.window.add(self.entry)
  28.         self.window.show_all()
  29.  
  30.         self.completer = Completer(tabkey=gtk.keysyms.Tab,
  31.                             commands=COMMANDS, dotfiles=False)
  32.  
  33.     def on_key_press(self, widget, event):
  34.         # Unica forma que encontre para posicionar
  35.         # el cursor al final del texto
  36.         self.entry.select_region(
  37.             len(self.entry.get_text()),
  38.             len(self.entry.get_text())+1)
  39.  
  40.         # Esc: salir
  41.         if event.keyval == gtk.keysyms.Escape:
  42.             gtk.main_quit()
  43.         # Tab: autocompletar
  44.         elif event.keyval == gtk.keysyms.Tab:
  45.             self.entry.set_text(
  46.                 self.completer.complete(self.entry.get_text()))
  47.  
  48.         # Completer necesita saber si la ultima tecla fue Tab o no.
  49.         self.completer.set_lastkey(event.keyval)
  50.  
  51.     def show(self):
  52.         gtk.main()
  53.  
  54. class Completer:
  55.     '''Clase para autocompletado de texto mediante Tab,
  56.    similar al modo menu-complete usado por GNU readline.'''
  57.  
  58.     def __init__(self, tabkey, commands, dotfiles=True):
  59.         '''tabkey es un entero con el valor de la tecla Tab (gtk.keysyms.Tab).
  60.  
  61.        commands es un diccionario con el listado de palabras/comandos,
  62.        indicando en cada caso si se admite o no el parametro path:
  63.  
  64.            commands = {
  65.                ':cp': True,        <- comando + path
  66.                ':rm': False,       <- comando sin path
  67.            }
  68.  
  69.        dotfiles hace que se listen o no los archivos ocultos cuando se
  70.        ejecuta /algun_dir/<Tab>.
  71.        En cualquier caso /algun_dir/.<Tab> funciona como es de esperarse.
  72.  
  73.        '''
  74.         self.tabkey = tabkey
  75.         self.commands = commands
  76.         self.dotfiles = dotfiles
  77.         self.lastkey = None
  78.         self.basedir = None
  79.         self.matches = []
  80.         self.index = -1
  81.  
  82.     def complete(self, text):
  83.         '''complete(text) -> string'''
  84.         if not text.strip():
  85.             return ''
  86.  
  87.         tokens = text.strip().split(' ', 1)
  88.  
  89.         # Command
  90.         if len(tokens) == 1:
  91.             if self.lastkey != self.tabkey:
  92.                 self.complete_word(tokens[0])
  93.             tokens[0] = self.get_next_completion()
  94.         # Path
  95.         elif self.commands[tokens[0]]:
  96.             if self.lastkey != self.tabkey or len(self.matches) == 2:
  97.                 self.complete_path(tokens[1])
  98.             tokens[1] = os.path.join(self.basedir, self.get_next_completion())
  99.  
  100.         return ' '.join(tokens)
  101.  
  102.     def get_next_completion(self):
  103.         '''get_next_completion() -> string'''
  104.         if len(self.matches):
  105.             if self.index == len(self.matches) - 1:
  106.                 self.index = 0
  107.             else:
  108.                 self.index += 1
  109.             return self.matches[self.index]
  110.  
  111.     def complete_word(self, token):
  112.         '''complete_word(token) -> list'''
  113.         self.matches = [token]
  114.         self.index = 0
  115.         for cmd in self.commands.keys():
  116.             if cmd[0:len(token)] == token:
  117.                 self.matches.append(cmd)
  118.         if len(self.matches) > 2:
  119.             self.matches = sorted(self.matches)
  120.         return self.matches
  121.  
  122.     def complete_path(self, token):
  123.         '''complete_path(token) -> list'''
  124.         if token[0:2] == '~/':
  125.             token = os.path.expanduser(token)
  126.         elif token[0] != '/':
  127.             token = os.path.realpath(token)
  128.         self.basedir = token[0:token.rfind('/')+1]
  129.         q = token[len(self.basedir):]
  130.         self.matches = [q]
  131.         self.index = 0
  132.         if os.path.isdir(self.basedir):
  133.             try:
  134.                 listdir = os.listdir(self.basedir)
  135.             except (OSError,):
  136.                 pass
  137.             else:
  138.                 for entry in listdir:
  139.                     if entry[0:len(q)] == q and not (q == '' and
  140.                             entry[0] == '.' and not self.dotfiles):
  141.                         if os.path.isdir(
  142.                                 os.path.join(self.basedir, entry)):
  143.                             entry += '/'
  144.                         self.matches.append(entry)
  145.                 if len(self.matches) > 2:
  146.                     self.matches = sorted(self.matches)
  147.         return self.matches
  148.  
  149.     def set_lastkey(self, lastkey):
  150.         '''Completer necesita saber si la ultima tecla fue Tab o no,
  151.        por eso el metodo que captura el evento key-press-event
  152.        debe pasarle al final el valor de la tecla pulsada:
  153.  
  154.            def on_key_press(self, widget, event):
  155.                if event.keyval == gtk.keysyms.Tab:
  156.                    self.entry.set_text(
  157.                        self.completer.complete(self.entry.get_text()))
  158.  
  159.                self.completer.set_lastkey(event.keyval)
  160.  
  161.        '''
  162.         self.lastkey = lastkey
  163.  
  164. if __name__ == '__main__':
  165.     main = Main()
  166.     main.show()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement