nutools/lib/nulib/python/nulib/editor.py

131 lines
3.8 KiB
Python

# -*- coding: utf-8 -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
"""Des fonctions pour éditer des fichiers.
"""
__all__ = ('edit_file', 'edit_template')
import os, sys
from .base import isseq
from .env import get_editor, get_editor_options, get_editor_setrow
from .uio import EditorIO, _s
from .lines import Lines
from .args import split_args
from .tmpfiles import mktemp
from .paths import in_PATH
from .procs import spawn
# options, setrow, setcol, colplus
EDITOR_CAPS = {'emacs': ('', '+', ':', 1),
'xemacs': ('', '+', ':', 1),
'gvim': ('-f', '+', '', 0),
'vim': ('-f', '+', '', 0),
'vi': ('', '+', '', 0),
}
def get_default_editors():
"""Retourner une liste d'éditeurs par défaut pour la plateforme en cours
"""
if sys.platform.startswith('linux'):
return ('emacs', 'xemacs', 'gvim', 'vim', 'vi')
else:
return ('xemacs', 'emacs', 'gvim', 'vim', 'vi')
def get_editor_caps():
"""Obtenir les caractéristiques de l'éditeur configuré.
@return: (editor, options, setrow, setcol, colplus)
"""
options = None
setrow = None
setcol = ''
colplus = 0
editor = get_editor()
if editor is None:
for editor in get_default_editors():
if in_PATH(editor): break
else:
raise OSError("Unable to find a default editor. Please set UTOOLS_EDITOR.")
if EDITOR_CAPS.has_key(editor):
options, setrow, setcol, colplus = EDITOR_CAPS[editor]
if options is None and setrow is None:
options = split_args(get_editor_options())
setrow = get_editor_setrow()
if options is None and setrow is None and EDITOR_CAPS.has_key(editor):
options, setrow, setcol, colplus = EDITOR_CAPS[editor]
return editor, options, setrow or '', setcol or '', int(colplus)
def edit_file(file, row=None, col=None):
"""Lancer un éditeur pour éditer le fichier file.
@return: le status d'exécution de l'éditeur.
"""
editor, options, setrow, setcol, colplus = get_editor_caps()
cmd = [editor]
if options:
if isseq(options): cmd.extend(options)
else: cmd.append(options)
if setrow and row is not None:
row = int(row)
opt = '%s%i' % (setrow, row)
if setcol and col is not None:
col = int(col)
opt += '%s%i' % (setcol, col + colplus)
cmd.append(opt)
cmd.append(file)
return spawn(*cmd)
def edit_template(template=None, strip_prefix=None, row=None, col=None, lines=None):
"""Obtenir une valeur éditée dans un éditeur.
Un fichier temporaire vide est initialisé avec le contenu de template,
puis le fichier est proposé à l'édition.
A la sortie, toutes les lignes commençant par strip_prefix sont supprimée,
et une instance de Lines avec les lignes du fichier est retourné.
@return: lines
@rtype: Lines
"""
if lines is None:
uio = EditorIO()
lines = Lines(uio=uio)
else:
uio = lines.uio
if uio is None:
uio = EditorIO()
lines.uio = uio
## préparer le fichier
tmpf, tmpfile = mktemp('utools')
try:
if template is not None:
template = uio.s(template)
try: tmpf.write(template)
finally: tmpf.close()
else:
tmpf.close()
## l'éditer
edit_file(tmpfile, row, col)
## traiter le résultat
lines.readlines(tmpfile)
# enlever les préfixes
if strip_prefix is not None:
lines.filter(lambda l: not l.startswith(strip_prefix))
# supprimer les lignes vides au début et à la fin
while lines and not lines[0].strip(): del lines[0]
while lines and not lines[-1].strip(): del lines[-1]
return lines
finally:
os.remove(tmpfile)