] > blog entries (Logilab.org)

blog entries

Petites astuces de vim

2008/05/27 by Arthur Lutz

J'ai découvert vim-addons (qui est apparu dans debian récement) et ce petit outil permet de faire d'etendre les fonctionnalités de vim assez facilement. Voici une utilisation parmi tant d'autres :

mode gnupg

pour installer le mode gnupg faites

vim-addons install gnupg

Ensuite vim pourra ouvrir directement des fichiers encryptés et les réncrypter lorsque vous sauvez. Donc simplement

vim mot-de-passe-envoyé-par-client.gpg

Voilà, le tour est joué.

J'avoue que je reste avec emacs pour le code, mais ce genre de petit raccourcis est bien pratique.


Petit raccourci pratique avec ion3

2008/05/27 by Arthur Lutz

Un petit raccourci pratique pour ion3, qui permet, sur la combinaison de touches de son choix, de prendre le texte actuellement sélectionné (surligné) dans sa session X11, et, en fonction de son contenu :

  • d'ouvrir un onglet Firefox avec l'url sélectionnée,
  • d'ouvrir un xpdf si c'est une URL de fichier PDF,
  • lancer OpenOffice.org si c'est un fichier OOo,
  • ouvrir le fichier dans emacs si c'est un .py, .po, etc.
  • etc.

Pour cela, il faut le script magique ci-dessous, et configurer ion pour appeler ce script sur la bonne combinaison de touches. Par ex. ajouter dans votre ~/.ion3/cfg_ion.lua les lignes

defbindings("WMPlex.toplevel", {
  bdoc("Automagically view the selected string"),
  kpress(META.."F7",
         "ioncore.exec_on(_, '/home/user/bin/view')"),
})

Ici, j'ai mappé "Meta+F7", et le script est /home/user/bin/view

#!/usr/bin/env python

from mimetypes import guess_type
import sys
from os.path import abspath
from os import system, popen

import re
RGX = re.compile

EMACS = 'emacsclient --no-wait %(uri)s'
EMACS_WITH_LINE = 'emacsclient --no-wait +%(lineno)s %(uri)s'
FIREFOX = 'firefox -remote "openURL(%(uri)s, new-tab)"'
WGET = 'cd /home/adim/tmp && wget %(uri)s & '

commands = [
    ('text/html', FIREFOX),
    ('application/xml', EMACS),
    ('text', EMACS),
    ('image', 'display %(uri)s &'),
    ('application/pdf', 'xpdf %(uri)s &'),
    ('application/postcript', 'gv %(uri)s &'),
    ('application/vnd.sun.xml', 'ooffice %(uri)s &'), # matches writer, impress, etc.
    ('application/vnd.oasis.opendocument', 'ooffice %(uri)s &'),
    ('application/msword', 'ooffice %(uri)s &'),
    ('application/vnd.ms-', 'ooffice %(uri)s &'),
    ]

patterns = [
    (RGX(r'https?://.*?(zip|gz|pdf|ods|doc|odt|ppt|sxw|sxi)$'), WGET),
    (RGX(r'.*(?P<uri>https?://[^ ()]*)( .*)?'), FIREFOX),
    (RGX('.*?\.conf$'), EMACS),
    (RGX('.*?\.po$'), EMACS),
    (RGX('.*?\.xslt$'), EMACS),
    (RGX('.*?\.pot$'), EMACS),
    (RGX(r'\s*F?i?l?e? ?"?(?P<uri>.*?\.py)", line (?P<lineno>\d+)[a-zA-Z_:-]*'), EMACS_WITH_LINE),
    (RGX('.*?(readme|changelog|depends|manifest|makefile)(\.in|\.gz|\.bz2)?$', re.I), EMACS),
    # others might come here ...
    ]

def find_command(selection):
    for rgx, cmd in patterns:
        m = rgx.match(selection)
        if m:
            args = m.groupdict() or {'uri' : selection}
            return cmd, args
    mimetype, encoding = guess_type(selection)
    # XXX: encodings like zip, or gz could be handled
    if mimetype is not None:
        selection = abspath(selection)
        for registered_type, cmd in commands:
            if mimetype.startswith(registered_type):
                return cmd, {'uri' : selection}
    raise ValueError('nothing matched')

if len(sys.argv)>1:
    selected = ' '.join(sys.argv[1:])
else:
    selected = popen('xclip -o').read()

if selected:
    try:
        cmd, args = find_command(selected)
    except ValueError:
        # system('wmiijabber error viewing %s' % ' '.join(sys.argv[1:]))
        # XXX print a message in wmii status bar ?
        pass
    else:
        #print "yooo =>", repr(cmd), repr(args)
        system(cmd % args)

Pour que cela fonctionne, il ne faut pas oublier d'installer xclip (sous debian, apt-get install xclip).

-- écrit par David Douard sur un script de Adrien diMascio


Fusionner dans le bon sens avec mercurial

2008/11/27 by Nicolas Chauvat
http://www.selenic.com/hg-logo/logo-droplets-50.png

Contrairement à ce que l'on pourrait penser a priori, il y a un bon et un mauvais sens pour fusionner deux têtes dans en entrepôt mercurial.

Prenons un exemple et admettons que l'on parte d'une révision 123. Alfred, Barnabé et Coruscant font des changements qui produisent l'arbre suivant:

123 -> 124 -> 125 ---> 126 -> 129 --> 130
                   \-> 127 -> 128 /

Si dans le même temps, Zoé part de la révision 123 et produit l'arbre:

123 -> 131

quand Zoé va vouloir faire son hg push sur l'entrepôt partagé, elle va avoir le message "ça crée des têtes, est-ce que vous êtes sûr de vouloir faire ce push". Zoé va se dire qu'il vaut mieux commencer par un 'pull' et un 'merge', mais c'est là qu'il faut se méfier.

En effet, si Zoé est sur la révision 131 et qu'elle fusionne avec 130, le changeset sera énorme car il contiendra tous les changements qui permettent de passer de 123 à 130. En revanche, si Zoé passe sur la 130 et fusionne avec la 131, elle n'aura que les changements qu'elle vient d'apporter. Dans le premier cas, le 'merge' sera difficile à comprendre, alors qu'il sera bien plus simple dans le second.

Au final, comment faire la fusion dans le "bon" sens ?

1/ hg push -> ah tient, ça crée des têtes, donc je ne le fais pas

2/ hg pull -u ou hg pull suivi de hg merge -> y'a eu un merge

3/ hg status -> beaucoup de fichiers modifiés... oulàlà, c'est bizarre je vais regarder

4/ hgview -> ah oui, sur l'autre tête y'a beaucoup plus de changements, donc je vais plutôt faire le 'merge' dans l'autre sens

5/ hg up -C ab123_autre_tete -> je me retrouve sur l'autre tête

6/ hg merge cd456_ma_tete -> un joli 'merge'

7/ hg status -> seulement quelques fichiers modifés, voilà qui est mieux

8/ hg ci -m merge -> youpi, je valide cette fusion

9/ hg push -> tagada, je partage avec mes voisins

Moralité: faites des hg status et des hgview aussi souvent que nécessaire pour préparer vos commits et parvenir à un historique facile à comprendre.

Remarque: on peut aussi remplacer les étapes 5, 6 et 7 par hg diff -r ab123_autre_tete -r cd456_ma_tete pour afficher le diff de ma_tete par rapport à autre_tete, car l'opération de fusion doit être symétrique et donner le même résultat qu'on la lance depuis l'une ou l'autre tête, même si l'affichage par défaut de hg status et hg diff dépend de la tête qui constitue le premier parent (l'étape 5 ayant justement pour effet de changer ce premier parent).