;; p4bl0's .emacs
(setq user-full-name "Pablo Rauzy")
(setq user-mail-address "pablo rauzy gmail com")

;; I use the Meta (Windows) key extensively for OpenBox
;(setq x-alt-keysym 'meta)
;(setq x-meta-keysym 'alt)
(setq x-super-keysym 'alt)

;; cool frame title with currently edited buffer name
(setq frame-title-format
      (concat "%b - " invocation-name "@" system-name))

;; add my .emacs.d to load-path
(setq emacs-dir "/home/p4bl0/.emacs.d/")
(setq load-path (cons emacs-dir load-path))

;; utf-8 powaa!!
(set-language-environment 'utf-8)
(prefer-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(setq locale-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(set-input-method nil)

;; no annoying blinking cursor
(blink-cursor-mode -1)

;; fancy streching cursor
(setq x-stretch-cursor t)

;; usual behavior when text is selected
(delete-selection-mode t)

;; default fill column is 70, why?
(setq default-fill-column 79)

;; my sentences end with a dot, not with two spaces
(setq sentence-end-double-space nil)

;; automatically indent wherever I am
(global-set-key (kbd "RET") 'newline-and-indent)

;; kill whole line with C-; (because ; is close to k)
(global-set-key (kbd "C-;") 'kill-whole-line)

;; replace-string and replace-regexp need a key binding
(global-set-key (kbd "C-c s") 'replace-string)
(global-set-key (kbd "C-c r") 'replace-regexp)

;; string-insert-rectangle is useful but not binded to any key by default
(global-set-key (kbd "C-x r a") 'string-insert-rectangle)

;; rect-missing-features is my first package :)
(load "rect-missing-features")
(global-set-key (kbd "C-x r z") 'string-insert-after-rectangle)
(global-set-key (kbd "C-x r e") 'string-insert-rectangle-eol)

;; keybindings for useful function
(global-set-key (kbd "C-c w") 'delete-trailing-whitespace)
(global-set-key (kbd "C-c a") 'align-entire)
(global-set-key (kbd "C-c A") 'align-string)
(global-set-key (kbd "C-c f") 'font-lock-fontify-buffer)
(global-set-key (kbd "C-c b") 'revert-buffer)

;; enable disabled command
(put 'narrow-to-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)

;; twitter in Emacs !
(autoload 'twitter-get-friends-timeline "twitter" nil t)
(autoload 'twitter-status-edit "twitter" nil t)
(setq twitter-username "p4bl0")
(add-hook 'twitter-timeline-view-mode-hook
    (lambda ()
      (set-face-foreground 'twitter-user-name-face "#dddddd")
      (set-face-background 'twitter-user-name-face "#1D73C8")
      (set-face-foreground 'twitter-time-stamp-face "#dddddd")
      (set-face-background 'twitter-time-stamp-face "#1D73C8")))
(global-set-key (kbd "C-x t t") 'twitter-get-friends-timeline)
(global-set-key (kbd "C-x t s") 'twitter-status-edit)

;; identi.ca too :-)
(require 'identica-mode)
(setq identica-username "p4bl0")
(setq identica-status-format "%i %s (%S), %@, from %f:\n  %t")
(setq identica-timer-interval 120)
(global-set-key (kbd "C-x t i") 'identica-mode)
(global-set-key (kbd "C-x t p") 'identica-update-status-interactive)

;; tetris score file
(setq tetris-score-file (concat emacs-dir "tetris"))

;; erc
;; (require 'erc)
;; (erc-autojoin-mode t)
;; (setq erc-autojoin-channels-alist
;;       '((".*\\.freenode.net"
;;          "#soap.coders.fm" "##!/web/shebang" "#yapok")))

;; in a text editor, everything is (at least) text
(setq default-major-mode 'text-mode)

;; colorize hexa color in css
(add-hook 'css-mode-hook
   (lambda ()
     (font-lock-add-keywords nil
       '(("\\(#\\([0-9a-fA-F]\\{3\\}\\)\\{1,2\\}\\)" 1
          font-lock-type-face)))))

;; colorize number too (like constant)
(defun font-lock-fontify-numbers ()
  "Use this function as a hook to fontify numbers as constant"
  (font-lock-add-keywords nil
      '(("[^a-zA-Z_]\\(0x[0-9a-fA-F]+\\)" 1 font-lock-constant-face) ; hexa
        ("[^a-zA-Z_]\\(-?[0-9]+\\.[0-9]+\\)" 1 font-lock-constant-face) ; float
        ("[^a-zA-Z_1-9]\\(-?[0-9]+L?\\)" 1 font-lock-constant-face)))) ; int
(add-hook 'php-mode-hook 'font-lock-fontify-numbers)
(add-hook 'c-mode-hook 'font-lock-fontify-numbers)
(add-hook 'c++-mode-hook 'font-lock-fontify-numbers)
(add-hook 'perl-mode-hook 'font-lock-fontify-numbers)
(add-hook 'css-mode-hook 'font-lock-fontify-numbers)
(add-hook 'emacs-lisp-mode-hook 'font-lock-fontify-numbers)
(add-hook 'tuareg-mode-hook 'font-lock-fontify-numbers)
(add-hook 'js2-mode-hook 'font-lock-fontify-numbers)

;; font-lock setting
(if (>= emacs-major-version 23)
    (set-default-font "DejaVu Sans Mono-7.5")) ; .Xdefaults
(global-font-lock-mode t)
(show-paren-mode t)
(transient-mark-mode t)
(set-face-background 'default "#333333") ; .Xdefaults
(set-face-foreground 'default "#cccccc") ; .Xdefaults
(set-face-background 'cursor "#ffaa00") ; .Xdefaults
(set-face-foreground 'cursor "#333333") ; .Xdefaults
(setq x-pointer-foreground-color "#aaaaaa") ; .Xdefaults
(set-face-background 'region "#33aaff")
(set-face-foreground 'region "#eeeeee")
(set-face-background 'show-paren-match-face "#666666")
(set-face-foreground 'show-paren-match-face "#ffffff")
(set-face-background 'show-paren-mismatch-face "#dd0000")
(set-face-foreground 'show-paren-mismatch-face "#333333")
(set-face-foreground 'font-lock-warning-face "#dd0000")
(set-face-foreground 'font-lock-preprocessor-face "#99cc33")
(set-face-foreground 'font-lock-constant-face "#dd00dd")
(set-face-foreground 'font-lock-comment-face "#888888")
(set-face-foreground 'font-lock-keyword-face "#dddd00")
(set-face-foreground 'font-lock-type-face "#ffaa00")
(set-face-foreground 'font-lock-function-name-face "#2277dd")
(set-face-foreground 'font-lock-string-face "#33aaff")
(set-face-foreground 'font-lock-variable-name-face "#00bb00")
;(global-hl-line-mode t)
;(set-face-background 'hl-line "#3a3a3a")
;(set-face-foreground 'hl-line "#eeeeee")
(set-face-foreground 'highlight "#333333")
(set-face-background 'highlight "#dddd00")
(set-face-foreground 'isearch "#333333")
(set-face-background 'isearch "#bbbb22")
(set-face-foreground 'isearch-lazy-highlight-face "#333333")
(set-face-background 'isearch-lazy-highlight-face "#bbbb66")
(set-face-background 'modeline "#aaaaaa")
(set-face-foreground 'modeline "#333333")
(set-face-foreground 'link "#4466ff")
(set-face-foreground 'link-visited "#aa33bb")
(set-face-foreground 'minibuffer-prompt "#bababa")
(set-face-foreground 'escape-glyph "#ccaa11")

;; tab = two spaces
(setq default-tab-width 2)
(setq-default tab-width 2)
(setq-default indent-tabs-mode nil)
(setq css-indent-offset 2)

;; in sh-mode too...
(setq-default sh-basic-offset 2)
(setq-default sh-indentation 2)

;; and perl-mode..!
(setq-default perl-indent-level 2)

;; set the random number seed from current time and pid
(random t)

;; kill the splash screen before its birth
(setq inhibit-splash-screen t)

;; get rid of the useless tool-bar and menu-bar
(tool-bar-mode -1) ; .Xdefaults
(menu-bar-mode -1) ; .Xdefaults

;; but give the emacs window a still good shape !
(setq initial-frame-alist '((width . 90) (height . 42))) ; .Xdefaults

;; scroll bar on the right side
(set-scroll-bar-mode 'right)

;; show column number in mode-line
(setq column-number-mode t)

;; line numbering with linum (WTF it's not activated by defaults?!)
(require 'linum)
(global-linum-mode t)

;; texdrive for math formulae in html
;(require 'texdrive)

;; do not kill `emacs --daemon`, juste delete this frame
(global-set-key (kbd "C-x C-c")
  (function
    (lambda () (interactive)
      (cond ((y-or-n-p "Delete this frame? ")
             (delete-frame))))))
;; ask before quitting
;      (cond ((y-or-n-p "Quit? ")
;             (save-buffers-kill-emacs))))))

;; C-x 5 0 is really not handy on a laptop
(global-set-key (kbd "C-x w") 'delete-frame)

;; y or n ?
(fset 'yes-or-no-p 'y-or-n-p)

;; and no boring gtk+ dialog
(setq use-dialog-box nil)

;; Emacs is not Ed !
(setq window-min-height 3)

;; middle click should pastes at cursor position
(setq mouse-yank-at-point t)

;; I prefer electric-buffer-list
(global-set-key (kbd "C-x C-b") 'electric-buffer-list)

;; C-tab to go through buffer like everywhere else
(global-set-key [C-tab] 'next-buffer)
(global-set-key [C-S-iso-lefttab] 'previous-buffer)

;; use M-{up,right,down,left} for windmove
(windmove-default-keybindings 'meta)

;; fullscreen emacs !
; I don't need it anymore since i added the command to my Openbox (W-F11)
;(defun fullscreen-toggle ()
; "Toogle fullscreen"
; (interactive)
; (shell-command "wmctrl -r :ACTIVE: -b toggle,fullscreen"))
;(global-set-key (kbd "<f11>") 'fullscreen-toggle)

;; C-x k == C-x # when editing emacsclient is waiting
(add-hook 'server-switch-hook
  (lambda ()
    (local-set-key (kbd "C-x k") '(lambda ()
                                    (interactive)
                                    (if server-buffer-clients
                                        (server-edit)
                                      (ido-kill-buffer))))))

;; revert-all-buffer from emacswiki
(defun revert-all-buffers ()
  "Revert all opened buffers from their respective files"
  (interactive)
  (let* ((list (buffer-list))
         (buffer (car list)))
    (while buffer
      (when (buffer-file-name buffer)
        (progn
          (set-buffer buffer)
          (revert-buffer t t t)))
      (setq list (cdr list))
      (setq buffer (car list))))
  (message "All buffers reverted"))
(global-set-key (kbd "C-c B") 'revert-all-buffers)

;; browse kill ring
(require 'browse-kill-ring)
(global-set-key (kbd "C-x y") 'browse-kill-ring)

;; keep minibuffer history between session
(savehist-mode t)

;; autocompletion
(global-set-key (kbd "ESC ESC") 'dabbrev-expand) ; ESC ESC ESC not usable :-/
(setq skeleton-pair t)
(global-set-key (kbd "(") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "{") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "[") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "\"") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "'") 'skeleton-pair-insert-maybe)

;; textmate-next-line from textmate.el - github.com/defunkt/textmate.el
(defun textmate-next-line ()
  "Go to next line and indent wherever you are in a line"
  (interactive)
  (end-of-line)
  (newline-and-indent))
(global-set-key [C-return] 'textmate-next-line)

;; textmate-semicolon-and-next-line
(defun textmate-semicolon-and-next-line ()
  "Put a semicolon at the end of the line where you are then
go to next line and indent wherever you are in a line"
  (interactive)
  (end-of-line)
  (insert ";")
  (newline-and-indent))
(global-set-key [M-return] 'textmate-semicolon-and-next-line)

;; comment-or-uncomment-region-or-line
; it's almost the same as in textmate.el but I wrote it before I know about
; textmate.el, in fact that's how I found textmate.el, by googling this
; function to see if somebody already did that in a better way than me.
(defun comment-or-uncomment-region-or-line ()
  "Like comment-or-uncomment-region, but if there's no mark \(that means no
region\) apply comment-or-uncomment to the current line"
  (interactive)
  (if (not mark-active)
      (comment-or-uncomment-region
        (line-beginning-position) (line-end-position))
      (if (< (point) (mark))
          (comment-or-uncomment-region (point) (mark))
        (comment-or-uncomment-region (mark) (point)))))
(global-set-key (kbd "C-/") 'comment-or-uncomment-region-or-line)

;; personal-layout
(defun personal-layout ()
  "Arrange windows to my personal layout."
  (interactive)
  (split-window-horizontally)
  (windmove-right)
  (split-window-vertically)
  (enlarge-window-vertically 10))
(global-set-key (kbd "C-c l") 'personal-layout)

;; embedded php in html
(defun toggle-php-and-xml-mode ()
  "Toggle between php-mode and xml-mode"
  (interactive)
  (if (eq major-mode 'php-mode)
      (xml-mode)
    (php-mode)))
(global-set-key (kbd "C-c h") 'toggle-php-and-xml-mode)

;; toggle artiste-mode
(defun artist-mode-toggle ()
  "Toggle artist-mode"
  (interactive)
  (if (eq major-mode 'artist-mode)
      (artist-mode-off)
    (artist-mode)))
(global-set-key (kbd "C-c d") 'artist-mode-toggle)

;; toggle debug comments (C style)
;; (defun debug-comments-toggle ()
;;   "toggle /**/ and /*/")

;; uniquify!
(require 'uniquify)
(setq uniquify-buffer-name-style 'reverse)
(setq uniquify-separator "|")
(setq uniquify-after-kill-buffer-p t)
(setq uniquify-ignore-buffers-re "^\\*")

;; yasnippet!
(require 'dropdown-list)
(setq yas/prompt-functions '(yas/dropdown-prompt
                             yas/ido-prompt
                             yas/completing-prompt))
(require 'yasnippet)
(yas/initialize)
(yas/load-directory (concat emacs-dir "snippets/"))

;; ido! is fantastic
(require 'ido)
(ido-mode t)
(setq ido-enable-flex-matching t)

;; scrolling settings
(setq scroll-preserve-screen-position t)
(setq scroll-margin 2)
(setq scroll-step 1)

;; files should always end with a new line
(setq require-final-newline t)

;; no automatic saving and ugly #file#
(setq auto-save-default nil)

;; tramp ça claque (really bad french play-on-word)
(setq tramp-default-method "scp")

;; php-mode
(require 'php-mode)
(add-to-list 'auto-mode-alist
  '("\\.php[345]?\\'\\|\\.inc\\'" . php-mode))

;; js2-mode
(require 'js2-mode)
(add-to-list 'auto-mode-alist
  '("\\.js\\'\\|\\.json\\'" . js2-mode))

;; mmm-mode
;(require 'mmm-auto)
;(setq mmm-global-mode 'maybe)
;(setq mmm-submode-decoration-level 0)
;(mmm-add-classes
;  '((embedded-php
;     :submode php-mode
;     :front "<\\?php"
;     :back "\\?>"
;     :include-front t
;     :include-back t)))
;(add-to-list 'mmm-mode-ext-classes-alist '(html-mode nil embedded-php))
;(add-to-list 'auto-mode-alist
;  '("\\.phtml\\'" . html-mode))

;; xml-mode is better than nxml-mode or html-mode
(add-to-list 'auto-mode-alist
  '("\\.html\\'\\|\\.xml\\'\\|\\.phtml\\'" . xml-mode))

;; outline-mode
(add-to-list 'auto-mode-alist
  '("\\.list\\'" . outline-mode))

;; don't let Customize mess with my .emacs
(setq custom-file (concat emacs-dir "custom.el"))
(load custom-file 'noerror)

;; start the server for emacsclient use
(server-start)

;; open my todo list
(find-file "~/.todo")
(rename-buffer "*todo*")