#f matlab-mode.tcl - mode for editing matlab code
# 
# 
# Historique 
#   21/10/96 (Marc Aldebert) pleins de choses
#   28/11/01 (Maurice Diamantini) : début de refonte
#   



## mode_matlab_init - 
# 
# 
proc mode_matlab_init {} {
    global stead
    global EDITPREFS
    
    # définit le préfixe pour le mode matlab (pour mettre en commentaires)
    set EDITPREFS(prefix) "% "
    
    
    # Une liste de fichier fréquement éditer (à personaliser par l'utilisateur)
    # On peut utiliser les métacaracteres ou les variables d'environnement)
    set stead(mode,matlab,favorFiles) {
        $::env(MY_PROJECT)/matlab/iterpenduleps.m
        ~/matlab/iteration/principal2.m
    }
    
    ########################################################################
    # Gestion de la Balance
    ########################################################################
    
    # Definition de patterns pour la balance
    global OpenSymbol CloseSymbol OpenList CloseList
    # source "~aldebert/.tk/stead/newbalance.tcl"
    
    ########################################################################
    # L'utilisateur definit ses mots cles sous la forme 
    # {Mot Cle ouvrant - Mot Cle fermant correspondant}
    # Deux listes distinctes (ouvrants et fermants) sont ensuite generees
    # On genere egalement deux listes de patterns a matcher pendant la 
    # recherche. Les prefixes ou suffixes sont a choisir par l'utilisateur
    # en respectant la forme ci-dessous (quote et parentheses essentiels).
    # Attention aux expressions du type "begin(" ou une parenthese peut )
    # etre collee a un mot cle. Si de telles expressions existent dans le 
    # langage concerne, il faut en tenir compte dans le prefixe ou suffixe.
    
    
    set PrefKey {"(^|\n| |;|\t|,)}
    set SuffKey {(\n| |;|,|\t)"}
    set ListPairKey {
        {for   end}
        {begin end}
        {if    end}
        {while end}
    }
    
    set ListKeyOpen {}
    set ListKeyClose {}
    foreach pair $ListPairKey {
       lappend  ListKeyOpen   [lindex $pair 0]
       lappend  ListKeyClose [lindex $pair 1]
    }
    
    set PatKeyOpen "${PrefKey}([join $ListKeyOpen |])$SuffKey"
    set PatKeyClose "${PrefKey}([join $ListKeyClose |])$SuffKey"
    
    
    # A priori les parentheses ouvrantes et fermantes sont independantes
    # du langage. Quand on a une parenthese ouvrante, on doit trouver
    # une fermante. Le choix n'est donc pas laisse a l'utilisateur comme
    # pour les mots cles.
    
    set ListBraceOpen {\{ \( \[}
    set ListBraceClose {\} \) \]}
    set PatBraceOpen {{(^|[^\])(\{|\(|\[)}}
    set PatBraceClose {{(^|[^\])(\}|\)|\])}}
    
    # On regroupe enfin les symboles ouvrants ensemble et les fermants aussi
    set OpenSymbol "$PatKeyOpen $PatBraceOpen"
    set CloseSymbol "$PatKeyClose $PatBraceClose"
    set OpenList [list $ListKeyOpen $ListBraceOpen]
    set CloseList [list $ListKeyClose $ListBraceClose]
    
    bind .main.t <Meta-B> {
        Balance_KeywordPairs .main.t $OpenSymbol $OpenList \
                                     $CloseSymbol $CloseList
    }
}

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

  set help {\

    Aide du mode Matlab :  CE QUI SUIT EST OBSOLÈTE !

    Colorisation :
    -------------
    Mots mots-clés important    Rouge
    Structure (if,then,...)     Bleu
    Commentaires                Vert
    
    Abbréviation statiques : 
    ------------------------
    Taper l'abrév. suivis de <Meta-Espace>, 
    
        be  --> Bloc begin end
        wh  --> Bloc while
        for --> Bloc for
        if  --> Bloc if
        ife --> Bloc if else
        
    A l'intérieur de ces structures <Control-j> permet de sauter d'une
    marque à l'autre. 
    
    Raccourcis claviers : (à compléter)
    ---------------------

    Balance des structures :  (INHIBER POUR L'INSTANT (refonte en cours)
    ------------------------
    Un appui sur <Meta-Shift-B> active la balance (recherche de la
    structure du type ( ), begin end, { }, ...) qui entoure la
    selection ou le point d'insertion. C'est un peu lent pour le
    moment... 
  }
  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_matlab_defineSabbrev - définit les alias static pour ce mode
# 
proc mode_matlab_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
    
    electricAlias-def ${M}matlab be    {begin\n[i]${M}\nend\n${M}}
    electricAlias-def ${M}matlab wh    {while ${M},\n${M}\nend;\n}
    electricAlias-def ${M}matlab for   {for ${M}\n[i]\nend\n${M}}
    electricAlias-def ${M}matlab ife   {if ${M}\n[i]${M}\nelse\n[i]${M}\nend\n}
    electricAlias-def ${M}matlab if    {if ${M}\n[i]${M}\nend\n}
                      
}

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

    # Style quote  : guillemets "doubles" ou 'simples'
    xtext_style $w define matlab quote {
        -type regexpLine
        -config {-foreground #700}
        -pat {(".*?"|'.*?')}
    }
 
    # Style comment  : commentaire : ligne débutant par %
    xtext_style $w define matlab comment {
        -type regexpLine
        -config {-foreground #060}
        -pat {(%.*)}
    }
 
    xtext_style $w enable matlab

}

## te:mode:navig_sort_hook - rédéfinition de l'ordre de tri pour la navigation
# 
# list inchangée => par ordre alphabetique
# 
proc te:mode:navig_sort_hook {list} {
    # Exemple : tri les marques
    # return [lsort -command te:mode:sort_command $list]
    
    # Exemple : tri par ordre alphabetique
    return 
}


## mode_matlab_defineMenu_Matlab - défini le menu principale de matlab
# 
# 
proc mode_matlab_defineMenu_Matlab {} {
    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 Matlab} \
            -command {mode_matlab_execMatlab}
            
              
    $m add separator
    $m add command \
            -label "Aide du mode Matlab"  \
            -command [list stead -readonly 1 -text [mode_matlab_getHelp] ]
    
    ## Sous menu pour les fichiers modèles de ce mode
    $m add cascade \
            -label {Fichiers modèles}  \
            -menu "$m.files"
          
    menu $m.files
    foreach file [glob -nocomplain  $stead(mode,matlab,favorFiles)] {
        $m.files add command \
             -label $file \
             -command "stead $file"
    }
    
            
    ## Sous menu pour les fichiers Matlab du répertoire courant
    menu:makeEditSubmenuFromDirectory2  $m.files $m.files.[xtcl_uid]  \
           "répertoire courant"  \
          [file dirname $stead(file)]/*.m 
    
    
       
    # $m add cascade \
    #         -label {Fichiers Matlab du répertoire courant} \
    #         -menu "$m.currentfiles"
    # menu $m.currentfiles
    # set alphaliste [lsort $FILELIST]
    # foreach {file} $alphaliste {
    #     $m.currentfiles add command \
    #         -label $file \
    #         -command [list stead [file dirname $FILENAME]/$file.m &]
    # }
}

## mode_matlab_defineMenu_Templates - défini le menu Templates de matlab
# 
# 
proc mode_matlab_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
    # .menu.templates.m add command -label {process} \
                                    -command {electricAlias-wrap process}
                                    
    
    $m add cascade -label Alias -menu $m.alias
    menu $m.alias
    foreach alias [electricAlias-softNames] {
        set tmp [string index $alias 0]
        if {$tmp == [string toupper $tmp]} {
            $m.alias add command \
              -label $alias \
              -command "electricAlias-insert $stead(text) [te:no_interp $alias]"
        }
    }
}

## mode_matlab_execMatlab -
# 
# Lancement de Matlab depuis le répertoire contenant le fichier :
# cette procedure lance Matlab dans le repertoire du fichier edite
# 
proc mode_matlab_execMatlab {} {
    global stead    
    # set dir [file dirname $stead(file)]
    # cd $dir
    return [exec xterm -e matlab &]
}

   

## stead:modeStart_matlab - lancement du mode matlab
# 
# 
proc stead:modeStart_matlab {} {
    mode_matlab_init
    
    mode_matlab_defineMenu_Matlab
    mode_matlab_defineMenu_Templates
    mode_matlab_defineSabbrev
    mode_matlab_defineStyles
}

## stead:modeQuit_matlab -- nettoyage en cas de changement de mode
# 
proc stead:modeQuit_matlab {} {
    global stead
    upvar #0 stead(text) w
    
    te:mode:destroy_menu $stead(mode)
    te:mode:destroy_menu templates
    xtext_style $w delete $stead(mode)
} 
## Cette procédure est appelé automatiquement (sera refondu)
proc stead:modeCleanup {} {
    stead:modeQuit_matlab
}

# Ceci sera géré automatiquement par stead (via auto_load)
stead:modeStart_matlab
#./
