#+STARTUP: org-pretty-entities entitiespretty

#+SETUPFILE: ~/.emacs.d/org-html-themes/setup/theme-readtheorg-local.setup
#+PROPERTY: header-args :comments yes :results silent :exports both
#+options: h:3 num:t toc:3

#+TITLE: Configuration
#+OPTIONS: author:nil date:nil

#+LANGUAGE: fr

#+LATEX_CLASS_OPTIONS: [10pt]

#+LATEX_HEADER: \usepackage[hmargin=2.5cm,vmargin=1.5cm]{geometry}
#+LATEX_COMPILER: pdflatex --shell-escape

#+LATEX_HEADER_EXTRA: \usepackage{mdframed}
#+LATEX_HEADER_EXTRA: \BeforeBeginEnvironment{minted}{\begin{mdframed}}
#+LATEX_HEADER_EXTRA: \AfterEndEnvironment{minted}{\end{mdframed}}

* Choix d'interface
** Pas d'écran de bienvenue
#+BEGIN_SRC emacs-lisp
  (setq inhibit-startup-message t)
#+END_SRC

** Désactive des raccourcis
#+BEGIN_SRC emacs-lisp
  (global-set-key (kbd "C-x C-z") nil)
#+END_SRC

** Augumente la mémoire pour le /garbage collector/ \rArr meilleures performances
#+BEGIN_SRC emacs-lisp
  (setq gc-cons-threshold (* 100 1024 1024)
        read-process-output-max (* 1024 1024))
#+END_SRC

** /toolbar/
Elle est déactivée par défaut
#+BEGIN_SRC emacs-lisp
  (tool-bar-mode -1)
#+END_SRC

Elle est néanmoins lancée lorsque ~gud~ (l'interface à ~gdb~ dans Emacs)
est actif.
#+BEGIN_SRC emacs-lisp
  (load-file "~/.emacs.d/extra/tool-bar+.el")
  (require 'tool-bar+)
  (add-hook 'gud-mode-hook (lambda () (tool-bar-here-mode 1)))
#+END_SRC

** Réponses par y ou n
#+BEGIN_SRC emacs-lisp
  (fset 'yes-or-no-p 'y-or-n-p)
#+END_SRC

** Commentaires
| Raccourci | Description                       |
|-----------+-----------------------------------|
| ~C-c ;~     | Commente ou décommente une région |
#+BEGIN_SRC emacs-lisp
  (global-set-key (kbd "C-c ;") 'comment-or-uncomment-region)
#+END_SRC

** Désactive l'auto-save
#+BEGIN_SRC emacs-lisp
  (setq auto-save-default nil)
#+END_SRC

** Auto-fill
Utilise le mode mineur ~auto-fill~ (des retours à la ligne sont
automatiquement ajoutés quand les lignes sont trop longues).
#+BEGIN_SRC emacs-lisp
  (turn-on-auto-fill)
#+END_SRC
... sauf quand on code
#+BEGIN_SRC emacs-lisp
  (add-hook 'prog-mode-hook (lambda () (auto-fill-mode -1)))
#+END_SRC

** Supression des blancs inutiles
On retire les blancs qui traînent en fin de ligne à la sauvegarde d'un
/buffer/
#+BEGIN_SRC emacs-lisp
  (add-hook 'before-save-hook
            (lambda ()
              (when (not (derived-mode-p 'ein:notebook-multilang-mode))
                (delete-trailing-whitespace))))
#+END_SRC

** Numéros de lignes
Affiche les numéros des lignes en marge de gauche.
#+BEGIN_SRC emacs-lisp
  (when (version<= "26.0.50" emacs-version)
    (progn
      (global-display-line-numbers-mode 'visual)
      (add-hook 'pdf-view-mode-hook (lambda () (display-line-numbers-mode -1)))
      (add-hook 'compilation-mode-hook (lambda () (display-line-numbers-mode -1))))
    (add-hook 'magit-mode-hook (lambda () (display-line-numbers-mode -1)))
    (add-hook 'ediff-display-help-hook (lambda () (display-line-numbers-mode -1)))
    (add-hook 'gud-mode-hook (lambda () (display-line-numbers-mode -1)))
    (add-hook 'speedbar-before-popup-hook (lambda () (display-line-numbers-mode -1)))
    (custom-set-faces
     '(line-number-current-line ((t (:inherit line-number :foreground "dark gray")))))
    )
#+END_SRC

** Try
Permet d'essayer des paquets (sans les installer de manière permanente)
#+BEGIN_SRC emacs-lisp
  (use-package try
    :ensure t)
#+END_SRC

** Posframe
Affiche des boîtes de dialogue
#+BEGIN_SRC emacs-lisp
  (use-package posframe
    :ensure t)
#+END_SRC

** Which key
Aide en ligne pour les raccourcis (/quelle touche ?/)
#+BEGIN_SRC emacs-lisp
    (use-package which-key
      :ensure t
      :config
      (which-key-mode))
#+END_SRC

** Gnuplot
Ajout du mode ~gnuplot~, en particulier pour les interactions avec
~Org-mode~
#+BEGIN_SRC emacs-lisp
  (use-package gnuplot
    :ensure t)
#+END_SRC

** Org mode
/Org bullets/ pour un plus bel affichage des sections
#+BEGIN_SRC emacs-lisp
  (use-package org
    :ensure t
    :pin gnu)

  (setenv "BROWSER" "firefox")

  (use-package org-bullets
    :ensure t
    :config
    (add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))
    (add-hook 'org-babel-after-execute-hook
              '(lambda () (org-redisplay-inline-images)))
    (add-to-list 'org-latex-packages-alist '("" "listingsutf8"))
    (add-to-list 'org-latex-packages-alist '("" "minted")))

  (custom-set-variables
   '(org-default-notes-file (concat org-directory "/notes.org"))
   '(org-export-html-postamble nil)
   '(org-hide-leading-stars t)
   '(org-startup-folded (quote overview))
   '(org-startup-indented t)
   '(org-confirm-babel-evaluate nil)
   '(org-src-fontify-natively t)
   '(org-html-htmlize-output-type 'css)
   '(org-latex-listings 'minted)
   '(org-hide-emphasis-markers t))

  (setq org-startup-with-inline-images t)

  (setq org-latex-listings 'minted
        org-latex-packages-alist '(("" "minted"))
        org-latex-pdf-process
        '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
          "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

  (setq org-file-apps
        (append '(
                  ("\\.x?html?\\'" . "/usr/bin/firefox %s")
                  ) org-file-apps ))

  (global-set-key "\C-ca" 'org-agenda)
  (setq org-agenda-start-on-weekday nil)
  (setq org-agenda-custom-commands
        '(("c" "Simple agenda view"
           ((agenda "")
            (alltodo "")))))

  (global-set-key (kbd "C-c c") 'org-capture)

  (defun make-capture-frame ()
    "Create a new frame and run org-capture."
    (interactive)
    (make-frame '((name . "capture")))
    (select-frame-by-name "capture")
    (delete-other-windows)
    (noflet ((switch-to-buffer-other-window (buf) (switch-to-buffer buf)))
            (org-capture)))

  (define-key org-mode-map (kbd "C-c >")
    (lambda () (interactive (org-time-stamp-inactive))))

  (use-package htmlize
    :ensure t)

  (setq org-ditaa-jar-path "/usr/share/ditaa/ditaa.jar")
#+END_SRC

** Ace window
Permet de changer facilement de fenêtre. S'il y a plus de deux /buffers/
leur numéros sont affichés et il suffit de taper le numéro de la
fenêtre choisie pour s'y rendre.
| Raccourci | Description                            |
|-----------+----------------------------------------|
| ~C-x o~     | Met le curseur dans une autre fenêtre. |
#+BEGIN_SRC emacs-lisp
  (use-package ace-window
    :ensure t
    :init
    (progn
      (setq aw-scope 'global) ;; was frame
      (global-set-key (kbd "C-x O") 'other-frame)
      (global-set-key [remap other-window] 'ace-window)
      )
    :custom-face
    (aw-leading-char-face ((t (:inherit ace-jump-face-foreground :height 3.0))))
    )
#+END_SRC

** Window-jump
Permet de changer intuitivement de fenêtre en utilisant les flèches du
clavier. S'il y a plusieurs possibilités, la fenêtre choisie est celle
alignée avec le curseur.
| Raccourci | Description                                   |
|-----------+-----------------------------------------------|
| ~C-M-right~ | Déplace le curseur dans une fenêtre à droite  |
| ~C-M-left~  | Déplace le curseur dans une fenêtre à gauche  |
| ~C-M-up~    | Déplace le curseur dans une fenêtre au dessus |
| ~C-M-down~  | Déplace le curseur dans une fenêtre en dessous |
#+BEGIN_SRC emacs-lisp
  (use-package window-jump
    :ensure t
    :bind (("C-M-<up>" . 'window-jump-up)
           ("C-M-<down>" . 'window-jump-down)
           ("C-M-<right>" . 'window-jump-right)
           ("C-M-<left>" . 'window-jump-left)))
#+END_SRC

** Ivy / Counsel
Interface de complétion
#+BEGIN_SRC emacs-lisp
  (use-package counsel
    :ensure t
    :bind
    (("M-y" . counsel-yank-pop)
     :map ivy-minibuffer-map
     ("M-y" . ivy-next-line)))

  (use-package ivy
    :ensure t
    :demand t
    :diminish (ivy-mode)
    :bind (("C-x b" . ivy-switch-buffer))
    :config
    (ivy-mode 1)
    (setq ivy-use-virtual-buffers t)
    (setq ivy-count-format "%d/%d ")
    (setq ivy-display-style 'fancy)
    (setq ivy-wrap t)
    :custom-face
    (ivy-current-match ((t (:extend t :background "#27323D" :underline t :weight bold))))
  )

  (use-package ivy-rich
    :ensure t
    :hook (ivy-mode . ivy-rich-mode)
    :custom (ivy-rich-path-style 'abbrev)
    :config
    (ivy-rich-modify-columns
     'ivy-switch-buffer
     '((ivy-rich-switch-buffer-size (:align right))
       (ivy-rich-switch-buffer-major-mode (:width 20 :face error)))))
#+END_SRC

** Swiper
Améliore la recherche incrémentale. Les raccourcis sont les raccourcis
classiques. Deux différences notables.
- ~SPC~ joue le rôle de joker : ~r rc~ correspond au mot /recherche/ par
  exemple
- Si on souhaite créer un nouveau fichier avec ~C-x C-f~ dont le nom est
  une sous-chaîne d'un fichier existant, il ne faut pas utiliser ~RET~
  pour valider, mais ~C-M-j~. Utiliser ~RET~ valide la recherche, ~C-M-j~
  valide la chaîne saisie. Il est également possible de sélectionner
  la zone de saisie (avec les flèches) et de simplement valider la
  chaîne avec ~RET~.
| Raccourci | Description                                     |
|-----------+-------------------------------------------------|
| ~C-s~       | Recherche incrémentale vers le bas              |
| ~C-r~       | Recherche incrémentale vers le haut             |
| ~M-x~       | Recherche incrémentale d'une commande           |
| ~C-x C-f~   | Recherche incrémentale ou création d'un fichier |
#+BEGIN_SRC emacs-lisp
  (use-package swiper
    :ensure t
    :after ivy
    :bind (("C-s" . swiper-isearch)
           ("C-r" . swiper-isearch)
           ("C-c C-r" . ivy-resume)
           ("M-x" . counsel-M-x)
           ("C-x C-f" . counsel-find-file))
    :config
    (progn
      (setq ivy-use-virtual-buffers t)
      (setq ivy-display-style 'fancy)
      (setq ivy-use-selectable-prompt t)
      (define-key read-expression-map (kbd "C-r") 'counsel-expression-history)
      (define-key ivy-minibuffer-map (kbd "C-w") 'ivy-yank-word)
      )
    :custom-face
    (swiper-line-face ((t (:inherit highlight :underline t :weight bold))))
    (swiper-match-face-1 ((t (:background "#74b5727c5654" :foreground "black"))))
    (swiper-match-face-2 ((t (:background "#ce8bf1006cba" :foreground "black"))))
    (swiper-match-face-3 ((t (:background "#fefdc4fe5941" :foreground "black"))))
    (swiper-match-face-4 ((t (:background "#fefd9c40f85a" :foreground "black"))))
    )
#+END_SRC

** Avy
Saute très rapidement vers la zone de texte contenant une lettre.
| Raccourci | Description                         |
|-----------+-------------------------------------|
| ~M-s~       | Demande une lettre du mot recherché |
#+BEGIN_SRC emacs-lisp
  (use-package avy
    :ensure t
    :bind ("M-s" . avy-goto-word-1))
#+END_SRC

** COMMENT Company
Boîtes de dialogue pour la complétion
#+BEGIN_SRC emacs-lisp
  (use-package company
    :ensure t
    :config
    (setq company-idle-delay 0)
    (setq company-minimum-prefix-length 2)
    (setq company-tooltip-align-annotations t)
    (global-company-mode t)
    :custom-face
    (company-tooltip-selection ((t (:background "dim gray" :foreground "white" :weight normal))))
    )

  (use-package company-box
    :ensure t
    :hook (company-mode . company-box-mode))

  (defun my/python-mode-hook ()
    (add-to-list 'company-backends 'company-jedi))

  (add-hook 'python-mode-hook 'my/python-mode-hook)
  (use-package company-jedi
    :ensure t
    :config
    (add-hook 'python-mode-hook 'jedi:setup)
    )

  (defun my/python-mode-hook ()
    (add-to-list 'company-backends 'company-jedi))

  (add-hook 'python-mode-hook 'my/python-mode-hook)
#+END_SRC
** Treemacs
#+BEGIN_SRC emacs-lisp
  (use-package treemacs
    :ensure t)
#+END_SRC
** C++
Transforme Emacs en un véritable IDE en utilisant ~lsp~.

De nombreuses fonctionnalités sont accessibles au clic droit de la
souris. On peut accéder à de nombreuses fonctionnalités en utilisant
les raccourcis contextuels proposés par ~hydra~ en faisant ~C-l~.  En
passant la souris sur le texte, un /popup/ décrivant l'élément est
affiché.

On rappelle quelques raccourcis utiles :
| Raccourci         | Description                                           |
|-------------------+-------------------------------------------------------|
| ~M-.~ ou ~C-<mouse1>~ | Se rend à la déclaration de l'élément sous le curseur |
| ~M-?~               | Affiche les références à l'élément sous le curseur    |
| ~C-l~               | Débute l'interaction ~hydra~                            |
| ~C-<mouse3>~        | Menu contextuel                                       |
#+BEGIN_SRC emacs-lisp
  ;; config basique de lsp
  (use-package lsp-mode
    :ensure t
    :init
    (setq lsp-keymap-prefix "C-c l")
    ;; on vire les recommandations de codage : un peu lourd
    (setq lsp-ui-sideline-show-code-actions nil)
    (setq lsp-modeline-code-actions-enable nil)
    ;; on vire l'affichage de la doc sous le curseur : trop invasif
    (setq lsp-ui-doc-show-with-cursor nil)
    ;; on vire les ajouts de code automatiques à la complétion : insupportable
    (setq lsp-completion-enable-additional-text-edit nil)
    ;; barre de localisation
    (setq lsp-headerline-breadcrumb-enable t)
    :hook ((c++-mode . lsp)
           (python-mode . lsp)
           (lsp-mode . lsp-enable-which-key-integration))
    :custom-face
    (lsp-face-highlight-textual ((t (:inherit highlight :underline t))))
    :commands lsp)

  ;; on utilise lsp-ui et ivy
  (use-package lsp-ui
    :ensure t
    :commands lsp-ui-mode)
  (use-package lsp-ivy
    :ensure t
    :commands lsp-ivy-workspace-symbol)

  (use-package treemacs
    :ensure t)

  (use-package lsp-treemacs
    :ensure t
    :commands lsp-treemacs-errors-list)

  ;; autres paquets de base
  (setq package-selected-packages '(yasnippet tramp projectile hydra flycheck company avy which-key ivy-xref))

  (when (cl-find-if-not #'package-installed-p package-selected-packages)
    (package-refresh-contents)
    (mapc #'package-install package-selected-packages))

  (add-hook 'c-mode-hook 'lsp)
  (add-hook 'c++-mode-hook 'lsp)
  (setq lsp-keymap-prefix "C-c l")

                                          ; réactivité de lsp
  (setq lsp-idle-delay 0.1)

  (with-eval-after-load 'lsp-mode
    (add-hook 'lsp-mode-hook #'lsp-enable-which-key-integration)
    ;; (lsp-register-client
    ;;  ;; *** Mettre le chemin complet vers clangd ***
    ;;  (make-lsp-client :new-connection (lsp-tramp-connection "/home/test-emacs/bin/clangd")
    ;;                   :major-modes '(c++-mode)
    ;;                   :remote? t
    ;;                   :server-id 'clangd-remote))
    )
#+END_SRC

*** Formatage automatique : ~clang-format~
Création d'un raccourci spécial pour formater une zone du code.
| Raccourci | Description                                      |
|-----------+--------------------------------------------------|
| ~C-c C-f~   | Indente la région comme définie par clang-format |
#+BEGIN_SRC emacs-lisp
  (use-package clang-format
    :ensure t
    :bind
    (("C-c C-f" . clang-format-region)))
#+END_SRC

Surcharge l'indentation classique d'Emacs par ~clang-format~ en ~C~/~C++~.
Si ~clang-format~ n'est pas installé ou désactivé, l'indentation
classique fonctionne encore.
| Raccourci | Description                                      |
|-----------+--------------------------------------------------|
| ~<TAB>~     | Indente la région comme définie par ~clang-format~ |
#+BEGIN_SRC emacs-lisp
  (defun clang-format-c-mode-common-hook ()
    (define-key c-mode-base-map (kbd "<tab>")
      (lambda ()
        (interactive)
          (if (use-region-p)
              (progn
                (c-indent-line-or-region (region-beginning) (region-end))
                (clang-format-region (region-beginning) (region-end))
                )
            (progn
                (c-indent-line-or-region)
                (clang-format-region (point) (point)))))))
  (add-hook 'c-mode-common-hook 'clang-format-c-mode-common-hook)
#+END_SRC

Force le formatage du fichier quand il est sauvegardé
#+BEGIN_SRC emacs-lisp
  (defun clang-format-buffer-on-save ()
    "Add auto-save hook for clang-format-buffer-smart."
    (add-hook 'before-save-hook 'clang-format-buffer nil t))
  (add-hook 'c-mode-common-hook 'clang-format-buffer-on-save)
#+END_SRC

*** Coloration syntaxique (C++ moderne)
#+BEGIN_SRC emacs-lisp
  (use-package modern-cpp-font-lock
    :ensure t
    :init
    (eval-when-compile
      ;; Silence missing function warnings
      (declare-function modern-c++-font-lock-global-mode
                        "modern-cpp-font-lock.el"))
    :config (modern-c++-font-lock-global-mode t))
#+END_SRC

** Thèmes
Chargement de quelques thèmes
#+BEGIN_SRC emacs-lisp
  (use-package cloud-theme
    :ensure t)
  (use-package zenburn-theme
    :ensure t)
  (use-package sourcerer-theme
    :ensure t)
  (use-package monokai-theme
    :ensure t)
  (use-package gruvbox-theme
    :ensure t)
  (use-package bubbleberry-theme
    :ensure t)
  (use-package solarized-theme
    :ensure t)
#+END_SRC

** Modeline
Augmente la taille de la police
#+BEGIN_SRC emacs-lisp
  (defvar my-font-size 140)
#+END_SRC

Taille de la Modeline
#+BEGIN_SRC emacs-lisp
  (set-face-attribute 'mode-line nil  :height my-font-size)
#+END_SRC

Taille du titre
#+BEGIN_SRC emacs-lisp
  (set-face-attribute 'header-line nil  :height my-font-size)
#+END_SRC

Taille des attributs
#+BEGIN_SRC emacs-lisp
  (set-face-attribute 'default nil :height my-font-size)
#+END_SRC

Taille de la fenêtre et position
#+BEGIN_SRC emacs-lisp
  (setq default-frame-alist
        '((top . 0) (left . 0) ;; position
          (width . 110) (height . 90) ;; size
          ))
#+END_SRC

** Parenthèses arc-en-ciel
Améliore le visuel des parenthèses
#+BEGIN_SRC emacs-lisp
  (use-package rainbow-delimiters
    :ensure t
    :init
    (eval-when-compile
      ;; Silence missing function warnings
      (declare-function rainbow-delimiters-mode "rainbow-delimiters.el"))
    (add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
#+END_SRC

** FlyCheck
On charge ~FlyCheck~
#+BEGIN_SRC emacs-lisp
  (use-package flycheck
    :ensure t
    :init
    (global-flycheck-mode t))
#+END_SRC

Active ~FlyCheck~ globalement
#+BEGIN_SRC emacs-lisp
  (add-hook 'after-init-hook #'global-flycheck-mode)
#+END_SRC

On utilise ~posframe~ pour afficher les erreurs en ligne
#+BEGIN_SRC emacs-lisp
  (use-package flycheck-posframe
    :ensure t
    :init
    (flycheck-posframe-configure-pretty-defaults)
    :config
    (add-hook 'flycheck-mode-hook #'flycheck-posframe-mode)
    (setq flycheck-posframe-position 'window-bottom-left-corner))
#+END_SRC
** Python
Attention pour que la configuration fonctionne, il faut installer
~pylsp~.
#+BEGIN_SRC bash :eval no
  pip install python-lsp-server
#+END_SRC
#+BEGIN_SRC emacs-lisp
  (setq py-python-command "python3")
  (setq python-shell-interpreter "python3")

  (add-hook 'python-mode-hook
        (lambda ()
          (setq indent-tabs-mode nil)
          (setq tab-width 4)
          (setq python-indent-offset 4)))
#+END_SRC

** YASnippet
Le système de templates pour Emacs
#+BEGIN_SRC emacs-lisp
  (use-package yasnippet
    :ensure t
    :init
    (yas-global-mode 1)
    (unbind-key "<tab>" yas-minor-mode-map)
    :bind ("C-<return>" . yas-expand))

  (use-package yasnippet-snippets
    :ensure t)
#+END_SRC

** Divers paquets
*** Highlight line
Mise en valeur de la ligne courante
#+BEGIN_SRC emacs-lisp
  (global-hl-line-mode t)
#+END_SRC

*** Beacon
Flash de la ligne aux changements de page ou de buffer
#+BEGIN_SRC emacs-lisp
  (use-package beacon
    :ensure t
    :config
    (beacon-mode 1))
#+END_SRC

*** hungry-delete
Suppression de tous les blancs quand appuie sur backspace ou delete
#+BEGIN_SRC emacs-lisp
  (use-package hungry-delete
    :ensure t
    :config
    (global-hungry-delete-mode))
#+END_SRC

*** Expand-region
Sélectionne une zone de manière incrémentale. mot, phrase, paragraphe,
etc de manière intelligente.
#+BEGIN_SRC emacs-lisp
  (use-package expand-region
    :ensure t
    :config
    (global-set-key (kbd "C-=") 'er/expand-region))
#+END_SRC

*** Meilleure gestion du ~kill-ring~
#+BEGIN_SRC emacs-lisp
  (setq save-interprogram-paste-before-kill t)
#+END_SRC

*** Gestion de la restauration des buffers
#+BEGIN_SRC emacs-lisp
  (global-auto-revert-mode 1)
  (setq auto-revert-verbose nil)
  (setq revert-without-query (quote (".*.pdf")))
  (global-set-key (kbd "<f5>") 'revert-buffer)
#+END_SRC

** Powerline
Un bel affichage pour la barre d'état (/modeline/)
#+BEGIN_SRC emacs-lisp
  (use-package powerline
    :ensure t
    :config
    (powerline-default-theme)
    (setq powerline-default-separator 'utf-8)
    (setq powerline-gui-use-vcs-glyph 1))
#+END_SRC

Remplace le nom du mode majeur par une icône si possible.
#+BEGIN_SRC emacs-lisp
  (use-package mode-icons
    :ensure t
    :config (mode-icons-mode 1))
#+END_SRC

N'affiche pas tous les modes mineurs, les place dans le menu de la
/modeline/ désigné par un /smiley/.
#+BEGIN_SRC emacs-lisp
  (use-package minions
    :ensure t
    :config (minions-mode 1)
    (defpowerline powerline-major-mode "")
    (defpowerline powerline-process "")
    (defpowerline powerline-minor-modes minions-mode-line-modes))
#+END_SRC

** iedit
Modifie les copies d'une zone séléctionnée simultanément

| Raccourci | Description                |
|-----------+----------------------------|
| ~C-h C-;~   | démarrer les modifications |
| ~M-ESC ESC~ | sortir du mode             |
#+BEGIN_SRC emacs-lisp
  (use-package iedit
    :ensure t)
#+END_SRC

** Narrow/widen dwim
Réduit/agrandit une zone d'édition de manière intelligente
#+BEGIN_SRC emacs-lisp
  (defun narrow-or-widen-dwim (p)
    "If the buffer is narrowed, it widens. Otherwise, it narrows intelligently.
  Intelligently means: region, org-src-block, org-subtree, or defun,
  whichever applies first.
  Narrowing to org-src-block actually calls `org-edit-src-code'.

  With prefix P, don't widen, just narrow even if buffer is already
  narrowed."
    (interactive "P")
    (declare (interactive-only))
    (cond ((and (buffer-narrowed-p) (not p)) (widen))
          ((region-active-p)
           (narrow-to-region (region-beginning) (region-end)))
          ((derived-mode-p 'org-mode)
           ;; `org-edit-src-code' is not a real narrowing command.
           ;; Remove this first conditional if you don't want it.
           (cond ((ignore-errors (org-edit-src-code))
                  (delete-other-windows))
                 ((org-at-block-p)
                  (org-narrow-to-block))
                 (t (org-narrow-to-subtree))))
          (t (narrow-to-defun))))
#+END_SRC

Remplace la fonction Emacs standard par ~dwim~
#+BEGIN_SRC emacs-lisp
  (define-key ctl-x-map "n" #'narrow-or-widen-dwim)
  (add-hook 'LaTeX-mode-hook
            (lambda ()
              (define-key LaTeX-mode-map "\C-xn"
                nil)))
#+END_SRC

** Web Mode
Mode avancé pour l'édition de pages ~HTML~, ~Css~,...
#+BEGIN_SRC emacs-lisp
  (use-package web-mode
    :ensure t
    :config
    (add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.vue?\\'" . web-mode))
    (setq web-mode-engines-alist
          '(("django"    . "\\.html\\'")))
    (setq web-mode-ac-sources-alist
          '(("css" . (ac-source-css-property))
            ("vue" . (ac-source-words-in-buffer ac-source-abbrev))
            ("html" . (ac-source-words-in-buffer ac-source-abbrev))))
    (setq web-mode-enable-auto-closing t))
  (setq web-mode-enable-auto-quoting t) ; this fixes the quote problem I mentioned
#+END_SRC

** Emmet mode
Ensemble de fonctions permettant l'édition rapide de /markup languages/
(~HTML~, ~SGML~,...)
#+BEGIN_SRC emacs-lisp
  (use-package emmet-mode
    :ensure t
    :config
    ;; Auto-start on any markup modes
    (add-hook 'sgml-mode-hook 'emmet-mode)
    ;; Auto-start on any markup modes
    (add-hook 'web-mode-hook  'emmet-mode)
    ;; enable Emmet's css abbreviation
    (add-hook 'css-mode-hook  'emmet-mode))
#+END_SRC

** Dired-dwim
Permet d'utiliser réduire/agrandir les affichages de répertoires
#+BEGIN_SRC emacs-lisp
  (setq dired-dwim-target t)

  (use-package dired-narrow
    :ensure t
    :config
    (bind-key "C-c C-n" #'dired-narrow)
    (bind-key "C-c C-f" #'dired-narrow-fuzzy)
    (bind-key "C-x C-N" #'dired-narrow-regexp))

  (use-package dired-subtree
    :ensure t
    :after dired
    :config
    (bind-key "<tab>" #'dired-subtree-toggle dired-mode-map)
    (bind-key "<backtab>" #'dired-subtree-cycle dired-mode-map))
#+END_SRC

** LaTeX
Configuration LaTeX basique.
#+BEGIN_SRC emacs-lisp
  (use-package tex
    :ensure auctex
    :init
    (add-hook 'LaTeX-mode-hook 'turn-on-reftex)
    (setq TeX-parse-self t)
    :config
    (add-hook 'reftex-mode-hook
              '(lambda ()
                 (define-key reftex-mode-map (kbd "C-c [")
                   (lambda ()
                     (interactive)
                     (let ((ivy-count-format "'=' for all | %d/%d "))
                       (reftex-citation)
                       ))))))
#+END_SRC

** Gestion de projets
#+BEGIN_SRC emacs-lisp
  (use-package projectile
    :ensure t
    :bind ("C-c p" . projectile-command-map)
    :config
    (projectile-mode)
    (setq projectile-completion-system 'ivy))
#+END_SRC

** Org-mode (langages suportés)
Charge les langages disponibles pour org-mode
#+BEGIN_SRC emacs-lisp
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((python . t)
     (emacs-lisp . t)
     (shell . t)
     (C . t)
     (gnuplot . t)
     (js . t)
     (ditaa . t)
     (dot . t)
     (org . t)
     (latex . t )))
  (setq org-babel-python-command "python3")
  (add-hook 'org-babel-after-execute-hook
            'org-redisplay-inline-images)
#+END_SRC

** Parenthèses
Gestion intelligente des parenthèses.

*Attention* les guillemets sont automatiquement échappés à l'intérieur
de chaînes de caractères, ce qui peut être gênant pour l'utilisateur
non averti. Pour couper une chaîne en deux morceaux, utiliser alors le
raccourci suivant.
| Raccourci | Description                           |
|-----------+---------------------------------------|
| ~C-"~       | Coupe la chaîne de caractères en deux |

#+BEGIN_SRC emacs-lisp
  (use-package smartparens
    :ensure t
    :hook (prog-mode . smartparens-mode)
    :custom
    (sp-escape-quotes-after-insert nil)
    :config
    (require 'smartparens-config)
    (global-set-key (kbd "C-\"") 'sp-split-sexp)
    :custom-face
    (show-paren-match ((t (:background "green" :foreground "grey15" :inverse-video t :weight bold))))
    )

  (show-paren-mode t)
  (setq show-paren-style 'mixed)
#+END_SRC

Affiche le contexte de la parenthèse associée dans le /mini-buffer/ si
elle n'apparaît pas à l'écran.

#+BEGIN_SRC emacs-lisp
  (use-package mic-paren
    :ensure t
    )

  (paren-activate)
#+END_SRC

** Taille de la police
Change la taille de la police dynamiquement (temporaire)
| Raccourci | Description                     |
|-----------+---------------------------------|
| ~C-M-=~     | Augmente la taille de la police |
| ~C-M--~     | Réduit la taille de la police   |
#+BEGIN_SRC emacs-lisp
  (use-package default-text-scale
    :ensure t
    :config
    (global-set-key (kbd "C-M-=") 'default-text-scale-increase)
    (global-set-key (kbd "C-M--") 'default-text-scale-decrease))
#+END_SRC

** Hydra
Outil de simplification des raccourcis. Un /popup/ contextuel apparaît.
| Raccourci | Description                           |
|-----------+---------------------------------------|
| ~C-x t~     | Active désactive certains utilitaires |
| ~C-c t~     | Gestion du timer                      |
#+BEGIN_SRC emacs-lisp
  (use-package hydra
    :ensure hydra
    :init
    (global-set-key
     (kbd "C-x t")
     (defhydra toggle (:color blue :hint nil)
       "
                        Toggle
  --------------------------------------------------
   [_a_] Abbrev    [_s_] FlySpell    [_c_] FlyCheck
   [_d_] Debug     [_f_] Auto-Fill   [_t_] Truncate lines
   [_l_] Line num. [_w_] Whitespace  [_q_] Quit"
       ("a" abbrev-mode)
       ("s" flyspell-mode)
       ("c" flycheck-mode)
       ("d" toggle-debug-on-error)
       ("f" auto-fill-mode)
       ("t" toggle-truncate-lines)
       ("l" display-line-numbers-mode)
       ("w" whitespace-mode)
       ("q" nil)))
    (global-set-key
     (kbd "C-c t")
     (defhydra hydra-global-org (:color blue)
       "Org"
       ("t" org-timer-start "Start Timer")
       ("s" org-timer-stop "Stop Timer")
       ("r" org-timer-set-timer "Set Timer") ; This one requires you be in an orgmode doc, as it sets the timer for the header
       ("p" org-timer "Print Timer") ; output timer value to buffer
       ("w" (org-clock-in '(4)) "Clock-In") ; used with (org-clock-persistence-insinuate) (setq org-clock-persist t)
       ("o" org-clock-out "Clock-Out") ; you might also want (setq org-log-note-clock-out t)
       ("j" org-clock-goto "Clock Goto") ; global visit the clocked task
       ("c" org-capture "Capture") ; Don't forget to define the captures you want http://orgmode.org/manual/Capture.html
       ("l" (or )rg-capture-goto-last-stored "Last Capture"))
     ))
#+END_SRC

** Modes git
Le sublime ~Magit~.
| Raccourci | Description                      |
|-----------+----------------------------------|
| ~C-x g~     | Démarre *magit* (~M-x magit-status~) |
#+BEGIN_SRC emacs-lisp
  (use-package magit
    :ensure t
    :init
    (progn
      (bind-key "C-x g" 'magit-status))
    :config
    (setq magit-display-buffer-function 'magit-display-buffer-same-window-except-diff-v1))
#+END_SRC

Affiche l'état ~git~ dans la marge?
#+BEGIN_SRC emacs-lisp
  (setq magit-status-margin
        '(nil "%Y-%m-%d %H:%M " magit-log-margin-width t 18))
#+END_SRC

Utilise ~git-gutter~ avec ~hydra~. Permet de voir rapidement les
modifications, de les valider (~git add -p~) ou de les annuler (~git
checkout -p~)
| Raccourci | Description                                       |
|-----------+---------------------------------------------------|
| ~M-g M-g~   | Lance le menu ~Hydra~ pour l'interaction ~git-gutter~ |
#+BEGIN_SRC emacs-lisp
  (use-package git-gutter
    :ensure t
    :init
    (global-git-gutter-mode +1)
    (add-hook 'magit-post-refresh-hook
              #'git-gutter:update-all-windows)
    :custom-face
    (git-gutter:added ((t (:inherit bold :background "green" :foreground "gray15" :inverse-video t :weight bold))))
    (git-gutter:deleted ((t (:inherit bold :background "red" :foreground "gray15" :inverse-video t :weight bold))))
    (git-gutter:modified ((t (:inherit bold :background "yellow" :foreground "gray15" :inverse-video t :weight bold))))
    )

  (global-set-key (kbd "M-g M-g") 'hydra-git-gutter/body)

  (use-package git-timemachine
    :ensure t)
  (defhydra hydra-git-gutter (:body-pre (git-gutter-mode 1)
                                        :hint nil)
    "
  Git gutter:
    _j_: next hunk        _s_tage hunk     _q_uit
    _k_: previous hunk    _r_evert hunk    _Q_uit and deactivate git-gutter
    ^ ^                   _p_opup hunk
    _h_: first hunk
    _l_: last hunk        set start _R_evision
  "
    ("j" git-gutter:next-hunk)
    ("k" git-gutter:previous-hunk)
    ("h" (progn (goto-char (point-min))
                (git-gutter:next-hunk 1)))
    ("l" (progn (goto-char (point-min))
                (git-gutter:previous-hunk 1)))
    ("s" git-gutter:stage-hunk)
    ("r" git-gutter:revert-hunk)
    ("p" git-gutter:popup-hunk)
    ("R" git-gutter:set-start-revision)
    ("q" nil :color blue)
    ("Q" (progn (git-gutter-mode -1)
                ;; git-gutter-fringe doesn't seem to
                ;; clear the markup right away
                (sit-for 0.1)
                (git-gutter-mode))
     :color blue))
#+END_SRC

** FlySpell
Correcteur orthographique à la volée.
#+BEGIN_SRC emacs-lisp
  (add-hook 'LaTeX-mode-hook 'turn-on-flyspell)
  (add-hook 'git-commit-setup-hook 'git-commit-turn-on-flyspell)
  (add-hook 'c++-mode-hook 'flyspell-prog-mode)
  (add-hook 'c-mode-hook 'flyspell-prog-mode)
  (add-hook 'python-mode-hook 'flyspell-prog-mode)
  (add-hook 'LaTeX-mode-hook 'turn-on-flyspell)
  (add-hook 'org-mode-hook 'turn-on-flyspell)
  (add-hook 'org-mode-hook 'turn-on-auto-fill)
  (add-hook 'mu4e-compose-mode-hook 'turn-on-flyspell)
  (add-hook 'mu4e-compose-mode-hook 'turn-on-auto-fill)
  (setq flyspell-issue-message-flag nil)
#+END_SRC

** Compilation
Active le rendu des couleurs ANSI dans le /buffer/ de compilation
#+BEGIN_SRC emacs-lisp
  (defun endless/colorize-compilation ()
    "Colorize from `compilation-filter-start' to `point'."
    (let ((inhibit-read-only t))
      (ansi-color-apply-on-region
       compilation-filter-start (point))))
  (add-hook 'compilation-filter-hook
            #'endless/colorize-compilation)
#+END_SRC

Force la création du /buffer/ de compilation en dessous
#+BEGIN_SRC emacs-lisp
  (defun display-buffer-by-splitting-largest (buffer force-other-window)
    "Display buffer BUFFER by splitting the largest buffer vertically, except if
    there is already a window for it."
    (or (get-buffer-window buffer)
        (let ((new-win
               (with-selected-window (get-largest-window)
                 (split-window-vertically))))
          (set-window-buffer new-win buffer)
          new-win)))
  (defun my-compile ()
    "Ad-hoc display of compilation buffer."
    (interactive)
    (let ((display-buffer-function 'display-buffer-by-splitting-largest))
      (call-interactively 'compile)))
#+END_SRC

Quelques réglages supplémentaires.
#+BEGIN_SRC emacs-lisp
  (setq-default
   compilation-read-command t
   compilation-scroll-output 'first-error
   compilation-ask-about-save nil
   compilation-window-height 15)
#+END_SRC

Définit ~C-c C-c~ comme raccourci pour invoquer ~make~.
#+BEGIN_SRC emacs-lisp
  (global-set-key (kbd "C-c C-c") 'compile)
  (global-set-key (kbd "M-<up>") 'previous-error)
  (global-set-key (kbd "M-<down>") 'next-error)
  (defun compilation-c-mode-common-hook ()
    (define-key c-mode-base-map (kbd "C-c C-c") 'my-compile)
    (setq compilation-scroll-output 'first-error))
  (add-hook 'c-mode-common-hook 'compilation-c-mode-common-hook)
#+END_SRC

** CMake
#+BEGIN_SRC emacs-lisp
  (use-package cmake-mode
    :ensure t
    :mode ("CMakeLists.txt" ".cmake")
    :hook (cmake-mode . (lambda ()
                          (add-to-list 'company-backends 'company-cmake)))
    )

  (use-package cmake-font-lock
    :ensure t
    :commands (cmake-font-lock-activate)
    :hook (cmake-mode . (lambda ()
                          (cmake-font-lock-activate)
                          (font-lock-add-keywords
                           nil '(("\\<\\(FIXME\\|TODO\\|BUG\\|DONE\\)"
                                  1 font-lock-warning-face t)))))
    )
#+END_SRC

** Markdown
#+BEGIN_SRC emacs-lisp
  (use-package markdown-mode
    :ensure t
    :mode (".md" ".markdown"))
#+END_SRC

** Dumb jump
Permet de se déplacer *très* rapidement dans un texte ou de retrouver
une définition.
| Raccourci | Description                                                             |
|-----------+-------------------------------------------------------------------------|
| ~M-g j~     | Saute à la définition de l'objet sous le curseur                        |
| ~M-g o~     | Saute à la définition de l'objet sous le curseur dans une autre fenêtre |
#+BEGIN_SRC emacs-lisp
  (use-package dumb-jump
    :bind (("M-g o" . dumb-jump-go-other-window)
           ("M-g j" . dumb-jump-go)
           ("M-g x" . dumb-jump-go-prefer-external)
           ("M-g z" . dumb-jump-go-prefer-external-other-window))
    :init
    (dumb-jump-mode)
    :ensure t)
#+END_SRC

** Origami
Mode permettant le pliage (/folding/) de régions
#+BEGIN_SRC emacs-lisp
  (use-package origami
    :ensure t)
#+END_SRC

** IBuffer
Un meilleur gestionnaire de /buffers/.

| Raccourci | Description                      |
|-----------+----------------------------------|
| ~C-x C-b~   | Ouvre le gestionnaire de /buffers/ |
| ~C-x b~     | Change de /buffer/                 |
#+BEGIN_SRC emacs-lisp
  (global-set-key (kbd "C-x C-b") 'ibuffer)
  (setq ibuffer-saved-filter-groups
        (quote (("default"
                 ("dired" (mode . dired-mode))
                 ("org" (name . "^.*org$"))
                 ("magit" (mode . magit-mode))
                 ("IRC" (or (mode . circe-channel-mode)
                            (mode . circe-server-mode)))
                 ("web" (or (mode . web-mode) (mode . js2-mode)))
                 ("shell" (or (mode . eshell-mode) (mode . shell-mode)))
                 ("mu4e" (or (mode . mu4e-compose-mode)
                             (name . "\\*mu4e\\*")))
                 ("programming" (or (mode . clojure-mode)
                                    (mode . clojurescript-mode)
                                    (mode . python-mode)
                                    (mode . c++-mode)))
                 ("emacs" (or (name . "^\\*scratch\\*$")
                              (name . "^\\*Messages\\*$")))
                 ))))
  (add-hook 'ibuffer-mode-hook
            (lambda ()
              (ibuffer-auto-mode 1)
              (ibuffer-switch-to-saved-filter-groups "default")))

  ;; Don't show filter groups if there are no buffers in that group
  (setq ibuffer-show-empty-filter-groups nil)

  ;; Don't ask for confirmation to delete marked buffers
  (setq ibuffer-expert t)
#+END_SRC

** WGrep
Permet de modifier le résultat d'un ~grep~ (donc simultanément dans
plusieurs fichiers par exemple).

| Raccourci | Description                                            |
|-----------+--------------------------------------------------------|
| ~C-c C-p~   | passe en mode écriture dans le buffer résultat de *grep* |
| ~C-c C-e~   | sauve les modifications                                |
| ~C-x C-q~   | quitte le mode                                         |
voir [[https://github.com/emacsmirror/emacswiki.org/blob/master/wgrep.el][wgrep]] pour plus d'infos.
#+BEGIN_SRC emacs-lisp
  (use-package wgrep
    :ensure t)
  (use-package wgrep-ag
    :ensure t)
  (require 'wgrep-ag)
#+END_SRC

** PDF tools
Outils d'édition de ~PDF~ dans Emacs
#+BEGIN_SRC emacs-lisp
  (use-package pdf-tools
    :ensure t
    :config
    (when (eq system-type 'gnu/linux)
      (pdf-tools-install)
      (setq TeX-view-program-selection '((output-pdf "pdf-tools")))
      (setq TeX-view-program-list '(("pdf-tools" "TeX-pdf-tools-sync-view"))))
    :init
    (add-hook 'LaTeX-mode-hook
              '(lambda () (local-set-key (kbd "C-c C-g")
                                         'pdf-sync-forward-search))))

  (use-package org-pdftools
    :ensure t)
#+END_SRC

** AutoYASnippet
Outil de création rapide de snipets.
Voir la documentation en ligne [[https://github.com/abo-abo/auto-yasnippet]]
#+BEGIN_SRC emacs-lisp
  (use-package auto-yasnippet
    :ensure t)
#+END_SRC

** Divers
Quelques réglages utilitaires
#+BEGIN_SRC emacs-lisp
  (setq browse-url-browser-function 'browse-url-generic
        browse-url-generic-program "firefox")
  (setq auto-window-vscroll nil)
  (blink-cursor-mode t)
  (setq default-frame-alist
        '((cursor-color . "DarkGrey")))
#+END_SRC

** Keyfreq
Enregistre la fréquence d'utilisation de commandes. Pour obtenir les
statistiques, utiliser la commande ~M-x keyfreq-show~
#+BEGIN_SRC emacs-lisp
  (use-package keyfreq
    :ensure t
    :config
    (require 'keyfreq)
    (keyfreq-mode 1)
    (keyfreq-autosave-mode 1))
#+END_SRC

** Dictionnaire et césures
#+BEGIN_SRC emacs-lisp
  (use-package dictionary
    :ensure t)
  (use-package synosaurus
    :ensure t)
#+END_SRC

** Mode pugs
#+BEGIN_SRC emacs-lisp
  (load-library "~/.emacs.d/extra/pugs.el")
  (add-to-list 'auto-mode-alist '("\\.pgs?\\'" . pugs-mode))
  (require 'pugs-mode)
#+END_SRC

* Annexes
** Génération de toute la documentation

On génère la documentation ~HTML~ et ~PDF~ de cette configuration à partir
de tous les fichier ~.org~ du répertoire de configuration Emacs.
#+BEGIN_SRC emacs-lisp
  (defun config-org-to-export()
    "Regenerate all .emacs.d docs"
    (interactive)
    (let ((files (file-expand-wildcards "~/.emacs.d/*.org")))
      (mapc
       (lambda (f) .
         ((with-current-buffer
              (find-file-noselect f)
            (org-latex-export-to-pdf)
            (org-html-export-to-html))))
       files)))
#+END_SRC

# Local Variables:
# ispell-local-dictionary: "francais"
# End: