Remove legacy dev config and consolidate to Eglot-based setup
- Delete emacs-dev-config.el (650 lines of legacy lsp-mode config) - Update emacs-dev-config-modern.el to use Company instead of Corfu - Remove legacy config loading from init.el and init-utils.el - Update CLAUDE.md documentation to reflect new architecture New structure: - init-eglot.el: LSP support (auto-enables for programming modes) - emacs-dev-config-modern.el: Optional extras via M-x enable-dev-mode-modern - init-completion.el: Company completion (single source of truth) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -106,7 +106,6 @@ Thumbs.db
|
||||
|
||||
# Keep these files
|
||||
!init.el
|
||||
!emacs-dev-config.el
|
||||
!init-bungee.el
|
||||
!bungee.el
|
||||
!qml-config.el
|
||||
|
||||
@@ -68,10 +68,9 @@ M-x disable-eslint-in-buffer ; Disable ESLint in current buffer
|
||||
- `init-editor.el` - Selection keybindings, shift-selection fixes
|
||||
|
||||
**Development:**
|
||||
- `init-eglot.el` - Built-in LSP client configuration
|
||||
- `init-eglot.el` - Built-in LSP client configuration (auto-enables for programming modes)
|
||||
- `init-treesitter.el` - Tree-sitter support for Emacs 29+
|
||||
- `emacs-dev-config-modern.el` - Modern development setup with Eglot
|
||||
- `emacs-dev-config.el` - Legacy LSP-mode configuration
|
||||
- `emacs-dev-config-modern.el` - Additional dev tools (yasnippet, origami, etc.) via `M-x enable-dev-mode-modern`
|
||||
|
||||
**Fix Modules:**
|
||||
- `init-emergency-fix.el` - Emergency editing restoration
|
||||
|
||||
30
init.el
30
init.el
@@ -40,20 +40,11 @@
|
||||
|
||||
;;; Load optional configurations
|
||||
|
||||
;; Development configuration - Modern version with Eglot
|
||||
;; Development configuration - Eglot-based (init-eglot.el provides base LSP support)
|
||||
;; Use M-x enable-dev-mode-modern for additional dev tools (yasnippet, origami, etc.)
|
||||
(let ((dev-config-modern (expand-file-name "lisp/emacs-dev-config-modern.el" user-emacs-directory)))
|
||||
(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.")))))))
|
||||
|
||||
;; Legacy development configuration (lsp-mode) - kept for compatibility
|
||||
(let ((dev-config (expand-file-name "lisp/emacs-dev-config.el" user-emacs-directory)))
|
||||
(when (file-exists-p dev-config)
|
||||
(load-file dev-config)))
|
||||
(load-file dev-config-modern)))
|
||||
|
||||
;; SHR Configuration (for HTML rendering in mu4e, elfeed, eww)
|
||||
(let ((shr-config (expand-file-name "lisp/shr-config.el" user-emacs-directory)))
|
||||
@@ -77,19 +68,6 @@
|
||||
(error
|
||||
(message "mu4e configuration available but mu4e not installed. Install mu4e package to enable email.")))))
|
||||
|
||||
;; Beancount Configuration
|
||||
(let ((beancount-config (expand-file-name "lisp/beancount-config.el" user-emacs-directory)))
|
||||
(when (file-exists-p beancount-config)
|
||||
(load-file beancount-config)
|
||||
(message "Beancount portfolio tracking configuration loaded.")))
|
||||
|
||||
;; Portfolio Tracker Configuration
|
||||
(with-eval-after-load 'tabulated-list
|
||||
(let ((portfolio-tracker (expand-file-name "lisp/portfolio-tracker-v2.el" user-emacs-directory)))
|
||||
(when (file-exists-p portfolio-tracker)
|
||||
(load-file portfolio-tracker)
|
||||
(message "Portfolio tracker with live prices loaded."))))
|
||||
|
||||
;; Keybinding fixes are now integrated into the respective configuration files:
|
||||
;; - Elfeed fixes in lisp/elfeed-config.el
|
||||
;; - Portfolio tracker fixes in portfolio-tracker-v2.el
|
||||
@@ -130,8 +108,6 @@
|
||||
(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")
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
"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
|
||||
'(;; Core development tools (Eglot built-in for Emacs 29+)
|
||||
consult-eglot ; Consult integration with Eglot
|
||||
flycheck ; Can still use alongside Flymake
|
||||
yasnippet
|
||||
@@ -32,13 +30,14 @@
|
||||
|
||||
;; Debugging
|
||||
dap-mode)
|
||||
"List of packages for modern development mode.")
|
||||
"List of packages for modern development mode.
|
||||
Company completion is configured globally in init-completion.el.
|
||||
Eglot LSP is configured in init-eglot.el.")
|
||||
|
||||
(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+
|
||||
(unless (package-installed-p package)
|
||||
(package-refresh-contents)
|
||||
(package-install package))))
|
||||
|
||||
@@ -58,15 +57,14 @@
|
||||
(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)))))
|
||||
"Setup completion for development.
|
||||
Company is configured globally in init-completion.el.
|
||||
This function adds development-specific tweaks."
|
||||
;; More aggressive completion in programming modes
|
||||
(add-hook 'prog-mode-hook
|
||||
(lambda ()
|
||||
(setq-local company-idle-delay 0.1)
|
||||
(setq-local company-minimum-prefix-length 1))))
|
||||
|
||||
(defun dev-mode-modern-setup-yasnippet ()
|
||||
"Configure yasnippet for code snippets."
|
||||
|
||||
@@ -1,619 +0,0 @@
|
||||
;;; -*- lexical-binding: t -*-
|
||||
;;; emacs-dev-config.el --- Development configuration for Emacs
|
||||
;;; Commentary:
|
||||
;;; Development-related configurations including LSP, languages, debugging, etc.
|
||||
;;; Use M-x enable-dev-mode to activate this configuration
|
||||
;;; Use M-x disable-dev-mode to deactivate this configuration
|
||||
|
||||
;;; Code:
|
||||
|
||||
(defvar dev-mode-enabled nil
|
||||
"Flag indicating whether development mode is enabled.")
|
||||
|
||||
(defvar dev-mode-packages
|
||||
`(;; Development tools
|
||||
lsp-mode lsp-ui lsp-treemacs
|
||||
company company-box
|
||||
flycheck yasnippet
|
||||
ggtags multiple-cursors expand-region
|
||||
hl-todo rainbow-delimiters
|
||||
origami ;; Code folding
|
||||
|
||||
;; Version control
|
||||
magit
|
||||
,@(when (executable-find "delta") '(magit-delta)) ;; Only if delta is installed
|
||||
treemacs-magit
|
||||
|
||||
;; Helm integration for development
|
||||
helm-lsp helm-xref
|
||||
|
||||
;; Languages
|
||||
clang-format qml-mode company-qml
|
||||
|
||||
;; Debugging
|
||||
dap-mode)
|
||||
"List of packages required for development mode.")
|
||||
|
||||
(defun dev-mode-ensure-packages ()
|
||||
"Ensure all development packages are installed."
|
||||
(dolist (package dev-mode-packages)
|
||||
(unless (package-installed-p package)
|
||||
(package-refresh-contents)
|
||||
(package-install package))))
|
||||
|
||||
(defun dev-mode-setup-lsp ()
|
||||
"Configure LSP mode for development."
|
||||
(use-package lsp-mode
|
||||
:ensure t
|
||||
:hook ((c-mode c++-mode python-mode) . lsp-deferred) ; Removed qml-mode - Qt5 has no LSP
|
||||
:commands (lsp lsp-deferred)
|
||||
:config
|
||||
(setq lsp-keymap-prefix "C-c l")
|
||||
(setq lsp-idle-delay 0.5)
|
||||
(setq lsp-log-io nil)
|
||||
(setq lsp-completion-enable t)
|
||||
(setq lsp-headerline-breadcrumb-enable t)
|
||||
(setq lsp-enable-snippet t)
|
||||
(setq lsp-enable-semantic-highlighting t))
|
||||
|
||||
(use-package lsp-ui
|
||||
:ensure t
|
||||
:commands lsp-ui-mode
|
||||
:config
|
||||
(setq lsp-ui-doc-enable t)
|
||||
(setq lsp-ui-doc-position 'bottom)
|
||||
(setq lsp-ui-doc-delay 1)
|
||||
(setq lsp-ui-sideline-enable t)
|
||||
(setq lsp-ui-sideline-show-hover t)
|
||||
(setq lsp-ui-sideline-show-diagnostics t)
|
||||
(setq lsp-ui-sideline-show-code-actions t))
|
||||
|
||||
(use-package helm-lsp
|
||||
:ensure t
|
||||
:commands helm-lsp-workspace-symbol)
|
||||
|
||||
(use-package lsp-treemacs
|
||||
:ensure t
|
||||
:commands lsp-treemacs-errors-list))
|
||||
|
||||
(defun dev-mode-setup-company ()
|
||||
"Configure company mode for auto-completion."
|
||||
(use-package company
|
||||
:ensure t
|
||||
:hook (after-init . global-company-mode)
|
||||
:bind (:map company-active-map
|
||||
("C-n" . company-select-next)
|
||||
("C-p" . company-select-previous)
|
||||
("TAB" . company-complete-selection))
|
||||
:config
|
||||
(setq company-idle-delay 0.2)
|
||||
(setq company-minimum-prefix-length 1)
|
||||
(setq company-selection-wrap-around t)
|
||||
(setq company-show-numbers t)
|
||||
(setq company-tooltip-align-annotations t))
|
||||
|
||||
(use-package company-box
|
||||
:ensure t
|
||||
:hook (company-mode . company-box-mode)))
|
||||
|
||||
(defun dev-mode-setup-flycheck ()
|
||||
"Configure flycheck for syntax checking."
|
||||
(use-package flycheck
|
||||
:ensure t
|
||||
:init (global-flycheck-mode)
|
||||
:config
|
||||
(setq flycheck-display-errors-delay 0.3)
|
||||
(setq flycheck-gcc-language-standard "c++17")
|
||||
(setq flycheck-clang-language-standard "c++17")))
|
||||
|
||||
(defun dev-mode-setup-yasnippet ()
|
||||
"Configure yasnippet for code snippets."
|
||||
(use-package yasnippet
|
||||
:ensure t
|
||||
:config
|
||||
(yas-global-mode 1)))
|
||||
|
||||
;; Project management is now handled by project.el in init-project.el
|
||||
(defun dev-mode-setup-project ()
|
||||
"Configure project.el for project management."
|
||||
;; Project configuration is in init-project.el
|
||||
;; Add any dev-specific project configs here
|
||||
(with-eval-after-load 'project
|
||||
(define-key project-prefix-map (kbd "c") 'project-compile)
|
||||
(define-key project-prefix-map (kbd "t") 'recompile)))
|
||||
|
||||
(defun dev-mode-setup-ggtags ()
|
||||
"Configure ggtags for code navigation."
|
||||
(use-package ggtags
|
||||
:ensure t
|
||||
:hook ((c-mode c++-mode python-mode) . ggtags-mode)
|
||||
:bind (:map ggtags-mode-map
|
||||
("C-c g s" . ggtags-find-other-symbol)
|
||||
("C-c g h" . ggtags-view-tag-history)
|
||||
("C-c g r" . ggtags-find-reference)
|
||||
("C-c g f" . ggtags-find-file)
|
||||
("C-c g c" . ggtags-create-tags))
|
||||
:config
|
||||
(setq ggtags-completing-read-function nil)
|
||||
(setq ggtags-navigation-mode-lighter nil)
|
||||
(setq ggtags-mode-line-project-name nil)))
|
||||
|
||||
(defun dev-mode-setup-origami ()
|
||||
"Configure Origami for code folding."
|
||||
(use-package origami
|
||||
:ensure t
|
||||
:config
|
||||
;; Define global keybindings for origami (using C-c o prefix to avoid conflict)
|
||||
(global-set-key (kbd "C-c o f") 'origami-toggle-node)
|
||||
(global-set-key (kbd "C-c o o") 'origami-open-node)
|
||||
(global-set-key (kbd "C-c o c") 'origami-close-node)
|
||||
(global-set-key (kbd "C-c o a") 'origami-close-all-nodes)
|
||||
(global-set-key (kbd "C-c o A") 'origami-open-all-nodes)
|
||||
(global-set-key (kbd "C-c o t") 'origami-toggle-all-nodes)
|
||||
(global-set-key (kbd "C-c o r") 'origami-recursively-toggle-node)
|
||||
(global-set-key (kbd "C-c o R") 'origami-open-node-recursively)
|
||||
(global-set-key (kbd "C-c o n") 'origami-next-fold)
|
||||
(global-set-key (kbd "C-c o p") 'origami-previous-fold)
|
||||
(global-set-key (kbd "C-c o s") 'origami-show-only-node)
|
||||
(global-set-key (kbd "C-c o u") 'origami-undo)
|
||||
(global-set-key (kbd "C-c o d") 'origami-redo)
|
||||
|
||||
;; Setup origami
|
||||
(setq origami-show-fold-header t)
|
||||
|
||||
;; Enable origami mode globally for programming modes
|
||||
(global-origami-mode 1)
|
||||
|
||||
;; Add hook to ensure origami works in prog-mode buffers
|
||||
(add-hook 'prog-mode-hook 'origami-mode)
|
||||
|
||||
;; Initialize parsers
|
||||
(origami-mode 1)
|
||||
|
||||
;; Face customization for fold markers (only if faces exist)
|
||||
(when (facep 'origami-fold-header-face)
|
||||
(set-face-attribute 'origami-fold-header-face nil
|
||||
:box nil
|
||||
:foreground "dim gray"))
|
||||
(when (facep 'origami-fold-fringe-face)
|
||||
(set-face-attribute 'origami-fold-fringe-face nil
|
||||
:foreground "dim gray"))))
|
||||
|
||||
(defun dev-mode-setup-editing-tools ()
|
||||
"Configure advanced editing tools."
|
||||
(use-package multiple-cursors
|
||||
:ensure t
|
||||
:bind (("C-S-l" . mc/edit-lines)
|
||||
("C-S-d" . mc/mark-all-like-this)
|
||||
("C->" . mc/mark-next-like-this)
|
||||
("C-<" . mc/mark-previous-like-this)
|
||||
("C-c M n" . mc/skip-to-next-like-this)
|
||||
("C-c M p" . mc/skip-to-previous-like-this)
|
||||
("C-S-<mouse-1>" . mc/add-cursor-on-click)))
|
||||
|
||||
(use-package expand-region
|
||||
:ensure t
|
||||
:bind ("C-=" . er/expand-region))
|
||||
|
||||
(use-package hl-todo
|
||||
:ensure t
|
||||
:hook (prog-mode . hl-todo-mode)
|
||||
:config
|
||||
(setq hl-todo-keyword-faces
|
||||
'(("TODO" . "#FF0000")
|
||||
("FIXME" . "#FF0000")
|
||||
("DEBUG" . "#A020F0")
|
||||
("GOTCHA" . "#FF4500")
|
||||
("STUB" . "#1E90FF"))))
|
||||
|
||||
(use-package rainbow-delimiters
|
||||
:ensure t
|
||||
:hook (prog-mode . rainbow-delimiters-mode)))
|
||||
|
||||
(defun dev-mode-setup-languages ()
|
||||
"Configure language-specific settings."
|
||||
;; C/C++ Configuration
|
||||
(use-package cc-mode
|
||||
:ensure nil
|
||||
:mode (("\\.cpp\\'" . c++-mode)
|
||||
("\\.hpp\\'" . c++-mode)
|
||||
("\\.cc\\'" . c++-mode)
|
||||
("\\.hh\\'" . c++-mode)
|
||||
("\\.cxx\\'" . c++-mode)
|
||||
("\\.hxx\\'" . c++-mode))
|
||||
:config
|
||||
(setq c-default-style "linux"
|
||||
c-basic-offset 4)
|
||||
(add-hook 'c++-mode-hook 'electric-pair-local-mode)
|
||||
(add-hook 'c++-mode-hook
|
||||
(lambda ()
|
||||
(setq compile-command
|
||||
(concat "g++ -Wall -Wextra -std=c++17 -g -o "
|
||||
(file-name-sans-extension (buffer-name))
|
||||
" "
|
||||
(buffer-name)))
|
||||
(local-set-key (kbd "C-c c") 'compile)
|
||||
(local-set-key (kbd "C-c r") 'gdb)
|
||||
(local-set-key (kbd "C-c C-c") 'recompile))))
|
||||
|
||||
(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)))
|
||||
|
||||
;; Python Configuration
|
||||
(use-package python
|
||||
:ensure nil
|
||||
:mode ("\\.py\\'" . python-mode)
|
||||
:config
|
||||
(setq python-indent-offset 4)
|
||||
(setq python-shell-interpreter "python3")
|
||||
(add-hook 'python-mode-hook
|
||||
(lambda ()
|
||||
(setq compile-command (concat "python3 " (buffer-name)))
|
||||
(local-set-key (kbd "C-c c") 'compile)
|
||||
(local-set-key (kbd "C-c r") 'run-python)
|
||||
(local-set-key (kbd "C-c C-c") 'python-shell-send-buffer))))
|
||||
|
||||
;; QML Configuration - Always use qml-mode for .qml files (not JavaScript mode)
|
||||
(use-package qml-mode
|
||||
:ensure t
|
||||
:mode ("\\.qml\\'" . qml-mode)
|
||||
:init
|
||||
;; Remove any potential js-mode associations for .qml files
|
||||
(setq auto-mode-alist (delete '("\\.qml\\'" . js-mode) auto-mode-alist))
|
||||
(setq auto-mode-alist (delete '("\\.qml\\'" . javascript-mode) auto-mode-alist))
|
||||
(setq auto-mode-alist (delete '("\\.qml\\'" . js2-mode) auto-mode-alist))
|
||||
(setq auto-mode-alist (delete '("\\.qml\\'" . js3-mode) auto-mode-alist))
|
||||
(setq auto-mode-alist (delete '("\\.qml\\'" . rjsx-mode) auto-mode-alist))
|
||||
:config
|
||||
;; Ensure qml-mode is at the front of auto-mode-alist
|
||||
(add-to-list 'auto-mode-alist '("\\.qml\\'" . qml-mode))
|
||||
(message "QML mode configured for .qml files"))
|
||||
|
||||
(use-package company-qml
|
||||
:ensure t
|
||||
:after (company qml-mode)
|
||||
:config
|
||||
(add-to-list 'company-backends 'company-qml)))
|
||||
|
||||
(defun dev-mode-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
|
||||
;; Configure Magit integration
|
||||
(setq vc-follow-symlinks t)
|
||||
(setq vc-display-status t) ; Enable to show VC status in mode line
|
||||
|
||||
;; Configure Magit status sections
|
||||
(setq magit-status-sections-hook
|
||||
'(magit-insert-status-headers
|
||||
magit-insert-merge-log
|
||||
magit-insert-rebase-sequence
|
||||
magit-insert-am-sequence
|
||||
magit-insert-sequencer-sequence
|
||||
magit-insert-bisect-output
|
||||
magit-insert-bisect-rest
|
||||
magit-insert-bisect-log
|
||||
magit-insert-untracked-files
|
||||
magit-insert-unstaged-changes
|
||||
magit-insert-staged-changes
|
||||
magit-insert-stashes
|
||||
magit-insert-unpushed-to-pushremote
|
||||
magit-insert-unpushed-to-upstream-or-recent
|
||||
magit-insert-unpulled-from-pushremote
|
||||
magit-insert-unpulled-from-upstream
|
||||
magit-insert-recent-commits))
|
||||
|
||||
(setq magit-log-section-commit-count 10)
|
||||
(setq magit-log-arguments '("--graph" "--color" "--decorate" "--all"))
|
||||
(setq magit-log-section-arguments '("--graph" "--color" "--decorate" "-n256" "--all"))
|
||||
(setq magit-log-margin '(t "%Y-%m-%d %H:%M " magit-log-margin-width t 18))
|
||||
(setq magit-log-show-refname-after-summary t)
|
||||
(setq magit-diff-refine-hunk 'all))
|
||||
|
||||
;; Only enable magit-delta if delta is installed
|
||||
(when (executable-find "delta")
|
||||
(use-package magit-delta
|
||||
:ensure t
|
||||
:hook (magit-mode . magit-delta-mode)))
|
||||
|
||||
(use-package treemacs-magit
|
||||
:ensure t
|
||||
:after (treemacs magit))
|
||||
|
||||
;; Custom Magit functions
|
||||
(defun magit-save-commit-as-patch ()
|
||||
"Save the commit at point as a patch file."
|
||||
(interactive)
|
||||
(let* ((commit (or (magit-commit-at-point)
|
||||
(error "No commit at point")))
|
||||
(default-name (format "%s.patch"
|
||||
(substring commit 0 (min 8 (length commit)))))
|
||||
(file (read-file-name "Save patch to file: "
|
||||
default-directory
|
||||
default-name
|
||||
nil
|
||||
default-name))
|
||||
(default-directory (magit-toplevel)))
|
||||
(if (zerop (shell-command
|
||||
(format "git format-patch -1 %s --stdout > %s"
|
||||
(shell-quote-argument commit)
|
||||
(shell-quote-argument (expand-file-name file)))))
|
||||
(message "Patch saved to %s" file)
|
||||
(error "Failed to save patch"))))
|
||||
|
||||
;; Set up keybindings for saving patches
|
||||
(with-eval-after-load 'magit
|
||||
(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-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
|
||||
;; Only enable if you want Magit to control diff-hl updates
|
||||
;; Comment out these lines if diff-hl has issues with Magit
|
||||
(when (and (fboundp 'diff-hl-mode)
|
||||
(not (bound-and-true-p diff-hl-disable-magit-integration)))
|
||||
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
|
||||
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
|
||||
|
||||
;; Fix common Magit issues
|
||||
(defun magit-fix-refresh ()
|
||||
"Fix Magit refresh issues."
|
||||
(interactive)
|
||||
(setq magit-refresh-verbose t)
|
||||
(setq magit-git-executable (executable-find "git"))
|
||||
(when (and buffer-file-name (vc-backend buffer-file-name))
|
||||
(vc-refresh-state))
|
||||
(magit-refresh)
|
||||
(message "Magit refresh fixed. Git executable: %s" magit-git-executable))
|
||||
|
||||
;; Diagnose Magit issues
|
||||
(defun magit-diagnose ()
|
||||
"Diagnose Magit configuration."
|
||||
(interactive)
|
||||
(let ((diagnosis '()))
|
||||
(push (format "Git executable: %s" (executable-find "git")) diagnosis)
|
||||
(push (format "Magit git executable: %s" magit-git-executable) diagnosis)
|
||||
(push (format "Delta installed: %s" (if (executable-find "delta") "yes" "no")) diagnosis)
|
||||
(push (format "Magit-delta mode: %s" (if (bound-and-true-p magit-delta-mode) "enabled" "disabled")) diagnosis)
|
||||
(push (format "Default directory: %s" default-directory) diagnosis)
|
||||
(push (format "In git repo: %s" (magit-toplevel)) diagnosis)
|
||||
(push (format "Git version: %s" (magit-git-version)) diagnosis)
|
||||
(push (format "Magit version: %s" (magit-version)) diagnosis)
|
||||
(message (mapconcat 'identity (nreverse diagnosis) "\n"))))
|
||||
|
||||
;; Disable magit-delta if causing issues
|
||||
(defun magit-disable-delta ()
|
||||
"Disable magit-delta mode."
|
||||
(interactive)
|
||||
(when (fboundp 'magit-delta-mode)
|
||||
(magit-delta-mode -1)
|
||||
(remove-hook 'magit-mode-hook 'magit-delta-mode)
|
||||
(message "Magit-delta disabled. Using standard git diff."))))
|
||||
|
||||
(defun dev-mode-setup-debugging ()
|
||||
"Configure debugging support."
|
||||
(use-package dap-mode
|
||||
:ensure t
|
||||
:commands (dap-debug dap-debug-edit-template)
|
||||
;; Don't auto-enable - only load when explicitly needed
|
||||
:config
|
||||
(require 'dap-python)
|
||||
(require 'dap-gdb-lldb)
|
||||
;; Don't auto-configure globally - causes performance issues
|
||||
;; (dap-auto-configure-mode 1) ; Commented out for performance
|
||||
(setq dap-auto-configure-features '(sessions locals controls tooltip))))
|
||||
|
||||
(defun dev-mode-custom-functions ()
|
||||
"Define custom development functions."
|
||||
(defun generate-cpp-tags ()
|
||||
"Generate TAGS file for C++ project."
|
||||
(interactive)
|
||||
(require 'project)
|
||||
(let ((project-root (or (when-let ((proj (project-current)))
|
||||
(project-root proj))
|
||||
default-directory)))
|
||||
(shell-command
|
||||
(format "cd %s && find . -name '*.cpp' -o -name '*.hpp' -o -name '*.cc' -o -name '*.hh' -o -name '*.c' -o -name '*.h' | etags -"
|
||||
project-root))
|
||||
(visit-tags-table (concat project-root "TAGS"))
|
||||
(message "C++ TAGS file generated for project: %s" project-root)))
|
||||
|
||||
(defun generate-python-tags ()
|
||||
"Generate TAGS file for Python project."
|
||||
(interactive)
|
||||
(require 'project)
|
||||
(let ((project-root (or (when-let ((proj (project-current)))
|
||||
(project-root proj))
|
||||
default-directory)))
|
||||
(shell-command
|
||||
(format "cd %s && find . -name '*.py' | etags -"
|
||||
project-root))
|
||||
(visit-tags-table (concat project-root "TAGS"))
|
||||
(message "Python TAGS file generated for project: %s" project-root)))
|
||||
|
||||
(defun generate-all-tags ()
|
||||
"Generate TAGS file for both C++ and Python files."
|
||||
(interactive)
|
||||
(require 'project)
|
||||
(let ((project-root (or (when-let ((proj (project-current)))
|
||||
(project-root proj))
|
||||
default-directory)))
|
||||
(shell-command
|
||||
(format "cd %s && find . -name '*.cpp' -o -name '*.hpp' -o -name '*.cc' -o -name '*.hh' -o -name '*.c' -o -name '*.h' -o -name '*.py' | etags -"
|
||||
project-root))
|
||||
(visit-tags-table (concat project-root "TAGS"))
|
||||
(message "TAGS file generated for all supported files in: %s" project-root)))
|
||||
|
||||
(defun quick-compile-and-run ()
|
||||
"Quick compile and run current file."
|
||||
(interactive)
|
||||
(save-buffer)
|
||||
(cond
|
||||
((derived-mode-p 'c++-mode)
|
||||
(shell-command
|
||||
(format "g++ -std=c++17 -o %s %s && ./%s"
|
||||
(file-name-sans-extension (buffer-name))
|
||||
(buffer-name)
|
||||
(file-name-sans-extension (buffer-name)))))
|
||||
((derived-mode-p 'python-mode)
|
||||
(shell-command (format "python3 %s" (buffer-name))))
|
||||
(t (message "Unsupported file type for quick compile and run")))))
|
||||
|
||||
(defun dev-mode-setup-keybindings ()
|
||||
"Set up development-specific keybindings."
|
||||
;; Tag generation - use C-c C-t prefix to avoid conflict with CUA copy
|
||||
(global-set-key (kbd "C-c C-t c") 'generate-cpp-tags)
|
||||
(global-set-key (kbd "C-c C-t p") 'generate-python-tags)
|
||||
(global-set-key (kbd "C-c C-t a") 'generate-all-tags)
|
||||
(global-set-key (kbd "C-c C-q") 'quick-compile-and-run)
|
||||
(global-set-key (kbd "M-.") 'xref-find-definitions)
|
||||
(global-set-key (kbd "M-,") 'xref-pop-marker-stack)
|
||||
(global-set-key (kbd "C-M-.") 'xref-find-references)
|
||||
|
||||
;; Helper function to refresh origami in current buffer
|
||||
(defun origami-reset-buffer ()
|
||||
"Reset origami in the current buffer."
|
||||
(interactive)
|
||||
(when (bound-and-true-p origami-mode)
|
||||
(origami-mode -1)
|
||||
(origami-mode 1)
|
||||
(message "Origami reset in buffer")))
|
||||
|
||||
(global-set-key (kbd "C-c f 0") 'origami-reset-buffer))
|
||||
|
||||
(defun show-dev-mode-help ()
|
||||
"Show key bindings for development configuration."
|
||||
(interactive)
|
||||
(with-output-to-temp-buffer "*Development Mode Help*"
|
||||
(princ "=== Development Mode Key Bindings ===\n\n")
|
||||
(princ "EDITING (CUA MODE):\n")
|
||||
(princ " C-c : Copy\n")
|
||||
(princ " C-v : Paste\n")
|
||||
(princ " C-x : Cut\n")
|
||||
(princ " C-z : Undo\n")
|
||||
(princ " C-<return> : Rectangle selection\n\n")
|
||||
(princ "LSP COMMANDS:\n")
|
||||
(princ " C-c l : LSP prefix for all LSP commands\n")
|
||||
(princ " M-. : Go to definition\n")
|
||||
(princ " M-, : Return from definition\n")
|
||||
(princ " C-M-. : Find references\n\n")
|
||||
(princ "TAGS & NAVIGATION:\n")
|
||||
(princ " C-c C-t c : Generate C++ TAGS file\n")
|
||||
(princ " C-c C-t p : Generate Python TAGS file\n")
|
||||
(princ " C-c C-t a : Generate TAGS for all files\n\n")
|
||||
(princ "COMPILATION & EXECUTION:\n")
|
||||
(princ " C-c c : Compile current file\n")
|
||||
(princ " C-c r : Run (GDB for C++, Python REPL for Python)\n")
|
||||
(princ " C-c C-q : Quick compile and run\n")
|
||||
(princ " C-c C-c : Recompile (C++) or Send buffer to Python\n\n")
|
||||
(princ "PROJECT MANAGEMENT:\n")
|
||||
(princ " C-x p : Project commands prefix\n")
|
||||
(princ " C-c p : Additional project bindings (compatibility)\n\n")
|
||||
(princ "VERSION CONTROL (MAGIT):\n")
|
||||
(princ " C-x g : Magit status\n")
|
||||
(princ " C-x M-g : Magit dispatch\n")
|
||||
(princ " C-c g : Magit file dispatch\n")
|
||||
(princ " C-c C-p : Save commit as patch (in Magit buffers)\n\n")
|
||||
(princ "EDITING:\n")
|
||||
(princ " C-= : Expand region\n")
|
||||
(princ " C-> : Mark next like this (multiple cursors)\n")
|
||||
(princ " C-< : Mark previous like this\n")
|
||||
(princ " C-S-d : Mark all like this\n\n")
|
||||
(princ "CODE FOLDING (ORIGAMI):\n")
|
||||
(princ " C-c f f : Toggle fold at point\n")
|
||||
(princ " C-c f o : Open fold\n")
|
||||
(princ " C-c f c : Close fold\n")
|
||||
(princ " C-c f a : Close all folds\n")
|
||||
(princ " C-c f A : Open all folds\n")
|
||||
(princ " C-c f t : Toggle all folds\n")
|
||||
(princ " C-c f r : Recursively toggle fold\n")
|
||||
(princ " C-c f n/p : Next/Previous fold\n")
|
||||
(princ " C-c f s : Show only current fold\n\n")
|
||||
(princ "LANGUAGE MODES:\n")
|
||||
(princ " .qml files : Always use qml-mode (not JavaScript mode)\n")
|
||||
(princ " .py files : Python mode with LSP support\n")
|
||||
(princ " .cpp/.hpp : C++ mode with LSP support\n\n")
|
||||
(princ "DEVELOPMENT MODE:\n")
|
||||
(princ " M-x enable-dev-mode : Enable development mode\n")
|
||||
(princ " M-x disable-dev-mode : Disable development mode\n")
|
||||
(princ " C-c h : Show this help\n")))
|
||||
|
||||
;;;###autoload
|
||||
(defun enable-dev-mode ()
|
||||
"Enable development mode with all programming tools."
|
||||
(interactive)
|
||||
(if dev-mode-enabled
|
||||
(message "Development mode is already enabled")
|
||||
(message "Enabling development mode...")
|
||||
;; Ensure packages are installed
|
||||
(dev-mode-ensure-packages)
|
||||
;; Set up all development features
|
||||
(dev-mode-setup-lsp)
|
||||
(dev-mode-setup-company)
|
||||
(dev-mode-setup-flycheck)
|
||||
(dev-mode-setup-yasnippet)
|
||||
(dev-mode-setup-project)
|
||||
(dev-mode-setup-ggtags)
|
||||
(dev-mode-setup-origami)
|
||||
(dev-mode-setup-editing-tools)
|
||||
(dev-mode-setup-languages)
|
||||
(dev-mode-setup-magit)
|
||||
(dev-mode-setup-debugging)
|
||||
(dev-mode-custom-functions)
|
||||
(dev-mode-setup-keybindings)
|
||||
;; Ensure QML files use qml-mode (override any JS mode associations)
|
||||
(add-to-list 'auto-mode-alist '("\\.qml\\'" . qml-mode))
|
||||
;; Set up help command
|
||||
(global-set-key (kbd "C-c h") 'show-dev-mode-help)
|
||||
;; Stop elfeed auto-updates to prevent UI lag
|
||||
(when (fboundp 'elfeed-stop-auto-updates)
|
||||
(elfeed-stop-auto-updates))
|
||||
(setq dev-mode-enabled t)
|
||||
(message "Development mode enabled! Press C-c h for help. QML files will use qml-mode. Elfeed auto-updates disabled.")))
|
||||
|
||||
;;;###autoload
|
||||
(defun disable-dev-mode ()
|
||||
"Disable development mode."
|
||||
(interactive)
|
||||
(if (not dev-mode-enabled)
|
||||
(message "Development mode is not enabled")
|
||||
(message "Disabling development mode...")
|
||||
;; Disable major modes that can be toggled
|
||||
(global-company-mode -1)
|
||||
(global-flycheck-mode -1)
|
||||
(yas-global-mode -1)
|
||||
;; Project.el is built-in, no need to disable
|
||||
(global-hl-todo-mode -1)
|
||||
;; Re-enable elfeed auto-updates
|
||||
(when (fboundp 'elfeed-start-auto-updates)
|
||||
(elfeed-start-auto-updates))
|
||||
;; Note: Some modes might require restarting Emacs to fully disable
|
||||
(setq dev-mode-enabled nil)
|
||||
(message "Development mode disabled. Elfeed auto-updates re-enabled. Some features may require restarting Emacs to fully disable.")))
|
||||
|
||||
;;;###autoload
|
||||
(defun dev-mode-status ()
|
||||
"Check if development mode is enabled."
|
||||
(interactive)
|
||||
(if dev-mode-enabled
|
||||
(message "Development mode is ENABLED")
|
||||
(message "Development mode is DISABLED")))
|
||||
|
||||
(provide 'emacs-dev-config)
|
||||
;;; emacs-dev-config.el ends here
|
||||
@@ -85,6 +85,45 @@
|
||||
;; Enhanced font-lock for tree-sitter modes
|
||||
(setq treesit-font-lock-level 3) ; Balanced highlighting (was 4, reduced for performance)
|
||||
|
||||
;; C/C++ Tree-sitter indentation - Allman style with 4 spaces
|
||||
(with-eval-after-load 'c-ts-mode
|
||||
;; Set indentation offset to 4 spaces
|
||||
(setq c-ts-mode-indent-offset 4)
|
||||
|
||||
;; Configure Allman style for C/C++ tree-sitter modes
|
||||
(defun my-c-ts-mode-setup ()
|
||||
"Configure C tree-sitter mode for Allman style."
|
||||
(setq-local indent-tabs-mode nil
|
||||
tab-width 4
|
||||
c-ts-mode-indent-offset 4))
|
||||
|
||||
(defun my-c++-ts-mode-setup ()
|
||||
"Configure C++ tree-sitter mode for Allman style."
|
||||
(setq-local indent-tabs-mode nil
|
||||
tab-width 4
|
||||
c-ts-mode-indent-offset 4))
|
||||
|
||||
(add-hook 'c-ts-mode-hook #'my-c-ts-mode-setup)
|
||||
(add-hook 'c++-ts-mode-hook #'my-c++-ts-mode-setup)
|
||||
|
||||
;; Custom indentation rules for Allman style
|
||||
;; These rules ensure braces go on new lines
|
||||
(setq c-ts-mode-indent-style 'linux) ; Base style, we'll override specific rules
|
||||
|
||||
;; Add clang-format support for tree-sitter modes
|
||||
(with-eval-after-load 'clang-format
|
||||
;; Bind clang-format to C-c C-f in tree-sitter C/C++ modes
|
||||
(defun setup-clang-format-for-c-ts-modes ()
|
||||
"Set up clang-format keybinding for C/C++ tree-sitter modes."
|
||||
(local-set-key (kbd "C-c C-f") 'clang-format-buffer))
|
||||
|
||||
(add-hook 'c-ts-mode-hook #'setup-clang-format-for-c-ts-modes)
|
||||
(add-hook 'c++-ts-mode-hook #'setup-clang-format-for-c-ts-modes))
|
||||
|
||||
;; Note: Tree-sitter C mode indentation is less configurable than cc-mode
|
||||
;; For full Allman style control, use clang-format (C-c C-f)
|
||||
(message "C/C++ tree-sitter mode configured for Allman style with 4-space indentation"))
|
||||
|
||||
;; Tree-sitter debugging helpers
|
||||
(defun treesit-inspect-node-at-point ()
|
||||
"Show tree-sitter node information at point."
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
:foundry "nil"
|
||||
:slant 'normal
|
||||
:weight 'regular
|
||||
:height 180
|
||||
:height 120
|
||||
:width 'normal)
|
||||
|
||||
;; Ensure font settings apply to new frames
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
;; 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 "lisp/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 "lisp/shr-config.el" user-emacs-directory)))
|
||||
(when (file-exists-p shr-config)
|
||||
@@ -98,7 +93,6 @@ to prevent UI freezing. With prefix ARG, use blocking reload."
|
||||
(cl-remove-if-not
|
||||
#'file-exists-p
|
||||
(list (expand-file-name "init.el" user-emacs-directory)
|
||||
(expand-file-name "lisp/emacs-dev-config.el" user-emacs-directory)
|
||||
(expand-file-name "lisp/shr-config.el" user-emacs-directory)
|
||||
(expand-file-name "lisp/elfeed-config.el" user-emacs-directory)
|
||||
(expand-file-name "lisp/mu4e-config.el" user-emacs-directory))))
|
||||
@@ -129,7 +123,6 @@ to prevent UI freezing. With prefix ARG, use blocking reload."
|
||||
(cl-remove-if-not
|
||||
#'file-exists-p
|
||||
(list
|
||||
(expand-file-name "lisp/emacs-dev-config.el" user-emacs-directory)
|
||||
(expand-file-name "lisp/shr-config.el" user-emacs-directory)
|
||||
(expand-file-name "lisp/elfeed-config.el" user-emacs-directory)
|
||||
(expand-file-name "lisp/mu4e-config.el" user-emacs-directory)))))
|
||||
@@ -188,7 +181,7 @@ to prevent UI freezing. With prefix ARG, use blocking reload."
|
||||
(message "Error reloading %s: %s"
|
||||
(file-name-nondirectory file) err))))
|
||||
(message "Smart reload complete!"))
|
||||
(message "No files changed recently. Use C-u C-c C-r for full reload.")))))
|
||||
(message "No files changed recently. Use C-u C-c C-r for full reload."))))))
|
||||
|
||||
(defun reload-current-file ()
|
||||
"Reload only the current file if it's an Emacs Lisp file."
|
||||
@@ -271,7 +264,7 @@ This is the fastest reload method but requires byte-compilation."
|
||||
(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."))
|
||||
(message "Development mode is available. Use M-x enable-dev-mode-modern to activate yasnippet, origami, and other development tools. LSP (Eglot) is already active for programming modes."))
|
||||
|
||||
;;; God-mode helpers
|
||||
(defun enable-god-mode-config ()
|
||||
@@ -284,7 +277,7 @@ This is the fastest reload method but requires byte-compilation."
|
||||
(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)))))
|
||||
(message "God-mode config file not found at %s" god-config))))
|
||||
|
||||
(provide 'init-utils)
|
||||
;;; init-utils.el ends here
|
||||
Reference in New Issue
Block a user