;;; init.el --- Init file for emacs

;;; Commentary:

;; Init file, load everything necessary to have a full functional Emacs, this should
;; not be used with Emacs < 24.

;;; Code:

(add-to-list 'load-path "~/.emacs.d/one-file-mode/")

;; Themes
(setq custom-theme-directory "~/.emacs.d/themes/")
(load-theme 'hydandata-light t)

;; Packages
(require 'package) ;; You might already have this line
(add-to-list 'package-archives
             '("melpa" . "http://melpa.org/packages/"))
(when (< emacs-major-version 24)
  ;; For important compatibility libraries like cl-lib
  (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
(setq package-enable-at-startup nil)
(package-initialize) ;; You might already have this line

(require 'iso-transl)
(require 'use-package)

(setq use-package-verbose t)

;; No menu, scrollbar, display line and column
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(column-number-mode t)
(line-number-mode t)

;; Command rebinding

;; M-f (forward-word) : Déplacement d'un mot vers la droite du curseur.
;; M-b (backward-word) : Déplacement d'un mot vers la gauche du curseur.
;; C-a (beginning-of-line) : Déplacement au début de la ligne courante.
;; C-e (end-of-line) : Déplacement à la fin de la ligne courante.
;; M-{ (backward-paragraph) : Déplacement vers le paragraphe précédent.
(global-set-key (kbd "M-p") 'backward-paragraph)
;; M-} (forward-paragraph) : Déplacement vers le paragraphe suivant.
(global-set-key (kbd "M-n") 'forward-paragraph)
;; C-v (scroll-up) : Déplacement d'un écran vers le bas.
;; M-v (scroll-down) : Déplacement d'un écran vers le haut.
;; M-> (end-of-buffer) : Déplacement à la fin du buffer.
;; M-< (beginning-of-buffer) : Déplacement au début du buffer.


;; No split screen at startup
(setq inhibit-startup-screen t)

;; Encoding
(set-language-environment "UTF-8")

;; Selection mode
(delete-selection-mode 1)

;; Indentation mode
(setq-default indent-tabs-mode nil)
(setq tab-width 4)

;; Compilation coloration

(ignore-errors
  (require 'ansi-color)
  (defun my-colorize-compilation-buffer ()
    (when (eq major-mode 'compilation-mode)
      (ansi-color-apply-on-region compilation-filter-start (point-max))))
  (add-hook 'compilation-filter-hook 'my-colorize-compilation-buffer))

;; Auto complete + Yasnippet

(use-package sr-speedbar
  :config
  (setq speedbar-show-unknown-files t)
  (setq speedbar-use-images t))

(use-package semantic/sb
  :config
  ;; (semantic-mode)
  (global-set-key (kbd "C-c C-k C-l") 'sr-speedbar-toggle))

(use-package helm-config
  :config
  (global-set-key (kbd "M-x")      'helm-M-x)
  (global-set-key (kbd "C-x r b")  'helm-filtered-bookmarks)
  (global-set-key (kbd "C-x C-f")  'helm-find-files)
  (global-set-key (kbd "C-x C-b")  'helm-buffers-list)
  (helm-mode 1)
  (projectile-global-mode)
  (setq projectile-completion-system 'helm)
  (add-to-list 'helm-boring-buffer-regexp-list "\\*.*")
  (helm-projectile-on))

(use-package yasnippet
  :config
  (yas-global-mode 1))

(use-package flycheck
  :config
  (require 'flycheck-color-mode-line)
  (add-hook 'flycheck-mode-hook 'flycheck-color-mode-line-mode)
  (add-hook 'flycheck-mode-hook 'flycheck-pos-tip-mode)
  (add-hook 'flycheck-after-syntax-check-hook 'flycheck-autolist-hook)
  (global-flycheck-mode)
  (setq flycheck-emacs-lisp-load-path "inherit")
  (setq flycheck-clang-language-standard "-std=c++14")
  (setq flycheck-clang-args '("-W" "-Wall")))

(use-package company
  :init
  (require 'company-auctex)
  (setq company-backends (append company-backends '(company-c-headers
                                                    company-jedi
                                                    company-web-html)))
  (add-hook 'LaTeX-mode-hook 'company-auctex-init)
  (add-hook 'python-mode-hook
            (lambda ()
              (setq-local company-backends '(company-jedi))))
  :config
  (add-hook 'after-init-hook 'global-company-mode)
  (global-set-key (kbd "M-/") 'company-complete)
  (setq company-clang-arguments '("-std=c++14")))

;; Latex
(use-package tex-mik
    :config
    (setq TeX-auto-save t)
    (setq TeX-parse-self t)
    (setq-default TeX-master nil)
    (defun my-latex-mode-setup ()
      "Redefines and updates variables for various customizations."
      (setq LaTeX-paragraph-commands
            '("If" "State" "Loop" "For" "ForAll"))
      (setq LaTeX-begin-regexp
            (concat LaTeX-begin-regexp "\\|If\\b" "\\|Loop\\b" "\\|For\\b" "\\|ForAll\\b"))
      (setq LaTeX-end-regexp
            (concat LaTeX-end-regexp "\\|EndIf\\b" "\\|EndLoop\\b"
                    "\\|EndFor\\b" "\\|Else\\b" "\\|ElsIf\\b"))
      (setq LaTeX-paragraph-commands-regexp (LaTeX-paragraph-commands-regexp-make))
      (defun LaTeX-indent-level-count ()
        "Count indentation change caused by all \\left, \\right, \\begin, and
    \\end commands in the current line."
        (save-excursion
          (save-restriction
            (let ((count 0))
              (narrow-to-region (point)
                                (save-excursion
                                  (re-search-forward
                                   (concat "[^" TeX-esc "]"
                                           "\\(" LaTeX-indent-comment-start-regexp
                                           "\\)\\|\n\\|\\'"))
                                  (backward-char)
                                  (point)))
              (while (search-forward TeX-esc nil t)
                (cond
                 ((looking-at "left\\b")
                  (setq count (+ count LaTeX-left-right-indent-level)))
                 ((looking-at "right\\b")
                  (setq count (- count LaTeX-left-right-indent-level)))
                 ((looking-at LaTeX-begin-regexp)
                  (setq count (+ count LaTeX-indent-level)))
                 ((looking-at "Else\\b"))
                 ((looking-at "ElsIf\\b"))
                 ((looking-at LaTeX-end-regexp)
                  (setq count (- count LaTeX-indent-level)))
                 ((looking-at (regexp-quote TeX-esc))
                  (forward-char 1))))
              count)))))

    (add-hook 'LaTeX-mode-hook 'my-latex-mode-setup)
    (add-hook 'LaTeX-mode-hook 'visual-line-mode)
    (add-hook 'LaTeX-mode-hook 'flyspell-mode)
    (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)

    (add-hook 'LaTeX-mode-hook 'turn-on-reftex)
    (setq reftex-plug-into-AUCTeX t)
    (require 'tex)
    (TeX-global-PDF-mode t)
)

;; magit
(use-package magit
  :config
  (add-hook 'after-save-hook 'magit-after-save-refresh-status))

;; CSS style
(setq css-indent-offset 2)

;; Markdown mode
(use-package markdown-mode
    :mode "\\.text\\'" "\\.markdown\\'" "\\.md\\'")

;; White space mode & Fill mode column

(defun my-visual-hook ()
  (setq-default fill-column 95)
  (setq-local whitespace-line-column 95)
  (visual-line-mode t)
  (visual-fill-column-mode t)
  (define-key visual-line-mode-map [remap kill-line] nil)
  (whitespace-mode t))

(add-hook 'before-save-hook 'whitespace-cleanup)

(add-hook 'python-mode-hook (lambda () (setq-local whitespace-line-column 140)))
(add-hook 'LaTeX-mode-hook (lambda () (setq-local whitespace-line-column -1)))
(add-hook 'web-mode-hook (lambda () (setq-local whitespace-line-column -1)))

(add-hook 'text-mode-hook 'my-visual-hook)
(add-hook 'prog-mode-hook 'my-visual-hook)

;; Electric pair mode
(electric-pair-mode 1)
(show-paren-mode 1)
(setq show-paren-delay 0)

;; C mode
(setq c-default-style "k&r")
(setq c-basic-offset 4)

(use-package c++1x-minor-mode)

(defun ac-cc-mode-setup ()
  "Initialization hook for CC-mode runs before any other hooks."
  (hide-ifdef-mode)
  (hs-minor-mode)
  (setq hide-ifdef-shadow t))

(add-hook 'c-mode-common-hook 'ac-cc-mode-setup)
(add-hook 'c++-mode-common-hook 'ac-cc-mode-setup)
(add-hook 'auto-complete-mode-hook 'ac-common-setup)

(setq c-doc-comment-style
      '((java-mode . javadoc)
        (pike-mode . autodoc)
        (c-mode    . javadoc)
        (c++-mode  . javadoc)))

(add-to-list 'auto-mode-alist '("\\.hpp\\'" . c++-mode))

;; Run C programs directly from within emacs
(setq execute-command nil)
(setq execute-buffer-name "*output*")
(setq execute-process-name "execute")

(defun set-execute-command ()
  (interactive)
  (setq sp (split-string (read-from-minibuffer "Execute command: ")))
  (setq execute-command (combine-and-quote-strings (cons (file-truename (car sp)) (cdr sp)))))

(defun kill-execute-c-program ()
  (interactive)
  (if (get-process execute-process-name)
      (delete-process (get-process execute-process-name))))

(defun execute-c-program ()
  (interactive)
  (if (not execute-command) (set-execute-command))
  (kill-execute-c-program)
  (setq old-buffer (current-buffer))
  (setq output-buffer (get-buffer-create execute-buffer-name))
  (switch-to-buffer-other-window output-buffer)
  (end-of-buffer)
  (insert (concat (propertize execute-command 'face 'bold) "\n"))
  (switch-to-buffer-other-window old-buffer)
  (start-process-shell-command execute-process-name execute-buffer-name execute-command))

(defun key-c-mode-setup ()
  (local-set-key (kbd "C-c C-c") 'smart-compile)
  (local-set-key (kbd "C-c C-r") 'execute-c-program)
  (local-set-key [f3] 'kill-execute-c-program)
  (local-set-key [f4] 'set-execute-command))

(add-hook 'c++-mode-common-hook 'key-c-mode-setup)
(add-hook 'c-mode-common-hook 'key-c-mode-setup)

;; Flyspell dictionarie
(defun fd-switch-dictionary ()
  (interactive)
  (let* ((dic ispell-current-dictionary)
         (change (if (string= dic "francais") "english" "francais")))
    (ispell-change-dictionary change)
    (message "Dictionary switched from %s to %s" dic change)
    ))

(defun key-latex-mode-setup ()
  (local-set-key [f8] 'fd-switch-dictionary))

(add-hook 'LaTeX-mode-hook 'key-latex-mode-setup)

;; python

(use-package python-mode
  :mode "\\.py\\'"
  :config)

;; (use-package jedi
;;   :config
;;   (add-hook 'python-mode-hook 'jedi:setup)
;;   (setq jedi:complete-on-dot t))

(use-package cython-mode
  :init
  (require 'python-mode)
  (setq python-indent 4)
  (setq python-indent-offset 4)
  :mode "\\.pyx\\'")

;; Web mode
(add-to-list 'auto-mode-alist '("\\.ctp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))

;;(use-package mmm-mode
;;  :config
;;  (require 'mmm-auto)
;;  (setq mmm-global-mode 'maybe)
;;  (mmm-add-mode-ext-class 'html-mode "\\.php\\'" 'html-php)
;;  (mmm-add-mode-ext-class nil "\\.ctp\\'" 'html-php)
;;  (add-to-list 'mmm-mode-ext-classes-alist '(html-mode nil html-js))
;;  (add-to-list 'mmm-mode-ext-classes-alist '(html-mode nil embedded-css))
;;  (add-to-list 'mmm-mode-ext-classes-alist '(html-mode nil fancy-html)))

;; Term

(setq explicit-shell-file-name "/bin/bash")
(defun my-term-hook ()
  (visual-fill-column-mode nil)
  (visual-line-mode nil))
(add-hook 'term-load-hook 'my-term-hook)
(eval-after-load "term"
  '(define-key term-raw-map (kbd "C-c C-y") 'term-paste))

(setq custom-file "~/.emacs.d/custom.el")
(load custom-file)
(put 'narrow-to-region 'disabled nil)

(provide 'init)
;;; init.el ends here
