This repository has been archived on 2024-10-30. You can view files and clone it, but cannot push or open issues or pull requests.
emacs/README.org
2020-09-29 00:28:12 +02:00

573 lines
17 KiB
Org Mode

#+PROPERTY: header-args:emacs-lisp :tangle yes
* My Emacs' configuration
This is my Emacs configuration, it's written as [[https://www.wikiwand.com/en/Literate_programming][literate programming]]
using [[https://orgmode.org/][org-mode]]'s Babel.
All the settings are enclosed inside this single file named
[[README.org]], the reason of this choice is that many services (like
GitHub) automatically looks for these names.
The configuration of different Emacs' aspects are kept divided in
different paragraphs.
This file must be considered part of the Git repository to which it
belongs and it may not work properly without the other files.
Despite I mainly use [[https://nixos.org][NixOS]] I chose to keep my Emacs configuration
detached from my Nix files, this way I should be able get my Emacs'
settings in a non-Nix environment.
However the installing process of the required packages is not managed
by this configuration; for example on my NixOS system I use the
[[https://github.com/nix-community/emacs-overlay][emacs-overlay]] which automatically parses this file looking for the
~(use-package <package>)~ declarations and then downloads and builds
the latest versions from MELPA.
I preferred to maintain this agnostic approach in order to don't make
this already dense file even more complex.
Indeed, as it's configured, ~use-package~ should ensure that the
packages are installed, and if this is not the case it should install
them.
I use [[https://github.com/ch11ng/exwm][EXWM]] (i.e. Emacs X Window Manager) but since I wanted to keep
the possibility to use this configuration also on different systems
(maybe without X.org) I tried to isolate its settings.
So, even if I never tried, it should be easy to disable it without
consequences.
** General tweaking
This should increase the space thresold before the garbage collector
starts doing its work.
Some users on the internet said that this snippet speeded up the boot.
#+begin_src emacs-lisp
;; (let* ((normal-gc-cons-threshold (* 20 1024 1024))
;; (init-gc-cons-threshold (* 128 1024 1024)))
;; (setq gc-cons-threshold init-gc-cons-threshold)
;; (add-hook 'emacs-startup-hook
;; (lambda () (setq gc-cons-threshold normal-gc-cons-threshold))))
#+end_src
** use-package
This is the only package that has to be manually installed
(automatically installed if using the NixOS' emacs-overlay)
#+begin_src emacs-lisp
(require 'use-package)
(setq use-package-alwaysensure t) ;automatically downloads packages if not installed
#+end_src
** General settings
This snippet contatins different things that I wasn't able to gather
better.
Hopefully, in a future, this section won't exist anymore.
#+begin_src emacs-lisp
(setq create-lockfiles nil)
(setq backup-directory-alist '((".*" . "~/.emacs-saves/")))
(setq auto-save-file-name-transforms '((".*" "~/.emacs-saves/" t)))
(setq backup-by-copying t)
(setq delete-old-versions t
kept-new-versions 6
kept-old-versions 2
version-control t)
(defalias 'yes-or-no-p 'y-or-n-p)
(setq use-dialog-box nil)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)
(fringe-mode 1)
(setq display-time-format "%H:%M")
(display-time-mode 1)
(setq mouse-autoselect-window 't)
(setq inhibit-startup-screen t)
(setq async-shell-command-buffer 'new-buffer)
(add-hook 'prog-mode-hook 'display-line-numbers-mode)
(add-hook 'prog-mode-hook 'hl-line-mode)
(add-hook 'org-mode-hook 'auto-fill-mode)
(set-fill-column 80)
(add-to-list 'default-frame-alist '(font . "Fira Code-12"))
(set-face-attribute 'default t :font "Fira Code-12")
(setq show-paren-delay 0)
(set-face-background 'show-paren-match "#111")
(set-face-attribute 'show-paren-match nil :weight 'extra-bold)
(show-paren-mode 1)
(use-package quelpa-use-package)
(package-initialize)
(server-start)
#+end_src
** Org configuration
#+begin_src emacs-lisp
(require 'org-protocol)
(setq org-default-notes-file (concat org-directory "~/notes.org"))
(setq org-capture-templates `(
("p" "Protocol" entry (file+headline ,(concat org-directory "notes.org") "Inbox")
"* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?")
("L" "Protocol Link" entry (file+headline ,(concat org-directory "notes.org") "Inbox")
"* %? [[%:link][%:description]] \nCaptured On: %U")
))
(org-babel-do-load-languages
'org-babel-load-languages
'((python . t)))
(setq safe-local-variable-values '((eval add-hook 'after-save-hook 'org-icalendar-export-to-ics nil t)))
(setq org-agenda-files '("~/nas/syncthing/orgzly/Agenda.org" "~/nas/syncthing/orgzly/Lavoro.org"))
;; (setq org-format-latex-options (plist-put org-format-latex-options :scale 1.6))
;; (use-package org-fragtog
;; :hook (org-mode org-fragtog)
;; )
#+end_src
** Theming
I'm using the ~doom-one~ theme from the ~doom-themes~ package.
In addition it's loaded the ~all-the-icons~ fonts and a special
modeline from ~doom-modeline~.
#+begin_src emacs-lisp
(use-package doom-themes
:after treemacs
:config
;; Global settings (defaults)
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-one t)
;; Enable flashing mode-line on errors
(doom-themes-visual-bell-config)
(setq doom-themes-treemacs-theme "doom-colors") ; use the colorful treemacs theme
(doom-themes-treemacs-config)
;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config)
)
(use-package all-the-icons)
(use-package doom-modeline
:init (doom-modeline-mode 1))
(use-package fira-code-mode
:hook prog-mode
:config (setq fira-code-mode-disabled-ligatures '("x")))
#+end_src
** EXWM
The following configuration must be commented out one doesn't want to
use Emacs as windows manager.
#+begin_src emacs-lisp
(use-package exwm
:if window-system
:config
(progn
(require 'seq)
(setq exwm-input-global-keys
`(
([?\s-c] . exwm-reset) ; works?
([?\s-w] . exwm-workspace-switch)
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))
([?\s-f] . exwm-layout-toggle-fullscreen)
([?\s-g] . exwm-floating-toggle-floating)
([?\s-t] . helm-exwm)
([?\s-q] . kill-current-buffer)
([?\s-m] . (lambda () (interactive)
(async-shell-command "spotify")
(async-shell-command "spotify-adkiller")))
([?\s-b] . (lambda () (interactive)
(start-process "" nil "firefox")))
([?\s-p] . (lambda () (interactive)
(start-process "" nil "screenshot")))
([?\s-d] . helm-run-external-command)))
(defun exwm-rename-buffer-to-title ()
(exwm-workspace-rename-buffer exwm-title))
(add-hook 'exwm-update-title-hook 'exwm-rename-buffer-to-title)
(add-hook 'exwm-floating-setup-hook 'exwm-layout-hide-mode-line)
(add-hook 'exwm-floating-exit-hook 'exwm-layout-show-mode-line)
(setq exwm-workspace-show-all-buffers t)
(setq window-divider-default-bottom-width 2
window-divider-default-right-width 2)
(window-divider-mode)
(exwm-input-set-key (kbd "s-h") #'windmove-left)
(exwm-input-set-key (kbd "s-j") #'windmove-down)
(exwm-input-set-key (kbd "s-k") #'windmove-up)
(exwm-input-set-key (kbd "s-l") #'windmove-right)
(exwm-enable)))
(use-package windsize
:after exwm
:config (progn
(windsize-default-keybindings)
(exwm-input-set-key (kbd "s-H") #'windsize-left)
(exwm-input-set-key (kbd "s-J") #'windsize-down)
(exwm-input-set-key (kbd "s-K") #'windsize-up)
(exwm-input-set-key (kbd "s-L") #'windsize-right)
))
(use-package helm-exwm
:after (exwm helm)
:config (setq helm-exwm-buffer-max-length nil)
)
#+end_src
** Evil
In a future I think I'll try the Emacs keybindings, but for now I
prefer the Vim keybindings, at least for the text editing.
Since I use small keyboards I think it's better to use a modal editor,
however for everything that is not text editing I use the normal Emacs
keybindings.
#+begin_src emacs-lisp
(use-package evil
:init
(setq evil-want-keybinding nil)
:config
(progn
(evil-mode 1) ; globally enable evil-mode except for the following modes
(mapcar (lambda (mode) (evil-set-initial-state mode 'emacs))
'(vterm-mode
eshell-mode
dired-mode
))))
(use-package evil-collection
:after (evil company-mode vterm)
:config
(evil-collection-init))
(use-package org-evil)
#+end_src
** Vterm
This is a really good terminal emulator.
I tend to use Emacs for everything but sometimes I need to use
external tools, and in this case I tend to use ~eshell~ which is
better ingrated with Emacs, but sometimes this is not sufficient
(e.g. the application uses nCurses, or I'm simply sshing in a remote
shell and I don't want to use TRAMP) and then I use Vterm.
#+begin_src emacs-lisp
(use-package vterm)
#+end_src
** Helm
Unfortunately this is currently unmantained (there was only a
mantainer, who devoted himself to it for years) but I hope that
someone in the near future will pick up the project.
However this is really stable and I never had problems.
#+begin_src emacs-lisp
(use-package helm
:init
(progn
(require 'helm-config)
(setq helm-autoresize-max-height 0)
(setq helm-autoresize-min-height 20)
(global-set-key (kbd "C-c h") 'helm-command-prefix)
(global-unset-key (kbd "C-x c"))
(when (executable-find "ack")
(setq helm-grep-default-command "ack -Hn --no-group --no-color %e %p %f"
helm-grep-default-recurse-command "ack -H --no-group --no-color %e %p %f"))
(setq helm-semantic-fuzzy-match t
helm-imenu-fuzzy-match t
helm-M-x-fuzzy-match t ;; optional fuzzy matching for helm-M-x
helm-buffers-fuzzy-matching t
helm-recentf-fuzzy-match t
helm-split-window-in-side-p t
helm-buffer-max-length nil)
(helm-mode 1)
(helm-autoresize-mode 1))
:bind
(("C-c h" . helm-command-prefix)
:map helm-command-map
("b" . helm-buffers-list)
("f" . helm-find-files)
("m" . helm-mini)
("o" . helm-imenu))
:bind
(("M-x" . helm-M-x)
("M-y" . helm-show-kill-ring)
("C-x b" . helm-mini)
("C-x C-f" . helm-find-files))
)
#+end_src
** Projectile
#+begin_src emacs-lisp
(use-package projectile
:config
(progn
(define-key projectile-mode-map (kbd "s-p") 'projectile-command-map)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(projectile-mode +1)))
(use-package helm-projectile
:after projectile
:config
(progn
(helm-projectile-on)))
#+end_src
** Treemacs
#+begin_src emacs-lisp
(use-package treemacs)
(use-package treemacs-evil
:after treemacs)
#+end_src
** Company
#+begin_src emacs-lisp
(use-package company
:config (global-company-mode))
#+end_src
** Nix(Os) integration
This section contains everything related to Nix(Os).
#+begin_src emacs-lisp
(use-package nix-mode
:mode "\\.nix\\'")
(use-package company-nixos-options
:after company
:config
(progn
(add-to-list 'company-backends 'company-nixos-options)))
(use-package helm-nixos-options)
#+end_src
** Paredit
This package is fundamental when writing Lisp/Scheme.
#+begin_src emacs-lisp
(use-package paredit
:hook ((lisp-mode
emacs-lisp-mode
ielm-mode
lisp-interaction-mode
scheme-mode
eval-expression-minibuffer-setup) .
paredit-mode)
:config (eldoc-add-command 'paredit-backward-delete 'paredit-close-round))
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
#+end_src
** Pass
I use the `pass` password manager, to use these packages I manually
configure it in the shell before.
#+begin_src emacs-lisp
(use-package pass)
(use-package helm-pass)
#+end_src
** Emms
I don't use it anymore because I didn't like the way it managed MPD,
however I'll leave here my configuration.
Now I use `mpdel`, see the next paragraph.
#+begin_src emacs-lisp
;; (use-package emms
;; :config
;; (progn
;; (require 'emms-setup)
;; (require 'emms-player-mpd)
;; (require 'emms-volume)
;; (setq emms-player-mpd-server-name "localhost")
;; (setq emms-player-mpd-server-port "6600")
;; (setq emms-volume-change-function 'emms-volume-mpd-change)
;; (add-to-list 'emms-info-functions 'emms-info-mpd)
;; (add-to-list 'emms-player-list 'emms-player-mpd)
;; (emms-all)
;; (defun my-emms-browser-covers (dir dim)
;; (emms-browser-cache-thumbnail-async (concat "/home/andrea/nas/musica/" dir) dim))
;; (setq emms-browser-covers 'my-emms-browser-covers)
;; (emms-cache-set-from-mpd-all)))
#+end_src
** MPDel
This package permit to control the MPD deamon, obviously it has to be
installed and started before.
#+begin_src emacs-lisp
(use-package mpdel
:config
(progn
(setq libmpdel-hostname "localhost")
(setq libmpdel-port "6600")))
#+end_src
** Elfeed
To manage my RSS feeds.
#+begin_src emacs-lisp
(use-package elfeed-org
:config (progn
(elfeed-org)
(setq rmh-elfeed-org-files (list "~/.emacs.d/feeds/feeds.org"))
(defun elfeed-v-mpv (url)
"Watch a video from URL in MPV"
(async-shell-command (format "mpv %s" url)))
(defun elfeed-view-mpv (&optional use-generic-p)
"Youtube-feed link"
(interactive "P")
(let ((entries (elfeed-search-selected)))
(cl-loop for entry in entries
do (elfeed-untag entry 'unread)
when (elfeed-entry-link entry)
do (elfeed-v-mpv it))
(mapc #'elfeed-search-update-entry entries)
(unless (use-region-p) (forward-line))))
(define-key elfeed-search-mode-map (kbd "v") 'elfeed-view-mpv)))
#+end_src
** Edit-server
This package allows to edit a textbox in a browser (with the related
extension installed) using an Emacs buffer.
#+begin_src emacs-lisp
(use-package edit-server
:commands edit-server-start
:init (if after-init-time
(edit-server-start)
(add-hook 'after-init-hook
#'(lambda() (edit-server-start))))
:config (setq edit-server-new-frame-alist
'((name . "Edit with Emacs FRAME")
(top . 200)
(left . 200)
(width . 80)
(height . 25)
(minibuffer . t)
(menu-bar-lines . t)
(window-system . x))))
#+end_src
** Magit
One of the most famous Emacs package, I never needed to edit the
defaults.
#+begin_src emacs-lisp
(use-package magit)
#+end_src
** Zoom
At the moment I'm not using it should automatically resize Emacs
windows in order to mantain specifit ratios, e.g. the golden ratio.
#+begin_src emacs-lisp
(use-package zoom)
#+end_src
** Dired+
Installed directly from a script fetched on emacswiki, it adds new
features to Dired.
#+begin_src emacs-lisp
;; (use-package dired+
;; :quelpa (dired+ :fetcher url :url "https://www.emacswiki.org/emacs/download/dired+.el")
;; :defer 1
;; :init
;; (setq diredp-hide-details-initially-flag nil)
;; (setq diredp-hide-details-propagate-flag nil)
;; :config
;; (diredp-toggle-find-file-reuse-dir 1))
#+end_src
** Working with React
#+begin_src emacs-lisp
(use-package typescript-mode)
(use-package rjsx-mode)
(use-package tide
:ensure t
:after (typescript-mode company flycheck)
:hook ((typescript-mode . tide-setup)
(typescript-mode . tide-hl-identifier-mode)
(before-save . tide-format-before-save))
:config (progn
(defun setup-tide-mode ()
(interactive)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(tide-hl-identifier-mode +1)
;; company is an optional dependency. You have to
;; install it separately via package-install
;; `M-x package-install [ret] company`
(company-mode +1))
;; aligns annotation to the right hand side
(setq company-tooltip-align-annotations t)
;; formats the buffer before saving
(add-hook 'before-save-hook 'tide-format-before-save)
(add-hook 'typescript-mode-hook #'setup-tide-mode)
;; to manage tsx files
(require 'web-mode)
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . web-mode))
(add-hook 'web-mode-hook
(lambda ()
(when (string-equal "tsx" (file-name-extension buffer-file-name))
(setup-tide-mode))))
;; enable typescript-tslint checker
(flycheck-add-mode 'typescript-tslint 'web-mode)))
#+end_src
** Journal
I keep a journal with my notes, when I save an entry it's
automatically committed and pushed on a remote repository.
#+begin_src emacs-lisp
(use-package org-journal
:init (progn
(add-hook 'after-save-hook (lambda () (async-shell-command "git add * && git commit -m 'Automatic' && git push origin master")))
;; Change default prefix key; needs to be set before loading org-journal
(setq org-journal-prefix-key "C-x j"))
:config
(setq org-journal-dir "~/journal/"
org-journal-date-format "%A, %d %B %Y"))
#+end_src