nixos-config/extraFiles/config/emacs/emacs-materus-config.org

20 KiB

Materus Emacs Cfg

My emacs config, tangled file is there

Init Files

Early Init

Early init file, setting for GC and some paths. Tangled file is there

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

Early Init Variables

Setting early init variables

  (defvar materus/init-early t
    "Is emacs using materus early init")                                                    ; Var to ensure early-init loaded, not used anymore but keeping it anyway
  (setq materus/init-early t)                                                               ; Probably useless

  (setenv "LSP_USE_PLISTS" "true")                                                          ; Make lsp-mode use plists
  ;; 
  (setq c-default-style nil)                                                                ; Clear default styles for languages, will set them up later
  (setq default-input-method nil)                                                           ; Disable default input method, I'm not using them anyway so far
  (setq initial-major-mode 'fundamental-mode)                                               ; Use fundamental mode in scratch buffer, speed up loading, not really important when emacs used as daemon
  (setq auto-save-default nil)                                                              ; TODO: configure auto saves, disable for now
  (setq backup-directory-alist
        `((".*" . ,(concat user-emacs-directory "var/backups/"))))                          ; Set backup location
  (setq auto-save-file-name-transforms
        `((".*" ,(concat user-emacs-directory "var/recovery/") t)))                         ; Set auto-save location  
  (setq auto-save-list-file-prefix (concat user-emacs-directory "var/auto-save/sessions/")) ; Set auto-save-list location
  (setq load-prefer-newer t)                                                                ; Prefer newer files to load

  ;; Packages
  (setq package-enable-at-startup t)                                                        ; Ensure packages are enable since I'm either using built in package manager or nix
  (setq package-quickstart nil)                                                             ; Disable package quickstart, it's annoying if forget to update it and doesn't speed up much
  ;;

  (setq inhibit-compacting-font-caches t)                                                   ; Don't compact fonts

  (set-language-environment "UTF-8")                                                        ; Use UTF-8

  (setq custom-file (concat user-emacs-directory "etc/custom.el"))                          ; Set custom file location, don't want clutter in main directory
  (setq custom-theme-directory
        (concat user-emacs-directory "/etc/materus/themes" ))                               ; Set custom themes location

  (setq ring-bell-function 'ignore)                                                         ; Disable bell


  (defvar materus-emacs-gc-cons-threshold (* 64 1024 1024)
    "The value of `gc-cons-threshold' after Emacs startup.")                                ; Define after init garbage collector threshold

Garbage Collector

Settings for garbage collector

  (setq gc-cons-threshold most-positive-fixnum)                                             ; Set `gc-cons-threshold' so it won't collectect during initialization 

  (add-hook 'emacs-startup-hook
            (lambda ()
              (setq gc-cons-threshold materus-emacs-gc-cons-threshold)))                    ; Set `gc-cons-threshold' to desired value after startup

Early Frame Settings

Early frame settings, maybe some could be move to normal init

  (setq frame-inhibit-implied-resize t)
  (setq frame-resize-pixelwise t)
  (setq window-resize-pixelwise t)                                ; Allow pixelwise resizing of window and frame

  (unless (daemonp)
    (add-to-list 'initial-frame-alist '(fullscreen . maximized))) ; Start first frame maximized if not running as daemon, daemon frame are set up later in config
  (setq default-frame-alist                                       ; Set default size for frames
        '((width . 130)   
          (height . 40)))                 

  (advice-add #'tty-run-terminal-initialization :override #'ignore)
  (add-hook 'window-setup-hook
            (lambda ()
              (unless (display-graphic-p)
                (advice-remove #'tty-run-terminal-initialization #'ignore) 
                (tty-run-terminal-initialization (selected-frame) nil t)
                )))

Native compilation

  (setq native-comp-async-report-warnings-errors nil) ; Silence warnings
  (setq native-comp-speed 3)                          ; Set native-comp speed

  (setq native-comp-jit-compilation t
        ;;native-comp-deferred-compilation t 
        package-native-compile t)


  ;; Setting up native-comp cache location

  (when (and (fboundp 'startup-redirect-eln-cache)
             (fboundp 'native-comp-available-p)
             (native-comp-available-p))
    (startup-redirect-eln-cache
     (convert-standard-filename
      (concat user-emacs-directory "var/eln-cache/"))))

Init

Init File, tangled there Checking if using emacs from my nix config, loads config and custom.el Sets up package.el

  ;;; -*- lexical-binding: t; -*-
  (setq-default materus/use-nix-packages (require 'materus-config nil 'noerror))
  (require 'cl-lib)
  (require 'package)

  (add-to-list 'load-path (concat user-emacs-directory "etc/materus/extra"))                ; Extra load path for packages
  (setq package-user-dir (concat user-emacs-directory "var/elpa/" emacs-version "/" ))      ; Set elpa path for this emacs version, should use nix packages anyway so keeping just in case
  (setq package-gnupghome-dir (concat user-emacs-directory "var/elpa/gnupg/" ))             ; Set path to gnupg for elpa
  (add-to-list 'package-archives 
               '("nongnu-devel" . "https://elpa.nongnu.org/nongnu-devel/"))                 ; Add nongnu-devel repo to package manager
  (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)              ; Add melpa repo to package manager
  (customize-set-variable 'package-archive-priorities '(("gnu"    . 99)
                                                        ("nongnu" . 80)
                                                        ("nongnu-devel" . 70)
                                                        ("melpa"  . 0)))                    ; Repository priority

  (load (concat user-emacs-directory "etc/materus/nix-init") t)
  (load (concat user-emacs-directory "etc/materus/emacs-config"))
  (load custom-file t)

Compile Time

Some defvar so native-compile wont complain

  ;;; -*- lexical-binding: t; -*-
  (eval-when-compile 
    (defvar doom-modeline-support-imenu nil)
    (defvar display-time-24hr-format nil)
    (defvar lsp-nix-nixd-formatting-command nil)
    (defvar cua--cua-keys-keymap nil)
    (declare-function lsp-stdio-connection "lsp-mode" (COMMAND &optional TEST-COMMAND))
    (declare-function make-lsp-client "lsp-mode")
    (declare-function lsp-register-client "lsp-mode" ( CLIENT ))
    )

Packages

Package manager config if not using nix. After some testing default package manager works best for me.

Init package manager config

Packages list & function

Packages to install

  (defvar materus/packages
    '(
      use-package
      elcord
      dashboard
      magit
      git-timemachine
      avy
      vterm
      direnv
      projectile
      clipetty
      which-key
      iedit
      hideshowvis
      evil
      perspective
      treemacs-evil
      treemacs
      treemacs-nerd-icons
      treemacs-perspective
      treemacs-icons-dired
      treemacs-magit
      treemacs-projectile
      tree-edit
      nerd-icons
      nerd-icons-completion
      minions
      rainbow-delimiters
      rainbow-mode
      cmake-mode
      lsp-mode
      lsp-java
      lsp-jedi
      lsp-haskell
      lsp-ui
      lsp-treemacs
      flycheck
      gradle-mode
      groovy-mode
      kotlin-mode
      dap-mode
      d-mode
      lua-mode
      multiple-cursors
      org
      org-contrib
      org-ql
      org-rainbow-tags
      org-roam
      org-roam-ui
      org-review
      org-present
      org-superstar
      org-auto-tangle
      visual-fill-column
      csharp-mode
      markdown-mode
      json-mode
      nix-mode
      nixfmt
      no-littering
      right-click-context
      dracula-theme
      doom-themes
      doom-modeline
      popper
      undo-tree
      bash-completion
      eldoc-box
      yasnippet
      async
      request
      nix-ts-mode
      markdown-ts-mode
      llvm-ts-mode
      treesit-fold
      treesit-auto
      tree-sitter-langs
      eat
      vlf
      edit-indirect
      zones
      sudo-edit
      toc-org
      empv
      volatile-highlights
      highlight
      elfeed
      elfeed-goodies
      drag-stuff
      dirvish
      rg
      shfmt
      ;; Completions & Minibuffer
      corfu
      company
      company-quickhelp
      cape
      embark
      embark-consult
      orderless
      vertico
      marginalia
      )
    "A list of packages to ensure are installed at launch.")

  (defun materus/packages-installed-p ()
    (cl-loop for p in materus/packages
             when (not (package-installed-p p)) do (cl-return nil)
             finally (cl-return t)))

  (defun materus/install-packages ()
    (unless (materus/packages-installed-p)
      (package-refresh-contents)
      (dolist (p materus/packages)
        (when (not (package-installed-p p))
          (package-install p)))))
  (unless materus/use-nix-packages 
    (materus/install-packages))

Configuration

General configurations of packages modes etc.

No Littering

Set up no littering

Graphical

Graphical related settings.

Mouse

Misc

  ;; Rainbow mode

Dashboard

Modeline

Diff-hl

Org-mode

Org mode settings

Completions

Style

Minibuffer

Miscellaneous

Programming

LSP

  (use-package lsp-mode
    :custom
    (lsp-completion-provider :none) ;; we use Corfu!
    :config
    (setq lsp-keep-workspace-alive nil)
    (require 'lsp-ui)
    :init
    (defun materus/orderless-dispatch-flex-first (_pattern index _total)
      (and (eq index 0) 'orderless-flex))

    (defun materus/lsp-mode-setup-completion ()
      (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
            '(orderless))
      ;; Optionally configure the first word as flex filtered.
      (add-hook 'orderless-style-dispatchers #'materus/orderless-dispatch-flex-first nil 'local)
      ;; Optionally configure the cape-capf-buster.
      (setq-local completion-at-point-functions (list (cape-capf-buster #'lsp-completion-at-point))))

    :hook
    (lsp-completion-mode . materus/lsp-mode-setup-completion))

   


    (setq read-process-output-max (* 1024 1024 3))

    (defun lsp-booster--advice-json-parse (old-fn &rest args)
      "Try to parse bytecode instead of json."
      (or
       (when (equal (following-char) ?#)
         (let ((bytecode (read (current-buffer))))
           (when (byte-code-function-p bytecode)
             (funcall bytecode))))
       (apply old-fn args)))
    (advice-add (if (progn (require 'json)
                           (fboundp 'json-parse-buffer))
                    'json-parse-buffer
                  'json-read)
                :around
                #'lsp-booster--advice-json-parse)

    (defun lsp-booster--advice-final-command (old-fn cmd &optional test?)
      "Prepend emacs-lsp-booster command to lsp CMD."
      (let ((orig-result (funcall old-fn cmd test?)))
        (if (and (not test?)                                                             ; for check lsp-server-present?
                 (not (file-remote-p default-directory))                                 ; see lsp-resolve-final-command, it would add extra shell wrapper
                 lsp-use-plists
                 (not (functionp 'json-rpc-connection))                                  ; native json-rpc
                 (executable-find "emacs-lsp-booster"))
            (progn
              (when-let* ((command-from-exec-path (executable-find (car orig-result))))  ; resolve command from exec-path (in case not found in $PATH)
                (setcar orig-result command-from-exec-path))
              (message "Using emacs-lsp-booster for %s!" orig-result)
              (cons "emacs-lsp-booster" orig-result))
          orig-result)))
    (advice-add 'lsp-resolve-final-command :around #'lsp-booster--advice-final-command)

DAP

  (use-package dap-mode
    :config
    (require 'dap-lldb)
    (require 'dap-gdb-lldb)
    (require 'dap-cpptools)
    (setq dap-gdb-lldb-extension-version "0.27.0")
    (dap-auto-configure-mode 1)
    )

Nix

  (use-package nix-mode)
  (use-package nix-ts-mode)
  (use-package nixfmt)
  (use-package lsp-nix)
  (with-eval-after-load 'lsp-mode
    (add-to-list 'lsp-disabled-clients '(nix-mode . nix-nil)) 
    (setq lsp-nix-nixd-server-path "nixd"
          lsp-nix-nixd-formatting-command [ "nixfmt" ]
          lsp-nix-nixd-nixpkgs-expr "import <nixpkgs> { }"))

  (setq lsp-nix-nixd-formatting-command "nixfmt")
  (add-hook 'nix-mode-hook 'lsp-deferred)
  (add-hook 'nix-mode-hook 'display-line-numbers-mode)

  (add-hook 'nix-ts-mode-hook 'lsp-deferred)
  (add-hook 'nix-ts-mode-hook 'display-line-numbers-mode)

  (when (treesit-language-available-p 'nix) (push '(nix-mode . nix-ts-mode) major-mode-remap-alist))

Emacs Lisp

  (add-hook 'emacs-lisp-mode-hook 'display-line-numbers-mode)

C/C++

  (use-package lsp-clangd)
  (setq lsp-clients-clangd-args '("--fallback-style=microsoft"))

  (add-hook 'c-mode-hook 'lsp-deferred)
  (add-hook 'c-mode-hook 'display-line-numbers-mode)
  (add-hook 'c-ts-mode-hook 'lsp-deferred)
  (add-hook 'c-ts-mode-hook 'display-line-numbers-mode)

  (add-hook 'c++-mode-hook 'lsp-deferred)
  (add-hook 'c++-mode-hook 'display-line-numbers-mode)
  (add-hook 'c++-ts-mode-hook 'lsp-deferred)
  (add-hook 'c++-ts-mode-hook 'display-line-numbers-mode)
  (when (treesit-language-available-p 'c) (push '(c-mode . c-ts-mode) major-mode-remap-alist))
  (when (treesit-language-available-p 'cpp) (push '(c++-mode . c++-ts-mode) major-mode-remap-alist))

  (add-to-list 'c-default-style '(c-mode . "bsd"))
  (add-to-list 'c-default-style '(c++-mode . "bsd"))
  (add-to-list 'c-default-style '(c-ts-mode . "bsd"))
  (add-to-list 'c-default-style '(c++-ts-mode . "bsd"))

Python

  (use-package lsp-pyright)
  (setq lsp-pyright-langserver-command "pyright")
  (add-hook 'python-mode-hook 'lsp-deferred)
  (add-hook 'python-ts-mode-hook 'lsp-deferred)
  (when (treesit-language-available-p 'python) (push '(python-mode . python-ts-mode) major-mode-remap-alist))

Java

  (use-package lsp-java)
  (setq lsp-java-vmargs '("-XX:+UseParallelGC" "-XX:GCTimeRatio=4" "-XX:AdaptiveSizePolicyWeight=90" "-Dsun.zip.disableMemoryMapping=true" "-Xmx2G" "-Xms100m"))
  (add-hook 'java-mode-hook (lambda ()  (when (getenv "JDTLS_PATH") (setq lsp-java-server-install-dir (getenv "JDTLS_PATH")))))
  (add-hook 'java-mode-hook 'lsp-deferred)
  (add-hook 'java-mode-hook 'display-line-numbers-mode)

  (add-hook 'java-ts-mode-hook (lambda ()  (when (getenv "JDTLS_PATH") (setq lsp-java-server-install-dir (getenv "JDTLS_PATH")))))
  (add-hook 'java-ts-mode-hook 'lsp-deferred)
  (add-hook 'java-ts-mode-hook 'display-line-numbers-mode)

  (when (treesit-language-available-p 'java) (push '(java-mode . java-ts-mode) major-mode-remap-alist))

  (add-to-list 'c-default-style '(java-mode . "java"))
  (add-to-list 'c-default-style '(java-ts-mode . "java"))

Other

  (add-to-list 'c-default-style '(awk-mode . "awk"))
  (add-to-list 'c-default-style '(other . "bsd"))




  (setq-default c-basic-offset 4)
  (setq-default c-indent-level 4)

  (setq-default c-ts-mode-indent-offset 4)
  (setq-default c-ts-mode-indent-style 'bsd)

  (setq-default c-hungry-delete-key t)

  (electric-pair-mode 1)
  (electric-indent-mode -1)
  (setq-default tab-width 4)
  (setq-default indent-tabs-mode nil)

  (add-hook 'prog-mode-hook 'display-line-numbers-mode)
  (add-hook 'prog-mode-hook 'electric-indent-local-mode)

Keybindings

Keys

Snippets

Yasnippet init

Other

Update config script

  (defun materus/sync-config ()
    "Function to sync config from MATERUS_CONFIG_DIR to emacs folder"
    (if (getenv "MATERUS_CONFIG_DIR")
        (progn (copy-directory (concat (getenv "MATERUS_CONFIG_DIR") "extraFiles/config/emacs/") 
                               user-emacs-directory t t t) t)
      (progn (message "Can't use if MATERUS_CONFIG_DIR is not set!") nil)))
  (defun materus/compare-file-time (file1 file2)
    "Returns t when file1 is newer than file2"
    (time-less-p 
     (nth 5 (file-attributes file2))
     (nth 5 (file-attributes file1))
     ))
  (defun materus/compile-if-needed (file)
    (unless (and (file-exists-p (concat user-emacs-directory file "c"))
                 (materus/compare-file-time (concat user-emacs-directory file "c")
                                            (concat user-emacs-directory file)))
      (byte-compile-file (concat user-emacs-directory file)))
    )
  (defun materus/compile-config-if-needed ()
    (materus/compile-if-needed "early-init.el")
    (materus/compile-if-needed "init.el")
    (materus/compile-if-needed "etc/materus/emacs-config.el"))
  (defun materus/update-config ()
    "Will sync and compile config"
    (interactive)
    (when (materus/sync-config) (materus/compile-config-if-needed) (byte-recompile-directory (concat user-emacs-directory "etc/materus/extra") 0 t)))

Byte compile

Byte compile files.

  (materus/compile-config-if-needed)

Test

Just for testing some code

  ;;; (global-set-key (kbd "C-∇") (kbd "C-H"))
  ;;; (global-set-key (kbd "H-∇") (lambda () (interactive) (insert-char #x2207)))
  ;;; (buffer-text-pixel-size)
  ;;; (set-window-vscroll nil 960 t t)

  ;;;  (set-window-margins (selected-window) 0 0)

  ;;; (buffer-local-value 'var (get-buffer  "your-buffer-name"))

  ;;; (setq completion-styles '(orderless basic)
  ;;;   completion-category-defaults nil
  ;;;   completion-category-overrides '((file (styles partial-completion))))