;;; BOOTSTRAP: (require 'package) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t) (add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") t) (package-initialize) ;;;; Put variables set by customize out of the way (setq custom-file (expand-file-name "customize.el" user-emacs-directory)) (when (file-exists-p custom-file) (load custom-file)) ;;;; Put autogenerated files aside (setq auto-save-file-name-transforms (quote ((".*" "~/.emacs.d/.autogeneres/auto-save-files/" t)))) (setq auto-save-list-file-prefix "~/.emacs.d/.autogeneres/auto-save-list/saves-") (setq backup-directory-alist (quote ((".*" . "~/.emacs.d/backups/")))) ;;; BASIC DEFAULTS (setq shift-select-mode t ; select with shift transient-mark-mode t x-select-enable-clipboard-manager nil ; dont’t transfer emacs clipboard data to X clipboard manager on exit (avoid hangups) hi-lock-file-patterns-policy t ; Automatically load hi-lock patterns if found in file help-window-select 'other show-paren-style 'mixed) ; Show show the matching paren if it is visible, and the expression otherwise (show-paren-mode 1) ; turn on paren highlighting (delete-selection-mode) (require 'uniquify) ;uniquify buffer names (setq uniquify-buffer-name-style 'reverse) ; path after file name to ease autocompletion (defalias 'yes-or-no-p 'y-or-n-p) ; Never ask long confirmations (put 'narrow-to-region 'disabled nil) ; Enable narrow-to region. Bound to C-x n n. (put 'list-timers 'disabled nil) ; Enable list-timers (require 'iso-transl) ; Don’t complain that dead-circumflex is undefined ;;; TEXT DEFAULTS: ;;;; Basics ;; (setq visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow)) ; materialiser les limites des lignes (electric-pair-mode) (setq sentence-end-double-space nil) (setq-default use-hard-newlines t) ; or Ctrl-o to insert hard new lines (never filled) (global-set-key (kbd "M-q") 'org-fill-paragraph) ; Rebind M-q to the org function which seems to work better in mails etc. ;;;; Autofill ;; (add-hook 'text-mode-hook 'turn-on-auto-fill) (add-hook 'fill-nobreak-predicate 'fill-french-nobreak-p) (add-hook 'fill-nobreak-predicate 'fill-single-word-nobreak-p) ;;;; Guillemets et apostrophes (defvar V-syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?’ "w" table) (modify-syntax-entry ?- "w" table) (modify-syntax-entry ?« "(»" table) (modify-syntax-entry ?» ")«" table) table)) (defun V-guillemets () "Insert a pair of guillemets and leave cursor in the middle. If region is active wrap in guillemets instead" (interactive) (let ((rend (region-end)) (rbeg (region-beginning))) (if (region-active-p) (progn (goto-char rend) (insert " »") (goto-char rbeg) (insert "« ")) (progn (insert "«  »");<-- deux espaces insécables (backward-char 2))))) ;; Mimick auto-fill-mode but leave long lines (add-hook 'visual-line-mode-hook #'visual-fill-column-mode) (setq visual-fill-column-fringes-outside-margins t) (advice-add 'text-scale-adjust :after #'visual-fill-column-adjust) (add-hook 'text-mode-hook (lambda () (set-syntax-table V-syntax-table) (local-set-key "«" 'V-guillemets) (electric-quote-mode) ; Pair curved quotes for opening/closing (turn-on-visual-line-mode))) (add-hook 'mu4e-compose-mode-hook (lambda () (local-set-key "«" 'V-guillemets) (orgalist-mode 1) (turn-on-visual-line-mode))) ;;;; Opposite of fill-paragraph (defun unfill-region (beg end) "Unfill the region, joining text paragraphs into a single logical line. This is useful, e.g., for use with `visual-line-mode'." (interactive "*r") (let ((fill-column (point-max))) (fill-region beg end))) ;; Handy key definition (global-set-key "\M-Q" 'unfill-region) ;;;; Better word navigation ;; From https://www.emacswiki.org/emacs/download/misc-cmds.el (defun to-next-word (&optional n) "Go to the beginning of the Nth word after point. N defaults to 1 (next word)." (interactive "p") (if (< n 0) (to-previous-word (- n)) (dotimes (_ n) (let ((opt (point))) (skip-syntax-forward "^w") (when (eq opt (point)) (skip-syntax-forward "w") (skip-syntax-forward "^w")))))) (defun to-previous-word (&optional n) "Go to the beginning of the Nth word before point. N defaults to 1 (previous word)." (interactive "p") (if (< n 0) (to-next-word (- n)) (dotimes (_ n) (let ((opt (point))) (skip-syntax-backward "w") (when (eq opt (point)) (skip-syntax-backward "^w") (skip-syntax-backward "w")))))) (global-set-key (kbd "M-f") 'to-next-word) (global-set-key (kbd "M-b") 'to-previous-word) ;;;; Expand-region (require 'expand-region) (global-set-key (kbd "C-à") 'er/expand-region) ;;;; Wrap region (require 'wrap-region) (wrap-region-add-wrappers '(("*" "*" nil org-mode) ("~" "~" nil org-mode) ("/" "/" nil org-mode) ("=" "=" nil org-mode) ("_" "_" nil org-mode) ("$" "$" nil (org-mode latex-mode)) ("« " " »" "«" (org-mode mu4e-compose message-mode)))) (add-hook 'org-mode-hook 'wrap-region-mode) (add-hook 'mu4e-compose-mode-hook 'wrap-region-mode) (add-hook 'latex-mode-hook 'wrap-region-mode) ;;;; Abbrevs (define-abbrev-table 'global-abbrev-table '( ("->" "→") ("-->" "⇉"))) (abbrev-mode 1) ; turn on abbrev mode ;;; SOME CUSTOM KEYBINDINGS: ;;;; Isearch (progn ;; set arrow keys in isearch. left/right is backward/forward, up/down is history. press Return to exit (define-key isearch-mode-map (kbd "") 'isearch-ring-retreat ) (define-key isearch-mode-map (kbd "") 'isearch-ring-advance ) (define-key isearch-mode-map (kbd "") 'isearch-repeat-backward) (define-key isearch-mode-map (kbd "") 'isearch-repeat-forward)) ;;;; Various (global-set-key (kbd "C-ç") 'comment-dwim-2) (global-set-key "\M-n" 'forward-paragraph) (global-set-key "\M-p" 'backward-paragraph) (global-set-key "\M-/" 'hippie-expand) ; 'dabbrev-expand is one of the functions in hippie-expand-try-functions-list anyway ;;; WINDOW and BUFFER behavior: ;;;; Basics (setq split-height-threshold 39 split-width-threshold 80) (setq ediff-split-window-function 'split-window-horizontally) ; split window vertically for ediff ;;;; Efficiently Kill buffers and their windows ;; From https://www.emacswiki.org/emacs/download/misc-cmds.el ;; Candidate as a replacement for `kill-buffer', at least when used interactively. ;; For example: (define-key global-map [remap kill-buffer] 'kill-buffer-and-its-windows) ;; ;; We cannot just redefine `kill-buffer', because some programs count on a ;; specific other buffer taking the place of the killed buffer (in the window). (defun kill-buffer-and-its-windows (buffer) "Kill BUFFER and delete its windows. Default is `current-buffer'. BUFFER may be either a buffer or its name (a string)." (interactive (list (read-buffer "Kill buffer: " (current-buffer) 'existing))) (setq buffer (get-buffer buffer)) (if (buffer-live-p buffer) ; Kill live buffer only. (let ((wins (get-buffer-window-list buffer nil t))) ; On all frames. (when (and (buffer-modified-p buffer) (fboundp '1on1-flash-ding-minibuffer-frame)) (1on1-flash-ding-minibuffer-frame t)) ; Defined in `oneonone.el'. (when (kill-buffer buffer) ; Only delete windows if buffer killed. (dolist (win wins) ; (User might keep buffer if modified.) (when (window-live-p win) ;; Ignore error, in particular, ;; "Attempt to delete the sole visible or iconified frame". (condition-case nil (delete-window win) (error nil)))))) (when (interactive-p) (error "Cannot kill buffer. Not a live buffer: `%s'" buffer)))) (define-key global-map [remap kill-buffer] 'kill-buffer-and-its-windows) (when (fboundp 'quit-restore-window) (defun quit-window-delete (&optional kill window) "Quit WINDOW, deleting it, and bury its buffer. WINDOW must be a live window and defaults to the selected one. With prefix argument KILL non-nil, kill the buffer instead of burying it. This is similar to the version of `quit-window' that Emacs had before the introduction of `quit-restore-window'. It ignores the information stored in WINDOW's `quit-restore' window parameter. It deletes the WINDOW more often, rather than switching to another buffer in it. If WINDOW is alone in its frame then the frame is deleted or iconified, according to option `frame-auto-hide-function'." (interactive "P") (set-window-parameter window 'quit-restore `(frame frame nil ,(current-buffer))) (quit-restore-window window (if kill 'kill 'bury)))) ;; Kill window opened by debug, auto-complete etc. (defun quit-next-window () "If there are multiple windows, then close the other pane and kill the buffer in it also." (interactive) (other-window 1) (quit-window)) (defun quit-next-window-delete () "If there are multiple windows, then close the other pane and kill the buffer in it also." (interactive) (other-window 1) (quit-window-delete)) ;;;; Window shortcuts (winner-mode 1) (global-set-key (kbd "M-þ") 'winner-undo) (global-set-key (kbd "M-\"") 'delete-other-windows) (global-set-key (kbd "M-«") 'split-window-vertically) (global-set-key (kbd "M-»") 'split-window-horizontally) (require 'ace-window) (global-unset-key (kbd "M-t")) ;; transpose-char (global-set-key (kbd "M-t") 'ace-window) (setq aw-keys '(?t ?s ?r ?n ?a ?u ?i ?e ) aw-dispatch-always nil) ;;;; Buffer shortcuts (global-set-key (kbd "C-ê") 'previous-buffer) (global-set-key (kbd "M-ê") 'next-buffer) ;;; APPEARANCE: ;;;; Theme: ;; (load-theme 'monokai t) (load-theme 'gruvbox-dark-medium t) ;; (load-theme 'gruvbox-light-medium t) ;; (load-theme 'tao-yang t) ;;;;; Monokai settings: (defun V-monokai-theme () (require 'monokai-theme) ;; Need to load it to configure it (setq monokai-height-minus-1 0.8 monokai-height-plus-1 1.1 monokai-height-plus-2 1.15 monokai-height-plus-3 1.2 monokai-height-plus-4 1.3) (setq monokai-use-variable-pitch t) (custom-theme-set-faces 'monokai `(mu4e-replied-face ((t (:foreground ,"YellowGreen"))) NOW)) (custom-theme-set-faces 'monokai `(mu4e-forwarded-face ((t (:foreground ,"LightGoldenrod"))) NOW))) ;;;; Display time in modeline (display-time) (setq display-time-24hr-format t display-time-default-load-average nil) ;;;; Mixed-pitch-mode: (add-hook 'text-mode-hook 'mixed-pitch-mode) (setq mixed-pitch-variable-pitch-cursor 'box) ;;;; Toolbar and scrollbar (tool-bar-mode -1) ;turn off toolbar (scroll-bar-mode -1) ;turn off scrollbar ;;; OUTLINE MODE (add-hook 'emacs-lisp-mode-hook (lambda () (set (make-local-variable 'outline-regexp) ";;;[;]*"))) (add-hook 'Man-mode-hook (lambda () (set (make-local-variable 'outline-regexp) "[A-Z]\\|\\s-+[-+]"))) ;;; DIRED: ;;;; Basics ;; -si for human readable size time-style for yyyy-mm-dd (setq dired-listing-switches "-Al --si --time-style long-iso" delete-by-moving-to-trash t dired-recursive-copies (quote always) ; always means don’t ask dired-recursive-deletes (quote top) dired-dwim-target t ; When 2 visible dired buffers, copy from one to the other dired-isearch-filenames 'dwim) ;; Do dired operations (copy, rename etc.) asynchroneously. With prefix arg disables async on the operation (autoload 'dired-async-mode "dired-async.el" nil t) (dired-async-mode 1) (define-key dired-mode-map "\C-cn" 'dired-narrow) (add-hook 'dired-load-hook (lambda () (load "dired-x") (dired-hide-details-mode 1) ;; Hide details by default. Unhide with "(" (setq dired-x-hands-off-my-keys nil) ;; hide dotfiles (dired-hide-dotfiles-mode) (define-key dired-mode-map "." #'dired-hide-dotfiles-mode) (toggle-truncate-lines t))) ;;;; Dired-jump ;; autoload dired-jump to work before a dired buffer is opened ;; In any file buffer, Alt+x dired-jump [Ctrl+x Ctrl+j] to jump to the directory of current buffer. (autoload 'dired-jump "dired-x" "Jump to Dired buffer corresponding to current buffer." t) (autoload 'dired-jump-other-window "dired-x" "Like \\[dired-jump] (dired-jump) but in other window." t) (define-key global-map (kbd "C-x C-j") 'dired-jump) (define-key global-map (kbd "C-x C-S-j") 'dired-jump-other-window) ;;; IVY: ;;;; Basics (ivy-mode) (setq ivy-use-virtual-buffers t ivy-count-format "(%d/%d) " ivy-extra-directories '("./") ;; Don’t print /.. counsel-find-file-ignore-regexp "\(?:\‘[#.]\)\|\(?:[#~]\’\)\|\’\." ivy-magic-slash-non-match-action 'ivy-magic-slash-non-match-create ivy-display-style 'fancy) ;;;; Ivy-based interface to standard commands (global-set-key (kbd "C-s") 'swiper-isearch) (global-set-key (kbd "M-x") 'counsel-M-x) (global-set-key (kbd "C-x C-f") 'counsel-find-file) (global-set-key (kbd "C-x f") 'counsel-recentf) (global-set-key (kbd "M-y") 'counsel-yank-pop) (global-set-key (kbd " f") 'counsel-describe-function) (global-set-key (kbd " v") 'counsel-describe-variable) (global-set-key (kbd " l") 'counsel-find-library) (global-set-key (kbd " i") 'counsel-info-lookup-symbol) (global-set-key (kbd " u") 'counsel-unicode-char) (global-set-key (kbd " j") 'counsel-set-variable) (global-set-key (kbd "C-M-ê") 'ivy-switch-buffer) (global-set-key (kbd "C-c v") 'ivy-push-view) (global-set-key (kbd "C-c V") 'ivy-pop-view) ;; Default binding S-SPC is taken by bépo (define-key ivy-minibuffer-map (kbd "C- ") 'ivy-restrict-to-matches) ;;;; Ivy-based interface to shell and system tools (global-set-key (kbd "C-c g") 'counsel-git) (global-set-key (kbd "C-c j") 'counsel-git-grep) (global-set-key (kbd "C-c y") 'counsel-git-log) (global-set-key (kbd "C-c k") 'counsel-rg) ;; Interacts with mu ;; (global-set-key (kbd "C-c m") 'counsel-linux-app) (global-set-key (kbd "C-c n") 'counsel-fzf) (global-set-key (kbd "C-x l") 'counsel-locate) (global-set-key (kbd "C-c J") 'counsel-file-jump) (global-set-key (kbd "C-S-o") 'counsel-rhythmbox) (global-set-key (kbd "C-c w") 'counsel-wmctrl) ;;;; Ivy-resume and other commands (global-set-key (kbd "C-c C-r") 'ivy-resume) (global-set-key (kbd "C-c b") 'counsel-bookmark) (global-set-key (kbd "C-c d") 'counsel-descbinds) (global-set-key (kbd "C-c g") 'counsel-git) (global-set-key (kbd "C-c o") 'counsel-outline) (global-set-key (kbd "C-c t") 'counsel-load-theme) (global-set-key (kbd "C-c F") 'counsel-org-file) (defun vic-counsel-find-file-symlink (x) "Create symbolic link to file X." (counsel--find-file-1 "Link file to: " ivy--directory (lambda (new-name) (make-symbolic-link x new-name 1)) 'vic-counsel-find-file-symlink)) (ivy-add-actions 'counsel-find-file '(("L" vic-counsel-find-file-symlink "symlink file"))) ;;;; Ivy-bibtex (autoload 'ivy-bibtex "ivy-bibtex" "" t) ;; ivy-bibtex requires ivy's `ivy--regex-ignore-order` regex builder, which ;; ignores the order of regexp tokens when searching for matching candidates. ;; Add something like this to your init file: (setq ivy-re-builders-alist '((ivy-bibtex . ivy--regex-ignore-order) (t . ivy--regex-plus))) ;;; TRAMP (require 'tramp) (add-to-list 'tramp-remote-path 'tramp-own-remote-path) (setq tramp-default-method "ssh") ; good for root on localhost too ;;; PASSWORD STORE: (require 'auth-source-pass) (auth-source-pass-enable) ;;; ESHELL: (require 'eshell-toggle) (global-set-key (kbd "") 'eshell-toggle) ;;; PDF TOOLS: ;;;; Basics (pdf-tools-install) (setq-default pdf-view-display-size 'fit-page) ; open pdfs scaled to fit page (setq pdf-misc-print-program "lpr") ;;;; Functions to save to kill ring after annotating (defun vic/pdf-annot-add-highlight-markup-annotation-and-kill () "Highlight and copy region to `kill-ring'." (interactive) (pdf-annot-add-highlight-markup-annotation (pdf-view-active-region nil)) (pdf-view-kill-ring-save)) (defun vic/pdf-annot-add-underline-markup-annotation-and-kill () "Highlight and copy region to `kill-ring'." (interactive) (pdf-annot-add-underline-markup-annotation (pdf-view-active-region nil)) (pdf-view-kill-ring-save)) (defun vic/pdf-annot-add-squiggly-markup-annotation-and-kill () "Highlight and copy region to `kill-ring'." (interactive) (pdf-annot-add-squiggly-markup-annotation (pdf-view-active-region nil)) (pdf-view-kill-ring-save)) (defun vic/pdf-annot-toggle-activate-created-annotations () "Toggle automatic activation of new annotations" (interactive) (when (string= major-mode "pdf-view-mode") (if pdf-annot-activate-created-annotations (setq-local pdf-annot-activate-created-annotations nil) (setq-local pdf-annot-activate-created-annotations t)) (message (format "Activate created annotations %s" pdf-annot-activate-created-annotations)))) ;;;; Keybindings (define-key pdf-view-mode-map (kbd "C-s") 'isearch-forward) ; use normal isearch (define-key pdf-view-mode-map (kbd "\"") 'vic/pdf-annot-add-underline-markup-annotation-and-kill) (define-key pdf-view-mode-map (kbd "«") 'vic/pdf-annot-add-highlight-markup-annotation-and-kill) (define-key pdf-view-mode-map (kbd "»") 'vic/pdf-annot-add-squiggly-markup-annotation-and-kill) (define-key pdf-view-mode-map (kbd "(") 'pdf-annot-add-text-annotation) (define-key pdf-view-mode-map (kbd "(") 'pdf-annot-add-text-annotation) (define-key pdf-view-mode-map (kbd "*") 'vic/pdf-annot-toggle-activate-created-annotations) ;;; LILYPOND: (autoload 'LilyPond-mode "lilypond-mode" "LilyPond Editing Mode" t) (add-to-list 'auto-mode-alist '("\\.ly$" . LilyPond-mode)) (add-to-list 'auto-mode-alist '("\\.ily$" . LilyPond-mode)) (add-hook 'LilyPond-mode-hook (lambda () (turn-on-font-lock))) (setq LilyPond-pdf-command "evince %f" LilyPond-midi-command "vlc %f" LilyPond-fancy-comments t) ;; Distinguish between %, %% and %%% comments ;;; ERC chat: (add-hook 'erc-mode-hook (lambda () (add-to-list 'erc-modules 'notifications) (setq erc-echo-notices-in-minibuffer-flag t erc-auto-query 'buffer) ;query buffers open automatically when someone sends a private message. erc-track-exclude-types '("JOIN" "NICK" "PART" "QUIT"))) ;;; COMPANY MODE: (add-hook 'prog-mode-hook 'company-mode) ;;; MAGIT: (global-set-key (kbd "C-x g") 'magit-status) ;;; NXML: ;;;; Basics (setq nxml-slash-auto-complete-flag t) ;;;; Fold/unfold (hideshow) (require 'hideshow) (add-to-list 'hs-special-modes-alist '(nxml-mode "\\|]*[^/]>" "\\|]*[^/]>" "