;; -*- lexical-binding: t -*- ;; Copyright © 2018-2025 Uko Koknevics ;; Make sure early-init has been loaded. (unless (boundp 'loaded-early-init) (load (expand-file-name "early-init" (file-name-directory load-file-name)) nil t)) (when (version< emacs-version "29.1") (error "Using %s. Minimum supported version is 29.1." (emacs-version))) (setq-default user-full-name "Uko Kokņevičs" user-email-address "perkontevs@gmail.com") (defconst +emacs29+ (version< emacs-version "30.0")) (defconst +linux+ (eq system-type 'gnu/linux)) (defconst +mac+ (eq system-type 'darwin)) (defconst +bsd+ (or +mac+ (eq system-type 'berkeley-unix))) (defconst +windows+ (memq system-type '(cygwin windows-nt ms-dos))) (defconst base-dir user-emacs-directory) (defconst local-dir (expand-file-name "local" base-dir)) (defconst local-config-dir (expand-file-name "config" local-dir)) (defconst tmp-dir (expand-file-name "tmp" local-dir)) (defconst shared-dir (expand-file-name "shared" base-dir)) ;; TODO: Check how to do add smth like `:advice (fn :around advice)` sometime (require 'use-package) (use-package use-package) ;; Early configurations (setq shared-game-score-directory (expand-file-name "shared-game-score" shared-dir)) (use-package cus-edit :defer t :custom (custom-file (expand-file-name "custom.el" shared-dir))) (defun $adv-write-to-sane-paths (fn &rest args) "Write 3rd party files to `local-config-dir` to keep `user-emacs-directory` clean." (let ((user-emacs-directory local-config-dir) (user-init-file custom-file)) (apply fn args))) (use-package files :defer t :custom (auto-mode-case-fold nil) (auto-save-file-name-transforms `((".*" ,tmp-dir t))) (backup-directory-alist `((".*" . ,tmp-dir))) (major-mode-remap-alist '((c-mode . c-ts-mode) (c-or-c++-mode . c-or-c++-ts-mode) (c++-mode . c++-ts-mode) (cmake-mode . cmake-ts-mode) (csharp-mode . csharp-ts-mode) (css-mode . css-ts-mode) (dockerfile-mode . dockerfile-ts-mode) (go-mode . go-ts-mode) (go-mod-mode . go-mod-ts-mode) (html-mode . mhtml-mode) (java-mode . java-ts-mode) (js-mode . js-ts-mode) (json-mode . json-ts-mode) (python-mode . python-ts-mode) (ruby-mode . ruby-ts-mode) (rust-mode . rust-ts-mode) (yaml-mode . yaml-ts-mode) (toml-mode . toml-ts-mode) (tsx-mode . tsx-ts-mode) (typescript-mode . typescript-ts-mode))) :config (advice-add #'locate-user-emacs-file :around #'$adv-write-to-sane-paths)) (use-package novice :defer t :config (advice-add #'enable-command :around #'$adv-write-to-sane-paths) (advice-add #'disable-command :around #'$adv-write-to-sane-paths)) ;; Improve Emacs security somewhat (setq gnutls-min-prime-bits 3072 gnutls-verify-error (and (fboundp 'gnutls-available-p) (gnutls-available-p) (not (getenv-internal "INSECURE"))) tls-checktrust gnutls-verify-error tls-program '("openssl s_client -connect %h:%p -CAfile %t -nbio -no_ssl3 -no_tls1 -no_tls1_1 -ign_eof" "gnutls-cli -p %p --dh-bits=3072 --ocsp --x509cafile=%t --strict-tofu --priority='SECURE128:+SECURE192:-VERS-ALL:+VERS-TLS1.2:+VERS-TLS1.3' %h" "gnutls-cli -p %p %h")) (when (boundp 'libgnutls-version) (setq gnutls-algorithm-priority (concat "SECURE128:+SECURE192:-VERS-ALL" (if (and (not +windows+) (>= libgnutls-version 30605)) ":+VERS-TLS1.3" ":+VERS-TLS1.2")))) (when +mac+ (setq mac-option-modifier 'meta mac-command-modifier 'super)) (when (file-exists-p custom-file) (load custom-file)) (use-package auth-source :defer t :custom ;; Make sure authinfo is GPG'd (auth-sources (list (expand-file-name "authinfo.gpg" local-config-dir) "~/.authinfo.gpg"))) (use-package ffap :defer t :custom ;; Don't ping random stuff (ffap-machine-p-known 'reject)) (use-package startup :defer t :custom (inhibit-default-init t) (inhibit-startup-echo-area-message user-login-name) (inhibit-startup-screen t) (initial-major-mode 'fundamental-mode) (initial-scratch-message nil)) ;; Don't draw stuff in other windows. (setq-default cursor-in-non-selected-windows nil) (setq highlight-nonselected-windows nil) ;; Faster scrolling (setq fast-but-imprecise-scrolling t) ;; Inhibit frame resizing (setq frame-inhibit-implied-resize t) ;; Don’t compact font caches during GC. (setq inhibit-compacting-font-caches t) (setq read-process-output-max (* 64 1024)) ;; Don't fontify if stuck on reading input (setq redisplay-skip-fontification-on-input t) (when +windows+ (setq w32-get-true-file-attributes nil w32-pipe-read-delay 0 w32-pipe-buffer-size read-process-output-max)) ;; Install straight.el (defvar bootstrap-version) (let ((bootstrap-file (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)) (bootstrap-version 6)) (unless (file-exists-p bootstrap-file) (message "This might take a long time...") (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)) (defun arkta/update-packages () (interactive) (straight-pull-all) (straight-freeze-versions)) (defun arkta/fix-versions () (interactive) ;; Thaw & freeze to make sure we also freeze new stuff (straight-thaw-versions) (straight-freeze-versions)) ;; compat (use-package compat-30 :if +emacs29+ :straight 'compat) ;; Helper functions (defmacro defsetter (name &rest emacs-names) (let ((name (intern (concat "set-" (symbol-name name))))) `(defun ,name (value &optional default) (if default (progn ,@(mapcar (lambda (name) `(setq-default ,name value)) emacs-names)) ,@(mapcar (lambda (name) `(setq ,name value)) emacs-names))))) (defsetter fill-width fill-column) (defsetter tab-usage indent-tabs-mode) (defsetter tab-width c-basic-offset nasm-offset standard-indent tab-width) ;; Miscellany (set-fill-width 120 t) (set-tab-usage nil t) (set-tab-width 4 t) ;; HIC SVNT DRACONES (require 'arkta-cosmetic) (require 'arkta-progmodes) (require 'arkta-project) (use-package ace-window :straight t :bind (([remap other-window] . ace-window) ("C-x o" . ace-window))) (use-package amx :straight t :config (amx-mode +1)) (use-package company :straight t :custom (company-format-margin-function #'company-text-icons-margin) (company-text-face-extra-attributes '(:weight bold)) (company-text-icons-add-background t) (company-tooltip-flip-when-above nil) (company-tooltip-limit 6) (company-tooltip-minimum 6) (company-tooltip-offset-display 'lines) :config (global-company-mode +1)) (use-package compile :straight '(compile :type built-in) :bind (("C-c k" . compile))) (use-package copyright :straight '(copyright :type built-in) :init (defun arkta/maybe-fix-copyright () (save-mark-and-excursion (copyright-update) (copyright-fix-years))) :hook (before-save . arkta/maybe-fix-copyright) :custom (copyright-names-regexp "Eris\\|Ukko\\|Uko\\|Free Software") (copyright-year-ranges t)) (use-package counsel :straight t :after amx :config (counsel-mode +1)) (use-package dashboard :straight t :demand t :hook (server-after-make-frame . dashboard-open) :custom (dashboard-center-content nil) (dashboard-startup-banner (expand-file-name "logo.png" user-emacs-directory)) (dashboard-items '((projects . 5) (recents . 5) (bookmarks . 5))) (dashboard-projects-backend 'project-el) (dashboard-remove-missing-entry nil) (dashboard-set-heading-icons t) (dashboard-set-file-icons t) (dashboard-set-init-info t) :config (dashboard-setup-startup-hook)) (use-package editorconfig :straight t :config (editorconfig-mode +1)) (use-package eglot :straight '(eglot :type built-in) :hook ((gdscript-mode go-ts-mode) . eglot-ensure) :custom (eglot-ignored-server-capabilities '(:documentFormattingProvider :documentRangeFormattingProvider :documentOnTypeFormattingProvider)) (eglot-autoshutdown t)) (use-package elpher :straight t :commands (elpher) :custom (elpher-default-url-type "gemini")) (use-package envrc :straight t ;; This actually has to be hooked to after-init to be one of the first minor modes enabled :hook (after-init . envrc-global-mode)) (use-package gcmh :straight t :custom (gcmh-idle-delay 'auto) (gcmh-auto-idle-delay-factor 10) (gcmh-high-cons-threshold (* 16 1024 1024)) :config (gcmh-mode +1)) (use-package ibuffer :straight '(ibuffer :type built-in) :bind (("C-x C-b" . ibuffer) ([remap list-buffers] . ibuffer))) (use-package ivy :after (counsel swiper) :straight t :demand t :bind (("C-c r" . ivy-resume) ("C-c v" . ivy-push-view) ("C-c V" . ivy-pop-view)) :custom (ivy-use-virtual-buffers t) (ivy-count-format "(%d/%d) ") :config (ivy-mode +1)) (use-package magit ;; TODO: Do some proper setup :straight t :config (use-package forge :straight t :after magit)) (use-package simple :straight (simple :type built-in) :hook ((text-mode . turn-on-auto-fill) (before-save . delete-trailing-whitespace)) :custom (backward-delete-char-untabify-method nil)) (use-package swiper :straight t :bind (([remap isearch-forward] . swiper-isearch) ([remap isearch-backward] . swiper-isearch-backward) ("C-s" . swiper-isearch) ("C-r" . swiper-isearch-backward))) (use-package treemacs :straight t :commands (treemacs treemacs-select-window) :custom (treemacs-select-when-already-in-treemacs 'next-or-back) :bind (("C-c SPC" . treemacs-select-window) ("C-c C-SPC" . treemacs-select-window))) (use-package treesit :straight '(treesit :type built-in) :config (setq treesit-extra-load-path (list (expand-file-name "tree-sitter" local-config-dir))) (setq treesit-language-source-alist '((c "https://github.com/tree-sitter/tree-sitter-c.git") (cmake "https://github.com/uyha/tree-sitter-cmake.git") (cpp "https://github.com/tree-sitter/tree-sitter-cpp.git") (c-sharp "https://github.com/tree-sitter/tree-sitter-c-sharp.git") (css "https://github.com/tree-sitter/tree-sitter-css.git") (dockerfile "https://github.com/camdencheek/tree-sitter-dockerfile.git") (go "https://github.com/tree-sitter/tree-sitter-go.git") (gomod "https://github.com/camdencheek/tree-sitter-go-mod.git") (java "https://github.com/tree-sitter/tree-sitter-java.git") (javascript "https://github.com/tree-sitter/tree-sitter-javascript.git") (json "https://github.com/tree-sitter/tree-sitter-json.git") (python "https://github.com/tree-sitter/tree-sitter-python.git") (ruby "https://github.com/tree-sitter/tree-sitter-ruby.git") (rust "https://github.com/tree-sitter/tree-sitter-rust.git") (toml "https://github.com/ikatyang/tree-sitter-toml.git") (tsx "https://github.com/tree-sitter/tree-sitter-typescript.git" nil "tsx/src") (typescript "https://github.com/tree-sitter/tree-sitter-typescript.git" nil "typescript/src") (yaml "https://github.com/ikatyang/tree-sitter-yaml.git"))) (mapc (lambda (spec) (let ((name (car spec))) (unless (treesit-language-available-p name) (treesit-install-language-grammar name)))) treesit-language-source-alist)) (use-package warnings :straight '(warnings :type built-in) :custom (warning-suppress-types '((comp))))