Split init.el into seperate modules
This commit is contained in:
49
early-init.el
Normal file
49
early-init.el
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
;;; early-init.el --- Early initialization settings -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; This file is loaded before the package system and GUI is initialized.
|
||||||
|
;;; Use it for settings that need to be set very early in the startup process.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;; Defer garbage collection further back in the startup process
|
||||||
|
;; This makes startup faster by preventing frequent GC
|
||||||
|
(setq gc-cons-threshold most-positive-fixnum
|
||||||
|
gc-cons-percentage 0.6)
|
||||||
|
|
||||||
|
;; Store default values to restore after init
|
||||||
|
(defvar default-gc-cons-threshold 16777216) ; 16MB is a good default
|
||||||
|
(defvar default-gc-cons-percentage 0.1)
|
||||||
|
|
||||||
|
;; In Emacs 27+, package initialization occurs before `user-init-file' is loaded,
|
||||||
|
;; but after `early-init-file'. We handle package initialization ourselves.
|
||||||
|
(setq package-enable-at-startup nil)
|
||||||
|
|
||||||
|
;; Prevent the glimpse of un-styled Emacs by disabling these UI elements early.
|
||||||
|
(push '(menu-bar-lines . 0) default-frame-alist)
|
||||||
|
(push '(tool-bar-lines . 0) default-frame-alist)
|
||||||
|
(push '(vertical-scroll-bars) default-frame-alist)
|
||||||
|
|
||||||
|
;; Resizing the Emacs frame can be a terribly expensive part of changing the
|
||||||
|
;; font. By inhibiting this, we easily halve startup times with fonts that are
|
||||||
|
;; larger than the system default.
|
||||||
|
(setq frame-inhibit-implied-resize t)
|
||||||
|
|
||||||
|
;; Native compilation settings for Emacs 28+
|
||||||
|
(when (and (fboundp 'native-comp-available-p)
|
||||||
|
(native-comp-available-p))
|
||||||
|
;; Silence compiler warnings as they can be pretty disruptive
|
||||||
|
(setq native-comp-async-report-warnings-errors nil)
|
||||||
|
;; Make native compilation happen asynchronously
|
||||||
|
(setq native-comp-deferred-compilation t)
|
||||||
|
;; Set the right directory for native compilation cache
|
||||||
|
(add-to-list 'native-comp-eln-load-path (expand-file-name "eln-cache/" user-emacs-directory))
|
||||||
|
;; Compile AOT all the .el files in the configuration
|
||||||
|
(setq native-comp-speed 2) ; Max optimization
|
||||||
|
(setq native-comp-jit-compilation t)) ; JIT compile loaded files
|
||||||
|
|
||||||
|
;; Disable some warnings during initialization
|
||||||
|
(setq byte-compile-warnings '(not obsolete))
|
||||||
|
(setq warning-suppress-log-types '((comp) (bytecomp)))
|
||||||
|
|
||||||
|
(provide 'early-init)
|
||||||
|
;;; early-init.el ends here
|
||||||
231
emacs-dev-config-modern.el
Normal file
231
emacs-dev-config-modern.el
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
;;; emacs-dev-config-modern.el --- Modern development configuration using Eglot -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Development configuration using built-in Eglot instead of lsp-mode
|
||||||
|
;;; This is a lighter, faster alternative to the original dev config
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defvar dev-mode-modern-enabled nil
|
||||||
|
"Flag indicating whether modern development mode is enabled.")
|
||||||
|
|
||||||
|
(defvar dev-mode-modern-packages
|
||||||
|
'(;; Core development tools
|
||||||
|
eglot ; Only needed for Emacs < 29
|
||||||
|
corfu corfu-terminal cape ; Modern completion
|
||||||
|
consult-eglot ; Consult integration with Eglot
|
||||||
|
flycheck ; Can still use alongside Flymake
|
||||||
|
yasnippet
|
||||||
|
projectile
|
||||||
|
ggtags
|
||||||
|
multiple-cursors expand-region
|
||||||
|
hl-todo rainbow-delimiters
|
||||||
|
origami ; Code folding
|
||||||
|
|
||||||
|
;; Version control
|
||||||
|
magit
|
||||||
|
forge ; GitHub/GitLab integration
|
||||||
|
magit-delta ; Better diffs if delta is installed
|
||||||
|
treemacs-magit
|
||||||
|
|
||||||
|
;; Languages
|
||||||
|
clang-format
|
||||||
|
qml-mode
|
||||||
|
|
||||||
|
;; Debugging
|
||||||
|
dap-mode)
|
||||||
|
"List of packages for modern development mode.")
|
||||||
|
|
||||||
|
(defun dev-mode-modern-ensure-packages ()
|
||||||
|
"Ensure all modern development packages are installed."
|
||||||
|
(dolist (package dev-mode-modern-packages)
|
||||||
|
(unless (or (package-installed-p package)
|
||||||
|
(and (eq package 'eglot) (fboundp 'eglot))) ; Eglot is built-in for Emacs 29+
|
||||||
|
(package-refresh-contents)
|
||||||
|
(package-install package))))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-eglot ()
|
||||||
|
"Setup Eglot for modern development."
|
||||||
|
;; Load eglot configuration
|
||||||
|
(require 'init-eglot)
|
||||||
|
|
||||||
|
;; Additional Eglot configuration for development
|
||||||
|
(with-eval-after-load 'eglot
|
||||||
|
;; Enable format on save for specific modes
|
||||||
|
(dolist (mode '(c-mode-hook c++-mode-hook python-mode-hook))
|
||||||
|
(add-hook mode #'eglot-format-buffer-on-save))
|
||||||
|
|
||||||
|
;; Configure Consult-Eglot if available
|
||||||
|
(when (fboundp 'consult-eglot-symbols)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l s") 'consult-eglot-symbols))))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-completion ()
|
||||||
|
"Setup modern completion with Corfu."
|
||||||
|
;; Corfu is already configured in init-completion.el
|
||||||
|
;; Add development-specific configurations here
|
||||||
|
(with-eval-after-load 'corfu
|
||||||
|
;; More aggressive completion in programming modes
|
||||||
|
(add-hook 'prog-mode-hook
|
||||||
|
(lambda ()
|
||||||
|
(setq-local corfu-auto-delay 0.1)
|
||||||
|
(setq-local corfu-auto-prefix 1)))))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-yasnippet ()
|
||||||
|
"Configure yasnippet for code snippets."
|
||||||
|
(use-package yasnippet
|
||||||
|
:ensure t
|
||||||
|
:config
|
||||||
|
(yas-global-mode 1)
|
||||||
|
;; Load snippets from the snippets directory if it exists
|
||||||
|
(let ((snippets-dir (expand-file-name "snippets" user-emacs-directory)))
|
||||||
|
(when (file-directory-p snippets-dir)
|
||||||
|
(add-to-list 'yas-snippet-dirs snippets-dir)))))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-flycheck ()
|
||||||
|
"Configure Flycheck alongside Flymake."
|
||||||
|
(use-package flycheck
|
||||||
|
:ensure t
|
||||||
|
:init
|
||||||
|
;; Use Flycheck for modes not well-supported by Flymake
|
||||||
|
(add-hook 'sh-mode-hook 'flycheck-mode)
|
||||||
|
(add-hook 'json-mode-hook 'flycheck-mode)
|
||||||
|
(add-hook 'yaml-mode-hook 'flycheck-mode)
|
||||||
|
:config
|
||||||
|
(setq flycheck-display-errors-delay 0.3)))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-projectile ()
|
||||||
|
"Configure projectile for project management."
|
||||||
|
;; Already configured in init-project.el
|
||||||
|
;; Add development-specific configurations here
|
||||||
|
(with-eval-after-load 'projectile
|
||||||
|
(define-key projectile-command-map (kbd "t") 'projectile-test-project)
|
||||||
|
(define-key projectile-command-map (kbd "c") 'projectile-compile-project)))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-magit ()
|
||||||
|
"Configure Magit for version control."
|
||||||
|
(use-package magit
|
||||||
|
:ensure t
|
||||||
|
:bind (("C-x g" . magit-status)
|
||||||
|
("C-x M-g" . magit-dispatch)
|
||||||
|
("C-c g" . magit-file-dispatch))
|
||||||
|
:config
|
||||||
|
(setq magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1))
|
||||||
|
|
||||||
|
;; Forge for GitHub/GitLab integration
|
||||||
|
(use-package forge
|
||||||
|
:ensure t
|
||||||
|
:after magit)
|
||||||
|
|
||||||
|
;; Magit-delta for better diffs (if delta is installed)
|
||||||
|
(when (executable-find "delta")
|
||||||
|
(use-package magit-delta
|
||||||
|
:ensure t
|
||||||
|
:hook (magit-mode . magit-delta-mode))))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-debugging ()
|
||||||
|
"Configure debugging with dap-mode."
|
||||||
|
(use-package dap-mode
|
||||||
|
:ensure t
|
||||||
|
:commands dap-debug
|
||||||
|
:config
|
||||||
|
;; Python debugging
|
||||||
|
(require 'dap-python)
|
||||||
|
;; C/C++ debugging
|
||||||
|
(require 'dap-gdb-lldb)
|
||||||
|
;; Automatic configuration
|
||||||
|
(dap-auto-configure-mode 1)))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-languages ()
|
||||||
|
"Configure language-specific settings."
|
||||||
|
;; C/C++ formatting
|
||||||
|
(use-package clang-format
|
||||||
|
:ensure t
|
||||||
|
:bind (:map c-mode-map
|
||||||
|
("C-c C-f" . clang-format-buffer)
|
||||||
|
:map c++-mode-map
|
||||||
|
("C-c C-f" . clang-format-buffer)))
|
||||||
|
|
||||||
|
;; QML support
|
||||||
|
(use-package qml-mode
|
||||||
|
:ensure t
|
||||||
|
:mode "\\.qml\\'"
|
||||||
|
:hook (qml-mode . eglot-ensure)))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-editing-tools ()
|
||||||
|
"Setup advanced editing tools for development."
|
||||||
|
;; These are now in init-qol.el, but we can add dev-specific configs
|
||||||
|
(with-eval-after-load 'hl-todo
|
||||||
|
(add-hook 'prog-mode-hook #'hl-todo-mode))
|
||||||
|
|
||||||
|
(with-eval-after-load 'rainbow-delimiters
|
||||||
|
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode))
|
||||||
|
|
||||||
|
;; Origami for code folding
|
||||||
|
(use-package origami
|
||||||
|
:ensure t
|
||||||
|
:hook (prog-mode . origami-mode)
|
||||||
|
:bind (:map origami-mode-map
|
||||||
|
("C-c f f" . origami-toggle-node)
|
||||||
|
("C-c f o" . origami-open-node)
|
||||||
|
("C-c f c" . origami-close-node)
|
||||||
|
("C-c f a" . origami-close-all-nodes)
|
||||||
|
("C-c f A" . origami-open-all-nodes))))
|
||||||
|
|
||||||
|
(defun dev-mode-modern-setup-keybindings ()
|
||||||
|
"Setup development-specific keybindings."
|
||||||
|
;; Compile commands
|
||||||
|
(global-set-key (kbd "<f5>") 'compile)
|
||||||
|
(global-set-key (kbd "<f6>") 'recompile)
|
||||||
|
|
||||||
|
;; Testing
|
||||||
|
(global-set-key (kbd "C-c t p") 'projectile-test-project)
|
||||||
|
(global-set-key (kbd "C-c t f") 'projectile-test-file)
|
||||||
|
|
||||||
|
;; Navigation
|
||||||
|
(global-set-key (kbd "M-.") 'xref-find-definitions)
|
||||||
|
(global-set-key (kbd "M-,") 'xref-pop-marker-stack)
|
||||||
|
(global-set-key (kbd "M-?") 'xref-find-references))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun enable-dev-mode-modern ()
|
||||||
|
"Enable modern development mode with Eglot and other tools."
|
||||||
|
(interactive)
|
||||||
|
(if dev-mode-modern-enabled
|
||||||
|
(message "Modern development mode is already enabled")
|
||||||
|
(message "Enabling modern development mode...")
|
||||||
|
;; Ensure packages are installed
|
||||||
|
(dev-mode-modern-ensure-packages)
|
||||||
|
;; Set up all development features
|
||||||
|
(dev-mode-modern-setup-eglot)
|
||||||
|
(dev-mode-modern-setup-completion)
|
||||||
|
(dev-mode-modern-setup-yasnippet)
|
||||||
|
(dev-mode-modern-setup-flycheck)
|
||||||
|
(dev-mode-modern-setup-projectile)
|
||||||
|
(dev-mode-modern-setup-magit)
|
||||||
|
(dev-mode-modern-setup-debugging)
|
||||||
|
(dev-mode-modern-setup-languages)
|
||||||
|
(dev-mode-modern-setup-editing-tools)
|
||||||
|
(dev-mode-modern-setup-keybindings)
|
||||||
|
;; Load tree-sitter if available
|
||||||
|
(when (file-exists-p (expand-file-name "lisp/init-treesitter.el" user-emacs-directory))
|
||||||
|
(require 'init-treesitter))
|
||||||
|
(setq dev-mode-modern-enabled t)
|
||||||
|
(message "Modern development mode enabled! Eglot will auto-start for supported files.")))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun disable-dev-mode-modern ()
|
||||||
|
"Disable modern development mode."
|
||||||
|
(interactive)
|
||||||
|
(if (not dev-mode-modern-enabled)
|
||||||
|
(message "Modern development mode is not enabled")
|
||||||
|
(message "Disabling modern development mode...")
|
||||||
|
;; Shutdown all Eglot servers
|
||||||
|
(when (fboundp 'eglot-shutdown-all)
|
||||||
|
(eglot-shutdown-all))
|
||||||
|
;; Disable some modes
|
||||||
|
(yas-global-mode -1)
|
||||||
|
(global-flycheck-mode -1)
|
||||||
|
(setq dev-mode-modern-enabled nil)
|
||||||
|
(message "Modern development mode disabled.")))
|
||||||
|
|
||||||
|
(provide 'emacs-dev-config-modern)
|
||||||
|
;;; emacs-dev-config-modern.el ends here
|
||||||
@@ -359,11 +359,20 @@
|
|||||||
(message "Patch saved to %s" file)
|
(message "Patch saved to %s" file)
|
||||||
(error "Failed to save patch"))))
|
(error "Failed to save patch"))))
|
||||||
|
|
||||||
|
;; Set up keybindings for saving patches
|
||||||
(with-eval-after-load 'magit
|
(with-eval-after-load 'magit
|
||||||
(define-key magit-revision-mode-map (kbd "C-c C-p") 'magit-save-commit-as-patch)
|
(define-key magit-revision-mode-map (kbd "C-c C-p") 'magit-save-commit-as-patch)
|
||||||
(define-key magit-log-mode-map (kbd "C-c C-p") 'magit-save-commit-as-patch)
|
(define-key magit-log-mode-map (kbd "C-c C-p") 'magit-save-commit-as-patch)
|
||||||
(define-key magit-log-select-mode-map (kbd "C-c C-p") 'magit-save-commit-as-patch))
|
(define-key magit-log-select-mode-map (kbd "C-c C-p") 'magit-save-commit-as-patch))
|
||||||
|
|
||||||
|
;; Also set up hooks to ensure keybindings are available
|
||||||
|
(add-hook 'magit-revision-mode-hook
|
||||||
|
(lambda () (local-set-key (kbd "C-c C-p") 'magit-save-commit-as-patch)))
|
||||||
|
(add-hook 'magit-log-mode-hook
|
||||||
|
(lambda () (local-set-key (kbd "C-c C-p") 'magit-save-commit-as-patch)))
|
||||||
|
(add-hook 'magit-log-select-mode-hook
|
||||||
|
(lambda () (local-set-key (kbd "C-c C-p") 'magit-save-commit-as-patch)))
|
||||||
|
|
||||||
;; Optional: Integrate diff-hl with Magit when both are available
|
;; Optional: Integrate diff-hl with Magit when both are available
|
||||||
;; Only enable if you want Magit to control diff-hl updates
|
;; Only enable if you want Magit to control diff-hl updates
|
||||||
;; Comment out these lines if diff-hl has issues with Magit
|
;; Comment out these lines if diff-hl has issues with Magit
|
||||||
|
|||||||
@@ -15,11 +15,13 @@
|
|||||||
("C-x C-3" . split-window-right)
|
("C-x C-3" . split-window-right)
|
||||||
("C-x C-0" . delete-window))
|
("C-x C-0" . delete-window))
|
||||||
:config
|
:config
|
||||||
;; Define keybindings after god-mode is loaded
|
;; Define keybindings after god-mode is loaded and map exists
|
||||||
|
(with-eval-after-load 'god-mode
|
||||||
|
(when (boundp 'god-local-mode-map)
|
||||||
(define-key god-local-mode-map (kbd ".") 'repeat)
|
(define-key god-local-mode-map (kbd ".") 'repeat)
|
||||||
(define-key god-local-mode-map (kbd "[") 'backward-paragraph)
|
(define-key god-local-mode-map (kbd "[") 'backward-paragraph)
|
||||||
(define-key god-local-mode-map (kbd "]") 'forward-paragraph)
|
(define-key god-local-mode-map (kbd "]") 'forward-paragraph)
|
||||||
(define-key god-local-mode-map (kbd "i") 'god-mode-all)
|
(define-key god-local-mode-map (kbd "i") 'god-mode-all)))
|
||||||
;; Update cursor to indicate god-mode state
|
;; Update cursor to indicate god-mode state
|
||||||
(defun god-mode-update-cursor ()
|
(defun god-mode-update-cursor ()
|
||||||
"Update cursor style based on god-mode state."
|
"Update cursor style based on god-mode state."
|
||||||
|
|||||||
892
init.el
892
init.el
@@ -1,767 +1,67 @@
|
|||||||
;;; -*- lexical-binding: t -*-
|
;;; init.el --- Main Emacs configuration file -*- lexical-binding: t -*-
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
;;; This is the main configuration file that loads all modular configuration files.
|
||||||
|
;;; The configuration has been split into logical modules for better organization
|
||||||
|
;;; and maintainability.
|
||||||
|
|
||||||
;;; Improved Emacs Configuration
|
;;; Code:
|
||||||
;;; Keeping: treemacs, helm, diff-hl, magit
|
|
||||||
|
|
||||||
;;; Package Management - Consolidated
|
;; Add lisp subdirectory to load path (avoids load-path warning)
|
||||||
(require 'package)
|
(add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
|
||||||
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
|
|
||||||
(package-initialize)
|
|
||||||
|
|
||||||
;; Core package list - consolidated and cleaned
|
;; EMERGENCY FIX - Load this first to ensure editing works
|
||||||
(setq package-selected-packages
|
(require 'init-emergency-fix)
|
||||||
'(;; Core utilities
|
|
||||||
use-package which-key
|
|
||||||
|
|
||||||
;; Themes
|
;;; Load core modules in order
|
||||||
modus-themes
|
(require 'init-core) ; Core settings and package management
|
||||||
|
(require 'init-completion); Modern completion with Vertico, Consult, etc.
|
||||||
|
(require 'init-ui) ; UI and theme configurations
|
||||||
|
(require 'init-editor) ; Basic editor enhancements
|
||||||
|
(require 'init-project) ; Project management with projectile
|
||||||
|
(require 'init-vcs) ; Version control (diff-hl)
|
||||||
|
(require 'init-search) ; Search tools
|
||||||
|
(require 'init-dired) ; Dired configuration
|
||||||
|
(require 'init-treemacs) ; Treemacs file browser
|
||||||
|
(require 'init-markdown) ; Markdown support
|
||||||
|
(require 'init-utils) ; Utility functions
|
||||||
|
(require 'init-keybindings); Global keybindings
|
||||||
|
(require 'init-compile) ; Byte compilation utilities
|
||||||
|
(require 'init-qol) ; Quality of life improvements
|
||||||
|
(require 'init-treesitter); Tree-sitter support for Emacs 29+
|
||||||
|
(require 'init-eglot) ; Built-in LSP client
|
||||||
|
(require 'init-eslint-fix); Fix ESLint configuration issues
|
||||||
|
(require 'init-terminal) ; Terminal emulator configuration
|
||||||
|
|
||||||
;; Version control
|
;;; Load optional configurations
|
||||||
diff-hl
|
|
||||||
|
|
||||||
;; File management
|
;; Development configuration - Modern version with Eglot
|
||||||
treemacs treemacs-projectile treemacs-all-the-icons
|
(let ((dev-config-modern (expand-file-name "emacs-dev-config-modern.el" user-emacs-directory)))
|
||||||
neotree all-the-icons all-the-icons-dired diredfl
|
(when (file-exists-p dev-config-modern)
|
||||||
|
(load-file dev-config-modern)
|
||||||
|
(add-hook 'emacs-startup-hook
|
||||||
|
(lambda ()
|
||||||
|
(run-with-timer 1 nil
|
||||||
|
(lambda ()
|
||||||
|
(message "Modern development mode available. Use M-x enable-dev-mode-modern to activate.")))))))
|
||||||
|
|
||||||
;; Helm ecosystem
|
;; Legacy development configuration (lsp-mode) - kept for compatibility
|
||||||
helm helm-xref helm-projectile
|
|
||||||
|
|
||||||
;; Core project management
|
|
||||||
projectile
|
|
||||||
|
|
||||||
;; Markdown & Notes
|
|
||||||
markdown-mode markdown-toc grip-mode
|
|
||||||
obsidian olivetti
|
|
||||||
|
|
||||||
;; Search and navigation
|
|
||||||
deadgrep ripgrep wgrep anzu
|
|
||||||
ibuffer-sidebar ibuffer-projectile
|
|
||||||
|
|
||||||
;; Required for some functionality
|
|
||||||
org dash s f ht spinner lv hydra avy
|
|
||||||
|
|
||||||
;; RSS/News reader
|
|
||||||
elfeed elfeed-org
|
|
||||||
|
|
||||||
;; Email (mu4e installed separately)
|
|
||||||
|
|
||||||
;; Finance tracking
|
|
||||||
beancount
|
|
||||||
))
|
|
||||||
|
|
||||||
;; Auto-install missing packages
|
|
||||||
(when (cl-find-if-not #'package-installed-p package-selected-packages)
|
|
||||||
(package-refresh-contents)
|
|
||||||
(mapc #'package-install package-selected-packages))
|
|
||||||
|
|
||||||
;; Ensure use-package is loaded
|
|
||||||
(eval-when-compile
|
|
||||||
(require 'use-package))
|
|
||||||
(setq use-package-always-ensure t)
|
|
||||||
|
|
||||||
;;; Custom Settings (preserved from original)
|
|
||||||
(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.
|
|
||||||
'(before-save-hook '(delete-trailing-whitespace))
|
|
||||||
'(column-number-mode t)
|
|
||||||
'(cua-mode t)
|
|
||||||
'(custom-enabled-themes '(developer-dark))
|
|
||||||
'(custom-safe-themes
|
|
||||||
'("2974c2d5ffede4f111b02701ccdfadfbcde3d158ad9b09dade627b3ce3049ea1"
|
|
||||||
"f8859f15bd0089a85d8d14e21dd774a9a8b391dac076e3ff17a13529b3d16576"
|
|
||||||
"de2f009a49f8eaf2f323519d86016849cd1716d979bc3f7e4afb58899e52ddb7"
|
|
||||||
"9fb69436c074b82a62b78b8d733e6274d0bd16d156f7b094e2afe4345c040c49"
|
|
||||||
"004f174754c688f358fa2afc4f8699b5db647fbfaa0d6b55ff39f63e05bfbbf5"
|
|
||||||
"ca1b398ceb1b61709197478dc7f705b8337a0a9631e399948e643520c5557382"
|
|
||||||
"75eef60308d7328ed14fa27002e85de255c2342e73275173a14ed3aa1643d545"
|
|
||||||
"77f281064ea1c8b14938866e21c4e51e4168e05db98863bd7430f1352cab294a"
|
|
||||||
"242e6f00c98aa43539b41c505ef094d21cbc981203809a82949efaa2bc6cb194"
|
|
||||||
"c9e63647d90e7dc59d52c176fbfd46fd2cfed275cd2bad9b29b6cf620d3389b6"
|
|
||||||
"ad7d874d137291e09fe2963babc33d381d087fa14928cb9d34350b67b6556b6d"
|
|
||||||
default))
|
|
||||||
'(diff-hl-global-modes t)
|
|
||||||
'(display-line-numbers t)
|
|
||||||
'(display-line-numbers-type 'relative)
|
|
||||||
'(global-display-line-numbers-mode t)
|
|
||||||
'(ls-lisp-dirs-first t)
|
|
||||||
'(neo-show-hidden-files t)
|
|
||||||
'(neo-window-width 40)
|
|
||||||
'(package-selected-packages
|
|
||||||
'(all-the-icons all-the-icons-dired anzu avy clang-format
|
|
||||||
clang-format+ commenter company company-box
|
|
||||||
company-qml cyberpunk-theme dap-mode dash deadgrep
|
|
||||||
diff-hl diredfl expand-region f flycheck ggtags
|
|
||||||
god-mode grip-mode helm helm-lsp helm-projectile
|
|
||||||
helm-xref hl-todo ht hydra ibuffer-projectile
|
|
||||||
ibuffer-sidebar lsp-mode lsp-treemacs lsp-ui lv
|
|
||||||
magit magit-delta markdown-mode markdown-toc
|
|
||||||
modus-themes multiple-cursors neotree obsidian
|
|
||||||
olivetti org origami projectile qml-mode
|
|
||||||
rainbow-delimiters ripgrep s spinner treemacs
|
|
||||||
treemacs-all-the-icons treemacs-magit
|
|
||||||
treemacs-projectile use-package wgrep which-key
|
|
||||||
yasnippet))
|
|
||||||
'(ring-bell-function 'ignore)
|
|
||||||
'(safe-local-variable-values
|
|
||||||
'((company-backends
|
|
||||||
(company-qml company-capf company-files company-yasnippet))
|
|
||||||
(lsp-clients-qml-server-executable . "/usr/lib/qt6/bin/qmlls")
|
|
||||||
(company-minimum-prefix-length . 1) (company-idle-delay . 0.2)
|
|
||||||
(lsp-clangd-binary-path . "clangd")
|
|
||||||
(lsp-clients-clangd-args
|
|
||||||
"--compile-commands-dir=/home/jens/sources/thulio"
|
|
||||||
"--background-index" "--clang-tidy"
|
|
||||||
"--completion-style=detailed" "--header-insertion=iwyu"
|
|
||||||
"--pch-storage=memory")
|
|
||||||
(projectile-project-root . "/home/jens/sources/thulio")))
|
|
||||||
'(save-place-mode t)
|
|
||||||
'(show-trailing-whitespace t)
|
|
||||||
'(tool-bar-mode nil)
|
|
||||||
'(url-proxy-services
|
|
||||||
'(("https" . "eudewerepo001:3128") ("http" . "eudewerepo001:3128"))))
|
|
||||||
|
|
||||||
(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.
|
|
||||||
'(default ((t (:family "0xProto Nerd Font Mono" :foundry "nil" :slant normal :weight regular :height 140 :width normal))))
|
|
||||||
'(diff-hl-change ((t (:background "blue3" :foreground "blue3"))))
|
|
||||||
'(diff-hl-delete ((t (:background "red3" :foreground "red3"))))
|
|
||||||
'(diff-hl-insert ((t (:background "green3" :foreground "green3")))))
|
|
||||||
|
|
||||||
;;; Helm Configuration (Primary interface)
|
|
||||||
(use-package helm
|
|
||||||
:ensure t
|
|
||||||
:demand t
|
|
||||||
:bind (("M-x" . helm-M-x)
|
|
||||||
("C-x C-f" . helm-find-files)
|
|
||||||
("C-x b" . helm-buffers-list)
|
|
||||||
("C-x r b" . helm-bookmarks)
|
|
||||||
("M-y" . helm-show-kill-ring)
|
|
||||||
("C-h SPC" . helm-all-mark-rings))
|
|
||||||
:config
|
|
||||||
(helm-mode 1)
|
|
||||||
(setq helm-split-window-in-side-p t
|
|
||||||
helm-move-to-line-cycle-in-source t
|
|
||||||
helm-ff-search-library-in-sexp t
|
|
||||||
helm-scroll-amount 8
|
|
||||||
helm-ff-file-name-history-use-recentf t
|
|
||||||
helm-echo-input-in-header-line t)
|
|
||||||
;; Make helm more responsive
|
|
||||||
(setq helm-input-idle-delay 0.01
|
|
||||||
helm-cycle-resume-delay 2
|
|
||||||
helm-follow-input-idle-delay 0.01)
|
|
||||||
;; Prevent helm from opening new frames
|
|
||||||
(setq helm-always-two-windows nil)
|
|
||||||
(setq helm-display-buffer-default-height 15)
|
|
||||||
(setq helm-default-display-buffer-functions '(display-buffer-in-side-window)))
|
|
||||||
|
|
||||||
(use-package helm-xref
|
|
||||||
:ensure t
|
|
||||||
:after helm)
|
|
||||||
|
|
||||||
(use-package helm-projectile
|
|
||||||
:ensure t
|
|
||||||
:after (helm projectile)
|
|
||||||
:config
|
|
||||||
(helm-projectile-on)
|
|
||||||
;; Prevent helm-projectile from opening new frames
|
|
||||||
(setq helm-projectile-sources-list
|
|
||||||
'(helm-source-projectile-buffers-list
|
|
||||||
helm-source-projectile-recentf-list
|
|
||||||
helm-source-projectile-files-list
|
|
||||||
helm-source-projectile-projects))
|
|
||||||
;; Use current window for file actions
|
|
||||||
(setq helm-display-function 'helm-default-display-buffer))
|
|
||||||
|
|
||||||
;;; Load development configuration (optional - use M-x enable-dev-mode)
|
|
||||||
(let ((dev-config (expand-file-name "emacs-dev-config.el" user-emacs-directory)))
|
(let ((dev-config (expand-file-name "emacs-dev-config.el" user-emacs-directory)))
|
||||||
(when (file-exists-p dev-config)
|
(when (file-exists-p dev-config)
|
||||||
(load-file dev-config)))
|
(load-file dev-config)))
|
||||||
|
|
||||||
;;; Version Control (basic) - Magit moved to development mode
|
;; SHR Configuration (for HTML rendering in mu4e, elfeed, eww)
|
||||||
|
|
||||||
;;; Diff-hl Configuration
|
|
||||||
(use-package diff-hl
|
|
||||||
:ensure t
|
|
||||||
:hook ((prog-mode . diff-hl-mode)
|
|
||||||
(dired-mode . diff-hl-dired-mode)
|
|
||||||
(text-mode . diff-hl-mode)
|
|
||||||
(conf-mode . diff-hl-mode))
|
|
||||||
:bind (("M-n" . diff-hl-next-hunk)
|
|
||||||
("M-p" . diff-hl-previous-hunk)
|
|
||||||
("C-c v r" . diff-hl-revert-hunk)
|
|
||||||
("C-c v s" . diff-hl-diff-goto-hunk)
|
|
||||||
("C-c v u" . diff-hl-refresh))
|
|
||||||
:init
|
|
||||||
;; Set fringe width before diff-hl loads
|
|
||||||
(setq-default left-fringe-width 8)
|
|
||||||
(setq-default right-fringe-width 8)
|
|
||||||
;; Ensure fringes are visible
|
|
||||||
(fringe-mode 8)
|
|
||||||
:config
|
|
||||||
;; Configure VC backend for Git
|
|
||||||
(setq vc-handled-backends '(Git))
|
|
||||||
(setq vc-git-diff-switches '("--histogram"))
|
|
||||||
|
|
||||||
;; IMPORTANT: Tell diff-hl to use VC backend, not Magit
|
|
||||||
(setq diff-hl-reference-revision nil) ; Use working tree, not index
|
|
||||||
(setq diff-hl-disable-on-remote nil) ; Work even on remote files
|
|
||||||
|
|
||||||
;; Make diff-hl use the left fringe
|
|
||||||
(setq diff-hl-side 'left)
|
|
||||||
|
|
||||||
;; Ensure diff-hl draws in fringe, not margin
|
|
||||||
(setq diff-hl-draw-borders nil)
|
|
||||||
(setq diff-hl-margin-mode nil)
|
|
||||||
|
|
||||||
;; Set diff-hl fringe bitmaps (ensure they're visible)
|
|
||||||
(setq diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-type)
|
|
||||||
|
|
||||||
;; Enable flydiff for real-time updates using VC
|
|
||||||
(diff-hl-flydiff-mode 1)
|
|
||||||
|
|
||||||
;; Update immediately when visiting a file
|
|
||||||
(setq diff-hl-flydiff-delay 0.3)
|
|
||||||
|
|
||||||
;; Make sure diff-hl updates on various events
|
|
||||||
(add-hook 'after-save-hook 'diff-hl-update)
|
|
||||||
(add-hook 'after-revert-hook 'diff-hl-update)
|
|
||||||
(add-hook 'find-file-hook 'diff-hl-update)
|
|
||||||
(add-hook 'vc-checkin-hook 'diff-hl-update)
|
|
||||||
|
|
||||||
;; Enable globally
|
|
||||||
(global-diff-hl-mode 1)
|
|
||||||
|
|
||||||
;; Explicitly disable Magit integration in base config
|
|
||||||
;; (Magit hooks will only be added when dev-mode is enabled)
|
|
||||||
(setq diff-hl-disable-on-remote nil)
|
|
||||||
|
|
||||||
;; Manual refresh command
|
|
||||||
(defun diff-hl-refresh ()
|
|
||||||
"Manually refresh diff-hl indicators in all buffers."
|
|
||||||
(interactive)
|
|
||||||
(dolist (buf (buffer-list))
|
|
||||||
(with-current-buffer buf
|
|
||||||
(when diff-hl-mode
|
|
||||||
(diff-hl-update)))))
|
|
||||||
|
|
||||||
;; Troubleshooting function
|
|
||||||
(defun diff-hl-diagnose ()
|
|
||||||
"Diagnose diff-hl issues."
|
|
||||||
(interactive)
|
|
||||||
(let ((diagnosis '()))
|
|
||||||
(push (format "diff-hl-mode: %s" (if diff-hl-mode "enabled" "disabled")) diagnosis)
|
|
||||||
(push (format "Buffer file: %s" (or buffer-file-name "none")) diagnosis)
|
|
||||||
(push (format "VC backend: %s" (or (vc-backend buffer-file-name) "none")) diagnosis)
|
|
||||||
(push (format "VC responsible backend: %s" (or (vc-responsible-backend default-directory) "none")) diagnosis)
|
|
||||||
(push (format "Modified: %s" (if (and buffer-file-name (buffer-modified-p)) "yes" "no")) diagnosis)
|
|
||||||
(push (format "VC state: %s" (when buffer-file-name (vc-state buffer-file-name))) diagnosis)
|
|
||||||
(push (format "Left fringe width: %s" left-fringe-width) diagnosis)
|
|
||||||
(push (format "Right fringe width: %s" right-fringe-width) diagnosis)
|
|
||||||
(push (format "diff-hl-side: %s" diff-hl-side) diagnosis)
|
|
||||||
(push (format "diff-hl-margin-mode: %s" diff-hl-margin-mode) diagnosis)
|
|
||||||
(push (format "diff-hl-reference-revision: %s" diff-hl-reference-revision) diagnosis)
|
|
||||||
(push (format "Magit loaded: %s" (if (fboundp 'magit-status) "yes" "no")) diagnosis)
|
|
||||||
(message (mapconcat 'identity (nreverse diagnosis) "\n"))))
|
|
||||||
|
|
||||||
;; Force VC to refresh its state
|
|
||||||
(defun diff-hl-force-vc-refresh ()
|
|
||||||
"Force VC to refresh state and then update diff-hl."
|
|
||||||
(interactive)
|
|
||||||
(when buffer-file-name
|
|
||||||
(vc-refresh-state)
|
|
||||||
(diff-hl-update)
|
|
||||||
(message "VC state refreshed and diff-hl updated")))
|
|
||||||
|
|
||||||
;; Disable Magit integration if causing issues
|
|
||||||
(defun diff-hl-disable-magit ()
|
|
||||||
"Disable Magit integration with diff-hl."
|
|
||||||
(interactive)
|
|
||||||
(setq diff-hl-disable-magit-integration t)
|
|
||||||
(remove-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
|
|
||||||
(remove-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)
|
|
||||||
(message "Magit integration with diff-hl disabled. Using pure VC backend."))
|
|
||||||
|
|
||||||
;; Ensure we're using VC backend
|
|
||||||
(defun diff-hl-ensure-vc-backend ()
|
|
||||||
"Ensure diff-hl is using VC backend."
|
|
||||||
(interactive)
|
|
||||||
(setq diff-hl-reference-revision nil)
|
|
||||||
(diff-hl-disable-magit)
|
|
||||||
(diff-hl-refresh)
|
|
||||||
(message "diff-hl configured to use VC backend only")))
|
|
||||||
|
|
||||||
;;; Treemacs Configuration
|
|
||||||
(use-package treemacs
|
|
||||||
:ensure t
|
|
||||||
:defer t
|
|
||||||
:bind (("M-0" . treemacs-select-window)
|
|
||||||
("C-x t t" . treemacs)
|
|
||||||
("C-x t 1" . treemacs-delete-other-windows)
|
|
||||||
("C-x t d" . treemacs-select-directory)
|
|
||||||
("C-x t B" . treemacs-bookmark)
|
|
||||||
("<f8>" . treemacs)
|
|
||||||
:map treemacs-mode-map
|
|
||||||
("/" . treemacs-search-file)
|
|
||||||
("C-s" . helm-projectile-find-file)
|
|
||||||
("s" . helm-projectile-grep))
|
|
||||||
:config
|
|
||||||
(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-follow-delay 0.2
|
|
||||||
treemacs-follow-after-init t
|
|
||||||
treemacs-expand-after-init t
|
|
||||||
treemacs-find-workspace-method 'find-for-file-or-pick-first
|
|
||||||
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-delete-other-windows t
|
|
||||||
treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
|
|
||||||
treemacs-position 'left
|
|
||||||
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-show-cursor nil
|
|
||||||
treemacs-show-hidden-files t
|
|
||||||
treemacs-silent-filewatch nil
|
|
||||||
treemacs-silent-refresh nil
|
|
||||||
treemacs-sorting 'alphabetic-asc
|
|
||||||
treemacs-space-between-root-nodes t
|
|
||||||
treemacs-tag-follow-cleanup t
|
|
||||||
treemacs-tag-follow-delay 1.5
|
|
||||||
treemacs-width 35
|
|
||||||
treemacs-width-is-initially-locked t
|
|
||||||
treemacs-workspace-switch-cleanup nil)
|
|
||||||
|
|
||||||
(treemacs-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))
|
|
||||||
|
|
||||||
(use-package treemacs-projectile
|
|
||||||
:ensure t
|
|
||||||
:after (treemacs projectile))
|
|
||||||
|
|
||||||
(use-package treemacs-all-the-icons
|
|
||||||
:ensure t
|
|
||||||
:after (treemacs all-the-icons)
|
|
||||||
:config
|
|
||||||
(treemacs-load-theme "all-the-icons"))
|
|
||||||
|
|
||||||
;; Treemacs helper functions
|
|
||||||
(defun treemacs-toggle-and-focus ()
|
|
||||||
"Toggle treemacs and focus on it if it's visible."
|
|
||||||
(interactive)
|
|
||||||
(if (treemacs-get-local-window)
|
|
||||||
(treemacs-toggle)
|
|
||||||
(progn
|
|
||||||
(treemacs)
|
|
||||||
(treemacs-select-window))))
|
|
||||||
|
|
||||||
(defun treemacs-search-file ()
|
|
||||||
"Search for a file in the current project using helm."
|
|
||||||
(interactive)
|
|
||||||
(if (fboundp 'helm-projectile-find-file)
|
|
||||||
(helm-projectile-find-file)
|
|
||||||
(helm-find-files)))
|
|
||||||
|
|
||||||
(defun treemacs-open-marked-files ()
|
|
||||||
"Open all marked files in treemacs."
|
|
||||||
(interactive)
|
|
||||||
(when (eq major-mode 'treemacs-mode)
|
|
||||||
(treemacs-bulk-file-actions
|
|
||||||
:actions '(treemacs-visit-node-no-split))))
|
|
||||||
|
|
||||||
(defun treemacs-mark-visible-files ()
|
|
||||||
"Mark all visible files in the current directory."
|
|
||||||
(interactive)
|
|
||||||
(when (eq major-mode 'treemacs-mode)
|
|
||||||
(save-excursion
|
|
||||||
(treemacs-goto-parent-node)
|
|
||||||
(treemacs-TAB-action)
|
|
||||||
(forward-line 1)
|
|
||||||
(while (and (not (eobp))
|
|
||||||
(> (treemacs--get-depth-of-item) 0))
|
|
||||||
(when (treemacs-is-node-file?)
|
|
||||||
(treemacs-do-mark))
|
|
||||||
(forward-line 1)))))
|
|
||||||
|
|
||||||
(global-set-key (kbd "C-c t f") 'treemacs-toggle-and-focus)
|
|
||||||
(global-set-key (kbd "C-c t s") 'treemacs-search-file)
|
|
||||||
|
|
||||||
;;; Search Configuration (with Helm)
|
|
||||||
(use-package deadgrep
|
|
||||||
:ensure t
|
|
||||||
:bind (("C-c r" . deadgrep)))
|
|
||||||
|
|
||||||
(use-package wgrep
|
|
||||||
:ensure t
|
|
||||||
:config
|
|
||||||
(setq wgrep-auto-save-buffer t)
|
|
||||||
(setq wgrep-enable-key "r"))
|
|
||||||
|
|
||||||
(use-package anzu
|
|
||||||
:ensure t
|
|
||||||
:config
|
|
||||||
(global-anzu-mode 1)
|
|
||||||
:bind (([remap query-replace] . anzu-query-replace)
|
|
||||||
([remap query-replace-regexp] . anzu-query-replace-regexp)))
|
|
||||||
|
|
||||||
;;; Project Management
|
|
||||||
(use-package projectile
|
|
||||||
:ensure t
|
|
||||||
:init
|
|
||||||
(projectile-mode +1)
|
|
||||||
:bind-keymap ("C-c p" . projectile-command-map)
|
|
||||||
:config
|
|
||||||
(setq projectile-completion-system 'helm)
|
|
||||||
(setq projectile-switch-project-action #'projectile-dired))
|
|
||||||
|
|
||||||
;;; Development Tools - Moved to emacs-dev-config.el
|
|
||||||
;;; Use M-x enable-dev-mode to activate development features
|
|
||||||
|
|
||||||
;;; Editor Enhancements
|
|
||||||
(use-package which-key
|
|
||||||
:ensure t
|
|
||||||
:init (which-key-mode)
|
|
||||||
:config
|
|
||||||
(setq which-key-idle-delay 0.3)
|
|
||||||
(setq which-key-popup-type 'side-window))
|
|
||||||
|
|
||||||
;;; Editor Enhancements - Development-specific features moved to emacs-dev-config.el
|
|
||||||
|
|
||||||
(use-package all-the-icons-dired
|
|
||||||
:ensure t
|
|
||||||
:hook (dired-mode . all-the-icons-dired-mode))
|
|
||||||
|
|
||||||
(use-package diredfl
|
|
||||||
:ensure t
|
|
||||||
:config (diredfl-global-mode 1))
|
|
||||||
|
|
||||||
;; Enhanced Dired configuration for multi-file operations
|
|
||||||
(use-package dired
|
|
||||||
:ensure nil
|
|
||||||
:bind (("C-c d" . dired-jump)
|
|
||||||
("C-c D" . projectile-dired))
|
|
||||||
:config
|
|
||||||
(setq dired-dwim-target t) ; Guess target directory
|
|
||||||
(setq dired-recursive-copies 'always)
|
|
||||||
(setq dired-recursive-deletes 'always)
|
|
||||||
;; Use macOS-compatible ls options (no --group-directories-first)
|
|
||||||
(setq dired-listing-switches "-alh")
|
|
||||||
|
|
||||||
;; Enable multiple file marking with mouse
|
|
||||||
(define-key dired-mode-map (kbd "<mouse-2>") 'dired-find-file)
|
|
||||||
(define-key dired-mode-map (kbd "C-<mouse-1>") 'dired-mouse-mark)
|
|
||||||
|
|
||||||
;; Quick marking shortcuts
|
|
||||||
(define-key dired-mode-map (kbd "* .") 'dired-mark-extension)
|
|
||||||
(define-key dired-mode-map (kbd "* /") 'dired-mark-directories))
|
|
||||||
|
|
||||||
;; Custom sorting: directories first (dotted first), then files (dotted first)
|
|
||||||
(defun dired-sort-dotfiles-first ()
|
|
||||||
"Sort dired: dirs first (dots first within), then files (dots first within)."
|
|
||||||
(save-excursion
|
|
||||||
(let (buffer-read-only)
|
|
||||||
(goto-char (point-min))
|
|
||||||
;; Skip past the directory header
|
|
||||||
(while (and (not (eobp))
|
|
||||||
(not (looking-at "^ \\|^\\s-*$")))
|
|
||||||
(forward-line 1))
|
|
||||||
(let ((start (point))
|
|
||||||
dirs dotdirs files dotfiles special-entries)
|
|
||||||
;; Collect all entries
|
|
||||||
(while (not (eobp))
|
|
||||||
(when (looking-at "^ \\(.*\\)$")
|
|
||||||
(let* ((line (match-string 0))
|
|
||||||
(filename (ignore-errors (dired-get-filename 'no-dir t))))
|
|
||||||
(cond
|
|
||||||
;; Keep . and .. entries separate to put at top
|
|
||||||
((member filename '("." ".."))
|
|
||||||
(push line special-entries))
|
|
||||||
;; Process other entries
|
|
||||||
(filename
|
|
||||||
(let ((fullpath (ignore-errors (dired-get-filename t))))
|
|
||||||
(when fullpath
|
|
||||||
(cond
|
|
||||||
;; Dot directory
|
|
||||||
((and (file-directory-p fullpath)
|
|
||||||
(string-prefix-p "." filename))
|
|
||||||
(push line dotdirs))
|
|
||||||
;; Regular directory
|
|
||||||
((file-directory-p fullpath)
|
|
||||||
(push line dirs))
|
|
||||||
;; Dotfile
|
|
||||||
((string-prefix-p "." filename)
|
|
||||||
(push line dotfiles))
|
|
||||||
;; Regular file
|
|
||||||
(t
|
|
||||||
(push line files)))))))))
|
|
||||||
(forward-line 1))
|
|
||||||
;; Delete old content and insert sorted
|
|
||||||
(when (or special-entries dirs dotdirs files dotfiles)
|
|
||||||
(delete-region start (point-max))
|
|
||||||
(goto-char start)
|
|
||||||
;; Insert in order: . and .., dot dirs, regular dirs, dotfiles, regular files
|
|
||||||
(dolist (line (nreverse special-entries))
|
|
||||||
(insert line "\n"))
|
|
||||||
(dolist (line (sort (nreverse dotdirs) 'string<))
|
|
||||||
(insert line "\n"))
|
|
||||||
(dolist (line (sort (nreverse dirs) 'string<))
|
|
||||||
(insert line "\n"))
|
|
||||||
(dolist (line (sort (nreverse dotfiles) 'string<))
|
|
||||||
(insert line "\n"))
|
|
||||||
(dolist (line (sort (nreverse files) 'string<))
|
|
||||||
(insert line "\n")))))
|
|
||||||
(set-buffer-modified-p nil)))
|
|
||||||
|
|
||||||
;; Apply custom sorting after dired reads directory
|
|
||||||
(add-hook 'dired-after-readin-hook 'dired-sort-dotfiles-first)
|
|
||||||
|
|
||||||
;;; Markdown Support
|
|
||||||
(use-package markdown-mode
|
|
||||||
:ensure t
|
|
||||||
:mode (("\\.md\\'" . markdown-mode)
|
|
||||||
("\\.markdown\\'" . markdown-mode))
|
|
||||||
:hook (markdown-mode . (lambda ()
|
|
||||||
(visual-line-mode 1)
|
|
||||||
(flyspell-mode 1)
|
|
||||||
(auto-fill-mode -1)))
|
|
||||||
:bind (:map markdown-mode-map
|
|
||||||
("C-c C-l" . markdown-insert-link)
|
|
||||||
("C-c C-i" . markdown-insert-image)
|
|
||||||
("C-c C-c p" . markdown-preview)
|
|
||||||
("C-c C-c l" . markdown-live-preview-mode))
|
|
||||||
:config
|
|
||||||
(setq markdown-command "markdown")
|
|
||||||
(setq markdown-enable-wiki-links t)
|
|
||||||
(setq markdown-italic-underscore t)
|
|
||||||
(setq markdown-asymmetric-header t)
|
|
||||||
(setq markdown-make-gfm-checkboxes-buttons t)
|
|
||||||
(setq markdown-gfm-uppercase-checkbox t)
|
|
||||||
(setq markdown-fontify-code-blocks-natively t))
|
|
||||||
|
|
||||||
(use-package markdown-toc
|
|
||||||
:ensure t
|
|
||||||
:after markdown-mode
|
|
||||||
:bind (:map markdown-mode-map
|
|
||||||
("C-c C-t" . markdown-toc-generate-or-refresh-toc)))
|
|
||||||
|
|
||||||
(use-package grip-mode
|
|
||||||
:ensure t
|
|
||||||
:after markdown-mode
|
|
||||||
:bind (:map markdown-mode-map
|
|
||||||
("C-c C-c g" . grip-mode)))
|
|
||||||
|
|
||||||
|
|
||||||
;;; UI Configuration
|
|
||||||
(setq-default display-fill-column-indicator-column 80)
|
|
||||||
(setq-default display-fill-column-indicator-character ?\u2502)
|
|
||||||
(global-display-fill-column-indicator-mode 1)
|
|
||||||
(set-face-attribute 'fill-column-indicator nil :foreground "red")
|
|
||||||
|
|
||||||
;; Enable mouse window resizing
|
|
||||||
(setq mouse-autoselect-window nil) ; Don't auto-select windows on mouse hover
|
|
||||||
(setq window-divider-default-places t) ; Show dividers everywhere
|
|
||||||
(setq window-divider-default-bottom-width 1) ; Bottom divider width
|
|
||||||
(setq window-divider-default-right-width 1) ; Right divider width
|
|
||||||
(window-divider-mode 1) ; Enable window dividers for easier mouse dragging
|
|
||||||
|
|
||||||
;; CUA mode for rectangles
|
|
||||||
(setq cua-auto-tabify-rectangles nil)
|
|
||||||
(setq cua-keep-region-after-copy t)
|
|
||||||
(global-set-key (kbd "C-<return>") 'cua-set-rectangle-mark)
|
|
||||||
|
|
||||||
;;; Session Management
|
|
||||||
(desktop-save-mode 1)
|
|
||||||
(setq desktop-save t)
|
|
||||||
(setq desktop-auto-save-timeout 300)
|
|
||||||
(setq desktop-path '("~/.emacs.d/"))
|
|
||||||
(setq desktop-dirname "~/.emacs.d/")
|
|
||||||
(setq desktop-base-file-name "emacs-desktop")
|
|
||||||
(setq desktop-restore-eager 10)
|
|
||||||
(setq desktop-restore-frames t)
|
|
||||||
|
|
||||||
(savehist-mode 1)
|
|
||||||
(setq savehist-file "~/.emacs.d/savehist")
|
|
||||||
(setq history-length 1000)
|
|
||||||
|
|
||||||
(save-place-mode 1)
|
|
||||||
(setq save-place-file "~/.emacs.d/saveplace")
|
|
||||||
|
|
||||||
(recentf-mode 1)
|
|
||||||
(setq recentf-max-menu-items 50)
|
|
||||||
(setq recentf-max-saved-items 200)
|
|
||||||
|
|
||||||
;;; Performance Optimizations
|
|
||||||
(setq gc-cons-threshold 100000000)
|
|
||||||
(setq read-process-output-max (* 1024 1024))
|
|
||||||
|
|
||||||
;;; General Settings
|
|
||||||
(setq-default indent-tabs-mode nil)
|
|
||||||
(setq tab-width 4)
|
|
||||||
(setq inhibit-startup-screen t)
|
|
||||||
(global-auto-revert-mode t)
|
|
||||||
(electric-pair-mode 1)
|
|
||||||
(show-paren-mode 1)
|
|
||||||
(setq show-paren-delay 0)
|
|
||||||
(global-hl-line-mode 1)
|
|
||||||
|
|
||||||
;; Use system ls for better performance and features
|
|
||||||
;; Use ls-lisp (Emacs's built-in ls emulation) for better cross-platform compatibility
|
|
||||||
;; This avoids issues with macOS ls not supporting GNU ls options
|
|
||||||
(setq ls-lisp-use-insert-directory-program nil) ; Use Emacs's ls-lisp instead of system ls
|
|
||||||
(setq ls-lisp-dirs-first t) ; Group directories first (already set in custom-variables)
|
|
||||||
|
|
||||||
;; Auto-save and backup settings
|
|
||||||
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
|
|
||||||
(setq delete-old-versions t
|
|
||||||
kept-new-versions 6
|
|
||||||
kept-old-versions 2
|
|
||||||
version-control t)
|
|
||||||
(setq auto-save-file-name-transforms
|
|
||||||
'((".*" "~/.emacs.d/auto-save-list/" t)))
|
|
||||||
|
|
||||||
;;; Custom Functions
|
|
||||||
(defun kill-current-buffer-no-confirm ()
|
|
||||||
"Kill the current buffer without confirmation, unless it has unsaved changes."
|
|
||||||
(interactive)
|
|
||||||
(kill-buffer (current-buffer)))
|
|
||||||
|
|
||||||
(defun package-refresh-without-proxy ()
|
|
||||||
"Temporarily disable proxy and refresh packages."
|
|
||||||
(interactive)
|
|
||||||
(let ((url-proxy-services nil))
|
|
||||||
(package-refresh-contents)
|
|
||||||
(message "Package list refreshed without proxy")))
|
|
||||||
|
|
||||||
(defun package-install-without-proxy (package)
|
|
||||||
"Install PACKAGE without using proxy."
|
|
||||||
(interactive
|
|
||||||
(list (intern (completing-read "Install package: "
|
|
||||||
(mapcar #'car package-archive-contents)))))
|
|
||||||
(let ((url-proxy-services nil))
|
|
||||||
(package-install package)
|
|
||||||
(message "Package %s installed without proxy" package)))
|
|
||||||
|
|
||||||
(defun install-dev-packages ()
|
|
||||||
"Install development packages without proxy."
|
|
||||||
(interactive)
|
|
||||||
(let ((url-proxy-services nil)
|
|
||||||
(dev-packages '(lsp-mode lsp-ui lsp-treemacs
|
|
||||||
company company-box yasnippet
|
|
||||||
flycheck magit forge)))
|
|
||||||
(package-refresh-contents)
|
|
||||||
(dolist (pkg dev-packages)
|
|
||||||
(unless (package-installed-p pkg)
|
|
||||||
(condition-case err
|
|
||||||
(progn
|
|
||||||
(package-install pkg)
|
|
||||||
(message "Installed %s" pkg))
|
|
||||||
(error
|
|
||||||
(message "Failed to install %s: %s" pkg err)))))
|
|
||||||
(message "Development packages installation complete")))
|
|
||||||
|
|
||||||
(defvar url-proxy-services-backup nil
|
|
||||||
"Backup of proxy settings.")
|
|
||||||
|
|
||||||
(defun toggle-proxy ()
|
|
||||||
"Toggle proxy settings on/off."
|
|
||||||
(interactive)
|
|
||||||
(if url-proxy-services
|
|
||||||
(progn
|
|
||||||
(setq url-proxy-services-backup url-proxy-services)
|
|
||||||
(setq url-proxy-services nil)
|
|
||||||
(message "Proxy disabled"))
|
|
||||||
(progn
|
|
||||||
(setq url-proxy-services (or url-proxy-services-backup
|
|
||||||
'(("https" . "eudewerepo001:3128")
|
|
||||||
("http" . "eudewerepo001:3128"))))
|
|
||||||
(message "Proxy enabled: %s" (cdr (assoc "http" url-proxy-services))))))
|
|
||||||
|
|
||||||
(defun reload-emacs-config ()
|
|
||||||
"Reload the Emacs configuration file and all dependent configs."
|
|
||||||
(interactive)
|
|
||||||
;; First reload the main init.el
|
|
||||||
(load-file (expand-file-name "init.el" user-emacs-directory))
|
|
||||||
|
|
||||||
;; Reload development config if it exists
|
|
||||||
(let ((dev-config (expand-file-name "emacs-dev-config.el" user-emacs-directory)))
|
|
||||||
(when (file-exists-p dev-config)
|
|
||||||
(load-file dev-config)))
|
|
||||||
|
|
||||||
;; Reload SHR config if it exists
|
|
||||||
(let ((shr-config (expand-file-name "shr-config.el" user-emacs-directory)))
|
|
||||||
(when (file-exists-p shr-config)
|
|
||||||
(load-file shr-config)))
|
|
||||||
|
|
||||||
;; Reload elfeed config if it exists
|
|
||||||
(let ((elfeed-config (expand-file-name "elfeed-config.el" user-emacs-directory)))
|
|
||||||
(when (file-exists-p elfeed-config)
|
|
||||||
(load-file elfeed-config)))
|
|
||||||
|
|
||||||
;; Reload mu4e config if it exists
|
|
||||||
(let ((mu4e-config (expand-file-name "mu4e-config.el" user-emacs-directory)))
|
|
||||||
(when (file-exists-p mu4e-config)
|
|
||||||
(condition-case err
|
|
||||||
(load-file mu4e-config)
|
|
||||||
(error
|
|
||||||
(message "mu4e config available but mu4e not installed")))))
|
|
||||||
|
|
||||||
(message "Emacs configuration fully reloaded!"))
|
|
||||||
|
|
||||||
;;; Final Keybindings
|
|
||||||
(global-set-key (kbd "C-x k") 'kill-current-buffer-no-confirm)
|
|
||||||
(global-set-key (kbd "C-c C-r") 'reload-emacs-config)
|
|
||||||
(global-set-key (kbd "C-x C-b") 'helm-buffers-list)
|
|
||||||
|
|
||||||
;;; Fix for keybinding conflicts with CUA mode
|
|
||||||
(let ((keybinding-fix (expand-file-name "keybinding-fix.el" user-emacs-directory)))
|
|
||||||
(when (file-exists-p keybinding-fix)
|
|
||||||
(load-file keybinding-fix)
|
|
||||||
;; Automatically apply fixes for special modes
|
|
||||||
(fix-elfeed-keybindings)
|
|
||||||
(fix-portfolio-tracker-keybindings)
|
|
||||||
(disable-cua-in-special-modes)
|
|
||||||
(message "Keybinding fixes loaded and applied.")))
|
|
||||||
|
|
||||||
;;; SHR Configuration (for HTML rendering in mu4e, elfeed, eww)
|
|
||||||
(let ((shr-config (expand-file-name "shr-config.el" user-emacs-directory)))
|
(let ((shr-config (expand-file-name "shr-config.el" user-emacs-directory)))
|
||||||
(when (file-exists-p shr-config)
|
(when (file-exists-p shr-config)
|
||||||
(load-file shr-config)
|
(load-file shr-config)
|
||||||
(message "SHR configuration loaded.")))
|
(message "SHR configuration loaded.")))
|
||||||
|
|
||||||
;;; RSS Reader Configuration (Elfeed)
|
;; RSS Reader Configuration (Elfeed)
|
||||||
(let ((elfeed-config (expand-file-name "elfeed-config.el" user-emacs-directory)))
|
(let ((elfeed-config (expand-file-name "elfeed-config.el" user-emacs-directory)))
|
||||||
(when (file-exists-p elfeed-config)
|
(when (file-exists-p elfeed-config)
|
||||||
(load-file elfeed-config)
|
(load-file elfeed-config)
|
||||||
(message "Elfeed RSS reader configuration loaded.")))
|
(message "Elfeed RSS reader configuration loaded.")))
|
||||||
|
|
||||||
;;; Email Configuration (mu4e)
|
;; Email Configuration (mu4e)
|
||||||
(let ((mu4e-config (expand-file-name "mu4e-config.el" user-emacs-directory)))
|
(let ((mu4e-config (expand-file-name "mu4e-config.el" user-emacs-directory)))
|
||||||
(when (file-exists-p mu4e-config)
|
(when (file-exists-p mu4e-config)
|
||||||
(condition-case err
|
(condition-case err
|
||||||
@@ -771,56 +71,94 @@
|
|||||||
(error
|
(error
|
||||||
(message "mu4e configuration available but mu4e not installed. Install mu4e package to enable email.")))))
|
(message "mu4e configuration available but mu4e not installed. Install mu4e package to enable email.")))))
|
||||||
|
|
||||||
;;; Beancount Configuration
|
;; Beancount Configuration
|
||||||
(let ((beancount-config (expand-file-name "beancount-config.el" user-emacs-directory)))
|
(let ((beancount-config (expand-file-name "beancount-config.el" user-emacs-directory)))
|
||||||
(when (file-exists-p beancount-config)
|
(when (file-exists-p beancount-config)
|
||||||
(load-file beancount-config)
|
(load-file beancount-config)
|
||||||
(message "Beancount portfolio tracking configuration loaded.")))
|
(message "Beancount portfolio tracking configuration loaded.")))
|
||||||
|
|
||||||
;;; Portfolio Tracker Configuration
|
;; Portfolio Tracker Configuration
|
||||||
(with-eval-after-load 'tabulated-list
|
(with-eval-after-load 'tabulated-list
|
||||||
(let ((portfolio-tracker (expand-file-name "portfolio-tracker-v2.el" user-emacs-directory)))
|
(let ((portfolio-tracker (expand-file-name "portfolio-tracker-v2.el" user-emacs-directory)))
|
||||||
(when (file-exists-p portfolio-tracker)
|
(when (file-exists-p portfolio-tracker)
|
||||||
(load-file portfolio-tracker)
|
(load-file portfolio-tracker)
|
||||||
(message "Portfolio tracker with live prices loaded."))))
|
(message "Portfolio tracker with live prices loaded."))))
|
||||||
|
|
||||||
|
;; Keybinding fixes for special modes
|
||||||
|
(let ((keybinding-fix (expand-file-name "keybinding-fix.el" user-emacs-directory)))
|
||||||
|
(when (file-exists-p keybinding-fix)
|
||||||
|
(load-file keybinding-fix)
|
||||||
|
;; Automatically apply fixes for special modes
|
||||||
|
(fix-elfeed-keybindings)
|
||||||
|
(fix-portfolio-tracker-keybindings)
|
||||||
|
(disable-cua-in-special-modes)
|
||||||
|
(message "Keybinding fixes loaded and applied.")))
|
||||||
|
|
||||||
|
;;; Custom Settings (preserved from original)
|
||||||
|
;;; These are managed by Emacs Custom system - do not edit manually
|
||||||
|
(setq custom-file (expand-file-name "custom.el" user-emacs-directory))
|
||||||
|
|
||||||
|
;; Create custom.el with the existing customizations if it doesn't exist
|
||||||
|
(unless (file-exists-p custom-file)
|
||||||
|
(with-temp-file custom-file
|
||||||
|
(insert ";;; custom.el --- Custom variables set by Emacs -*- lexical-binding: t -*-\n")
|
||||||
|
(insert ";;; Commentary:\n")
|
||||||
|
(insert ";;; This file contains customizations set through the Custom interface.\n")
|
||||||
|
(insert ";;; It is automatically loaded by init.el.\n\n")
|
||||||
|
(insert ";;; Code:\n\n")
|
||||||
|
(insert "(custom-set-variables\n")
|
||||||
|
(insert " ;; custom-set-variables was added by Custom.\n")
|
||||||
|
(insert " ;; If you edit it by hand, you could mess it up, so be careful.\n")
|
||||||
|
(insert " ;; Your init file should contain only one such instance.\n")
|
||||||
|
(insert " ;; If there is more than one, they won't work right.\n")
|
||||||
|
(insert " '(custom-enabled-themes '(developer-dark))\n")
|
||||||
|
(insert " '(custom-safe-themes\n")
|
||||||
|
(insert " '(\"2974c2d5ffede4f111b02701ccdfadfbcde3d158ad9b09dade627b3ce3049ea1\"\n")
|
||||||
|
(insert " \"f8859f15bd0089a85d8d14e21dd774a9a8b391dac076e3ff17a13529b3d16576\"\n")
|
||||||
|
(insert " \"de2f009a49f8eaf2f323519d86016849cd1716d979bc3f7e4afb58899e52ddb7\"\n")
|
||||||
|
(insert " \"9fb69436c074b82a62b78b8d733e6274d0bd16d156f7b094e2afe4345c040c49\"\n")
|
||||||
|
(insert " \"004f174754c688f358fa2afc4f8699b5db647fbfaa0d6b55ff39f63e05bfbbf5\"\n")
|
||||||
|
(insert " \"ca1b398ceb1b61709197478dc7f705b8337a0a9631e399948e643520c5557382\"\n")
|
||||||
|
(insert " \"75eef60308d7328ed14fa27002e85de255c2342e73275173a14ed3aa1643d545\"\n")
|
||||||
|
(insert " \"77f281064ea1c8b14938866e21c4e51e4168e05db98863bd7430f1352cab294a\"\n")
|
||||||
|
(insert " \"242e6f00c98aa43539b41c505ef094d21cbc981203809a82949efaa2bc6cb194\"\n")
|
||||||
|
(insert " \"c9e63647d90e7dc59d52c176fbfd46fd2cfed275cd2bad9b29b6cf620d3389b6\"\n")
|
||||||
|
(insert " \"ad7d874d137291e09fe2963babc33d381d087fa14928cb9d34350b67b6556b6d\"\n")
|
||||||
|
(insert " default))\n")
|
||||||
|
(insert " '(diff-hl-global-modes t)\n")
|
||||||
|
(insert " '(neo-show-hidden-files t)\n")
|
||||||
|
(insert " '(neo-window-width 40)\n")
|
||||||
|
(insert " '(url-proxy-services\n")
|
||||||
|
(insert " '((\"https\" . \"eudewerepo001:3128\") (\"http\" . \"eudewerepo001:3128\")))\n")
|
||||||
|
(insert " '(safe-local-variable-values\n")
|
||||||
|
(insert " '((company-backends\n")
|
||||||
|
(insert " (company-qml company-capf company-files company-yasnippet))\n")
|
||||||
|
(insert " (lsp-clients-qml-server-executable . \"/usr/lib/qt6/bin/qmlls\")\n")
|
||||||
|
(insert " (company-minimum-prefix-length . 1) (company-idle-delay . 0.2)\n")
|
||||||
|
(insert " (lsp-clangd-binary-path . \"clangd\")\n")
|
||||||
|
(insert " (lsp-clients-clangd-args\n")
|
||||||
|
(insert " \"--compile-commands-dir=/home/jens/sources/thulio\"\n")
|
||||||
|
(insert " \"--background-index\" \"--clang-tidy\"\n")
|
||||||
|
(insert " \"--completion-style=detailed\" \"--header-insertion=iwyu\"\n")
|
||||||
|
(insert " \"--pch-storage=memory\")\n")
|
||||||
|
(insert " (projectile-project-root . \"/home/jens/sources/thulio\"))))\n\n")
|
||||||
|
(insert "(custom-set-faces\n")
|
||||||
|
(insert " ;; custom-set-faces was added by Custom.\n")
|
||||||
|
(insert " ;; If you edit it by hand, you could mess it up, so be careful.\n")
|
||||||
|
(insert " ;; Your init file should contain only one such instance.\n")
|
||||||
|
(insert " ;; If there is more than one, they won't work right.\n")
|
||||||
|
(insert " )\n\n")
|
||||||
|
(insert "(provide 'custom)\n")
|
||||||
|
(insert ";;; custom.el ends here\n")))
|
||||||
|
|
||||||
|
;; Load custom file
|
||||||
|
(when (file-exists-p custom-file)
|
||||||
|
(load custom-file))
|
||||||
|
|
||||||
;; Optional: Set default portfolio file to load on startup
|
;; Optional: Set default portfolio file to load on startup
|
||||||
(defvar portfolio-tracker-default-file
|
(defvar portfolio-tracker-default-file
|
||||||
(expand-file-name "sample-portfolio-v2.el" user-emacs-directory)
|
(expand-file-name "sample-portfolio-v2.el" user-emacs-directory)
|
||||||
"Default portfolio file to load.")
|
"Default portfolio file to load.")
|
||||||
|
|
||||||
;; Keybinding for quick access to portfolio tracker
|
|
||||||
(global-set-key (kbd "C-c $") 'portfolio-tracker)
|
|
||||||
|
|
||||||
;;; Theme Management
|
|
||||||
(defun load-jens-dark-theme ()
|
|
||||||
"Load the custom jens-dark theme."
|
|
||||||
(interactive)
|
|
||||||
(load-theme 'jens-dark t)
|
|
||||||
(message "Jens Dark theme loaded"))
|
|
||||||
|
|
||||||
(defun switch-theme (theme)
|
|
||||||
"Switch to a different theme interactively."
|
|
||||||
(interactive
|
|
||||||
(list (intern (completing-read "Load theme: "
|
|
||||||
(mapcar #'symbol-name (custom-available-themes))))))
|
|
||||||
(mapc #'disable-theme custom-enabled-themes)
|
|
||||||
(load-theme theme t)
|
|
||||||
(message "Switched to %s theme" theme))
|
|
||||||
|
|
||||||
;;; Development Mode Information
|
|
||||||
(defun show-dev-mode-info ()
|
|
||||||
"Show information about development mode."
|
|
||||||
(interactive)
|
|
||||||
(message "Development mode is available. Use M-x enable-dev-mode to activate LSP, company-mode, flycheck, and other development tools."))
|
|
||||||
|
|
||||||
;; Show info on startup if dev config is loaded
|
|
||||||
(when (featurep 'emacs-dev-config)
|
|
||||||
(add-hook 'emacs-startup-hook
|
|
||||||
(lambda ()
|
|
||||||
(run-with-timer 1 nil
|
|
||||||
(lambda ()
|
|
||||||
(message "Development mode available. Use M-x enable-dev-mode to activate."))))))
|
|
||||||
|
|
||||||
(provide 'init)
|
(provide 'init)
|
||||||
;;; init.el ends here
|
;;; init.el ends here
|
||||||
66
lisp/init-compile.el
Normal file
66
lisp/init-compile.el
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
;;; init-compile.el --- Byte compilation utilities -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Functions to byte-compile configuration files for faster loading
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(defun byte-compile-init-files ()
|
||||||
|
"Byte compile all init files in the lisp directory."
|
||||||
|
(interactive)
|
||||||
|
(let ((lisp-dir (expand-file-name "lisp" user-emacs-directory)))
|
||||||
|
(byte-recompile-directory lisp-dir 0 t)
|
||||||
|
(message "All init files byte-compiled")))
|
||||||
|
|
||||||
|
(defun byte-compile-config ()
|
||||||
|
"Byte compile the entire Emacs configuration."
|
||||||
|
(interactive)
|
||||||
|
(byte-compile-file (expand-file-name "init.el" user-emacs-directory))
|
||||||
|
(byte-compile-file (expand-file-name "early-init.el" user-emacs-directory))
|
||||||
|
(byte-compile-init-files)
|
||||||
|
(message "Configuration byte-compiled successfully"))
|
||||||
|
|
||||||
|
(defun clean-byte-compiled-files ()
|
||||||
|
"Remove all byte-compiled files from configuration."
|
||||||
|
(interactive)
|
||||||
|
(let ((lisp-dir (expand-file-name "lisp" user-emacs-directory)))
|
||||||
|
;; Remove .elc files from lisp directory
|
||||||
|
(dolist (file (directory-files lisp-dir t "\\.elc$"))
|
||||||
|
(delete-file file))
|
||||||
|
;; Remove main init.elc and early-init.elc
|
||||||
|
(let ((init-elc (expand-file-name "init.elc" user-emacs-directory))
|
||||||
|
(early-elc (expand-file-name "early-init.elc" user-emacs-directory)))
|
||||||
|
(when (file-exists-p init-elc) (delete-file init-elc))
|
||||||
|
(when (file-exists-p early-elc) (delete-file early-elc)))
|
||||||
|
(message "All byte-compiled files removed")))
|
||||||
|
|
||||||
|
;; Auto-compile on save if enabled
|
||||||
|
(defvar auto-compile-on-save nil
|
||||||
|
"If non-nil, automatically byte-compile init files when saved.")
|
||||||
|
|
||||||
|
(defun maybe-byte-compile-file ()
|
||||||
|
"Byte compile the current file if it's an init file and auto-compile is enabled."
|
||||||
|
(when (and auto-compile-on-save
|
||||||
|
(string-match-p "\\(init\\|early-init\\).*\\.el$" buffer-file-name)
|
||||||
|
(not (string-match-p "\\.elc$" buffer-file-name)))
|
||||||
|
(byte-compile-file buffer-file-name)))
|
||||||
|
|
||||||
|
(add-hook 'after-save-hook #'maybe-byte-compile-file)
|
||||||
|
|
||||||
|
;; Byte compile configuration after packages are installed
|
||||||
|
(defun byte-compile-after-package-install ()
|
||||||
|
"Byte compile configuration after new packages are installed."
|
||||||
|
(when (and (boundp 'package-alist)
|
||||||
|
(> (length package-alist) 0))
|
||||||
|
(byte-compile-config)))
|
||||||
|
|
||||||
|
;; Add startup message about byte compilation
|
||||||
|
(add-hook 'emacs-startup-hook
|
||||||
|
(lambda ()
|
||||||
|
(let ((init-elc (expand-file-name "init.elc" user-emacs-directory)))
|
||||||
|
(if (file-exists-p init-elc)
|
||||||
|
(message "Running byte-compiled configuration")
|
||||||
|
(message "Running interpreted configuration (use M-x byte-compile-config for faster startup)"))))
|
||||||
|
90)
|
||||||
|
|
||||||
|
(provide 'init-compile)
|
||||||
|
;;; init-compile.el ends here
|
||||||
205
lisp/init-completion.el
Normal file
205
lisp/init-completion.el
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
;;; init-completion.el --- Modern completion configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Configuration for Vertico, Consult, Orderless, Marginalia, and Embark
|
||||||
|
;;; This replaces Helm with a lighter, faster, more native completion system
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Vertico - Vertical completion UI
|
||||||
|
(use-package vertico
|
||||||
|
:ensure t
|
||||||
|
:init
|
||||||
|
(vertico-mode)
|
||||||
|
:config
|
||||||
|
;; Different scroll margin
|
||||||
|
(setq vertico-scroll-margin 0)
|
||||||
|
;; Show more candidates
|
||||||
|
(setq vertico-count 15)
|
||||||
|
;; Grow and shrink the Vertico minibuffer
|
||||||
|
(setq vertico-resize t)
|
||||||
|
;; Enable cycling
|
||||||
|
(setq vertico-cycle t))
|
||||||
|
|
||||||
|
;;; Savehist - Persist history over Emacs restarts
|
||||||
|
(use-package savehist
|
||||||
|
:ensure nil
|
||||||
|
:init
|
||||||
|
(savehist-mode))
|
||||||
|
|
||||||
|
;;; Orderless - Powerful completion style
|
||||||
|
(use-package orderless
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(completion-styles '(orderless basic))
|
||||||
|
(completion-category-overrides '((file (styles basic partial-completion)))))
|
||||||
|
|
||||||
|
;;; Marginalia - Rich annotations in minibuffer
|
||||||
|
(use-package marginalia
|
||||||
|
:ensure t
|
||||||
|
:init
|
||||||
|
(marginalia-mode)
|
||||||
|
:bind (:map minibuffer-local-map
|
||||||
|
("M-A" . marginalia-cycle)))
|
||||||
|
|
||||||
|
;;; Consult - Practical commands based on completing-read
|
||||||
|
(use-package consult
|
||||||
|
:ensure t
|
||||||
|
:bind (;; C-c bindings (mode-specific-map)
|
||||||
|
("C-c h" . consult-history)
|
||||||
|
("C-c m" . consult-mode-command)
|
||||||
|
("C-c k" . consult-kmacro)
|
||||||
|
;; C-x bindings (ctl-x-map)
|
||||||
|
("C-x M-:" . consult-complex-command)
|
||||||
|
("C-x b" . consult-buffer)
|
||||||
|
("C-x 4 b" . consult-buffer-other-window)
|
||||||
|
("C-x 5 b" . consult-buffer-other-frame)
|
||||||
|
("C-x r b" . consult-bookmark)
|
||||||
|
("C-x p b" . consult-project-buffer)
|
||||||
|
;; Custom M-# bindings for fast register access
|
||||||
|
("M-#" . consult-register-load)
|
||||||
|
("M-'" . consult-register-store)
|
||||||
|
("C-M-#" . consult-register)
|
||||||
|
;; Other custom bindings
|
||||||
|
("M-y" . consult-yank-pop)
|
||||||
|
;; M-g bindings (goto-map)
|
||||||
|
("M-g e" . consult-compile-error)
|
||||||
|
("M-g f" . consult-flymake)
|
||||||
|
("M-g g" . consult-goto-line)
|
||||||
|
("M-g M-g" . consult-goto-line)
|
||||||
|
("M-g o" . consult-outline)
|
||||||
|
("M-g m" . consult-mark)
|
||||||
|
("M-g k" . consult-global-mark)
|
||||||
|
("M-g i" . consult-imenu)
|
||||||
|
("M-g I" . consult-imenu-multi)
|
||||||
|
;; M-s bindings (search-map)
|
||||||
|
("M-s d" . consult-find)
|
||||||
|
("M-s D" . consult-locate)
|
||||||
|
("M-s g" . consult-grep)
|
||||||
|
("M-s G" . consult-git-grep)
|
||||||
|
("M-s r" . consult-ripgrep)
|
||||||
|
("M-s l" . consult-line)
|
||||||
|
("M-s L" . consult-line-multi)
|
||||||
|
("M-s k" . consult-keep-lines)
|
||||||
|
("M-s u" . consult-focus-lines)
|
||||||
|
;; Isearch integration
|
||||||
|
("M-s e" . consult-isearch-history)
|
||||||
|
:map isearch-mode-map
|
||||||
|
("M-e" . consult-isearch-history)
|
||||||
|
("M-s e" . consult-isearch-history)
|
||||||
|
("M-s l" . consult-line)
|
||||||
|
("M-s L" . consult-line-multi)
|
||||||
|
;; Minibuffer history
|
||||||
|
:map minibuffer-local-map
|
||||||
|
("M-s" . consult-history)
|
||||||
|
("M-r" . consult-history))
|
||||||
|
|
||||||
|
;; Enable automatic preview at point in the *Completions* buffer.
|
||||||
|
:hook (completion-list-mode . consult-preview-at-point-mode)
|
||||||
|
|
||||||
|
:init
|
||||||
|
;; Optionally configure the register formatting. This improves the register
|
||||||
|
;; preview for `consult-register', `consult-register-load',
|
||||||
|
;; `consult-register-store' and the Emacs built-ins.
|
||||||
|
(setq register-preview-delay 0.5
|
||||||
|
register-preview-function #'consult-register-format)
|
||||||
|
|
||||||
|
;; Optionally tweak the register preview window.
|
||||||
|
(advice-add #'register-preview :override #'consult-register-window)
|
||||||
|
|
||||||
|
;; Use Consult to select xref locations with preview
|
||||||
|
(setq xref-show-xrefs-function #'consult-xref
|
||||||
|
xref-show-definitions-function #'consult-xref)
|
||||||
|
|
||||||
|
:config
|
||||||
|
;; Optionally configure preview. The default value
|
||||||
|
;; is 'any, such that any key triggers the preview.
|
||||||
|
(setq consult-preview-key 'any)
|
||||||
|
|
||||||
|
;; Configure other variables and modes
|
||||||
|
(setq consult-narrow-key "<") ;; "C-+"
|
||||||
|
|
||||||
|
;; Make narrowing help available in the minibuffer.
|
||||||
|
(define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
|
||||||
|
|
||||||
|
;; By default `consult-project-function' uses `project-root' from project.el.
|
||||||
|
;; Configure a different project root function.
|
||||||
|
(autoload 'projectile-project-root "projectile")
|
||||||
|
(setq consult-project-function (lambda (_) (projectile-project-root))))
|
||||||
|
|
||||||
|
;;; Embark - Contextual actions
|
||||||
|
(use-package embark
|
||||||
|
:ensure t
|
||||||
|
:bind
|
||||||
|
(("C-." . embark-act) ;; pick some comfortable binding
|
||||||
|
("C-;" . embark-dwim) ;; good alternative: M-.
|
||||||
|
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
|
||||||
|
|
||||||
|
:init
|
||||||
|
;; Optionally replace the key help with a completing-read interface
|
||||||
|
(setq prefix-help-command #'embark-prefix-help-command)
|
||||||
|
|
||||||
|
:config
|
||||||
|
;; Hide the mode line of the Embark live/completions buffers
|
||||||
|
(add-to-list 'display-buffer-alist
|
||||||
|
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
|
||||||
|
nil
|
||||||
|
(window-parameters (mode-line-format . none)))))
|
||||||
|
|
||||||
|
;;; Embark-Consult - Integration between Embark and Consult
|
||||||
|
(use-package embark-consult
|
||||||
|
:ensure t
|
||||||
|
:hook
|
||||||
|
(embark-collect-mode . consult-preview-at-point-mode))
|
||||||
|
|
||||||
|
;;; Corfu - In-buffer completion popup
|
||||||
|
(use-package corfu
|
||||||
|
:ensure t
|
||||||
|
:custom
|
||||||
|
(corfu-cycle t) ;; Enable cycling for `corfu-next/previous'
|
||||||
|
(corfu-auto t) ;; Enable auto completion
|
||||||
|
(corfu-auto-delay 0.2)
|
||||||
|
(corfu-auto-prefix 2)
|
||||||
|
(corfu-separator ?\s) ;; Orderless field separator
|
||||||
|
(corfu-quit-at-boundary nil) ;; Never quit at completion boundary
|
||||||
|
(corfu-quit-no-match nil) ;; Never quit, even if there is no match
|
||||||
|
(corfu-preview-current nil) ;; Disable current candidate preview
|
||||||
|
(corfu-preselect 'prompt) ;; Preselect the prompt
|
||||||
|
(corfu-on-exact-match nil) ;; Configure handling of exact matches
|
||||||
|
(corfu-scroll-margin 5) ;; Use scroll margin
|
||||||
|
|
||||||
|
:init
|
||||||
|
(global-corfu-mode))
|
||||||
|
|
||||||
|
;;; Cape - Completion extensions for Corfu
|
||||||
|
(use-package cape
|
||||||
|
:ensure t
|
||||||
|
:init
|
||||||
|
;; Add `completion-at-point-functions', used by `completion-at-point'.
|
||||||
|
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
|
||||||
|
(add-to-list 'completion-at-point-functions #'cape-file)
|
||||||
|
(add-to-list 'completion-at-point-functions #'cape-keyword)
|
||||||
|
;;(add-to-list 'completion-at-point-functions #'cape-tex)
|
||||||
|
;;(add-to-list 'completion-at-point-functions #'cape-sgml)
|
||||||
|
;;(add-to-list 'completion-at-point-functions #'cape-rfc1345)
|
||||||
|
;;(add-to-list 'completion-at-point-functions #'cape-abbrev)
|
||||||
|
;;(add-to-list 'completion-at-point-functions #'cape-dict)
|
||||||
|
;;(add-to-list 'completion-at-point-functions #'cape-symbol)
|
||||||
|
;;(add-to-list 'completion-at-point-functions #'cape-line)
|
||||||
|
)
|
||||||
|
|
||||||
|
;;; Additional Consult commands for enhanced functionality
|
||||||
|
(defun consult-ripgrep-project-root ()
|
||||||
|
"Search project root with ripgrep."
|
||||||
|
(interactive)
|
||||||
|
(let ((root (or (projectile-project-root) default-directory)))
|
||||||
|
(consult-ripgrep root)))
|
||||||
|
|
||||||
|
(global-set-key (kbd "C-c r") 'consult-ripgrep-project-root)
|
||||||
|
|
||||||
|
;;; Make completion work nicely with Projectile
|
||||||
|
(with-eval-after-load 'projectile
|
||||||
|
(define-key projectile-command-map (kbd "b") #'consult-project-buffer)
|
||||||
|
(define-key projectile-command-map (kbd "r") #'consult-ripgrep))
|
||||||
|
|
||||||
|
(provide 'init-completion)
|
||||||
|
;;; init-completion.el ends here
|
||||||
153
lisp/init-core.el
Normal file
153
lisp/init-core.el
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
;;; init-core.el --- Core settings and package management -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Core Emacs settings, package management, and fundamental configurations
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Package Management
|
||||||
|
(require 'package)
|
||||||
|
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
|
||||||
|
(package-initialize)
|
||||||
|
|
||||||
|
;; Core package list - consolidated and cleaned
|
||||||
|
(setq package-selected-packages
|
||||||
|
'(;; Core utilities
|
||||||
|
use-package which-key
|
||||||
|
|
||||||
|
;; Themes
|
||||||
|
modus-themes
|
||||||
|
|
||||||
|
;; Version control
|
||||||
|
diff-hl
|
||||||
|
|
||||||
|
;; File management
|
||||||
|
treemacs treemacs-projectile treemacs-all-the-icons
|
||||||
|
neotree all-the-icons all-the-icons-dired diredfl
|
||||||
|
|
||||||
|
;; Modern completion ecosystem (replaces Helm)
|
||||||
|
vertico ; Vertical completion UI
|
||||||
|
consult ; Practical commands based on completing-read
|
||||||
|
orderless ; Powerful completion style
|
||||||
|
marginalia ; Rich annotations in minibuffer
|
||||||
|
embark ; Contextual actions
|
||||||
|
embark-consult ; Embark integration with Consult
|
||||||
|
corfu ; In-buffer completion popup
|
||||||
|
cape ; Completion extensions for Corfu
|
||||||
|
|
||||||
|
;; Core project management
|
||||||
|
projectile
|
||||||
|
|
||||||
|
;; Markdown & Notes
|
||||||
|
markdown-mode markdown-toc grip-mode
|
||||||
|
obsidian olivetti
|
||||||
|
|
||||||
|
;; Search and navigation
|
||||||
|
deadgrep ripgrep wgrep anzu
|
||||||
|
ibuffer-sidebar ibuffer-projectile
|
||||||
|
|
||||||
|
;; Required for some functionality
|
||||||
|
org dash s f ht spinner lv hydra avy
|
||||||
|
|
||||||
|
;; RSS/News reader
|
||||||
|
elfeed elfeed-org
|
||||||
|
|
||||||
|
;; Email (mu4e installed separately)
|
||||||
|
|
||||||
|
;; Finance tracking
|
||||||
|
beancount
|
||||||
|
|
||||||
|
;; God mode for modal editing
|
||||||
|
god-mode
|
||||||
|
|
||||||
|
;; Quality of life improvements
|
||||||
|
helpful ; Better help buffers
|
||||||
|
undo-tree ; Visual undo history
|
||||||
|
smartparens ; Better than electric-pair-mode
|
||||||
|
crux ; Collection of useful functions
|
||||||
|
ace-window ; Quick window switching
|
||||||
|
|
||||||
|
;; Terminal emulator
|
||||||
|
eat ; Emacs terminal emulator
|
||||||
|
))
|
||||||
|
|
||||||
|
;; Auto-install missing packages
|
||||||
|
(when (cl-find-if-not #'package-installed-p package-selected-packages)
|
||||||
|
(package-refresh-contents)
|
||||||
|
(mapc #'package-install package-selected-packages))
|
||||||
|
|
||||||
|
;; Ensure use-package is loaded
|
||||||
|
(eval-when-compile
|
||||||
|
(require 'use-package))
|
||||||
|
(setq use-package-always-ensure t)
|
||||||
|
|
||||||
|
;;; Performance Optimizations
|
||||||
|
;; Reset GC threshold after init for better runtime performance
|
||||||
|
(add-hook 'emacs-startup-hook
|
||||||
|
(lambda ()
|
||||||
|
;; Use the defaults we stored in early-init.el
|
||||||
|
(setq gc-cons-threshold (if (boundp 'default-gc-cons-threshold)
|
||||||
|
default-gc-cons-threshold
|
||||||
|
16777216) ; 16MB
|
||||||
|
gc-cons-percentage (if (boundp 'default-gc-cons-percentage)
|
||||||
|
default-gc-cons-percentage
|
||||||
|
0.1))
|
||||||
|
(message "GC threshold reset to %s" gc-cons-threshold))
|
||||||
|
50) ; Run after most other startup hooks
|
||||||
|
|
||||||
|
(setq read-process-output-max (* 1024 1024))
|
||||||
|
|
||||||
|
;;; General Settings
|
||||||
|
(setq-default indent-tabs-mode nil)
|
||||||
|
(setq tab-width 4)
|
||||||
|
(setq inhibit-startup-screen t)
|
||||||
|
(setq ring-bell-function 'ignore)
|
||||||
|
|
||||||
|
;; Auto-save and backup settings
|
||||||
|
(setq backup-directory-alist '(("." . "~/.emacs.d/backups")))
|
||||||
|
(setq delete-old-versions t
|
||||||
|
kept-new-versions 6
|
||||||
|
kept-old-versions 2
|
||||||
|
version-control t)
|
||||||
|
(setq auto-save-file-name-transforms
|
||||||
|
'((".*" "~/.emacs.d/auto-save-list/" t)))
|
||||||
|
|
||||||
|
;; Use ls-lisp (Emacs's built-in ls emulation) for better cross-platform compatibility
|
||||||
|
(setq ls-lisp-use-insert-directory-program nil)
|
||||||
|
(setq ls-lisp-dirs-first t)
|
||||||
|
|
||||||
|
;;; Session Management
|
||||||
|
(save-place-mode 1)
|
||||||
|
(setq save-place-file "~/.emacs.d/saveplace")
|
||||||
|
|
||||||
|
(savehist-mode 1)
|
||||||
|
(setq savehist-file "~/.emacs.d/savehist")
|
||||||
|
(setq history-length 1000)
|
||||||
|
|
||||||
|
(recentf-mode 1)
|
||||||
|
(setq recentf-max-menu-items 50)
|
||||||
|
(setq recentf-max-saved-items 200)
|
||||||
|
|
||||||
|
;; Desktop save mode - with lazy loading for better performance
|
||||||
|
;; Defer desktop restoration to speed up initial startup
|
||||||
|
(setq desktop-restore-eager 5) ; Restore only 5 buffers initially
|
||||||
|
(setq desktop-lazy-verbose nil)
|
||||||
|
(setq desktop-lazy-idle-delay 1) ; Restore rest after 1 second idle
|
||||||
|
|
||||||
|
;; Enable desktop-save-mode after startup
|
||||||
|
(add-hook 'after-init-hook
|
||||||
|
(lambda ()
|
||||||
|
(desktop-save-mode 1)
|
||||||
|
(setq desktop-save t)
|
||||||
|
(setq desktop-auto-save-timeout 300)
|
||||||
|
(setq desktop-path '("~/.emacs.d/"))
|
||||||
|
(setq desktop-dirname "~/.emacs.d/")
|
||||||
|
(setq desktop-base-file-name "emacs-desktop")
|
||||||
|
(setq desktop-restore-frames t)
|
||||||
|
;; Load desktop after a delay
|
||||||
|
(run-with-idle-timer 2 nil
|
||||||
|
(lambda ()
|
||||||
|
(desktop-read)
|
||||||
|
(message "Desktop restored")))))
|
||||||
|
|
||||||
|
(provide 'init-core)
|
||||||
|
;;; init-core.el ends here
|
||||||
91
lisp/init-dired.el
Normal file
91
lisp/init-dired.el
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
;;; init-dired.el --- Dired configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Enhanced Dired configuration for file management
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(use-package diredfl
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:hook (dired-mode . diredfl-mode))
|
||||||
|
|
||||||
|
;; Enhanced Dired configuration for multi-file operations
|
||||||
|
(use-package dired
|
||||||
|
:ensure nil
|
||||||
|
:config
|
||||||
|
(setq dired-dwim-target t) ; Guess target directory
|
||||||
|
(setq dired-recursive-copies 'always)
|
||||||
|
(setq dired-recursive-deletes 'always)
|
||||||
|
;; Use macOS-compatible ls options (no --group-directories-first)
|
||||||
|
(setq dired-listing-switches "-alh")
|
||||||
|
|
||||||
|
;; Enable multiple file marking with mouse
|
||||||
|
(define-key dired-mode-map (kbd "<mouse-2>") 'dired-find-file)
|
||||||
|
(define-key dired-mode-map (kbd "C-<mouse-1>") 'dired-mouse-mark)
|
||||||
|
|
||||||
|
;; Quick marking shortcuts
|
||||||
|
(define-key dired-mode-map (kbd "* .") 'dired-mark-extension)
|
||||||
|
(define-key dired-mode-map (kbd "* /") 'dired-mark-directories))
|
||||||
|
|
||||||
|
;; Custom sorting: directories first (dotted first), then files (dotted first)
|
||||||
|
(defun dired-sort-dotfiles-first ()
|
||||||
|
"Sort dired: dirs first (dots first within), then files (dots first within)."
|
||||||
|
(save-excursion
|
||||||
|
(let (buffer-read-only)
|
||||||
|
(goto-char (point-min))
|
||||||
|
;; Skip past the directory header
|
||||||
|
(while (and (not (eobp))
|
||||||
|
(not (looking-at "^ \\|^\\s-*$")))
|
||||||
|
(forward-line 1))
|
||||||
|
(let ((start (point))
|
||||||
|
dirs dotdirs files dotfiles special-entries)
|
||||||
|
;; Collect all entries
|
||||||
|
(while (not (eobp))
|
||||||
|
(when (looking-at "^ \\(.*\\)$")
|
||||||
|
(let* ((line (match-string 0))
|
||||||
|
(filename (ignore-errors (dired-get-filename 'no-dir t))))
|
||||||
|
(cond
|
||||||
|
;; Keep . and .. entries separate to put at top
|
||||||
|
((member filename '("." ".."))
|
||||||
|
(push line special-entries))
|
||||||
|
;; Process other entries
|
||||||
|
(filename
|
||||||
|
(let ((fullpath (ignore-errors (dired-get-filename t))))
|
||||||
|
(when fullpath
|
||||||
|
(cond
|
||||||
|
;; Dot directory
|
||||||
|
((and (file-directory-p fullpath)
|
||||||
|
(string-prefix-p "." filename))
|
||||||
|
(push line dotdirs))
|
||||||
|
;; Regular directory
|
||||||
|
((file-directory-p fullpath)
|
||||||
|
(push line dirs))
|
||||||
|
;; Dotfile
|
||||||
|
((string-prefix-p "." filename)
|
||||||
|
(push line dotfiles))
|
||||||
|
;; Regular file
|
||||||
|
(t
|
||||||
|
(push line files)))))))))
|
||||||
|
(forward-line 1))
|
||||||
|
;; Delete old content and insert sorted
|
||||||
|
(when (or special-entries dirs dotdirs files dotfiles)
|
||||||
|
(delete-region start (point-max))
|
||||||
|
(goto-char start)
|
||||||
|
;; Insert in order: . and .., dot dirs, regular dirs, dotfiles, regular files
|
||||||
|
(dolist (line (nreverse special-entries))
|
||||||
|
(insert line "\n"))
|
||||||
|
(dolist (line (sort (nreverse dotdirs) 'string<))
|
||||||
|
(insert line "\n"))
|
||||||
|
(dolist (line (sort (nreverse dirs) 'string<))
|
||||||
|
(insert line "\n"))
|
||||||
|
(dolist (line (sort (nreverse dotfiles) 'string<))
|
||||||
|
(insert line "\n"))
|
||||||
|
(dolist (line (sort (nreverse files) 'string<))
|
||||||
|
(insert line "\n")))))
|
||||||
|
(set-buffer-modified-p nil)))
|
||||||
|
|
||||||
|
;; Apply custom sorting after dired reads directory
|
||||||
|
(add-hook 'dired-after-readin-hook 'dired-sort-dotfiles-first)
|
||||||
|
|
||||||
|
(provide 'init-dired)
|
||||||
|
;;; init-dired.el ends here
|
||||||
53
lisp/init-editor.el
Normal file
53
lisp/init-editor.el
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
;;; init-editor.el --- Editor enhancements and editing settings -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Basic editor settings and enhancements for a better editing experience
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Basic editing settings
|
||||||
|
(global-auto-revert-mode t)
|
||||||
|
;; Electric-pair-mode is replaced by smartparens in init-qol.el
|
||||||
|
|
||||||
|
;; Enable shift-select mode for selecting text with Shift+Arrow keys
|
||||||
|
(setq shift-select-mode t)
|
||||||
|
(transient-mark-mode t)
|
||||||
|
|
||||||
|
;;; Text manipulation
|
||||||
|
(global-set-key (kbd "C-<return>") 'cua-set-rectangle-mark)
|
||||||
|
|
||||||
|
;;; Anzu - show match information in mode line
|
||||||
|
(use-package anzu
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
(global-anzu-mode 1)
|
||||||
|
:bind (([remap query-replace] . anzu-query-replace)
|
||||||
|
([remap query-replace-regexp] . anzu-query-replace-regexp)))
|
||||||
|
|
||||||
|
;;; Avy - jump to visible text
|
||||||
|
(use-package avy
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:bind (("C-:" . avy-goto-char)
|
||||||
|
("C-'" . avy-goto-char-2)
|
||||||
|
("M-g f" . avy-goto-line)
|
||||||
|
("M-g w" . avy-goto-word-1)))
|
||||||
|
|
||||||
|
;;; Olivetti - distraction-free writing
|
||||||
|
(use-package olivetti
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:commands olivetti-mode
|
||||||
|
:config
|
||||||
|
(setq olivetti-body-width 100))
|
||||||
|
|
||||||
|
;;; God-mode configuration (disabled by default)
|
||||||
|
;; Uncomment the following lines to enable god-mode
|
||||||
|
;; (let ((god-config (expand-file-name "god-mode-config.el" user-emacs-directory)))
|
||||||
|
;; (when (file-exists-p god-config)
|
||||||
|
;; (condition-case err
|
||||||
|
;; (load-file god-config)
|
||||||
|
;; (error (message "Failed to load god-mode config: %s" err)))))
|
||||||
|
|
||||||
|
(provide 'init-editor)
|
||||||
|
;;; init-editor.el ends here
|
||||||
140
lisp/init-eglot.el
Normal file
140
lisp/init-eglot.el
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
;;; init-eglot.el --- Eglot (built-in LSP) configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Lightweight LSP client using Emacs built-in Eglot (Emacs 29+)
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;; Eglot is built-in for Emacs 29+, otherwise install it
|
||||||
|
(unless (fboundp 'eglot)
|
||||||
|
(use-package eglot
|
||||||
|
:ensure t))
|
||||||
|
|
||||||
|
;; Configure Eglot
|
||||||
|
(with-eval-after-load 'eglot
|
||||||
|
;; Performance tuning
|
||||||
|
(setq eglot-autoshutdown t) ; Shutdown language server after closing last file
|
||||||
|
(setq eglot-sync-connect 0) ; Don't block on language server startup
|
||||||
|
(setq eglot-connect-timeout 10) ; Connection timeout in seconds
|
||||||
|
(setq eglot-events-buffer-size 0) ; Disable events buffer for performance
|
||||||
|
(setq eglot-ignored-server-capabilities '(:documentHighlightProvider)) ; Disable some features for speed
|
||||||
|
|
||||||
|
;; Don't let Eglot manage Flymake, we'll configure it separately
|
||||||
|
(setq eglot-stay-out-of '(flymake))
|
||||||
|
|
||||||
|
;; Workspace configuration for different servers
|
||||||
|
(setq-default eglot-workspace-configuration
|
||||||
|
'(:pylsp (:plugins (:pycodestyle (:enabled t)
|
||||||
|
:pyflakes (:enabled t)
|
||||||
|
:pylint (:enabled nil)))
|
||||||
|
:gopls (:usePlaceholders t)
|
||||||
|
;; Disable ESLint for TypeScript/JavaScript by default
|
||||||
|
:typescript (:validate (:enable :json-false))
|
||||||
|
:javascript (:validate (:enable :json-false))
|
||||||
|
:eslint (:enable :json-false)))
|
||||||
|
|
||||||
|
;; Configure language servers
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'((c-mode c++-mode c-ts-mode c++-ts-mode) . ("clangd"
|
||||||
|
"--background-index"
|
||||||
|
"--clang-tidy"
|
||||||
|
"--completion-style=detailed"
|
||||||
|
"--header-insertion=iwyu"
|
||||||
|
"--pch-storage=memory")))
|
||||||
|
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'((python-mode python-ts-mode) . ("pylsp")))
|
||||||
|
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'((rust-mode rust-ts-mode) . ("rust-analyzer")))
|
||||||
|
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'((go-mode go-ts-mode) . ("gopls")))
|
||||||
|
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'((typescript-mode typescript-ts-mode tsx-ts-mode) . ("typescript-language-server" "--stdio")))
|
||||||
|
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'((js-mode js-ts-mode) . ("typescript-language-server" "--stdio")))
|
||||||
|
|
||||||
|
;; QML support (if qmlls is available)
|
||||||
|
(when (executable-find "qmlls")
|
||||||
|
(add-to-list 'eglot-server-programs
|
||||||
|
'(qml-mode . ("qmlls"))))
|
||||||
|
|
||||||
|
;; Format on save
|
||||||
|
(defun eglot-format-buffer-on-save ()
|
||||||
|
"Format buffer with eglot before saving."
|
||||||
|
(add-hook 'before-save-hook #'eglot-format-buffer -10 t))
|
||||||
|
|
||||||
|
;; Keybindings
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l r") 'eglot-rename)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l a") 'eglot-code-actions)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l f") 'eglot-format)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l F") 'eglot-format-buffer)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l h") 'eldoc)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l d") 'xref-find-definitions)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l R") 'xref-find-references)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l i") 'eglot-find-implementation)
|
||||||
|
(define-key eglot-mode-map (kbd "C-c l t") 'eglot-find-typeDefinition))
|
||||||
|
|
||||||
|
;; Hook eglot to programming modes
|
||||||
|
(defun maybe-enable-eglot ()
|
||||||
|
"Enable eglot if a language server is available."
|
||||||
|
(when (and (not (bound-and-true-p lsp-mode)) ; Don't conflict with lsp-mode
|
||||||
|
(eglot-current-server)) ; Only if server is available
|
||||||
|
(eglot-ensure)))
|
||||||
|
|
||||||
|
;; Enable eglot for specific modes
|
||||||
|
(dolist (mode '(c-mode-hook
|
||||||
|
c++-mode-hook
|
||||||
|
c-ts-mode-hook
|
||||||
|
c++-ts-mode-hook
|
||||||
|
python-mode-hook
|
||||||
|
python-ts-mode-hook
|
||||||
|
rust-mode-hook
|
||||||
|
rust-ts-mode-hook
|
||||||
|
go-mode-hook
|
||||||
|
go-ts-mode-hook
|
||||||
|
js-mode-hook
|
||||||
|
js-ts-mode-hook
|
||||||
|
typescript-mode-hook
|
||||||
|
typescript-ts-mode-hook
|
||||||
|
tsx-ts-mode-hook))
|
||||||
|
(add-hook mode #'eglot-ensure))
|
||||||
|
|
||||||
|
;; Integration with Corfu for completion
|
||||||
|
(with-eval-after-load 'corfu
|
||||||
|
(setq completion-category-overrides '((eglot (styles orderless))))
|
||||||
|
(add-hook 'eglot-managed-mode-hook
|
||||||
|
(lambda ()
|
||||||
|
(setq-local completion-at-point-functions
|
||||||
|
(list (cape-super-capf
|
||||||
|
#'eglot-completion-at-point
|
||||||
|
#'cape-file))))))
|
||||||
|
|
||||||
|
;; Eldoc configuration for better documentation display
|
||||||
|
(with-eval-after-load 'eldoc
|
||||||
|
(setq eldoc-echo-area-use-multiline-p nil) ; Don't use multi-line eldoc
|
||||||
|
(setq eldoc-idle-delay 0.5))
|
||||||
|
|
||||||
|
;; Diagnostic display with Flymake (built-in)
|
||||||
|
(with-eval-after-load 'flymake
|
||||||
|
(define-key flymake-mode-map (kbd "C-c ! n") 'flymake-goto-next-error)
|
||||||
|
(define-key flymake-mode-map (kbd "C-c ! p") 'flymake-goto-prev-error)
|
||||||
|
(define-key flymake-mode-map (kbd "C-c ! l") 'flymake-show-buffer-diagnostics)
|
||||||
|
(define-key flymake-mode-map (kbd "C-c ! L") 'flymake-show-project-diagnostics))
|
||||||
|
|
||||||
|
;; Helper functions
|
||||||
|
(defun eglot-organize-imports ()
|
||||||
|
"Organize imports using Eglot."
|
||||||
|
(interactive)
|
||||||
|
(eglot-code-actions nil nil "source.organizeImports" t))
|
||||||
|
|
||||||
|
(defun eglot-restart-server ()
|
||||||
|
"Restart the Eglot server."
|
||||||
|
(interactive)
|
||||||
|
(call-interactively #'eglot-shutdown)
|
||||||
|
(call-interactively #'eglot))
|
||||||
|
|
||||||
|
(provide 'init-eglot)
|
||||||
|
;;; init-eglot.el ends here
|
||||||
72
lisp/init-emergency-fix.el
Normal file
72
lisp/init-emergency-fix.el
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
;;; init-emergency-fix.el --- Emergency fixes for editing issues -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Quick fixes for when editing is broken
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;; Emergency function to restore editing capability
|
||||||
|
(defun fix-editing-now ()
|
||||||
|
"Emergency fix to restore editing capability."
|
||||||
|
(interactive)
|
||||||
|
;; Disable read-only mode
|
||||||
|
(read-only-mode -1)
|
||||||
|
(setq buffer-read-only nil)
|
||||||
|
|
||||||
|
;; Disable god-mode if it's enabled
|
||||||
|
(when (boundp 'god-local-mode)
|
||||||
|
(god-local-mode -1))
|
||||||
|
(when (boundp 'god-global-mode)
|
||||||
|
(god-global-mode -1))
|
||||||
|
|
||||||
|
;; Disable view-mode if active
|
||||||
|
(when (bound-and-true-p view-mode)
|
||||||
|
(view-mode -1))
|
||||||
|
|
||||||
|
;; Ensure we're not in special modes
|
||||||
|
(when (bound-and-true-p special-mode)
|
||||||
|
(fundamental-mode))
|
||||||
|
|
||||||
|
;; Disable any potential read-only causing modes
|
||||||
|
(when (bound-and-true-p buffer-read-only)
|
||||||
|
(toggle-read-only -1))
|
||||||
|
|
||||||
|
;; Reset cursor type
|
||||||
|
(setq cursor-type 'bar)
|
||||||
|
|
||||||
|
;; Ensure CUA mode isn't causing issues
|
||||||
|
(when cua-mode
|
||||||
|
(cua-mode -1)
|
||||||
|
(cua-mode 1))
|
||||||
|
|
||||||
|
(message "Editing should be restored. If not, try M-x fundamental-mode"))
|
||||||
|
|
||||||
|
;; Diagnostic function
|
||||||
|
(defun diagnose-editing-issue ()
|
||||||
|
"Diagnose why editing might be disabled."
|
||||||
|
(interactive)
|
||||||
|
(let ((issues '()))
|
||||||
|
(when buffer-read-only
|
||||||
|
(push "Buffer is read-only" issues))
|
||||||
|
(when (bound-and-true-p god-local-mode)
|
||||||
|
(push "God-mode is enabled" issues))
|
||||||
|
(when (bound-and-true-p view-mode)
|
||||||
|
(push "View-mode is enabled" issues))
|
||||||
|
(when (bound-and-true-p special-mode)
|
||||||
|
(push "Special-mode is active" issues))
|
||||||
|
(when (eq major-mode 'fundamental-mode)
|
||||||
|
(push "In fundamental-mode" issues))
|
||||||
|
(if issues
|
||||||
|
(message "Issues found: %s" (string-join issues ", "))
|
||||||
|
(message "No obvious issues found. Mode: %s, Read-only: %s"
|
||||||
|
major-mode buffer-read-only))))
|
||||||
|
|
||||||
|
;; Global keybinding for emergency fix
|
||||||
|
(global-set-key (kbd "C-c C-!") 'fix-editing-now)
|
||||||
|
(global-set-key (kbd "C-c C-?") 'diagnose-editing-issue)
|
||||||
|
|
||||||
|
;; Ensure fundamental settings are correct
|
||||||
|
(setq-default buffer-read-only nil)
|
||||||
|
(setq inhibit-read-only nil)
|
||||||
|
|
||||||
|
(provide 'init-emergency-fix)
|
||||||
|
;;; init-emergency-fix.el ends here
|
||||||
102
lisp/init-eslint-fix.el
Normal file
102
lisp/init-eslint-fix.el
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
;;; init-eslint-fix.el --- Fix ESLint configuration issues -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Handles ESLint configuration issues when no .eslintrc is present
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;; Function to check if ESLint is configured in the current project
|
||||||
|
(defun project-has-eslint-config-p ()
|
||||||
|
"Check if the current project has ESLint configuration."
|
||||||
|
(let ((project-root (or (projectile-project-root)
|
||||||
|
(locate-dominating-file default-directory ".git")
|
||||||
|
default-directory)))
|
||||||
|
(or (file-exists-p (expand-file-name ".eslintrc" project-root))
|
||||||
|
(file-exists-p (expand-file-name ".eslintrc.js" project-root))
|
||||||
|
(file-exists-p (expand-file-name ".eslintrc.json" project-root))
|
||||||
|
(file-exists-p (expand-file-name ".eslintrc.yml" project-root))
|
||||||
|
(file-exists-p (expand-file-name ".eslintrc.yaml" project-root))
|
||||||
|
(file-exists-p (expand-file-name "eslint.config.js" project-root))
|
||||||
|
(file-exists-p (expand-file-name "package.json" project-root)))))
|
||||||
|
|
||||||
|
;; Disable ESLint for TypeScript/JavaScript if no config exists
|
||||||
|
(defun maybe-disable-eslint ()
|
||||||
|
"Disable ESLint if no configuration is found."
|
||||||
|
(when (and (derived-mode-p 'js-mode 'js-ts-mode 'typescript-mode 'typescript-ts-mode 'tsx-ts-mode)
|
||||||
|
(not (project-has-eslint-config-p)))
|
||||||
|
;; Tell Eglot to ignore ESLint diagnostics
|
||||||
|
(setq-local eglot-ignored-server-capabilities
|
||||||
|
(append eglot-ignored-server-capabilities
|
||||||
|
'(:documentFormattingProvider :documentRangeFormattingProvider)))
|
||||||
|
(message "ESLint disabled - no configuration found in project")))
|
||||||
|
|
||||||
|
;; Hook to check ESLint configuration
|
||||||
|
(add-hook 'eglot-managed-mode-hook #'maybe-disable-eslint)
|
||||||
|
|
||||||
|
;; Alternative: Completely disable ESLint in typescript-language-server
|
||||||
|
(with-eval-after-load 'eglot
|
||||||
|
(defun eglot-disable-eslint-for-typescript ()
|
||||||
|
"Disable ESLint for TypeScript language server."
|
||||||
|
(when (cl-find-if (lambda (server)
|
||||||
|
(and (eglot--server-capable server :textDocument/publishDiagnostics)
|
||||||
|
(string-match-p "typescript" (eglot--project-nickname server))))
|
||||||
|
(eglot-current-server))
|
||||||
|
(setq-local eglot-workspace-configuration
|
||||||
|
'(:typescript (:validate (:enable :json-false))
|
||||||
|
:javascript (:validate (:enable :json-false))
|
||||||
|
:eslint (:enable :json-false))))))
|
||||||
|
|
||||||
|
;; Function to manually disable ESLint in current buffer
|
||||||
|
(defun disable-eslint-in-buffer ()
|
||||||
|
"Disable ESLint validation in the current buffer."
|
||||||
|
(interactive)
|
||||||
|
(when (eglot-current-server)
|
||||||
|
(eglot--server-capable-or-lose (eglot-current-server) :workspace/didChangeConfiguration)
|
||||||
|
(jsonrpc-notify
|
||||||
|
(eglot-current-server)
|
||||||
|
:workspace/didChangeConfiguration
|
||||||
|
'(:settings (:eslint (:enable :json-false)
|
||||||
|
:validate (:enable :json-false))))
|
||||||
|
(message "ESLint disabled in current buffer")))
|
||||||
|
|
||||||
|
;; Function to create a basic .eslintrc if needed
|
||||||
|
(defun create-basic-eslintrc ()
|
||||||
|
"Create a basic .eslintrc.json file in the project root."
|
||||||
|
(interactive)
|
||||||
|
(let* ((project-root (or (projectile-project-root)
|
||||||
|
(locate-dominating-file default-directory ".git")
|
||||||
|
default-directory))
|
||||||
|
(eslintrc-path (expand-file-name ".eslintrc.json" project-root)))
|
||||||
|
(if (file-exists-p eslintrc-path)
|
||||||
|
(message ".eslintrc.json already exists")
|
||||||
|
(with-temp-file eslintrc-path
|
||||||
|
(insert "{\n")
|
||||||
|
(insert " \"env\": {\n")
|
||||||
|
(insert " \"browser\": true,\n")
|
||||||
|
(insert " \"es2021\": true,\n")
|
||||||
|
(insert " \"node\": true\n")
|
||||||
|
(insert " },\n")
|
||||||
|
(insert " \"extends\": \"eslint:recommended\",\n")
|
||||||
|
(insert " \"parserOptions\": {\n")
|
||||||
|
(insert " \"ecmaVersion\": \"latest\",\n")
|
||||||
|
(insert " \"sourceType\": \"module\"\n")
|
||||||
|
(insert " },\n")
|
||||||
|
(insert " \"rules\": {}\n")
|
||||||
|
(insert "}\n"))
|
||||||
|
(message "Created basic .eslintrc.json in %s" project-root))))
|
||||||
|
|
||||||
|
;; Global keybinding to disable ESLint - using C-c L e for LSP ESLint commands
|
||||||
|
(global-set-key (kbd "C-c L e d") 'disable-eslint-in-buffer)
|
||||||
|
(global-set-key (kbd "C-c L e c") 'create-basic-eslintrc)
|
||||||
|
|
||||||
|
;; Advice to suppress ESLint errors in the echo area
|
||||||
|
(defun suppress-eslint-errors (orig-fun &rest args)
|
||||||
|
"Suppress ESLint configuration errors."
|
||||||
|
(let ((msg (apply orig-fun args)))
|
||||||
|
(if (and msg (string-match-p "ESLint.*not configured" msg))
|
||||||
|
nil ; Don't show the message
|
||||||
|
msg)))
|
||||||
|
|
||||||
|
(advice-add 'eglot--message :around #'suppress-eslint-errors)
|
||||||
|
|
||||||
|
(provide 'init-eslint-fix)
|
||||||
|
;;; init-eslint-fix.el ends here
|
||||||
56
lisp/init-keybindings.el
Normal file
56
lisp/init-keybindings.el
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
;;; init-keybindings.el --- Global keybindings -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Global keybinding configurations
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Buffer management
|
||||||
|
(global-set-key (kbd "C-x k") 'kill-current-buffer-no-confirm)
|
||||||
|
|
||||||
|
;;; Configuration reload
|
||||||
|
(global-set-key (kbd "C-c C-r") 'reload-emacs-config)
|
||||||
|
|
||||||
|
;;; Portfolio tracker
|
||||||
|
(global-set-key (kbd "C-c $") 'portfolio-tracker)
|
||||||
|
|
||||||
|
;;; Window management
|
||||||
|
;; Consider adding ace-window or windmove keybindings here
|
||||||
|
;; (global-set-key (kbd "M-o") 'ace-window)
|
||||||
|
;; (windmove-default-keybindings)
|
||||||
|
|
||||||
|
;;; Better defaults
|
||||||
|
(global-set-key (kbd "C-x C-r") 'recentf-open-files)
|
||||||
|
(global-set-key (kbd "M-/") 'hippie-expand)
|
||||||
|
|
||||||
|
;;; Text manipulation helpers
|
||||||
|
(defun duplicate-current-line-or-region (arg)
|
||||||
|
"Duplicate current line, or region if active.
|
||||||
|
With argument ARG, make ARG copies."
|
||||||
|
(interactive "p")
|
||||||
|
(let (beg end (origin (point)))
|
||||||
|
(if (and mark-active (> (point) (mark)))
|
||||||
|
(exchange-point-and-mark))
|
||||||
|
(setq beg (line-beginning-position))
|
||||||
|
(if mark-active
|
||||||
|
(exchange-point-and-mark))
|
||||||
|
(setq end (line-end-position))
|
||||||
|
(let ((region (buffer-substring-no-properties beg end)))
|
||||||
|
(dotimes (i arg)
|
||||||
|
(goto-char end)
|
||||||
|
(newline)
|
||||||
|
(insert region)
|
||||||
|
(setq end (point)))
|
||||||
|
(goto-char (+ origin (* (length region) arg) arg)))))
|
||||||
|
|
||||||
|
(global-set-key (kbd "C-c C-d") 'duplicate-current-line-or-region)
|
||||||
|
|
||||||
|
;;; Quick buffer switching
|
||||||
|
(defun switch-to-previous-buffer ()
|
||||||
|
"Switch to the most recently used buffer."
|
||||||
|
(interactive)
|
||||||
|
(switch-to-buffer (other-buffer (current-buffer) 1)))
|
||||||
|
|
||||||
|
(global-set-key (kbd "C-c b") 'switch-to-previous-buffer)
|
||||||
|
|
||||||
|
(provide 'init-keybindings)
|
||||||
|
;;; init-keybindings.el ends here
|
||||||
51
lisp/init-markdown.el
Normal file
51
lisp/init-markdown.el
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
;;; init-markdown.el --- Markdown support configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Markdown editing and preview configuration
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(use-package markdown-mode
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:commands (markdown-mode gfm-mode)
|
||||||
|
:mode (("\\.md\\'" . markdown-mode)
|
||||||
|
("\\.markdown\\'" . markdown-mode)
|
||||||
|
("README\\.md\\'" . gfm-mode))
|
||||||
|
:hook (markdown-mode . (lambda ()
|
||||||
|
(visual-line-mode 1)
|
||||||
|
(flyspell-mode 1)
|
||||||
|
(auto-fill-mode -1)))
|
||||||
|
:bind (:map markdown-mode-map
|
||||||
|
("C-c C-l" . markdown-insert-link)
|
||||||
|
("C-c C-i" . markdown-insert-image)
|
||||||
|
("C-c C-c p" . markdown-preview)
|
||||||
|
("C-c C-c l" . markdown-live-preview-mode))
|
||||||
|
:config
|
||||||
|
(setq markdown-command "markdown")
|
||||||
|
(setq markdown-enable-wiki-links t)
|
||||||
|
(setq markdown-italic-underscore t)
|
||||||
|
(setq markdown-asymmetric-header t)
|
||||||
|
(setq markdown-make-gfm-checkboxes-buttons t)
|
||||||
|
(setq markdown-gfm-uppercase-checkbox t)
|
||||||
|
(setq markdown-fontify-code-blocks-natively t))
|
||||||
|
|
||||||
|
(use-package markdown-toc
|
||||||
|
:ensure t
|
||||||
|
:after markdown-mode
|
||||||
|
:defer t
|
||||||
|
:bind (:map markdown-mode-map
|
||||||
|
("C-c C-t" . markdown-toc-generate-or-refresh-toc)))
|
||||||
|
|
||||||
|
(use-package grip-mode
|
||||||
|
:ensure t
|
||||||
|
:after markdown-mode
|
||||||
|
:defer t
|
||||||
|
:bind (:map markdown-mode-map
|
||||||
|
("C-c C-c g" . grip-mode)))
|
||||||
|
|
||||||
|
(use-package obsidian
|
||||||
|
:ensure t
|
||||||
|
:defer t)
|
||||||
|
|
||||||
|
(provide 'init-markdown)
|
||||||
|
;;; init-markdown.el ends here
|
||||||
21
lisp/init-project.el
Normal file
21
lisp/init-project.el
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
;;; init-project.el --- Project management configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Projectile and project management settings
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Projectile - Project Management
|
||||||
|
(use-package projectile
|
||||||
|
:ensure t
|
||||||
|
:init
|
||||||
|
(projectile-mode +1)
|
||||||
|
:bind-keymap ("C-c p" . projectile-command-map)
|
||||||
|
:bind (("C-c d" . dired-jump)
|
||||||
|
("C-c D" . projectile-dired))
|
||||||
|
:config
|
||||||
|
(setq projectile-completion-system 'default) ; Use default completion (works with Vertico)
|
||||||
|
(setq projectile-switch-project-action #'projectile-dired)
|
||||||
|
(setq projectile-enable-caching t))
|
||||||
|
|
||||||
|
(provide 'init-project)
|
||||||
|
;;; init-project.el ends here
|
||||||
190
lisp/init-qol.el
Normal file
190
lisp/init-qol.el
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
;;; init-qol.el --- Quality of Life improvements -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Better help, undo, parentheses, and useful functions
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Helpful - Better help buffers
|
||||||
|
(use-package helpful
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:bind
|
||||||
|
(("C-h f" . helpful-callable)
|
||||||
|
("C-h v" . helpful-variable)
|
||||||
|
("C-h k" . helpful-key)
|
||||||
|
("C-h F" . helpful-function)
|
||||||
|
("C-h C" . helpful-command)
|
||||||
|
("C-c C-d" . helpful-at-point))
|
||||||
|
:config
|
||||||
|
;; Make helpful buffers more readable
|
||||||
|
(setq helpful-max-buffers 3))
|
||||||
|
|
||||||
|
;;; Undo-tree - Visual undo history
|
||||||
|
(use-package undo-tree
|
||||||
|
:ensure t
|
||||||
|
:diminish undo-tree-mode
|
||||||
|
:init
|
||||||
|
(global-undo-tree-mode)
|
||||||
|
:config
|
||||||
|
(setq undo-tree-visualizer-timestamps t)
|
||||||
|
(setq undo-tree-visualizer-diff t)
|
||||||
|
(setq undo-tree-history-directory-alist '(("." . "~/.emacs.d/undo-tree-history")))
|
||||||
|
(setq undo-tree-auto-save-history t)
|
||||||
|
:bind (("C-x u" . undo-tree-visualize)
|
||||||
|
("C-/" . undo-tree-undo)
|
||||||
|
("C-?" . undo-tree-redo)))
|
||||||
|
|
||||||
|
;;; Smartparens - Better parentheses handling
|
||||||
|
(use-package smartparens
|
||||||
|
:ensure t
|
||||||
|
:diminish smartparens-mode
|
||||||
|
:hook (prog-mode . smartparens-mode)
|
||||||
|
:init
|
||||||
|
;; Start disabled to avoid conflicts
|
||||||
|
(setq smartparens-global-mode nil)
|
||||||
|
:config
|
||||||
|
;; Load default config
|
||||||
|
(require 'smartparens-config)
|
||||||
|
|
||||||
|
;; Keybindings
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-f") 'sp-forward-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-b") 'sp-backward-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-n") 'sp-next-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-p") 'sp-previous-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-k") 'sp-kill-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-w") 'sp-copy-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "M-<delete>") 'sp-unwrap-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "M-<backspace>") 'sp-backward-unwrap-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-<right>") 'sp-forward-slurp-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-<left>") 'sp-forward-barf-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-<right>") 'sp-backward-barf-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-M-<left>") 'sp-backward-slurp-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "M-D") 'sp-splice-sexp)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-]") 'sp-select-next-thing-exchange)
|
||||||
|
(define-key smartparens-mode-map (kbd "C-<") 'sp-select-previous-thing)
|
||||||
|
(define-key smartparens-mode-map (kbd "C->") 'sp-select-next-thing)
|
||||||
|
|
||||||
|
;; Disable smartparens in minibuffer
|
||||||
|
(setq sp-ignore-modes-list '(minibuffer-mode minibuffer-inactive-mode))
|
||||||
|
|
||||||
|
;; Don't use strict mode by default as it can prevent editing
|
||||||
|
;; (dolist (mode '(emacs-lisp-mode-hook
|
||||||
|
;; lisp-mode-hook
|
||||||
|
;; lisp-interaction-mode-hook
|
||||||
|
;; scheme-mode-hook
|
||||||
|
;; clojure-mode-hook))
|
||||||
|
;; (add-hook mode #'smartparens-strict-mode))
|
||||||
|
)
|
||||||
|
|
||||||
|
;;; Crux - Collection of useful functions
|
||||||
|
(use-package crux
|
||||||
|
:ensure t
|
||||||
|
:bind (("C-c o" . crux-open-with)
|
||||||
|
("C-c n" . crux-cleanup-buffer-or-region)
|
||||||
|
("C-c f" . crux-recentf-find-file)
|
||||||
|
("C-M-z" . crux-indent-defun)
|
||||||
|
("C-c u" . crux-view-url)
|
||||||
|
("C-c e" . crux-eval-and-replace)
|
||||||
|
("C-c w" . crux-swap-windows)
|
||||||
|
("C-c D" . crux-delete-file-and-buffer)
|
||||||
|
("C-c r" . crux-rename-buffer-and-file)
|
||||||
|
("C-c t" . crux-visit-term-buffer)
|
||||||
|
("C-c k" . crux-kill-other-buffers)
|
||||||
|
("C-c TAB" . crux-indent-rigidly-and-copy-to-clipboard)
|
||||||
|
("C-c I" . crux-find-user-init-file)
|
||||||
|
("C-c S" . crux-find-shell-init-file)
|
||||||
|
("s-r" . crux-recentf-find-file)
|
||||||
|
("s-j" . crux-top-join-line)
|
||||||
|
("C-^" . crux-top-join-line)
|
||||||
|
("s-k" . crux-kill-whole-line)
|
||||||
|
("C-<backspace>" . crux-kill-line-backwards)
|
||||||
|
("s-o" . crux-smart-open-line-above)
|
||||||
|
("C-S-RET" . crux-smart-open-line-above)
|
||||||
|
("C-RET" . crux-smart-open-line)
|
||||||
|
("C-c c" . crux-create-scratch-buffer)
|
||||||
|
("C-c d" . crux-duplicate-current-line-or-region)
|
||||||
|
("C-c M-d" . crux-duplicate-and-comment-current-line-or-region)
|
||||||
|
("C-c F" . crux-recentf-find-directory)
|
||||||
|
([remap move-beginning-of-line] . crux-move-beginning-of-line)
|
||||||
|
([remap kill-whole-line] . crux-kill-whole-line)
|
||||||
|
([remap kill-line] . crux-smart-kill-line))
|
||||||
|
:config
|
||||||
|
;; Use crux cleanup on save for programming modes
|
||||||
|
(add-hook 'before-save-hook 'crux-cleanup-buffer-or-region))
|
||||||
|
|
||||||
|
;;; Ace-window - Quick window switching
|
||||||
|
(use-package ace-window
|
||||||
|
:ensure t
|
||||||
|
:bind (("M-o" . ace-window)
|
||||||
|
("C-x o" . ace-window))
|
||||||
|
:config
|
||||||
|
(setq aw-keys '(?a ?s ?d ?f ?g ?h ?j ?k ?l))
|
||||||
|
(setq aw-scope 'frame)
|
||||||
|
(setq aw-background t)
|
||||||
|
;; Make ace-window numbers larger and more visible
|
||||||
|
(custom-set-faces
|
||||||
|
'(aw-leading-char-face
|
||||||
|
((t (:inherit ace-jump-face-foreground :height 3.0))))))
|
||||||
|
|
||||||
|
;;; Additional useful functions
|
||||||
|
(defun qol-toggle-window-split ()
|
||||||
|
"Toggle between horizontal and vertical split."
|
||||||
|
(interactive)
|
||||||
|
(if (= (count-windows) 2)
|
||||||
|
(let* ((this-win-buffer (window-buffer))
|
||||||
|
(next-win-buffer (window-buffer (next-window)))
|
||||||
|
(this-win-edges (window-edges (selected-window)))
|
||||||
|
(next-win-edges (window-edges (next-window)))
|
||||||
|
(this-win-2nd (not (and (<= (car this-win-edges)
|
||||||
|
(car next-win-edges))
|
||||||
|
(<= (cadr this-win-edges)
|
||||||
|
(cadr next-win-edges)))))
|
||||||
|
(splitter
|
||||||
|
(if (= (car this-win-edges)
|
||||||
|
(car (window-edges (next-window))))
|
||||||
|
'split-window-horizontally
|
||||||
|
'split-window-vertically)))
|
||||||
|
(delete-other-windows)
|
||||||
|
(let ((first-win (selected-window)))
|
||||||
|
(funcall splitter)
|
||||||
|
(if this-win-2nd (other-window 1))
|
||||||
|
(set-window-buffer (selected-window) this-win-buffer)
|
||||||
|
(set-window-buffer (next-window) next-win-buffer)
|
||||||
|
(select-window first-win)
|
||||||
|
(if this-win-2nd (other-window 1))))))
|
||||||
|
|
||||||
|
(global-set-key (kbd "C-x |") 'qol-toggle-window-split)
|
||||||
|
|
||||||
|
;;; Window movement with windmove
|
||||||
|
(windmove-default-keybindings) ; Use Shift+arrows to move between windows
|
||||||
|
(setq windmove-wrap-around t)
|
||||||
|
|
||||||
|
;;; Better buffer names for duplicates
|
||||||
|
(require 'uniquify)
|
||||||
|
(setq uniquify-buffer-name-style 'forward)
|
||||||
|
(setq uniquify-separator "/")
|
||||||
|
(setq uniquify-after-kill-buffer-p t)
|
||||||
|
(setq uniquify-ignore-buffers-re "^\\*")
|
||||||
|
|
||||||
|
;;; Remember recently opened files
|
||||||
|
(setq recentf-max-saved-items 500)
|
||||||
|
(setq recentf-max-menu-items 15)
|
||||||
|
(setq recentf-auto-cleanup 'never)
|
||||||
|
(setq recentf-exclude '("^/var/folders\\.*"
|
||||||
|
"COMMIT_EDITMSG\\'"
|
||||||
|
".*-autoloads\\.el\\'"
|
||||||
|
"[/\\]\\.elpa/"))
|
||||||
|
|
||||||
|
;;; Better scrolling
|
||||||
|
(setq scroll-conservatively 101)
|
||||||
|
(setq scroll-margin 3)
|
||||||
|
(setq scroll-preserve-screen-position t)
|
||||||
|
|
||||||
|
;;; Enable some disabled commands
|
||||||
|
(put 'narrow-to-region 'disabled nil)
|
||||||
|
(put 'narrow-to-page 'disabled nil)
|
||||||
|
(put 'upcase-region 'disabled nil)
|
||||||
|
(put 'downcase-region 'disabled nil)
|
||||||
|
|
||||||
|
(provide 'init-qol)
|
||||||
|
;;; init-qol.el ends here
|
||||||
30
lisp/init-search.el
Normal file
30
lisp/init-search.el
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
;;; init-search.el --- Search and navigation tools -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Configuration for search tools like deadgrep, ripgrep, and wgrep
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Deadgrep - fast search with ripgrep
|
||||||
|
(use-package deadgrep
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:commands deadgrep
|
||||||
|
:bind (("C-c r" . deadgrep)))
|
||||||
|
|
||||||
|
;;; Wgrep - editable grep buffers
|
||||||
|
(use-package wgrep
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:after grep
|
||||||
|
:config
|
||||||
|
(setq wgrep-auto-save-buffer t)
|
||||||
|
(setq wgrep-enable-key "r"))
|
||||||
|
|
||||||
|
;;; Ripgrep
|
||||||
|
(use-package ripgrep
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:commands (ripgrep-regexp))
|
||||||
|
|
||||||
|
(provide 'init-search)
|
||||||
|
;;; init-search.el ends here
|
||||||
122
lisp/init-terminal.el
Normal file
122
lisp/init-terminal.el
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
;;; init-terminal.el --- Terminal emulator configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Configuration for eat (Emacs Terminal Emulator) and other terminal settings
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Eat - Emacs Terminal Emulator
|
||||||
|
(use-package eat
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:hook ((eshell-mode . eat-eshell-mode)
|
||||||
|
(eshell-mode . eat-eshell-visual-command-mode))
|
||||||
|
:config
|
||||||
|
;; Close eat buffer when process exits
|
||||||
|
(setq eat-kill-buffer-on-exit t)
|
||||||
|
|
||||||
|
;; Enable eat for eshell
|
||||||
|
(eat-eshell-mode 1)
|
||||||
|
|
||||||
|
;; Better color support
|
||||||
|
(setq eat-term-name "xterm-256color")
|
||||||
|
|
||||||
|
;; Set default shell
|
||||||
|
(setq eat-shell (getenv "SHELL"))
|
||||||
|
|
||||||
|
;; Increase scrollback
|
||||||
|
(setq eat-term-scrollback-size 10000)
|
||||||
|
|
||||||
|
;; Enable mouse support
|
||||||
|
(setq eat-enable-mouse t)
|
||||||
|
|
||||||
|
;; Custom keybindings for eat
|
||||||
|
(add-hook 'eat-mode-hook
|
||||||
|
(lambda ()
|
||||||
|
(local-set-key (kbd "C-c C-d") 'eat-self-input) ; Send C-d to terminal
|
||||||
|
(local-set-key (kbd "C-c C-c") 'eat-self-input) ; Send C-c to terminal
|
||||||
|
(local-set-key (kbd "C-c C-z") 'eat-self-input) ; Send C-z to terminal
|
||||||
|
(local-set-key (kbd "C-c C-k") 'eat-kill-process) ; Kill terminal process
|
||||||
|
(local-set-key (kbd "C-c C-p") 'eat-previous-shell-prompt)
|
||||||
|
(local-set-key (kbd "C-c C-n") 'eat-next-shell-prompt)))
|
||||||
|
|
||||||
|
;; Auto-close on exit codes
|
||||||
|
(defun eat-close-on-exit ()
|
||||||
|
"Close eat buffer automatically when shell exits."
|
||||||
|
(when (and (eq major-mode 'eat-mode)
|
||||||
|
(not (process-live-p (get-buffer-process (current-buffer)))))
|
||||||
|
(kill-buffer)))
|
||||||
|
|
||||||
|
;; Add hook to close buffer when process exits
|
||||||
|
(add-hook 'eat-exit-hook 'eat-close-on-exit)
|
||||||
|
|
||||||
|
;; Alternative: Close with a delay to see exit message
|
||||||
|
(defun eat-close-on-exit-with-delay ()
|
||||||
|
"Close eat buffer with a small delay after exit."
|
||||||
|
(run-with-timer 0.5 nil
|
||||||
|
(lambda (buf)
|
||||||
|
(when (buffer-live-p buf)
|
||||||
|
(kill-buffer buf)))
|
||||||
|
(current-buffer)))
|
||||||
|
|
||||||
|
;; Uncomment this and comment the previous hook if you want a delay
|
||||||
|
;; (add-hook 'eat-exit-hook 'eat-close-on-exit-with-delay)
|
||||||
|
)
|
||||||
|
|
||||||
|
;;; Quick terminal access
|
||||||
|
(defun open-eat-terminal ()
|
||||||
|
"Open a new eat terminal in the current window."
|
||||||
|
(interactive)
|
||||||
|
(eat))
|
||||||
|
|
||||||
|
(defun open-eat-terminal-here ()
|
||||||
|
"Open a new eat terminal in the current directory."
|
||||||
|
(interactive)
|
||||||
|
(let ((default-directory (if (buffer-file-name)
|
||||||
|
(file-name-directory (buffer-file-name))
|
||||||
|
default-directory)))
|
||||||
|
(eat)))
|
||||||
|
|
||||||
|
(defun open-eat-terminal-split ()
|
||||||
|
"Open a new eat terminal in a horizontal split."
|
||||||
|
(interactive)
|
||||||
|
(split-window-below)
|
||||||
|
(other-window 1)
|
||||||
|
(eat))
|
||||||
|
|
||||||
|
(defun open-eat-terminal-vsplit ()
|
||||||
|
"Open a new eat terminal in a vertical split."
|
||||||
|
(interactive)
|
||||||
|
(split-window-right)
|
||||||
|
(other-window 1)
|
||||||
|
(eat))
|
||||||
|
|
||||||
|
;;; Global keybindings for terminal access - using C-c E for Eat terminal
|
||||||
|
(global-set-key (kbd "C-c E t") 'open-eat-terminal)
|
||||||
|
(global-set-key (kbd "C-c E h") 'open-eat-terminal-here)
|
||||||
|
(global-set-key (kbd "C-c E s") 'open-eat-terminal-split)
|
||||||
|
(global-set-key (kbd "C-c E v") 'open-eat-terminal-vsplit)
|
||||||
|
|
||||||
|
;;; Eshell configuration (as alternative to eat)
|
||||||
|
(use-package eshell
|
||||||
|
:ensure nil
|
||||||
|
:config
|
||||||
|
;; Close eshell on exit
|
||||||
|
(defun eshell-close-on-exit ()
|
||||||
|
"Close eshell window on exit."
|
||||||
|
(when (not (one-window-p))
|
||||||
|
(delete-window)))
|
||||||
|
|
||||||
|
(add-hook 'eshell-exit-hook 'eshell-close-on-exit)
|
||||||
|
|
||||||
|
;; Better prompt
|
||||||
|
(setq eshell-prompt-function
|
||||||
|
(lambda ()
|
||||||
|
(concat
|
||||||
|
(propertize (abbreviate-file-name (eshell/pwd)) 'face '(:foreground "blue"))
|
||||||
|
(if (= (user-uid) 0) " # " " $ "))))
|
||||||
|
|
||||||
|
(setq eshell-highlight-prompt t)
|
||||||
|
(setq eshell-prompt-regexp "^[^#$\n]* [#$] "))
|
||||||
|
|
||||||
|
(provide 'init-terminal)
|
||||||
|
;;; init-terminal.el ends here
|
||||||
125
lisp/init-treemacs.el
Normal file
125
lisp/init-treemacs.el
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
;;; init-treemacs.el --- Treemacs configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; File tree configuration with Treemacs
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(use-package treemacs
|
||||||
|
:ensure t
|
||||||
|
:defer t
|
||||||
|
:commands (treemacs treemacs-select-window)
|
||||||
|
:bind (("M-0" . treemacs-select-window)
|
||||||
|
("C-c T t" . treemacs)
|
||||||
|
("C-c T 1" . treemacs-delete-other-windows)
|
||||||
|
("C-c T d" . treemacs-select-directory)
|
||||||
|
("C-c T B" . treemacs-bookmark)
|
||||||
|
("<f8>" . treemacs)
|
||||||
|
("C-c T f" . treemacs-toggle-and-focus)
|
||||||
|
("C-c T s" . treemacs-search-file)
|
||||||
|
:map treemacs-mode-map
|
||||||
|
("/" . treemacs-search-file)
|
||||||
|
("C-s" . projectile-find-file)
|
||||||
|
("s" . consult-ripgrep))
|
||||||
|
:config
|
||||||
|
(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-follow-delay 0.2
|
||||||
|
treemacs-follow-after-init t
|
||||||
|
treemacs-expand-after-init t
|
||||||
|
treemacs-find-workspace-method 'find-for-file-or-pick-first
|
||||||
|
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-delete-other-windows t
|
||||||
|
treemacs-persist-file (expand-file-name ".cache/treemacs-persist" user-emacs-directory)
|
||||||
|
treemacs-position 'left
|
||||||
|
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-show-cursor nil
|
||||||
|
treemacs-show-hidden-files t
|
||||||
|
treemacs-silent-filewatch nil
|
||||||
|
treemacs-silent-refresh nil
|
||||||
|
treemacs-sorting 'alphabetic-asc
|
||||||
|
treemacs-space-between-root-nodes t
|
||||||
|
treemacs-tag-follow-cleanup t
|
||||||
|
treemacs-tag-follow-delay 1.5
|
||||||
|
treemacs-width 35
|
||||||
|
treemacs-width-is-initially-locked t
|
||||||
|
treemacs-workspace-switch-cleanup nil)
|
||||||
|
|
||||||
|
(treemacs-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))
|
||||||
|
|
||||||
|
(use-package treemacs-projectile
|
||||||
|
:ensure t
|
||||||
|
:after (treemacs projectile)
|
||||||
|
:defer t)
|
||||||
|
|
||||||
|
(use-package treemacs-all-the-icons
|
||||||
|
:ensure t
|
||||||
|
:after (treemacs all-the-icons)
|
||||||
|
:defer t
|
||||||
|
:config
|
||||||
|
(treemacs-load-theme "all-the-icons"))
|
||||||
|
|
||||||
|
;; Treemacs helper functions
|
||||||
|
(defun treemacs-toggle-and-focus ()
|
||||||
|
"Toggle treemacs and focus on it if it's visible."
|
||||||
|
(interactive)
|
||||||
|
(if (treemacs-get-local-window)
|
||||||
|
(treemacs-toggle)
|
||||||
|
(progn
|
||||||
|
(treemacs)
|
||||||
|
(treemacs-select-window))))
|
||||||
|
|
||||||
|
(defun treemacs-search-file ()
|
||||||
|
"Search for a file in the current project using consult."
|
||||||
|
(interactive)
|
||||||
|
(if (fboundp 'projectile-find-file)
|
||||||
|
(projectile-find-file)
|
||||||
|
(consult-find)))
|
||||||
|
|
||||||
|
(defun treemacs-open-marked-files ()
|
||||||
|
"Open all marked files in treemacs."
|
||||||
|
(interactive)
|
||||||
|
(when (eq major-mode 'treemacs-mode)
|
||||||
|
(treemacs-bulk-file-actions
|
||||||
|
:actions '(treemacs-visit-node-no-split))))
|
||||||
|
|
||||||
|
(defun treemacs-mark-visible-files ()
|
||||||
|
"Mark all visible files in the current directory."
|
||||||
|
(interactive)
|
||||||
|
(when (eq major-mode 'treemacs-mode)
|
||||||
|
(save-excursion
|
||||||
|
(treemacs-goto-parent-node)
|
||||||
|
(treemacs-TAB-action)
|
||||||
|
(forward-line 1)
|
||||||
|
(while (and (not (eobp))
|
||||||
|
(> (treemacs--get-depth-of-item) 0))
|
||||||
|
(when (treemacs-is-node-file?)
|
||||||
|
(treemacs-do-mark))
|
||||||
|
(forward-line 1)))))
|
||||||
|
|
||||||
|
(provide 'init-treemacs)
|
||||||
|
;;; init-treemacs.el ends here
|
||||||
109
lisp/init-treesitter.el
Normal file
109
lisp/init-treesitter.el
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
;;; init-treesitter.el --- Tree-sitter configuration for Emacs 29+ -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Modern syntax highlighting and code analysis with tree-sitter
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;; Only load tree-sitter configuration if Emacs 29+ with tree-sitter support
|
||||||
|
(when (and (fboundp 'treesit-available-p)
|
||||||
|
(treesit-available-p))
|
||||||
|
|
||||||
|
;; Configure tree-sitter languages
|
||||||
|
(setq treesit-language-source-alist
|
||||||
|
'((bash "https://github.com/tree-sitter/tree-sitter-bash")
|
||||||
|
(c "https://github.com/tree-sitter/tree-sitter-c")
|
||||||
|
(cmake "https://github.com/uyha/tree-sitter-cmake")
|
||||||
|
(cpp "https://github.com/tree-sitter/tree-sitter-cpp")
|
||||||
|
(css "https://github.com/tree-sitter/tree-sitter-css")
|
||||||
|
(elisp "https://github.com/Wilfred/tree-sitter-elisp")
|
||||||
|
(go "https://github.com/tree-sitter/tree-sitter-go")
|
||||||
|
(html "https://github.com/tree-sitter/tree-sitter-html")
|
||||||
|
(javascript "https://github.com/tree-sitter/tree-sitter-javascript" "master" "src")
|
||||||
|
(json "https://github.com/tree-sitter/tree-sitter-json")
|
||||||
|
(make "https://github.com/alemuller/tree-sitter-make")
|
||||||
|
(markdown "https://github.com/ikatyang/tree-sitter-markdown")
|
||||||
|
(python "https://github.com/tree-sitter/tree-sitter-python")
|
||||||
|
(rust "https://github.com/tree-sitter/tree-sitter-rust")
|
||||||
|
(toml "https://github.com/tree-sitter/tree-sitter-toml")
|
||||||
|
(tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")
|
||||||
|
(typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")
|
||||||
|
(yaml "https://github.com/ikatyang/tree-sitter-yaml")))
|
||||||
|
|
||||||
|
;; Function to install a tree-sitter grammar
|
||||||
|
(defun treesit-install-language-grammar (lang)
|
||||||
|
"Install tree-sitter grammar for LANG."
|
||||||
|
(interactive (list (intern (completing-read "Language: "
|
||||||
|
(mapcar #'car treesit-language-source-alist)))))
|
||||||
|
(unless (treesit-language-available-p lang)
|
||||||
|
(let ((lang-source (alist-get lang treesit-language-source-alist)))
|
||||||
|
(if lang-source
|
||||||
|
(treesit-install-language-grammar lang)
|
||||||
|
(message "Language source not configured for %s" lang)))))
|
||||||
|
|
||||||
|
;; Install all configured grammars
|
||||||
|
(defun treesit-install-all-grammars ()
|
||||||
|
"Install all configured tree-sitter grammars."
|
||||||
|
(interactive)
|
||||||
|
(dolist (lang-source treesit-language-source-alist)
|
||||||
|
(let ((lang (car lang-source)))
|
||||||
|
(unless (treesit-language-available-p lang)
|
||||||
|
(message "Installing tree-sitter grammar for %s..." lang)
|
||||||
|
(condition-case err
|
||||||
|
(treesit-install-language-grammar lang)
|
||||||
|
(error (message "Failed to install %s: %s" lang err)))))))
|
||||||
|
|
||||||
|
;; Remap major modes to use tree-sitter variants
|
||||||
|
(setq major-mode-remap-alist
|
||||||
|
'((yaml-mode . yaml-ts-mode)
|
||||||
|
(bash-mode . bash-ts-mode)
|
||||||
|
(js2-mode . js-ts-mode)
|
||||||
|
(javascript-mode . js-ts-mode)
|
||||||
|
(js-mode . js-ts-mode)
|
||||||
|
(typescript-mode . typescript-ts-mode)
|
||||||
|
(json-mode . json-ts-mode)
|
||||||
|
(css-mode . css-ts-mode)
|
||||||
|
(python-mode . python-ts-mode)
|
||||||
|
(c-mode . c-ts-mode)
|
||||||
|
(c++-mode . c++-ts-mode)
|
||||||
|
(cmake-mode . cmake-ts-mode)
|
||||||
|
(toml-mode . toml-ts-mode)
|
||||||
|
(rust-mode . rust-ts-mode)
|
||||||
|
(go-mode . go-ts-mode)))
|
||||||
|
|
||||||
|
;; Auto-mode-alist for tree-sitter modes
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.ts\\'" . typescript-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.tsx\\'" . tsx-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.js\\'" . js-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.mjs\\'" . js-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.json\\'" . json-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.yaml\\'" . yaml-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.yml\\'" . yaml-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.toml\\'" . toml-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-ts-mode))
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode))
|
||||||
|
|
||||||
|
;; Enhanced font-lock for tree-sitter modes
|
||||||
|
(setq treesit-font-lock-level 4) ; Maximum highlighting
|
||||||
|
|
||||||
|
;; Tree-sitter debugging helpers
|
||||||
|
(defun treesit-inspect-node-at-point ()
|
||||||
|
"Show tree-sitter node information at point."
|
||||||
|
(interactive)
|
||||||
|
(when (treesit-parser-list)
|
||||||
|
(let ((node (treesit-node-at (point))))
|
||||||
|
(message "Node: %s, Type: %s, Text: %s"
|
||||||
|
node
|
||||||
|
(treesit-node-type node)
|
||||||
|
(treesit-node-text node)))))
|
||||||
|
|
||||||
|
;; Add to startup hook to check for tree-sitter grammars
|
||||||
|
(add-hook 'emacs-startup-hook
|
||||||
|
(lambda ()
|
||||||
|
(when (and (treesit-available-p)
|
||||||
|
(not (treesit-language-available-p 'python)))
|
||||||
|
(message "Tree-sitter grammars not installed. Run M-x treesit-install-all-grammars"))))
|
||||||
|
|
||||||
|
(message "Tree-sitter support enabled"))
|
||||||
|
|
||||||
|
(provide 'init-treesitter)
|
||||||
|
;;; init-treesitter.el ends here
|
||||||
100
lisp/init-ui.el
Normal file
100
lisp/init-ui.el
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
;;; init-ui.el --- UI and theme configurations -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; User interface settings, themes, and visual configurations
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Display Settings
|
||||||
|
(column-number-mode t)
|
||||||
|
(global-display-line-numbers-mode t)
|
||||||
|
(setq display-line-numbers-type 'relative)
|
||||||
|
(tool-bar-mode -1)
|
||||||
|
(when (fboundp 'scroll-bar-mode)
|
||||||
|
(scroll-bar-mode -1))
|
||||||
|
(global-hl-line-mode 1)
|
||||||
|
(show-paren-mode 1)
|
||||||
|
(setq show-paren-delay 0)
|
||||||
|
|
||||||
|
;; CUA mode for rectangles - use selection mode only to avoid conflicts
|
||||||
|
(cua-selection-mode t) ; Only rectangle selection, not full CUA bindings
|
||||||
|
(setq cua-auto-tabify-rectangles nil)
|
||||||
|
(setq cua-keep-region-after-copy t)
|
||||||
|
|
||||||
|
;; Trailing whitespace
|
||||||
|
(setq show-trailing-whitespace t)
|
||||||
|
(add-hook 'before-save-hook 'delete-trailing-whitespace)
|
||||||
|
|
||||||
|
;; Fill column indicator
|
||||||
|
(setq-default display-fill-column-indicator-column 80)
|
||||||
|
(setq-default display-fill-column-indicator-character ?\u2502)
|
||||||
|
(global-display-fill-column-indicator-mode 1)
|
||||||
|
(set-face-attribute 'fill-column-indicator nil :foreground "red")
|
||||||
|
|
||||||
|
;; Window dividers for mouse resizing
|
||||||
|
(setq mouse-autoselect-window nil)
|
||||||
|
(setq window-divider-default-places t)
|
||||||
|
(setq window-divider-default-bottom-width 1)
|
||||||
|
(setq window-divider-default-right-width 1)
|
||||||
|
(window-divider-mode 1)
|
||||||
|
|
||||||
|
;;; Font Settings (preserved from custom-set-faces)
|
||||||
|
(set-face-attribute 'default nil
|
||||||
|
:family "0xProto Nerd Font Mono"
|
||||||
|
:foundry "nil"
|
||||||
|
:slant 'normal
|
||||||
|
:weight 'regular
|
||||||
|
:height 140
|
||||||
|
:width 'normal)
|
||||||
|
|
||||||
|
;;; Diff-hl face customizations
|
||||||
|
(with-eval-after-load 'diff-hl
|
||||||
|
(set-face-attribute 'diff-hl-change nil :background "blue3" :foreground "blue3")
|
||||||
|
(set-face-attribute 'diff-hl-delete nil :background "red3" :foreground "red3")
|
||||||
|
(set-face-attribute 'diff-hl-insert nil :background "green3" :foreground "green3"))
|
||||||
|
|
||||||
|
;;; Theme Management
|
||||||
|
(defvar jens-themes
|
||||||
|
'(developer-dark
|
||||||
|
modus-vivendi
|
||||||
|
modus-operandi)
|
||||||
|
"List of preferred themes.")
|
||||||
|
|
||||||
|
(defun load-jens-dark-theme ()
|
||||||
|
"Load the custom jens-dark theme."
|
||||||
|
(interactive)
|
||||||
|
(load-theme 'jens-dark t)
|
||||||
|
(message "Jens Dark theme loaded"))
|
||||||
|
|
||||||
|
(defun switch-theme (theme)
|
||||||
|
"Switch to a different theme interactively."
|
||||||
|
(interactive
|
||||||
|
(list (intern (completing-read "Load theme: "
|
||||||
|
(mapcar #'symbol-name (custom-available-themes))))))
|
||||||
|
(mapc #'disable-theme custom-enabled-themes)
|
||||||
|
(load-theme theme t)
|
||||||
|
(message "Switched to %s theme" theme))
|
||||||
|
|
||||||
|
;; Load default theme
|
||||||
|
(when (member 'developer-dark (custom-available-themes))
|
||||||
|
(load-theme 'developer-dark t))
|
||||||
|
|
||||||
|
;;; Icons
|
||||||
|
(use-package all-the-icons
|
||||||
|
:ensure t
|
||||||
|
:defer t)
|
||||||
|
|
||||||
|
(use-package all-the-icons-dired
|
||||||
|
:ensure t
|
||||||
|
:after all-the-icons
|
||||||
|
:hook (dired-mode . all-the-icons-dired-mode))
|
||||||
|
|
||||||
|
;;; Which-key for discovering keybindings
|
||||||
|
(use-package which-key
|
||||||
|
:ensure t
|
||||||
|
:init (which-key-mode)
|
||||||
|
:config
|
||||||
|
(setq which-key-idle-delay 0.3)
|
||||||
|
(setq which-key-popup-type 'side-window))
|
||||||
|
|
||||||
|
(provide 'init-ui)
|
||||||
|
;;; init-ui.el ends here
|
||||||
117
lisp/init-utils.el
Normal file
117
lisp/init-utils.el
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
;;; init-utils.el --- Utility functions and configurations -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Custom utility functions and helper configurations
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Custom Functions
|
||||||
|
(defun kill-current-buffer-no-confirm ()
|
||||||
|
"Kill the current buffer without confirmation, unless it has unsaved changes."
|
||||||
|
(interactive)
|
||||||
|
(kill-buffer (current-buffer)))
|
||||||
|
|
||||||
|
(defun reload-emacs-config ()
|
||||||
|
"Reload the Emacs configuration file and all dependent configs."
|
||||||
|
(interactive)
|
||||||
|
;; First reload the main init.el
|
||||||
|
(load-file (expand-file-name "init.el" user-emacs-directory))
|
||||||
|
|
||||||
|
;; Reload development config if it exists
|
||||||
|
(let ((dev-config (expand-file-name "emacs-dev-config.el" user-emacs-directory)))
|
||||||
|
(when (file-exists-p dev-config)
|
||||||
|
(load-file dev-config)))
|
||||||
|
|
||||||
|
;; Reload SHR config if it exists
|
||||||
|
(let ((shr-config (expand-file-name "shr-config.el" user-emacs-directory)))
|
||||||
|
(when (file-exists-p shr-config)
|
||||||
|
(load-file shr-config)))
|
||||||
|
|
||||||
|
;; Reload elfeed config if it exists
|
||||||
|
(let ((elfeed-config (expand-file-name "elfeed-config.el" user-emacs-directory)))
|
||||||
|
(when (file-exists-p elfeed-config)
|
||||||
|
(load-file elfeed-config)))
|
||||||
|
|
||||||
|
;; Reload mu4e config if it exists
|
||||||
|
(let ((mu4e-config (expand-file-name "mu4e-config.el" user-emacs-directory)))
|
||||||
|
(when (file-exists-p mu4e-config)
|
||||||
|
(condition-case err
|
||||||
|
(load-file mu4e-config)
|
||||||
|
(error
|
||||||
|
(message "mu4e config available but mu4e not installed")))))
|
||||||
|
|
||||||
|
(message "Emacs configuration fully reloaded!"))
|
||||||
|
|
||||||
|
;;; Package management helpers
|
||||||
|
(defun package-refresh-without-proxy ()
|
||||||
|
"Temporarily disable proxy and refresh packages."
|
||||||
|
(interactive)
|
||||||
|
(let ((url-proxy-services nil))
|
||||||
|
(package-refresh-contents)
|
||||||
|
(message "Package list refreshed without proxy")))
|
||||||
|
|
||||||
|
(defun package-install-without-proxy (package)
|
||||||
|
"Install PACKAGE without using proxy."
|
||||||
|
(interactive
|
||||||
|
(list (intern (completing-read "Install package: "
|
||||||
|
(mapcar #'car package-archive-contents)))))
|
||||||
|
(let ((url-proxy-services nil))
|
||||||
|
(package-install package)
|
||||||
|
(message "Package %s installed without proxy" package)))
|
||||||
|
|
||||||
|
(defun install-dev-packages ()
|
||||||
|
"Install development packages without proxy."
|
||||||
|
(interactive)
|
||||||
|
(let ((url-proxy-services nil)
|
||||||
|
(dev-packages '(lsp-mode lsp-ui lsp-treemacs
|
||||||
|
company company-box yasnippet
|
||||||
|
flycheck magit forge)))
|
||||||
|
(package-refresh-contents)
|
||||||
|
(dolist (pkg dev-packages)
|
||||||
|
(unless (package-installed-p pkg)
|
||||||
|
(condition-case err
|
||||||
|
(progn
|
||||||
|
(package-install pkg)
|
||||||
|
(message "Installed %s" pkg))
|
||||||
|
(error
|
||||||
|
(message "Failed to install %s: %s" pkg err)))))
|
||||||
|
(message "Development packages installation complete")))
|
||||||
|
|
||||||
|
;;; Proxy management
|
||||||
|
(defvar url-proxy-services-backup nil
|
||||||
|
"Backup of proxy settings.")
|
||||||
|
|
||||||
|
(defun toggle-proxy ()
|
||||||
|
"Toggle proxy settings on/off."
|
||||||
|
(interactive)
|
||||||
|
(if url-proxy-services
|
||||||
|
(progn
|
||||||
|
(setq url-proxy-services-backup url-proxy-services)
|
||||||
|
(setq url-proxy-services nil)
|
||||||
|
(message "Proxy disabled"))
|
||||||
|
(progn
|
||||||
|
(setq url-proxy-services (or url-proxy-services-backup
|
||||||
|
'(("https" . "eudewerepo001:3128")
|
||||||
|
("http" . "eudewerepo001:3128"))))
|
||||||
|
(message "Proxy enabled: %s" (cdr (assoc "http" url-proxy-services))))))
|
||||||
|
|
||||||
|
;;; Development mode helpers
|
||||||
|
(defun show-dev-mode-info ()
|
||||||
|
"Show information about development mode."
|
||||||
|
(interactive)
|
||||||
|
(message "Development mode is available. Use M-x enable-dev-mode to activate LSP, company-mode, flycheck, and other development tools."))
|
||||||
|
|
||||||
|
;;; God-mode helpers
|
||||||
|
(defun enable-god-mode-config ()
|
||||||
|
"Enable god-mode configuration."
|
||||||
|
(interactive)
|
||||||
|
(let ((god-config (expand-file-name "god-mode-config.el" user-emacs-directory)))
|
||||||
|
(if (file-exists-p god-config)
|
||||||
|
(condition-case err
|
||||||
|
(progn
|
||||||
|
(load-file god-config)
|
||||||
|
(message "God-mode configuration loaded. Press ESC to toggle god-mode."))
|
||||||
|
(error (message "Failed to load god-mode config: %s" err)))
|
||||||
|
(message "God-mode config file not found at %s" god-config))))
|
||||||
|
|
||||||
|
(provide 'init-utils)
|
||||||
|
;;; init-utils.el ends here
|
||||||
78
lisp/init-vcs.el
Normal file
78
lisp/init-vcs.el
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
;;; init-vcs.el --- Version control configuration -*- lexical-binding: t -*-
|
||||||
|
;;; Commentary:
|
||||||
|
;;; Configuration for version control, primarily diff-hl and Git support
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;; Diff-hl Configuration
|
||||||
|
(use-package diff-hl
|
||||||
|
:ensure t
|
||||||
|
:hook ((prog-mode . diff-hl-mode)
|
||||||
|
(dired-mode . diff-hl-dired-mode)
|
||||||
|
(text-mode . diff-hl-mode)
|
||||||
|
(conf-mode . diff-hl-mode))
|
||||||
|
:bind (("M-n" . diff-hl-next-hunk)
|
||||||
|
("M-p" . diff-hl-previous-hunk)
|
||||||
|
("C-c v r" . diff-hl-revert-hunk)
|
||||||
|
("C-c v s" . diff-hl-diff-goto-hunk)
|
||||||
|
("C-c v u" . diff-hl-update))
|
||||||
|
:init
|
||||||
|
;; Set fringe width before diff-hl loads
|
||||||
|
(setq-default left-fringe-width 8)
|
||||||
|
(setq-default right-fringe-width 8)
|
||||||
|
;; Ensure fringes are visible
|
||||||
|
(fringe-mode 8)
|
||||||
|
:config
|
||||||
|
;; Configure VC backend for Git
|
||||||
|
(setq vc-handled-backends '(Git))
|
||||||
|
(setq vc-git-diff-switches '("--histogram"))
|
||||||
|
|
||||||
|
;; Tell diff-hl to use VC backend
|
||||||
|
(setq diff-hl-reference-revision nil)
|
||||||
|
(setq diff-hl-disable-on-remote nil)
|
||||||
|
|
||||||
|
;; Make diff-hl use the left fringe
|
||||||
|
(setq diff-hl-side 'left)
|
||||||
|
|
||||||
|
;; Ensure diff-hl draws in fringe, not margin
|
||||||
|
(setq diff-hl-draw-borders nil)
|
||||||
|
(setq diff-hl-margin-mode nil)
|
||||||
|
|
||||||
|
;; Set diff-hl fringe bitmaps
|
||||||
|
(setq diff-hl-fringe-bmp-function 'diff-hl-fringe-bmp-from-type)
|
||||||
|
|
||||||
|
;; Enable flydiff for real-time updates
|
||||||
|
(diff-hl-flydiff-mode 1)
|
||||||
|
|
||||||
|
;; Update immediately when visiting a file
|
||||||
|
(setq diff-hl-flydiff-delay 0.3)
|
||||||
|
|
||||||
|
;; Make sure diff-hl updates on various events
|
||||||
|
(add-hook 'after-save-hook 'diff-hl-update)
|
||||||
|
(add-hook 'after-revert-hook 'diff-hl-update)
|
||||||
|
(add-hook 'find-file-hook 'diff-hl-update)
|
||||||
|
(add-hook 'vc-checkin-hook 'diff-hl-update)
|
||||||
|
|
||||||
|
;; Enable globally with a slight delay to speed up initial startup
|
||||||
|
(run-with-idle-timer 2 nil #'global-diff-hl-mode))
|
||||||
|
|
||||||
|
;; Manual refresh command
|
||||||
|
(defun diff-hl-refresh ()
|
||||||
|
"Manually refresh diff-hl indicators in all buffers."
|
||||||
|
(interactive)
|
||||||
|
(dolist (buf (buffer-list))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(when diff-hl-mode
|
||||||
|
(diff-hl-update)))))
|
||||||
|
|
||||||
|
;; Force VC to refresh its state
|
||||||
|
(defun diff-hl-force-vc-refresh ()
|
||||||
|
"Force VC to refresh state and then update diff-hl."
|
||||||
|
(interactive)
|
||||||
|
(when buffer-file-name
|
||||||
|
(vc-refresh-state)
|
||||||
|
(diff-hl-update)
|
||||||
|
(message "VC state refreshed and diff-hl updated")))
|
||||||
|
|
||||||
|
(provide 'init-vcs)
|
||||||
|
;;; init-vcs.el ends here
|
||||||
@@ -49,6 +49,19 @@
|
|||||||
|
|
||||||
(add-hook 'shr-after-render-hook 'my-shr-apply-serif-font))
|
(add-hook 'shr-after-render-hook 'my-shr-apply-serif-font))
|
||||||
|
|
||||||
|
;; Disable the fill-column indicator (red margin line) in SHR-related modes
|
||||||
|
(defun disable-fill-column-indicator ()
|
||||||
|
"Disable the fill column indicator in the current buffer."
|
||||||
|
(display-fill-column-indicator-mode -1))
|
||||||
|
|
||||||
|
;; Add hooks to disable fill-column indicator in SHR-using modes
|
||||||
|
(add-hook 'eww-mode-hook 'disable-fill-column-indicator)
|
||||||
|
(add-hook 'elfeed-show-mode-hook 'disable-fill-column-indicator)
|
||||||
|
(add-hook 'mu4e-view-mode-hook 'disable-fill-column-indicator)
|
||||||
|
|
||||||
|
;; Also disable it after SHR renders content
|
||||||
|
(add-hook 'shr-after-render-hook 'disable-fill-column-indicator)
|
||||||
|
|
||||||
;; Disable line numbers in all modes that use SHR
|
;; Disable line numbers in all modes that use SHR
|
||||||
(defun my-shr-disable-line-numbers ()
|
(defun my-shr-disable-line-numbers ()
|
||||||
"Disable line numbers in SHR-rendered buffers."
|
"Disable line numbers in SHR-rendered buffers."
|
||||||
|
|||||||
Reference in New Issue
Block a user