nixos/config/emacs/emacs.org
2024-09-24 22:41:16 +04:00

48 KiB

EMACS 2

Welcome!

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

Package Setup

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

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

  ;; TODO add better detection to this
  (when (eq system-type 'windows-nt)
    (message "setting up straight.el")
    (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))
      (setq straight-use-package-by-default t))

Make Emacs faster

(message "Speeding up")

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

Set garbage collection to be further back

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

Unset file-name-handler-alist

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

Reset gc once init has finished

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

Read more

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

Keybinds

Ill use this later eventually

(message "Got to keybinds")

Make emacs more human

(global-set-key (kbd "<escape>") 'keyboard-escape-quit)

Core

  (message "Reached core.")

Encoding

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

Cleanup .emacs.d

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

(use-package no-littering
  :config
  (setq custom-file (if (boundp 'server-socket-dir)
                        (expand-file-name "custom.el" server-socket-dir)
                      (no-littering-expand-etc-file-name "custom.el")))
  (when (file-exists-p custom-file)
    (load custom-file t))

  ;; Don't litter project folders with backup files
  (let ((backup-dir (no-littering-expand-var-file-name "backup/")))
    (make-directory backup-dir t)
    (setq backup-directory-alist
          `(("\\`/tmp/" . nil)
            ("\\`/dev/shm/" . nil)
            ("." . ,backup-dir))))

  (setq auto-save-default nil)

  ;; Tidy up auto-save files
  (setq auto-save-default nil)
  (let ((auto-save-dir (no-littering-expand-var-file-name "auto-save/")))
    (make-directory auto-save-dir t)
    (setq auto-save-file-name-transforms
          `(("\\`/[^/]*:\\([^/]*/\\)*\\([^/]*\\)\\'"
             ,(concat temporary-file-directory "\\2") t)
            ("\\`\\(/tmp\\|/dev/shm\\)\\([^/]*/\\)*\\(.*\\)\\'" "\\3")
            ("." ,auto-save-dir t)))))

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

Native Compilation

(setq native-comp-async-report-warnings-errors nil)

(add-to-list 'native-comp-eln-load-path (expand-file-name "eln-cache/" user-emacs-directory))

Emacs settings

(setq inhibit-startup-message t)

;; make emacs look a little more cleaner
(scroll-bar-mode -1)
(tool-bar-mode -1)
(tooltip-mode -1)
(set-fringe-mode 10)
(menu-bar-mode -1)

;; this is really annoying i hate it
(setq visible-bell nil)

;; -- core keybinds and packages --
(repeat-mode 1)

(column-number-mode)

(dolist (mode '(text-mode-hook
                prog-mode-hook
                conf-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 1))))

Core Keybinds

(repeat-mode 1)

(column-number-mode)

(dolist (mode '(text-mode-hook
                prog-mode-hook
                conf-mode-hook))
  (add-hook mode (lambda () (display-line-numbers-mode 1))))

Appearance

  ;; (use-package doom-themes
  ;;   :config
  ;;   (load-theme 'doom-sourcerer t))

  ;; (use-package grandshell-theme
  ;;   :config
  ;;   (load-theme 'grandshell t))

  (use-package ef-themes
    :config
    (load-theme 'ef-dark t))

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

  ;; GO AWAY
  (defun my/disable-scroll-bars (frame)
    (modify-frame-parameters frame
                             '((vertical-scroll-bars . nil)
                               (horizontal-scroll-bars . nil))))
  (add-hook 'after-make-frame-functions 'my/disable-scroll-bars)


  ;; y/n is better than yes/no
  (fset 'yes-or-no-p 'y-or-n-p)

  ;; font
  (set-face-attribute 'default nil
  		    :font "JetBrainsMono NF"
  		    :weight 'light
  		    :height 125)

Emacs Client

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

Modeline

  ;; (use-package nerd-icons
  ;;   :custom
  ;;   (nerd-icons-font-family "JetBrainsMono NF"))
  ;; (use-package doom-modeline
  ;;   :custom
  ;;   (doom-modeline-height 35)
  ;;   (doom-modeline-modal-modern-icon nil)
  ;;   :init (doom-modeline-mode 1))

Editor Configuration

(use-package super-save
  :config
  (super-save-mode +1)
  (setq super-save-auto-save-when-idle t))

;; revert dired and other buffers
(setq global-auto-revert-non-file-buffers t)

;; revert buffers when file has been changed
(global-auto-revert-mode 1)

;; popups and stuff
(use-package popper
  :bind (("C-M-'" . popper-toggle)
         ("M-'" . popper-cycle)
         ("C-M-\"" . popper-toggle-type))
  :custom
  (popper-window-height 12)
  (popper-reference-buffers '(eshell-mode
                              vterm-mode
                              geiser-repl-mode
                              help-mode
                              grep-mode
                              helpful-mode
                              compilation-mode))
  :config
  (popper-mode 1))

Helpful

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

Which Key

;; incase i get lost
(use-package which-key
  :init (which-key-mode)
  :diminish which-key-mode
  :config
  (setq which-key-idle-delay 1))

Alerts

(when (eq system-type 'windows-nt)
  (use-package alert
    :commands (alert)
    :config (setq alert-default-style 'toast))
  
  (use-package alert-toast
    :after alert))

Daemon

(if (eq system-type 'windows-nt)
    (setq server-socket-dir "~/.emacs.d/server"))
(server-start)

Keys

(message "got to keys setup")

General

  (use-package general
    :config
    (general-create-definer sk/leader-keys
      :keymaps '(normal insert visual emacs)
      :prefix "SPC"
      :global-prefix "C-SPC")

    (sk/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" '(project-switch-project :which-key "open project")
     "pk" '(project-kill-buffers :which-key "close project")
     "pt" '(magit-todos-list :which-key "list project todos")
     "po" '(project-find-file :which-key "find file")
     "pc" '(project-compile :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")
     "ov" '(vterm :which-key "vterm")
     "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")
     ;; mail
     "m" '(mu4e :which-key "mu4e")))

Evil

  (use-package evil
    :init
    ;; Pre-load configuration
    (setq evil-want-integration t)
    (setq evil-want-keybinding nil)
    (setq evil-want-C-u-scroll t)
    (setq evil-want-C-i-jump nil)
    (setq evil-respect-visual-line-mode t)
    (setq evil-undo-system 'undo-tree)
    :config
    (evil-mode 1)

     ;; use emacs state for these mods
    (dolist (mode '(custom-mode
                    eshell-mode
                    git-rebase-mode
                    erc-mode
                    circe-server-mode
                    circe-chat-mode
                    circe-query-mode
                    term-mode))
      (add-to-list 'evil-emacs-state-modes mode))

     (defun sk/dont-arrow-me-bro ()
        (interactive)
        (message "STOP USING THE ARROW KEYS!!!!!!!!!!!!!!!!!!!!!!!"))

      ;; Disable arrow keys in normal and visual modes
      (define-key evil-normal-state-map (kbd "<left>") 'sk/dont-arrow-me-bro)
      (define-key evil-normal-state-map (kbd "<right>") 'sk/dont-arrow-me-bro)
      (define-key evil-normal-state-map (kbd "<down>") 'sk/dont-arrow-me-bro)
      (define-key evil-normal-state-map (kbd "<up>") 'sk/dont-arrow-me-bro)
      (evil-global-set-key 'motion (kbd "<left>") 'sk/dont-arrow-me-bro)
      (evil-global-set-key 'motion (kbd "<right>") 'sk/dont-arrow-me-bro)
      (evil-global-set-key 'motion (kbd "<down>") 'sk/dont-arrow-me-bro)
      (evil-global-set-key 'motion (kbd "<up>") 'sk/dont-arrow-me-bro)

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

  (use-package evil-collection
    :after evil
    :custom
    (evil-collection-outline-bind-tab-p nil)
    :config
    ;; Is this a bug in evil-collection?
    (setq evil-collection-company-use-tng nil)
    (delete 'lispy evil-collection-mode-list)
    (delete 'org-present evil-collection-mode-list)
    ;; (delete 'mu4e evil-collection-mode-list)
    ;; (delete 'mu4e-conversation evil-collection-mode-list)
    (evil-collection-init))

  (use-package evil-org
    :after (evil org)
    :hook ((org-mode . evil-org-mode)
           (org-agenda-mode . evil-org-mode))
    :config
    (require 'evil-org-agenda)
    (evil-org-set-key-theme '(navigation todo insert textobjects additional))
    (evil-org-agenda-set-keys))

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

  (with-eval-after-load 'org
    (evil-define-key '(normal insert visual) org-mode-map (kbd "C-j") 'org-next-visible-heading)
    (evil-define-key '(normal insert visual) org-mode-map (kbd "C-k") 'org-previous-visible-heading)
    (evil-define-key '(normal insert visual) org-mode-map (kbd "M-j") 'org-metadown)
    (evil-define-key '(normal insert visual) org-mode-map (kbd "M-k") 'org-metaup))

Interface

(message "Got to interface")

Hydra

(use-package hydra)

Vertico

  (use-package vertico
    :bind (:map vertico-map
  	      ("C-j" . vertico-next)
  	      ("C-k" . vertico-previous)
  	      ("C-f" . vertico-exit-input)
  	      :map minibuffer-local-map
  	      ("M-h" . vertico-directory-up))
    :custom
    (vertico-cycle t)

    :hook (rfn-eshadow-update-overlay . vertico-directory-tidy)
    :init
    (require 'vertico-directory)
    (vertico-mode))

Marginalia

(use-package marginalia
  :after vertico
  :ensure t
  :custom
  (marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
  :init
  (marginalia-mode))

Consult

(use-package consult
  :bind (("C-s" . consult-line)
         ("C-M-l" . consult-imenu)
         ("C-M-j" . consult-buffer)
         ("C-x C-b" . consult-buffer)
         :map minibuffer-local-map
         ("C-r" . consult-history)))


(use-package consult-dir
  :bind (("C-x C-d" . consult-dir)
         :map vertico-map
         ("C-x C-d" . consult-dir)
         ("C-x C-j" . consult-dir-jump-file))

  :custom
  (consult-dir-project-list-function nil))

Orderless

(use-package orderless
  :config
  (orderless-define-completion-style orderless+initialism
    (orderless-matching-styles '(orderless-initialism
                                 orderless-literal
                                 orderless-regexp)))

  (setq completion-styles '(orderless)
        completion-category-defaults nil
        orderless-matching-styles '(orderless-literal orderless-regexp)
        completion-category-overrides
        '((file (styles partial-completion)))))

Embark

  (use-package embark
    :after vertico
    :bind (("C-." . embark-act)
           ("M-." . embark-dwim)
           :map minibuffer-local-map
           ("C-d" . embark-act)
           :map embark-region-map
           ("D" . denote-region))

    :config
    ;; Remove the mixed indicator to prevent the popup from being displayed
    ;; automatically
    (delete #'embark-mixed-indicator embark-indicators)
    (add-to-list 'embark-indicators 'embark-minimal-indicator)

    ;; Use Embark to show command prefix help
    (setq prefix-help-command #'embark-prefix-help-command))

  (use-package embark-consult
    :after embark)

Corfu

    (use-package corfu
    :bind (:map corfu-map
                ("C-j" . corfu-next)
                ("C-k" . corfu-previous)
                ("TAB" . corfu-insert)
                ([tab] . corfu-insert)
                ("C-f" . corfu-insert))
    :custom
    (corfu-cycle t)
    (corfu-auto t)
    (corfu-preview-current nil)
    (corfu-quit-at-boundary t)
    (corfu-quit-no-match t)
    (corfu-min-chars 3)
    (corfu-auto-delay 0)
    (corfu-auto-prefix 0)
    :init
    (global-corfu-mode) 

    (defun corfu-enable-in-minibuffer ()
      "Enable Corfu in the minibuffer if `completion-at-point' is bound."
      (when (where-is-internal #'completion-at-point (list (current-local-map)))
        (setq-local corfu-auto nil) ;; Enable/disable auto completion
        (setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
                    corfu-popupinfo-delay nil)
        (corfu-mode 1)))

    (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer))

Dashboard

    (use-package dashboard
      :init
      (setq initial-buffer-choice 'dashboard-open) 
      ;; Set the title
      (setq dashboard-banner-logo-title "GET ME OUT GET ME OUT GET ME OUT")
      (setq dashboard-image-banner-max-height 200)
      ;; Set the banner
      (setq dashboard-startup-banner '"~/.emacs.d/icon.png")
      (setq dashboard-center-content t)
      (setq dashboard-vertically-center-content t)
      (setq dashboard-show-shortcuts nil)

      ;; nerd icons
      (setq dashboard-display-icons-p t)     ; display icons on both GUI and terminal
      (setq dashboard-icon-type 'nerd-icons) ; use `nerd-icons' package

      ;; list stuff
      (setq dashboard-items '((recents   . 3)
                          (projects  . 3)
                          (agenda    . 3)))
      :config
      (dashboard-setup-startup-hook))

Auth

(message "Reached auth")

Pinentry

  (unless (eq system-type 'windows-nt)
    (use-package pinentry
      :config
      (setq epa-pinentry-mode 'loopback))
    (pinentry-start))

Password-Store

  (use-package password-store
    :bind (("C-c p p" . password-store-copy)
           ("C-c p i" . password-store-insert)
           ("C-c p g" . password-store-generate))
    :config
    (setq password-store-password-length 12))

  (use-package auth-source-pass
    :config
    (auth-source-pass-enable))

OAuth2

this should be useful later

(use-package oauth2
  :ensure t)

Shell

(message "Reached shell")

EShell

(defun sk/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))

Dev

(message "Reached dev")

{} and () matching

(use-package smartparens 
  :hook (prog-mode . smartparens-mode)
  :config
  (sp-use-smartparens-bindings))

(use-package rainbow-delimiters
  :hook (prog-mode . rainbow-delimiters-mode))

Compilation

(setq compilation-scroll-output t)

(setq compilation-environment '("TERM=xterm-256color"))

(defun sk/advice-compilation-filter (f proc string)
  (funcall f proc (xterm-color-filter string)))

(advice-add 'compilation-filter :around #'sk/advice-compilation-filter)

(defun sk/auto-recompile-buffer ()
  (interactive)
  (if (member #'recompile after-save-hook)
      (remove-hook 'after-save-hook #'recompile t)
    (add-hook 'after-save-hook #'recompile nil t)))

Project.el

(setq project-switch-commands '((project-find-file "Find file" "f") (project-find-dir "Find dir" "d") (project-dired "Dired" "D") (consult-ripgrep "ripgrep" "g") (magit-project-status "Magit" "m")))

Eglot (LSP)

  (use-package eglot
    :bind (:map eglot-mode-map
                ("C-c C-a" . eglot-code-actions)
                ("C-c C-r" . eglot-rename))
    :config
    (setq eglot-autoshutdown t
          eglot-confirm-server-initiated-edits nil))

  ;; this'll make it so i don't have to use vscode every now and then
  ;; (when (eq system-type 'windows-nt)
  ;;   (use-package eglot-booster
  ;;     :straight (eglot-booster :type git :host github :repo "jdtsmith/eglot-booster")
  ;;     :after eglot
  ;;     :config (eglot-booster-mode))
  ;;   )

  (when (eq system-type 'gnu/linux)
      (use-package eglot-booster
        :ensure nil
        :config (eglot-booster-mode)))

Magit

(use-package magit
  :bind ("C-M-;" . magit-status-here)
  :custom
  (magit-show-long-lines-warning nil)
  (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))

(use-package magit-todos
  :after magit
  :config
  (magit-todos-mode))

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

(defhydra sk/smerge-panel ()
  "smerge"
  ("k" (smerge-prev) "prev change" )
  ("j" (smerge-next) "next change")
  ("u" (smerge-keep-upper) "keep upper")
  ("l" (smerge-keep-lower) "keep lower")
  ("q" nil "quit" :exit t))

Formatting

(use-package apheleia
  :hook (prog-mode . apheleia-mode))

Flycheck (Syntax Checking)

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

Docker

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

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-magit
  :after (treemacs magit))

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

Direnv

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

Color Picker

  (use-package zenity-color-picker)

Languages

(message "Reached languages")

HTML/CSS

(use-package web-mode
     :hook (web-mode . eglot-ensure)
     :mode ("\\.html\\'"
             "\\.css\\'"))

Javascript

(use-package js2-mode
:mode ("\\.js\\'"
  	 "\\.jsx\\'")
:hook (js2-mode . eglot-ensure)
: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

  (add-to-list 'auto-mode-alist '(".*\\.ts" . typescript-ts-mode))
  (add-to-list 'auto-mode-alist '(".*\\.tsx" . tsx-ts-mode))
  
  (add-hook 'typescript-ts-mode-hook 'eglot-ensure) 
  (add-hook 'tsx-ts-mode-hook 'eglot-ensure) 

  (setq treesit-language-source-alist
  	'((typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src" nil nil)
          (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src" nil nil)))

Astro

  (define-derived-mode astro-mode web-mode "astro")
  (setq auto-mode-alist
  (append '((".*\\.astro\\'" . astro-mode))
  auto-mode-alist))
  
  (add-to-list 'eglot-server-programs
               '(astro-mode . ("astro-ls" "--stdio"
                               :initializationOptions
                               (:typescript (:tsdk "./node_modules/typescript/lib")))))

C/C++

(add-hook 'c-mode-hook 'eglot-ensure)
(add-hook 'c++-mode-hook 'eglot-ensure)

C#

  (add-hook 'csharp-mode-hook 'eglot-ensure)
  (when (eq system-type 'gnu/linux)
  (add-to-list 'eglot-server-programs
             `(csharp-mode . ("OmniSharp" "-lsp"))))

  (use-package csproj-mode
    :mode ("\\.csproj\\'"))

  (use-package dotnet
    :hook (dotnet-mode . csharp-mode))

CMake

(use-package cmake-mode
  :mode "CMakeLists.txt"
  :hook (cmake-mode . eglot-ensure))

Lua

(use-package lua-mode
  :mode "\\.lua\\'"
  :hook (lua-mode . eglot-ensure))

Python

(use-package python-mode
  :mode "\\.py\\'"
  :hook (python-mode . eglot-ensure))

(use-package elpy
:after python-mode

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

:config
(elpy-enable))

(use-package poetry
  :config
  (poetry-tracking-mode 1))

Yaml

  (use-package yaml-mode
    :hook (yaml-mode. eglot-ensure) 
    :mode ("\\.yml\\'"
  	 "\\.yaml\\'"))

Nix

(use-package nix-mode
  :hook (nix-mode . eglot-ensure) 
  :mode "\\.nix\\'")

Dart

(use-package dart-mode
 :hook (dart-mode . eglot-ensure)
: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 . eglot-ensure)
  :mode "\\.gd\\'")

Rust

  (use-package rustic
    :ensure t
    :config
    (setq rustic-format-on-save nil)
    (setq rustic-lsp-client 'eglot)
    :custom
    (rustic-cargo-use-last-stored-arguments t))

Haskell

  (use-package haskell-mode
    :hook (haskell-mode . eglot-ensure)
    :mode "\\.hs'")

Go

  (use-package go-mode
    :mode "\\.go\\'"
    :hook (go-mode . eglot-ensure))

Social

(message "Reached social")

Elcord (Discord rich precense)

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

Telegram

does NOT WORK ON WINDOWS

(unless (eq system-type 'windows-nt)
  (use-package telega))

IRC

Will configure later

(use-package rcirc)

RSS

Will configure later, (use elfeed protocol ok ty)

    (use-package elfeed
      :config
      (setq elfeed-use-curl t)
      (elfeed-set-timeout 36000)
      )

    (use-package elfeed-protocol
      :config
      ;; setup feeds
      (setq elfeed-protocol-fever-update-unread-only nil)
      (setq elfeed-protocol-fever-fetch-category-as-tag t)
      (setq elfeed-protocol-feeds '(("fever+https://sako@rss.sako.box"
    				 :api-url "https://rss.sako.box/fever/"
    				 :password (password-store-get "SelfHosted/rss.sako.box/fever"))))

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

Matrix

Ill set this up later as well

  (use-package ement
  :commands ement-connect
  :custom
  (ement-notify-dbus-p nil) ;; Turn off notifications
  (ement-sessions-file "~/.cache/ement.el")
  (ement-room-list-default-keys
   '(;; Group all invitations (this group will appear first since the rooms are
     ;; already sorted first).
     ((membership :status 'invite))

     ;; Group all left rooms (this group will appear last, because the rooms are already
     ;; sorted last).
     ((membership :status 'leave))

     ;; Group all favorite rooms, which are already sorted first.
     (favourite)

     ;; Group all low-priority rooms, which are already sorted last.
     (low-priority)

     ;; Group other rooms which are unread.
     (unread)
     (people)
     freshness)))

Subsonic

(use-package subsonic)

EMMS

Emacs music player lmfao

  (use-package emms
    :config
    (emms-all)
    (setq emms-player-list '(emms-player-mpd))
    (setq emms-info-functions '(emms-info-mod))
    (setq emms-source-file-default-directory "~/music")
    ;; TODO Keybinds maybe
    )

GPTel

its over the machines took over guys can i get my likes now

    (use-package gptel
      :config
      (gptel-make-ollama "Ollama"            
        :host "localhost:11434"              
        :stream t                             
        :models '("mistral:latest")))

mu4e

GNU patch review metho dor sometihng idk

    (use-package mu4e
      :config

      ;; mu4e syncing issue with isync
      (setq mu4e-change-filenames-when-moving t)

      ;; sending mail
      (setq message-send-mail-function 'smtpmail-send-it)

      (setq mu4e-update-interval (* 10 60))
      (setq mu4e-get-mail-command "offlineimap")
      (setq mu4e-maildir "~/Mail")

      (setq outlook-mail-address
      	(string-trim (shell-command-to-string "pass Microsoft | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'")))

      (defvar proton-mail-address nil)

      (defun get-proton-mail-address-from-pass (command)
        "Execute COMMAND, concatenate its output with 'hello', and store it in my-greeting."
        (let ((output (shell-command-to-string command)))
          (setq output (string-trim output))
          (setq proton-mail-address (concat "@proton.me" output))))

      (get-proton-mail-address-from-pass "pass Proton\ Account | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'")

      (setq gmail-1-mail-address
      	(string-trim (shell-command-to-string "pass accounts.google.com/one | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'")))

      (setq gmail-2-mail-address
      	(string-trim (shell-command-to-string "pass accounts.google.com/two | awk 'BEGIN {ORS=\"\"} FNR == 2{gsub(\"login: \", \"\"); gsub(/ /, \"\"); print}'")))

      (setq mu4e-context-policy 'pick-first)
      (setq mu4e-compose-context-policy 'always-ask)
      (setq mu4e-contexts
      	(list
      	 ;; outlook
      	 (make-mu4e-context
      	  :name "Outlook"
      	  :match-func
      	  (lambda (msg)
      	    (when msg
      	      (string-prefix-p "/Outlook" (mu4e-message-field msg :maildir))))
      	  :vars `((user-mail-address . ,outlook-mail-address)
      	          (user-full-name . "Sako")
      		  (mu4e-drafts-folder . "/Outlook/Drafts")
      		  (mu4e-sent-folder . "/Outlook/Sent")
      		  (mu4e-refile-folder . "/Outlook/Inbox")
      		  (mu4e-trash-folder . "/Outlook/Deleted")
    		  ;; todo stmpmail and compose signatures
  		  ))
      	 (make-mu4e-context
      	  :name "Proton"
      	  :match-func
      	  (lambda (msg)
      	    (when msg
      	      (string-prefix-p "/Proton" (mu4e-message-field msg :maildir))))
      	  :vars `((user-mail-address . ,proton-mail-address)
      	          (user-full-name . "Sako")
      		  (mu4e-drafts-folder . "/Proton/Drafts")
      		  (mu4e-sent-folder . "/Proton/Sent")
      		  (mu4e-refile-folder . "/Proton/Inbox")
      		  (mu4e-trash-folder . "/Proton/Trash"))
    	  ;; todo stmpmail and compose signatures
    	  )
    	 (make-mu4e-context
    	  :name "Gmail Personal 1"
    	  :match-func
    	  (lambda (msg)
    	    (when msg
    	      (string-prefix-p "/Gmail-Personal-1" (mu4e-message-field msg :maildir))))
    	  :vars `((user-mail-address .  ,gmail-1-mail-address)
    		  (user-full-name . "Sako")
    		  (mu4e-drafts-folder . "/Gmail-Personal-1/Drafts")
    		  (mu4e-sent-folder . "/Gmail-Personal-1/Sent Mail")
    		  (mu4e-refile-folder . "/Gmail-Personal-1/Inbox")
    		  (mu4e-trash-folder . "Gmail-Personal-1/Trash")
    		  ;; todo stmpmail and compose signatures
    		  ))
    	 (make-mu4e-context
    	  :name "Second Personal Gmail"
    	  :match-func
    	  (lambda (msg)
    	    (when msg
    	      (string-prefix-p "/Gmail-Personal-2" (mu4e-message-field msg :maildir))))
    	  :vars `((user-mail-address .  ,gmail-2-mail-address)
    		  (user-full-name . "Sako")
    		  (mu4e-drafts-folder . "/Gmail-Personal-2/Drafts")
    		  (mu4e-sent-folder . "/Gmail-Personal-2/Sent Mail")
    		  (mu4e-refile-folder . "/Gmail-Personal-2/Inbox")
    		  (mu4e-trash-folder . "Gmail-Personal-2/Trash")
    		  ))
    	 
      	 ))
      )

Org

(message "Reached Org")

Org mode configuration

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

  ;; habits, useless for now though
  ;; (require 'org-habit)
  ;; (add-to-list 'org-modules 'org-habit)
  ;; (setq org-habit-graph-column 60)

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

  ;; make sure to save everything after refiling
  (advice-add 'org-refile :after 'org-save-all-org-buffers)

  ;; org agenda
  (setq org-agenda-files
        '("~/org/tasks.org"
          "~/org/school.org"
          "~/org/daily.org"
          "~/org/irl.org"
          "~/org/work.org"))

  ;; follow links
  (setq org-return-follows-link  t)

  ;; hide leading stars
  (setq org-hide-leading-stars t)
  (setq org-hide-emphasis-markers nil)

  ;; templates
  (require 'org-tempo)

  ;; this'll come in handly later
  (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"))

  ;; more options
   (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@)")))

   ;; this is really useful 
  (setq org-startup-with-inline-images t)

  ;; i hope i actually use this eventually
  (setq org-capture-templates
  	`(("t" "Tasks")
  	  ("tt" "Task" entry (file+olp "~/org/tasks.org" "captured")
  	   "* TODO %?\n %U\n %a\n %i" :empty-lines1)))
  )

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

Org-Pomodoro

(use-package org-pomodoro)

PDF-Tools

Export and then view with emacs :)

(use-package pdf-tools)

EXWM

I'm scared

      (defcustom is-exwm nil
        "Toggle if EXWM is being used"
        :type 'boolean)

      (when (eq system-type 'gnu/linux)
        (when is-exwm
        (use-package exwm
          :config
          (set-frame-parameter nil 'alpha '(90 . 90))
          (add-to-list 'default-frame-alist '(alpha . (90 . 90)))

          (defun sakomacs/exwm-init-hook ()
            ;; background
            (call-process-shell-command "feh --bg-fill ~/background.png" nil 0)     
            ;; (set-frame-parameter nil 'alpha 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)  
            
            ;; battery
            (display-battery-mode)
            ;; show time on the modeline 
            (setq display-time-default-load-average nil)
            (setq display-time-24hr-format t)
            (display-time-mode t)
            ;; shrink fringe to 1px
            (fringe-mode 1)
            )

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

          ;; make the buffer names better
          (add-hook 'exwm-update-class-hook
                    (lambda ()
      		(unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
                                  (string= "gimp" exwm-instance-name))
      		  (exwm-workspace-rename-buffer exwm-class-name))))
          (add-hook 'exwm-update-title-hook
                    (lambda ()
      		(when (or (not exwm-instance-name)
      			  (string-prefix-p "sun-awt-X11-" exwm-instance-name)
      			  (string= "gimp" exwm-instance-name))
      		  (exwm-workspace-rename-buffer exwm-title))))     
          
          ;; 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

          (setq exwm-input-stimulation-keys
      	  '(
      	    ;; cut/paste.
      	    ([?\C-w] . [?\C-x])
      	    ([?\M-w] . [?\C-c])
      	    ([?\C-y] . [?\C-v])))
          

          ;; Ctrl+/3Q 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") 'app-launcher-run-app)
          (exwm-input-set-key (kbd "s-f") 'exwm-layout-toggle-fullscreen)
          (exwm-input-set-key (kbd "s-<return>") 'vterm)

          ;; kill apps
          (exwm-input-set-key (kbd "s-q") #'kill-current-buffer)
          
          ;; 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%-"))
        ))

End

  (message "Welcome to Emacs!")

  ;; EOF