nixos/config/emacs/emacs.org
2024-02-29 20:58:48 +04:00

50 KiB

Sako's Emacs configuration

Usage

M-x org-bable-tangle

Lexical Binding

Should make startup faster, taken from doom-emacs

;; -*- lexical-binding: t; -*-

Default Enconding

  (setq utf-translate-cjk-mode nil) ; disable CJK coding/encoding (Chinese/Japanese/Korean characters)
  (set-language-environment 'utf-8)
  (set-keyboard-coding-system 'utf-8) ; For old Carbon emacs on OS X only
  (setq locale-coding-system 'utf-8)
  (set-default-coding-systems 'utf-8)
  (set-terminal-coding-system 'utf-8)
  (set-selection-coding-system
    (if (eq system-type 'windows-nt)
        'utf-16-le  ;; https://rufflewind.com/2014-07-20/pasting-unicode-in-emacs-on-windows
      'utf-8))
  (prefer-coding-system 'utf-8)

Put Backup Files Somewhere else

  (setq backup-directory-alist '(("." . "~/.emacs.d/backup"))
  backup-by-copying t
  version-control t     
  delete-old-versions t  
  kept-new-versions 20 
  kept-old-versions 5)

EmacsClient UI

        (setq frame-resize-pixelwise t)
        ;; ui settings apparently go below
        (setq default-frame-alist '((font . "JetBrainsMono NF")
                                    '(vertical-scroll-bars . nil)
                                    '(horizontal-scroll-bars . nil)))

UI

  ;; UI/UX
  (setq inhibit-splash-screen t)
  ;; remove useless GUI elements
  (scroll-bar-mode -1)
  (tool-bar-mode -1)
  (tooltip-mode -1)
  (set-fringe-mode 10)
  (menu-bar-mode -1)
  ;; Line Numbers
  (column-number-mode)
  ;; Bell
  (setq visible-bell nil)
  ;; prefer y/n
  (fset 'yes-or-no-p 'y-or-n-p)
  ;; delet eseciotn 
  (delete-selection-mode +1)
  ;; Stop Emacs from trying to use dialog boxes.
  (setq use-dialog-box nil)
  ;; idc emacs just work already 
  (setq warning-minimum-level :emergency)

Line Numbers

    (add-hook 'prog-mode 'display-line-numbers-mode)
    (add-hook 'yaml-mode 'display-line-numbers-mode)
    (add-hook 'conf-mode 'display-line-numbers-mode)
  (setq display-line-numbers-width-start t)
  (setq display-line-numbers-type 'relative)

Keymaps

  ;; switch buffers
  (global-set-key (kbd "C-M-j") 'counsel-switch-buffer)
  ;; instead of control-g
  (global-set-key (kbd "<escape>") 'keyboard-escape-quit)
  ;; repeat keybinds
  (repeat-mode)
  ;; electric pairs
  (electric-pair-mode)

Fonts

  (set-face-attribute `default nil :font "JetBrainsMono NF" :height 125)

Use-Package setup

  (message "setting up use-package")
  (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-installed-p 'use-package)
    (progn
      (package-refresh-contents)
      (package-install 'use-package)))

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

Straight.el

We only enable Straight.el for anything other than NixOS Cause emacs overlay lol

  ;; TODO Test this one darwin someday
  (when (eq system-type 'windows-nt)
    (defvar bootstrap-version)
    (let ((bootstrap-file
           (expand-file-name
            "straight/repos/straight.el/bootstrap.el"
            (or (bound-and-true-p straight-base-dir)
                user-emacs-directory)))
          (bootstrap-version 7))
      (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))
    (use-package straight
      :custom
      (straight-use-package-by-default t))
    )

SPEED SPEED SPEED SPEED

Avoid Garbage Collection at startup

  (use-package gcmh
    :init
    (setq gcmh-idle-delay 5)
    (setq gcmh-high-cons-threshold (* 16 1024 1024))
    :config
    (gcmh-mode))

Move Garbage collection further back

(setq gc-cons-threshold most-positive-fixnum)

Unset file-name-handler-alist temporarily

(defvar sakomacs--file-name-handler-alist file-name-handler-alist)
(setq file-name-handler-alist nil)

;; Alternatively, restore it even later:
(add-hook 'emacs-startup-hook
  (lambda ()
    (setq file-name-handler-alist sakomacs--file-name-handler-alist)))

Go back to normal GC after init

  (add-hook 'emacs-startup-hook
            (lambda ()
              ;;(setq gc-cons-threshold 16777216 ; 16mb
            ;; this could be really bad idk
            (setq gc-cons-threshold 100000000
                    gc-cons-percentage 0.1)))

Don't use GC when minibuffer is used

(defun doom-defer-garbage-collection-h ()
  "Disable garbage collection."
  (setq gc-cons-threshold most-positive-fixnum))

(defun doom-restore-garbage-collection-h ()
  "Restore garbage collection."
  (run-at-time
   1 nil (lambda () (setq gc-cons-threshold 16777216))))

(add-hook 'minibuffer-setup-hook #'doom-defer-garbage-collection-h)
(add-hook 'minibuffer-exit-hook #'doom-restore-garbage-collection-h)

Make Emacs read more

(setq read-process-output-max (* 1024 1024)) ;; 1mb

Native Compilation

  (setq package-native-compile t)
  (setq comp-deferred-compilation t)
  (setq native-comp-deferred-compilation-deny-list nil)
  (setq warning-suppress-log-types '((comp)))

Custom Modeline

  ;;ill continue making this later
  (setq mode-line-format nil)

  (kill-local-variable 'mode-line-format)

  (force-mode-line-update)

  (setq-default mode-line-format
    	      '((:eval (sakoline-render
    			;; left
    			(quote ("%e"
    				sakoline-evil-mode
    				" "
    				sakoline-buffer-name
    				" "
    				sakoline-buffer-state))
    			;; right
    			(quote (sakoline-major-mode
    				)
    			       )))))

  (defun sakoline-render (left right)
    "Return a string of `window-width' length.
    Containing LEFT, and RIGHT aligned respectively."
    (let ((available-width
           (- (window-total-width)
              (+ (length (format-mode-line left))
                 (length (format-mode-line right))))))
      (append left
              (list (format (format "%%%ds" available-width) ""))
              right)))

  (defvar-local sakoline-buffer-name
      '(:eval
        (propertize (buffer-name) 'face '(:foreground "#ffffff")))
    "Mode line variable that shows the buffer name.")

  (put 'sakoline-buffer-name 'risky-local-variable t)

  (defface sakoline-major-mode-color
    '((t :foreground "grey"))
    "Major Mode color for sakoline.")

  (defun sakoline--major-mode-name ()
    "Return Capitalized Major Mode"
    (capitalize (symbol-name major-mode)))

  (defvar-local sakoline-major-mode
      '(:eval
        (propertize (sakoline--major-mode-name) 'face 'sakoline-major-mode-color)))

  (put 'sakoline-major-mode 'risky-local-variable t)

  (defface sakoline-evil-visual-color
    '((t :background "#6600cc" :foreground "black"))
    "Evil Visual Color")

  (defface sakoline-evil-normal-color
    '((t :background "#99ff99" :foreground "black"))
    "Evil Visual Color")

  (defface sakoline-evil-insert-color
    '((t :background "#00cc66" :foreground "black"))
    "Evil Visual Color")

  (defface sakoline-evil-emacs-color
    '((t :background "#9900ff" :foreground "black"))
    "Evil Visual Color")

  (defface sakoline-evil-operator-color
    '((t :background "#ff3300" :foreground "black"))
    "Evil Visual Color")

  (defvar-local sakoline-evil-mode 
      '(:eval (cond
               ((eq evil-state 'visual) (propertize " VISUAL " 'face 'sakoline-evil-visual-color ))
               ((eq evil-state 'normal) (propertize " NORMAL " 'face 'sakoline-evil-normal-color ))
               ((eq evil-state 'insert) (propertize " INSERT " 'face 'sakoline-evil-insert-color ))
               ((eq evil-state 'emacs) (propertize " EMACS " 'face 'sakoline-evil-emacs-color ))
               ((eq evil-state 'operator) (propertize " OPERATOR " 'face 'sakoline-evil-operator-color))
      	     "Get current evil mode state")))

  (put 'sakoline-evil-mode 'risky-local-variable t)

  (defface sakoline-buffer-state-readonly
    '((t :foreground "red"))
    "Face for read-only buffer")
  (defface sakoline-buffer-state-modified
    '((t :foreground "orange"))
    "Face for modified buffer")

  (defvar-local sakoline-buffer-state
      '(:eval
        (cond
         (buffer-read-only
        	(propertize ">:("
        		    'face 'sakoline-buffer-state-readonly
        		    'help-echo "buffer is read only"))
         ((buffer-modified-p)
        	(propertize "!!!"
        		    'face 'sakoline-buffer-state-modified)))))

  (put 'sakoline-buffer-state 'risky-local-variable t)

Packages

Log state

(message "setting up packages")

Command Log Mode

      (use-package command-log-mode
        )

Command Autocompletion Packages

    ;; better search
    (use-package swiper
      )
    ;; better commands
    (use-package counsel
      :custom
      (counsel-linux-app-format-function #'counsel-linux-app-format-function-name-only)
      )
    ;; 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))

    ;; ivy in the middle
    (use-package ivy-posframe
      :init
      (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-center)))
      :config
      (ivy-posframe-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-rouge t)

  (doom-themes-org-config)

  (doom-themes-treemacs-config)

  ;; Enable flashing mode-line on errors
  (doom-themes-visual-bell-config))

All the Icons (to make doom-themes happy)

(use-package all-the-icons)

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

(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
  ;;   ;; :hook (after-init . doom-modeline-mode)
  ;;   :init (doom-modeline-mode 1)
  ;;   :custom (
  ;;            (doom-modeline-height 30)
  ;;            (doom-modeline-major-mode-icon nil)
  ;;            (doom-modeline-modal-modern-icon nil)
  ;;            ))

Hide Modeline

    (use-package hide-mode-line
      :hook (((treemacs-mode
               eshell-mode shell-mode
               term-mode vterm-mode
               embark-collect-mode
               lsp-ui-imenu-mode
               pdf-annot-list-mode
  	     dashboard-mode) . turn-on-hide-mode-line-mode)
             (dired-mode . turn-off-hide-mode-line-mode)))

Minor mode menu for modline

  (use-package minions
    :hook (doom-modeline-mode . minions-mode))

Better help menu

(use-package helpful
  :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
     ;; code
     "c" '(:ignore c :which-key "code")
     "cc" '(compile :which-key "compile")
     "cC" '(recompile :which-key "compile")
     "cX" '(lsp-treeemacs-errors-list :which-ley "list errors")
     ;; toggles
     "t" '(:ignore t :which-key "toggles")
     "tt" '(counsel-load-theme :which-key "choose theme")
     "ts" '(hydra-text-scale/body :which-key "scale text")
     ;; search
     "s" '(:ignore s :which-key "search")
     "sb" '(swiper :which-key "search buffer")
     ;; insert
     "i" '(:ignore i :which-key "insert")
     "ie" '(emoji-search :which-key "Emoji")
     ;; project
     "p" '(:ignore p :which-key "projects")
     "pp" '(projectile-switch-project :which-key "open project")
     "pk" '(projectile-kill-buffers :which-key "close project")
     "pa" '(projectile-add-known-project :which-key "add project")
     "pR" '(projectile-run-project :which-key "run project")
     "pt" '(magit-todos-list :which-key "list project todos")
     "ps" '(projectile-save-project-buffers :which-key "save project")
     "po" '(projectile-find-other-file :which-key "find other file")
     "pg" '(projectile-configure-project :which-key "configure project")
     "pc" '(projectile-compile-project :which-key "compile project")
     ;; open
     "o" '(:ignore o :which-key "open")
     "op" '(treemacs :which-key "treemacs")
     "oP" '(treemacs-find-file :which-key "treemacs find file")
     "oe" '(eshell :which-key "eshell")
     "or" '(elfeed :which-key "rss")
     ;; notes
     "n" '(:ignore o :which-key "notes")
     "na" '(org-agenda :which-key "agenda")
     "nf" '(org-roam-node-find :which-key "find node")
     "nc" '(org-capture :which-key "capture")
     "np" '(org-pomodoro :which-key "pomodoro")
     "ne" '(:ignore ne :which-key "export")
     "nep" '(org-latex-export-to-pdf :which-key "pdf")
     ;; quit
     "q" '(:ignore q :which-key "quit")
     "qq" '(delete-frame :which-key "close emacs")
     "qK" '(kill-emacs :which-key "quit emacs")
     ;; git
     "g" '(:ignore g :which-key "git")
     "gs" '(magit-status :which-key "status")
     "gc" '(:ignore gc :which-key "create")
     "gcr" '(magit-init :which-key "init repo")
     "gcR" '(magit-clone :which-key "clone repo")
     "gcc" '(magit-commit-create :which-key "commit")
     "gci" '(forge-create-issue :which-key "issue")
     "gcp" '(forge-create-pullreq :which-key "pull request")))

Dashboard

    (use-package dashboard
      :init
      (setq dashboard-display-icons-p t) ;; display icons on both GUI and terminal
      (setq dashboard-icon-type 'nerd-icons) ;; use `nerd-icons' package
      (setq initial-buffer-choice (lambda () (get-buffer-create "*dashboard*")))
      (setq dashboard-center-content t)
      (setq dashboard-projects-backend 'projectile)
      (setq dashboard-startup-banner "~/.emacs.d/dashboard.png")
      (setq dashboard-footer-messages '("i think i have emacs pinky"
                                        "why are we still using lisp again?"
                                        "why is this running on 1/16 threads?!?!?"
                                        "still waiting for multithreaded :)"
                                        "any day now"
                                        "make sure to pray today"
                                        "im literally kanye west"
                                        "please dont break please dont break"
                                        "GNU/Linux/Emacs/???"
                                        "what is a GNU/Linux ?????????????"
                                        "done!"
                                        "remove / for faster emacs on linux"
                                        ""))
      (setq dashboard-items '((recents  . 3)
                              (projects . 3)
                              (agenda . 5)))

      (setq dashboard-image-banner-max-height 200)
      (setq dashboard-image-banner-max-width 300)

      (setq dashboard-page-separator "\n\n")
      (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
      (dashboard-setup-startup-hook))

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)
    :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))

  ;; commenting
  (use-package evil-commentary
  :after evil
  :diminish
  :config (evil-commentary-mode +1))

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))

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

  (use-package org
    :hook (org-mode . org-indent-mode)
    :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 agenda files
    (setq org-agenda-files
          '("~/org/tasks.org"
            "~/org/school.org"
            "~/org/daily.org"
            "~/org/irl.org"
            "~/org/work.org"))

    ;; Following
    (setq org-return-follows-link  t)

    ;; hide stars except for leader star
    (setq org-hide-leading-stars t)
    (setq org-hide-emphasis-markers nil)

    ;; 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"))

    (setq org-todo-keywords
          '((sequence "TODO(t)" "NEXT(n)" "|" "DONE(d!)")
            (sequence "BACKLOG(b)" "PLAN(p)" "READY(r)" "ACTIVE(a)" "REVIEW(v)" "WAIT(w@/!)" "HOLD(h)" "|" "COMPLETED(c)" "CANCELED(k@)")))

    (setq org-refile-targets
          '(("archive.org" :maxlevel . 1)
            ("tasks.org" :maxlevel . 1)))

    ;; Save Org buffers after refiling!
    (advice-add 'org-refile :after 'org-save-all-org-buffers)

    (setq org-startup-with-inline-images t)

    (setq org-tag-alist
          '((:startgroup)
                                          ; Put mutually exclusive tags here
            (:endgroup)
            ("@errand" . ?E)
            ("@home" . ?H)
            ("@work" . ?W)
            ("agenda" . ?a)
            ("planning" . ?p)
            ("publish" . ?P)
            ("batch" . ?b)
            ("note" . ?n)
            ("idea" . ?i)))

    ;; Configure custom agenda views
    (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 "WAIT"
                    ((org-agenda-overriding-header "Waiting on External")
                     (org-agenda-files org-agenda-files)))
              (todo "REVIEW"
                    ((org-agenda-overriding-header "In Review")
                     (org-agenda-files org-agenda-files)))
              (todo "PLAN"
                    ((org-agenda-overriding-header "In Planning")
                     (org-agenda-todo-list-sublevels nil)
                     (org-agenda-files org-agenda-files)))
              (todo "BACKLOG"
                    ((org-agenda-overriding-header "Project Backlog")
                     (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)))))

            ("1" "Events" agenda "display deadlines and exclude scheduled" (
                                                                            (org-agenda-span 'month)
                                                                            (org-agenda-time-grid nil)
                                                                            (org-agenda-show-all-dates nil)
                                                                            (org-agenda-entry-types '(:deadline)) ;; this entry excludes :scheduled
                                                                            (org-deadline-warning-days 0) ))))

    ;; TODO Setup template for school

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

            ("j" "Journal Entries")
            ("jj" "Journal" entry
             (file+olp+datetree "~/org/journal.org")
             "\n* %<%I:%M %p> - Journal :journal:\n\n%?\n\n"
             ;; ,(dw/read-file-as-string "~/Notes/Templates/Daily.org")
             :clock-in :clock-resume
             :empty-lines 1))))

Org Mode Beautifers

Olivetti

    (use-package olivetti
      :hook ((org-mode . (lambda () (interactive) (olivetti-mode) (olivetti-set-width 100)))
             (org-agenda-mode . (lambda () (interactive) (olivetti-mode) (olivetti-set-width 100)))))

Org-Modern

Org-super-agenda

        (use-package org-super-agenda
          :hook ((org-agenda-mode . org-super-agenda-mode))
          :config
          (setq org-super-agenda-groups
                '((:auto-group t))))

Org Pomodoro

  (use-package org-pomodoro)

Org-Roam

  (use-package org-roam
  :custom
  (org-roam-directory "~/org/notes")
  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n i" . org-roam-node-insert))
  :config
  (org-roam-setup))

Org-Wild-Notifier

    (use-package org-wild-notifier
      :config
      (org-wild-notifier-mode))

Alert.el

  ;; quick and dirty fix for windows alert.el
  (when (eq system-type 'windows-nt)
    (use-package alert
      :commands (alert)
      :config (setq alert-default-style 'toast))
    
    (use-package alert-toast
      :after alert))

Treemacs

  (use-package treemacs
    :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-tag-follow-mode t)
      (treemacs-project-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))

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

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

  (use-package treemacs-nerd-icons
    :config
    (treemacs-load-theme "nerd-icons"))

Dev Packages

Magit (git in emacs)

        (use-package magit
          :custom
          (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)
          )
        (use-package magit-todos
          :after magit
  	:config (magit-todos-mode 1))

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"))

Direnv

  (when (eq system-type 'gnu/linux)
        (use-package direnv
          :config
          (direnv-mode))
  )

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)
      (setq lsp-keep-workspace-alive nil))
Lsp-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
HTML/CSS
  (use-package web-mode
       :hook (web-mode . lsp)
       :mode ("\\.html\\'"
               "\\.css\\'"))
Javascript
    (use-package js2-mode
    :mode ("\\.js\\'"
  	 "\\.jsx\\'")
    :hook (js2-mode . lsp)
    :config
    (setq web-mode-markup-indent-offset 2) ; HTML
    (setq web-mode-css-indent-offset 2)    ; CSS
    (setq web-mode-code-indent-offset 2)   ; JS/JSX/TS/TSX
    (setq web-mode-content-types-alist '(("jsx" . "\\.js[x]?\\'"))))
Typescript
  (use-package typescript-mode
    :mode ("\\.ts\\'"
  	 "\\.tsx\\'")
    :hook (typescript-mode . lsp))
Astro
    (define-derived-mode astro-mode web-mode "astro")
    (setq auto-mode-alist
    (append '((".*\\.astro\\'" . astro-mode))
    auto-mode-alist))

    (add-to-list 'lsp-language-id-configuration
                 '(astro-mode . "astro"))

  (defun astro-get-tsserver ()
    ""
    (f-join (lsp-workspace-root) "node_modules/typescript/lib/tsserverlibrary.js"))

  (lsp-register-client
   (make-lsp-client :new-connection (lsp-stdio-connection '("astro-ls" "--stdio"))
                    :activation-fn (lsp-activate-on "astro")
                    :initialization-options (lambda ()
                                              `(:typescript (:serverPath ,(astro-get-tsserver))))
                    :server-id 'astro-ls))
C/C++
(add-hook 'c-mode-hook 'lsp)
(add-hook 'c++-mode-hook 'lsp)
CMake
  (use-package cmake-mode
    :mode "CMakeLists.txt"
    :hook (cmake-mode . lsp))
Lua
  (use-package lua-mode
    :mode "\\.lua\\'"
    :hook (lua-mode . lsp))
Python
  (use-package python-mode
    :mode "\\.py\\'"
    :hook (python-mode . lsp))

  (use-package elpy
  :after python-mode

  :custom
  (elpy-rpc-python-command "python3")

  :config
  (elpy-enable))

  (use-package lsp-pyright
    :hook (python-mode . (lambda ()
                           (require 'lsp-pyright)
                           (lsp))))  ; or lsp-deferred
Haskell
  (use-package haskell-mode
    :mode "\\.hs\\'"
    :hook (python-mode . lsp))
Yaml editing
      (use-package yaml-mode
        :mode ("\\.yaml\\'"
               "\\.yml\\'"))
Nix
    (use-package nix-mode
      :hook ((nix-mode . lsp) 
               (nix-mode . format-all-mode)
               (nix-mode . (lambda () (setq-local format-all-formatters '(("Nix" alejandra))))))
      :mode "\\.nix\\'")
Dart
  (use-package lsp-dart)
  (use-package dart-mode
   :hook (dart-mode . lsp)
  :mode "\\.dart\\'" )
Markdown
  (use-package markdown-mode
    :hook (markdown-mode . visual-line-mode))

  (use-package markdown-preview-mode)
GDScript
  (use-package gdscript-mode
    :hook (gdscript-mode . lsp)
    :mode "\\.gd\\'")

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)
      (company-selection-wrap-around t)
      (company-tooltip-align-annotations t))

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

Syntax Checking (Flycheck)

(use-package flycheck :config (global-flycheck-mode +1))

Formatting

  (use-package format-all
    )

Better Compile Messages

  ;; (use-package fancy-compilation
    ;; :commands (fancy-compilation-mode))

  ;; (with-eval-after-load 'compile
    ;; (fancy-compilation-mode))

Snippets

  (use-package yasnippet
    :diminish yas-minor-mode
    :hook (after-init . yas-global-mode))

  (use-package yasnippet-snippets)

  (use-package yasnippet-capf
  :init (add-to-list 'completion-at-point-functions #'yasnippet-capf))

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
      ;; :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))

    (global-set-key (kbd "C-x C-j") 'dired-jump)
    (setq dired-listing-switches "-agho --group-directories-first")
    (evil-collection-define-key 'normal 'dired-mode-map
       "h" 'dired-single-up-directory
       "l" 'dired-single-buffer)

    ;; (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)))

RSS Reader

  (when (eq system-type 'gnu/linux)
    (use-package elfeed
    :config
    (setq elfeed-use-curl t)
    (setq browse-url-browser-function 'eww-browse-url)
    (setq elfeed-search-title-max-width 100)
    )

  (use-package elfeed-protocol
    :after elfeed
    :config
    (elfeed-set-timeout 36000)
    (setq elfeed-curl-extra-arguments '("--insecure")) ;necessary for https without a trust certificate

    ;; workaround for smth
    (setq elfeed-protocol-fever-update-unread-only t)

    ;; setup feeds
    (setq elfeed-protocol-feeds '(("fever+https://sako@rss.sako.box"
				   :api-url "https://rss.sako.box/fever/"
				   :use-authinfo t)))

    ;; enable elfeed-protocol
    (setq elfeed-protocol-enabled-protocols '(fever))
    (elfeed-protocol-enable)
    )

  (let* ((proto-id "fever+https://sako@rss.sako.box")
	 (last-id (elfeed-protocol-fever-get-update-mark proto-id 'update)))
    (elfeed-protocol-fever-set-update-mark  proto-id 'update (- last-id 1000)))

  (run-at-time 300 300
	     (lambda () (when (= elfeed-curl-queue-active 0)
			  (elfeed-update))))

  ;; (add-hook 'emacs-startup-hook (elfeed-update))
  )

Telegram

only god knows why im doing this

  ;; codeberg thingy
  ;; breaks on nixos
  ;; (use-package visual-fill-column)
  ;; (use-package telega)

pdf-tools

Emacs can be everything? Why not turn it into a pdf reader

    (use-package pdf-tools
      :mode ("\\.pdf\\'" . pdf-view-mode)
      :config
      (setq-default pdf-view-display-size 'fit-page)
      :init
      (pdf-tools-install))

Matrix Client

okay this one is a bit more understandable

  (use-package ement)

Discord RPC

  (use-package elcord
    :init
    (setq elcord-display-buffer-details nil)
    (setq elcord-use-major-mode-as-main-icon t)
    )

Email

This ONLY works on Linux and Darwin Not windows

  (when (eq system-type 'gnu/linux)
    (use-package mu4e)
  )

Docker

Aint no way bro

(use-package docker
  :bind ("C-c d" . docker))

EXWM

RELEASE ME

  (when (eq system-type 'gnu/linux)
    (display-battery-mode)
    (use-package exwm
      :config

      (defun sakomacs/exwm-init-hook ()
        ;; background
        (call-process-shell-command "feh --bg-fill ~/background.png" nil 0)     
        (set-frame-parameter (selected-frame)'alpha '(90 . 90))
        (call-process-shell-command "~/.config/polybar/startpolybar" nil 0)     
        ;; (call-process-shell-command "~/.config/picom/startpicom" nil 0)     
        ;; startup
        (call-process-shell-command "nm-applet" nil 0)     
        (call-process-shell-command "blueman-applet" nil 0)     
        (call-process-shell-command "nextcloud" nil 0)     
        (call-process-shell-command "bitwarden" nil 0)     
        (call-process-shell-command "flameshot" nil 0)  
        )

      ;; background
      ;; todo turn this info a function
      (add-hook 'exwm-init-hook 'sakomacs/exwm-init-hook)
      ;; startup
      ;; workspaces
      (setq exwm-workspace-number 5)


      (require 'exwm-systemtray)
      (exwm-systemtray-enable)

      ;; polybar
      (defvar sakomacs/polybar-process nil
        "Holds the process of the running Polybar instance, if any")

      (server-start)

      (defun sakomacs/kill-panel ()
        (interactive)
        (when sakomacs/polybar-process
          (ignore-errors
            (kill-process sakomacs/polybar-process)))
        (setq sakomacs/polybar-process nil))

      (defun sakomacs/start-panel ()
        (interactive)
        (sakomacs/kill-panel)
        (setq sakomacs/polybar-process (start-process-shell-command "polybar" nil "polybar panel")))

      (defun sakomacs/send-polybar-hook (module-name hook-index)
        (start-process-shell-command "polybar-msg" nil (format "polybar-msg hook %s %s" module-name hook-index)))

      (defun sakomacs/send-polybar-exwm-workspace ()
        (sakomacs/send-polybar-hook "exwm-workspace" 1))

      ;; Update panel indicator when workspace changes
      (add-hook 'exwm-workspace-switch-hook #'sakomacs/send-polybar-exwm-workspace)

      ;; always use these keys in emacs
      (setq exwm-input-prefix-keys
            '(?\C-x
              ?\C-u
              ?\C-h
              ?\M-x
              ?\M-`
              ?\M-&
              ?\M-:
              ?\C-\M-j  ;; Buffer list
              ?\C-\ ))  ;; Ctrl+Space

      ;; Ctrl+Q will enable the next key to be sent directly
      (define-key exwm-mode-map [?\C-q] 'exwm-input-send-next-key)
      ;; app launcher and fullscreen
      (exwm-input-set-key (kbd "s-SPC") 'counsel-linux-app)
      (exwm-input-set-key (kbd "s-f") 'exwm-layout-toggle-fullscreen)
      ;; Set up global key bindings.  These always work, no matter the input state!
      ;; Keep in mind that changing this list after EXWM initializes has no effect.
      (setq exwm-input-global-keys
            `(
              ;; Reset to line-mode (C-c C-k switches to char-mode via exwm-input-release-keyboard)
              ([?\s-r] . exwm-reset)

              ;; Move between windows
              ([s-left] . windmove-left)
              ([s-right] . windmove-right)
              ([s-up] . windmove-up)
              ([s-down] . windmove-down)

              ;; Launch applications via shell command
              ([?\s-&] . (lambda (command)
                           (interactive (list (read-shell-command "$ ")))
                           (start-process-shell-command command nil command)))

              ;; Switch workspace
              ([?\s-w] . exwm-workspace-switch)

              ;; 's-N': Switch to certain workspace with Super (Win) plus a number key (0 - 9)
              ,@(mapcar (lambda (i)
                          `(,(kbd (format "s-%d" i)) .
                            (lambda ()
                              (interactive)
                              (exwm-workspace-switch-create ,i))))
                        (number-sequence 0 9))))
      )

    (use-package desktop-environment
      :after exwm
      :config (desktop-environment-mode)
      :custom
      (desktop-environment-brightness-small-increment "2%+")
      (desktop-environment-brightness-small-decrement "2%-")
      (desktop-environment-brightness-normal-increment "5%+")
      (desktop-environment-brightness-normal-decrement "5%-"))

    )

ERC

  (setq erc-nick "sahko"
        erc-user-full-name "sako"
        ;; erc-autojoin-channels-alist '(("irc-libera.chat" "#systemcrafters" "#emacs"))
        erc-kill-buffer-on-part 8)

Org Mode Configuration Setup

Babel Languages

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

Terminals

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)

    
    (add-hook 'eshell-first-time-mode 'sakomacs/configure-eshell)

    (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))

VTerm

  (use-package vterm
    :commands vterm
    :config
    (setq vterm-max-scrollback 10000))

End

notify that it has loaded

  (require 'notifications)

  (if (eq system-type 'windows-nt)
      (w32-notification-notify
       :title "Emacs Daemon"
       :body "The Emacs Daemon has started"))

  (if (eq system-type 'gnu/linux)
      (notifications-notify
       :title "Emacs Daemon"
       :body "The Emacs Daemon has started"))


  (message "Emacs is ready")