dotfiles/emacs/emacs.org

18 KiB

Emacs config

Prelims

Workarounds?

(setq max-lisp-eval-depth 10000)
(setq max-specpdl-size 13000)

start server

(server-start)

use-package compile-time

(eval-when-compile (require 'use-package))
(require 'diminish)
(require 'bind-key)

Custom file

  (setq custom-file "~/dotfiles/emacs/emacs-custom.el")
  (load custom-file)

Org stuff

Scratch buffer

  (setq org-src-preserve-indentation 't)
  (setq initial-major-mode 'org-mode)
  (setq initial-scratch-message "\
  ,#+TITLE: Scratch buffer
  ,#+AUTHOR: Yorick van Pelt

  ")

modules

keybindings

  (bind-keys :map global-map
             ("C-c l" . org-store-link)
             ("C-c a" . org-agenda)
             ("C-c b" . org-iswitchb)
             ("C-c c" . org-capture))

config

  (setq org-pretty-entities t)
  (setq org-startup-indented t)
  (setq org-src-fontify-natively t)
  (setq org-completion-use-ido t)
  (setq org-src-tab-acts-natively t)
  (setq org-ellipsis "⬎")
  (setq org-log-done t)
  (setq org-todo-keywords
        '((sequence "TODO(t)" "WAIT" "|" "DONE(d)" "CANCEL")))
  (setq org-agenda-files (list "~/org/life.org"
            "~/org/ru.org" 
            "~/org/symfo.org"
            "~/org/fiction.org"
            "~/serokell/serok.el/2019.org"
            "~/engineering/lumi.org"
            "~/serokell/serok.el/tasks.org"))
  (setq org-use-fast-todo-selection t)
  (setq org-directory "~/org")

  (defun org-file-path (filename)
    "Return the absolute address of an org file, given its relative name."
    (concat (file-name-as-directory org-directory) filename))

  ; (setq org-inbox-file "~/org/inbox.org")
  (setq org-index-file (org-file-path "life.org"))
  (setq org-archive-location
      (concat (org-file-path "archive.org") "::* From %s"))

  (setq org-default-notes-file "~/org/refile.org")

  (setq org-agenda-todo-ignore-scheduled t)

  (setq org-capture-templates
        '(("l" "Today I learned"
           entry
           (file+datetree (org-file-path "til.org"))
           "* %?\n")
          ("u" "link"
           entry
           (file+headline org-index-file "check links")
           "* %^L\n")
          ("w" "Week review"
           entry
           (file+datetree (org-file-path "weeklog.org"))
           "* %?\n")
          ("t" "todo item"
           entry
           (file+headline org-index-file "todo")
           "* TODO %?\n")))
l Today I learned entry (file+datetree (org-file-path til.org)) * %?
u link entry (file+headline org-index-file check links) * %^L
w Week review entry (file+datetree (org-file-path weeklog.org)) * %?
t todo item entry (file+headline org-index-file todo) * TODO %?

add templates

    (add-to-list 'org-structure-template-alist
                 '("el" "#+BEGIN_SRC emacs-lisp\n?\n#+END_SRC"))
    (add-to-list 'org-structure-template-alist
                 '("py" "#+BEGIN_SRC python\n?\n#+END_SRC"))
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((python . t)
     
     ))

org-bullets

(use-package org-bullets
    :init (add-hook 'org-mode-hook 'org-bullets-mode t)
    :commands org-bullets-mode
)

TODO org-ref

  (use-package org-ref
      :disabled
      :config
      (setq org-ref-completion-library 'org-ref-ivy-cite))

Look

Solarized

;; used to fix modeline
(defvar after-load-theme-hook nil
  "Hook run after a color theme is loaded using `load-theme'.")
(defun reload-solarized (event)
  (let ((theme (intern (concat "solarized-" (with-temp-buffer
                                              (insert-file-contents "~/dotfiles/color-scheme")
                                              (string-trim (buffer-string))
                                              )))))
    (load-theme theme t)
    (run-hooks 'after-load-theme-hook)))
(use-package solarized
  :init
  (setq solarized-distinct-fringe-background t)
  (setq solarized-scale-org-headlines nil)
  :config (reload-solarized nil))

;; auto-reload
(use-package filenotify
  :after solarized
  :config
  (file-notify-add-watch "~/dotfiles/color-scheme" '(change) 'reload-solarized))

Cleaner frames

  ;; toolbars are disabled in early-init.el
  (setq inhibit-startup-screen t)

hl-line

(when window-system (global-hl-line-mode))
(show-paren-mode t)

live hex color previews

from https://vickychijwani.me/nuggets-from-my-emacs-part-i/

;; CSS color values colored by themselves
;; http://news.ycombinator.com/item?id=873541
(defvar hexcolor-keywords
  '(("#[abcdef[:digit:]]+"
     (0 (put-text-property
         (match-beginning 0)
         (match-end 0)
         'face (list :background
                     (match-string-no-properties 0)))))))

(defun hexcolor-add-to-font-lock ()
  (font-lock-add-keywords nil hexcolor-keywords))
(add-hook 'css-mode-hook 'hexcolor-add-to-font-lock)

doom-modeline

  (use-package doom-modeline
    :hook
    (after-init . doom-modeline-mode)
    (after-load-theme . doom-modeline-mode))

Feel

  (defalias 'yes-or-no-p 'y-or-n-p)
  (setq compilation-scroll-output t)

fix escape

; Map escape to cancel (like C-g)...
(define-key isearch-mode-map [escape] 'isearch-abort)   ;; isearch
(define-key isearch-mode-map "\e" 'isearch-abort)   ;; \e seems to work better for terminals
(global-set-key [escape] 'keyboard-escape-quit)         ;; everywhere else

Fix mouse wheel

(setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ;; one line at a time
(setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
(setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
(setq scroll-step 1) ;; keyboard scroll one line at a time
(defun sfp-page-down (&optional arg)
    (interactive "^P")
    (setq this-command 'next-line)
    (next-line
    (- (window-text-height)
	next-screen-context-lines)))
(put 'sfp-page-down 'isearch-scroll t)
(put 'sfp-page-down 'CUA 'move)
(defun sfp-page-up (&optional arg)
    (interactive "^P")
    (setq this-command 'previous-line)
    (previous-line
    (- (window-text-height)
	next-screen-context-lines)))
(put 'sfp-page-up 'isearch-scroll t)
(put 'sfp-page-up 'CUA 'move)
(setq scroll-error-top-bottom t)

fix c-z

(global-unset-key (kbd "C-z"))

Ivy

  (use-package ivy
      :init
      (setq ivy-height 10)
      (setq ivy-use-virtual-buffers t)
      (setq enable-recursive-minibuffers t)
      :config
      (ivy-mode t)
      :diminish
      :bind (("C-s" . swiper)
             ("C-c C-r" . ivy-resume)
             ("C-x b" . ivy-switch-buffer)
             ("<f6>" . ivy-resume)))

Counsel

    (use-package counsel
        :bind (("M-x" . counsel-M-x)
               ("C-x C-f" . counsel-find-file)
               ("C-h f" . counsel-describe-function)
               ("C-h v" . counsel-describe-variable)))

(global-set-key (kbd "<f1> l") 'counsel-find-library) (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol) (global-set-key (kbd "<f2> u") 'counsel-unicode-char) ;; (global-set-key (kbd "C-c g") 'counsel-git) ;; (global-set-key (kbd "C-c j") 'counsel-git-grep) ;; (global-set-key (kbd "C-c k") 'counsel-ag) ;; (global-set-key (kbd "C-x l") 'counsel-locate) ;; (global-set-key (kbd "C-S-o") 'counsel-rhythmbox) ;; (define-key read-expression-map (kbd "C-r") 'counsel-expression-history)

projectile

    (use-package projectile
      :init
      (setq projectile-mode-line "Projectile")
      :config
      (projectile-global-mode t)
      )
  ;(use-package counsel-projectile))

ggtags

(use-package ggtags
:bind ("M-." . ggtags-find-tag-dwim))

intuitive window resize

;; intuitive window resizing
(defun xor (b1 b2)
  (or (and b1 b2)
      (and (not b1) (not b2))))

(defun move-border-left-or-right (arg dir)
  "General function covering move-border-left and move-border-right. If DIR is
     t, then move left, otherwise move right."
  (interactive)
  (if (null arg) (setq arg 3))
  (let ((left-edge (nth 0 (window-edges))))
    (if (xor (= left-edge 0) dir)
        (shrink-window arg t)
        (enlarge-window arg t))))

(defun move-border-up-or-down (arg dir)
  "General function covering move-border-up and move-border-down. If DIR is
     t, then move up, otherwise move down."
  (interactive)
  (if (null arg) (setq arg 3))
  (let ((top-edge (nth 1 (window-edges))))
    (if (xor (= top-edge 0) dir)
        (shrink-window arg nil)
        (enlarge-window arg nil))))

(defun move-border-left (arg)
  (interactive "P")
  (move-border-left-or-right arg t))

(defun move-border-right (arg)
  (interactive "P")
  (move-border-left-or-right arg nil))

(defun move-border-up (arg)
  (interactive "P")
  (move-border-up-or-down arg t))

(defun move-border-down (arg)
  (interactive "P")
  (move-border-up-or-down arg nil))
;; keybindings for window resizing
(global-set-key (kbd "C-S-<left>") 'move-border-left)
(global-set-key (kbd "C-S-<right>") 'move-border-right)
(global-set-key (kbd "C-s-<up>") 'move-border-up)
(global-set-key (kbd "C-s-<down>") 'move-border-down)
move-border-down

TODO i3-emacs

Terminal

(xterm-mouse-mode 1)
(define-key local-function-key-map "\033[73;5~" [(control return)])

editing

line numbers

relative

(use-package linum-relative
    :commands linum-relative-toggle)

enable globally

(global-linum-mode t)

direnv

(use-package direnv
 :config
 (direnv-mode))

autocomplete

  (use-package company
    :diminish
  :hook (after-init . global-company-mode)
  :config
  ;; use copilot
  (delq 'company-preview-if-just-one-frontend company-frontends))

Indentation

  (setq-default indent-tabs-mode nil)
  (setq-default tab-width 2) ; or any other preferred value
  (defvaralias 'c-basic-offset 'tab-width)
  (defvaralias 'cperl-indent-level 'tab-width)
(defun yorick/copilot-tab (arg)
  (interactive "P")
  (or (copilot-accept-completion)
      (company-indent-or-complete-common arg)))
  (define-key prog-mode-map (kbd "<tab>") #'yorick/copilot-tab)

smart home key

;; "smart" home, i.e., home toggles b/w 1st non-blank character and 1st column
(defun smart-beginning-of-line ()
  "Move point to first non-whitespace character or beginning-of-line."
  (interactive "^") ; Use (interactive "^") in Emacs 23 to make shift-select work
  (let ((oldpos (point)))
    (back-to-indentation)
    (and (= oldpos (point))
         (beginning-of-line))))
(global-set-key (kbd "C-a") 'smart-beginning-of-line)

git-gutter-fringe

  ;; (use-package git-gutter-fringe
  ;;     :config (global-git-gutter-mode t))

all-the-icons

(use-package all-the-icons
    :commands all-the-icons-insert)

backups

from emacs wiki

(setq vc-make-backup-files t)
(setq
   backup-by-copying t      ; don't clobber symlinks
   backup-directory-alist
    '(("." . "~/.emacs.d/.saves"))    ; don't litter my fs tree
   delete-old-versions t
   kept-new-versions 6
   kept-old-versions 2
   version-control t)       ; use versioned backups

Undo-tree

  (use-package undo-tree
    :diminish undo-tree-mode
    :init
    ;; prevent .~undo-tree file pollution
    (setq undo-tree-auto-save-history nil)
    :config
    (global-undo-tree-mode))

Evil

  (setq evil-want-C-i-jump nil)

  (use-package evil
    :config
    (evil-mode t)
    (evil-set-undo-system 'undo-tree)

    (define-key evil-motion-state-map (kbd "<home>") 'smart-beginning-of-line)

    ;; change cursor based on mode
    (add-hook 'evil-insert-state-entry-hook (lambda () (when (not (display-graphic-p)) (send-string-to-terminal "\033[5 q"))))
    (add-hook 'evil-normal-state-entry-hook (lambda () (when (not (display-graphic-p)) (send-string-to-terminal "\033[0 q"))))
    )
  (use-package evil-mc
    :config (global-evil-mc-mode 1)
    :after evil)
  (use-package which-key
    :diminish
    :init
    (setq which-key-allow-evil-operators t)
    (setq which-key-show-operator-state-maps t)
    :config
    (which-key-mode 1)
    (which-key-setup-minibuffer)) ; do I need this?
t

evil-goggles

  (use-package evil-goggles
    :diminish
    :after evil
    :config
    (evil-goggles-mode)
    (evil-goggles-use-diff-faces))

TODO multiple-cursors

crdt

  (use-package crdt
    :commands (crdt-connect))

copilot

(use-package copilot
  :commands (copilot-login copilot-mode)
  :bind (:map copilot-mode-map ("TAB" . copilot-accept-completion)))

DONE fix clipboard on wayland

  (setq wl-copy-process nil)
  (defun wl-copy (text)
    (setq wl-copy-process (let ((default-directory "~"))
                            (make-process :name "wl-copy"
                                          :buffer nil
                                          :command '("wl-copy" "-f" "-n")
                                          :noquery t
                                          :connection-type 'pipe)))
    (process-send-string wl-copy-process text)
    (process-send-eof wl-copy-process))
  (defun wl-paste ()
    (if (and wl-copy-process (process-live-p wl-copy-process))
        nil
        (let ((default-directory "~"))
          (shell-command-to-string "wl-paste -n | tr -d '\r'"))))
  (setq interprogram-cut-function 'wl-copy)
  (setq interprogram-paste-function 'wl-paste)
wl-paste

Tools

Magit

  (use-package magit
      :bind (("C-c g" . magit-status)
             ("C-c C-g l" . magit-log-all)))
  (use-package forge
    :init
(setq forge-topic-list-limit '(60 . 0))
    :after magit)

weechat

(use-package weechat
  :commands weechat-connect
  :init
  (setq weechat-more-lines-amount 100)
  (setq weechat-host-default "pennyworth.yori.cc")
  (setq weechat-mode-default "ssh -W localhost:%p %h")
  (setq weechat-modules '(weechat-button weechat-complete weechat-notifications))
)

notmuch

(use-package notmuch
      :bind (("C-c n" . notmuch)))

language-specific

markdown

  (use-package markdown-mode
    :commands (markdown-mode gfm-mode)
    :mode (("README\\.md\\'" . gfm-mode)
           ("\\.md\\'" . markdown-mode)
           ("\\.markdown\\'" . markdown-mode))
    :init (setq markdown-command "multimarkdown"))

org

TODO spellchecking

TODO disable linum on org mode

TODO use org-cliplink

lua

(use-package lua-mode
  :commands (lua-mode)
  :mode (("\\.lua\\'" . lua-mode)))

nix


  (defun nix-flake-current-dir ()
    (interactive)
    (let ((default-directory (projectile-project-root)))
      (nix-flake (projectile-project-root))))
  (use-package nix-mode
    :commands (nix-mode nix-flake)
    :bind (("C-c f" . nix-flake-current-dir))
    :mode (("\\.nix\\'" . nix-mode)))

lsp

  (use-package lsp-mode
    :init
    (setq lsp-keymap-prefix "C-c s")
    :hook
    (lsp-mode . lsp-enable-which-key-integration)
    :commands
    (lsp lsp-deferred))
  (use-package lsp-ivy
    :commands lsp-ivy-workspace-symbol
    :after lsp)
  (use-package lsp-ui
    :commands lsp-ui-mode
    :after lsp)
  (setq gc-cons-threshold 100000000)
  (setq read-process-output-max (* 1024 1024 3)) ;; 3mb
3145728

haskell

  (load-library "haskell-mode-autoloads")
  ;;   (use-package intero
  ;;    :config     (add-hook 'haskell-mode-hook 'intero-mode)
  ;;   )

TODO intero / haskell mode https://wiki.haskell.org/Emacs

rust

(use-package rust-mode
    :commands (rust-mode)
    :mode (("\\.rs\\'" . rust-mode)))

terraform-mode

(use-package terraform-mode
    :commands (terraform-mode)
    :mode (("\\.tf\\'" . terraform-mode)))

vue

(use-package vue-mode
    :commands (vue-mode)
    :mode (("\\.vue\\'" . vue-mode)))

reason

(use-package reason-mode
    :commands (reason-mode)
    :mode (("\\.re\\'" . reason-mode)))

TODO proof-general