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:

  1. Select region
  2. Select localization (US)
  3. Select keyboard layout (most likely US/ISO)
  4. Select connected if you have Ethernet connection or wireless if you want to connect to wifi.
  5. Choose hostname.
  6. Skip domain name.
  7. Skip proxy.
  8. Select mirror in your region.
  9. Set root password.
  10. Set user's full name, username and password.
  11. Deselect all software packages except base.
  12. To dual boot with Windows select guided partitioning (free space).
  13. Select /home folder on a separate partition.
  14. Start the installation.
  15. Reboot and check that you can boot everything.

2. Setting up GNU/Linux

2.1. User setup

  1. Login as root
  2. Edit /etc/apt/sources and add non-free contrib testing unstable
  3. apt udpate
  4. apt upgrade
  5. apt install sudo
  6. visudo (%wheel ALL=(ALL) NOPASSWD: ALL)
  7. groupadd wheel
  8. usermod -aG wheel YOUR_USERNAME
  9. 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

emacs-lisp[emacs/init.el]
(server-start)
emacs-lisp[emacs/init.el]
(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)
emacs-lisp[emacs/init.el]
(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)
emacs-lisp[emacs/init.el]
(menu-bar-mode   -1)
(tool-bar-mode   -1)
(scroll-bar-mode -1)
emacs-lisp[emacs/init.el]
(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)
emacs-lisp[emacs/init.el]
(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)
emacs-lisp[emacs/init.el]
(use-package trashed)
(setq delete-by-moving-to-trash t)
emacs-lisp[emacs/init.el]
(use-package undo-tree
  :config
  (global-undo-tree-mode))
emacs-lisp[emacs/init.el]
(use-package page-break-lines
  :config
  (global-page-break-lines-mode))
emacs-lisp[emacs/init.el]
(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))
emacs-lisp[emacs/init.el]
(use-package eglot)
emacs-lisp[emacs/init.el]
(use-package project)
emacs-lisp[emacs/init.el]
(use-package vterm)
(use-package eat)
emacs-lisp[emacs/init.el]
(use-package telega
  :custom
  (telega-server-libs-prefix "/usr"))
emacs-lisp[emacs/init.el]
(use-package emms)
emacs-lisp[emacs/init.el]
(use-package multitran
  :bind
  (("s-t" . multitran-at-pos)))
emacs-lisp[emacs/init.el]
(use-package savehist
  :config
  (savehist-mode))
emacs-lisp[emacs/init.el]
(use-package lorem-ipsum)
emacs-lisp[emacs/init.el]
(use-package smartparens
  :init
  (smartparens-global-mode t))
emacs-lisp[emacs/init.el]
(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))
emacs-lisp[emacs/init.el]
(setq dired-listing-switches "-alh"
      dired-dwim-target t
      dired-recursive-copies  'always
      dired-recursive-deletes 'always)
(use-package dired-single)
emacs-lisp[emacs/init.el]
(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)
emacs-lisp[emacs/init.el]
(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)))
emacs-lisp[emacs/init.el]
(use-package expand-region
  :bind
  (("C-M-=" . er/expand-region)))
emacs-lisp[emacs/init.el]
(use-package move-text
  :bind
  (("M-P" . move-text-up)
   ("M-N" . move-text-down)))
emacs-lisp[emacs/init.el]
(keymap-global-set "C-'" 'duplicate-dwim)
(setq duplicate-line-final-position 1)
emacs-lisp[emacs/init.el]
(use-package hl-todo
  :config
  (global-hl-todo-mode 1))
emacs-lisp[emacs/init.el]
(use-package ligature
  :config
  (ligature-set-ligatures
   't '("-<<" "-<" "-<-" "<--" "<---" "<<-" "<-" "->" "->>" "-->" "--->" "->-" ">-" ">>-"
        "=<<" "=<" "=<=" "<==" "<===" "<<=" "<=" "=>" "=>>" "==>" "===>" "=>=" ">=" ">>="
        "<->" "<-->" "<--->" "<---->" "<=>" "<==>" "<===>" "<====>" "::" ":::" "__"
        "<~~" "</" "</>" "/>" "~~>" "==" "!=" "/=" "~=" "<>" "===" "!==" "!===" "=/=" "=!="
        "<:" ":=" "*=" "*+" "<*" "<*>" "*>" "<|" "<|>" "|>" "<." "<.>" ".>" "+*" "=*" "=:" ":>"
        "(*" "*)" "/*" "*/" "[|" "|]" "{|" "|}" "++" "+++" "\\/" "/\\" "|-" "-|" "<!--" "<!---"))
  (global-ligature-mode -1))
emacs-lisp[emacs/init.el]
(use-package magit)
emacs-lisp[emacs/init.el]
(use-package restart-emacs)
emacs-lisp[emacs/init.el]
(use-package bluetooth)

2.2.3. Installing fonts

  1. Wget latest PkgTTC-Iosevka-X.X.X.zip asset from iosevka releases
  2. unzip DOWNLOADED_FILE
  3. mv contents ~/.local/share/fonts
  4. 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

conf-space[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.

conf-space[i3/config]
font pango:monospace 12

Start XDG autostart .desktop files using dex. See also XDG Autostart - ArchWiki

conf-space[i3/config]
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.

conf-space[i3/config]
exec --no-startup-id xss-lock --transfer-sleep-lock -- i3lock --nofork
conf-space[i3/config]
exec --no-startup-id setxkbmap -layout "us,ru" -option 'grp:shifts_toggle' -option "ctrl:nocaps"
conf-space[i3/config]
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.

conf-space[i3/config]
exec --no-startup-id nm-applet
conf-space[i3/config]
exec emacs --background black

Use pactl to adjust volume in PulseAudio.

conf-space[i3/config]
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.

conf-space[i3/config]
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.

conf-space[i3/config]
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.

conf-space[i3/config]
tiling_drag modifier titlebar
conf-space[i3/config]
# 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"
conf-space[i3/config]
# Start i3bar to display a workspace bar (plus the system information i3status
# finds out, if available)
bar {
status_command i3status
}
conf-space[i3/config]
# 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