; ==============================================================================
; Fichier : .emacs
; Auteur  : Sebastien Beaugrand
; Date    : 26/11/2008
; Url     : http://www.chez.com/beaugrand/
; ==============================================================================
; Pour recharger la configuration : eval-buffer

; Parametres
(setq user-full-name    "Toto")
(setq user-mail-address "toto@toto.fr")
(setq mail-smtp-address "smtp.toto.fr")
(setq mail-signature
  "... Les orcs parcourent librement nos terres... (Eomer du Rohan)")
; Mettre les alias dans ~/.mailrc, par exemple:
;alias toto "Toto <toto@toto.fr>"
; Mettre l'X-Face dans ~/.xface , par exemple:
;X-Face: +/j%~KDrmR_.96jOJD::|&v]2z^G%ZFQ*kjONuMb}cMn/EFovusO|We`U=i]FW4zd%@p68C
; 1Y-s}c:eTgv?2#[:-GPMX5idi-4TZqg`g$:&wNLPRIy/w_Wa]!|>}k'NtfsO9[GiH/`Lrvzyfsi$Ir
; RMv7wT'uz

; Deplacements
(global-set-key [S-right] 'other-window)
(global-set-key [S-left]  '(lambda () (interactive) (other-window -1)))
(global-set-key [S-up]    '(lambda () (interactive) (scroll-down   1)))
(global-set-key [S-down]  '(lambda () (interactive) (scroll-up     1)))
(global-set-key [M-right] '(lambda () (interactive) (forward-char  1)
                                                    (scroll-left   1)))
(global-set-key [M-left]  '(lambda () (interactive) (backward-char 1)
                                                    (scroll-right  1)))
(global-set-key [\home]   'beginning-of-line)
(global-set-key [\end]    'end-of-line)
(global-set-key [M-g]     'goto-line)
(mouse-wheel-mode t)
(column-number-mode t)
(setq delete-key-deletes-forward t)

(defun setup-frame ()
  ; Font (-font 6x13)
  (set-face-font 'default "6x13")

  ; Couleurs
  (set-background-color "black")
  (set-foreground-color "white")
  (set-face-foreground 'menu "wheat")
  (set-face-background 'menu "DarkSlateGray")
  (set-face-background 'scroll-bar "DarkSlateGray")
  (set-face-background 'region "DarkSlateGray")
)
(setup-frame)

; Encodage des caracteres
(set-language-environment 'UTF-8)

; Taille et position de la fenetre (-geometry 255x73+54+0 pour du 1680x1050)
(setq x-width  (string-to-number (shell-command-to-string
  "xrdb -symbols | grep DWIDTH  | cut -d '=' -f 2")))
(setq x-height (string-to-number (shell-command-to-string
  "xrdb -symbols | grep DHEIGHT | cut -d '=' -f 2")))
(setq win-num  1)
(setq win-edge 7)
(if (>= x-width 1024) (setq win-num 2))
(if (>= x-width 1680) (setq win-num 3))
(if ( = x-width 1024) (progn (set-scroll-bar-mode nil) (setq win-edge 4)))
(if (> win-num 1) (progn
  (setq win-width (+ (+ (* 80 win-num) (* win-edge (- win-num 1))) 1))
  (setq win-height (/ (- x-height 100) 13))
  (setq win-pos (/ (- x-width (* (+ win-width win-edge) 6)) 2))
  (setq initial-frame-alist (list '(top . 0) (cons 'left win-pos)
    (cons 'width win-width) (cons 'height win-height)))
))

; Titre de la fenetre
(setq frame-title-format "Emacs")

; Index des methodes en C++ et en C
(add-hook 'c++-mode-hook 'imenu-add-menubar-index)
(add-hook   'c-mode-hook 'imenu-add-menubar-index)

; Remplacement des tabulations par 4 espaces
(defun indent-setup ()
  (setq c-basic-offset 4)
  (setq indent-tabs-mode nil)
)
(add-hook 'c++-mode-hook 'indent-setup)
(add-hook   'c-mode-hook 'indent-setup)

; Suppression des espaces en fin de ligne a l'enregistrement
(add-hook 'c++-mode-hook '(lambda ()
  (add-hook 'write-contents-hooks 'delete-trailing-whitespace nil t)))
(add-hook   'c-mode-hook '(lambda ()
  (add-hook 'write-contents-hooks 'delete-trailing-whitespace nil t)))

; Nouveaux types
(setq c++-font-lock-extra-types (append c++-font-lock-extra-types
  (list "UInt" "SInt" "UChar" "ULong" "UInt8" "UInt16" "UInt32" "UInt64")))
(setq   c-font-lock-extra-types (append   c-font-lock-extra-types
  (list "UInt" "SInt" "UChar" "ULong" "UInt8" "UInt16" "UInt32" "UInt64")))

; Web
(autoload 'w3m "w3m-load" nil t)

; PHP mode
(autoload 'php-mode "php-mode" nil t)
(add-to-list 'auto-mode-alist '(".php$" . php-mode))

; Une, deux, ou trois fenetres
(defun after-make-frame (frame)
  (select-frame frame)
  (setup-frame)
  (setq win-width (+ (+ (* 80 num) (* win-edge (- num 1))) 1))
  (set-frame-position frame win-pos 0)
  (set-frame-size frame win-width win-height)
  (if (> num 2) (split-window (selected-window) (* (+ 80 win-edge) 2) 1))
  (if (> num 1) (split-window (selected-window)    (+ 80 win-edge)    1))
  (delete-frame (previous-frame))
)
(global-set-key [f1] '(lambda () (interactive)
  (setq after-make-frame-functions 'after-make-frame)
  (setq num 1) (if (< win-num num) (setq num win-num))
  (make-frame)
))
(global-set-key [f2] '(lambda () (interactive)
  (setq after-make-frame-functions 'after-make-frame)
  (setq num 2) (if (< win-num num) (setq num win-num))
  (make-frame)
))
(global-set-key [f3] '(lambda () (interactive)
  (setq after-make-frame-functions 'after-make-frame)
  (setq num 3) (if (< win-num num) (setq num win-num))
  (make-frame)
))

; Sauvegarde des derniers noms de fichiers utilises
(defun save-prev-buffer-file-name ()
  (other-window -1)
  (if buffer-file-name (progn
    (setq list-buffers (cons (list buffer-file-name) list-buffers))
    (kill-this-buffer)
  ))
)
(add-hook 'kill-emacs-hook '(lambda ()
  (select-window (window-at 0 0))
  (setq list-buffers nil)
  (save-prev-buffer-file-name)
  (save-prev-buffer-file-name)
  (save-prev-buffer-file-name)
  (set-buffer (get-buffer-create "*Saved Last*"))
  (delete-region (point-min) (point-max))
  (print list-buffers (current-buffer))
  (write-region (point-min) (point-max) "~/.emacs-last")
))

; Chargement des derniers fichiers utilises
(global-set-key [f4] '(lambda () (interactive)
  (if (file-readable-p "~/.emacs-last") (progn
    (delete-other-windows)
    (find-file "~/.emacs-last")
    (setq last-buffers
      (car (read-from-string (buffer-substring (point-min) (point-max)))))
    (kill-buffer ".emacs-last")
    (if (> win-num 2) (find-file (caar (cddr last-buffers))))
    (if (> win-num 2) (split-window (selected-window) (* (+ 80 win-edge) 2) 1))
    (if (> win-num 1) (find-file (car  (cadr last-buffers))))
    (if (> win-num 1) (split-window (selected-window)    (+ 80 win-edge)    1))
    (find-file (caar last-buffers))
  ))
))

; Buffer precedent
(setq last-prev-buffer nil)
(global-set-key [f5] '(lambda () (interactive)
  (setq last-prev-buffer (current-buffer))
  (switch-to-buffer (other-buffer))
))
(global-set-key [f6] '(lambda () (interactive)
  (switch-to-buffer (other-buffer last-prev-buffer))
))

; Ajustements des fenetres
(global-set-key [f7]  'shrink-window-horizontally)
(global-set-key [f8] 'enlarge-window-horizontally)

; Mail
(autoload 'expand-mail-aliases   "mailalias" nil t)
(autoload 'message-make-date     "message"   nil t)
(autoload 'mc-install-write-mode "mailcrypt" nil t)
(autoload 'smtpmail-send-it      "smtpmail"  nil t)
(defun mail-send-setup ()
  (rfc822-goto-eoh)
  (setq delimline (point-marker))

  (expand-mail-aliases (point-min) delimline)
  (setq mail-aliases nil)

  (goto-char (point-min))
  (unless (re-search-forward "^Date:" delimline t)
    (insert "Date: " (message-make-date) "\n"))

  (if (file-exists-p "~/.xface") (insert-file-contents "~/.xface"))

  (if (y-or-n-p "justifier ? ") (justify-buffer))

  (rfc822-goto-eoh)
  (if (y-or-n-p "chiffrer ? ") (progn
    (save-buffer)
    (insert mail-header-separator "\n")
    (mc-install-write-mode)
    (mc-setversion "gpg")
    (setq mc-pgp-always-sign 'never)
    (mc-encrypt 0))
  (progn
    (insert "Content-Type: text/plain; charset=utf-8\n")
    (save-buffer))
  )

  (rename-buffer (concat "*" (buffer-name) "*"))
)
(global-set-key [f9] '(lambda () (interactive)
  (setq dir-mail  "~/.emacs-mel/")
  (setq dir-draft (concat dir-mail "brouillons/"))
  (setq dir-sent  (concat dir-mail "envoyes/" ))
  (if (not (file-accessible-directory-p dir-draft))
    (error (concat dir-draft " n'est pas accessible")))
  (if (not (file-accessible-directory-p dir-sent ))
    (error (concat dir-sent  " n'est pas accessible")))

  (setq draft-num (shell-command-to-string
    (concat "cd " dir-sent "; ls *.mel 2> /dev/null | tail -n 1 |
     cut -c-5 | gawk 'END { printf \"%05d\", $0+1 }'")))
  (setq draft-filename (concat dir-draft draft-num ".mel"))
  (setq draft-exist (file-exists-p draft-filename))
  (find-file draft-filename)

  (mail-mode)
  (mail-to)
  (mail-subject)
  (setq delimline (point-marker))
  (goto-char (point-min))
  (unless (re-search-forward "^From:" delimline t)
    (insert "From: " user-full-name " <" user-mail-address ">\n"))
  (mail-text)
  (if (not draft-exist) (progn
    (insert "\n")
    (if mail-signature (progn
      (setq to (point))
      (insert "\n-- \n")
      (insert mail-signature)
      (goto-char to)
    ))
  ))
  (save-buffer)

  (setq fill-column 60)
  (spell-mode-setup)
  (flyspell-region (point) (point-max))

  (add-hook 'mail-send-hook 'mail-send-setup)
  (setq mail-aliases t)
  (setq send-mail-function 'smtpmail-send-it)
  (setq smtpmail-smtp-server mail-smtp-address)

  (setq mail-send-actions (list (list '(lambda (dummy) (interactive)
    (rename-file draft-filename (concat dir-sent draft-num ".mel"))
    (setq mail-aliases t)
  ) t) nil))
))

; Justification
(defun justify-buffer ()
  (if mark-active
    (progn (setq min (mark))
           (setq max (point)))
    (if (eq major-mode 'mail-mode)
      (progn (rfc822-goto-eoh)
             (setq min (point))
             (setq max (point-max)))
      (progn (setq min (point-min))
             (setq max (point-max)))
    )
  )
  (fill-region min max)
)
(global-set-key [f10] '(lambda () (interactive)
  (justify-buffer)
))

; Largeur du texte des fichiers TeX
(add-hook 'tex-mode-hook '(lambda () (setq fill-column 80)))

; Orthographe
(setq flyspell-mode nil)
(unify-8859-on-encoding-mode 1)
(unify-8859-on-decoding-mode 1)
(setq ispell-program-name "ispell")
(setq ispell-dictionary "francais")
(setq flyspell-large-region 10000)

(global-set-key [f11] '(lambda () (interactive)
  (if flyspell-mode
    (flyspell-mode 0)
    (progn
      (flyspell-mode 1)
      (if mark-active
        (flyspell-region (mark) (point))
        (flyspell-buffer)
      )
    )
  )
))

; Aide sur les touches
(defun key-bindings-help ()
  (set-buffer (get-buffer-create "*Key Bindings Help*"))
  (delete-region (point-min) (point-max))
  (insert "\nF1  : Une fenetre de 80 colonnes\n")
  (insert "\nF2  : Deux fenetres de 80 colonnes\n")
  (insert "\nF3  : Trois fenetres de 80 colonnes\n")
  (insert "\nF4  : Charger les derniers fichiers utilises\n")
  (insert "\nF5  : Buffer precedent\n")
  (insert "\nF6  : Buffer precedent 2\n")
  (insert "\nF7  : Retrecir la fenetre\n")
  (insert "\nF8  : Agrandir la fenetre\n")
  (insert "\nF9  : Ecrire un courriel\n")
  (insert "\nF10 : Justifier\n")
  (insert "\nF11 : Orthographe\n")
  (insert "\nF12 : Aide sur les touches\n\n")
  (insert "\n<S-right> : Fenetre de droite\n")
  (insert "\n<S-left>  : Fenetre de gauche\n")
  (insert "\n<S-up>    : Defiler vers le haut\n")
  (insert "\n<S-down>  : Defiler vers le bas\n")
  (insert "\n<M-right> : Defiler vers la droite\n")
  (insert "\n<M-left>  : Defiler vers la gauche\n")
  (insert "\n<home>    : Debut de ligne\n")
  (insert "\n<end>     : Fin de ligne\n")
  (insert "\n<M-g>     : Aller a une ligne\n\n")
  (switch-to-buffer (current-buffer))
)
(global-set-key [f12] '(lambda () (interactive) (key-bindings-help)))

; Accents avec un clavier qwerty
; (require 'iso-acc)
; (add-hook 'text-mode-hook '(lambda () (iso-accents-mode 1)))
; (add-hook  'tex-mode-hook '(lambda () (iso-accents-mode 1)))


; Fin du fichier .emacs