Chapter 17. Set up emacs

  1. install benchmark-init manually

    Load benchmark directly, without using any package management, so it can benchmark everything. This is then invoked directly from the init scripts. cd ~/vc git clone git@github.com:dholm/benchmark-init-el.git cd benchmark-init-el/ make

  2. Set up config

    Remove default configuration, if any, that gets in the way of ~/.emacs.d/init.el. rm ~/.emacs.d Make sure the right directory exists. mkdir -p ~/.emacs.d

    Get the standard config cp ~/Dropbox/Basic/new_machine/linux/emacs/.emacs.d.init.el.current ~/.emacs.d/init.el

    Note

    ~/.emacs.d/init.el source:

    ;;; init.el --- Initialization file for Emacs -*- lexical-binding: t -*-
    ;;; Commentary:
    ;;; sanmarco version
    ;; Emacs Startup File --- initialization for Emacs
    
    ;; Settings from https://aronbedra.com/emacs.d/
    ;; Settings from https://www.sandeepnambiar.com/my-minimal-emacs-setup/
    ;; Settings from https://codeberg.org/oyvindstegard/emacs-d
    ;;; Code:
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Packaging
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    (require 'package)
    (package-initialize)
    
    
    (unless (package-installed-p 'use-package)
      (package-refresh-contents)
      (package-install 'use-package)
    (eval-when-compile
      (require 'use-package)))
    (require 'bind-key)
    
    ;; ;; Look for my own .el files here
    ;; (push "~/.emacs.d/lisp" load-path)
    
    ;; what does this do?
    ;; (add-hook 'after-change-major-mode-hook (lambda() (electric-indent-mode -1)))
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Custom
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; custom variables and custom faces are in custom.el, as configured in early-init.el
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Packages
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; this is causing freeze on load
    ;; (use-package auto-dark
    ;;   :ensure t
    ;;   :custom
    ;;   :init (auto-dark-mode))
    
    (use-package blacken)
    
    
    (use-package company
    ;; https://tychoish.com/post/better-company/
    ;; (setq company-backends '(company-capf
    ;;                          company-keywords
    ;;                          company-jedi))                       
      :ensure t
      :diminish company-mode
      :config
      (add-hook 'after-init-hook 'global-company-mode)
      :init
      (setq company-tooltip-limit 20)
      (setq company-show-quick-access t)
      (setq company-idle-delay 0)
      (setq company-echo-delay 0)
      (setq column-number-mode t)
    )
    
    (use-package crux
      ;; https://github.com/bbatsov/crux
      :ensure t
      :bind
      ("C-k" . crux-smart-kill-line)
      ("C-c n" . crux-cleanup-buffer-or-region)
      ("C-c f" . crux-recentf-find-file)
      ("C-a" . crux-move-beginning-of-line)
      ("C-d" . crux-insert-date)
    )
    
    (use-package eglot
      :ensure t
      :config
      (add-to-list 'eglot-server-programs '(python-ts-mode . ("rass" "python")))
      :hook
      ((python-ts-mode . eglot-ensure))
    )
    
    (use-package expand-region
      :ensure t
      :bind ("M-m" . er/expand-region))
    
    (use-package flycheck-eglot
      :ensure t
      :after (flycheck eglot)
      :config
      (global-flycheck-eglot-mode 1))
    
    
    ;; (use-package flycheck
    ;;  :ensure t
    ;;  :init (global-flycheck-mode)
    ;;     (setq flycheck-check-syntax-automatically
    ;;           '(save idle-change idle-buffer-switch new-line mode-enabled))
    ;;     (setq flycheck-disabled-checkers '(python-pylint))
    ;;     (setq flycheck-display-errors-delay 0.3)
    ;;     (setq flycheck-display-errors-function 'flycheck-display-error-messages-unless-error-list)
    ;;     (setq flycheck-idle-change-delay 0.2)
    ;;     (setq flycheck-indication-mode 'left-fringe)
    ;;     (setq flycheck-navigation-minimum-level 'error)
    ;;     (setq flycheck-relevant-error-other-file-minimum-level 'error)
    ;;     (setq flycheck-relevant-error-other-file-show nil)
    ;; )
    
    ;; (use-package flycheck-color-mode-line)
    
    ;; (use-package flycheck-inline)
    ;; (with-eval-after-load 'flycheck
    ;;   (add-hook 'flycheck-mode-hook #'flycheck-inline-mode)
    ;;   (add-hook 'flycheck-mode-hook 'flycheck-color-mode-line-mode)
    ;;   (flycheck-pos-tip-mode))
    
    
    (use-package git-gutter
      :config
      (global-git-gutter-mode 't)
      :init
        (setq git-gutter:modified-sign "Δ")
        (setq git-gutter:verbosity 0)
    )
    
    ;; (use-package graphviz-dot-mode)
    
    (add-hook 'nxml-mode-hook
              (lambda ()
                (keymap-set nxml-mode-map "C-<next>" 'rng-next-error)
                (keymap-set nxml-mode-map "C-<prior>" 'rng-previous-error)
    )
    )
    
    (unbind-key "C-o")
    
    (use-package outline-indent
      :commands outline-indent-minor-mode
      :custom
      (outline-indent-ellipsis " ▼")
      :bind
        ("C-o <right>" . outline-indent-open-fold)        ; Open fold at point
        ("C-o <left>"  . outline-indent-close-fold)       ; Close fold at point
        ("C-o <down>"  . outline-indent-open-folds)       ; Open all folds
        ("C-o <up>"    . outline-indent-close-folds)      ; Close all folds
    ;;     ("C-o O" . outline-indent-open-fold-rec)        ; Open fold recursively
        ("C-o TAB" . outline-indent-toggle-fold)         ; Toggle fold at point
        ("C-o t" . outline-indent-toggle-level-at-point) ; Toggle level at point
    
    ;; Selection
        ("C-o v" . outline-indent-select)                ; Select current indented block
    
    ;; Navigation at same indentation level
        ("C-o <next>" . outline-indent-forward-same-level)    ; Next heading at same level
        ("C-o <prior>" . outline-indent-backward-same-level)   ; Previous heading at same level
    
    ;; Insert heading
        ("C-o i" . outline-indent-insert-heading)
    )
    
    ;;(use-package powerline)
    ;;(powerline-default-theme)
    
    (declare-function pyvenv-mode ())
    (use-package pyvenv
      :ensure t
      :config
      (pyvenv-mode 1))
    
    (use-package rainbow-delimiters
      :config
      (add-hook 'prog-mode-hook 'rainbow-delimiters-mode))
    
    (use-package rainbow-mode
      :config
      (setq rainbow-x-colors nil)
      (add-hook 'prog-mode-hook 'rainbow-mode))
    
    (use-package recentf
      :config
      (recentf-mode 1))
    
    (use-package sgml-mode)
    
    ;; (use-package smart-mode-line
    ;;   :ensure t
    ;;   :config
    ;; ;;  (setq sml/theme 'powerline)
    ;;   (add-hook 'after-init-hook 'sml/setup))
    
    (use-package smex
      :bind
      ("M-x" . smex)
      ("M-X" . smex-major-mode-commands))
    
    (use-package solarized-theme
      :ensure t
      :config
      (load-theme 'solarized-gruvbox-light)
      )
    
    (use-package undo-tree
      :ensure t
      :defer 5
      :config
      (global-undo-tree-mode 1)
      (setq undo-tree-enable-undo-in-region nil)
      (setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo-tree/"))))
    
    (use-package which-key
        :config
        (which-key-mode))
    
    
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; ;; Python
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    (add-hook 'python-ts-mode-hook
              (lambda ()
               ;; (keymap-set python-ts-mode-map "C-<next>" 'next-error)
               ;; (keymap-set python-ts-mode-map "C-<prior>" 'previous-error)
              (keymap-set python-ts-mode-map "C-<next>" 'flymake-goto-next-error)
                (keymap-set python-ts-mode-map "C-<prior>" 'flymake-goto-prev-error)
                (keymap-set python-ts-mode-map "C-g" 'goto-line)
                )
    )
    
    (add-to-list `auto-mode-alist '("\\.py\\'" . python-ts-mode))
    
    ;; (add-hook 'python-mode-hook
    ;;           (lambda ()
    ;;             ;; explicitly load company for the occasion when the deferred
    ;;             ;; loading with use-package hasn't kicked in yet
    ;;             (company-mode)
    ;;             )
    ;;           )
    
    ;; (add-hook 'python-mode-hook 'python-isort-on-save-mode)
    
    
    ;; (org-babel-do-load-languages
    ;;  'org-babel-load-languages
    ;;  '((python . t)))
    
    
    
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; ;; LSP and Ruff
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; ;; (setq lsp-keymap-prefix "M-l")
    
    ;; ;; (require 'lsp-mode)
    ;; ;; (add-hook 'python-mode-hook #'lsp)
    
    ;; ;; (require 'flycheck-ruff)
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Flycheck
    ;; sources: https://medium.com/@enzuru/helpful-emacs-python-mode-hooks-especially-for-type-hinting
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; ;; (flycheck-define-checker
    ;; ;;     python-mypy ""
    ;; ;;     :command ("mypy"
    ;; ;;               "--ignore-missing-imports"
    ;; ;;               "--python-version" "3.8"
    ;; ;;               source-original)
    ;; ;;     :error-patterns
    ;; ;;     ((error line-start (file-name) ":" line ": error:" (message) line-end))
    ;; ;;     :modes python-mode
    ;; ;;     :after
    ;; ;;     (add-to-list 'flycheck-checkers 'python-mypy)
    ;; ;;     (remove-hook 'flymake-diagnostic-functions 'flymake-proc-legacy-flymake)
    ;; ;; )
    
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; ;; nXML/Docbook
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; ;;
    ;; ;; might need?  '(add-to-list 'rng-schema-locating-files "~/.schema/schemas.xml"))
    ;; ;; (add-hook 'nxml-mode-hook 'hs-minor-mode)
    ;; ;; ;; optional key bindings, easier than hs defaults
    ;; ;; (define-key nxml-mode-map (kbd "C-c h") 'hs-toggle-hiding)
    
    
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; ;; HTML/CSS
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; (defvar c-basic-offset)
    
    ;; (add-hook 'css-mode-hook
    ;;   (lambda ()
    ;;     (setq c-basic-offset 2)
    ;;     (setq indent-tabs-mode nil)))
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Global Keyboard Mappings
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; Default bindings where key is not already bound by something else
    
    (global-set-key [C-next] 'next-error)               ; Ctrl+<page-down>
    (global-set-key [C-prior] 'previous-error)          ; Ctrl+<page-up>
    (global-set-key [C-return] 'completion-at-point)
    
    
    ;; Bindings that override any other
    (declare-function org-store-link ())
    (require 'bind-key)
    (bind-keys*
     ("C--" .        company-complete)                 ; Ctrl+hyphen
     ("C-;" .        comment-or-uncomment-region)
     ;; ("C-c a" .      org-agenda)
    ;; ("C-c c" .      org-capture)
    ;; ("C-c l" .      org-store-link)
     ("C-c C-n" .    next-error)
     ("C-r" .        replace-string)
     ("C-v" .        yank)                             ; Stop scrolling-up by muscle memory
     ("C-z" .        undo)                             ; Stop minimizing by accident
    )
    
    
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; ;; Finish up
    ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
    ;; (require 'server)
    ;; (if (not (server-running-p)) (server-start));
    
    ;; (provide '.emacs)
    ;; (provide 'init)
    ;; ;;; init.el ends here
    
  3. Cleanup

    Start emacs. See which packages fail to load, and manually install them. M-x package-install

TODO for emacs