sluggo: Un shell intelligent

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Salut,

Ça fait un petit bout de temps que j'avais envie de créer un shell, car powerline et fish ne me suffisaient pas. L'idée m'est venue parce que ça m'ennuyait de devoir taper git avant mes commandes, mais je me suis rendu compte qu'il y a plein d'applications (interpréteur SQL, console FTP, etc…). Le principe est simple: mon shell est organisé de sorte à ce qu'on puisse utiliser des sous-shell (que j'appelle REPL, pour Read-Eval-Print Loop), qui nous permettent de ne pas taper le préfixe de la commande. L'avantage aussi est que l'environnement d'un REPL est conservé même si on visite un autre.

C'est assez difficile d'expliquer comme ça, donc voici une petite démo asciinema:

asciicast

(je sais je galère un max, je la referai un jour)

Le truc cool aussi c'est que c'est extensible, il suffit de mettre votre fichier .py dans le dossier ~/.sluggo/plugins pour que mon application le charge automatiquement.

Voilà, c'est une petite feature qui peut sembler pas super utile, mais c'est sympa à l'utilisation.

Liens:

Anciennement AlphaZeta

+15 -0

Cette réponse a aidé l'auteur du sujet

Salut !

J'adore le concept, c'est pratique et pour mon terminal avec git quand je bosse, ça me serait super utile. C'est vraiment une très bonne idée.
Par contre, je ne suis pas prêt à changer de shell. J'avais vu passer sur Reddit un utilitaire (pas un shell) qui se comportait de manière similaire, l'extensibilité en moins et sans certaines de tes fonctionnalités. De mémoire, il suffisait de taper qqch git pour que ça fonctionne plus ou moins sur le même principe. Je vais essayer de le retrouver, si j'y arrive je te le montrerai.

+3 -0
Auteur du sujet

Oui je pense avoir vu le même projet sur GitHub, ça ne serait pas ça par hasard ? Je m'en suis inspiré pour écrire mon plug-in cmd, qui fait exactement la même chose (à savoir juste ajouter la commande principale à l'entrée utilisateur avant d'exécuter), c'est d'ailleurs ce qui se passe quand je tape !go cmd pip3.4 dans la démo :)

Sinon merci beaucoup, mais du coup qu'est-ce qui t'empêcherait d'en faire ton shell par défaut ?

Je sais déjà qu'il me manque une coloration et une autocomplétion décente, par rapport à fish, je vais voir comment je peu faire :)

PS: Si quelqu'un connaît une lib pour faire ça, je suis preneur (je pourrais utiliser curses mais ça serait un peu fastidieux, je recherche un truc plus haut niveau).

Édité par felko

Anciennement AlphaZeta

+1 -0

Cette réponse a aidé l'auteur du sujet

C'est un projet super intéressant, bravo !

Le truc cool aussi c'est que c'est extensible, il suffit de mettre votre fichier .py dans le dossier ~/.sluggo/plugins pour que mon application le charge automatiquement.

Un truc bien serait que ton shell regarde dans le man de la commande en question (comme le fait fish pour l'auto-completion).

Et je trouverais pratique que ton shell affiche le nom du REPL courant.

Sinon pour tes démos, tu as ttygif. ;-)

Édité par Roipoussiere

"Il faut commencer par du rêve. Et les choses deviennent réelles à un moment ou un autre." - Kenny Todd, directeur des opérations pour l’ISS.

+0 -0

Cette réponse a aidé l'auteur du sujet

Oh merci, c'est ça, j'arrivais pas à le retrouver. Voici quelques remarques sur sluggo:

  • Il n'y a rien qui indique comment lancer sluggo dans le README, et il faudrait ajouter requirements.txt avec les dépendances dedans. J'ai essayé de lancer python sluggo/__main.py__, et il n'arrivait pas à trouver le module sluggo. Je n'ai donc pas pu tester, parce que je ne sais pas comment corriger ça.
  • Pour sortir d'une "session" shell, la manière idiomatique UNIX de faire est d'envoyer le caractère EOF (Ctrl+D). Je remplacerais donc !quit par EOF.
  • De même, !cls est remplaçable par Ctrl+L
  • Pitié, pas encore un soft qui crée encore un dossier dans mon home. Il faudrait respecter le standard XDG Basedir, pour ça tu peux utiliser PyXDG.
  • Je ne comprends pas bien l'intérêt de pouvoir imbriquer des REPL, personnellement j'ouvre un nouveau terminal ou je fais Ctrl+Z pour faire passer la tâche courante en arrière-plan, puis une fois que j'ai fini je la fais repasser au premier plan avec fg. D'ailleurs, ça marche sous sluggo le contrôle des tâches comme ça ? Est-ce que tu pourrais expliquer ta logique derrière l'imbrication des REPL ?
  • En fait, au vu du code, sluggo est une sorte de shell hyper basique, qui ne permet qu'un tout petit sous-ensemble de ce que permet sh. On peut juste lancer des exécutables ou des REPLs, donc pas de scripting, pas d'opérateurs du genre &&, pas de redirections, pas de job control, pas de gestion de l'historique, pas de globbing, pas de complétion (en tout cas pas partout et clairement pas de manière aussi puissante que zsh) etc etc. Je ne peux donc pas l'utiliser parce que tout ça, c'est des fonctionnalités indispensables d'un shell.

Comme j'ai été bien critique dans ce message, je ne voudrais pas que tu aies l'impression que je cherche à basher ton projet (jeu de mot non intentionnel, j'vous le jure monsieur le juge !). Il y a de bonnes idées (comme le système de plugins). Je cherche juste à te donner des pistes pour que tu l'améliores et que tu t'amuses ce faisant. Même si personnellement je ne l'utiliserai certainement pas, c'est ton projet et tu as de quoi bricoler des choses sympa avec, et c'est ça qui compte. Bonne continuation ! :)

P.S: l'idée générale c'est que je ne vois pas pourquoi en faire un shell au lieu d'un utilitaire comme repl, mais à toi de trouver des idées pour apporter une plus-value :)

Édité par anonyme

+4 -0
Auteur du sujet

SO a réponse à tout (pour l'auto completion). Et il me semble que colorama est la référence pour les couleurs en CLI. Il supporte les 3 platformes majeurs.

Si tu cherches une lib, fais un tour sur la liste awesome-* du langage.

tleb

Oui j'utilise déjà colorama, mais je sais pas comment colorer en direct l'entrée utilisateur.

Sinon merci pour le awesome-*, j'y pense pas assez souvent :P

Je ne comprends pas bien comment fonctionne ton système de plugins et que fait ce fichier .py, c'est un fichier de config qui répertorie la liste des commandes de git, pip, etc ?

Roipoussiere

En fait il y a deux choses:

  • Le fichier de configuration ~/.sluggorc, qui est juste une liste de commandes sluggo à exécuter au démarrage de sluggo.
  • Le dossier ~/.sluggo/plugins qui répertorie les plug-ins, chargés automatiquement au démarrage du shell. Si tu veux un exemple de plug-in, tu peux regarder dans le dossier plugins du dépôt GitHub (je les ai mis là mais il faut bien les mettre dans ~/.sluggo/plugins pour qu'ils soient chargés).

Quant aux remarques de Grimur:

D'ailleurs, ça marche sous sluggo le contrôle des tâches comme ça ? Est-ce que tu pourrais expliquer ta logique derrière l'imbrication des REPL ?

Pour l'instant il n'y a pas de tâche en arrière plan, mais je pense l'implémenter au plus vite. Pour l'instant les REPLs sont pas vraiment imbriqués, ils sont tous au même niveau (ils sont stockés dans une liste pour faire simple).

De même, !cls est remplaçable par Ctrl+L

Pas sous Windows :(

J'ai pas encore testé sur Windows mais normalement c'est portable. Soit je continue maintenir la portabilité Windows, soit je me concentre sur Unix. Je pense que la seconde option est plus raisonnable.

Il n'y a rien qui indique comment lancer sluggo dans le README, et il faudrait ajouter requirements.txt avec les dépendances dedans. J'ai essayé de lancer python sluggo/__main.py__, et il n'arrivait pas à trouver le module sluggo. Je n'ai donc pas pu tester, parce que je ne sais pas comment corriger ça.

En effet il faut que je complète le README (en attendant tu peux exécuter avec python3.4 -Bm sluggo depuis le dossier racine). Pour le requirements.txt, en fait je n'utilise aucune dépendance directement dans mon code. Par contre, oui, j'utilise colorama dans mes plug-ins, mais je sais pas si je dois le considérer comme une dépendance du coup :euh: . De toute façon, avec les histoires d'autocomplétion et de coloration, j'utiliserai sûrement des librairies externes, donc merci du conseil :)

Pitié, pas encore un soft qui crée encore un dossier dans mon home. Il faudrait respecter le standard XDG Basedir, pour ça tu peux utiliser PyXDG.

Je connaissais pas du tout, merci beaucoup.

En fait, au vu du code, sluggo est une sorte de shell hyper basique, qui ne permet qu'un tout petit sous-ensemble de ce que permet sh. On peut juste lancer des exécutables ou des REPLs, donc pas de scripting, pas d'opérateurs du genre &&, pas de redirections, pas de job control, pas de gestion de l'historique, pas de globbing, pas de complétion (en tout cas pas partout et clairement pas de manière aussi puissante que zsh) etc etc. Je ne peux donc pas l'utiliser parce que tout ça, c'est des fonctionnalités indispensables d'un shell.

Je vais explorer ces pistes, merci beaucoup !

Juste, les opérateurs && et | sont utilisables depuis le REPL système, car je délègue juste l'interprétation. Mais en effet ça serait sympa d'adapter ça aux autres REPLs.

P.S: l'idée générale c'est que je ne vois pas pourquoi en faire un shell au lieu d'un utilitaire comme repl, mais à toi de trouver des idées pour apporter une plus-value :)

Parce qu'on peut implémenter aussi des REPLs pour ftp, sql, ou python. Après on pourrait créer une commande ftp pour que ça puisse marcher avec repl, mais on pourra pas utiliser plusieurs REPLs en même temps, ni exécuter une tâche en arrière plan (qui n'est pas encore possible, mais bientôt je l'espère).

Merci Grimur pour tous tes conseils :)

Édité par felko

Anciennement AlphaZeta

+0 -0
Auteur du sujet

Salut,

Je suis en train de refaire pas mal de choses.

On aura plusieurs types de REPL desquels on pourra dériver. Actuellement je travaille sur le CommandREPL, qui permet d'implémenter un parser à la argparse mais avec de l'autocomplétion. Voici ce que ça donne:

1
2
3
4
5
6
7
8
9
@Command.from_signature
def ls(dir: (FilePath | '.'), *options: ['--all'], sep: String='\t'):
    if '--all' in options:
        print('.', '..', sep=sep, end=sep)  # c'est pour l'exemple
    print(*os.listdir(dir), sep=sep)

ls.process('ls .. --all sep=", "')

# => ., .., fichier1, fichier2, ...

A terme, chaque paramètre aura un "compléteur", comme ça sluggo affichera les différentes options adaptées à chacun d'eux :)

Ça peut paraître un peu trop précis comme classe, mais sinon j'ai un peu l'impression de ne faire qu'un fin wrapper autour de prompt-toolkit.

Édité par felko

Anciennement AlphaZeta

+3 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte