(set-language-environment "UTF-8")
(defvar bootstrap-version)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
(bootstrap-version 5))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"http://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage))
(setq straight-use-package-by-default t)
(straight-use-package 'use-package)
C-x + : resize windows equally C-x C-+ : Zoom in C-x C– : Zoom out
No need to set ensure to true for each package.
;; (setq use-package-always-ensure t)
Delight is used to hide some minor-mode from ModeLine
(use-package delight)
(use-package zenburn-theme)
(load-theme 'zenburn t)
(set-face-attribute 'default nil :family "FiraCode" :height 100)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(setq inhibit-startup-message t)
(column-number-mode t)
(line-number-mode t)
(global-display-line-numbers-mode t)
(defalias 'yes-or-no-p 'y-or-n-p)
(global-auto-revert-mode t)
(define-key global-map "\C-xk" 'kill-this-buffer)
(show-paren-mode)
(setq ring-bell-function 'ignore)
;; Only split vertically on very tall screens
;; (setq split-height-threshold 110)
Switch to help buffers
(setq help-window-select t)
Saw this and found it funny : https://www.reddit.com/r/emacs/comments/7v6fll/whats_in_your_initialscratchmessage/
(setq initial-scratch-message
";; - 'Tis but a scratch!\n;; - A scratch? Your arm's off!\n;; - No, it isn't!\n\n")
(use-package exec-path-from-shell
:config
(setq exec-path-from-shell-variables '("PATH" "GOPATH" "SHELL" "LC_CTYPE" "LC_ALL" "LANG"))
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize)))
Trailing whitespace display and management
(setq-default show-trailing-whitespace t)
(add-hook 'diff-mode-hook (lambda () (setq show-trailing-whitespace nil)))
(add-hook 'term-mode-hook (lambda () (setq show-trailing-whitespace nil)))
(add-hook 'compilation-mode-hook (lambda () (setq show-trailing-whitespace nil)))
(add-hook 'vterm-mode-hook (lambda () (setq show-trailing-whitespace nil)))
(add-hook 'before-save-hook 'delete-trailing-whitespace)
Store every backup fils in ~/.emacs.d/backups.
(setq
backup-by-copying t
backup-directory-alist
'(("." . "~/.emacs.d/backups"))
delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
(use-package smartparens
:delight smartparens-mode
:init
(progn
(require 'smartparens-config)
(smartparens-global-mode t)))
Bindings in ivy : C-M-j : ivy-immediate-done (use exactly what has been written)
(use-package ivy
:delight ivy-mode
:init
(ivy-mode 1)
;; add ‘recentf-mode’ and bookmarks to ‘ivy-switch-buffer’.
(setq ivy-use-virtual-buffers t)
;; number of result lines to display
(setq ivy-height 10)
;; change count format
(setq ivy-count-format "(%d) ")
;; no regexp by default
(setq ivy-initial-inputs-alist nil)
;; ivy completion in magit
(setq magit-completing-read-function 'ivy-completing-read)
;; configure regexp engine.
(setq ivy-re-builders-alist
;; allow input not in order
'((t . ivy--regex-ignore-order)))
;; use ivy as projectile completion
(setq projectile-completion-system 'ivy)
;; Do note show .. in files selction
(setq ivy-extra-directories '("./"))
)
Bindings and interesting commands : counsel-find-jump : from current directory, list recursively every file
(use-package counsel
:bind
(("M-x" . counsel-M-x)
("C-s" . swiper)
("C-x C-f" . counsel-find-file))
)
:init (setcdr (assoc ‘counsel-M-x ivy-initial-inputs-alist) “”)
(use-package counsel-projectile
:init (counsel-projectile-mode))
Smex is an M-x alternative it display the recently and most frequently used commands.
(use-package smex
:init (smex-initialize))
Display command bindings in M-x buffer
(use-package which-key
:delight which-key-mode
:init (which-key-mode 1))
Bindinds : C-= : expand-region
(use-package expand-region
:bind ("C-=" . er/expand-region))
Bindings : f - visit current file a - visit current file in same buffer
- - create a new subdirecorty
s - toggle name/date sorting d - flag file for deletion x - execute deletion requested R - rename or move file m - mark a file for latter command u - unmark a file = - compare file at point with the one at mark
(setq dired-listing-switches "-alh")
(put 'dired-find-alternate-file 'disabled nil)
Add colours to dired
(use-package diredfl
:init (diredfl-global-mode 1))
Bindings : C-x * q : quick-mode C-x * c : calc-mode
Bindings
C-g : Leave multiple cursors mode C-c m l : Edit multi line, one cursor is added at the beginning of each line of the region C-c m m : Mark-all-dwim C-j : In mc mode add a new line
(use-package multiple-cursors)
;; (define-key mc/keymap (kbd "<return>") nil)
(global-set-key (kbd "C-c m l") 'mc/edit-lines)
(global-set-key (kbd "C-c m m") 'mc/mark-all-dwim)
A templating system
Usefull functions : yas-insert-snippet : Insert a snippet from available snippets yas-expand : Expand snippet from key before point
(use-package yasnippet ; Snippets
:config
(yas-reload-all)
(yas-global-mode)
)
Bindings : C-p p p : projectile-switch-project C-x f or C-p p f : projectile-find-file C-p s g : grep in project
;; projectile
(use-package projectile
:delight projectile-mode
:init
(projectile-mode)
(setq projectile-use-git-grep t)
;; From : https://github.com/bbatsov/projectile/issues/1270#issuecomment-469039389
(defun projectile-default-generic-command (project-type command-type)
"Generic retrieval of COMMAND-TYPEs default cmd-value for PROJECT-TYPE.
If found, checks if value is symbol or string. In case of symbol
resolves to function `funcall's. Return value of function MUST
be string to be executed as command."
(let ((command (plist-get (alist-get project-type projectile-project-types) command-type)))
(cond
((stringp command) command)
((functionp command)
(if (fboundp command)
(funcall (symbol-function command))))
((and (not command) (eq command-type 'compilation-dir))
;; `compilation-dir' is special in that it is used as a fallback for the root
nil))))
:bind ("C-x f" . projectile-find-file))
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
Use projectile to group buffer per project in the iBuffer view.
(use-package ibuffer-projectile
:bind ("C-x C-b" . ibuffer)
:init
(add-hook 'ibuffer-hook
(lambda ()
(ibuffer-projectile-set-filter-groups)
(unless (eq ibuffer-sorting-mode 'alphabetic)
(ibuffer-do-sort-by-alphabetic)))))
(setq tab-width 4
indent-tabs-mode t)
(use-package magit
:init
(global-set-key (kbd "C-x g") 'magit-status)
(setq magit-completing-read-function 'ivy-completing-read)
)
Highlight uncommitted changes
(use-package git-gutter
:init
(global-git-gutter-mode t)
(add-to-list 'git-gutter:update-hooks 'focus-in-hook)
:hook (prog-mode . git-gutter-mode)
:delight git-gutter-mode)
Display todos in magit (disabled due to big project errors)
;; (use-package magit-todos
;; :config (magit-todos-mode t))
Usefull bindings: M-. Go to definition M-* Go back to the last place M-. was used C-c C-n : elpy-flymake-next-error C-c C-p : elpy-flymake-previous-error
Use M-x elpy-config to check required binaries
(use-package elpy
:delight elpy-mode
:defer t
:init
(advice-add 'python-mode :before 'elpy-enable))
Syntax highlighting for requirements.txt files
(use-package pip-requirements
:mode (("\\.pip\\'" . pip-requirements-mode)
("requirements.*\\.txt\\'" . pip-requirements-mode)
("requirements\\.in" . pip-requirements-mode)))
(setq c-default-style "linux"
c-basic-offset 4)
(use-package yaml-mode
)
C-c C-c l : live preview mode
(use-package markdown-mode
)
(use-package ansible)
(use-package dockerfile-mode
:init
(add-to-list 'auto-mode-alist '("Dockerfile\\'" . dockerfile-mode))
)
(use-package docker-compose-mode)
(use-package terraform-mode
:mode "\\.tf$"
:init
(add-hook 'terraform-mode-hook #'terraform-format-on-save-mode))
(use-package company-terraform
:init
(company-terraform-init))
Shellcheck is a shell script analysis tool.
(use-package flymake-shellcheck
:init
(add-hook 'sh-mode-hook 'flymake-shellcheck-load)
(add-hook 'sh-mode-hook 'flymake-mode))
;; (use-package vterm)
;; (add-hook 'vterm-mode-hook
;; (lambda ()
;; (display-line-numbers-mode 0)))
;; (use-package vterm-toggle)
(use-package web-mode
:commands (web-mode)
:mode
("\\.html\\'" . web-mode)
("\\.tsx\\'" . web-mode))
(use-package feature-mode
:mode ("\\.feature\\'" . feature-mode))
Bindings : C-c C-t C-p : toggle pdf mode C-c C-v : view document C-c C-c : master command C-c C-a : run all
(use-package tex
:straight auctex
:init
(setq TeX-auto-save t)
(setq TeX-parse-self t)
;; (setq TeX-view-evince-keep-focus t)
(add-hook 'LaTeX-mode-hook 'flymake-mode))
Use C-u M-x compile to run compilation buffer with shell interaction.
(use-package ansi-color
:init
(defun colorize-compilation-buffer ()
(when (eq major-mode 'compilation-mode)
(ansi-color-apply-on-region compilation-filter-start (point-max))))
(add-hook 'compilation-filter-hook 'colorize-compilation-buffer)
(add-to-list 'display-buffer-alist
'("*compilation*" display-buffer-same-window))
)
(add-hook 'compilation-mode-hook
(lambda ()
(display-line-numbers-mode 0)))
(use-package kubernetes
:commands (kubernetes-overview))
M-. Go to definition M-, Go back to the last place M-. was used
(use-package go-mode
:config (defun lsp-go-install-save-hooks ()
(add-hook 'before-save-hook #'lsp-format-buffer t t)
(add-hook 'before-save-hook #'lsp-organize-imports t t))
(add-hook 'go-mode-hook #'lsp-go-install-save-hooks))
(use-package lsp-mode
:commands (lsp lsp-deferred)
:hook (go-mode . lsp-deferred))
(use-package nix-mode
:mode "\\.nix\\'")
(use-package lua-mode)
Global bindings : C-c a org-agenda
In org-mode : C-c C-c or C-c C-q : on an Headline to add tag C-c C-t : to toggle TODO C-c C-s : to add a scheduled date C-c C-d : to add a deadline C-c . : add a timestamp C-c ! : add an inactive timestamp that will not cause an agenda entry C-u C-u TAB : switching back to startup visibility C-c C-k : expose all headers but not bodies
About dates :
<YYYY-MM-DD> is a timestamp, hit C-c C-c to normalize it [YYYY-MM-DD] is an inactive timestamp Repeater can be added to the timestamp ex: <YYYY-MM-DD +1w> everyweek ++ and .+ are special repeater to use when the next occurence depends on when the previous occurence is switched to DONE
Tables with org-mode C-c | : Create new table Tab : Next cell S-Tab | Previous cell M-S down : new row M-S right : new column M-S up : delete row
(use-package org
:mode (("\\.org$" . org-mode))
:init
(setq org-log-done t)
(setq org-directory (expand-file-name "~/org/"))
(setq org-agenda-files (list org-directory))
(setq org-agenda-window-setup 'current-window)
:bind
("C-c a" . org-agenda)
)
(setq org-todo-keywords
(quote ((sequence "TODO(t!)" "NEXT(n)" "|" "DONE(d!)")
(sequence "WAITING(w@/!)" "HOLD(h@/!)" "|" "CANCELLED(c@/!)" "PHONE" "MEETING"))))
(setq org-todo-keyword-faces
(quote (("TODO" :foreground "red" :weight bold)
("NEXT" :foreground "blue" :weight bold)
("DONE" :foreground "forest green" :weight bold)
("WAITING" :foreground "orange" :weight bold)
("HOLD" :foreground "magenta" :weight bold)
("CANCELLED" :foreground "forest green" :weight bold)
("MEETING" :foreground "forest green" :weight bold)
("PHONE" :foreground "forest green" :weight bold))))
An task cannot be DONE if a subtask is not DONE :
(setq org-enforce-todo-dependencies t)
NEXT keywords are for tasks and not projects. Auto convert NEXT state to TODO when a subtask state is added. source
(defun bh/mark-next-parent-tasks-todo ()
"Visit each parent task and change NEXT states to TODO"
(let ((mystate (or (and (fboundp 'org-state)
state)
(nth 2 (org-heading-components)))))
(when mystate
(save-excursion
(while (org-up-heading-safe)
(when (member (nth 2 (org-heading-components)) (list "NEXT"))
(org-todo "TODO")))))))
(add-hook 'org-after-todo-state-change-hook 'bh/mark-next-parent-tasks-todo 'append)
Add log state into a drawer
(setq org-log-into-drawer t)
(setq org-log-state-notes-insert-after-drawers nil)
(setq org-agenda-include-diary t)
From https://www.emacswiki.org/emacs/french-holidays.el
(defvar holiday-french-holidays nil
"French holidays")
(setq holiday-french-holidays
`((holiday-fixed 1 1 "Jour de l'an")
(holiday-fixed 1 6 "Épiphanie")
(holiday-fixed 2 2 "Chandeleur")
(holiday-fixed 2 14 "Saint Valentin")
(holiday-fixed 5 1 "Fête du travail")
(holiday-fixed 5 8 "Commémoration de la capitulation de l'Allemagne en 1945")
(holiday-fixed 6 21 "Fête de la musique")
(holiday-fixed 7 14 "Fête nationale - Prise de la Bastille")
(holiday-fixed 8 15 "Assomption (Religieux)")
(holiday-fixed 11 11 "Armistice de 1918")
(holiday-fixed 11 1 "Toussaint")
(holiday-fixed 11 2 "Commémoration des fidèles défunts")
(holiday-fixed 12 25 "Noël")
;; fetes a date variable
(holiday-easter-etc 0 "Pâques")
(holiday-easter-etc 1 "Lundi de Pâques")
(holiday-easter-etc 39 "Ascension")
(holiday-easter-etc 49 "Pentecôte")
(holiday-easter-etc -47 "Mardi gras")
(holiday-float 5 0 4 "Fête des mères")
;; dernier dimanche de mai ou premier dimanche de juin si c'est le
;; même jour que la pentecôte TODO
(holiday-float 6 0 3 "Fête des pères"))) ;; troisième dimanche de juin
(setq calendar-holidays holiday-french-holidays)
Because of ivy completion, we need to change refile complete behaviour.
From Aaron Bieber’s blog
… the default behavior for Refile is to allow you to do a step-by-step completion of this path, but if you’re using Helm, Helm is overriding the completing read to make it into a narrowing list (that we have all come to love).
So what you need to do is tell Org that you don’t want to complete in steps; you want Org to generate all of the possible completions and present them at once.
Bindings : C-c C-w : org-refile
(setq org-refile-use-outline-path 'file)
(setq org-outline-path-complete-in-steps nil)
(setq org-refile-allow-creating-parent-nodes 'confirm)
(setq org-refile-targets '(("next.org" :level . 0)
("someday.org" :level . 0)
("tickler.org" :level . 0)
("reading.org" :level . 1)
("reference.org" :level . 1)
("projects.org" :maxlevel . 1)))
Auto-save after org-refile From stackexchange
(defun my-org-refile (&optional goto default-buffer rfloc msg) (interactive "P") "Doc-string."
(org-refile goto default-buffer rfloc msg)
(org-save-all-org-buffers))
(add-hook 'org-mode-hook
(lambda () (local-set-key (kbd "C-c C-w") #'my-org-refile)))
Bindings : C-c C-x C-s or short C-c $ : org-archive-subtree
(setq org-archive-location "~/org/journal.org::datetree/")
(defun my-org-archive-subtree (&optional find-done) (interactive "P") "Doc-string."
(org-archive-subtree find-done)
(org-save-all-org-buffers))
(add-hook 'org-mode-hook
(lambda () (local-set-key (kbd "C-c C-x C-s") #'my-org-archive-subtree)))
Highlight source-blocks
(setq org-src-fontify-natively t)
(org-babel-do-load-languages 'org-babel-load-languages
(append org-babel-load-languages
'((shell . t))))
Org-babel async execution
(use-package ob-async
:init (require 'ob-async))
C-c C-x C-v : toggle inline images
(use-package ob-mermaid
:init (org-babel-do-load-languages
'org-babel-load-languages
(append org-babel-load-languages
'((mermaid . t)))))
(setq ob-mermaid-cli-path "/Users/ocazade/.nvm/versions/node/v10.16.0/bin/mmdc")
(defun shk-fix-inline-images ()
(when org-inline-image-overlays
(org-redisplay-inline-images)))
(add-hook 'org-babel-after-execute-hook 'shk-fix-inline-images)
(setq org-default-notes-file (concat org-directory "/notes.org"))
(define-key global-map "\C-cc" 'org-capture)
(setq org-capture-templates
'(("i" "Inbox" entry (file "~/org/inbox.org")
"* %?")
("l" "Log" entry (file+datetree "~/org/journal.org")
"* %?\nADDED: %U")
("I" "Work arrival" entry (file+datetree "~/org/journal.org")
"* Sophia arrival %u" :immediate-finish t)
("O" "Work departure" entry (file+datetree "~/org/journal.org")
"* Sophia departure %u" :immediate-finish t)
("c" "Add to current clocked task" plain (clock)
"%?")
))
Global bindings : C-c a A org-custom-agenda (include NEXT tasks)
In org-agenda : f Next time span b Previous time span . Go to today k capture l Toggle logbook mode (ex: Display Done tasks) } or ] Display inactive timestamp S-right/left Folowwing/preceding TODO state v change time range
(setq org-agenda-span 'day)
(use-package org-super-agenda
:config
(org-super-agenda-mode t))
(setq org-super-agenda-groups
'(
(:name "Appointment"
:time-grid t)
(:name "Today"
:scheduled t
:deadline t)
(:name "Office"
:tag "sophia")
(:name "Home"
:tag "pers")
)
)
(setq org-agenda-custom-commands
'(("A" "Office block agenda"
((agenda "" ((org-agenda-span 1)
(org-super-agenda-groups
'((:name "Appointment"
:time-grid t)
(:name "Today"
:scheduled t
:deadline t)))
))
(todo "NEXT"
((org-super-agenda-groups
'((:name "Work"
:tag "work")
(:name "Personal"
:tag "perso")))
)
))
)))
(add-hook 'org-agenda-mode-hook
(lambda ()
(display-line-numbers-mode 0)))
I like the idea of punching in and punching out like described here : http://doc.norang.ca/org-mode.html#GettingOrgModeWithGit
If idle for more than 15 minutes, resolve the things by asking what to do with the clock time. On os X, locales have to be properly set, otherwise, org-mac-idle-seconds always return 0.
(setq org-clock-idle-time 15)
Clock out when done
(setq org-clock-out-when-done t)
Save the running clock and all clock history when exiting Emacs, load it on startup
(setq org-clock-persist t)
Include current clocking task in clock reports
(setq org-clock-report-include-clocking-task t)
Clean 0 min clocked lines
(setq org-clock-out-remove-zero-time-clocks t)
(setq oc/workday-task-id nil)
(defun oc/arrival-hook ()
(setq oc/workday-task-id (org-id-get-create))
(oc/clock-in-workday-task))
(defun oc/departure-hook ()
(when oc/workday-task-id
(setq oc/workday-task-id nil))
(when (org-clock-is-active)
(org-clock-out)))
(defun oc/org-capture-hook ()
(when (string= "I" (plist-get org-capture-plist :key))
(oc/arrival-hook))
(when (string= "O" (plist-get org-capture-plist :key))
(oc/departure-hook)))
(add-hook 'org-capture-before-finalize-hook 'oc/org-capture-hook)
(defun oc/clock-in-workday-task()
(when oc/workday-task-id
(org-with-point-at (org-id-find oc/workday-task-id 'marker)
(org-clock-in '(16)))))
(defun oc/clock-out-hook ()
(when (and oc/workday-task-id
(not org-clock-clocking-in)
(not org-clock-resolving-clocks-due-to-idleness))
(oc/clock-in-workday-task)))
(add-hook 'org-clock-out-hook 'oc/clock-out-hook 'append)
Keybindings : C-x n e : Narrow to element C-x n s : Narrow to subtree C-x n w : Leave narrow mode C-c ’ : Narrow into babel source
NzcxNTAwMjc0MDc0OobHJTTx/VzWvRJK3XTkL5HrbXR0
(use-package org-jira
:delight org-jira-mode
:config
(unless (file-exists-p "~/.org-jira")
(make-directory "~/.org-jira"))
(setq jiralib-url "https://issues.redhat.com")
)
(setq gnus-select-method '(nnnil ""))
;; (setq user-mail-address "[email protected]"
;; user-full-name "Olivier Cazade")
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
;; (setq gnutls-algorithm-priority nil)
(setq gnus-secondary-select-methods
'((nnimap "gmail"
(nnimap-address "imap.gmail.com")
(nnimap-server-port 993)
(nnimap-stream ssl))))
(setq gnus-thread-sort-functions
'(gnus-thread-sort-by-most-recent-date
(not gnus-thread-sort-by-number)))
;; (use-package w3m)
(setq mm-text-html-renderer 'w3m)
Spell checking in Emacs.
Bindings: C-M-i : auto correct word
(use-package flyspell
:delight flyspell-mode
:init
(progn
(add-hook 'prog-mode-hook 'flyspell-prog-mode)
(add-hook 'text-mode-hook 'flyspell-mode)
(add-hook 'org-mode-hook 'flyspell-mode)
)
:config
;; Sets flyspell correction to use two-finger mouse click
(define-key flyspell-mouse-map [down-mouse-3] #'flyspell-correct-word)
)
(use-package flyspell-correct-ivy)
Tramp is used to edit remote files
Exemples : /ssh:user@host:/home/user/file /sudo::/etc/fstab /ssh:user@host|sudo::/home/user/file
Use C-c t to enable/disable vterm copy mode
(use-package tramp
:init
(setq tramp-default-method "ssh")
)
Bookmarks files location
Bindings :
C-x r m : Set the bookmark for the visited file, at point. C-x r m bookmark : Set the bookmark named bookmark at point (bookmark-set). C-x r M bookmark : Like C-x r m, but don’t overwrite an existing bookmark. C-x r b bookmark : Jump to the bookmark named bookmark (bookmark-jump). C-x r l : List all bookmarks (list-bookmarks).
https://github.com/pashky/restclient.el
(use-package restclient
:mode "\\.http$")
(use-package company-restclient
:after (restclient company)
:config (add-to-list 'company-backends 'company-restclient))
(use-package ob-restclient
:init (org-babel-do-load-languages
'org-babel-load-languages
(append org-babel-load-languages
'((restclient . t)))))
(use-package company
:config
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 3)
(global-company-mode t))
;; crash
;; (use-package company-box
;; :hook (company-mode . company-box-mode))
https://emacsair.me/2018/12/19/forge-0.1/
Periodically update package, default interval is 7 days.
;; (use-package auto-package-update
;; :config
;; (setq auto-package-update-delete-old-versions t)
;; (setq auto-package-update-hide-results t)
;; (auto-package-update-maybe))
Thanks to these persons for sharing their configuration :