diff options
| author | Franck Cuny <franck@fcuny.net> | 2025-06-02 19:50:57 -0700 |
|---|---|---|
| committer | Franck Cuny <franck@fcuny.net> | 2025-06-02 19:50:57 -0700 |
| commit | ec81c0462af44606d8a9b9b93526ef15fe9323d7 (patch) | |
| tree | 9c02baca1528553fac56e14a1a6024bdc5bbe61e | |
| parent | add things related to projects / rg (diff) | |
| download | infra-ec81c0462af44606d8a9b9b93526ef15fe9323d7.tar.gz | |
more configuration for emacs
Diffstat (limited to '')
| -rw-r--r-- | nix/users/fcuny/configs/emacs/init.el | 563 |
1 files changed, 343 insertions, 220 deletions
diff --git a/nix/users/fcuny/configs/emacs/init.el b/nix/users/fcuny/configs/emacs/init.el index d677ae9..36d05be 100644 --- a/nix/users/fcuny/configs/emacs/init.el +++ b/nix/users/fcuny/configs/emacs/init.el @@ -7,25 +7,52 @@ (setq backup-inhibited t) ;; no backups (setq create-lockfiles nil) ;; don't use a lock file +(setq auto-save-default nil) ;; no auto save +(setq confirm-kill-emacs #'yes-or-no-p) ;; ask before killing emacs +(setq cursor-in-non-selected-windows nil) ;; keep cursors and highlights in current window only +(setq delete-by-moving-to-trash t) ;; delete files by moving them to the trash +(setq highlight-nonselected-windows nil) ;; don't highlight inactive windows +(setq history-delete-duplicates t) ;; delete duplicate from history +(setq initial-major-mode 'fundamental-mode) ;; default mode for the scratch buffer +(setq initial-scratch-message "") ;; makes the scratch buffer empty +(setq midnight-period (* 3600 6)) ;; clear buffer every 6 hours +(setq mode-line-default-help-echo nil) ;; don't say anything on mode-line mouseover +(setq require-final-newline t) ;; ensure a new line is present at the bottom of files +(setq ring-bell-function 'ignore) ;; really no bell +(setq sentence-end-double-space nil) ;; it matters for filling +(setq use-short-answers t) ;; use y-or-n +(setq visible-bell nil) ;; no bell +(setq bidi-display-reordering nil) ;; disable bidirectional text support for slight performance bonus +(setq column-number-mode t) ;; show column number in the mode line + +(global-set-key (kbd "M-j") 'join-line) + (use-package recentf :hook (after-init . recentf-mode) + :custom + (recentf-max-saved-items 1000) + (recentf-max-menu-items 25) + (recentf-save-file-modes nil) + (recentf-keep nil) + (recentf-auto-cleanup nil) + (recentf-initialize-file-name-history nil) + (recentf-filename-handlers nil) + (recentf-show-file-shortcuts-flag nil)) + +(use-package midnight + :custom + ;; every 6 hours + (midnight-period (* 3600 6))) + +(use-package imenu :config - (setq recentf-max-saved-items 1000) - (setq recentf-max-menu-items 25) - (setq recentf-save-file-modes nil) - (setq recentf-keep nil) - (setq recentf-auto-cleanup nil) - (setq recentf-initialize-file-name-history nil) - (setq recentf-filename-handlers nil) - (setq recentf-show-file-shortcuts-flag nil)) - -;;;; Auto revert mode + (setq imenu-auto-rescan t)) + (use-package autorevert :hook (after-init . global-auto-revert-mode) - :config - (setq auto-revert-verbose t)) + :custom + (auto-revert-use-notify nil)) -;;;; Display current time (use-package time :commands (world-clock) :hook (after-init . display-time-mode) @@ -49,30 +76,40 @@ (setq world-clock-timer-enable t) (setq world-clock-timer-second 60)) -;;;; Emacs server (allow emacsclient to connect to running session) (use-package server - :defer 1 :config (setq server-client-instructions nil) (unless (server-running-p) (server-start))) -;;;; improved buffers management (use-package ibuffer - :ensure nil :bind ("C-x C-b" . ibuffer) - :init - (setq ibuffer-expert t) ;; set expert mode - (setq ibuffer-jump-offer-only-visible-buffers t) ;; only show visible buffers - (setq ibuffer-use-other-window t) ;; open ibuffer in other window - (setq ibuffer-filter-group-name-face '(:inherit (font-lock-string-face bold)))) + :custom + (ibuffer-expert t) + (ibuffer-show-empty-filter-groups nil) + (ibuffer-jump-offer-only-visible-buffers t) + (ibuffer-never-show-predicates '("^ ")) + (ibuffer-use-other-window t) + (ibuffer-filter-group-name-face '(:inherit (font-lock-string-face bold)))) + +(use-package which-key + :diminish + :hook (after-init . which-key-mode)) + +(use-package saveplace + :config + (save-place-mode t)) + +(use-package savehist + :hook (after-init . savehist-mode) + :custom + (savehist-file (locate-user-emacs-file "savehist")) + (history-length 100) + (history-delete-duplicates t) + (savehist-save-minibuffer-history t)) -;;;; magit, the best git client (use-package magit :bind ("C-x g" . magit-status) - :init - (add-to-list 'project-switch-commands - '(?v "Magit" magit-project-status)) :custom (magit-diff-refine-hunk t) (magit-repository-directories '(("~/workspace" . 1))) @@ -96,7 +133,6 @@ ;; for some reasons if it's in the `:custom' section it does not get set (setq magit-process-finish-apply-ansi-colors t)) -;;;; create links from a git commit to a forge (use-package git-link :defines git-link-remote-alist :bind ("C-c Y" . git-link) @@ -108,25 +144,35 @@ (add-to-list 'git-link-remote-alist '("github\\.rblx\\.com" git-link-github)) (add-to-list 'git-link-commit-remote-alist '("github\\.rblx\\.com" git-link-commit-github))) -;;;; navigate within a project +(use-package eshell + :commands (eshell eshell-command) + :bind (("C-r" . consult-history)) + :custom + (eshell-hist-ignoredups t) + (eshell-history-size 50000) + (eshell-ls-dired-initial-args '("-h")) + (eshell-ls-initial-args "-h") + (eshell-ls-exclude-regexp "~\\'") + (eshell-save-history-on-exit t) + (eshell-stringify-t nil) + (eshell-term-name "ansi")) + (use-package project :bind (("C-x p ." . project-dired) ("C-x p <return>" . project-dired)) :custom - (project-switch-commands '((?f "Find file" project-find-file) - (?e "Eshell" project-eshell) - (?d "Root dired" project-dired))) + (project-switch-commands + '( + (consult-project-buffer "buffer" ?b) + (project-dired "dired" ?d) + (magit-project-status "magit status" ?g) + (project-find-file "find file" ?p) + (consult-ripgrep "rigprep" ?r))) (setq project-mode-line t) (setq project-key-prompt-style t)) ; Emacs 30 -;;;; find stuff (use-package rg - :bind - (([remap project-find-regexp] . rg-project)) - :init - (add-to-list 'project-switch-commands - '(?g "Find regexp" rg-project)) :custom (rg-group-result t) (rg-show-columns t) @@ -138,74 +184,170 @@ (rg-align-position-numbers t) (rg-command-line-flags '("--follow"))) -(require 'imenu) -(require 'midnight) +(use-package exec-path-from-shell + :init (exec-path-from-shell-initialize)) -(setq auto-save-default nil) ;; no auto save -(setq confirm-kill-emacs #'yes-or-no-p) ;; ask before killing emacs -(setq cursor-in-non-selected-windows nil) ;; keep cursors and highlights in current window only -(setq delete-by-moving-to-trash t) ;; delete files by moving them to the trash -(setq highlight-nonselected-windows nil) ;; don't highlight inactive windows -(setq history-delete-duplicates t) ;; delete duplicate from history -(setq imenu-auto-rescan t) ;; rescan automatically -(setq initial-major-mode 'fundamental-mode) ;; default mode for the scratch buffer -(setq initial-scratch-message "") ;; makes the scratch buffer empty -(setq midnight-period (* 3600 6)) ;; clear buffer every 6 hours -(setq mode-line-default-help-echo nil) ;; don't say anything on mode-line mouseover -(setq require-final-newline t) ;; ensure a new line is present at the bottom of files -(setq ring-bell-function 'ignore) ;; really no bell -(setq sentence-end-double-space nil) ;; it matters for filling -(setq use-short-answers t) ;; use y-or-n -(setq visible-bell nil) ;; no bell -(setq bidi-display-reordering nil) ;; disable bidirectional text support for slight performance bonus -(setq column-number-mode t) ;; show column number in the mode line +(use-package elec-pair + :hook (prog-mode . electric-pair-mode)) -;; global minor modes -(fringe-mode '(8 . 0)) -(save-place-mode t) -(which-key-mode t) +(use-package eldoc + :diminish + :hook ((emacs-lisp-mode) . eldoc-mode) + :custom + (eldoc-idle-delay 1) + (eldoc-documentation-strategy #'eldoc-documentation-default) + ;; Don't resize the echo area if the documentation is longer. This is very + ;; distracting when combined with Eglot's highlight functionality. + (eldoc-echo-area-use-multiline-p nil)) + +(use-package compile + :hook (compilation-filter . ansi-color-compilation-filter) + :custom + (compilation-always-kill t) + (compilation-context-lines 10) + (compilation-disable-input t) + (compilation-scroll-output 'first-error) + (compilation-scroll-output t) + (compilation-skip-threshold 2) + ;; Save all buffers on M-x `compile' + (compilation-ask-about-save nil)) + +(use-package eglot + :after yasnippet + :bind (:map eglot-mode-map + ("C-c l a" . eglot-code-actions) + ("C-c l r" . eglot-rename) + ("C-c l f" . eglot-format-buffer)) + :hook ((go-mode . eglot-ensure) + (python-mode . eglot-ensure) + (nix-mode . eglot-ensure)) + :custom + (eglot-send-changes-idle-time 0.1) + :config + (setq eglot-autoshutdown t + ;; Disable logging of events. + eglot-events-buffer-size 0) + (setq-default eglot-workspace-configuration + '(:pylsp (:plugins (:ruff (:enabled t))) + :nil (:formatting (:command ["nixfmt"])) + :gopls (:usePlaceholders t + :staticcheck t + :completeUnimported t + :matcher "CaseSensitive"))) + ;; uses https://github.com/nix-community/nixd for the LSP server instead of rnix + (add-to-list 'eglot-server-programs '(nix-mode . ("nil")))) -(require 'savehist) -(savehist-mode t) -(setq history-length 100 - history-delete-duplicates t - savehist-save-minibuffer-history t) +(use-package emacs-lisp-mode + :bind (:map emacs-lisp-mode-map + ("C-c C-r" . eval-region) + ("C-c C-d" . eval-defun) + ("C-c C-b" . eval-buffer)) + :hook ((emacs-lisp-mode . flymake-mode))) + +(use-package go-mode + :hook ((go-mode . (lambda () (setq tab-width 4))) + (go-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t)))) + :bind (:map go-mode-map + ("C-c C-c" . compile)) + :config + (with-eval-after-load 'exec-path-from-shell + (exec-path-from-shell-copy-envs '("GOPATH" "GOBIN")))) -;; some key bindings -(global-set-key (kbd "M-j") 'join-line) -(global-set-key (kbd "C-c y") 'git-link) -(global-set-key (kbd "C-c C-r") 'eval-region) -(global-set-key (kbd "C-c C-d") 'eval-defun) -(global-set-key (kbd "C-c C-b") 'eval-buffer) -(global-set-key (kbd "C-c ! D") 'flymake-show-project-diagnostics) -(global-set-key (kbd "C-c ! d") 'flymake-show-buffer-diagnostics) -(global-set-key (kbd "C-c ! n") 'flymake-goto-next-error) -(global-set-key (kbd "C-c ! p") 'flymake-goto-prev-error) -(global-set-key (kbd "C-c ! s") 'flymake-start) - -;; load the PATH properly on macOS -(require 'exec-path-from-shell) -(let ((envs '("PATH" "GOPATH" "GOBIN"))) - (exec-path-from-shell-copy-envs envs)) - -;; ensure we highlights whitespaces -(require 'whitespace) -(dolist (mode-hook '(prog-mode-hook text-mode-hook conf-mode-hook)) - (add-hook mode-hook 'whitespace-mode)) - -(setq whitespace-style '(face trailing tabs)) -(setq-default show-trailing-whitespace t) - -;;; dired -(require 'dired) -(setq dired-use-ls-dired t - dired-clean-up-buffers-too nil - dired-dwim-target t - dired-hide-details-hide-information-lines nil - dired-hide-details-hide-symlink-targets nil - dired-recursive-copies 'always - dired-recursive-deletes 'always - dired-no-confirm '(byte-compile chgrp chmod chown copy hardlink symlink touch)) +(use-package gotest + :after go-mode + :custom + (go-test-verbose t)) + +(use-package nix-mode + :hook ((nix-mode . (lambda () (add-hook 'before-save-hook 'eglot-format-buffer nil t)))) + :custom + (nix-indent-function 'nix-indent-line)) + +(use-package python-mode) + +(use-package ruby-mode) + +(use-package json-mode) + +(use-package json-reformat + :after json-mode) + +(use-package jq-mode + :mode "\\.jq\\'") + +(use-package terraform-mode + :mode "\.tf\\'") + +(use-package hcl-mode + :mode "\.nomad\\'") + +(use-package toml-mode) + +(use-package yaml-mode) + +(use-package docker + :bind ("C-c d" . docker) + :diminish + :init + (use-package docker-image :commands docker-images) + (use-package docker-volume :commands docker-volumes) + (use-package docker-network :commands docker-containers) + (use-package docker-compose :commands docker-compose) + + (use-package docker-container + :commands docker-containers + :custom + (docker-containers-shell-file-name "/bin/bash") + (docker-containers-show-all nil))) + +(use-package docker-compose-mode + :mode "docker-compose.*\.yml\\'") + +(use-package dockerfile-mode + :mode "Dockerfile[a-zA-Z.-]*\\'") + +(use-package protobuf-mode + :mode "\\.proto\\'") + +(use-package css-mode + :custom + (css-indent-offset 2) + (cssm-indent-level 1)) + +(use-package fringe + :custom (fringe-mode '(8 . 0))) + +(use-package whitespace + :init + (global-whitespace-mode t) + :custom + (whitespace-style '(face + tabs + spaces + tab-mark + space-mark + trailing + missing-newline-at-eof + space-after-tab::tab + space-after-tab::space + space-before-tab::tab + space-before-tab::space))) + +(use-package dired + :hook (dired-mode . dired-omit-mode) + :bind (:map dired-mode-map + ( "." . dired-omit-mode)) + :custom + (dired-omit-files (rx (seq bol "."))) + (dired-use-ls-dired t) + (dired-clean-up-buffers-too nil) + (dired-dwim-target t) + (dired-hide-details-hide-information-lines nil) + (dired-hide-details-hide-symlink-targets nil) + (dired-recursive-copies 'always) + (dired-recursive-deletes 'always) + (dired-no-confirm + '(byte-compile chgrp chmod chown copy hardlink symlink touch))) (defun my/rename-this-buffer-and-file () "Renames current buffer and file it is visiting." @@ -225,110 +367,96 @@ (set-buffer-modified-p nil) (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name)))))))) -;;; prog mode related -(add-hook 'prog-mode-hook 'electric-pair-mode) -(add-hook 'prog-mode-hook 'flymake-mode) - -;; compile mode -(add-hook 'compilation-filter-hook 'ansi-color-compilation-filter) -(setq compilation-always-kill t - compilation-context-lines 10 - compilation-disable-input t - compilation-scroll-output 'first-error - compilation-scroll-output t - compilation-skip-threshold 2 - compilation-ask-about-save nil) - -;; elisp -(add-hook 'emacs-lisp-mode-hook 'eldoc-mode) -(add-hook 'emacs-lisp-mode-hook 'flymake-mode) - -(setq eldoc-idle-delay 1 - eldoc-documentation-strategy #'eldoc-documentation-default - eldoc-echo-area-use-multiline-p nil) - -;; direnv -(require 'direnv) -(direnv-mode t) -(setq direnv-always-show-summary nil) - -;; eglot -(require 'eglot) - -(add-hook 'python-mode-hook 'eglot-ensure) -(add-hook 'go-mode-hook 'eglot-ensure) -(add-hook 'nix-mode-hook 'eglot-ensure) - -(setq eglot-send-changes-idle-time 0.1 - eglot-autoshutdown t) - -(setq-default eglot-workspace-configuration - '(:pylsp (:plugins (:ruff (:enabled t))) - :nil (:formatting (:command ["nixfmt"])) - :gopls (:usePlaceholders t - :staticcheck t - :completeUnimported t - :matcher "CaseSensitive"))) - -;; uses https://github.com/nix-community/nixd for the LSP server instead of rnix -(with-eval-after-load 'eglot - (add-to-list 'eglot-server-programs '(nix-mode . ("nil")))) +(use-package direnv + :custom + (direnv-always-show-summary nil) + :config + (direnv-mode)) + +(use-package flymake + :bind (:prefix "C-c !" + :prefix-map flymake-prefix-map + ("l" . consult-flymake) + ("d" . flymake-show-buffer-diagnostics) + ("D" . flymake-show-project-diagnostics) + ("n" . flymake-goto-next-error) + ("p" . flymake-goto-prev-error)) + :hook + (prog-mode . flymake-mode) + :custom + (flymake-start-on-save-buffer t) + (flymake-fringe-indicator-position 'left-fringe) + (flymake-suppress-zero-counters t) + (flymake-proc-compilation-prevents-syntax-check t) + (flymake-no-changes-timeout 9999) + (elisp-flymake-byte-compile-load-path load-path)) + +(use-package consult + :commands (consult-ripgrep consult-buffer consult-imenu) + :bind (("C-c m" . consult-mode-command) + ("C-x b" . consult-buffer) + ("C-x r b" . consult-bookmark) + ("C-x p b" . consult-project-buffer) + ("C-c i" . consult-imenu) + ("M-g e" . consult-compile-error) + ("M-g M-g" . consult-goto-line) + ("M-g m" . consult-mark) + ("M-g k" . consult-global-mark))) + +(use-package corfu + :custom + (corfu-auto t) + :bind ("M-/" . completion-at-point) + :hook ((after-init . global-corfu-mode) + (global-corfu-mode . corfu-popupinfo-mode))) + +(use-package cape) + +(use-package marginalia + :hook (after-init . marginalia-mode)) + +(use-package orderless + :custom + (completion-styles '(orderless basic)) + (completion-category-defaults nil)) + +(use-package vertico + :hook ((after-init . vertico-mode))) + +(use-package consult-imenu + :after (consult)) + +(use-package corfu-popupinfo + :after corfu + :hook (corfu-mode . corfu-popupinfo-mode) + :custom + (corfu-popupinfo-delay '(0.25 . 0.1)) + (corfu-popupinfo-hide nil)) + +(use-package modus-themes + :custom + (modus-themes-italic-constructs t) + (modus-themes-syntax '(alt-syntax green-strings)) + (modus-themes-mode-line '(moody accented borderless)) + (modus-themes-tabs-accented t) + + (modus-themes-completions + '((matches . (extrabold background)) + (selection . (semibold accented)) + (popup . (accented)))) + + (modus-themes-fringe 'subtle) + (modus-themes-lang-checkers '(text-also straight-underline)) + (modus-themes-hl-line '(accented)) + (modus-themes-subtle-line-numbers t) + (modus-themes-markup '(bold italic)) + (modus-themes-paren-match '(bold)) + (modus-themes-region '()) + + :config + (load-theme 'modus-operandi) + (enable-theme 'modus-operandi-tinted)) -;; flymake -(require 'flymake) - -(setq flymake-start-on-save-buffer t - flymake-fringe-indicator-position 'left-fringe - flymake-suppress-zero-counters t - flymake-no-changes-timeout 9999 - elisp-flymake-byte-compile-load-path load-path) - -;;; completion -(require 'consult) -(require 'consult-imenu) -(require 'consult-compile) -(require 'corfu) -(require 'corfu-popupinfo) -(require 'cape) -(require 'marginalia) -(require 'orderless) -(require 'vertico) - -(global-corfu-mode t) -(corfu-popupinfo-mode t) -(marginalia-mode t) -(vertico-mode t) - -(setq corfu-auto t) -(setq completion-styles '(orderless basic) - completion-category-defaults nil) - -(bind-key "C-x b" #'consult-buffer) -(bind-key "C-x r b" #'consult-bookmark) -(bind-key "C-x p b" #'consult-project-buffer) -(bind-key "C-c i" #'consult-imenu) -(bind-key "M-g e" #'consult-compile-error) -(bind-key "M-g M-g" #'consult-goto-line) -(bind-key "M-g m" #'consult-mark) -(bind-key "M-g k" #'consult-global-mark) - -(add-hook 'after-init-mode 'global-corfu-mode) -(add-hook 'after-init-mode 'vertico-mode) - -;;; theming -(require-theme 'modus-themes) -(setq modus-themes-italic-constructs t - modus-themes-bold-constructs t - modus-themes-mixed-fonts t - modus-themes-variable-pitch-ui nil - modus-themes-prompts '(italic bold) - modus-themes-completions - '((matches . (extrabold)) - (selection . (semibold italic text-also)))) - -(load-theme 'modus-operandi-tinted :no-confirm) - -;;; 1Password Integration (defvar fcuny/op-item-cache nil) (defun fcuny/read-op-item (op-item-path) @@ -340,23 +468,18 @@ (push (cons op-item-path key) fcuny/op-item-cache) key)))) -;;; gptel -(require 'gptel) - -(with-eval-after-load 'gptel - (setq gptel-default-mode 'org-mode) - (gptel-make-anthropic "Claude" - :stream t - :key (lambda () (fcuny/read-op-item "op://Private/anthropic llm/credential")))) - -;;; aider -(require 'aidermacs) - -(global-set-key (kbd "C-c a") 'aidermacs-transient-menu) +(use-package gptel + :custom + (gptel-default-mode 'org-mode) + :config + (gptel-make-anthropic "Claude" :stream t :key (lambda () (fcuny/read-op-item "op://Private/anthropic llm/credential")))) -(with-eval-after-load 'aidermacs - (setq aider-args '("--no-check-update" "--no-show-model-warnings")) - (setq aidermacs-default-model "claude-3-7-sonnet-latest") +(use-package aidermacs + :bind ("C-c a" . aidermacs-transient-menu) + :custom + (aider-args '("--no-check-update" "--no-show-model-warnings")) + (aidermacs-default-model "claude-3-7-sonnet-latest") + :config (setenv "ANTHROPIC_API_KEY" (fcuny/read-op-item "op://Private/anthropic llm/credential"))) ;;; early-init.el ends here |
