# make-mode.tcl - mode for editing make code
# 
# modif :
# 04/05/95 (Maurice DIAMANTINI diam@ensta.fr)
# 13/01/97 (diam) refonte
# 
###########################################################################
global stead

## mode_make_init --
# 
proc mode_make_init {} {

    global stead
    global EDITPREFS 
    global TE_MODE_SEARCH_STRING TE_MODE_NAVIG_SHOW_TEXT
    
    if [info exists stead(file)] {
        set stead(fileToCompile) $stead(file)
    } else {
        set stead(fileToCompile) ""
    }
   
    
    # Quelques préférences globales :
    set EDITPREFS(autobreak)     0
    set EDITPREFS(autoindent)    1          ;# Force l'auto indent
    
    # define the prefix for c mode
    set EDITPREFS(prefix) "# "
    
    # cette variable contient une liste de fichiers à éditer dans ce mode
    if ![info exists stead(modeMAKE,sampleFiles)] {
        set stead(modeMAKE,sampleFiles) {
           /insert/here/you/favorite/list/of
           /Makefile/modeles
           see_file_make-mode.tcl_in_stead_library
        }
    }
   
    # La chaine d'indentation doit nécessairement être le caractère <Tab>
    set EDITPREFS(indent_string) "\t"
   
    # chaine de recherche (utilisé pour le générer le menu de navigation) :
    # set t1 "(\n\[ \t\]*\[-\._A-Za-z0-9\]*)"
    # set t2 "\[ \t\]*:"
    # set TE_MODE_SEARCH_STRING $t1$t2

    set TE_MODE_SEARCH_STRING {(\n\s*[-\._A-Za-z0-9]*)\s*:}
    
    set TE_MODE_NAVIG_SHOW_TEXT "labels" ;# nom de menu de navigation
    
} ;# endproc mode_make_init


########################################################################
# procédure de définition des couleurs des couleurs
########################################################################
proc mode_make_defineStyles {} {
    global stead
    upvar #0 stead(text) w
    
    # style "label"  définit les labels (doit etre en debut de ligne)
    # On veut trouver :
    #   $(PROJ).dvi: 
    # Mais pas :
    #   TEXINPUTS := $(TEXINPUTS):$(TEX_PATH)
    #   
    xtext_style $w define make label {
        -type regexpLine
        -config {-foreground red}
        -pat {^([-\(\)\$\.%/ \w\d]+)\s*:(?!=)}
    }
    
    # Style affect : commence une ligne jusqu'au signe "=" ; le début
    # d'une ligne est soit précédé d'un \n, soit en début du fichier (^)
    xtext_style $w define make affect {
        -type regexpLine
        -config {-foreground blue}
        -pat {^([-\(\)\$\.\w\d]+)\s*(?:=|:=)}
    }
    
    # Style keyword  : quelques mots clés connu de make
    # Une affectation commence une ligne jusqu'au signe "=" ; le début
    # d'une ligne est soit précédé d'un \n, soit en début du fichier (^)
    xtext_style $w define make keyword {
        -type wordList
        -config {-foreground blue}
        -prePat {^}
        -postPat {\M}
        -values {
            define endef ifdef ifndef ifeq ifneq else endif include override
            export vpath
        }
    }
    
    # Style sdQuote  : guillemets "doubles" ou 'simples'
    # 
    xtext_style $w define make sdQuotes {
        -type regexpLine
        -config {-foreground #700}
        -pat {(".*?"|'.*?')}
    }
 
    # Style odQuote  : guillemets "doubles" ophelines sur une ligne
    # 
    xtext_style $w define make orphQuotes {
        -type regexpLine
        -config {-foreground red -font bold}
        -pat {^(?:[^"]*)(")(?:[^"]*)$}
    }
    # Style makeVar  : variables prédéfinies de make
    xtext_style $w define make makeVar {
        -type wordList
        -config {-foreground DarkViolet}
        -values {
            MAKE VPATH MAKEFILES SHELL MAKESHELL MAKELEVEL MAKEFLAGS
            MAKECMDGOALS SUFFIXES CXX CPP CC OBJECTS 
            DEFS CFLAGS CPPFLAGS LDFLAGS LIBS 
            prefix
        }
    }
 
    # Style specChar  : variables spéciale prédéfinies par make
    xtext_style $w define make specChar1 {
        -type regexpLine
        -config {-foreground DarkViolet}
        -pat {(\$|(?:\t)@)}
    }
    xtext_style $w define make specChar2 {
        -type regexpLine
        -config {-foreground DarkViolet}
        -pat {(?:^\S.*)(%)}
    }
    xtext_style $w define make lastBS {
        -type regexpLight
        -config {-foreground red -font bold}
        -pat {\B$}
    }
 
    # Style specVar  : variables spéciales prédéfinies par make : $@ , $(?D) ...
    xtext_style $w define make specVar {
        -type regexpLight
        -config {-foreground blue}
        -pat {\$(@|%|<|\^|\+|\*|(\([@\*%<\^\+\?][DF]\)))}
    }
 
    # Style comment  : commentaire type shell #xxx
    xtext_style $w define make comment {
        -type regexpLine
        -config {-foreground #060}
        -pat {(#.*)}
    }
 
    # Style error1  : espace en début de ligne
    xtext_style $w define make error1 {
        -type regexpLight
        -config {-background #FAA}
        -pat {(^ +)}
    }
    # Style error2  : espace apres un backslash en fin de ligne
    xtext_style $w define make error2 {
        -type regexpLight
        -config {-background #FAA}
        -pat {(\B\s+)$}
    }
 
    xtext_style $w enable make
}

## make_GetHelp - aide sur le mode make
# 
# 
proc make_GetHelp {} {
    set help {
      aide du mode Make :
      
      Les electric alias sont des raccourcis qu'on peut lancer en tapant 
      l'abbreviation suivie de <Meta-Space>
      La liste complète de ces abbréviation est définie dans le sous-menu 
      "alias" du menu Template.
      
      Quelques exemples d'alias prédéfinis :
        clean          "clean: ... /bin/rm *.o"
      
      Le menu "Template" propose quelques macros prédéfinies. Vous pouvez
      en rajouter d'autres dans le fichier de mode utilisateur (voir menu
      "Help/xxx") 
      
      
      Le menu "Labels" permet d'accéder rapidement au etiquettes  
      du fichier.
      
      raccourci clavier      résultat
      ^^^^^^^^^^^^^^^^^      ^^^^^^^^
      <meta-1>               insertion d'un séparateur "c-----..."
      <Control-c>            rafrechit les couleurs
      
    }
    return $help
} 

## mode_make_defineSabbrev -- alias statique du mode Make
# 
# 
proc mode_make_defineSabbrev {} {

    global stead 
    
    # 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}$stead(mode) ${M}$stead(mode) ${M}$stead(mode)
    
    electricAlias-var $stead(mode) bb "\{" ;# Begin Bloc
    electricAlias-var $stead(mode) eb "\}" ;# End Bloc
    electricAlias-def ${M}$stead(mode) \{  "$V{bb}\n${B}i${E}$M\n$V{eb}$M"
    electricAlias-def ${M}$stead(mode) do  \
         "do $V{bb}\n${B}i${E}$M\n$V{eb} while ($M);$M"
   
    electricAlias-def ${M}$stead(mode) clean  "clean:\n\t/bin/rm *.o"
 
}

## mode_make_defineMenu_make -
# 
# 
proc mode_make_defineMenu_make {} {
global stead 

    te:mode:make_menu $stead(mode)
    
    
    .menu.$stead(mode).m add command -label {Refresh Colors} \
       -command {refresh_colors} \
       -accelerator {<Control-c>}
    .menu.$stead(mode).m add command -label {Cancel Colors} \
       -command {cancel_colors}
    .menu.$stead(mode).m add separator
    
    .menu.$stead(mode).m add separator
    .menu.$stead(mode).m add command -label "Aide du mode $stead(mode)"  \
       -command {stead  -r 1 -text [make_GetHelp] }  
    
    # Edition des fichier d'exemples
    .menu.$stead(mode).m add cascade -label {Files sample}  \
       -menu ".menu.$stead(mode).m.files"
    menu .menu.$stead(mode).m.files
    foreach {file} $stead(modeMAKE,sampleFiles) {
       .menu.$stead(mode).m.files add command -label $file \
          -command "exec $stead(exe) $file &"
    }
    
    
}    
    
## mode_make_defineMenu_templates - Création et remplissage de menu template
# 
# 
proc mode_make_defineMenu_templates {} {
global stead 

    te:mode:make_menu {templates}
    
    .menu.templates.m add command -label "Insérer un separateur" \
                          -command {separator 1}
    
    .menu.templates.m add separator
    
    .menu.templates.m add command -label {clean macro} \
                                    -command {electricAlias-wrap clean}
    
    .menu.templates.m add separator
                                    
    
    .menu.templates.m add cascade -label Alias -menu .menu.templates.m.alias
    menu .menu.templates.m.alias
    foreach alias [electricAlias-softNames] {
       .menu.templates.m.alias add command -label $alias \
       -command "electricAlias-insert $stead(text) [te:no_interp $alias]"
    }
}  

## separator {{NbLines 1}}
# 
# 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 
} 

## tri des procedures pour la navigation par ordre alphabetique
#
proc te:mode:navig_sort_hook {l} {
    return [lsort -command te:mode:sort_command $l]
}


## stead:modeStart_tcl - lancement du mode tcl
# 
# 
proc stead:modeStart_make {} {
    mode_make_init
    mode_make_defineSabbrev
    mode_make_defineMenu_make
    mode_make_defineMenu_templates
    mode_make_defineStyles
}
## stead:modeCleanup -
# 
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)
} 
stead:modeStart_make
#./
