;; =========================== ;; Package Management Setup ;; =========================== (require 'package) ;; Add MELPA, Org, and GNU package archives (setq package-archives '(("melpa" . "https://melpa.org/packages/") ("org" . "https://orgmode.org/elpa/") ("gnu" . "https://elpa.gnu.org/packages/"))) (package-initialize) ;; Refresh package list if it's not already available (unless package-archive-contents (package-refresh-contents)) ;; Install use-package if it's not already installed (unless (package-installed-p 'use-package) (package-install 'use-package)) (require 'use-package) (setq use-package-always-ensure t) ;; Always ensure packages are installed ;; =========================== ;; Theme Configuration ;; =========================== ;; Define your preferred light and dark themes (setq dark-theme 'zenburn) (setq light-theme 'solarized-light) ;; Install Themes (use-package solarized-theme :ensure t) (use-package zenburn-theme :ensure t) (defun my/get-system-appearance () (cond ;; --------------------------- ;; macOS ;; --------------------------- ((eq system-type 'darwin) (if (string= (shell-command-to-string "defaults read -g AppleInterfaceStyle 2>/dev/null") "Dark\n") 'dark 'light)) ;; --------------------------- ;; Windows ;; --------------------------- ((eq system-type 'windows-nt) ;; NOTE: For Windows 10/11, “AppsUseLightTheme” is under: ;; HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize ;; Value of 1 => Light, 0 => Dark (let ((output (shell-command-to-string "reg query \"HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize\" /v AppsUseLightTheme 2>nul"))) (cond ((string-match "0x1" output) 'light) ((string-match "0x0" output) 'dark) (t nil)))) ;; --------------------------- ;; GNOME-based Linux ;; --------------------------- ((eq system-type 'gnu/linux) ;; If you're on GNOME 42+, `color-scheme` often shows 'prefer-dark' or 'prefer-light'. ;; If the user is using an older system or a different DE, this may fail or return an empty string. (let ((gsettings-output (string-trim (shell-command-to-string "gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null")))) (cond ((string-match "dark" gsettings-output) 'dark) ((string-match "light" gsettings-output) 'light) (t nil)))) ;; --------------------------- ;; Otherwise, undetermined ;; --------------------------- (t nil))) (defun my/set-theme-based-on-appearance () "Set Emacs theme based on system appearance if possible, otherwise fallback." (let ((appearance (my/get-system-appearance))) ;; Disable all currently enabled themes to prevent conflicts (mapc #'disable-theme custom-enabled-themes) (pcase appearance ('dark (load-theme dark-theme t)) ('light (load-theme light-theme t)) (_ ;; If we cannot detect the theme, default to light (load-theme light-theme t))))) ;; Apply theme at startup (my/set-theme-based-on-appearance) ;; =========================== ;; UI Customizations ;; =========================== ;; Disable unnecessary UI elements (tool-bar-mode -1) ;; Hide the toolbar (menu-bar-mode -1) ;; Hide the menu bar (scroll-bar-mode -1) ;; Hide the scroll bar ;; Enable useful UI features (column-number-mode 1) ;; Show column numbers (global-display-line-numbers-mode 1) ;; Enable global line numbers ;; Enable visual line mode globally (global-visual-line-mode 1) ;; Set Default Font to Iosevka 18pt ;;(set-face-attribute 'default nil :family "Iosevka" :height 150) ;; Set font (set-face-attribute 'default nil :family "JetBrains Mono Nerd Font" :height 140 :weight 'normal :width 'normal) ;; Line spacing (setq-default line-spacing 0) ;; Backup files -> ~/.emacs.d/backups/ (setq backup-directory-alist `(("." . "~/.emacs.d/backups")) backup-by-copying t ;; Don't delink hardlinks version-control t ;; Use version numbers on backups delete-old-versions t ;; Automatically delete excess backups kept-new-versions 6 kept-old-versions 2) ;; =========================== ;; macOS Specific Settings ;; =========================== (when (eq system-type 'darwin) ;; Use Command key as Meta (setq mac-command-modifier 'meta mac-option-modifier 'none) ;; Better font rendering on macOS (setq ns-use-srgb-colorspace t) ;; Add homebrew (add-to-list 'exec-path "/opt/homebrew/bin") ) ;; =========================== ;; Evil Mode Configuration ;; =========================== (use-package evil :ensure t :init (setq evil-want-integration t) (setq evil-want-keybinding nil) :config (evil-mode 1)) ;; Enable Evil Mode globally (use-package evil-collection :init :after evil :ensure t :config (evil-collection-init)) (keymap-global-set "C-u" 'evil-scroll-up) ;; =========================== ;; Additional Packages ;; =========================== ;; Install and enable Helm (use-package helm :config (helm-mode 1)) ;; Install and enable Company Mode globally (use-package company :init (global-company-mode 1) :config ;; Integrate Company with LSP (setq company-minimum-prefix-length 1 company-idle-delay 0.0)) ;; Show completions immediately ;; Install and configure Projectile (use-package projectile :init (projectile-mode +1) :bind (:map projectile-mode-map ("s-p" . projectile-command-map))) ;; Install and bind Magit (use-package magit :bind ("C-x g" . magit-status)) ;; Install and enable Which-Key (use-package which-key :config (which-key-mode)) ;; =========================== ;; LSP Configuration ;; =========================== (use-package lsp-mode :hook ((python-mode . lsp) (kotlin-mode . lsp) (c++-mode . lsp) (c-mode . lsp) (rust-mode . lsp)) :commands lsp :config (setq lsp-prefer-flymake nil) ;; Use lsp-ui and flycheck instead of flymake (setq lsp-enable-snippet t) ;; Disable snippet support if not needed (setq lsp-headerline-breadcrumb-enable nil)) ;; Disable breadcrumb for performance (use-package lsp-ui :commands lsp-ui-mode :config (setq lsp-ui-doc-enable t lsp-ui-doc-delay 0.2 lsp-ui-sideline-enable t lsp-ui-imenu-enable t)) (use-package lsp-treemacs :commands lsp-treemacs-errors-list) (use-package flycheck :init (global-flycheck-mode)) ;; =========================== ;; Language-Specific Configurations ;; =========================== ;; Python (use-package lsp-pyright :ensure t :custom (lsp-pyright-langserver-command "pyright") ;; or basedpyright :hook (python-mode . (lambda () (require 'lsp-pyright) (lsp)))) ; or lsp-deferred (use-package python :ensure nil :hook (python-mode . lsp) :config (setq python-shell-interpreter "python3") ) (use-package poetry :ensure t) ;; Kotlin (use-package kotlin-mode :mode "\\.kt\\'" :config ) ;; C++ (use-package cc-mode :ensure nil :config ) ;; Rust (use-package rust-mode :hook (rust-mode . lsp) :config (setq rust-format-on-save t) ) (message "Emacs init loaded.") (custom-set-variables ;; custom-set-variables was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. '(helm-minibuffer-history-key "M-p") '(package-selected-packages '(catppuccin-theme lsp-pyright zenburn-theme which-key solarized-theme rust-mode projectile poetry magit lsp-ui lsp-treemacs kotlin-mode helm flycheck evil-collection dracula-theme company better-defaults))) (custom-set-faces ;; custom-set-faces was added by Custom. ;; If you edit it by hand, you could mess it up, so be careful. ;; Your init file should contain only one such instance. ;; If there is more than one, they won't work right. )