GNU/Linux and GNU Emacs Introduction
1. Installing Debian
1.1. Preparations
1.1.1. Getting debian
Download Debian installer image
1.1.2. Creating installation medium
On M$
Windows, use a tool like Rufus to create a bootable USB flash
drive with the downloaded .iso
file
1.1.3. Allocating disk space
Either get an empty disk or shrink on of your data partitions (toms) to get a continuous region of free space which is at least around 100GB.
1.2. Installation process
If installing on a laptop, make sure that it's fully charged and keep the charger plugged in.
1.2.1. Booting from the installation medium
NOTE: You might have to enable booting from USB in BIOS.
Select the USB from boot menu or change boot order.
1.2.2. The Debian installer
Select the install
option (not the Graphical install
) in the GRUB bootloader.
To navigate the menus, use arrow keys and TAB, to toggle check boxes use spacebar and to press button use the enter key.
Simple guide:
- Select region
- Select localization (US)
- Select keyboard layout (most likely US/ISO)
- Select connected if you have Ethernet connection or wireless if you want to connect to wifi.
- Choose hostname.
- Skip domain name.
- Skip proxy.
- Select mirror in your region.
- Set root password.
- Set user's full name, username and password.
- Deselect all software packages except base.
- To dual boot with Windows select guided partitioning (free space).
- Select
/home
folder on a separate partition. - Start the installation.
- Reboot and check that you can boot everything.
2. Setting up GNU/Linux
2.1. User setup
- Login as root
- Edit
/etc/apt/sources
and addnon-free contrib testing unstable
apt udpate
apt upgrade
apt install sudo
visudo
(%wheel ALL=(ALL) NOPASSWD: ALL)groupadd wheel
usermod -aG wheel YOUR_USERNAME
exit
2.2. Environment setup
2.2.1. Folder setup
cd rmdir Downloads Desktop ... mkdir downloads documents multimedia cd multimedia mkdir screenshots mkdir screencasts
2.2.2. Emacs setup
sudo apt install emacs git vterm-module libtd
Delete ~/.emacs.d
Edit ~/.config/emacs/init.el
(server-start)
(defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) (bootstrap-version 6)) (unless (file-exists-p bootstrap-file) (with-current-buffer (url-retrieve-synchronously "https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el" 'silent 'inhibit-cookies) (goto-char (point-max)) (eval-print-last-sexp))) (load bootstrap-file nil 'nomessage)) (straight-use-package 'use-package) (setq straight-use-package-by-default t use-package-always-ensure t)
(prefer-coding-system 'utf-8) (set-language-environment "UTF-8") (set-default-coding-systems 'utf-8) (set-terminal-coding-system 'utf-8) (setq-default buffer-file-coding-system 'utf-8)
(menu-bar-mode -1) (tool-bar-mode -1) (scroll-bar-mode -1)
(setq kill-ring-max 10000) (repeat-mode 1) (auto-insert-mode 1) (global-hl-line-mode 1) (setq display-time-24hr-format t) (setq default-input-method "russian-computer") (load-theme 'modus-vivendi t) (fset 'yes-or-no-p 'y-or-n-p) (set-face-attribute 'default nil :font "Iosevka" :height 180) (global-subword-mode)
(require 'ansi-color) (add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) (add-hook 'compilation-mode-hook 'toggle-truncate-lines) (define-key global-map (kbd "C-<f5>") 'compile) (define-key global-map (kbd "<f5>") 'recompile)
(use-package trashed) (setq delete-by-moving-to-trash t)
(use-package undo-tree :config (global-undo-tree-mode))
(use-package page-break-lines :config (global-page-break-lines-mode))
(use-package pdf-tools :demand t :hook (pdf-view-mode . pdf-view-themed-minor-mode) :config ;; Initialize the package (pdf-tools-install) ;; Associate pdf-view-mode with PDF files (add-to-list 'auto-mode-alist '("\\.pdf\\'" . pdf-view-mode)) ;; Enable seamless scrolling between pages (setq pdf-view-continuous-scroll-mode t) ;; Use normal Emacs keybindings for scrolling (setq pdf-view-continuous-scroll-keystrokes nil))
(use-package eglot)
(use-package project)
(use-package vterm) (use-package eat)
(use-package telega :custom (telega-server-libs-prefix "/usr"))
(use-package emms)
(use-package multitran :bind (("s-t" . multitran-at-pos)))
(use-package savehist :config (savehist-mode))
(use-package lorem-ipsum)
(use-package smartparens :init (smartparens-global-mode t))
(use-package vertico :init (vertico-mode) ;; (setq vertico-scroll-margin 0) ;; (setq vertico-count 20) ;; (setq vertico-resize t) (setq vertico-cycle t)) (use-package orderless :init ;; (setq orderless-style-dispatchers '(+orderless-consult-dispatch ;; orderless-affix-dispatch) orderless-component-separator #'orderless-escapable-split-on-space) (setq completion-styles '(orderless basic) completion-category-defaults nil completion-category-overrides '((file (styles partial-completion))))) (use-package consult :bind (;; C-c bindings in `mode-specific-map' ("C-c M-x" . consult-mode-command) ("C-c h" . consult-history) ("C-c k" . consult-kmacro) ("C-c m" . consult-man) ("C-c i" . consult-info) ([remap Info-search] . consult-info) ;; C-x bindings in `ctl-x-map' ("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command ("C-x b" . consult-buffer) ;; orig. switch-to-buffer ("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window ("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame ("C-x r b" . consult-bookmark) ;; orig. bookmark-jump ("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer ;; Custom M-# bindings for fast register access ("M-#" . consult-register-load) ("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated) ("C-M-#" . consult-register) ;; Other custom bindings ("M-y" . consult-yank-pop) ;; orig. yank-pop ;; M-g bindings in `goto-map' ("M-g e" . consult-compile-error) ("M-g f" . consult-flymake) ;; Alternative: consult-flycheck ("M-g g" . consult-goto-line) ;; orig. goto-line ("M-g M-g" . consult-goto-line) ;; orig. goto-line ("M-g o" . consult-outline) ;; Alternative: consult-org-heading ("M-g m" . consult-mark) ("M-g k" . consult-global-mark) ("M-g i" . consult-imenu) ("M-g I" . consult-imenu-multi) ;; M-s bindings in `search-map' ("M-s d" . consult-find) ;; Alternative: consult-fd ("M-s D" . consult-locate) ("M-s g" . consult-grep) ("M-s G" . consult-git-grep) ("M-s r" . consult-ripgrep) ("M-s l" . consult-line) ("M-s L" . consult-line-multi) ("M-s k" . consult-keep-lines) ("M-s u" . consult-focus-lines) ;; Isearch integration ("M-s e" . consult-isearch-history) :map isearch-mode-map ("M-e" . consult-isearch-history) ;; orig. isearch-edit-string ("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string ("M-s l" . consult-line) ;; needed by consult-line to detect isearch ("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch ;; Minibuffer history :map minibuffer-local-map ("M-s" . consult-history) ;; orig. next-matching-history-element ("M-r" . consult-history)) ;; orig. previous-matching-history-element ;; Enable automatic preview at point in the *Completions* buffer. This is ;; relevant when you use the default completion UI. :hook (completion-list-mode . consult-preview-at-point-mode) :init ;; Optionally configure the register formatting. This improves the register ;; preview for `consult-register', `consult-register-load', ;; `consult-register-store' and the Emacs built-ins. (setq register-preview-delay 0.5 register-preview-function #'consult-register-format) ;; Optionally tweak the register preview window. ;; This adds thin lines, sorting and hides the mode line of the window. (advice-add #'register-preview :override #'consult-register-window) ;; Use Consult to select xref locations with preview (setq xref-show-xrefs-function #'consult-xref xref-show-definitions-function #'consult-xref) ;; Configure other variables and modes in the :config section, ;; after lazily loading the package. :config ;; Optionally configure preview. The default value ;; is 'any, such that any key triggers the preview. ;; (setq consult-preview-key 'any) ;; (setq consult-preview-key "M-.") ;; (setq consult-preview-key '("S-<down>" "S-<up>")) ;; For some commands and buffer sources it is useful to configure the ;; :preview-key on a per-command basis using the `consult-customize' macro. (consult-customize consult-theme :preview-key '(:debounce 0.2 any) consult-ripgrep consult-git-grep consult-grep consult-bookmark consult-recent-file consult-xref consult--source-bookmark consult--source-file-register consult--source-recent-file consult--source-project-recent-file ;; :preview-key "M-." :preview-key '(:debounce 0.4 any)) ;; Optionally configure the narrowing key. ;; Both < and C-+ work reasonably well. (setq consult-narrow-key "<") ;; "C-+" ;; Optionally make narrowing help available in the minibuffer. ;; You may want to use `embark-prefix-help-command' or which-key instead. ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help) ) (use-package corfu :custom (corfu-cycle t) ;; Enable cycling for `corfu-next/previous' (corfu-auto t) ;; Enable auto completion (corfu-separator ?\s) ;; Orderless field separator (corfu-quit-at-boundary nil) ;; Never quit at completion boundary (corfu-quit-no-match nil) ;; Never quit, even if there is no match (corfu-preview-current nil) ;; Disable current candidate preview (corfu-preselect 'prompt) ;; Preselect the prompt (corfu-on-exact-match nil) ;; Configure handling of exact matches (corfu-scroll-margin 5) ;; Use scroll margin :init (global-corfu-mode))
(setq dired-listing-switches "-alh" dired-dwim-target t dired-recursive-copies 'always dired-recursive-deletes 'always) (use-package dired-single)
(use-package emacs :init ;; Add prompt indicator to `completing-read-multiple'. ;; We display [CRM<separator>], e.g., [CRM,] if the separator is a comma. (defun crm-indicator (args) (cons (format "[CRM%s] %s" (replace-regexp-in-string "\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" "" crm-separator) (car args)) (cdr args))) (advice-add #'completing-read-multiple :filter-args #'crm-indicator) ;; Do not allow the cursor in the minibuffer prompt (setq minibuffer-prompt-properties '(read-only t cursor-intangible t face minibuffer-prompt)) (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode) ;; Enable recursive minibuffers (setq enable-recursive-minibuffers t)) ;; Save all tempfiles in $TMPDIR/emacs$UID/ (defconst emacs-tmp-dir (expand-file-name (format "emacs%d" (user-uid)) temporary-file-directory)) (setq backup-directory-alist `((".*" . ,emacs-tmp-dir))) (setq auto-save-file-name-transforms `((".*" ,emacs-tmp-dir t))) (setq auto-save-list-file-prefix emacs-tmp-dir)
(use-package multiple-cursors :bind (("C-S-c" . mc/edit-lines) ("C->" . mc/mark-next-like-this) ("C-<" . mc/mark-previous-like-this) ("C-c C-S-c" . mc/mark-all-like-this) ("C-\"" . mc/skip-to-next-like-this) ("C-:" . mc/skip-to-previous-like-this)))
(use-package expand-region :bind (("C-M-=" . er/expand-region)))
(use-package move-text :bind (("M-P" . move-text-up) ("M-N" . move-text-down)))
(keymap-global-set "C-'" 'duplicate-dwim) (setq duplicate-line-final-position 1)
(use-package hl-todo :config (global-hl-todo-mode 1))
(use-package ligature :config (ligature-set-ligatures 't '("-<<" "-<" "-<-" "<--" "<---" "<<-" "<-" "->" "->>" "-->" "--->" "->-" ">-" ">>-" "=<<" "=<" "=<=" "<==" "<===" "<<=" "<=" "=>" "=>>" "==>" "===>" "=>=" ">=" ">>=" "<->" "<-->" "<--->" "<---->" "<=>" "<==>" "<===>" "<====>" "::" ":::" "__" "<~~" "</" "</>" "/>" "~~>" "==" "!=" "/=" "~=" "<>" "===" "!==" "!===" "=/=" "=!=" "<:" ":=" "*=" "*+" "<*" "<*>" "*>" "<|" "<|>" "|>" "<." "<.>" ".>" "+*" "=*" "=:" ":>" "(*" "*)" "/*" "*/" "[|" "|]" "{|" "|}" "++" "+++" "\\/" "/\\" "|-" "-|" "<!--" "<!---")) (global-ligature-mode -1))
(use-package magit)
(use-package restart-emacs)
(use-package bluetooth)
2.2.3. Installing fonts
- Wget latest
PkgTTC-Iosevka-X.X.X.zip
asset from iosevka releases unzip DOWNLOADED_FILE
mv contents ~/.local/share/fonts
fc-cache -fv
2.2.4. i3 setup
sudo apt install xorg i3 dbus-launch maim udiskie
Edit ~/.xinitrc
Disable access control for the current user.
xhost +SI:localuser:$USER
xset r rate 250 30
exec dbus-launch --exit-with-session i3
Edit ~/.config/i3/config
set $mod Mod4
Font for window titles. Will also be used by the bar unless a
different font is used in the bar {}
block below.
font pango:monospace 12
Start XDG autostart .desktop
files using dex
. See also XDG Autostart -
ArchWiki
exec --no-startup-id dex --autostart --environment i3
The combination of xss-lock
, nm-applet
and pactl
is a popular choice,
so they are included here as an example. Modify as you see fit.
xss-lock
grabs a logind suspend inhibit lock
and will use i3lock
to
lock the screen before suspend. Use loginctl lock-session
to lock your
screen.
exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
exec --no-startup-id setxkbmap -layout "us,ru" -option 'grp:shifts_toggle' -option "ctrl:nocaps"
exec --no-startup-id udiskie --automount
NetworkManager is the most popular way to manage wireless networks on
Linux, and nm-applet
is a desktop environment-independent system tray
GUI for it.
exec --no-startup-id nm-applet
exec emacs --background black
Use pactl
to adjust volume in PulseAudio.
set $refresh_i3status killall -SIGUSR1 i3status bindsym XF86AudioRaiseVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ +10% && $refresh_i3status bindsym XF86AudioLowerVolume exec --no-startup-id pactl set-sink-volume @DEFAULT_SINK@ -10% && $refresh_i3status bindsym XF86AudioMute exec --no-startup-id pactl set-sink-mute @DEFAULT_SINK@ toggle && $refresh_i3status bindsym XF86AudioMicMute exec --no-startup-id pactl set-source-mute @DEFAULT_SOURCE@ toggle && $refresh_i3status
Change brightness.
bindsym XF86MonBrightnessUp exec --no-startup-id brightnessctl set +5% bindsym XF86MonBrightnessDown exec --no-startup-id brightnessctl set 5%-
Use Mouse+$mod
to drag floating windows to their wanted position.
floating_modifier $mod
Move tiling windows via drag & drop by left-clicking into the title bar, or left-clicking anywhere into the window while holding the floating modifier.
tiling_drag modifier titlebar
# start a terminal bindsym $mod+Return exec emacsclient -c # kill focused window bindsym $mod+Shift+q kill # start dmenu (a program launcher) bindsym $mod+d exec --no-startup-id i3-dmenu-desktop --dmenu='dmenu -i -fn 12' # change focus bindsym $mod+j focus left bindsym $mod+k focus down bindsym $mod+l focus up bindsym $mod+semicolon focus right # alternatively, you can use the cursor keys: bindsym $mod+Left focus left bindsym $mod+Down focus down bindsym $mod+Up focus up bindsym $mod+Right focus right # move focused window bindsym $mod+Shift+j move left bindsym $mod+Shift+k move down bindsym $mod+Shift+l move up bindsym $mod+Shift+semicolon move right # alternatively, you can use the cursor keys: bindsym $mod+Shift+Left move left bindsym $mod+Shift+Down move down bindsym $mod+Shift+Up move up bindsym $mod+Shift+Right move right # split in horizontal orientation bindsym $mod+h split h # split in vertical orientation bindsym $mod+v split v # enter fullscreen mode for the focused container bindsym $mod+f fullscreen toggle # change container layout (stacked, tabbed, toggle split) bindsym $mod+s layout stacking bindsym $mod+w layout tabbed bindsym $mod+e layout toggle split # toggle tiling / floating bindsym $mod+Shift+space floating toggle # change focus between tiling / floating windows bindsym $mod+space focus mode_toggle # focus the parent container bindsym $mod+a focus parent # focus the child container #bindsym $mod+d focus child # Define names for default workspaces for which we configure key bindings later on. # We use variables to avoid repeating the names in multiple places. set $ws1 "1" set $ws2 "2" set $ws3 "3" set $ws4 "4" set $ws5 "5" set $ws6 "6" set $ws7 "7" set $ws8 "8" set $ws9 "9" set $ws10 "10" # switch to workspace bindsym $mod+1 workspace number $ws1 bindsym $mod+2 workspace number $ws2 bindsym $mod+3 workspace number $ws3 bindsym $mod+4 workspace number $ws4 bindsym $mod+5 workspace number $ws5 bindsym $mod+6 workspace number $ws6 bindsym $mod+7 workspace number $ws7 bindsym $mod+8 workspace number $ws8 bindsym $mod+9 workspace number $ws9 bindsym $mod+0 workspace number $ws10 # move focused container to workspace bindsym $mod+Shift+1 move container to workspace number $ws1 bindsym $mod+Shift+2 move container to workspace number $ws2 bindsym $mod+Shift+3 move container to workspace number $ws3 bindsym $mod+Shift+4 move container to workspace number $ws4 bindsym $mod+Shift+5 move container to workspace number $ws5 bindsym $mod+Shift+6 move container to workspace number $ws6 bindsym $mod+Shift+7 move container to workspace number $ws7 bindsym $mod+Shift+8 move container to workspace number $ws8 bindsym $mod+Shift+9 move container to workspace number $ws9 bindsym $mod+Shift+0 move container to workspace number $ws10 # reload the configuration file bindsym $mod+Shift+c reload # restart i3 inplace (preserves your layout/session, can be used to upgrade i3) bindsym $mod+Shift+r restart # exit i3 (logs you out of your X session) bindsym $mod+Shift+e exec i3-nagbar -t warning -m \ 'You pressed the exit shortcut. Do you really want to exit i3? This will end your X session.' \ -B 'Yes, exit i3' 'i3-msg exit' # resize window (you can also use the mouse for that) mode "resize" { # These bindings trigger as soon as you enter the resize mode # Pressing left will shrink the window’s width. # Pressing right will grow the window’s width. # Pressing up will shrink the window’s height. # Pressing down will grow the window’s height. bindsym Left resize shrink width 10 px or 10 ppt bindsym Down resize grow height 10 px or 10 ppt bindsym Up resize shrink height 10 px or 10 ppt bindsym Right resize grow width 10 px or 10 ppt # back to normal: Enter or Escape or $mod+r bindsym Return mode "default" bindsym Escape mode "default" bindsym $mod+r mode "default" } bindsym $mod+r mode "resize"
# Start i3bar to display a workspace bar (plus the system information i3status # finds out, if available) bar { status_command i3status }
# Print screen bindsym --release Print exec "maim $HOME/multimedia/screenshots/$(date '+%y%m%d-%H%M-%S').png" bindsym --release Shift+Print exec "maim --hidecursor --select $HOME/multimedia/screenshots/$(date '+%y%m%d-%H%M-%S').png" bindsym --release Ctrl+Print exec "maim | xclip -sel clip -t image/png" bindsym --release Shift+Ctrl+Print exec "maim --hidecursor --select | xclip -sel clip -t image/png"
startx
s-RET