nixos/config/emacs/emacs.org

22 KiB

#+title Sakomacs configuration

Emacs from scratch

DONE move init.el to here

CLOSED: [2023-09-08 Fri 23:20]

  • State "DONE" from "TODO" [2023-09-08 Fri 23:20]

Usage

M-x org-bable-tangle

ui configuration

    ;; UI/UX
    (setq inhibit-startup-message t)
    ;; make it look like neovim a little
    (scroll-bar-mode -1)
    (tool-bar-mode -1)
    (tooltip-mode -1)
    (set-fringe-mode 10)
    (menu-bar-mode -1)
    ;; Line Numbers
    (column-number-mode)
    (global-display-line-numbers-mode t)
    ;; disable line numbers on some modes
    (dolist (mode '(org-mode-hook
                    term-mode-hook
                    eshell-mode-hook
                    treemacs-mode-hook))
      (add-hook mode (lambda () (display-line-numbers-mode 0))))
    ;; Bell
    (setq visible-bell t)

Keymaps

(global-set-key (kbd "C-M-j") 'counsel-switch-buffer)
(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Fonts

      (set-face-attribute `default nil :font "JetBrains Mono" :height 150)

Package setup

(require `package)

(setq package-archives `(("mepla" . "https://melpa.org/packages/")
			 ("org" . "https://orgmode.org/elpa/")
			 ("elpa" . "https://elpa.gnu.org/packages/")))

(package-initialize)
(unless package-archive-contents
  (package-refresh-contents))

;; Init package for non-linux
(unless (package-installed-p `use-package)
  (package-install `use-package))

(require 'use-package)
(setq use-package-always-ensure t)

Packages

Command Log Mode

  (use-package command-log-mode)

Command Autocompletion Packages

;; better search
(use-package swiper)
;; better commands
(use-package counsel)
;; autocompletion on commands (?)
(use-package ivy
  :diminish
  :bind (("C-s" . swiper)
         :map ivy-minibuffer-map
         ("TAB" . ivy-alt-done)	
         ("C-l" . ivy-alt-done)
         ("C-j" . ivy-next-line)
         ("C-k" . ivy-previous-line)
         :map ivy-switch-buffer-map
         ("C-k" . ivy-previous-line)
         ("C-l" . ivy-done)
         ("C-d" . ivy-switch-buffer-kill)
         :map ivy-reverse-i-search-map
         ("C-k" . ivy-previous-line)
	 ("C-d" . ivy-reverse-i-search-kill))
  :demand
  :config
  (ivy-mode 1))
;; better ivy autocompletion
(use-package ivy-rich
  :init
  (ivy-rich-mode 1))

;; counsel M+X
(use-package counsel
  :bind (("M-x" . counsel-M-x)
	 ("C-x b" . counsel-ibuffer)
	 ("C-x C-f" . counsel-find-file)
	 :map minibuffer-local-map
	 ("C-r" . 'counsel-minibuffer-history))
  :config
  (setq ivy-inital-inputs-alist nil))

Custom Themes

  (use-package doom-themes
  :ensure t
  :config
  ;; Global settings (defaults)
  (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
        doom-themes-enable-italic t) ; if nil, italics is universally disabled
  ;; load the theme
  (load-theme 'doom-challenger-deep t)

  ;; Enable flashing mode-line on errors
  (doom-themes-visual-bell-config))
  ;; Enable custom neotree theme (all-the-icons must be installed!)
  ;;(doom-themes-neotree-config)
  ;; or for treemacs users
  ;;(setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
  ;;(doom-themes-treemacs-config)
  ;; Corrects (and improves) org-mode's native fontification.
  ;;(doom-themes-org-config))

Nerd-Fonts (All of the Icons doesnt work for me)

(use-package nerd-icons
  :custom
  ;; "Symbols Nerd Font Mono" is the default and is recommended
  ;; but you can use any other Nerd Font if you want
  (nerd-icons-font-family "JetBrainsMono NF")
  )

Rainbow Delimiters

TODO find something like this for other languages
(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))

Keybinding autocompletion

(use-package which-key
  :init (which-key-mode)
  :diminish which-key-mode
  :config
  (setq which-key-idle-delay 1))

Custom Modeline

(use-package doom-modeline
  :ensure t
  :init (doom-modeline-mode 1)
  :custom ((doom-modeline-height 35)))

Better help menu

(use-package helpful
  :ensure t
  :custom
  (counsel-describe-function-function #'helpful-callable)
  (counsel-describe-variable-function #'helpful-variable)
  :bind
  ([remap describe-function ] . counsel-describe-function)
  ([remap describe-command] . helpful-command)
  ([remap describe-variable] . counsel-describe-variable)
  ([remap describe-key] . helpful-key))

General Leader Key

  (use-package general
    :config
    (general-create-definer sakomacs/leader-keys
      :keymaps `(normal insert visual emacs)
      :prefix "SPC"
      :global-prefix "C-SPC")
    (sakomacs/leader-keys
      "t" `(:ignore t :which-key "toggles")
      "tt" `(counsel-load-theme :which-key "choose theme")
      "e" `(:ignore e :which-key "explorer")
      "ee" `(treemacs :which-key "treemacs")))

Evil Mode (vim)

(use-package evil
  :init
  (setq evil-want-integration t)
  (setq evil-want-keybinding nil)
  (setq evil-want-C-u-scroll t)
  (setq evil-want-C-i-jump nil)
  :hook (evil-mode . sakomacs/evil-hook)
  :ensure t
  :demand
  :config
  (evil-mode 1)
  (define-key evil-insert-state-map (kbd "C-g") 'evil-normal-state)
  (define-key evil-insert-state-map (kbd "C-h") `evil-delete-backward-char-and-join)

  ;; visual line motion
  (evil-global-set-key 'motion "j" 'evil-next-visual-line)
  (evil-global-set-key 'motion "k" 'evil-previous-visual-line)

  (evil-set-initial-state 'messages-buffer-mode 'normal)
  (evil-set-initial-state 'dashboard-mode 'normal))

;; extra things for Evil
(use-package evil-collection
  :after evil
  :config
  (evil-collection-init))

Hydra for scaling text

(use-package hydra)
(defhydra hydra-text-scale (:timeout 4)
  "scale text"
  ("j" text-scale-increase "in")
  ("k" text-scale-decrease "out")
  ("f" nil "finished" :exit t))

(sakomacs/leader-keys
  "ts" '(hydra-text-scale/body :which-key "scale text"))

Helpful for projects

(use-package projectile
  :diminish projectile-mode
  :demand
  :config (projectile-mode)
  :custom ((projectile-completion-system 'ivy))
  :bind-keymap
  ("C-c p" . projectile-command-map)
  :init
  (when (file-directory-p "~/dev")
    (setq projectile-project-search-path '("~/dev")))
  (setq projectile-switch-project-action #'projectile-dired))

(use-package counsel-projectile
  :config (counsel-projectile-mode))

Org-Mode

(defun sakomacs/org-mode-setup ()
  (org-indent-mode)
  (variable-pitch-mode 1)
  (visual-line-mode 1))

(use-package org
  :hook (org-mode . sakomacs/org-mode-setup)
  :config
  (setq org-ellipsis "▼")
  (setq org-agenda-start-with-log-mode t)
  (setq org-log-done 'time)
  (setq org-log-into-drawer t)

  ;; org habits thing
  (require 'org-habit)
  (add-to-list 'org-modules 'org-habit)
  (setq org-habit-graph-column 60)

  ;; archive thingy i forgot
  (setq org-refile-targets
      '(("archive.org" :maxlevel . 1)))

  ;; save org buffer before refile
  (advice-add 'org-refile :after 'org-save-all-org-buffers)

  ;; org mode src thing
  (require 'org-tempo)

  (add-to-list 'org-structure-template-alist '("sh" . "src shell"))
  (add-to-list 'org-structure-template-alist '("el" . "src emacs-lisp"))
  (add-to-list 'org-structure-template-alist '("py" . "src python"))
  
  ;; extra keywords
  (setq org-todo-keywords
   '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
     (sequence "PLAN(p)" "READY(r)" "ACTIVE(a)" "HOLD(h)" "|" "COMPLETED(c)" "CANC(k@)")  )

  ;; custom commands for org-agenda
 (setq org-agenda-custom-commands
   '(("d" "Dashboard"
     ((agenda "" ((org-deadline-warning-days 7)))
      (todo "NEXT"
        ((org-agenda-overriding-header "Next Tasks")))
      (tags-todo "agenda/ACTIVE" ((org-agenda-overriding-header "Active Projects")))))

    ("n" "Next Tasks"
     ((todo "NEXT"
        ((org-agenda-overriding-header "Next Tasks")))))

    ("W" "Work Tasks" tags-todo "+work-email")

    ;; Low-effort next actions
    ("e" tags-todo "+TODO=\"NEXT\"+Effort<15&+Effort>0"
     ((org-agenda-overriding-header "Low Effort Tasks")
      (org-agenda-max-todos 20)
      (org-agenda-files org-agenda-files)))

    ("w" "Workflow Status"
      (todo "PLAN"
            ((org-agenda-overriding-header "In Planning")
             (org-agenda-todo-list-sublevels nil)
             (org-agenda-files org-agenda-files)))
      (todo "READY"
            ((org-agenda-overriding-header "Ready for Work")
             (org-agenda-files org-agenda-files)))
      (todo "ACTIVE"
            ((org-agenda-overriding-header "Active Projects")
             (org-agenda-files org-agenda-files)))
      (todo "COMPLETED"
            ((org-agenda-overriding-header "Completed Projects")
             (org-agenda-files org-agenda-files)))
      (todo "CANC"
            ((org-agenda-overriding-header "Cancelled Projects")
             (org-agenda-files org-agenda-files))))))) 

  (setq org-agenda-files
	'("~/org/tasks.org")
	'("~/org/work.org"))

  (setq org-adapt-indentation t)

  (setq org-capture-templates
  `(("t" "Tasks / Projects")
    ("tt" "Task" entry (file+olp "~/org/tasks.org" "Inbox")
    "* TODO %?\n  %U\n  %a\n  %i" :empty-lines 1))))


;; i need more bullets, i need more bullets, i need more bullets, bigger weapons, bigger weapons, bigger weapons
;; thanks for the protein sir
(use-package org-bullets
  :after org
  :hook (org-mode . org-bullets-mode)
  :custom
  (org-bullets-bullet-list '("◉" "○" "●" "○" "●" "○" "●")))

;; word
(defun sakomacs/org-mode-visual-fill ()
  (setq visual-fill-column-width 100
	visual-fill-column-center-text t)
  (visual-fill-column-mode 1))

(use-package visual-fill-column
  :hook (org-mode . sakomacs/org-mode-visual-fill))

Treemacs

(use-package treemacs
  :ensure t
  :defer t
  :init
  (with-eval-after-load 'winum
    (define-key winum-keymap (kbd "M-0") #'treemacs-select-window))
  :config
  (progn
    (setq treemacs-collapse-dirs                   (if treemacs-python-executable 3 0)
          treemacs-deferred-git-apply-delay        0.5
          treemacs-directory-name-transformer      #'identity
          treemacs-display-in-side-window          t
          treemacs-eldoc-display                   'simple
          treemacs-file-event-delay                2000
          treemacs-file-extension-regex            treemacs-last-period-regex-value
          treemacs-file-follow-delay               0.2
          treemacs-file-name-transformer           #'identity
          treemacs-follow-after-init               t
          treemacs-expand-after-init               t
          treemacs-find-workspace-method           'find-for-file-or-pick-first
          treemacs-git-command-pipe                ""
          treemacs-goto-tag-strategy               'refetch-index
          treemacs-header-scroll-indicators        '(nil . "^^^^^^")
          treemacs-hide-dot-git-directory          t
          treemacs-indentation                     2
          treemacs-indentation-string              " "
          treemacs-is-never-other-window           nil
          treemacs-max-git-entries                 5000
          treemacs-missing-project-action          'ask
          treemacs-move-forward-on-expand          nil
          treemacs-no-png-images                   nil
          treemacs-no-delete-other-windows         t
          treemacs-project-follow-cleanup          nil
          treemacs-persist-file                    (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
          treemacs-position                        'left
          treemacs-read-string-input               'from-child-frame
          treemacs-recenter-distance               0.1
          treemacs-recenter-after-file-follow      nil
          treemacs-recenter-after-tag-follow       nil
          treemacs-recenter-after-project-jump     'always
          treemacs-recenter-after-project-expand   'on-distance
          treemacs-litter-directories              '("/node_modules" "/.venv" "/.cask")
          treemacs-project-follow-into-home        nil
          treemacs-show-cursor                     nil
          treemacs-show-hidden-files               t
          treemacs-silent-filewatch                nil
          treemacs-silent-refresh                  nil
          treemacs-sorting                         'alphabetic-asc
          treemacs-select-when-already-in-treemacs 'move-back
          treemacs-space-between-root-nodes        t
          treemacs-tag-follow-cleanup              t
          treemacs-tag-follow-delay                1.5
          treemacs-text-scale                      nil
          treemacs-user-mode-line-format           nil
          treemacs-user-header-line-format         nil
          treemacs-wide-toggle-width               70
          treemacs-width                           35
          treemacs-width-increment                 1
          treemacs-width-is-initially-locked       t
          treemacs-workspace-switch-cleanup        nil)

    ;; The default width and height of the icons is 22 pixels. If you are
    ;; using a Hi-DPI display, uncomment this to double the icon size.
    ;;(treemacs-resize-icons 44)

    (treemacs-follow-mode t)
    (treemacs-filewatch-mode t)
    (treemacs-fringe-indicator-mode 'always)
    (when treemacs-python-executable
      (treemacs-git-commit-diff-mode t))

    (pcase (cons (not (null (executable-find "git")))
                 (not (null treemacs-python-executable)))
      (`(t . t)
       (treemacs-git-mode 'deferred))
      (`(t . _)
       (treemacs-git-mode 'simple)))

    (treemacs-hide-gitignored-files-mode nil))
  :bind
  (:map global-map
        ("M-0"       . treemacs-select-window)
        ("C-x t 1"   . treemacs-delete-other-windows)
        ("C-x t d"   . treemacs-select-directory)
        ("C-x t B"   . treemacs-bookmark)
        ("C-x t C-t" . treemacs-find-file)
        ("C-x t M-t" . treemacs-find-tag)))

(use-package treemacs-evil
  :after (treemacs evil)
  :ensure t)

(use-package treemacs-projectile
  :after (treemacs projectile)
  :ensure t)

(use-package treemacs-magit
  :after (treemacs magit)
  :ensure t)

Dev Packages

Magit (git in emacs)

(use-package magit
  :custom
  (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))

Forge for Magit (Adds github, gitlab, etc PRs and Issues to magit)

make sure to setup authinfo

(use-package forge
  :after magit)
(setq auth-sources '("~/.authinfo"))

Lsp-mode

Language Servers
  (defun sakomacs/lsp-mode-setup ()
    (setq lsp-headerline-breadcrumb-segments '(path-up-to-project file symbols))
    (lsp-headerline-breadcrumb-mode))

    (use-package lsp-mode
      :commands (lsp lsp-deferred)
      :hook (lsp-mode . sakomacs/lsp-mode-setup)
      :init
      (setq lsp-keymap-prefix "C-c l")
      :config
      (lsp-enable-which-key-integration t))
Better lsp mode ui
  (use-package lsp-ui
    :hook (lsp-mode . lsp-ui-mode)
    :custom
    (lsp-ui-doc-position 'bottom))
Treemacs Lsp
  (use-package lsp-treemacs
    :after lsp)
lsp-ivy
(use-package lsp-ivy)
Languages
Javascript
  (use-package js2-mode
  :mode "\\.js\\'"
  :hook (js2-mode . lsp-deferred))
Nix
  (use-package nix-mode
    :hook (nix-mode . format-all-mode) 
   :mode "\\.nix\\'")

Commenter

  (use-package evil-nerd-commenter
  :bind ("M-/" . evilnc-comment-or-uncomment-lines))

Company Mode (Better Autocompletion)

(use-package company
  :after lsp-mode
  :hook (lsp-mode . company-mode)
  :bind (:map company-active-map
         ("<tab>" . company-complete-selection))
        (:map lsp-mode-map
         ("<tab>" . company-indent-or-complete-common))
  :custom
  (company-minimum-prefix-length 1)
  (company-idle-delay 0.0))

(use-package company-box
  :hook (company-mode . company-box-mode))

Formatting

(use-package format-all
  :custom
  ((setq format-all-formatters (("Nix" alejandra))))
  :hook
  ((format-all-mode . format-all-ensure-formatter)
   (prog-mode . format-all-mode)))

Dired (quick file management in emacs)

Dired is a built-in file manager for Emacs that does some pretty amazing things! Here are some key bindings you should try out:

Key Bindings

Navigation

Emacs / Evil

  • n / j - next line
  • p / k - previous line
  • j / J - jump to file in buffer
  • RET - select file or directory
  • ^ - go to parent directory
  • S-RET / g O - Open file in "other" window
  • M-RET - Show file in other window without focusing (previewing files)
  • g o (dired-view-file) - Open file but in a "preview" mode, close with q
  • g / g r Refresh the buffer with revert-buffer after changing configuration (and after filesystem changes!)
Marking files
  • m - Marks a file
  • u - Unmarks a file
  • U - Unmarks all files in buffer
  • * t / t - Inverts marked files in buffer
  • % m - Mark files in buffer using regular expression
  • * - Lots of other auto-marking functions
  • k / K - "Kill" marked items (refresh buffer with g / g r to get them back)
  • Many operations can be done on a single file if there are no active marks!
Copying and Renaming files
  • C - Copy marked files (or if no files are marked, the current file)
  • Copying single and multiple files
  • U - Unmark all files in buffer
  • R - Rename marked files, renaming multiple is a move!
  • % R - Rename based on regular expression: ^test , old-\&

Power command: C-x C-q (dired-toggle-read-only) - Makes all file names in the buffer editable directly to rename them! Press Z Z to confirm renaming or Z Q to abort.

Deleting files
  • D - Delete marked file
  • d - Mark file for deletion
  • x - Execute deletion for marks
  • delete-by-moving-to-trash - Move to trash instead of deleting permanently
Creating and extracting archives
  • Z - Compress or uncompress a file or folder to (.tar.gz)
  • c - Compress selection to a specific file
  • dired-compress-files-alist - Bind compression commands to file extension
Other common operations
  • T - Touch (change timestamp)
  • M - Change file mode
  • O - Change file owner
  • G - Change file group
  • S - Create a symbolic link to this file
  • L - Load an Emacs Lisp file into Emacs

Configuration

    (use-package dired
    :ensure nil
    :commands (dired dired-jump)
    :bind (("C-x C-j" . dired-jump))
    :custom ((dired-listing-switches "-agho --group-directories-first"))
    :config
    (evil-collection-define-key 'normal 'dired-mode-map
      "h" 'dired-single-up-directory
      "l" 'dired-single-buffer))

  (use-package dired-single)

  ;; (use-package dired-open
  ;;   :config
  ;;   (setq dired-open-extensions '(("png" . "feh")
  ;;                                 ("mkv" . "mpv"))))

  ;; (use-package dired-hide-dotfiles
  ;;   :hook (dired-mode . dired-hide-dotfiles-mode)
  ;;   :config
  ;;   (evil-collection-define-key 'normal 'dired-mode-map
  ;;     "H" 'dired-hide-dotfiles-mode))

Folder Cleaning

;; NOTE: If you want to move everything out of the ~/.emacs.d folder
;; reliably, set `user-emacs-directory` before loading no-littering!
;(setq user-emacs-directory "~/.cache/emacs")

(use-package no-littering)

;; no-littering doesn't set this by default so we must place
;; auto save files in the same path as it uses for sessions
(setq auto-save-file-name-transforms
      `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))

Org Mode Configuration Setup

Babel Languages

   (org-babel-do-load-languages
  'org-babel-load-languages
  '((emacs-lisp . t)
    (python . t)))

Auto-tangle Configuration

  (defun sakomacs/org-babel-tangle-config ()
    (when (string-equal (buffer-file-name)
                        (expand-file-name "~/nixos/config/emacs/emacs.org"))
      (let ((org-confirm-babel-evaluate nil))
        (org-babel-tangle)))
    (add-hook 'org-mode-hook (lambda () (add-hook 'after-save-hook #'sakomacs/org-babel-tangle-config))))

Terminals

term-mode

  (use-package term
  :config
  (setq explicit-shell-file-name "zsh"))

EShell

god dammit why are they making my shells in emacs lisp

(defun sakomacs/configure-eshell ()
  ;; Save command history when commands are entered
  (add-hook 'eshell-pre-command-hook 'eshell-save-some-history)

  ;; Truncate buffer for performance
  (add-to-list 'eshell-output-filter-functions 'eshell-truncate-buffer)

  ;; Bind some useful keys for evil-mode
  (evil-define-key '(normal insert visual) eshell-mode-map (kbd "C-r") 'counsel-esh-history)
  (evil-define-key '(normal insert visual) eshell-mode-map (kbd "<home>") 'eshell-bol)
  (evil-normalize-keymaps)

  (setq eshell-history-size         10000
        eshell-buffer-maximum-lines 10000
        eshell-hist-ignoredups t
        eshell-scroll-to-bottom-on-input t))

(use-package eshell-git-prompt)

(use-package eshell
  :hook (eshell-first-time-mode . sakomacs/configure-eshell)
  :config

  (with-eval-after-load 'esh-opt
    (setq eshell-destroy-buffer-when-process-dies t)
    (setq eshell-visual-commands '("htop" "zsh" "vim")))

  (eshell-git-prompt-use-theme 'powerline))