This Emacs configuration should work fine on any GNU/Linux distribution, just get the external package dependencies. I cannot guarantee full functionality on others systems without some particular tweaks, but about 70% should work out of the box. For the sources I used to build this configuration file, I had two main ones. First ‘daedreth’ YouTube channel, really good for learning Elisp and the Emacs wiki that contains pretty much everything about Emacs and it’s packages.
Some built-in emacs configurable variables, most interface and editing style related.
(tool-bar-mode -1)
(menu-bar-mode -1)
(scroll-bar-mode -1)
(defalias 'yes-or-no-p 'y-or-n-p)
(setq scroll-conservatively 100)
(setq auto-save-default nil)
(setq make-backup-file nil)
(global-hl-line-mode t)
(setq ring-bell-function 'ignore)
(setq inhibit-startup-message t)
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
When the subword-mode is enable, uppercase letters are marked as a single word, VarAtkOne would be identified as Var
, Atk
, and One
. Really good for managing multiple variables.
(global-subword-mode 1)
(setq electric-pair-pairs '(
(?\( . ?\))
(?\[ . ?\])
(?\" . ?\")
(?\{ . ?\})))
(electric-pair-mode t)
(show-paren-mode 1)
(line-number-mode 1)
(column-number-mode 1)
(defun config-visit()
(interactive)
(find-file "~/.emacs.d/config.org"))
(global-set-key (kbd "C-c e") 'config-visit)
(defun config-reload ()
(interactive)
(org-babel-load-file (expand-file-name "~/.emacs.d/config.org")))
(global-set-key (kbd "C-c r") 'config-reload)
(defun kill-word-function ()
(interactive)
(forward-char 1)
(backward-word)
(kill-word 1)
(delete-char 1))
(global-set-key (kbd "C-c w") 'kill-word-function)
(setq erc-nick "macc")
(setq erc-prompt (lambda () (concat "[" (buffer-name) "]")))
(setq erc-hide-list '("JOIN" "PART" "QUIT"))
(setq erc-server-history-list '("irc.rizon.net"
"localhost"))
(use-package erc-hl-nicks
:ensure t
:config
(erc-update-modules))
Some tweaks to use the Emacs ansi-term.
(defvar term "/bin/bash")
(defadvice ansi-term (before force-bash)
(interactive (list term)))
(ad-activate 'ansi-term)
(when window-system (global-set-key (kbd "<s-return>") 'ansi-term))
A package meant for learning emacs shortcuts, it gently lists all possible binds for completing all sorts of commands.
(use-package which-key
:ensure t
:init
(which-key-mode))
Highlight the current line when changing buffers.
(use-package beacon
:ensure t
:init
(beacon-mode 1))
Avy for perfect navigation in the file, saves me hundreds of keypresses and completly ditches a mouse usage.
(use-package avy
:ensure t
:bind
("M-s" . avy-goto-char))
Easy to use project manager.
(use-package projectile
:ensure t
:init
(projectile-mode 1))
(global-set-key (kbd "<f5>") 'projectile-compile-project)
Comfy git managing with Meta-g.
(use-package magit
:ensure t
:config
(setq magit-push-always-verify nil)
(setq git-commit-summary-max-length 50)
:bind
("M-g" . magit-status))
The “home” buffer of emacs to be said. The project item requires projectile
package, listed above.
(use-package dashboard
:ensure t
:config
(dashboard-setup-startup-hook)
(setq dashboard-startup-banner "~/.emacs.d/img/dashLogo.png")
(setq dashboard-items '((recents . 5)
(projects . 5)
(agenda . 5)
(bookmarks . 5)))
(setq dashboard-banner-logo-title "GNU/Emacs"))
Dmenu launchs applications within emacs.
(use-package dmenu
:ensure t
:bind
("s-SPC" . 'dmenu))
Linum lists the current and relative line number in the left corner in the code.
(use-package linum-relative
:ensure t
:config
(setq linum-relative-current-symbol "")
(add-hook 'prog-mode-hook 'linum-relative-mode))
Saves you from pressing (((((Backspace))))) for 2 hours straight, just to get rid of a huge blank space.
(use-package hungry-delete
:ensure t
:config (global-hungry-delete-mode))
(when window-system
(use-package pretty-mode
:ensure t
:config
(global-pretty-mode t)))
(use-package sudo-edit
:ensure t
:bind ("s-e" . sudo-edit))
It only works with more than two active windows, mapping them with “a, s, d, f, j, k, l” for a precise switch.
(use-package switch-window
:ensure t
:config
(setq switch-window-style 'minibuffer)
(setq switch-window-increase 4)
(setq switch-window-threshold 2)
(setq switch-window-shortcut-style 'qwerty)
(setq switch-window-qwerty-shortcuts
'( "a" "s" "d" "f" "h" "j" "k" "l"))
:bind
([remap other-window] . switch-window))
(defun vertical-win ()
(interactive)
(split-window-right)
(balance-windows)
(other-window 1))
(global-set-key (kbd "C-x 3") 'vertical-win)
(defun horizontal-win ()
(interactive)
(split-window-below)
(balance-windows)
(other-window 1))
(global-set-key (kbd "C-x 2") 'horizontal-win)
Now you can navigate in your kill-ring list using “M-y”, great.
(use-package popup-kill-ring
:ensure t
:bind ("M-y" . popup-kill-ring))
After selecting the wanted sting, press C-c q
to mark the next one.
(use-package mark-multiple
:ensure t
:bind
("C-c q" . 'mark-next-like-this)
("C-c a" . 'mark-all-like-this))
“C-x b” for default is really bad for navigating in buffers, specially if you are working with a dozen of them. IDO-mode + the ido-vertical-mode package lists all buffers and accept tab completion.
(setq ido-enable-flex-matching nil)
(setq ido-create-new-buffer 'always)
(setq ido-everywhere t)
(ido-mode 1)
(use-package ido-vertical-mode
:ensure t
:init
(ido-vertical-mode 1))
(setq ido-vertical-define-keys 'C-n-and-C-p-only)
(use-package smex
:ensure t
:init (smex-initialize)
:bind
("M-x" . smex))
(global-set-key (kbd "C-x C-b") 'ibuffer)
(setq ibuffer-expert t)
(defun murder-buffer ()
(interactive)
(kill-buffer (current-buffer)))
(global-set-key (kbd "C-x k") 'murder-buffer)
This transforms Emacs into a powerful tiling window manager. Delete this section for usage in desktop enviroments, other wm’s or tty-only
xorg-x11
, for full X support.- Any Audio controller. I personally use alsa/amixer. but you can use pulseaudio/pmixer or anything really.
- Some fonts, I personally use the
terminus-font
,noto
andttf-fonts
packages so X can load pretty much anything. compton
with some configuration, EXWM flickers a lot without a compositor.slock
, a simple screen locker.
(use-package exwm
:ensure t
:config
(require 'exwm-config)
(fringe-mode 1)
(server-start)
(exwm-config-ido)
; Setup the workpasces Mod + 1-9
(setq exwm-workspace-number 4)
(exwm-input-set-key (kbd "s-r") #'exwm-restart)
(exwm-input-set-key (kbd "s-k") #'exwm-workspace-delete)
(exwm-input-set-key (kbd "s-w") #'exwm-workspace-swap)
(dotimes (i 4)
(exwm-input-set-key (kbd (format "s-%d" i))
`(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(push ?\C-q exwm-input-prefix-keys)
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
(require 'exwm-randr)
(setq exwm-randr-workspace-output-plist '(0 "VGA-1"))
(add-hook 'exwm-randr-screen-change-hook
(lambda ()
(start-process-shell-command
"xrandr" nil "xrandr --output VGA-1 --left-of LVDS-1 --auto")))
(exwm-enable)
(exwm-randr-enable)
; (exwm-enable-ido-workaround)
; Keybinds
(exwm-input-set-simulation-keys
'(
;; movement
([?\C-b] . left)
([?\M-b] . C-left)
([?\C-f] . right)
([?\M-f] . C-right)
([?\C-p] . up)
([?\C-n] . down)
([?\C-a] . home)
([?\C-e] . end)
([?\M-v] . prior)
([?\C-v] . next)
([?\C-d] . delete)
([?\C-k] . (S-end delete))
;; cut/paste
([?\C-w] . ?\C-x)
([?\M-w] . ?\C-c)
([?\C-y] . ?\C-v)
; audio keys
([<XF86AudioMicMute>] . XF86AudioMicMute)
([<XF86AudioMute>] . XF86AudioMute)
([<XF86AudioLowerVolume>] . XF86AudioLowerVolume)
([<XF86AudioRaiseVolume>] . XF86AudioRaiseVolume)
;; search
([?\C-s] . ?\C-f)))
; Enables special keyboard keys.
(dolist (k '(XF86AudioLowerVolume
XF86AudioRaiseVolume
XF86PowerOff
XF86AudioMute
XF86AudioPlay
XF86AudioStop
XF86AudioPrev
XF86AudioNext
XF86ScreenSaver
XF86Launch1
XF68Back
XF86Forward
Scroll_Lock
print))
(cl-pushnew k exwm-input-prefix-keys))
(exwm-enable))
for applets in general
(require 'exwm-systemtray)
(exwm-systemtray-enable)
Functions for lauching a browser and locking the screen. Requires a browser and slock
package.
(defun exwm-async-run (name)
(interactive)
(start-process name nil name))
(defun launch-browser ()
(interactive)
(exwm-async-run "chromium"))
(defun launch-lock ()
(interactive)
(exwm-async-run "slock"))
(defun launch-wifi ()
(interactive)
(exwm-async-run "wpa_gui"))
(global-set-key (kbd "s-n") 'launch-wifi)
(global-set-key (kbd "s-i") 'launch-browser)
(global-set-key (kbd "s-x") 'launch-lock)
(defun screenshot ()
"Takes a fullscreen screenshot of the current workspace"
(interactive)
(when window-system
(message "Cheese!")
(start-process "screenshot" nil "import" "-window" "root"
(concat (getenv "HOME") "/Pictures/Screenshots/" (subseq (number-to-string (float-time)) 0 10) ".png"))
(message "Screenshot taken!")))
(global-set-key (kbd "<print>") 'screenshot)
(defun screenshot-window ()
"Takes a screenshot of a region selected by the user."
(interactive)
(when window-system
(call-process "import" nil nil nil ".newScreen.png")
(call-process "convert" nil nil nil ".newScreen.png" "-shave" "1x1"
(concat (getenv "HOME") "/Pictures/Screenshots/" (subseq (number-to-string (float-time)) 0 10) ".png"))
(call-process "rm" nil nil nil ".newScreen.png"))
(message "Screenshot taken!"))
(global-set-key (kbd "<XF86Favorites>") 'screenshot-window)
This should work for pulseaudio-alsa
and alsa
standalone users
(defconst volumeModifier "3")
(defun mic/mute ()
(interactive)
(start-process "mic-mute" nil "amixer" "sset" "Capture" "toggle" "all"))
(defun audio/mute ()
(interactive)
(start-process "audio-mute" nil "amixer" "sset" "Master" "toggle" "all"))
(defun audio/raise-volume ()
(interactive)
(start-process "raise-volume" nil "amixer" "-q" "sset" "Master" (concat volumeModifier "%+" )))
(defun audio/lower-volume ()
(interactive)
(start-process "lower-volume" nil "amixer" "-q" "sset" "Master" (concat volumeModifier "%-" )))
(global-set-key (kbd "<XF86AudioMicMute>") 'mic/mute)
(global-set-key (kbd "<XF86AudioMute>") 'audio/mute)
(global-set-key (kbd "<XF86AudioRaiseVolume>") 'audio/raise-volume)
(global-set-key (kbd "<XF86AudioLowerVolume>") 'audio/lower-volume)
Making the modeline great for information display.
(use-package spaceline
:ensure t
:config
(require 'spaceline-config)
(setq powerline-default-separator (quote arrow))
(spaceline-spacemacs-theme))
(use-package diminish
:ensure t
:init
(diminish 'hungry-delete-mode)
(diminish 'irony-mode)
(diminish 'abbrev-mode)
(diminish 'linum-relative-mode)
(diminish 'projectile-mode)
(diminish 'eldoc-mode)
(diminish 'beacon-mode)
(diminish 'subword-mode)
(diminish 'which-key-mode))
(use-package fancy-battery
:ensure t
:config
(setq fancy-battery-show-percentage t)
(setq battery-update-interval 10)
(if window-system
(fancy-battery-mode)
(display-battery-mode)))
(setq display-time-default-load-average nil)
(display-time-mode 1)
(setq display-time-24hr-format t)
(setq display-time-format "%H:%M - %d %B %Y")
The defaults create a new windown.
(setq org-src-window-setup 'current-window)
Organize the headers in a nice way.
(use-package org-bullets
:ensure t
:config
(add-hook 'org-mode-hook (lambda () (org-bullets-mode))))
Show the syntax in the SRC cases.
(setq org-src-fontify-natively t)
Because typing the languague everytime is very repetitive.
(add-to-list 'org-structure-template-alist
'("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC"))
(add-to-list 'org-structure-template-alist
'("cc" "#+BEGIN_SRC c\n?\n#+END_SRC"))
(add-to-list 'org-structure-template-alist
'("cpp" "#+BEGIN_SRC c++\n?\n#+END_SRC"))
My default org files is located on ~/Sync/schedules and I mainly use syncthing
to sync the files
between computers and mobile. Just change to whatever folder you want to synchronize.
(setq org-agenda-files (append
(file-expand-wildcards "~/Sync/schedules/*.org")))
(when window-system (global-set-key (kbd "s-a") 'org-agenda))
(defun acess-routine()
(interactive)
(dired "~/sync/schedules"))
(global-set-key (kbd "C-c s") 'acess-routine)
Snippets & autocompletion packages first, then configuration by language.
clang
for C/C++ completion.sbcl
(stell bank common lisp) interpreter for the various lisp dialects completion.
(use-package yasnippet
:ensure t
:config
(use-package yasnippet-snippets
:ensure t)
(yas-reload-all))
(use-package company
:ensure t
:config
(setq company-idle-delay 0)
(setq company-minimum-prefix-length 2))
(with-eval-after-load 'company
(define-key company-active-map (kbd "M-n") nil)
(define-key company-active-map (kbd "M-p") nil)
(define-key company-active-map (kbd "C-n") #'company-select-next)
(define-key company-active-map (kbd "C-p") #'company-select-previous)
(define-key company-active-map (kbd "SPC") #'company-abort))
(use-package flycheck
:ensure t)
(add-hook 'c++-mode-hook 'yas-minor-mode)
(add-hook 'c-mode-hook 'yas-minor-mode)
(use-package flycheck-clang-analyzer
:ensure t
:config
(with-eval-after-load 'flycheck
(require 'flycheck-clang-analyzer)
(flycheck-clang-analyzer-setup)))
(with-eval-after-load 'company
(add-hook 'c++-mode-hook 'company-mode)
(add-hook 'c-mode-hook 'company-mode))
(use-package company-c-headers
:ensure t)
(use-package company-irony
:ensure t
:config
(require 'company)
(setq company-backends '((company-c-headers
company-dabbrev-code
company-irony))))
(use-package irony
:ensure t
:config
(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'c-mode-hook 'irony-mode)
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options))
(add-hook 'python-mode-hook 'yas-minor-mode)
(add-hook 'python-mode-hook 'flycheck-mode)
(with-eval-after-load 'company
(add-hook 'python-mode-hook 'company-mode))
(use-package company-jedi
:ensure t
:config
(require 'company)
(add-to-list 'company-backends 'company-jedi))
(defun python-mode-company-init ()
(setq-local company-backends '((company-jedi
company-etags
company-dabbrev-code))))
(use-package company-jedi
:ensure t
:config
(require 'company)
(add-hook 'python-mode-hook 'python-mode-company-init))
(add-hook 'emacs-lisp-mode-hook 'eldoc-mode)
(add-hook 'emacs-lisp-mode-hook 'yas-minor-mode)
(add-hook 'emacs-lisp-mode-hook 'company-mode)
(use-package slime
:ensure t
:config
(setq inferior-lisp-program "/usr/bin/sbcl")
(setq slime-contribs '(slime-fancy)))
(use-package slime-company
:ensure t
:init
(require 'company)
(slime-setup '(slime-fancy slime-company)))
(add-hook 'shell-mode-hook 'yas-minor-mode)
(add-hook 'shell-mode-hook 'flycheck-mode)
(add-hook 'shell-mode-hook 'company-mode)
(defun shell-mode-company-init ()
(setq-local company-backends '((company-shell
company-shell-env
company-etags
company-dabbrev-code))))
(use-package company-shell
:ensure t
:config
(require 'company)
(add-hook 'shell-mode-hook 'shell-mode-company-init))
(use-package cheat-sh
:ensure t)
This is a little scheme to replace .xinitrc startup application calls. With these calls in the emacs configuration there’s no need of editing .xinitrc for every machine.
Remap ctrl to caps and increases press rate
(shell-command "xset r rate 200 50")
(shell-command "setxkbmap -model thinkpad60 -layout br -option ctrl:nocaps")
By default EXWM tends to flicker a little bit, compton fixes that
(shell-command "picom -b")
Hydra example
(use-package hydra
:ensure t
:defer 2
:bind ("C-c c" . hydra-clock/body))
(defhydra hydra-clock (:color blue)
"
^
^Clock^ ^Do^
^─────^─────────────^──^─────────
_q_ quit _c_ cancel
^^ _d_ display
^^ _e_ effort
^^ _i_ in
^^ _j_ jump
^^ _o_ out
^^ _r_ report
^^ ^^
"
("q" nil)
("c" org-clock-cancel :color pink)
("d" org-clock-display)
("e" org-clock-modify-effort-estimate)
("i" org-clock-in)
("j" org-clock-goto)
("o" org-clock-out)
("r" org-clock-report))