;;
;; GNU Emacs configuration file (~/.emacs) 
;; 2000-2009,  kolter <kolter@openics.org>
;;
;;  This file is distributed in the hope that it will be useful,
;;  but WITHOUT ANY WARRANTY
;;

;;-------------------------------------------------------------------
;; Compiling .emacs : regenerate the .emacs.elc if .emacs is newer
(defun dotemacscheck! ()
  "If .emacs exists and is newer than .emacs.elc, recompile it"
  (cond
   ((file-newer-than-file-p "~/.emacs" "~/.emacs.elc")
    (let ((mode-line-format "*** Recompiling .emacs ***"))
      (sit-for 1)
      (byte-compile-file "~/.emacs")
      (message ".emacs.elc recompiled --- reloading...")
      )
    (load "~/.emacs.elc" t t t)
    )))
(dotemacscheck!)

;;--------------------------------------------------------------------
;; Emacs internals stuff

;; trace errors (only for debug/testing)
;;(setq debug-on-error t)

;; adding lisp modules directory
(add-to-list 'load-path "~/.emacs-lisp/")

;; y = yes && n = no
(defalias 'yes-or-no-p 'y-or-n-p)

;; disable speaker's beep
(setq visible-bell t)

;; set a directory to save backup files
(setq 
 backup-by-copying t
 backup-directory-alist '(("." . "~/.emacs-backups/"))
 delete-old-versions t
 kept-new-versions 6
 kept-old-versions 2
 version-control t)

;; autoload apache-mode
;; apache-mode is available in debian package emacs-goodies-el
(autoload 'apache-mode "apache-mode" "autoloaded" t)

;; transparently work with compressed files
(auto-compression-mode 1)

;; define some modes for some filenames
(add-to-list 'auto-mode-alist '(".htaccess$"   . apache-mode))
(add-to-list 'auto-mode-alist '("httpd.conf$"  . apache-mode))
(add-to-list 'auto-mode-alist '("apache2.conf$"    . apache-mode))
(add-to-list 'auto-mode-alist '("ports.conf$" . apache-mode))

(add-to-list 'auto-mode-alist (cons "/etc/ssh/ssh_config" 'shell-script-mode))
(add-to-list 'auto-mode-alist (cons "/etc/ssh/sshd_config" 'shell-script-mode))

(add-to-list 'auto-mode-alist '("\\.zsh$" . shell-script-mode))
(add-to-list 'auto-mode-alist '("\\.zshrc$" . shell-script-mode))

;; specific settings for vt420 terminal
;;(enable-flow-control-on "vt420")

;;--------------------------------------------------------------------
;; Display stuff
;;

;; disabling menu bar
(menu-bar-mode nil)

;; disabling tool bar
;; (tool-bar-mode nil)

;; Remove startup messages
(setq inhibit-startup-message t)
(setq inhibit-startup-echo-area-message t)

;; line and column number in modeline
(setq column-number-mode t)
(setq line-number-mode t)

;; fonts (emacs X11)
(set-default-font "7x14")
(set-frame-font "7x14")

;; do not extend buffer content with 'down' key
(setq next-line-add-newlines nil)

;; parenthesis uses
(show-paren-mode t)
(setq blink-matching-paren t)
(setq blink-matching-paren-on-screen t)
(setq show-paren-style 'expression)
(setq blink-matching-paren-dont-ignore-comments t)

;; setting maximum colors
(font-lock-mode t)
(global-font-lock-mode t)
(setq font-lock-maximum-decoration t)

;; make selections more visible (color)
(setq transient-mark-mode t)

;; make the compilation window size fixed
(setq compilation-scroll-output t)

;; having a soft scrolling !
(defun point-of-beginning-of-bottom-line ()
  (save-excursion
    (move-to-window-line -1)
    (point)))

(defun point-of-beginning-of-line ()
  (save-excursion
    (beginning-of-line)
    (point)))

(defun next-one-line () (interactive)
  (if (= (point-of-beginning-of-bottom-line) (point-of-beginning-of-line))
      (progn (scroll-up 1)
             (next-line 1))
    (next-line 1)))

(defun point-of-beginning-of-top-line ()
  (save-excursion
    (move-to-window-line 0)
    (point)))

(defun previous-one-line () (interactive)
  (if (= (point-of-beginning-of-top-line) (point-of-beginning-of-line))
      (progn (scroll-down 1)
             (previous-line 1))
    (previous-line 1)))

(global-set-key (kbd "<down>") 'next-one-line)
(global-set-key (kbd "<up>") 'previous-one-line)


;; change tab width
;(setq default-tab-width 4)

;;--------------------------------------------------------------------
;; Key bindings stuff

;; easy navigation between buffers using cyclebuffer.el
;; cyclebuffer.el is available in debian package emacs-goodies-el
(global-set-key [f1] 'cyclebuffer-backward)
(global-set-key [f2] 'cyclebuffer-forward)
(global-set-key [f11] 'cyclebuffer-backward)
(global-set-key [f12] 'cyclebuffer-forward)


;; easy navigation between windows
(global-set-key "\C-n" 'other-window)
(global-set-key "\C-p" '(lambda () (interactive) (other-window -1)))

;; spliting windows
(global-set-key [f5] 'split-window-vertically)
(global-set-key [f6] 'split-window-horizontally)
(global-set-key [f7] 'delete-window)
(global-set-key [f8] 'delete-other-windows)


(global-set-key "\M-g" 'goto-line)
(global-set-key "\C-q" 'kill-this-buffer)
(global-set-key "\M-c" 'compile)
(global-set-key [f9] 'compile)

;; mouse settings (emacs X11)
;;(global-set-key (quote [(mouse-5)]) (quote scroll-up))
;;(global-set-key (quote [(mouse-4)]) (quote scroll-down))

;;-------------------------------------------------------------------
;; Mutt(ng) stuff
(load-library "mutt-post")
;; use muttrc-mode with mutt related files
;; muttrc-mode is available in debian package emacs-goodies-el
(add-to-list 'auto-mode-alist '("\\.mutt\\(.*\\)$" . muttrc-mode))
(add-to-list 'auto-mode-alist '("\\.mutt/conf/\\(.*\\)$" . muttrc-mode))
(add-to-list 'auto-mode-alist '("\\.muttng/conf/\\(.*\\)$" . muttrc-mode))
(add-to-list 'auto-mode-alist '("\\.madmutt\\(.*\\)$" . muttrc-mode))
;; automtically wrap lines when composing mail
(add-to-list 'auto-mode-alist '(".mutt/tmp/mutt-" . post-mode))
(add-to-list 'auto-mode-alist '(".muttng/tmp/muttng-" . post-mode))
(add-to-list 'auto-mode-alist '(".madmutt/tmp/madmutt-" . post-mode))
;;-------------------------------------------------------------------
;; CMake stuff
(add-to-list 'auto-mode-alist '("\\.cmake$" . cmake-mode))
(add-to-list 'auto-mode-alist '("\\CMakeLists.txt$" . cmake-mode))

;;-------------------------------------------------------------------
;; Ispell / Aspell settings
;; set default ispell dictionnary to french one
(setq ispell-program-name "/usr/bin/aspell")
(setq ispell-dictionary "francais")

;; enable flyspell on text-mode
;;(add-hook 'text-mode-hook
;;          '(lambda()
;;             (flyspell-mode)
;;             ))

;; enable flyspell on post-mode
;;(add-hook 'post-mode-hook
;;          '(lambda()
;;             (flyspell-mode)
;;             ))

;;-------------------------------------------------------------------
;; WeeChat coding style
(setq c-mode-hook
      '(lambda ()
	 (c-set-style "K&R")
	 (setq c-basic-offset 4)
	 (setq c-tab-always-indent t)))


;;-------------------------------------------------------------------
;; WEB coding
(load-library "multi-mode")
(defun web-mode () (interactive)
  (multi-mode 1
	      'html-mode
	      '("<%" ruby-mode)
	      '("<?php" php-mode)
	      '("<?" php-mode)
	      '("<script" java-mode)
	      '("<style" css-mode)
	      '("</script" html-mode)
	      '("?>" html-mode)
	      '("%>" html-mode)))

(add-hook 'php-mode-hook
          (lambda()
	    (defalias 'c-electric-backspace 'delete-backward-char)
	    (defun c-indent-command () (interactive "*") (self-insert-command 1))
	    (define-key php-mode-map "\C-a" 'beginning-of-line-text)
	    (define-key php-mode-map [home] 'beginning-of-line-text)
	    )
	  )
(add-hook 'html-mode-hook
          (lambda()
	    (defun indent-for-tab-command () (interactive "*") (self-insert-command 1))
	    (define-key html-mode-map "\C-a" 'beginning-of-line-text)
	    (define-key html-mode-map [home] 'beginning-of-line-text)
	    (define-key html-mode-map (kbd "RET") 'newline-and-indent)
	    )
	  )
(add-to-list 'auto-mode-alist '("\\.php$" . web-mode))
(add-to-list 'auto-mode-alist '("\\.rhtml$" . web-mode))


(defun indent-region-with-tab ()
  (interactive)
  (save-excursion
    (if (< (point) (mark)) (exchange-point-and-mark))
    (let ((save-mark (mark)))
      (if (= (point) (line-beginning-position)) (previous-line 1))
      (goto-char (line-beginning-position))
      (while (>= (point) save-mark)
	(goto-char (line-beginning-position))
	(insert "\t")
	(previous-line 1)))
    (setq deactivate-mark nil)
    ))


(defun unindent-region-with-tab ()
  (interactive)
  (save-excursion
    (if (< (point) (mark)) (exchange-point-and-mark))
    (let ((save-mark (mark)))
      (if (= (point) (line-beginning-position)) (previous-line 1))
      (goto-char (line-beginning-position))
      (while (>= (point) save-mark)
	(goto-char (line-beginning-position))
	(if (= (string-to-char "\t") (char-after (point))) (delete-char 1))
	(previous-line 1)))
    (setq deactivate-mark nil)
    ))

(global-set-key "\C-xi" 'indent-region-with-tab)
(global-set-key "\C-xj" 'unindent-region-with-tab)
