Table of Contents

1. General Programming Configuration

Common programming tools and utilities that apply across all languages.

1.1. Overview

This module provides:

  • Compilation: Enhanced compilation mode with ANSI colors
  • Version Control: Magit and merge conflict resolution
  • Project Management: Built-in project.el with custom markers and Magit integration
  • Documentation: Eldoc for inline documentation
  • Code Quality: Flymake for syntax checking
  • Editing Utilities: Electric pairs, parenthesis matching
  • Multi-Cursor Editing: Multiple cursors and intelligent region expansion
  • Diff & Merge: Advanced diff viewing and merge conflict resolution
  • Code Snippets: Template expansion with YASnippet
  • LSP: Language Server Protocol support with Eglot
  • REST Client: HTTP API testing from Emacs

1.2. What's Included

Category Tools
Build Tools compile, makefile-mode
Version Control magit, smerge-mode
Project Management project.el with custom markers
Documentation eldoc, eldoc-box
Syntax Checking flymake
Editing electric-pair, paren
Multi-Cursor Editing multiple-cursors, expand-region
Diff & Merge diff-mode, ediff
Code Snippets yasnippet
LSP eglot
REST Client restclient
File Formats conf-mode, yaml-mode, powershell, sql-indent

1.3. Compilation and Build Tools

Enhanced compilation mode with ANSI color support for better readability of build output. Includes support for Makefiles and configuration files.

Features:

  • ANSI color filtering in compilation buffers
  • Auto-scroll compilation output
  • Always kill existing compilation before starting new one
  • Tree-sitter support for Makefiles
;;; prog-general-conf.el --- General programming configuration -*- lexical-binding: t; -*-
;;; Commentary:
;;; General programming tools: compilation, version control,
;;; syntax checking, and common programming utilities.
;;; Code:

;; Compilation
(use-package compile
  :ensure nil
  :custom
  (compilation-always-kill t)
  (compilation-scroll-output t)
  (ansi-color-for-compilation-mode t)
  :config
  (add-hook 'compilation-filter-hook #'ansi-color-compilation-filter))

;; Makefile
(use-package makefile-mode
  :ensure nil
  :mode "\\Makefile.*\\'"
  :defer 't
  :config
  (add-to-list 'treesit-language-source-alist '(make "https://github.com/alemuller/tree-sitter-make")))

;; Configuration files
(use-package conf-mode
  :ensure nil
  :mode ("\\.env\\..*\\'" "\\.env\\'")
  :init
  (add-to-list 'auto-mode-alist '("\\.env\\'" . conf-mode)))

;; SQL
(use-package sql-indent
  :hook
  (sql-mode . sqlind-minor-mode))

(use-package powershell :defer t)
(use-package yaml-mode :defer t)

1.4. Version Control

Magit is the premier Git interface for Emacs, providing a comprehensive and intuitive way to work with Git repositories. Smerge-mode helps resolve merge conflicts directly in buffers.

Features:

  • Full-featured Git interface with C-x g
  • Same-window display (vim-fugitive style)
  • File-specific operations with C-c g
  • Refined diffs with word-level changes
  • Auto-save repository buffers without prompts
  • Smerge for interactive merge conflict resolution
  • Navigate conflicts with C-c ^ n/p
  • Keep upper/lower changes with C-c ^ u/l
;; Version Control
(use-package magit
  :ensure t
  :bind (("C-x g" . magit-status)
         ("C-x C-g" . magit-status)
         ("C-c g" . magit-file-dispatch)) ;; Great for acting on the current file
  :custom
  ;; 1. Window Management:
  ;; Open Magit in the same window (like vim-fugitive) rather than splitting.
  ;; This prevents Magit from messing up your window configuration.
  (magit-display-buffer-function #'magit-display-buffer-same-window-except-diff-v1)

  ;; 2. Safety & Workflow:
  ;; Save all modified buffers in the repo without asking every time.
  (magit-save-repository-buffers 'dontask)
  ;; Don't restore the window config when quitting Magit (let me stay where I am).
  (magit-bury-buffer-function #'magit-mode-quit-window)

  ;; 3. Appearance in the Status Buffer:
  ;; Refine the hunk headers to look cleaner.
  (magit-diff-refine-hunk t)
  ;; Show fine-grained differences within lines (word-wise diffs).
  (magit-diff-refine-ignore-whitespace t)

  :config
  ;; Optional: Add a hook to maximize the window when entering Magit Status
  ;; (uncomment if you prefer full-screen git management)
  ;; (add-hook 'magit-status-mode-hook #'delete-other-windows)
  )

(use-package smerge-mode
  :ensure nil
  :bind (:map smerge-mode-map
              ("C-c ^ u" . smerge-keep-upper)
              ("C-c ^ l" . smerge-keep-lower)
              ("C-c ^ n" . smerge-next)
              ("C-c ^ p" . smerge-previous)))

1.5. Project Management

Built-in project management system for working with projects defined by version control roots (Git, SVN, etc.) or manually specified directories.

Features:

  • Automatic project detection via version control
  • Project-aware file finding and searching
  • Switch between projects easily
  • Compile/recompile within project context
  • Shell and eshell integration per project
  • Remember recent projects

Key bindings:

  • C-x p f : Find file in project
  • C-x p g : Grep in project (requires ripgrep or grep)
  • C-x p d : Open Dired at project root
  • C-x p s : Open shell at project root
  • C-x p e : Open eshell at project root
  • C-x p p : Switch to another project
  • C-x p k : Kill all project buffers
  • C-x p C : Recompile in project (custom binding)
  • C-x p b : Switch to project buffer
;; Project Management
(use-package project
  :ensure nil
  :custom
  ;; Where to store the list of known projects
  (project-list-file (expand-file-name "projects" user-emacs-directory))

  ;; Use ripgrep if available, otherwise fall back to grep
  (project-switch-commands
   '((project-find-file "Find file" ?f)
     (project-find-regexp "Find regexp" ?g)
     (project-find-dir "Find directory" ?d)
     (project-dired "Dired" ?D)
     (project-vc-dir "VC-Dir" ?v)
     (project-shell "Shell" ?s)
     (project-eshell "Eshell" ?e)
     (magit-project-status "Magit" ?m)
     (project-compile "Compile" ?c)
     (project-switch-to-buffer "Switch buffer" ?b)))

  ;; Remember recent files per project
  (project-remember-projects-under "~/Projects" t)

  :bind
  (("C-x p C" . project-recompile)
   ("C-x p m" . magit-project-status)
   :map project-prefix-map
   ("m" . magit-project-status))

  :config
  ;; Add additional project root markers
  (defun fu/project-try-local (dir)
    "Try to find a project root in DIR by looking for marker files."
    (let ((markers '(".project" ".projectile" "package.json" "Cargo.toml"
                     "setup.py" "requirements.txt" "pom.xml" "build.gradle")))
      (cl-some (lambda (marker)
                 (when-let* ((root (locate-dominating-file dir marker)))
                   (cons 'transient root)))
               markers)))

  ;; Register the custom project finder
  (add-hook 'project-find-functions #'fu/project-try-local)

  ;; Ignore certain directories when finding projects
  (add-to-list 'project-vc-ignores "node_modules")
  (add-to-list 'project-vc-ignores "target")
  (add-to-list 'project-vc-ignores "build")
  (add-to-list 'project-vc-ignores "dist")
  (add-to-list 'project-vc-ignores ".venv")
  (add-to-list 'project-vc-ignores "__pycache__"))

1.6. Documentation

Eldoc provides inline documentation in the echo area or popup boxes, showing function signatures, variable documentation, and more.

Features:

  • Global eldoc mode for all programming buffers
  • Popup documentation boxes with eldoc-box
  • Hover documentation with C-c h .
  • Multiline documentation support
  • Scrollable documentation windows
;; Documentation
(use-package eldoc
  :ensure nil
  :init
  (global-eldoc-mode))

;; (use-package eldoc-box
;;   :defer t
;;   :custom
;;   (eldoc-box-border-width 1)
;;   (eldoc-box-echo-area-use-multiline-p t)
;;   (eldoc-box-scrollbar-width 8)
;;   (eldoc-box-max-lines 10)
;;   (eldoc-box-use-echo-area nil)
;;   :bind
;;   ("C-c h ." . eldoc-box-help-at-point)
;;   :hook
;;   (eldoc-mode . eldoc-box-hover-mode))

1.7. Editing Utilities

Essential editing enhancements for programming including automatic pairing of brackets, parenthesis matching, and visual delimiter highlighting.

Features:

  • Electric pair mode: Auto-insert closing brackets, quotes, parentheses
  • Show matching parentheses with no delay
  • Mixed style: highlight expression when point is inside
  • Show context when matching paren is off-screen
;; Editing utilities
(use-package elec-pair
  :ensure nil
  :defer
  :hook
  (after-init-hook . electric-pair-mode))

(use-package paren
  :ensure nil
  :hook
  (after-init-hook . show-paren-mode)
  :custom
  (show-paren-delay 0)
  (show-paren-style 'mixed)
  (show-paren-context-when-offscreen t))

1.8. Syntax Checking

Flymake provides on-the-fly syntax checking with visual indicators in the margin and optional diagnostics at end of line.

Features:

  • Automatic syntax checking in programming modes
  • Margin indicators for errors/warnings/notes
  • Navigate errors with M-7 / M-8 or C-c ! n / C-c ! p
  • Toggle end-of-line diagnostics with C-c ! t
  • View all diagnostics with C-c ! l
;; Syntax checking
(use-package flymake
  :ensure nil
  :defer t
  :hook ((prog-mode . flymake-mode)
         (elisp-mode . flymake-mode))
  :bind (:map flymake-mode-map
              ("M-8" . flymake-goto-next-error)
              ("M-7" . flymake-goto-prev-error)
              ("C-c ! n" . flymake-goto-next-error)
              ("C-c ! p" . flymake-goto-prev-error)
              ("C-c ! l" . flymake-show-buffer-diagnostics)
              ("C-c ! t" . toggle-flymake-diagnostics-at-eol))
  :custom
  (flymake-show-diagnostics-at-end-of-line nil)
  (flymake-indicator-type 'margins)
  (flymake-margin-indicators-string
   `((error   "!" compilation-error)
       (warning "?" compilation-warning)
       (note    "i" compilation-info)))
  :config
  (defun toggle-flymake-diagnostics-at-eol ()
      "Toggle the display of Flymake diagnostics at the end of the line
and restart Flymake to apply the changes."
      (interactive)
      (setq flymake-show-diagnostics-at-end-of-line
          (not flymake-show-diagnostics-at-end-of-line))
      (flymake-mode -1)
      (flymake-mode 1)
      (message "Flymake diagnostics at end of line: %s"
             (if flymake-show-diagnostics-at-end-of-line
                 "Enabled" "Disabled"))))

1.9. Diff and Merge

Tools for viewing differences between files and resolving merge conflicts with enhanced syntax highlighting and navigation.

Features:

  • Read-only diff buffers by default (safer)
  • Auto-advance after applying hunks
  • Live updates of diffs
  • Syntax highlighting in diff hunks
  • Horizontal split for ediff
  • Plain window setup (no separate control frame)
;; Diff and merge
(use-package diff-mode
  :ensure nil
  :defer t
  :config
  (setq diff-default-read-only t)
  (setq diff-advance-after-apply-hunk t)
  (setq diff-update-on-the-fly t)
  (setq diff-font-lock-syntax 'hunk-also)
  (setq diff-font-lock-prettify nil))

(use-package ediff
  :ensure nil
  :commands (ediff-buffers ediff-files ediff-buffers3 ediff-files3)
  :init
  (setq ediff-split-window-function 'split-window-horizontally)
  (setq ediff-window-setup-function 'ediff-setup-windows-plain)
  :config
  (setq ediff-keep-variants nil)
  (setq ediff-make-buffers-readonly-at-startup nil)
  (setq ediff-merge-revisions-with-ancestor t)
  (setq ediff-show-clashes-only t))

1.10. Code Snippets

YASnippet provides a template system for Emacs, allowing you to type abbreviations and expand them into code templates.

Features:

  • Automatic activation in programming modes
  • Tab-stop navigation through template fields
  • Wide library of pre-built snippets for many languages
  • Easy to create custom snippets
;; Snippets
(use-package yasnippet
  :hook
  (prog-mode . yas-minor-mode))

1.11. LSP - Language Server Protocol

Eglot is a lightweight LSP client for Emacs providing IDE-like features including code completion, navigation, and refactoring.

Features:

  • Minimal configuration required
  • Auto-shutdown when buffers are killed
  • Code actions with C-c l a
  • Organize imports with C-c l o
  • Rename symbols with C-c l r
  • Format code with C-c l f
  • Performance optimized (disabled event logging)
;; LSP - Eglot
(use-package eglot
  :ensure nil
  :custom
  (eglot-autoshutdown t)
  (eglot-events-buffer-size 0)
  (eglot-events-buffer-config '(:size 0 :format full))
  (eglot-prefer-plaintext t)
  (jsonrpc-event-hook nil)
  (eglot-code-action-indications nil)
  (eglot-ignored-server-capabilities '(:workspaceFolders))
  :init
  (fset #'jsonrpc--log-event #'ignore)
  :bind (:map eglot-mode-map
               ("C-c l a" . eglot-code-actions)
               ("C-c l o" . eglot-code-actions-organize-imports)
               ("C-c l r" . eglot-rename)
               ("C-c l f" . eglot-format)))

1.12. Multiple Cursors and Region Expansion

Powerful editing features for working with multiple selections and intelligently expanding/contracting selections.

1.12.1. Multiple Cursors

The multiple-cursors package allows you to edit multiple locations simultaneously, perfect for renaming variables or making repetitive edits.

Key bindings:

  • C-> : Mark next like this (add cursor to next occurrence)
  • C-< : Mark previous like this (add cursor to previous occurrence)
  • C-c C-> : Mark all like this in buffer
  • C-S-<mouse-1> : Add cursor with mouse click
  • C-c m r : Mark all in region matching selection
  • C-c m l : Edit lines (add cursor to each line in region)
;; Multiple Cursors
(use-package multiple-cursors
  :ensure t
  :bind (("C->" . mc/mark-next-like-this)
         ("C-<" . mc/mark-previous-like-this)
         ("C-c C->" . mc/mark-all-like-this)
         ("C-S-<mouse-1>" . mc/add-cursor-on-click)
         ("C-c m r" . mc/mark-all-in-region)
         ("C-c m l" . mc/edit-lines)))

1.12.2. Expand Region

The expand-region package provides smart selection expansion based on semantic units (words, expressions, functions, etc.).

Usage:

  • C-= : Expand region by semantic units
  • C-- : Contract region
  • Press repeatedly to expand/contract further

Example: Place cursor in a word, press C-= once for word, again for quotes, again for expression, again for function, etc.

;; Expand Region
(use-package expand-region
  :ensure t
  :bind (("C-=" . er/expand-region)
         ("C--" . er/contract-region)))

1.13. REST Client

HTTP REST client for testing APIs directly from Emacs buffers.

Features:

  • Write HTTP requests in a simple DSL
  • Execute requests and view responses inline
  • Support for variables and request chaining
  • Works with .rest files
;; REST client
(use-package restclient
  :mode ("\\.rest\\'" . restclient-mode)
  :commands (restclient-mode))

;; Claude Code integration
;; (use-package claude-code-emacs-client
;;   :ensure nil
;;   :load-path "~/Projects/claude-code-emacs-client"
;;   :custom
;;   (claude-code-default-permission-mode "acceptEdits")
;;   :bind
;;   (("C-c c n" . claude-code-new-session)
;;    ("C-c c r" . claude-code-resume-session)
;;    ("C-c c c" . claude-code-continue-session)
;;    ("C-c c m" . claude-code-send-message)
;;    ("C-c c s" . claude-code-send-region)))

2. End of File

(provide 'prog-general-conf)
;;; prog-general-conf.el ends here