Acme

Acme est l’éditeur de texte développé pour le système d’exploitation Plan9. Il utilise fortement la souris contrairement à des éditeurs comme vim ou emacs.

Et en tant que non-codeur et simple bidouilleur l’aspect modale de vim et le tout-sur-tout d’emacs m’ont bien sûr attiré pendant un moment avant que je ne veuille simplement avoir des outils simples, sans superflux.

Ce qu’il y a d’intéressant c’est la façon dont il intéragit avec le système. Ici tout est du texte et ainsi il est possible de le travailler avec les divers outils que l’on retrouve dans tout système unix(-like).

Utilisant principalement l’éditeur pour écrire sur ce blog je voulais pouvoir utiliser mes outils de vérifications orthographique et grammaticales. Creusant le sujet j’ai adapté grammalecte en le filtrant avec jq et mettant en forme les résultats avec du script shell basique. En revanche en vérification orthographique j’ai des soucis, pour le moment, avec les blocs de code ou les mots en anglais qui viennent remplir ma liste d’erreurs pour rien.

Puisque tout est du texte avec plan9 et acme je fouille un peu la documentation et tombe sur rdsel qui est en fait la selection actuelle. Je peux ainsi facilement bidouiller une condition pour que l’outil me vérifie que la selection. Pratique, de plus la touche Esc permet de séletionner la dernière modification au fichier en date.

#!/bin/sh

if [[ -z $(9p read acme/$winid/rdsel) ]]
then
9p read acme/$winid/body > /tmp/acg_tmp
else
9p read acme/$winid/rdsel > /tmp/acg_tmp
9p read acme/$winid/body > /tmp/acg_rtmp
rline=$(/usr/bin/grep -n "$(/bin/cat /tmp/acg_tmp)" /tmp/acg_rtmp | cut -d':' -f1)-1
fi

python3 ~/bin/grammalecte/grammalecte-cli.py -j -cl -owe -ctx -roff apostrophe_typographique apostrophe_typographique_après_t espaces_début_ligne espaces_milieu_ligne espaces_fin_de_ligne esp_début_ligne esp_milieu_ligne esp_fin_ligne esp_mélangés2 typo_apostrophe_incorrecte typo_espace_manquant_après2 typo_guillemets_typographiques_simples_fermants typo_guillemets_typographiques_doubles_fermants typo_guillemets_typographiques_doubles_ouvrants typo_points_suspension1 typo_tiret_début_ligne typo_tiret_incise typo_tiret_incise2 nbsp_avant_double_ponctuation nbsp_avant_deux_points nbsp_après_chevrons_ouvrants nbsp_avant_chevrons_fermants1 unit_nbsp_avant_unités1 unit_nbsp_avant_unités2 unit_nbsp_avant_unités3 -f /tmp/acg_tmp > /tmp/acg_file

jq '.data.[].lGrammarErrors.[] | .nStartY' /tmp/acg_file > /tmp/acg_gl
jq '.data.[].lGrammarErrors.[] | .nStartX' /tmp/acg_file > /tmp/acg_gc
jq '.data.[].lGrammarErrors.[] | .sMessage' /tmp/acg_file > /tmp/acg_gm
jq '.data.[].lGrammarErrors.[] | .aSuggestions[]' /tmp/acg_file > /tmp/acg_gs

jq '.data.[].lSpellingErrors.[] | .nStartY' /tmp/acg_file > /tmp/acg_sl
jq '.data.[].lSpellingErrors.[] | .nStartX' /tmp/acg_file > /tmp/acg_sc
jq '.data.[].lSpellingErrors.[] | .sValue' /tmp/acg_file > /tmp/acg_sv

filename=$(basename $(9p read acme/$winid/tag | cut -d' ' -f1))
let count=0
for g in $(cat /tmp/acg_gl);
do
let count=$count+1
if [[ -z $(9p read acme/$winid/rdsel) ]]
then
echo "$filename:$g:$(sed -n $count'p' /tmp/acg_gc) - $(sed -n $count'p' /tmp/acg_gm)"
echo "==> $(sed -n $count'p' /tmp/acg_gs)"
echo ""
else
let rl=$rline+$g
echo "$filename:$rl:$(sed -n $count'p' /tmp/acg_gc) - $(sed -n $count'p' /tmp/acg_gm)"
echo "==> $(sed -n $count'p' /tmp/acg_gs)"
echo ""
fi
done

echo "---"

let count=0
for s in $(cat /tmp/acg_sl);
do
let count=$count+1
echo "$filename:$s:$(sed -n $count'p' /tmp/acg_sc) - $(sed -n $count'p' /tmp/acg_sv)"
echo ""
done

acme/10/        is the directory associated to this text acme/10/addr  is a file with an address position for text insertions
acme/10/body  is a file with the contents of the editing window (can't overwrite)
acme/10/ctl  is a "file" (socket-like) that allows you to send commands to the window
acme/10/data  is a file with the data of the editing window (can overwrite)
acme/10/errors  is a file with data spat by commands executed by this window
acme/10/event  is a "file" (socket-like) where you can read/write the editing session
acme/10/tag  is a file holding the contents of the tag (the menu above)
acme/10/xdata  is a file with the data (addr bound) of the editing window
acme/10/rdsel selected text
#9indent
echo "WinId is: " $winid
echo -n "1,$" | 9p write acme/$winid/addr
echo "Selected whole contents for overwriting with 'write'"
9p read acme/$winid/body | indent -st | 9p write acme/$winid/data

echo "WinId is: " $winid
format=$(9p read acme/$winid/tag)
echo "Tag is " $format
echo "Format in tag"
case $format in
    \*"latex"\* )
        echo "latex ouput selected"
        format="latex" ;;
    \*"groff-mm"\* )
        echo "groff-mm output selected"
        format="groff-mm" ;;
    \*"odf"\* )
        echo "odf ouput selected"
        format="odf" ;;
    \*"html"\* )
        echo "html output selected"
        format="html" ;;
    \* )
     echo "Unrecognized format, defaulting to html"
     format="html" ;;
esac
echo -n "1,$" | 9p write acme/$winid/addr
echo "Selected whole contents for overwriting with 'write'"
9p read acme/$winid/body | peg-markdown --to=$format | 9p write acme/new/body
echo "Wrote the html-markdowned version to a new buffer"
last=$(9p ls acme | sort -g | tail -n 1)
echo "Get last created buffer"
echo -n "clean" | 9p write acme/$last/ctl
echo -n "0,0" | 9p write acme/$last/addr
echo -n "dot=addr" | 9p write acme/$last/ctl
echo -n "show" | 9p write acme/$last/ctl
echo "Moved to beginning"

Plan9 Port comes with two very useful scripts: B and E. B opens content in a new window inside your Acme session. E does the same, but returns to the calling process only after you’re done editing. This is perfect for git.

You can set EDITOR=E in your shell config file of choice, or you can use it on an as-needed basis, e.g. EDITOR=E git rebase -i HEAD~5

Liens entrants: home |