;; -*- emacs-lisp -*-
;;
;; ===========================================================================
;;
;; Fichier ~/.emacs (fichier de configuration d'Emacs)
;; Copyright (C) 2002-2009 Sébastien Dinot <sebastien.dinot@free.fr>
;; Dernière modification : 2009-08-27 23:14
;;
;; ===========================================================================
;;
;; Quelques commandes bien utiles que j'ai tendance à oublier à cause des
;; raccourcis que je définis :
;;
;; C-_ :
;;   Annulation de la dernière commande exécutée
;; C-x k :
;;   Clore un tampon d'édition (par défaut, le courant)
;; C-x C-right arrow :
;;   Passer au tampon d'édition suivant dans la liste
;; C-x C-left arrow :
;;   Passer au tampon d'édition précédent dans la liste
;; C-q <code ascii> RET :
;;   Insertion du caractère dont le code ASCII est indiqué à la suite de la
;;   séquence « C-q ». Par défaut, le code ASCII est exprimé en octal. Par
;;   exemple, pour insérer un espace insécable, dont le code ASCII est (0xa0
;;   en hexa, 160 en décimal et 0240 en octal), il faut taper « C-q 240 RET ».
;;   Pour pouvoir fournir la valeur décimale, il faut modifier la variable
;;   read-quoted-char-radix :
;;   (setq read-quoted-char-radix 10)
;;   Ceci fait, pour insérer le même espace insécable, on tapera désormais
;;   « C-q 160 RET »
;; M-g g <numéro de ligne> RET :
;;   Positionner le curseur sur la ligne <numéro de ligne>.
;; C-M-s :
;;   Recherche d'une expression rationnelle (contrairement à C-s) qui permet
;;   de rechercher une chaîne fixe.
;;
;; Parmi les commandes à utiliser sporadiquement mais précieuses lorsqu'on en
;; a besoin, il y a :
;; M-x flyspell-mode      : suggestions de correction à la volée
;; M-x flyspell-prog-mode : idem mais adapté au développement (l'analyse se
;;                          limite alors aux commentaires et aux chaînes
;;                          littérales).
;; Dans ces modes, lorsque Aspell détecte un mot mal orthographié, pour faire
;; apparaître les suggestions, placer le curseur sur le mot et appuyer sur la
;; combinaison de touches « M-$ ».
;;
;; À connaître dans le mode gdb :
;; - « M-x gdb » : activation du frontal graphique pour GDB (affichage
;;   multi-fenêtré car variable gdb-many-windows mise à 1)
;; - « M-x gdb-restore-windows » : restauration du mode multi-fenêtré après
;;   une bascule temporaire du tampon d'édition du code source pleine fenêtre.
;; - « M-x tool-bar-mode » : le frontal s'accompagne d'une barre d'outils
;;   adaptée qui peut s'avérer pratique.
;;
;; ===========================================================================
;;
;; Mille mercis et toute ma gratitude aux auteurs et contributeurs des sites
;; ci-dessous. Sans eux, ce fichier ne serait pas ce qu'il est :
;;
;; * EmacsWiki (http://www.emacswiki.org/)
;; * Emacs-Fu (http://emacs-fu.blogspot.com/)
;; * Xah Lee (http://xahlee.org/emacs/)
;;
;; ===========================================================================

;; Ajouter mon répertoire personnel à la liste des chemins de recherche des
;; modules.
(if (file-exists-p "~/.emacs.d/plugins")
  (setq load-path (cons (concat "~/.emacs.d/plugins") load-path))
)


;; ===========================================================================
;; Chargement et activation des modes que j'utilise couramment
;; ===========================================================================

;; Mode activant l'affichage des numéros de ligne dans la marge gauche de la
;; fenêtre
(require 'linum)

;; Lorsqu'on ouvre deux fichiers de même nom « fic », Emacs nomme les tampons
;; « fic » et « fic<2> », ce qui ne facilite pas leur identification. Le mode
;; uniquify permet de les distinguer via leur répertoire respectif.
(require 'uniquify)

;; Activer la mise en exergue des espaces superflus ou hétérogènes
(require 'whitespace)

;; Appariement visuel des parenthèses, crochets et accolades
(require 'paren)
(show-paren-mode 1)

;; Chargement du module d'impression Postscript
(require 'ps-print)

;; Mise en sur-brillance de la région sélectionnée
(transient-mark-mode 1)

;; Remplacement de la région sélectionnée par le texte saisi
(delete-selection-mode 1)

;; Sauvegarde d'une session à l'autre de l'historique des commandes et des
;; fichiers ouverts
(savehist-mode 1)

;; Choix de la police de caractères en environnement graphique
(if (eq window-system 'x)
  (progn
    ;; Je préfère voir apparaître le curseur sous la forme d'une barre
    ;; verticale clignotante.
    (bar-cursor-mode 1)
    (blink-cursor-mode 1)

    ;; Le menu est pratique lorsqu'on est en mode graphique mais encombrant et
    ;; moins utile dans une console texte.
    (menu-bar-mode 1)
  )
  ;; Le menu est pratique lorsqu'on est en mode graphique mais encombrant et
  ;; moins utile dans une console texte.
  (menu-bar-mode 0)
)

;; Allez savoir pourquoi, je me sers peu de la souris dans Emacs. (c:
(tool-bar-mode 0)


;; ===========================================================================
;; Initialisation de variables internes aux valeurs non standard
;; ===========================================================================

;; Informations qui peuvent être utiles à Emacs pour remplir certains champs
;; et configurer correctement certains modes.
(setq user-full-name "Sébastien DINOT")
(setq user-mail-address "sebastien.dinot@free.fr")

;; Configuration du mode Uniquify : on affiche la chaîne distinctive après le
;; nom en utilisant l'extrait minimal du chemin nécessaire à l'identification
;; du fichier (on ignore les tampons spéciaux et on supprime ce nommage
;; spécifique lorsque l'ambiguïté n'existe plus).
(setq uniquify-buffer-name-style 'post-forward)
(setq uniquify-after-kill-buffer-p 1)
(setq uniquify-ignore-buffers-re "^\\*")

;; Inhiber l'affichage de l'écran d'accueil au lancement d'Emacs.
(setq inhibit-startup-screen 1)

;; Il est fastidieux de taper « yes » pour confirmer une action, « y » suffit
;; amplement (idem pour « no », désormais « n »)
(defalias 'yes-or-no-p 'y-or-n-p)

;; Les modes historiquement choisis par Emacs lorsqu'on ouvre un fichier ne
;; sont pas toujours les plus satisfaisant. Corrigeons cela...
(defalias 'xml-mode 'nxml-mode)
(defalias 'perl-mode 'cperl-mode)

;; Formatage du texte sur 78 colonnes dans tous les modes
(setq-default fill-column 78)

;; Certains caractères ne sont associés à aucune combinaison de touches du
;; clavier. On peut cependant les désigner par leur code ASCII via la séquence
;; « C-q <code ascii> RET ». Par défaut, Emacs attend un code ASCII en octal
;; mais je connais mieux les valeurs décimales. Autant qu'Emacs s'adapte...
(setq read-quoted-char-radix 10)

;; Variable utilisée pour visualiser les espaces superflus en fin de ligne.
;; Je désactive cette fonctionnalité car elle est prise en compte par le mode
;; whitespace.
(setq-default show-trailing-whitespace nil)

;; Activation globale du mode mettant en exergue des « caractères blancs »
(global-whitespace-mode 1)

;; Choix des éléments mis en exergue :
;; - space      => montrer les espaces (KO car gestion intégrée d'Emacs)
;; - tabs       => montrer les tabulations
;; - trailing   => montrer les espaces superflus en fin de ligne
;; - lines-tail => montrer les lignes trop longues (excédent seulement)
;;
;; On peut en outre déclencher un nettoyage du tampon via la commande
;; « M-x whitespace-cleanup ». Cette commande lancera les actions annoncées
;; dans whitespace-style :
;; - empty            => suppression des lignes vides en début et fin de
;;                       tampon
;; - indentation      => substitution des tabulations de début de ligne par
;;                       des espaces
;; - space-before-tab => substitution des tabulations précédant des espaces
;;                       par des espaces
;; - space-after-tab  => substitution des tabulations suivant des espaces par
;;                       des espaces
;; - trailing         => suppression des espaces et tabulations superflus en
;;                       fin de ligne
;;
;; Le mode whitespace interfère avec la visualisation des espaces insécables
;; intégrée à Emacs (variable nobreak-char-display) et je n'ai pas réussi
;; à imposer à Emacs le paramétrage que j'avais défini au sein du mode
;; whitespace (si une âme charitable a la solution, j'en suis preneur). J'ai
;; donc fini par altérer le paramètre « nobreak-space » qui, dans le mode
;; intégré à Emacs, détermine l'affichage des espaces insécables. Pour ce
;; faire, j'ai eu recours à « custom-set-faces » et pour éviter un double
;; appel de cette fonction (fortement déconseillé), j'ai déporté l'instruction
;; dans le fichier ~/.emacs.d/custom.el. Le voici pour mémoire :
;;
;; (custom-set-faces
;;   '(nobreak-space
;;     (;; Paramétrage si fond foncé et grand nombre de couleurs disponible
;;      (((class color) (min-colors 88) (background dark))
;;       (:background "#483838"       :foreground "black" :underline nil))
;;      ;; Paramétrage si fond clair et grand nombre de couleurs disponible
;;      (((class color) (min-colors 88) (background light))
;;       (:background "LemonChiffon3" :foreground "cornsilk4" :underline nil))
;;      ;; Paramétrage dans les autres cas de figure
;;      (t (:inverse-video t)))))
(setq whitespace-style '(space tabs lines-tail trailing
                         empty indentation space-before-tab space-after-tab)
)

;; Nombre de colonnes au delà duquel on considère qu'une ligne est trop longue
(setq whitespace-line-column 78)

;; Lors de l'enregistrement du tampon :
;; 1. demander s'il faut ajouter un saut de ligne final lorsqu'il est absent,
;; 2. effacer les espaces superflus en fin de ligne,
;; 3. actualiser l'horodate interne,
;; 4. actualiser l'année dans la mention de copyright.
;; NB : La recherche du motif à actualiser avec l'horodate courante
;;      ("Time-stamp: <%%>" par défaut) s'effectue dans les 10 premières
;;      lignes (8 par défaut)
(setq
  time-stamp-active 1
  time-stamp-line-limit 10
  time-stamp-pattern "\\([Ll]ast modified\\|[Dd]erni[eè]re modification\\) *: %04y-%02m-%02d %02H:%02M$"
  time-stamp-format "%04y-%02m-%02d %02H:%02M")
(setq require-final-newline 'query)
(add-hook 'write-file-functions 'delete-trailing-whitespace)
(add-hook 'write-file-functions 'time-stamp)
(add-hook 'write-file-functions 'copyright-update)

;; Lors de la mise en exergue d'une correspondance de parenthèses, surligner
;; seulement les parenthèses (remplacer « parenthesis » par « expression »
;; pour que toute l'expression soit surlignée).
(setq show-paren-style 'parenthesis)

;; Lorsqu'un tampon vide est créé ou lorsqu'Emacs ne parvient pas à identifier
;; le mode adéquat, il bascule dans le mode « lisp-interaction-mode ». Ce
;; choix n'est pas pertinent (pour moi du moins) et je préfère qu'il opte dans
;; ce cas pour le mode texte.
;; Ceci vaut au lancement d'Emacs ...
(setq initial-major-mode 'text-mode)
;; ... et lorsqu'il crée un tampon ou ouvre un fichier de type non reconnu
(setq default-major-mode 'text-mode)

;; Pas de message initial dans le tampon *scratch*
(setq initial-scratch-message "")

;; Faire apparaître la position du curseur dans la ligne modale
(setq column-number-mode 1)
(setq line-number-mode 1)

;; Afficher l'heure dans la barre d'état (format 24 heures)
(display-time)
(setq display-time-24hr-format 1)

;; Ne pas remplacer les espaces par des tabulations
(setq-default indent-tabs-mode nil)

;; Lorsqu'il reformate un paragraphe, Emacs doit respecter les règles de
;; typographie française et ne pas sauter à la ligne avant un signe de
;; ponctuation double ou des guillemets ouvrants.
(setq fill-nobreak-predicate '(fill-french-nobreak-p))

;; Selon les règles typographiques françaises, le point final d'une phrase
;; n'est suivi que d'un seul espace (contre deux dans la tradition
;; anglo-saxonne). Il est utile qu'Emacs le sache pour formater correctement
;; les textes.
(setq sentence-end-double-space nil)

;; Supprimer les fichiers de sauvegarde en quittant (vous savez, ces fameux
;; fichiers dont le nom se termine par « ~ »)
(setq make-backup-files nil)

;; Choix de la police de caractères en environnement graphique
(if (eq window-system 'x)
  (progn
    ;(set-default-font "-*-fixed-medium-r-*-*-*-120-*-*-*-*-iso10646-*")
    ;(set-default-font "Inconsolata-12"))
    (set-default-font "terminus-12")

    ;; Taille par défaut de la fenêtre 100 x 60 caractères. Pour ajouter un
    ;; positionnement (en pixels), il faut saisir la ligne suivante :
    ;(setq initial-frame-alist '((width . 100) (height . 60)))
    (setq initial-frame-alist
          '((top . 1) (left . 1) (width . 100) (height . 45)))

    ;; Personnalisation du curseur
    (set-cursor-color "red")
  )
)

;; Configuration des paramètres d'impression Postscript
(setq ps-paper-type 'a4
      ps-font-family 'Courier
      ps-print-size 10
      ps-print-header t
      ps-landscape-mode nil)
(setq-default ps-header-lines 1)
(setq ps-print-color-p 'black-white)

;; Lorsque le curseur atteint la fin de la fenêtre, le contenu se déplace
;; d'une seule ligne et non d'une demi-fenêtre.
(setq scroll-step 1)

;; Nom français des jours et mois affichés dans le calendrier
;; (cf. M-x calendar)
(setq european-calendar-style t)
(setq calendar-week-start-day 1)
(defvar calendar-day-name-array
  ["dimanche" "lundi" "mardi" "mercredi" "jeudi" "vendredi" "samedi"])
(defvar calendar-day-abbrev-array
  ["dim" "lun" "mar" "mer" "jeu" "ven" "sam"])
(defvar calendar-month-name-array
  ["janvier" "février" "mars" "avril" "mai" "juin"
   "juillet" "août" "septembre" "octobre" "novembre" "décembre"])
(defvar calendar-month-abbrev-array
  ["jan" "fév" "mar" "avr" "mai" "jun"
   "jul" "aoû" "sep" "oct" "nov" "déc"])

;; Lorsqu'une ligne est plus large que la fenêtre d'affichage, je veux
;; qu'Emacs me l'affiche sur autant de lignes que nécessaire plutôt que de
;; masquer la partie qui dépasse à droite de l'écran. Pour que ce comportement
;; vaille en toute circonstance, il est nécessaire de fixer deux variables :
;; - truncate-lines : comportement dans un tampon occupant toute la largeur de
;;   la fenêtre
;; - truncate-partial-width-windows : comportement dans un tampon n'occupant
;;   qu'une fraction de la largeur de la fenêtre (par exemple, après un
;;   découpage horizontal C-x 3).
(setq truncate-lines nil)
(setq truncate-partial-width-windows nil)

;; Le correcteur Aspell est plus lent mais plus pertinent que Ispell. On
;; demande donc à Emacs d'utiliser Aspell dans le mode Ispell, normalement
;; chargé par défaut par Emacs 23.
;; L'option « --sug-mode=fast » demande à Aspell de limiter son analyse pour
;; gagner en vitesse... au détriment de la pertinence. Cette option est utile
;; pour la correction orthographique à la volée (le fonctionnement pouvant
;; être encore accéléré en remplaçant « fast » par « ultra ») mais je préfère
;; la pertinence à la rapidité.
;(setq ispell-extra-args '("--sug-mode=fast"))
(setq ispell-program-name "aspell")
(setq ispell-dictionary "francais")

;; Je préfère que l'outil de personnalisation d'Emacs crée son propre fichier
;; plutôt que d'altérer celui-ci.
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file 'noerror)

;; Activation de la correction à la volée lors de l'édition d'un texte
(add-hook 'text-mode-hook 'flyspell-mode)

;; « Face » (à traduire par « propriétés d'affichage » ?) utilisé pour mettre
;; en exergue des mots-clés qui annoncent une information importante.
(defface special-words
  `((((type tty) (class color))
     (:background "red" :foreground "yellow"))
    (((type tty) (class mono))
     (:inverse-video t))
    (((class color) (background dark))
     (:background "dark red" :foreground "gold" :bold t))
    (((class color) (background light))
     (:background "dark red" :foreground "gold" :bold t))
    (t (:background "red")))
  "Face used for highlighting few words like FIXME, TODO and others, that
points out an important information."
  :group 'basic-faces)

;; Variable utilisée par la fonction de mise en exergue des mots-clés (définie
;; ci-dessous) pour pointer les propriétés d'affichage (définies ci-dessus)
;; à leur appliquer.
(defvar special-words 'special-words)

;; On associe à l'ouverture d'un fichier une fonction (anonyme) qui recherche
;; et met en exergue une liste prédéfinie de mots-clés. Ces mots-clés ne sont
;; signalés que lorsqu'ils sont suivis d'un caractère « : », éventuellement
;; séparé du mot-clé par un ou plusieurs espaces.
(add-hook 'find-file-hooks
  (lambda ()
    (font-lock-add-keywords nil
      '(("\\<\\(FIXME\\|TODO\\|WARNING\\|BUG\\|XXX+\\|NB\\|NOTE\\|ATTENTION\\)[  ]*:"
         1 special-words t))
    )
  )
)


;; ===========================================================================
;; Fonctions spécifiques
;; ===========================================================================

;; Suppression du formatage sur N colonnes (comme la fonction n'existe pas,
;; l'astuce consiste à définir temporairement une largeur de ligne extrêmement
;; grande et de formater le paragraphe sur cette base).
(defun remove-hard-wrap-paragraph ()
  "Replace newline chars in current paragraph by single spaces."
  (interactive)
  (let ((fill-column 10000000))
    (fill-paragraph nil)
  )
)

;; Fonction équivalente à la précédente appliquée à la région sélectionnée et
;; non plus au paragraphe courant.
(defun remove-hard-wrap-region (start end)
  "Replace newline chars in region by single spaces."
  (interactive "r")
  (let ((fill-column 10000000))
    (fill-region start end)
  )
)

;; Fonction remplaçant toutes les tabulations du tampon courant par le nombre
;; d'espaces qui ne modifie pas la mise en page apparente (étrangement, la
;; fonction native d'Emacs ne s'applique qu'à une région, pas à un tampon
;; entier).
(defun untabify-buffer ()
  "Untabify the entire buffer."
  (interactive)
  (untabify (point-min) (point-max))
)

;; Effacement des caractères blancs (y compris les nouvelles lignes) jusqu'au
;; prochain caractère non blanc.
(defun trim-whitespace () (interactive)
  "Delete white-space characters up to the next non-white-space character."
  (save-excursion
    (if (re-search-forward "[  \t\r\n]*[^  \t\r\n]" nil t)
      (delete-region (match-beginning 0) (- (point) 1))
    )
  )
)

;; Insertion de date au format « AAAA-MM-JJ »
;; Fonction associée plus bas à la séquence « C-c d »
(defun insert-iso-date-string ()
  "Insert a nicely formated date string."
  (interactive)
  (insert (format-time-string "%Y-%m-%d"))
)

;; Insertion de date en clair « JJ Mois AAAA »
;; Fonction associée plus bas à la séquence « C-c S-d »
(defun insert-text-date-string ()
  "Insert a nicely formated date string."
  (interactive)
  (insert (format-time-string "%d %B %Y"))
)

;; Insertion d'horodate au format « AAAA-MM-JJ HH:NN:SS »
;; Fonction associée plus bas à la séquence « C-c t »
(defun insert-iso-time-string ()
  "Insert a nicely formated timestamp string."
  (interactive)
  (insert (format-time-string "%Y-%m-%d %H:%M:%S"))
)

;; Insertion d'horodate au format « JJ Mois AAAA à HH:NN:SS »
;; Fonction associée plus bas à la séquence « C-c S-t »
(defun insert-text-time-string ()
  "Insert a nicely formated timestamp string."
  (interactive)
  (insert (format-time-string "%d %B %Y à %H:%M:%S"))
)


;; ===========================================================================
;; Raccourcis clavier
;; ===========================================================================

;; « C-x k » : Cette séquence, qui est déjà affectée et demande normalement le
;; nom du tampon à supprimer, est ici surchargée pour détruire le tampon
;; courant sans demander de confirmation à l'utilisateur.
(global-set-key [(control x) (k)] 'kill-this-buffer)

;; « M-S-q » (i.e. M-Q) : supprime le formatage du paragraphe courant (la
;; combinaison « M-q », qui existe par défaut, le formatant)
(global-set-key (kbd "M-Q") 'remove-hard-wrap-paragraph)

;; « F6 » : demande le numéro de ligne sur lequel doit se positionner le
;; curseur (alternative à la séquence « M-g g »)
(global-set-key [f6]  'goto-line)

;; « S-F6 » : active et désactive alternativement l'affichage des numéros de
;; ligne
(global-set-key [(shift f6)] 'linum-mode)

;; L'appui sur la touche F7 fait basculer le mode d'affichage des lignes (cf.
;; variables truncate-lines et truncate-partial-width-windows plus haut)
(global-set-key [f7] 'toggle-truncate-lines)

;; « F9 »   : remplacement interactif simple
;; « S-F9 » : remplacement interactif intégrant des expressions rationnelles
(global-set-key [f9]         'query-replace)
(global-set-key [(shift f9)] 'query-replace-regexp)

;; « F10 » : suppression de tous les « caractères blancs » jusqu'au prochain
;; caractère qui n'en est pas un.
(global-set-key [f10] 'trim-whitespace)

;; La séquence « C-c d » insère la date au format « AAAA-MM-JJ »
(global-set-key [(control c) (d)] 'insert-iso-date-string)

;; La séquence « C-c S-d » insère la date au format « XX Mois AAAA »
(global-set-key [(control c) (shift d)] 'insert-text-date-string)

;; La séquence « C-c t » insère l'horodate au format « AAAA-MM-JJ à HH:NN:SS »
(global-set-key [(control c) (t)] 'insert-iso-time-string)

;; La séquence « C-c S-t » insère l'horodate au format « XX Mois AAAA à HH:NN:SS »
(global-set-key [(control c) (shift t)] 'insert-text-time-string)


;; ===========================================================================
;; Édition de code C/C++
;; ===========================================================================

;; Charger le mode C/C++
(require 'cc-mode)

;; Définition d'un style personnel basé sur le style prédéfini "gnu".
(defconst my-c-style
  '("gnu"
    ;; L'appui sur la touche « tabulation » ne doit pas insérer une tabulation
    ;; mais indenter la ligne courante en fonction du contexte et des règles
    ;; définies dans le style.
    (c-tab-always-indent . t)
    ;; Formatage sur 78 colonnes
    (fill-column . 78)
    ;; L'indentation se fait avec un pas de 2 caractères
    (c-basic-offset . 2)
    ;; Règles d'indentation modifiées. La liste complète des éléments
    ;; syntaxiques est disponible à l'adresse :
    ;; http://www.gnu.org/software/emacs/manual/html_node/ccmode/Syntactic-Symbols.html
    (c-offsets-alist .
      (
       ;; Alignement des lignes suivant la première ligne d'une instruction
       ;; sur l'opérateur d'affectation s'il existe ou, dans le cas contraire,
       ;; indentation d'un pas vers la droite.
       (statement-cont . (c-lineup-assignments +))
       ;; Accolade suivant une instruction de test ou de contrôle de boucle
       (substatement-open . 0)
       ;; Label d'un switch
       (case-label . +)
       ;; Label d'une classe (public, protected, private) en retrait d'un pas
       ;; par rapport à l'indentation normale au sein d'une classe (cf.
       ;; déclaration « inclass » plus bas).
       (access-label . -)
       ;; Autres labels
       (label . 0)
       ;; Ligne incluse dans une déclaration de classe (double indentation car
       ;; les labels d'accès public, protected et private sont déjà indentés)
       (inclass . ++)
      )
    )
  )
  "My C Programming Style")
(c-add-style "PERSONAL" my-c-style)

(defun my-c-mode-common-hook ()
  ;; Sélection du style personnel que je viens de définir
  (c-set-style "PERSONAL")
  ;; Chargement du mode fournissant une interface graphique à GDB
  (require 'gdb-ui)
  ;; Utilisation de GDB en mode multi-fenêtré, c'est quand même bien plus
  ;; puissant et pratique
  (setq gdb-many-windows 1)
)
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

(defun my-ctypes-mode-hook ()
  ;; Le module ctypes permet d'ajouter à la liste des types de données C/C++
  ;; des types non reconnus par défaut. Ces types sont alors connus et gérés
  ;; par le module de colorisation syntaxique.
  (require 'ctypes)
  (linum-mode 1)
)
(add-hook 'c-mode-hook 'my-ctypes-mode-hook)
(add-hook 'c++-mode-hook 'my-ctypes-mode-hook)

(defun my-ctypes-load-hook ()
  (ctypes-read-file "~/.emacs.d/ctypes" nil t t)
)
(add-hook 'ctypes-load-hook 'my-ctypes-load-hook)


;; ===========================================================================
;; Édition de code Perl
;; ===========================================================================

;; Adaptation de l'indentation du module cperl-mode à mes goûts.
(defun my-cperl-mode-hook ()
  (setq cperl-indent-level 2)
  (setq cperl-continued-statement-offset 0)
  (setq cperl-extra-newline-before-brace t)
)
(add-hook 'cperl-mode-hook 'my-cperl-mode-hook)


;; ===========================================================================
;; Mode d'édition préféré par type de fichier
;; ===========================================================================

;; Sélection du mode d'édition en fonction du motif satisfait par le nom du
;; fichier.
(setq auto-mode-alist
  (append
    '(("\\.k?sh\\'" . sh-mode)
      ("bash" . sh-mode)
      ("profile" . sh-mode)
      ("[Mm]akefile\\'" . makefile-mode)
      ("\\.mk\\'" . makefile-mode)
      ("\\.[ch]\\'" . c-mode)
      ("\\.[ch]pp\\'" . c++-mode)
      ("\\.cc\\'" . c++-mode)
      ("\\.hh\\'" . c++-mode)
      ("\\.pgc\\'" . c++-mode) ;; Fichiers « Embedded PostgreSQL in C »
      ("\\.p[lm]\\'" . cperl-mode)
      ("\\.sgml\\'" . nxml-mode)
      ("\\.x[ms]l\\'" . nxml-mode)
      ("\\.[sx]?html?\\'" . nxml-mode)
      ("\\.tpl\\'" . nxml-mode)
      ("\\.php\\'" . php-mode)
      ("\\.inc\\'" . php-mode)
      ("\\.sql\\'" . sql-mode) ;; Schémas de bases SQL
      ("\\.sep\\'" . sql-mode) ;; Extension de fichier de commandes SQL en
                               ;; usage dans le monde Oracle
     )
     auto-mode-alist
  )
)