package provide stead 2.0       ;# -*-tcl-*-

# 
# Pour obtenir les lignes "##" de ce fichier, utiliser le 
# menu "admin/Show MetaComment (##...)" de stead 
# 


# Fin de liste


## stead:usage -- affiche l'aide sur la sortie standard
# 
# 
proc stead:usage {  } {
    puts "Pas d'aide pour l'instant !"
}

## stead:new -- lancement d'un nouveau document dans stead
# 
proc stead:new {args} {

    global stead
    global arga
    global argc
    
    # Mémorisation de la liste initale des arguments (pour debug..)
    set arga(args) $args
    
    # Choix du comportement par défaut pour la procédure d'analyse d'arguments
    # 
    # mode = "strict" 'vs. "normal"pour interdire les options inconnues
    Parsarg_fullSpec -setDefault_mode "strict"
    # cache = 0  pour recompiler la spec d'option à chaque appel
    # cache = 1  pour mémoriser la précompilation au premier appel
    Parsarg_fullSpec -setDefault_cache 1
    
    
    # 
    # Extraction des options dans le tableau arga (dont le premier
    # fichier passé en parametre.
    # args contient les arguments résiduels
    # 
    # 
    stead:parseArgs

    # 
    # S'il reste des arguments supplémentaires : on considère que c'est 
    # un fichier et on relance un éditeur (par exec pour l'instant) 
    # en passant les options deja connues, suivis des arguments résiduels
    # 
    # Les options connues jusque ici son passés avec les arguments
    # mais peuvent etre ecrasés par les arguments résiduels
    # 
    if {[llength $args] >= 1 } {
        
        # 
        # Construction de la commande de lancement pour l'édition
        # des fichiers supplémentaies
        # 
        set defaultOut   [ list                 \
                     -mode     ""               \
                     -ins      ""               \
                     -cdf      $arga(-cdf)      \
                     -eval     ""               \
                     -readonly $arga(-readonly) \
                     -source   $arga(-source)   \
        ]
    
        # Mémorisation de la liste des arguments propagés (debug...)
        set arga(argsOut) [concat $defaultOut $args]
        
        set cmd [concat [list exec $stead(exe)] $defaultOut $args &]
        
        eval $cmd
    }

    # Les 100000 globales à virer progressivement 
    # (elle ne sont pas toute ici) :
    # 
    stead:initGlobals
     

    # Configuration AVANT construction de l'éditeur (lecture préférences ...)
    stead:preConfig
    
    
    # La  proc "stead:makeAllTraces" sera à scinder en deux pour 
    # séparer les alias du style :
    # 
    #   stead(file) <==> F     (en fin de chargement de stead)
    # 
    # des bidouille infame du style :
    # 
    #   stead(file) <==> FILENAME (doit etre chargé ici pour l'instant !)
    #   
    stead:makeAllTraces
    
    # la construction des widgets nécessite la trace sur la variable U (UID)
    stead:buildAppli
    stead:buildMenus
    

    # Configuration APRES construction de l'éditeur 
    # (dont exécution de stead:user_post_hook...)
    stead:postConfig
    
    ####################################################################
    # on peut enfin s'occuper de l'unique fichier à éditer. 
    # On commence par exploiter les option
    # 
    if {[string length $arga(file)]} {
        set stead(file) [file:normalName $arga(file)]
    }
    set stead(mode)     $arga(-mode)
    set stead(readonly) $arga(-readonly)
    stead:log "Stead Version: $stead(version)"

    ####################################################################
    # 
    # La suite devra refondue et faire appel à une procédure stead:loadFile
    # ATTENTION : il y a de la redondance dans ce qui suite ...
    # 
    ####################################################################
    
        

    # Si le "fichier" est en fait un répertoire : on lance le browser !
    if {[file isdirectory $stead(file)]} {
        cd $stead(file)
        
        # Cette procédure est a refondre également
        stead:loadBox
        return
    }

    # SI NECESSAIRE, PREVOIR UN CATCH A L'INTERIEUR DE CES PROCEDURES
    # 
    ## stead:load $stead(text) $stead(file) -mode $stead(mode)
    stead:read $stead(file)
    xtext_markClean .main.t
      

    # 
    # gestion du mode 
    # auto-select -mode if not specified explicitly
    # 
    if {$stead(mode) == ""} {
        # stead:modeGuess retourne un mode valide (éventuellement "text")
        set stead(mode) [stead:modeGuess $stead(file)]
    }
    
    stead:modeApply $stead(mode)
    
    # si option -cdf  : on se place dans le répertoire du fichier édité
    if {$arga(-cdf)} {
        set dir [file dirname $stead(file)]
        if {[file isdirectory $dir]} {
            xtcl_catch [list cd $dir]
        }
    }
  
    # option -text = -ins : on insère le texte à la fin de l'éditeur
    # (sauf si l'éditeur est vide car ce n'est plus évident de savoir
    # s'il est souhaitable qu'il apparaisse modifié ou pas !)
    # 
    # Le texte ne doit pas etre apparaitre comme étant modifié !
    # 
    if {[.main.t compare 1.0 == end-1c]} {
        .main.t insert end $arga(-ins)
    }
    
    # On fige le texte s'il est readony 
    # 
    # TODO :
    # À refaire en utilisant un bintags spécial car il y a un probleme 
    # avec les autre bindings qui continuent à etre actif !
    # 
    if {$stead(readonly)} {
        $stead(text) configure -state disable
    }
    # option -eval = -command : on exécute la commande
    # 
    # Ceci peut serir à chercher une chaine dans le nouvel éditeur.
    # Cette commande doit donc etre exécuter apres l'affichage du texte édité
    # 
    if {[string length $arga(-eval)]} {
        # # # xtcl_catch  #0  $arga(-eval) ;# MODIF 12/11/2005 
        xtcl_catch  -level #0  $arga(-eval) 
    }
    
    # exécution de la procédure stead:postLocalHook : personnalisation 
    # de Stead au niveau d'un site.
    # 
    # On **impose** à cette procédure d'exister !
    # 
    xtcl_catch stead:postLocalHook \
            "Error in local procedure stead:postLocalHook in file\
            $stead(localfile)"
    
    
    # exécution de la procédure stead:user_post_hook : personnalisation de STEAD
    # pour un utilisateur donné.
    # modif diam 23/07/01
    # 
    # La catch est nécessaire car :
    # - cette procédure n'existe pas forcément
    # - Stead doit être robuste aux erreurs de configuration utisateur
    # 
    if {[info procs stead:user_post_hook] == "stead:user_post_hook"} {
        xtcl_catch stead:user_post_hook \
            "Error in user procedure stead:user_post_hook in file \
                $stead(userfile)"
            
    }
    
    
} ;# endproc main

## stead:parseArgs --  extraction des options et du premier fichier
# 
# Extraction des options dela liste args dans le tableau arga (y compris
# le premier fichier).
# args contiendra les arguments résiduels
# 
# 
# -cdf 1|0
#     1  : se place dans le répertoire du fichier édité
#     0  : reste dans le répertoire d'origine du fichier édité
#     nota : on peut aussi utiliser -command cdf
# 
# -mode <mode> : passe en mode <mode>
# -i "baratin" (ou -ins ou -text) : insère le texte avant le chargement
#    du fichier.
#
# -command "ra pat1 pat2; exit" : exécute cette commande
#    -e = -command
# -r -readonly : lecture seul (sauvegarde interdite sous ce nom
#       de fichier
# -s -source <filerc> : 
#     exécute le fichier <filerc> apres l'exécution du fichier 
#     standard steadrc.
#     permet de personnaliser l'édition dans un repertoire ou
#     projet particulier
# -v -verboselevel : niveau de verbosité
# 
# TODO :
# -   (à la place du nom du fichier) l'entrée est le résultat de 
#     la commande précédente
# -clean ou -dirty  : impose l'état clean ou dirty **apres**
#     remplissage du widget text      
# -rpat <pat>  recherche reguliere  
# -gpat <gpat>    
# 
# exemple :
#   stead -r -m tcl  fichier_tcl -m latex fichier_latex 
# édite le fichier fichier_tcl en mode tcl en lecture seule, et le
# fichier fichier_latex en mode latex également en lecture seule.
# 
proc stead:parseArgs {} {
    global arga
    global stead
    upvar args args
    
    
    # Valeurs par défaut des options :
    # 
    set arga(-mode)         ""
    set arga(-meta)         "AUTO"
    set arga(-control)      "AUTO"
    set arga(-eval)         ""
    set arga(-source)       ""
    set arga(-ins)          ""
    set arga(-find)         ""
    set arga(-goto)         1.0
    set arga(-cdf)          1
    set arga(-readonly)     0
    set arga(-profiler)     0
    set arga(-verboseLovel) 0
    set arga(-Tstyle)       0 ;# Trace style pour debug FOURNIR UNE VALEUR !
    set arga(file)          ""
    
    while {[llength $args]} {
    
       switch -glob -- [lindex $args 0] {
           --      {
                    set args [lreplace $args 0 0]
                    break
           }
           -m      -
           -mode   {
                    set arga(-mode) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -meta   {
                    set arg1 [string totitle [lindex $args 1]]
                    if {![regexp -- {^(Meta|Alt|Command|Control)$} $arg1 ]} {
                        # error "-meta <Meta|Alt|Command|Control>"
                        puts stderr "\nInvalide value fo - meta: $arg1"
                        puts stderr "\n     -meta Meta | Alt | Control\n"
                        exit 1
                    }
                    
                    set arga(-meta) $arg1
                    set args [lreplace $args 0 1]
                    continue
           }
           -control   {
                    set arg1 [string totitle [lindex $args 1]]
                    if {![regexp -- {^(Meta|Alt|Command|Control)$} $arg1 ]} {
                        # error "-meta <Meta|Alt|Command|Control>"
                        puts stderr "\nInvalide value for -control: $arg1"
                        puts stderr "\n    -control Meta | Alt | Control\n"
                        exit 1
                    }
                    
                    set arga(-control) $arg1
                    set args [lreplace $args 0 1]
                    continue
           }
           -Tstyle   {
                    set arga(-Tstyle) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -i       -
           -ins     -
           -text    -
           -insert  {
                    set arga(-ins) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -command  -
           -e       -
           -eval   {
                    set arga(-eval) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -g      -
           -go     -
           -see    {
                    # set arga(-goto) [lindex $args 1]
                    lappend arga(-eval) [list \n  \
                        see [lindex $args 1]] ]
                    set args [lreplace $args 0 1]
                    continue
           }
           -s       -
           -source { 
                    set arga(-source) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -r       -
           -readonly { 
                    set arga(-readonly) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -cdf    { 
                    set arga(-cdf) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -v    { 
                    set arga(-v) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    continue
           }
           -edit    { 
                    set arga(-edit) 1
                    set args [lreplace $args 0 0]
                    # exec stead [info script] &
                    stead $stead(exe)
                    exit 0
           }
           -prof -
           -profile    { 
                    # Pour deboguer, mais ne fonctionne pas àa cause
                    # du package d'analyse d'arguments (les upvar...)
                    set arga(-profile) [lindex $args 1]
                    set args [lreplace $args 0 1]
                    ::profiler::init
                    continue
           }
           -*      {
                     puts stdout "unknow option [lindex $args 0]"
                     stead:usage
                     exit 1
           }
           default { break  ;# no more options}
        }
    }
    # L'argument suivant (s'il existe) doit etre un nom de fichier
    # à éditer (ou un répertoire...)
    # 
    if {[llength $args]} {
        set arga(file) [lindex $args 0]
        set args [lreplace $args 0 0]
    }
}


## stead:loadFile -- charge le fichier en parametre (EN COURS DEVELOPPEMENT)
# 
# - NON interactif
# - pas de confirmation pour sauvegarder
# - réinitialise le undo et l'état clean
# - accepte l'option -mode
# - accepte l'option -text
# - effectue la mise à jour des couleurs, ...
# - 
# 
# à faire (prioritaire) : 
#   1 - charger file -> .mail.t
#   2 - **puis** appeler stead:modeGuess
#       Criteres de choix pour deviner le mode
#          1 - option -mode <theMode>
#          2 - emacs string (i.e  -*-tcl-*- )
#          3 - firstLinePattern
#          4 - fileNamePattern
#          5 - si mode = sh => essayer de détecter le mode tcl
#               (en ignorant toutes ligne finissant par backslas)
# 
# 
# a faire (autre) : 
#   prévoir passage du texte à éditer au lieu d'un nom de fichier
#   (i.e proc stead:loadText)
# 
# 
#      
# !!!!!!!!! ATTENTION EN COURS DE DEVELOPPEMENT !!!!!!!!!!!!!
# 
# proc stead:loadFile {t fileName} {
#     
#     # Extrait de stead:loadBox (à alléger quand cette proc sera au point)
#     # 
#     # if {$prompt_result != {}} then {
#     #     set stead(file) $prompt_result
#     #     # # # stead:modeGuess $stead(file)
#     #      set $stead(mode) [stead:modeGuess $stead(file)]
#     #     stead:modeApply  $stead(mode)
#     #     stead:read $stead(file)
#     #     xtext_undoInit
#     #     xtext_markClean .main.t
#     # }
# 
#     if {![file isreadable $fileName]} {
#         stead:log "file $fileName is not readable"
#     }  ;# endif
#      
#     set stead(file) $fileName
#     
#     # auto-select -mode if not specified explicitly
#     if {$stead(mode) == "default"} {
#       # # # stead:modeGuess $stead(file)
#       set $stead(mode) [stead:modeGuess $stead(file)]
#     }
#     stead:modeApply $stead(mode)
#     
# }


## stead:initGlobals - initialisation des globales (hors préférences)
#
# 
proc stead:initGlobals {} {

    global stead
    global EDITPREFS            ;# editor prefs (all modes)


    # Lecture de la variable stead(version)
    source [file join $stead(install) etc VERSION.tcl]

    set stead@doc(file) "Nom du fichier à éditer"
    set stead(file) ""
    
    set stead@doc(message) "Variable associée au message d'information de stead"
    set stead(message) ""
    
    # Unique IDentifier
    set stead@doc(uid) "Unique IDentifier : incrémenté àvant chaque lecture"
    set stead(uid) -1    
    
    # les bindings d'annulation d'opération dans les dialogues
    # (remplace te:cancel_button)
    set stead(cancelBindSequence) {
        <Control-c> <Control-g> 
        <Meta-q> <Meta-w> <Meta-period> <Escape>
    }
    # set stead(cancelBindSequence) {
    #     <$stead(Control)-c> <$stead(Control)-g> 
    #     <$stead(Meta)-q> <$stead(Meta)-w> <$stead(Meta)-period> <Escape>
    # }
    
    # 
    # Le mode sera déterminé automatiquement en fonction du fichier 
    # Les variable liées au modes devrait etre construite automatiqueme
    # à partir du contenu des répertoire de chaque mode.
    # Ceci failiterait la création de nouveau mode.
    # Au besoin le résultat de cette "compilation" de toutes les
    # informations sur les modes pourra être en cache pour une raison
    # d'efficacité. 
    # 
    set stead(mode) ""
    set stead(defaultMode) text

    set stead@doc(modeSuffixMappings)  \
       "Liste de triplets associant une Gpatterne caractérisant un suffixe\
        au mode associé à ce suffixe"
        
    set stead(modeSuffixMappings)  {
      {*.c                c           {C source}}
      {*.h                cc          {C header files}}
      {*.H                cc          {C++ header files}}
      {*.hh               cc          {C++ header files}}
      {*.cc               cc          {C++ source}}
      {*.cp               cc          {C++ source}}
      {*.cpp              cc          {C++ source}}
      {*.hpp              cc          {C++ header/source}}
      {*.C                cc          {C++ source}}
      {*.c++              cc          {C++ source}}
      {*.cl               claire      {claire files (for optimisation)}}
      {*.java             java        {java source}}
      {*.javascript       java        {javascipt source}}
      {*.js               java        {javascipt source}}
      {*.groovy           groovy      {groovy source}}
      {*.grv              groovy      {groovy source}}
      {*.gv               groovy      {groovy source}}
      {*.ad?              ada         {fichiers ada }}
      {*.f                fortran     {Fortran source}}
      {*.for              fortran     {Fortran source}}
      {*.F                fortran     {Fortran source}}
      {*.f90              fortran     {Fortran source}}
      {*.F90              fortran     {Fortran source}}
      {*.html             html        {HTML files}}
      {*.shtml            html        {HTML files}}
      {*.[hH][tT][mM][lL] html        {HTML files}}
      {*.[hH][tT][mM]     html        {HTML files}}
      {*.php              php         {PHP files}}
      {*.php?             php         {PHP files}}
      {*.inc              php         {PHP include files (e.G; in Drupal}}
      {*.xml              html        {XML files}}
      {*.tml              html        {TML : TCL and HTML}}
      {*.stf              html        {STF Simple Taged Format (html like)}}
      {*.xml              html        {XML files}}
      {*.plist            html        {XML files property list for MacOSX}}
      {*.p                pascal      {Pascal source}}
      {*.sh               sh          {Bourne shell source}}
      {*.shar             sh          {Bourne shell archive}}
      {*.csh              sh          {C shell source}}
      {*.tcl              tcl         {Tcl scripts}}
      {*.tk               tcl         {Tk scripts}}
      {*.itcl             tcl         {incr tcl scripts}}
      {*.itk              tcl         {incr tk scripts}}
      {*.tclshrc          tcl         {Tcl scripts}}
      {*/steadrc          tcl         {Tcl scripts}}
      {*/tclIndex         tcl         {Tcl scripts}}
      {*.tk               tcl         {Tk/Tcl scripts}}
      {*.expect           tcl         {expect scripts}}
      {*.tex              latex       {TeX or LaTeX source}}
      {*.latex            latex       {LaTeX source}}
      {*.bib              latex       {LaTeX biblio}}
      {*.bbl              latex       {LaTeX biblio}}
      {*.sty              latex       {style Latex}}
      {*.cls              latex       {classes Latex}}
      {*texmf.cnf         latex       {fichier de config pour teTeX}}
      {*.ly               latex       {fichier lilypond (Latex like)}}
      {*.vhd              vhdl        {Vhdl source}}
      {*.v                verilog     {Verilog source}}
      {*.vlg              verilog     {Verilog source}}
      {*.sci              scilab      {Scilab file}}
      {*.sce              scilab      {Scilab file}}
      {*.m                matlab      {Matlab file}}
      {*.ps               postscript  {postscript file}}
      {*.rb               ruby        {ruby et jruby}}
      
      
      {*.tms              asmTMS      {assembler TMS}}
      {*.s                asmTMS      {assembler}}
      {*.asm              asmTMS      {assembler}}
      
      {*.mel              mail        {suffixe personnel ! }}
      {*.letter           mail        {Mail from tin}}
      {*.followup         mail        {nezs from slrn}}
      {*.article          mail        {trn}}
      {*/tkmail[0-9]*     mail        {tkmail}}
      {*/xrn*             mail        {xrn}}
      {*/mutt*            mail        {mail reader mutt}}
      {*/*Makefile*       make        {fichier Makefile, dependancy ...}}
      {*/*makefile*       make        {fichier Makefile, dependancy ...}}
      {*/*.d              make        {fichier Makefile, dependancy ...}}
      {*.make             make        {fichier Makefile, dependancy ...}}
      {*.mak              make        {fichier Makefile, dependancy ...}}
      {*.mk               make        {fichier Makefile, dependancy ...}}
      {*/.cshrc           csh         {~/.login, etc.}}
      {*/.tcshrc          csh         {~/.login, etc.}}
      {*/.login           csh         {~/.login, etc.}}
      {*/.logout          csh         {~/.login, etc.}}
      {*/draft*/[0-9]*    mail        {MH, exmh, xmh, etc.}}
      {*/tmp/snd.[0-9]*   mail        {elm}}
      {*/tmp/R*[0-9]      mail        {UCB Mail}}
      {*.job              gct         {GVT: job geocluster }}
      {*.modXXXXX         gct         {GVT: model geocluster }}
      {*.l??XXXXX         gct         {GVT: librairie geocluster }}
      
      {*.txt              text         { text file }}
    }                               

    set stead@doc(modeFirstLineMappings)  \
       "Liste de triplets associant une Gpatterne caractérisant un mode\
        associé à la première ligne d'un fichier"
    
    # # La liste des modes connus privilégiés (apparaissant dans le pop-menu)
    # set stead(modes) [lsort {
    #         ada asmTMS  c cc java
    #         fortran html latex
    #         verilog vhdl
    #         matlab scilab
    #         mail pascal postscript sh text tcl
    #         make plain
    #         claire
    # }]
    # Construction de la liste de tous les modes connus 
    foreach modeSuffixMapping $stead(modeSuffixMappings)   {
        set tmpArray([lindex $modeSuffixMapping 1]) X
    }
    set stead(allModes) [lsort [array name tmpArray]]
    set stead(modes) $stead(allModes) 
    # report -v stead(modes) stead(allModes)
    
    set stead(modeFirstLineMappings) {
      {%!*              postscript      {PostScript file}}
      {#!*wish*         tcl             {executable tcl script}}
      {exec*wish*       tcl             {executable tcl script (third line)}}
      {#!*tcl*          tcl             {executable tcl script}}
      {exec*tcl*        tcl             {executable tcl script (third line)}}
      {#!*csh*          sh              {executable csh script}}
      {#!*claire*       sh              {executable claire script}}
      {#!*ruby*         ruby            {executable ruby script}}
      {#!*/sh*          sh              {executable bourne script}}
      {//c++*           cc              {C++ code}}
    }

    # 
    # Abbréviation dynamiques (dabbrev)
    # 
    set stead@doc(ABBREV)     {contains last abbrev expanded}
    set stead@doc(ABBREV_POS) {start of last abbrev}
    set stead@doc(MATCH)      {contains last match found}
    set stead@doc(MATCH_POS)  {position last match found}
    array set stead {
        ABBREV       ""
        ABBREV_POS   ""
        MATCH        ""
        MATCH_POS    ""
    }

    
    # variable de preferences par defaut
    global EDITPREFS_DEF
    set EDITPREFS_DEF(autoposition) 1
    set EDITPREFS_DEF(bindings) emacs
    
    # doit être Alt | Meta | Command ( Control ? )
    # la valeur par défaut AUTO implique un appelle à stead:guessModifierKeys
    # NEW :
    # Meta n'est plus une préférence mais est changeable par une option
    #     set EDITPREFS_DEF(Meta) AUTO
    
    set EDITPREFS_DEF(confirm) 0
    # set EDITPREFS_DEF(print_command) {a2ps -8 %F | lp -dmure}
    # set EDITPREFS_DEF(print_command) {imprimer %F}
    # set EDITPREFS_DEF(print_command) {lpr %F}
    global tcl_platform
    switch -exact -- $tcl_platform(platform) {
      windows {
        set EDITPREFS_DEF(print_command) {notepad /p %F}
      } 
      default {
        set EDITPREFS_DEF(print_command) {lpr %F}
      } 
    } 


    set EDITPREFS_DEF(scrollbarside) right
    set EDITPREFS_DEF(tk_strictMotif) 0
    # set EDITPREFS_DEF(textbg) {#e7e7e7}
    set EDITPREFS_DEF(textbg) {#ffffff}
    set EDITPREFS_DEF(textfg) {black}
    set EDITPREFS_DEF(textsb) {#ccf}
    set EDITPREFS_DEF(textsf) {black}
    set EDITPREFS_DEF(textisb) {grey80}
    set EDITPREFS_DEF(textisf) {black}
    set EDITPREFS_DEF(textiw) 2
    set EDITPREFS_DEF(textbw) 2
    set EDITPREFS_DEF(textsbw) 1; # XXXXX
    set EDITPREFS_DEF(undolevels) 100

    # # set EDITPREFS_DEF(textfont)       {LucidaTypewriter 12}
    # set EDITPREFS_DEF(textfont)       {LucidaTypewriter 12 bold}
    
    # essai 06/11/2007
    # set EDITPREFS_DEF(textfont)       {Courier 12 bold}
    set EDITPREFS(textfont) {LucidaTypewriter 12 bold}
    # set EDITPREFS(textfont) {LucidaTypewriter 12} ;# meme pb qu'avec bold
    # set EDITPREFS(textfont) {Courier 12 bold}   ; # ok
    # set EDITPREFS(textfont) {Courier 12}   ; # ok
    # set EDITPREFS(textfont) {Lucida 12 bold}
    # set EDITPREFS(textfont) {Arial 12 bold} ; # ok
    # set EDITPREFS(textfont) {fixed 13 bold}
    # set EDITPREFS(textfont) {{Lucida Grande} 12 bold}
    # set EDITPREFS(textfont) {Monaco 12 bold}   ;# ok sur Mac
  



    set EDITPREFS_DEF(menufont)       {LucidaTypewriter 12 bold}
    
    # set EDITPREFS_DEF(menubuttonfont) {Helvetica 12 bold}
    set EDITPREFS_DEF(menubuttonfont) {Helvetica 12 bold}
    set EDITPREFS_DEF(buttonfont)     {Helvetica 12 bold}
    
    set EDITPREFS_DEF(textwidth) 80
    set EDITPREFS_DEF(textheight) 40
    set EDITPREFS_DEF(textwrap) char
    set EDITPREFS_DEF(sabbrev) 1
    set EDITPREFS_DEF(dabbrev) 1
    
    # One of {preAccentuation postAccentuation none}
    set EDITPREFS_DEF(accentmode) none

    
    set EDITPREFS_DEF(autobreak) 0
    set EDITPREFS_DEF(autoindent) 1
    set EDITPREFS_DEF(saveoldfile) 0
    
    # Comportement de tcl pour fconfigure -encoding XXXX :
    #   
    #   si PAS DE  -encoding xxx => automatique  (donc ya conversion !)
    #   si -encoding auto : plante ! il faut un traitement amont !
    #   si -encoding  ""      => iso8859-1 (pas de conversion ?)
    #   
    # Cette préférence introduit un nouvel encodage "auto" permettant
    # de distinguer l'absence d'encodage et un encodage automatique par tcl
    # 
    # set EDITPREFS_DEF(encoding)  "utf-8"
    # set EDITPREFS_DEF(encoding)  "iso8859-1"
    # set EDITPREFS_DEF(encoding)  "auto"
    set EDITPREFS_DEF(encoding)  ""
    
    set EDITPREFS_DEF(undoable) 1
    set EDITPREFS_DEF(prefix)  "# "
    set EDITPREFS_DEF(clearUndoOnSave) 1
    set EDITPREFS_DEF(indent_string) "    "
    # set EDITPREFS_DEF(fillcolumn) 72
    set EDITPREFS_DEF(fillcolumn) 80
    set EDITPREFS_DEF(otherabg) {#efefef}
    set EDITPREFS_DEF(otherbg) {#dfdfdf}
    set EDITPREFS_DEF(otherfg) {black}
    # # # set EDITPREFS_DEF(highlightbg) Magenta
    # set EDITPREFS_DEF(highlightbg) #FF8
    
    # NEW (02/02/05) en test avec wish8.5a2
    # # # set EDITPREFS_DEF(highlightbg) Magenta
    # set EDITPREFS_DEF(highlightbg) #AAF
    # highlightbg : 1 seconde lors de la fermeture de parenthèses
    set EDITPREFS_DEF(highlightbg) #FF8
    
    set EDITPREFS_DEF(errorbg) #FDD
    set EDITPREFS_DEF(foundbg) #8FF
    set EDITPREFS_DEF(flashtime) 1000  ;# en ms
    
    # Nb maxi de lignes autorisé pour l'indentation
    set stead(maxIndentNumber) 1000
    
    # commande unix par défaut (en faire une pref utilisateur)
    set stead(unixCommand) "make"

    # # filte unix par défaut (en faire une pref utilisateur)
    # Pas encore exploité : est-ce utile ?
    # set stead(pipeCommand) "make"

    # NON : retarder cette initialisation, quitte à l'appeler depuis chaque 
    # procédure de find !
    # # stead:findInit
    
    # Ajout diam le 20/05/03 suite à pb sous cygwin : j'impose les coupure 
    # de mot à la motif, même sous windows (définition dans [info lib]/word.tcl)
    # 
    set tcl_wordchars "\\w"
    set tcl_nonwordchars "\\W"
}

# stead:resetPrefsToDefault -- reread array EDITPREFS from default
# 
# 
proc stead:resetConfigToDefault {} {
    global stead
    global EDITPREFS EDITPREFS_DEF
    array set EDITPREFS [array get EDITPREFS_DEF]
}

## stead:preConfig -- recharge les prefs
# 
# A exécuter en premiere phase
# 
proc stead:preConfig {} {
    global stead
    global EDITPREFS 
    
    # report -v stead ::auto_path
    # puts [join [lsort [info proc *]] \n]
    
    stead:resetConfigToDefault
    xtcl_source $stead(userfile)
    xtcl_source $stead(localfile)
      

    # on donne aux champs d'entree la meme fonte qu'au texte
    option add *Entry.font $EDITPREFS(textfont) 60

    # on donne aux menus une fonte supportant les accents
    # 
    # Utiliser des fontes nouvelles 
    #   {LucidaTypewriter 12 bold}
    #   {courier          12 bold}
    #   {helvetica        12 bold}
    # 
    option add *Menu.font         $EDITPREFS(menufont)
    option add *Menubutton.font   $EDITPREFS(menubuttonfont)
    option add *Button.font       $EDITPREFS(buttonfont) 
       
    option add *Menubutton.padX    2   
    option add *Menubutton.padY    0   



    # Lecture et interprétation des préférences
    # stead(Meta) doit déja etre positionné pour lancer stead:initBindings
    # global EDITPREFS
    global arga
    
    # 1 - Les modifieurs sont initialisé&s à une valeur par défaut raisonnable
    # 
    set defaultMetaControl [stead:guessModifierKeys]
    set stead(Meta)    [lindex $defaultMetaControl 0]
    set stead(Control) [lindex $defaultMetaControl 1]
    
    # 2 - Si les variable d'environnement STEAD_META et STEAD_CONTROL
    #     existent : on les exploite
    #     
    # Le modifieur Meta
    if {[info exists ::env(STEAD_META)] \
            && [regexp -- "Meta|Alt|Command|Control" $::env(STEAD_META)]} {
        set stead(Meta) $::env(STEAD_META)
    }
    if {[info exists ::env(STEAD_CONTROL] && \
            [regexp -- "Meta|Alt|Command|Control" $::env(STEAD_CONTROL)]} {
        set stead(Control) $::env(STEAD_CONTROL)
    }    
    
    # 3 - Si une option est passée sur la ligne de commande : elle
    #     sera prioritaire
    if {$arga(-meta) != "AUTO" 
            && [regexp -- "Meta|Alt|Command|Control" $arga(-meta)]} {
        set stead(Meta) $arga(-meta)
    } 
    if {$arga(-control) != "AUTO" 
            && [regexp -- "Meta|Alt|Command|Control" $arga(-control)]} {
        set stead(Control) $arga(-control)
    } 
    
    # On vérifie qu'il n'y a pas conflit entre les deux modifiers 
    # pour Control et Meta
    if {$stead(Meta) ==  $stead(Control)} {
        set stead(Meta)    "Meta"
        set stead(Control) "Control"
    }
    

    bind Stead <Escape><Escape><Escape> stead:toggleMetaKey
    bind Stead <Escape><Control-a> {stead:updateModifierKey Alt Control; break}
    bind Stead <Escape><Control-c> {stead:updateModifierKey Control Alt; break}
    bind Stead <Escape><Control-m> {stead:updateModifierKey Meta Control; break}
    
}
## stead:postConfig -- exploite les prefs et execute stead:user_post_hook
# 
# L'éditeur doit déja etre construit
# 
proc stead:postConfig {} {
    global stead
    global EDITPREFS 

    upvar #0 stead(text) w
      
    electricAlias-init

    stead:initBindings

    stead:applyAccentsBindings
  
    # Les tab standard pour stead (i.e independant des modes
    # Note : Le widget text doit exister avant l'exécution de ces commandes ??
    $w tag configure highlight -background $EDITPREFS(highlightbg)
    $w tag configure found     -background $EDITPREFS(foundbg)
    $w tag configure error     -background $EDITPREFS(errorbg)
        
    # Les widgets doivent deja exister
    stead:updateFileLabel
    stead:applyColors
    stead:configureText
    
    # L'exécution de stead:user_post_hook est faite bien plus tard, 
    # mettre peut-etre que cette proc devrait etre executé 
    # plus tard également, et donc inclur plus de chose ??
    # 
    # Par exemple doit-elle être exécutée APRES chargement du fichier ?
}
## stead:rereadConfig -- recharge les prefs et execute stead:user_post_hook
# 
# L'éditeur doit déja etre construit
# 
proc stead:rereadConfig {} {
    stead:preConfig
    stead:postConfig
}

## stead:initBindings -- Initialisation des bindings
# 
# Les bindings liés à l'application stead (et non pas au widget de la c
# lasse XText)
# 
# ATTENTION :
# à compléter des que possible (en depclaçant certain binding 
# actuellement dans la class XText (alias steadXtext) :
#    - 
# 
proc stead:initBindings {} {

    global stead
    
    
    # diam 13/08/00 : EXTRAIT DE tk_library/tk.tcl : il faudra adapter/annuler 
    # (cleanly) ce comportement !
    # 
    # switch $tcl_platform(platform) {
    #     "unix" {
    #         event add <<Cut>> <$stead(Control)-Key-x> <Key-F20> 
    #         # CUT CUT 
    #     }
    #     "windows" {
    #         event add <<Cut>> <$stead(Control)-Key-x> <Shift-Key-Delete>
    #         # CUT CUT 
    #     }
    #     "macintosh" {
    #         event add <<Cut>> <$stead(Control)-Key-x> <Key-F2> 
    #         # CUT CUT 
    #     }
    # }
    # .... CUT ...
    # # ----------------------------------------------------------------------
    # # Default bindings for keyboard traversal.
    # # ----------------------------------------------------------------------
    # 
    # event add <<PrevWindow>> <Shift-Tab>
    # bind all <Tab> {tkTabToWindow [tk_focusNext %W]}
    # bind all <<PrevWindow>> {tkTabToWindow [tk_focusPrev %W]}


    event delete <<PrevWindow>> <Shift-Tab>
    bind all <Tab> {}
    bind all <Shift-Tab> {}
   
    ####################################################################
    # diam le 07/10/03 :
    #   Je place les raccourci <$stead(Control)-xxx> en premier pour qu'ils
    #   puissent être écrasés dans le cas où l'utilisateur préfère
    #   réserver le modifieur <Control> pour le copié-collé
    #   (par la variable d'environnement STEAD_META)
    
    bind Stead <$stead(Control)-o>              {stead:openSelectedFile ; break}
    
    bind Stead <$stead(Control)-$stead(Meta)-o> {Viewurl_Selected     ; break}
    bind Stead <$stead(Control)-$stead(Meta)-h> {Viewurl $stead(file) ; break}
    bind Stead <$stead(Control)-l>              {te:cmd:reset_to_last_save; break}
    
    # A  FAIRE : dialogue d'insertion gérique d'alias (ou de macro ??))
    # bind Stead <$stead(Control)-$stead(Meta)-space> {
    #     stead:insertAbbrevDialog 
    #     break
    # }

    # peut-etre que emacs utilise <$stead(Control)-j> ? à vérifier)
    bind Stead <$stead(Control)-j>            {electricAlias-nextStop; break}
    bind Stead <$stead(Control)-Shift-j>      {electricAlias-prevStop; break}
    # bind Stead <$stead(Control)-Tab>          {electricAlias-nextStop; break}
    # bind Stead <$stead(Control)-Shift-Tab>    {electricAlias-prevStop; break}

    # Ceci évite de quitter stead par un mauvais raccourci clavier
    # Ce raccourci est réservé à la commutation entre windowManager ou entre 
    # environnement graphiques différents (e.g : X11 versus aqua sous MacOSX)
    # bind Stead <$stead(Control)-Shift-Space>     {}
    # bind Stead <$stead(Control)-Shift-q>     {}

         
    # TODO homogéneiser les bindings d'evaluation TCL 
    #    - M-y-y  => Tcl Shell
    #    - M-y-e  => Tcl Entry (plus autre chose de rapide
    #                qui ferme l'entry apres retourne
    #    - M-y-s  => Tcl Eval Selection
    #    - M-y-k  => Tcl Calulate Selection
  
    # Pipe
    bind Stead <$stead(Meta)-bar>       {stead:askUnixFilter %W   ; break}
    bind Stead <$stead(Meta)-P>         {stead:askUnixFilter %W   ; break}
    # bind Stead <$stead(Meta)-equal>     {te:sys_fmt           ; break}
  
    # Extra 
    bind Stead <$stead(Meta)-L>         {te:cmd:execute_sel   ; break}
    bind Stead <$stead(Meta)-colon>     {stead:askChars %W    ; break}
    bind Stead <$stead(Control)-q>              {stead:askChars %W    ; break}
    
    
    # Le futur standard pour stead si pas de problèmes 
    bind Stead <Escape><Key-x>              {break}
    bind Stead <Escape><Key-x><Key-a>       {te:cmd:addition_sel  ; break}
    bind Stead <Escape><Key-x><Key-c>       {te:cmd:execute_clip  ; break}
    bind Stead <Escape><Key-x><Key-k>       {te:cmd:calculate_sel ; break}
    bind Stead <Escape><Key-x><Key-s>       {te:cmd:execute_sel   ; break}
    bind Stead <Escape><Key-x><Key-t>       {te:prompt_tcl        ; break}
    bind Stead <Escape><Key-x><Key-y>       {te:tclShell          ; break}
    bind Stead <Escape><Key-x><Key-u>       {stead:editUnixResult ; break}
    bind Stead <Escape><Key-x><Key-m>       {
                    stead:editUnixResult make; break}
    
    bind Stead <$stead(Meta)-t><Key-a>  {te:cmd:addition_sel  ; break}
    bind Stead <$stead(Meta)-t><Key-c>  {te:cmd:execute_clip  ; break}
    bind Stead <$stead(Meta)-t><Key-k>  {te:cmd:calculate_sel ; break}
    # bind Stead <Escape><k>              {te:cmd:calculate_sel ; break}
    bind Stead <$stead(Meta)-t><Key-s>  {te:cmd:execute_sel   ; break}
    bind Stead <$stead(Meta)-t><Key-t>  {te:prompt_tcl        ; break}
    bind Stead <$stead(Meta)-t><Key-y>  {te:tclShell          ; break}

    # Je conserve ces deux abbréviations !
    bind Stead <$stead(Meta)-y>         {te:prompt_tcl        ; break}
    bind Stead <$stead(Meta)-Y>         {te:tclShell          ; break}
    bind Stead <$stead(Meta)-U>         {stead:editUnixResult ; break}
    

    # iconification
    # 
    bind Stead <$stead(Meta)-m>         {stead:toggleIconify .   ; break}


    # Additional application-specific Emacs-style keyboard bindings  
    # 
    bind Stead <$stead(Control)-x><$stead(Control)-s>    {stead:save   ; break}
    bind Stead <$stead(Control)-x><$stead(Control)-w>    {stead:saveas ; break}
    bind Stead <$stead(Control)-x><$stead(Control)-f>    {stead:loadBox   ; break}
    bind Stead <$stead(Control)-x><$stead(Control)-v>    {stead:loadBox   ; break}
    bind Stead <$stead(Control)-x><$stead(Control)-c>    {stead:quitBox   ; break}
    bind Stead <$stead(Control)-s>               {stead:findBox .main.t  ; break}
    bind Stead <$stead(Control)-percent>         {stead:findBox .main.t  ; break}


   
    
    ####################################################################
    # Les raccourcis de base en dernier car on veut être sûr qu'ils soient 
    # pris en compte même si l'utilisateur veux imposer le modifieur Control 
    # pour la variable stead(Meta)  <== CECI EST PERIME !!
    # 
    bind Stead <$stead(Meta)-n>         {exec $stead(exe) &}
    bind Stead <$stead(Meta)-o>         {stead:openBox}
    bind Stead <$stead(Meta)-O>         {te:cmd:open_same_file}

    bind Stead <$stead(Meta)-l>         {stead:loadBox}
  
    bind Stead <$stead(Meta)-s>         {stead:save}
    bind Stead <$stead(Meta)-S>         {stead:saveas}
    bind Stead <$stead(Meta)-p>         {stead:printBox}
    bind Stead <$stead(Meta)-I>         {stead:insertFileBox}
    bind Stead <$stead(Meta)-exclam>    {stead:insertUnixResult}
    bind Stead <$stead(Meta)-question>  {te:cmd:show_file_info}
    # le break final évite au finder (sous MacoOSX) de recevoir ce raccourci
    # qui permet de se déloguer !)
    # bind Stead <$stead(Meta)-Q>         {te:cmd:reset_to_last_save; break}
    # bind Stead <$stead(Meta)-$stead(Control)-l> {te:cmd:reset_to_last_save; break}
    bind Stead <$stead(Meta)-q>           {stead:quitBox}
    
    # TODO 
    # Changer les binding de sépateur pour insérer des caractères
    # ascii affichable arbitraires.
    # 
    # Exemple  Meta-1-d insere une ligne de d.
    # Cela libère les raccourcis pour Meta-2, Meta-3...
    # pour ENCADRER LA SELECTION (par exemple)

    # Bindings pour les lignes de séparation Meta-0, Meta-1,...
    # par exemple <Meta-5> déclenchera la fonction utilisateur te:macro5
    for {set i 0} {$i <= 9} {incr i} {
         set func_touche "<Meta-Key-$i>"
         bind Stead $func_touche "te:macro$i; break"
         
         set func_touche "<Meta-KP_$i>"
         bind Stead $func_touche "te:macro$i; break"
    }

    # COMPLEMENT POUR L'EXEMPLE
    # 
    # A FAIRE : gérer la notion de document (doc ou activedoc ?)
    #   le nom du document = alias la future toplevel, alias "." 
    # pour l'instant ?) 
    # 
    # bind Stead <$stead(Meta)-n> {stead:new}
    # bind Stead <$stead(Meta)-N> {stead:newProcess}
    # bind Stead <$stead(Meta)-o> {stead:open      [stead:new]}
    # bind Stead <$stead(Meta)-l> {stead:open      $stead(activeDoc)}
    # bind Stead <$stead(Meta)-O> {stead:reopen    $stead(activeDoc)}
    # bind Stead <$stead(Meta)-s> {stead:save      $stead(activeDoc)}
    # bind Stead <$stead(Meta)-S> {stead:saveas    $stead(activeDoc)}
    # bind Stead <$stead(Meta)-p> {stead:print     $stead(activeDoc)}
    # bind Stead <$stead(Meta)-w> {stead:close     $stead(activeDoc)}  
    # bind Stead <$stead(Meta)-q> {stead:quit}

    # Fonction du menu Edit
    # 
    # Ces deux bindings doivent probalement rester liés au widget !
    # 
    # bind Stead <$stead(Meta)-z> {xtext_undo      $stead(activeDoc)}
    # bind Stead <$stead(Meta)-Z> {xtext_redo      $stead(activeDoc)}
    # 
    # bind Stead <$stead(Meta)-x> {stead:cut       $stead(activeDoc)}
    # bind Stead <$stead(Meta)-c> {stead:copy      $stead(activeDoc)}
    # bind Stead <$stead(Meta)-v> {stead:paste     $stead(activeDoc)}
    # bind Stead <$stead(Meta)-a> {stead:selectAll $stead(activeDoc)}
    # bind Stead <Escape> "stead:unSelectAll Stead"
    
} ;# endproc stead:initBindings


## stead:applyAccentsBindings -- mise à jour pré/post accentuation
# 
# 
proc stead:applyAccentsBindings {  } {
    
    global EDITPREFS
    set w $::stead(text)
    
    switch  -exact -- $EDITPREFS(accentmode) {
         preaccentuation -
         preAccentuation {
             accents_IsoPreBind $w
         }
         postaccentuation -
         postAccentuation {
             accents_IsoPostBind $w
         }
         none {
         }
         default {
              set msg "incorrect value for EDITPREFS(accentmode)\n"
              append msg "it is $EDITPREFS(accentmode)\n"
              append msg "it should be one off this list:\n"
              append msg "{preAccentuation  postAccentuation  none}"
              error $msg
         }
    }
}

## stead:configureText - set text for current preferences
# 
proc stead:configureText {} {
    global stead
    global EDITPREFS
    xtcl_catch  [list  $stead(text) configure \
              -background $EDITPREFS(textbg) \
              -foreground $EDITPREFS(textfg) \
              -insertbackground $EDITPREFS(textfg) \
              -selectbackground $EDITPREFS(textsb) \
              -selectforeground $EDITPREFS(textsf) \
              -selectborderwidth $EDITPREFS(textsbw) \
              -borderwidth $EDITPREFS(textbw) \
              -insertwidth $EDITPREFS(textiw) \
              -width $EDITPREFS(textwidth) \
              -height $EDITPREFS(textheight) \
              -wrap $EDITPREFS(textwrap) \
    ]
    # Traitement spécial pour les options spécifiques à wish8.5
    xtcl_catch [list  $stead(text) configure \
              -inactiveselectbackground $EDITPREFS(textisb) \
    ]
    $stead(text) configure -font $EDITPREFS(textfont)
}
## stead:setFont
# 
# effecte et prend en compted'une nouvelle fonte dans l'éditeur
proc stead:setFont {fontSpec} {
    set ::EDITPREFS(textfont) $fontSpec
    stead:configureText
}


## stead:modeGuess -- retourne un mode valide en fonction
# 
# param f : a filename
# globales lues : stead(modeSuffixMappings) 
#                 stead(modeFirstLineMappings) 
#
# En faire DEUX procédures :
#    stead:modeGuessFromWidget $w  : utilisant le widget préchargé
#    stead:modeGuessFromFileName $f  : prenant un nom de fichier 
# 
# A refaire avec les criteres de choix pour deviner le mode
#     0 - option -mode <theMode>
#     1 - emacs string (i.e  -*-latex-*- )
#     2 - firstLinePattern
#     3 - fileNamePattern
#     4 - si mode = sh => essayer de détecter le mode tcl
#          (en ignorant toutes ligne finissant par backslas)
# 
proc stead:modeGuess {f} {
    global stead
    upvar 0 stead(text) w
  
    set localMode ""
    
    # Cette boucle sert à imposer un point de sortie unique de cette procédure
    while {1} {
    
        # 1 - Détection du mode "à la emacs" par la présense dans le fichier
        #     d'une chaine de la forme  -*-latex-*-
        #     ATTENTION, en cas de l'existence de plusieurs chaines emacs
        #     dans le meme fichier (c'est le cas dans ce présent fichier tcl !)
        #     La priorité doit etre donnée à la première chaine rencontree
        # 
        set idx [$w search -regexp -count count -- {-\*-\w+-\*-} 1.0 ]
        if {[string length $idx]} {
            set emacsString [$w get $idx "$idx + $count c"]
            set modeString ""
            regexp -- {\w+} $emacsString modeString
            set modeString [string tolower $modeString]
            
            # On vérifie que la chaine détectée est bien un nom de mode :
            set modeIdx [lsearch -exact $stead(modes)  $modeString]
            
            if {$modeIdx != -1} {
                # On a trouver un mode existant
                set localMode $modeString
                break
            }
        } 
        #
        # 2 - détection du mode par le suffixe (en fait par une patterne 
        #     arbitraire)
        #
        foreach i $stead(modeSuffixMappings) {
            if [string match [lindex $i 0] $f] {
                set localMode [lindex $i 1]
                break
            }
        }
        
        #
        # 3 - examen de la premiere ligne du fichier (%! => postscript)
        #
        if {[file exists $f]} {
            set file [open $f {r}]
            gets $file line1  
            close $file
            
            # (unix only sees 32 chars)
            set line1 [string range $line1 0 31]
            foreach i $stead(modeFirstLineMappings) {
                if [string match [lindex $i 0] $line1] {
                    set localMode [lindex $i 1]
                    
                    if {$localMode != "sh"} {
                        break
                    } else {
                        # if the found <mode> is sh,  must do more work...
                        break
                    }
                }
            }
        }
        
        #
        # 4 - détection d'un script tcl débutant par #!/bin/sh :
        #
        if {$localMode == "sh"} {
            
            # On cherche dans les premieres lignes du script shell une ligne
            # de la forme "exec tclsh ..."
            # 
            set pat {^\s*exec.*(tcl|wish)}
            set idx [$w search -regexp -count count -- $pat 1.0  20.0]
            if {[string length $idx]} {
                set localMode "tcl"
                break
            } 
        }
        
        # Ne pas oublier ce break final sous peine de bouclage !
        break
    }
    
    #
    # 5 - si on ne trouve rien, on retourne vide 
    #     (i.e par de mode par défaut ici) !
    #
    if { "$localMode" == "" } {
        set localMode "text"
    }

    # On peut rajouter ici des bidouilles avant de retourner le mode
    # par exemple pour gérer plusieurs version d'un même mode en fonction
    # d'une préférence...
    
    # if {($stead(user) == "diam") && ($localMode == "tcl")} {
    #     set localMode tclNEW
    # }
    
    
    return $localMode
} ;# stead:modeGuess

## stead:modeRemove - nettoye les variable et proc avant de quitter un mode
# 
# 
proc stead:modeRemove { oldMode } {

    global stead
    global MODE_MARK_LIST TE_MODE_SEARCH_STRING
    global TE_MODE_NAVIG_SHOW_TEXT TE_MODE_NAVIG_RESET_TEXT

    # Nettoyage à faire pour quitter l'ancien mode
    # A faire AVANT le changement de la variable stead(mode) !!
    if {[info procs stead:modeCleanup] != {}} {
        stead:modeCleanup
        rename stead:modeCleanup {}
    }
    # Supression des style seulement pour le mode à quitter
    # (Il peut y avoir des style d'utilité générale à conserver)
    style delete $oldMode
    
    catch {
        foreach m $MODE_MARK_LIST {
           .main.t mark unset $m
        }
        unset  MODE_MARK_LIST
    }

    catch {unset TE_MODE_SEARCH_STRING }
    catch {unset TE_MODE_NAVIG_SHOW_TEXT}
    catch {unset TE_MODE_NAVIG_RESET_TEXT}

    # on detruit la fenetre de navigation éventuellement affichée 
    # par le mode précédent
    catch {destroy .navig} 


    # on detruit les electric alias s'ils existent
    # diam 15/10/2001 : 
    # Est-ce vraiment nécessaire de supprimer les alias de l'ancien
    # mode ? Car il peut-etre utile d'avoir à la fois les alias du mode
    # html et tcl (en attendant de savoir gérer plusieurs modes différents
    # pour un même fichier)
    # 
    if [info exists ALIAS] {
        electricAlias-removeall
    }

    foreach proc {
        stead:read_pre_hook
        stead:read_inside_hook
        stead:read_post_hook

        stead:write_pre_hook
        stead:write_inside_hook
        stead:write_post_hook

        stead:quit_pre_hook

        stead:spacebar_pre_hook
        stead:spacebar_inside_hook
        stead:spacebar_post_hook

        stead:tabkey_pre_hook
        stead:tabkey_inside_hook
        stead:tabkey_post_hook

        stead:returnkey_pre_hook
        stead:returnkey_inside_hook
        stead:returnkey_post_hook

        stead:paste_pre_hook
        stead:paste_post_hook

        stead:xpaste_pre_hook
        stead:xpaste_post_hook

        xtext_insertFilter_hook

        te:mode:rescan_hook

    } {
        catch {
            rename $proc {}
        }
    }
    
    uplevel #0 {
        catch {rename te:mode:navig_label_hook {}}
        proc te:mode:navig_sort_hook {list}    { return $list } 
        proc te:mode:rescan_hook {}         { ; } 
    }
}
## stead:modeApply - passe au mode et le mémorise dans stead(mode)
# 
# 
proc stead:modeApply {newMode} {

    global stead
    global MODE_MARK_LIST TE_MODE_SEARCH_STRING
    global TE_MODE_NAVIG_SHOW_TEXT TE_MODE_NAVIG_RESET_TEXT

    if {[string length $stead(mode)]} {
        # Si le mode demandé est différent du mode reel précédent : on 
        # supprime les effets du mode précédents 
        if {[string compare $stead(mode) $newMode]} {
            stead:modeRemove $stead(mode)
            set stead(mode)  $newMode            
        }
    } 
    if {![string length $newMode]} {
        # aucun mode défini : on applique le mode par défaut
        set newMode $stead(defaultMode)
    }
    
    set stead(mode)  $newMode


    # on charge éventuellement les abréviations utilisateur
    xtcl_source [file join $stead(userlib) alias.tcl]

    electricAlias-setMode $stead(mode)
    set file "[set stead(mode)]-main.tcl"


    # 
    # on source soit le fichier systeme dans stead(install)/lib/modes, 
    # soit le fichier de meme nom dans stead(userlib)
    # 
    foreach dir [list \
        $stead(userlib) \
        $stead(install_modes) \
    ] {
        if [file isfile [file join $dir $file]] {
            xtcl_source [file join $dir $file]
            break
        }
    }
    
    # 
    # s'il existe un fichier utilisateur pour ce mode,
    # on le "source" en plus.
    # 
    set file [file join $stead(userlib) $stead(mode)-user.tcl]
    if [file isfile $file] {
        xtcl_source $file
    }


    stead:configureText
    # cree le menu de navigation pour les modes
    te:mode:make_navig_menu
    # ajoute les commandes d'edition des fichiers de configuration
    te:mode:add_edit_commands $stead(mode)

    stead:styleRefresh
    
} ;# stead:modeApply

## stead:styleRefresh - redéfinie pour le mode tcl
# 
# Rafraichir tous les styles actifs
# 
# Anciennement refresh_colors
# Cette procédure recolorise l'ensemble du fichier (au départ ou sur demande)
# 
proc stead:styleRefresh {args} {
    global stead
    upvar 0 stead(text) w
    # set opt(-maxFile) 999999999
    set opt(-maxFile) 100000
    Parsarg_fullSpec opt {
        all  {
            -type flag
            -eval {set opt(-maxFile) 999999999}
        }
        maxFile  {
            -type integer
            -doc "Taille maxi du fichier pour rafraichissement total"
        }
        step  {
            -type integer
            -default 100
            -doc "Nbr de ligne par tranche de rafraichissements"
        }
        after {
            -type integer
            -default 100
            -doc "Nbr ms entre deux rafraichissements"
        }
    }
    
    
    # Ce premier update est utile au lancement , mais devrait être déplacé ?
    update
    # On recolorise d'abord la page visible pour aller plus vite
    xtext_style $w apply -screen
    
    # Si fichier trop grand : on évite la coloration complète
    # Quand ce sera au point : en faire une préférence utilisateur
    # 
    if {[file exists $stead(file)]} {
        set fileSize [file size $stead(file)]
        if {$fileSize > $opt(-maxFile)} {
            return
        }
    }

    # Puis par blocs de 100 lignes
    # 
    # set M1 M[xtcl_uid]
    # set M2 M[xtcl_uid]
    # $w mark set $M1 1.0
    # $w mark set $M2 "$M1+$opt(-step)lines"
    $w mark set refresh1 1.0
    $w mark set refresh2 "refresh1+$opt(-step)lines"
    while { [$w compare refresh1 < end] } {
        update
        xtext_style $w apply -range "refresh1 refresh2"

        $w mark set refresh1 refresh2
        $w mark set refresh2 "refresh1+$opt(-step)lines"
        
        if {$opt(-after) != 0} {
            # On attend pendant le temps précisé
            after $opt(-after)
        }
        
    }
} 

## stead:styleCancel - redéfinie pour le mode tcl
# 
# Cette procédure efface les styles dans tout le fichier
# 
# Anciennement cancel_colors
# 
proc stead:styleCancel {} {
   upvar 0 ::stead(text) w
   xtext_style $w remove
}

## stead:guessModifierKeys -- retourne la liste des modifieurs Meta et Control
# 
# 
# return "Alt Control", "Meta Control" ou "Command Control" en fonction 
# des caracteristiques de la plateforme.
# La liste retournée sera utilisée pour construire des valeurs par 
# défaut raisonnable pour les variable stead(Meta) et stead(Control)
# 
proc stead:guessModifierKeys {  } {

    set theMeta ""
    
    set arch [xtcl_guessArch]
    switch -glob -- $arch {
        *platform=macintosh* {
            set theMeta "Command"
        } 
        *platform=windows* {
            set theMeta "Alt"
        } 
        # "Le reste est pour les différents unix"
        *machine=sun* -
        *machine=ppc* -
        "*machine=Power Macintosh*" {
            set theMeta "Meta"
        } 
        default {
            set theMeta "Alt"
        } 
    }
    # TODO : prévoir une procédure hook pour cette extension
    #   stead:guessModifierKeysHook 
    #       Retourne  Alt|Meta|Command
    # 
    # # Ensuite on écrase par les différents cas particuliers
    # if {[string match "*ppc*Linux*2.2.19*" $arch]} {
    #     # Ma nouvelle version YellowDog-2.0 d'aout 2001
    #     set theMeta "Alt"
    # }
    return [list $theMeta "Control"]
}

## stead:updateFileLabel -- met à jour tout ce qui dépend du nom du fichier
# 
# TODO : 
# - prévoir une preference de formatage avec variable du style
#   "%!%N-%B"  =="$isModified$TkAppName-Basename"
# - créer une trace activée sur la modif de stead(file)
# 
proc stead:updateFileLabel {{name USE_FILENAME} {l .main.status.name}} {
    global stead    
    
    if {![info exists stead(file)]} {
        return        
    }

    set but $stead(toggleFileNameButton)
    set lab $stead(fileNameLabel)
    
    set sign [$but cget -text]
    if { [string equal "-" $sign] } {
        set stead(fileNameLabelVar) [file tail $stead(file)]
    } else {
        set stead(fileNameLabelVar) $stead(file)
    }

    wm title .    "[file tail $stead(file)] ($stead(interpName))"
    wm iconname . "[file tail $stead(file)]"
    
}

## stead:updateModifierKey -- relance les bindings pour des nouveau Modifier
# 
# Redefini les bindings suite à une modification dynamique de la 
# touche Meta ou control (qui peut valeur Meta, Alt, Option, Command...)
# On doit faire appel à la procédure bas niveau "xtextInitBindings"
# (qui n'est normalement appelée que par "xtextInit" lors de la
# première utilisation d'un XText)
# 
proc stead:updateModifierKey {newMeta newControl} {
    global stead
    
    set stead(Control) $newControl
    set stead(Meta)    $newMeta
    
    set bindingCmds {
        xtextInitBindings
        stead:initBindings
    }
    foreach cmd $bindingCmds {
        eval $cmd
    }    
    
    stead:log "Prise en compte modifieurs $stead(Meta) et $stead(Control) faite"
}
## stead:toggleMetaKey -- commute le modifieur "Alt" versus "Meta"
# 
# Ces binding permettent de passer de commuter stead(Meta) entre 
# la touche Meta à la touche Alt
# 
proc stead:toggleMetaKey {} {
    global stead
    
    switch -exact -- $stead(Meta) {
      Meta {
              set newMeta    "Alt"
              set newControl "Control"
      }
      Alt -
      Control -
      default {
              set newMeta "Meta"
              set newControl "Control"
      }
    }
    stead:updateModifierKey $newMeta $newControl
}


## stead:autobreak_hook -- gère les sauts de lignes automatiques
# 
# 12/09/00 diam : A FAIRE :
#     Cette fonction est boguee : elle devrait tenir compte
#     de la variable EDITPREFS(fillcolumn) et ne couper la ligne
#     que si la longueur totale dépasse EDITPREFS(fillcolumn).
#     Dans ce cas, la coupure doit etre insérer proprement 
#     AVANT le mot responsable.
#     Q : Faut-il prévoir de pouvoir inhiber le checkPoint dans 
#         ce cas ?
# 
#     Il ne faut pas utiliser EDITPREFS(textwidth) (à réserver 
#     à la taille initiale du widget text) mais EDITPREFS(fillcolumn)
#    
proc stead:autobreak_hook {{t .main.t}} {
  global stead
  global EDITPREFS

  if {$EDITPREFS(autobreak)} {
    set length [string length [$t get {insert linestart} insert]]
    if {$length > ($EDITPREFS(textwidth) - 15)} {
      stead:returnkey
    }
  }
}


## stead:autoindent_hook - insert same indentation as previous line
# 
proc stead:autoindent_hook {{w .main.t}} {
  global stead
  global EDITPREFS

  if $EDITPREFS(autoindent) {
      set prevline [$w get {insert -1lines linestart} {insert -1lines lineend}]
      
      # modif diam 12/10/01 
      # 
      # # if {[regexp {^[ \t]+} $prevline indentation]} {
      # #     xtext_insert $w -string $indentation
      # # }
      set indentString ""
      
      # Modif diam le 24/11/02 :
      # Il faut inhiber les caracteres spéciaux éventuels qui pourraient
      # apparaitre dans la chaine prfix (par exemple "\" ou "**" )
      # 
      regsub -all {([\.\+\?\*\\])} $EDITPREFS(prefix) {\\\1} prefix
      set rpat {^\s*($prefix)*\s*}
      # set rpat {^\s*($EDITPREFS(prefix))*\s*}
      set rpat [subst -nobackslash $rpat]
      regexp $rpat $prevline indentString
      xtext_insert $w -string $indentString
  }
}

## stead:dabbrev_hook t - stead:cmd:dabbrev if it's on
# 
# (not used by plain mode - Tab does dabbrev *INSTEAD OF* inserting
#   tab, not *before* inserting tab)
# 
proc stead:dabbrev_hook {{w .main.t}} {
    global stead
    global EDITPREFS
    
    if $EDITPREFS(dabbrev) {
        stead:cmd:dabbrev
    }
} 


## xtk_rule parent [args] - returns a rule suitable for parent
#       used as argument to a pack command
# 
# version originale Jay Sekora (jstools)
# 
proc xtk_rule { parent args} {

    # so "." doesn't give "..rule0"
    if {$parent == "."} {
        set parent ""
    }

    set rule "$parent.rule[xtcl_uid]"
    frame $rule -height 2 -width 2 -borderwidth 1 -relief sunken
    if {$args != ""} {
        eval $rule configure $args
    }
    return $rule
}



## stead:applyColors  - reinitialise les couleurs 
# 
# Réinitialise les couleurs en fonction de la variable globale EDITPREFS 
# pour les widgets autres que le widget texte
# 
# Attention : certaines options de configuration n'existent pas pour certains
# widget (Toplevel, Frame, Scrollbar... ?)
# 
# Si on veut imposer une couleur à la création : on ne doit doit pas
# reconfigurer le widget en question 
# d'ou le if {$w == ".main.alert.version"}
# 
proc stead:applyColors {} {
    global EDITPREFS
    
    set widgets .
    set n_w2 {}
    set new_widgets $widgets
    set still_children 1
    while {$still_children} {
        set still_children 0
        foreach w $new_widgets {  
            set n_w [winfo children $w]
            if {![string match "" $n_w]} {
                set still_children 1
                append widgets " $n_w"
                append n_w2 " $n_w"
            }
        }
        set new_widgets $n_w2
        set n_w2 {}
    } 

    foreach w $widgets {
    
        # On ne veut pas changer la couleur de ce widget
        if {$w == ".main.alert.version"} {
            continue
        }
        
        # Décommenter la ligne suivante pour détecter les nouvelles 
        # classes ne disposant pas de l'option -foreground ...
        # 
        # puts "\n@@@@@@@@ winfo class $w : \"[winfo class $w]\"\n"
        # 
        if {
            [catch {
                $w configure -foreground $EDITPREFS(otherfg)
                $w configure -activebackground $EDITPREFS(otherbg)
                # # $w configure -inactiveselectbackground $EDITPREFS(textisb)
            }  result]
        } {
            # puts -nonewline "option -foreground non supportée pour :"
            # puts "@@@@@@@@ winfo class $w : \"[winfo class $w]\""
        }
        
        $w configure -background $EDITPREFS(otherbg)
        
    }
  
    option add *background $EDITPREFS(otherbg) 60
    option add *foreground $EDITPREFS(otherfg) 60
    option add *activeBackground $EDITPREFS(otherabg) 60
    # option add *inactiveSelectBackground $EDITPREFS(textisb) 60
    option add *Scrollbar.background $EDITPREFS(otherabg) 60
    option add *Scrollbar.foreground $EDITPREFS(otherbg) 60
    option add *Scale.background $EDITPREFS(otherabg) 60
    option add *Scale.sliderForeground $EDITPREFS(otherbg) 60
}


## stead:log -- gère l'affichage des messages de stead
# 
# Suivant la longueur du message, cette procédure affiche le résulat
# dans l'entry, et dans un nouvel éditeur.
# Pour l'entry, des options permettent de coloré le message suivant`
# l'importance de celui-ci (-error, -warnig, -info (defaut) )
# 
# A FAIRE : compléter la doc de cette procédure.
# 
# exemples :
#   stead:log "Bonjour tout le monde"  
#   stead:log Bonjour tout le monde
#   stead:log -long 1 $theString
#   stead:log -e -title "Attention" $result
# 
proc stead:log {args} {
    global stead
    upvar 0 $stead(text) w

    Parsarg_fullSpec -mode normal opt {
        title   "msg"
        text    ""
        level   {
            -default "info"
            -regexp {^info|warning|error$}
        }
        long   {
            -default "auto"
            -regexp {^auto|0|1$}
        }
        e -
        error {
            -type flag
            -variable opt(-level)
            -value "error"
        }
        w -
        warning {
            -type flag
            -variable opt(-level)
            -value "warning"
        }
        i -
        info {
            -type flag
            -variable opt(-level)
            -value "info"
        }
        text ""
    }
    # L'option -text est provisoire, et permet d'etre compatible avec
    # l'ancienne proc "stead:log"
    #   set text [join $args]
    #   
    set text "$opt(-text)[join $args]"
    
    set maxLengthForEntryDisplay 500

    if {[string equal $opt(-long) "auto"]} {
        if {[string length "$opt(-title): $text"] \
                                    > $maxLengthForEntryDisplay} {
            set opt(-long) 1
        } elseif { [regexp {\n} $opt(-text)] } {
            set opt(-long) 1
        } else {
            set opt(-long) 0
        }
    }
    
    if {$opt(-long)} {
        # texte long : on lance un éditeur
        exec stead -text "$opt(-title) :\n $text" 
    } else {
        # texte court : on l'affiche dans l'entée
        
        set label ".main.alert.label"
        
        set stead(message) [string range "$opt(-title) : $text"  0  \
                                                $maxLengthForEntryDisplay]
        switch -exact -- $opt(-level) {
            warning {
                # On peut changer l'apparence...
                $label configure -fg blue 
            }
            error {
                # faire un highlite rouge tanporaire et un beep
                $label configure -fg red 
            }
            default {
                # Tout est normal : rien de spécial
                $label configure -fg black 
            }
        }
    }
}

## stead:read filename ?t? - charge le fichier passé en param (avec hook)
# 
# param  filename ?t? -
# param   ?t? 
# 
# initialement dans file.tcl
# 
proc stead:read { filename {t .main.t}} {
    global stead
    global EDITPREFS
  
    if {[info procs stead:read_pre_hook] != {}} {
        stead:read_pre_hook $filename $t
    }
    if {[info procs stead:read_inside_hook] != {}} {
        stead:read_inside_hook $filename $t
    } else {
        if {! [file exists $filename]} then {
            # # # $t delete 1.0 end
            # # # $t mark set insert 1.0
            # # # stead:updateFileLabel "$filename (new file)"
            
            # stead:updateFileLabel
            stead:log "Creating new file   .../[file tail $stead(file)]"
        } else {
            # should do error checking
            set file [open $filename {r}]

            if {"x$EDITPREFS(encoding)" != "xauto"} {
                 fconfigure $file -encoding $EDITPREFS(encoding)
            }

            $t delete 1.0 end
            
            # modif diam 21/08/00 car dans tk8 il y toujours en \n final
            # $t insert end  [read $file]
            $t insert end-1c  [read $file]
            
            $t mark set insert 1.0
            close $file

        }
    }
    # display name over text field
    stead:updateFileLabel  
    if {[info procs stead:read_post_hook] != ""} {
        stead:read_post_hook $filename $t
    }
}



## separator -- insère N (=1) lignes de séparation (ligne commentaire)
# 
# Insère "Nblines" lignes (défaut : 1) correspondant au separateur
# souhaité ;
# 
# Cette procédure peut être redefinie dans les fichiers liés au mode
# NE PAS LA METTRE AILLEURS QUE DANS CE FICHIER pour quelle ne risque pas
# de redéfinir celle définie dans les modes !
# 
proc separator {{NbLines 1}} {

   insert_fill_lines "#" $NbLines

}

########################################################################
########################################################################
# Définition de quelques proc par défaut qui pouront être redéfinies
# suivant le fichier utilisateur, ou les modes
########################################################################
########################################################################


## stead --  lancement de **ce** stead
# 
proc stead {args} {
    global stead
    # set cmd [concat "exec $stead(exe)" $args]
    # On lance CE wish avec CE stead
    set cmd [concat "exec [info name] $stead(exe)" $args]
    eval $cmd &
}
## stead83 -- set env(STEAD_WISH) "wish8.3" puis apple la procédure stead
# 
proc stead83 {args} {
    global stead
    global env 
    set env(STEAD_WISH) "wish8.3"
    eval stead $args &
}

## stead:makeAllTraces --
# 
# Création de traces sur certaines variables
# 
# Deux objets différents :
# 
# 1 - Verrues permettant de continuer à utiliser d'anciennes globales
#     (à virer dés que possible
#           FILENAME  pour stead(file)
#           MODE      pour stead(mode)
# 
# 2 - abbreviation pratique pour les variables tres courantes utilisables
#     par l'utilisateur dans les macros :
# 
#         global F ;# nom du Fichier édité
#         global D ;# répertoire du fichier édité
#         global S ;# la Selection
#         global T = w = W ;# le widget .main.t
#         global X ;# répertoire d'installation de stead : $stead(install)
#         global C ;# le Clipboard
#         global U ;# un entier incrémenté avant chaque lectuer (Uniq Id)
# 
proc stead:makeAllTraces {} {


    global stead

    ########################################################################
    # Création de quelques "alias" trace sur quelques globales :
    
    # F et FILENAME sont synomyme de stead(file) 
    # (le nom du fichier en cours d'edition)
    # 
    # Supprimer la variable FILENAME quand elle ne sera plus utilisée
    # (ATTENTION : elle utilisée PARTOUT ! !) :
    # 
    uplevel #0 {upvar #0 stead(file) FILENAME}
    uplevel #0 {upvar #0 stead(file) F}
    
    # Creer une variable D correspondant au répertoire de FILENAME
    # # # global D
    uplevel #0 {
        trace variable D rwu trace-D
        proc trace-D {name1 name2 op} {
           global stead D
           switch $op {
               r {set D [file dirname $stead(file) ]}
               w {set D [file dirname $stead(file) ]}
               u {set D [file dirname $stead(file) ]}
           }
        }
    }
    
    # Creer une variable U contenant contenant un entier unique chaque
    # fois quelle est lu (par appel à xtcl_uid) :
    uplevel #0 {
        trace variable U rwu trace-U
        proc trace-U {name1 name2 op} {
           global U
           switch $op {
           r {set U [xtcl_uid]}
           w {set U [xtcl_uid]}
           u {set U [xtcl_uid]}
           }
        }
    }
    
    # X synonyme de stead(install) (répertoire de stead) : utilité : > cd $X
    uplevel #0 {upvar #0 stead(install) X}
    
    # C synonyme de CUTBUFFER (Presse-papier) : utilité : > set C1 $C
    uplevel #0 {upvar #0 xtext(buf,clip,data) C}
    
    # Creer une variable S contenant la selection chaque fois quelle est lue :
    uplevel #0 {
        trace variable S rwu trace-S
        proc trace-S {name1 name2 op} {
           global S stead
           switch $op {
               r {set S [xtext_getSel $stead(text)]}
               w {set S [xtext_getSel $stead(text)]}
               u {set S [xtext_getSel $stead(text)]}
           }
        }
    }
    
    # Met à jour les indicateurs de stead en fonction de l'état modifié ou 
    # non du widget text :
    # - "!" devant le titre de la fenetre si "dirty"
    # - le bouton rouge (en bas à gauche) est mis à jour automatique
    #    par la variable 
    # 
    uplevel #0 {
        trace variable xtext(.main.t,modified) w trace-updateModifiedState
        proc trace-updateModifiedState {name1 name2 op} {
           global xtext
           
           # On extrait le nom du widget text (par exemple .main.t)
           regexp ^(.*),modified $name2 foo w
           # La toplevel (sera utiles quand stead sera multidocument)
           set top .
           
           set cleanTitle [string trimleft [wm title $top] !]
           set cleanIconName [string trimleft [wm title $top] !]
           
           if {[xtext_isDirty $w]} {
               wm title $top "!$cleanTitle"
               wm iconname $top "!cleanIconName"
           } else {
               wm title $top "$cleanTitle"
               wm iconname $top "cleanIconName"
           }
           
        }
    }
    
    # Met à jour les menus concernant le undo lorsque qu'on inhibe ou
    # valide la fonctionnalité du undo :
    # 
    uplevel #0 {
        trace variable EDITPREFS(undoable) w trace-updateUndoMenu
        proc trace-updateUndoMenu {name1 name2 op} {
           global xtext 
           global EDITPREFS 
           
           # modif diam 30/11/2004 
           # car bug car le undo n'est plus débraillable au menu !
           # if {$EDITPREFS(undoable)} {
           #       .menu.edit.m entryconfigure {Undo} -state normal
           #       .menu.edit.m entryconfigure {Redo} -state normal
           #       .menu.edit.m.undo entryconfigure "Enable Undoing" \
           #             -label "Disable Undoing"
           # } else {
           #       .menu.edit.m entryconfigure {Undo} -state disabled
           #       .menu.edit.m entryconfigure {Redo} -state disabled
           #       .menu.edit.m.undo entryconfigure "Disable Undoing" \
           #             -label "Enable Undoing"
           # }
        }
    }
    
    # Creer une trace pour affecter MODE chaque fois que stead(mode) est 
    # affecté puis supprimer la variable MODE quand elle ne sera 
    # plus utilisée (ATTENTION : tous les modes en font appel !) :
    # 
    uplevel #0 {upvar #0 stead(mode) MODE}
    
    # À partir de tk 8.4, les variables et procédures privées de Tk ont 
    # été déplacées dans le namespace Tk
    # Le tableau tkPriv ainsi que les commandes de Tk seront (à termee)
    # intégrées à stead
    if {[info tclversion] >= 8.4} {
        uplevel #0 {upvar #0 ::tk::Priv tkPriv}
        interp alias  {} tkButtonInvoke  {} ::tk::ButtonInvoke
    }
    
    
    # Le widget text 
    uplevel #0 {set T .main.t}
    uplevel #0 {set w .main.t}
    
}
# ./


