#f scilab-mode.tcl - mode for editing scilab code
# 
# Historique 
#   28/11/01 (Maurice Diamantini) : premier version, histoire de commencer 
#          quelque chose
#   



## mode_scilab_init - 
# 
# 
proc mode_scilab_init {} {
    global stead
    global EDITPREFS
    
    # définit le préfixe pour le mode scilab (pour mettre en commentaires)
    set EDITPREFS(prefix) "// "
    
    
    # Une liste de fichiers fréquemment édités (à personaliser par 
    # l'utilisateur)
    # On peut utiliser les métacaracteres ou les variables d'environnement)
    set stead(mode,scilab,favorFiles) [list   \
       file  "LISTE A COMPLETER"   fichierBidon.sci                          \
       file  "Mon .cshrc"    $::env(HOME)/.cshrc                             \
       sep   -----------     ----------------------                          \
       file  lmiSolver.sci   \
                 $::stead(install)/adm/modes_exemples/scilab_lmisolver.sci   \
       dir   modes_exemples/*    $::stead(install)/adm/modes_exemples/*      \
    ]       
    
    ####################################################################
    # 
    # Ce qui suit sera refondu !
    # 
    # Définition du menu de navigation A REFONDRE
    # 
    set ::TE_MODE_SEARCH_STRING    {\s*function\s+[^=]+=([^\n]*)}
    set ::TE_MODE_NAVIG_SHOW_TEXT  "function"
      
    proc te:mode:navig_sort_hook {list} {
        # Exemple : tri par ordre alphabetique
        return [lsort -command te:mode:sort_command $list]
        
        # Exemple : aucun tri (pour conserver l'ordre d'apparition)
        # return  $list
    }

}

## mode_scilab_getHelp - retourne une chaine d'info spécifique au mode Matlab
# 
proc mode_scilab_getHelp {} { 

  set help {\

    (Début d')Aide du mode Scilab : 

    Colorisation :
    -------------
    Mots mots-clés important    Rouge
    Structure (if,then,...)     Bleu
    Commentaires                Vert
    
    Abbréviation statiques : 
    ------------------------
    Taper l'abrév. suivis de <Meta-Espace>, 
        
        f ou funct  =>     bloc function (interactif)
        wh ou w     =>     Bloc while
        for         =>     Bloc for
        if          =>     Bloc if..end
        ife         =>     Bloc if..else..end
        
    A l'intérieur de ces structures <Control-j> permet de sauter d'une
    marque à l'autre. 
    
    Remarques : une sélection de ces abbréviation est disponible via le 
    menu "Templates/alias=>"
    
    Raccourcis claviers : (à compléter)
    ---------------------

  }
  return $help

}

## separator - insère une N lignes de caractères de séparation
# 
# Insère "Nblines" lignes (défaut : 1) correspondant au separateur 
# souhaité ;
# Cette procédure est automatiquement liée à <Meta-1>
# 
proc separator {{NbLines 1} } {
    insert_fill_lines "/" $NbLines 
} 

## mode_scilab_defineSabbrev - définit les alias static pour ce mode
# 
proc mode_scilab_defineSabbrev {} {

    # pour simplifier l'ecriture des electric-alias en déclarant :
    #    M : Marque temporaire
    #    B : début de postcommande 
    #    E : fin de postcommande
    #    V : Inclusion d'une variable TCL
    electricAlias-use8bitsCars
    
    # Convention (en attendant mieux) : une abbréviation statique
    # dont le nom se termine par le caractere "_" apparaitra dans le menu
    # "Templates/alias"
    
    # # # electricAlias-def ${M}scilab be    {begin\n${M}\nend\n${M}}
    # # # electricAlias-def ${M}scilab wh    {while ${M},\n${M}\nend\n}
    # # # electricAlias-def ${M}scilab for   {for ${M},\n\nend;\n${M}}
    # # # electricAlias-def ${M}scilab ife   {if ${M}\n${M}\nelse\n${M}\nend\n}
    # # # electricAlias-def ${M}scilab if    {if ${M}\n${M}\nend\n}
    
    set    tmp {while [setStop]\n}
    append tmp {[i][setStop]\n}
    append tmp {end\n}
    append tmp {[setStop]}
    electricAlias-def ${M}scilab w           $tmp
    electricAlias-def ${M}scilab wh          $tmp
    electricAlias-def ${M}scilab while       $tmp
    electricAlias-def ${M}scilab while..end_ $tmp
    
    set    tmp {for [setStop]\n}
    append tmp {[i][setStop]\n}
    append tmp {end\n}
    append tmp {[setStop]}
    electricAlias-def ${M}scilab fo        $tmp
    electricAlias-def ${M}scilab for       $tmp
    electricAlias-def ${M}scilab for..end_ $tmp
    
    set    tmp {if [setStop] then \n}
    append tmp {[i][setStop]\n}
    append tmp {end\n}
    append tmp {[setStop]}
    electricAlias-def ${M}scilab if       $tmp
    electricAlias-def ${M}scilab if..end_ $tmp
    
    set    tmp {if [setStop] then\n}
    append tmp {[i][setStop]\n}
    append tmp {else\n}
    append tmp {[i][setStop]\n}
    append tmp {end\n}
    append tmp {[setStop]}
    electricAlias-def ${M}scilab ife       $tmp
    electricAlias-def ${M}scilab if..else..end_ $tmp
    
    set    tmp {[askVar "Function name" NAME]}
    append tmp {/// [getVar NAME] -- [setStop]\n}
    append tmp {// \n}
    append tmp {// \n}
    append tmp {function \[ [setStop] \] = [getVar NAME] ([setStop])\n}
    append tmp {[i][setStop]}
    append tmp {\n}
    append tmp {// end [getVar NAME]()}
    append tmp {\n[setStop]}
    electricAlias-def ${M}scilab fu $tmp
    electricAlias-def ${M}scilab func $tmp
    electricAlias-def ${M}scilab function_ $tmp
    
    set   tmp {\[[setStop]\] = [setStop]([setStop]);\n[setStop]}
    electricAlias-def ${M}scilab  =          $tmp
    electricAlias-def ${M}scilab {affect_}   $tmp
                      
}

## mode_scilab_defineStyles - 
# 
proc mode_scilab_defineStyles {} {
    
    global stead
    upvar #0 stead(text) w
    
    # On commence par supprimer tout style précédent de la feuille "scilab"
    xtext_style $w delete scilab
    
    
    # "keylist1"  définit une patterne de reconnaissance des mots clé 
    # "important" (i.e. modif de structure et autre...)
    # 
    xtext_style $w define scilab keylist1 {
        -type wordList
        -config {-foreground red}
        -prePat {(?:^|;|,)(?:\s*)}
        -prePat {\m}
        -postPat {\M}
        -values {
            error break return clear
        }
    }
    
    # "keylist2"  reconnaissance des mots clé  "courants" du langage :
    # 
    xtext_style $w define scilab keylist2 {
        -type wordList
        -config {-foreground blue}
        -prePat {(?:^|;|,)(?:\s*)\m}
        -prePat {\m}
        -postPat {\M}
        -values {
            if then else elseif while for begin end
            select case
            "echo\s+on" "echo\s+off"
            type
        }
    }

    # "functs"  définit une patterne pour les functions courantes :
    # 
    xtext_style $w define scilab functs  {
        -type regexpLine
        -config {-foreground #008}
        -pat {\m([\w\d_]+)(?:\s*\()}
    }
    # "functs"  pour les parentheses (souvent liées aux functions)
    # 
    xtext_style $w define scilab parenth  {
        -type regexpLight
        -type regexpLine
        -config {-foreground #008}
        -pat {([\(\)])}
    }

    # "number"  un nombre dans scilab :
    # 
    xtext_style $w define scilab number  {
        -type regexpLine
        -config {-foreground #008 -background #FFFFDD}
        -pat {(?:\W)(([-+])?\d+(\.\d+([eE]-?\d+(\.\d*)?)?)?)\y}
    }


    # Style quote  : guillemets "doubles" ou 'simples'
    # 
    xtext_style $w define scilab quote {
        -type regexpLine
        -config {-foreground #700}
        -pat {(".*?"|'.*?')}
    }
    
    # specChars : quelques caractères spéciaux
    # 
    xtext_style $w define scilab specChars {
        -type regexpLight
        -config {-foreground magenta4}
        -pat {([=,;%<>])}
    }
    
    
 
    # "function"  déclaration de fonctions
    # 
    xtext_style $w define scilab function {
        -type regexpLine
        -config {-foreground red  -background yellow}
        -pat {^\s*(function\s*.*)$}
    }
    
    # Style comment  : Tout ce qui suit "//"
    xtext_style $w define scilab comment {
        -type regexpLine
        -config {-foreground #060}
        -pat {(//.*)}
    }
 
    xtext_style $w enable scilab

}


## mode_scilab_defineMenu_Scilab - défini le menu principale de scilab
# 
# 
proc mode_scilab_defineMenu_Scilab {} {
    global stead
    
    set menubutton  .menu.$stead(mode)
    set m           .menu.$stead(mode).m
    
    if {[winfo exists $menubutton]} {
        destroy $menubutton
    }
    # Création d'un bouton de menu (ce qu'on voit)
    menubutton $menubutton \
            -text [string totitle $stead(mode)] \
            -menu .menu.$stead(mode).m
            
    # On positionne ce bouton
    pack append .menu $menubutton left
  
    # Création d'un menu (ce qui ce déroule quand on clique sur le menubutton)
    set m [menu $m]
    
    $m add command \
            -label {Lancer Scilab} \
            -command {mode_scilab_execScilab}
            
    $m add separator
    $m add command \
            -label {Balance Structure} \
            -state disable \
            -command {StructBalance 
                    $OpenSymbol $OpenList $CloseSymbol $CloseList} \
            -accelerator {<Meta-B>} 
              
    $m add separator
    $m add command \
            -label "Aide du mode Scilab"  \
            -command [list stead -readonly 1 -text [mode_scilab_getHelp] ]
    
    
    
    ####################################################################
    # Création d'un menu pour éditer les fichiers modèles de ce mode
    menu $m.modeles
    $m add cascade  -label {Fichiers modèles poue le mode Scilab}  \
                    -menu "$m.modeles"
    stead:makeEditMenuFromSpecs $m.modeles $stead(mode,scilab,favorFiles)
    
    
    ## Sous menu pour les fichiers Scilab du répertoire courant
    menu:makeEditSubmenuFromDirectory2  $m $m.[xtcl_uid]  \
           "Fichier scilab du répertoire courant"  \
           [file dirname $stead(file)]/*.sci
    
}

## mode_scilab_defineMenu_Templates - défini le menu Templates de scilab
# 
# 
proc mode_scilab_defineMenu_Templates {} {
    global stead
    
    set menubutton  .menu.template
    set m           .menu.template.m
    
    if {[winfo exists $menubutton]} {
        destroy $menubutton
    }
    # Création d'un bouton de menu (ce qu'on voit)
    menubutton $menubutton \
            -text Templates \
            -menu $m
            
    # On positionne ce bouton
    pack append .menu $menubutton left
  
    # Création d'un menu (ce qui ce déroule quand on clique sur le menubutton)
    set m [menu $m]

    $m add command \
            -label "Insérer un separateur \"%%%...\"" \
            -command {separator 1}
    
    $m add separator
                                    
    
    $m add cascade -label Alias -menu $m.alias
    menu $m.alias
    foreach alias [electricAlias-softNames] {
        # on peut ne retenir QUE les alias finissant par "_"
        if {[string match *_ $alias]} {
            $m.alias add command \
                 -label $alias \
                 -command "electricAlias-insert $stead(text)  $alias"
        }
    }     
}

## mode_scilab_execScilab - lancement de Scilab 
# 
# cette procedure lance scilab dans le repertoire du fichier edite
# 
proc mode_scilab_execScilab {} {
    global stead    
    set dir [file dirname $stead(file)]
    cd $dir
    return [exec xterm -e scilab &]
}

   

## stead:modeStart_scilab - lancement du mode scilab
# 
# 
proc stead:modeStart_scilab {} {
    mode_scilab_init
    mode_scilab_defineSabbrev
    mode_scilab_defineMenu_Scilab
    mode_scilab_defineMenu_Templates
    mode_scilab_defineStyles
}

## stead:modeCleanup -- nettoyage en cas de changement de mode
# 
proc stead:modeCleanup {} {
    global stead
    upvar #0 stead(text) w
    te:mode:destroy_menu $stead(mode)
    te:mode:destroy_menu templates
    xtext_style $w delete $stead(mode)
} 

# Ceci sera gérer automatique par stead (via auto_load)
stead:modeStart_scilab
#./
