diff options
| author | Franck Cuny <franck@fcuny.net> | 2025-06-08 11:00:00 -0700 |
|---|---|---|
| committer | Franck Cuny <franck@fcuny.net> | 2025-06-08 11:00:00 -0700 |
| commit | 2fb1c9cc4b770f2345ebe06b04eb60241f5bd8c1 (patch) | |
| tree | df19dd18dd3f9e51553a8da25ae3617801ad8bc1 /nix | |
| parent | flake.lock: Update (diff) | |
| download | infra-2fb1c9cc4b770f2345ebe06b04eb60241f5bd8c1.tar.gz | |
structure emacs configuration
Diffstat (limited to 'nix')
| -rw-r--r-- | nix/users/fcuny/configs/emacs/init.el | 465 | ||||
| -rw-r--r-- | nix/users/fcuny/configs/emacs/site-lisp/init-base.el | 183 | ||||
| -rw-r--r-- | nix/users/fcuny/configs/emacs/site-lisp/init-completion.el | 54 | ||||
| -rw-r--r-- | nix/users/fcuny/configs/emacs/site-lisp/init-llm.el | 36 | ||||
| -rw-r--r-- | nix/users/fcuny/configs/emacs/site-lisp/init-programming.el | 198 | ||||
| -rw-r--r-- | nix/users/fcuny/configs/emacs/site-lisp/init-ui.el | 50 | ||||
| -rw-r--r-- | nix/users/fcuny/emacs.nix | 19 |
7 files changed, 545 insertions, 460 deletions
diff --git a/nix/users/fcuny/configs/emacs/init.el b/nix/users/fcuny/configs/emacs/init.el index 36d05be..a6cc8c7 100644 --- a/nix/users/fcuny/configs/emacs/init.el +++ b/nix/users/fcuny/configs/emacs/init.el @@ -4,77 +4,15 @@ ;;; Code: -(setq backup-inhibited t) ;; no backups -(setq create-lockfiles nil) ;; don't use a lock file +(add-to-list 'load-path (concat user-emacs-directory (convert-standard-filename "site-lisp/"))) -(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 imenu-auto-rescan t)) - -(use-package autorevert - :hook (after-init . global-auto-revert-mode) - :custom - (auto-revert-use-notify nil)) - -(use-package time - :commands (world-clock) - :hook (after-init . display-time-mode) - :config - (setq display-time-format " %a %e %b, %H:%M ") - (setq display-time-24hr-format t) - (setq display-time-interval 60) - (setq display-time-default-load-average nil) - (setq display-time-world-list t) - - ;; M-x shell RET timedatectl list-timezones - (setq zoneinfo-style-world-list '(("America/Los_Angeles" "Berkeley") - ("America/Chicago" "Chicago") - ("UTC" "UTC") - ("Europe/Paris" "Paris"))) +(use-package exec-path-from-shell + :init (exec-path-from-shell-initialize)) - ;; M-x world-clock - (setq world-clock-list t) - (setq world-clock-time-format "%z %R %a %d %b (%Z)") - (setq world-clock-buffer-name "*world-clock*") ; Placement handled by `display-buffer-alist' - (setq world-clock-timer-enable t) - (setq world-clock-timer-second 60)) +(require 'init-base) +(require 'init-ui) +(require 'init-completion) +(require 'init-programming) (use-package server :config @@ -82,68 +20,6 @@ (unless (server-running-p) (server-start))) -(use-package ibuffer - :bind ("C-x C-b" . ibuffer) - :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)) - -(use-package magit - :bind ("C-x g" . magit-status) - :custom - (magit-diff-refine-hunk t) - (magit-repository-directories '(("~/workspace" . 1))) - (magit-repolist-column-flag-alist '((magit-untracked-files . "N") - (magit-unstaged-files . "U") - (magit-staged-files . "S"))) - (magit-repolist-columns '(("Name" 25 magit-repolist-column-ident nil) - ("" 3 magit-repolist-column-flag) - ("Version" 25 magit-repolist-column-version - ((:sort magit-repolist-version<))) - ("B<U" 3 magit-repolist-column-unpulled-from-upstream - ((:right-align t) - (:sort <))) - ("B>U" 3 magit-repolist-column-unpushed-to-upstream - ((:right-align t) - (:sort <))) - ("Path" 99 magit-repolist-column-path nil))) - (magit-clone-default-directory "~/workspace/") - :config - ;; show ANSI colors in the process buffer, so it's easier to read what's going on - ;; for some reasons if it's in the `:custom' section it does not get set - (setq magit-process-finish-apply-ansi-colors t)) - -(use-package git-link - :defines git-link-remote-alist - :bind ("C-c Y" . git-link) - :commands (git-link git-link-commit git-link-homepage) - :custom - (git-link-open-in-browser t) - :config - ;; sets up roblox git enterprise as a git-link handler - (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))) - (use-package eshell :commands (eshell eshell-command) :bind (("C-r" . consult-history)) @@ -157,331 +33,6 @@ (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 - '( - (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 - -(use-package rg - :custom - (rg-group-result t) - (rg-show-columns t) - (rg-align-line-number-field-length 3) - (rg-align-column-number-field-length 3) - (rg-align-line-column-separator "#") - (rg-align-position-content-separator "|") - (rg-hide-command nil) - (rg-align-position-numbers t) - (rg-command-line-flags '("--follow"))) - -(use-package exec-path-from-shell - :init (exec-path-from-shell-initialize)) - -(use-package elec-pair - :hook (prog-mode . electric-pair-mode)) - -(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")))) - -(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")))) - -(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." - (interactive) - (let ((name (buffer-name)) - (filename (buffer-file-name)) - (read-file-name-function 'read-file-name-default)) - (if (not (and filename (file-exists-p filename))) - (error "Buffer '%s' is not visiting a file!" name) - (let ((new-name (read-file-name "New name: " filename))) - (cond ((get-buffer new-name) - (error "A buffer named '%s' already exists!" new-name)) - (t - (rename-file filename new-name 1) - (rename-buffer new-name) - (set-visited-file-name new-name) - (set-buffer-modified-p nil) - (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name)))))))) - -(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)) - -(defvar fcuny/op-item-cache nil) - -(defun fcuny/read-op-item (op-item-path) - "Read and cache OP-ITEM-PATH item." - (or (cdr (assoc op-item-path fcuny/op-item-cache)) - (let ((key (string-trim-right - (shell-command-to-string (format "op read '%s'" op-item-path))))) - (unless (string-match-p "\\[ERROR\\]" key) - (push (cons op-item-path key) fcuny/op-item-cache) - key)))) - -(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")))) - -(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 +;;; init.el ends here ;; byte-compile-warnings: (not docstrings lexical noruntime) ;; End: diff --git a/nix/users/fcuny/configs/emacs/site-lisp/init-base.el b/nix/users/fcuny/configs/emacs/site-lisp/init-base.el new file mode 100644 index 0000000..0699619 --- /dev/null +++ b/nix/users/fcuny/configs/emacs/site-lisp/init-base.el @@ -0,0 +1,183 @@ +;;; init-base.el --- base configuration -*- lexical-binding: t -*- +;; Author: Franck Cuny <franck@fcuny.net> + +;;; Commentary: + +;; commentary + +;;; Code: + +(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 imenu-auto-rescan t)) + +(use-package autorevert + :hook (after-init . global-auto-revert-mode) + :custom + (auto-revert-use-notify nil)) + +(use-package time + :commands (world-clock) + :hook (after-init . display-time-mode) + :config + (setq display-time-format " %a %e %b, %H:%M ") + (setq display-time-24hr-format t) + (setq display-time-interval 60) + (setq display-time-default-load-average nil) + (setq display-time-world-list t) + + ;; M-x shell RET timedatectl list-timezones + (setq zoneinfo-style-world-list '(("America/Los_Angeles" "Berkeley") + ("America/Chicago" "Chicago") + ("UTC" "UTC") + ("Europe/Paris" "Paris"))) + + ;; M-x world-clock + (setq world-clock-list t) + (setq world-clock-time-format "%z %R %a %d %b (%Z)") + (setq world-clock-buffer-name "*world-clock*") ; Placement handled by `display-buffer-alist' + (setq world-clock-timer-enable t) + (setq world-clock-timer-second 60)) + +(use-package ibuffer + :bind ("C-x C-b" . ibuffer) + :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)) + +(use-package project + :bind + (("C-x p ." . project-dired) + ("C-x p <return>" . project-dired)) + :custom + (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 + +(use-package rg + :custom + (rg-group-result t) + (rg-show-columns t) + (rg-align-line-number-field-length 3) + (rg-align-column-number-field-length 3) + (rg-align-line-column-separator "#") + (rg-align-position-content-separator "|") + (rg-hide-command nil) + (rg-align-position-numbers t) + (rg-command-line-flags '("--follow"))) + +(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." + (interactive) + (let ((name (buffer-name)) + (filename (buffer-file-name)) + (read-file-name-function 'read-file-name-default)) + (if (not (and filename (file-exists-p filename))) + (error "Buffer '%s' is not visiting a file!" name) + (let ((new-name (read-file-name "New name: " filename))) + (cond ((get-buffer new-name) + (error "A buffer named '%s' already exists!" new-name)) + (t + (rename-file filename new-name 1) + (rename-buffer new-name) + (set-visited-file-name new-name) + (set-buffer-modified-p nil) + (message "File '%s' successfully renamed to '%s'" name (file-name-nondirectory new-name)))))))) + + +(provide 'init-base) + +;;; init-base.el ends here diff --git a/nix/users/fcuny/configs/emacs/site-lisp/init-completion.el b/nix/users/fcuny/configs/emacs/site-lisp/init-completion.el new file mode 100644 index 0000000..fc01a39 --- /dev/null +++ b/nix/users/fcuny/configs/emacs/site-lisp/init-completion.el @@ -0,0 +1,54 @@ +;;; init-completion.el --- Configure completion -*- lexical-binding: t -*- +;; Author: Franck Cuny <franck@fcuny.net> + +;;; Commentary: + +;; Configure completions + +;;; Code: + +(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)) + +(provide 'init-completion) + +;;; init-completion.el ends here diff --git a/nix/users/fcuny/configs/emacs/site-lisp/init-llm.el b/nix/users/fcuny/configs/emacs/site-lisp/init-llm.el new file mode 100644 index 0000000..4654613 --- /dev/null +++ b/nix/users/fcuny/configs/emacs/site-lisp/init-llm.el @@ -0,0 +1,36 @@ +;;; init-llm.el --- Configure LLMs -*- lexical-binding: t -*- +;; Author: Franck Cuny <franck@fcuny.net> + +;;; Commentary: + +;; Configure completions + +;;; Code: +(defvar fcuny/op-item-cache nil) + +(defun fcuny/read-op-item (op-item-path) + "Read and cache OP-ITEM-PATH item." + (or (cdr (assoc op-item-path fcuny/op-item-cache)) + (let ((key (string-trim-right + (shell-command-to-string (format "op read '%s'" op-item-path))))) + (unless (string-match-p "\\[ERROR\\]" key) + (push (cons op-item-path key) fcuny/op-item-cache) + key)))) + +(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")))) + +(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"))) + +(provide 'init-llm) + +;;; init-llm.el ends here diff --git a/nix/users/fcuny/configs/emacs/site-lisp/init-programming.el b/nix/users/fcuny/configs/emacs/site-lisp/init-programming.el new file mode 100644 index 0000000..b3712e7 --- /dev/null +++ b/nix/users/fcuny/configs/emacs/site-lisp/init-programming.el @@ -0,0 +1,198 @@ +;;; init-programming.el --- Configure things related to programming -*- lexical-binding: t -*- +;; Author: Franck Cuny <franck@fcuny.net> + +;;; Commentary: + +;; Configure things related to programming + +;;; Code: + +(use-package magit + :bind ("C-x g" . magit-status) + :custom + (magit-diff-refine-hunk t) + (magit-repository-directories '(("~/workspace" . 1))) + (magit-repolist-column-flag-alist '((magit-untracked-files . "N") + (magit-unstaged-files . "U") + (magit-staged-files . "S"))) + (magit-repolist-columns '(("Name" 25 magit-repolist-column-ident nil) + ("" 3 magit-repolist-column-flag) + ("Version" 25 magit-repolist-column-version + ((:sort magit-repolist-version<))) + ("B<U" 3 magit-repolist-column-unpulled-from-upstream + ((:right-align t) + (:sort <))) + ("B>U" 3 magit-repolist-column-unpushed-to-upstream + ((:right-align t) + (:sort <))) + ("Path" 99 magit-repolist-column-path nil))) + (magit-clone-default-directory "~/workspace/") + :config + ;; show ANSI colors in the process buffer, so it's easier to read what's going on + ;; for some reasons if it's in the `:custom' section it does not get set + (setq magit-process-finish-apply-ansi-colors t)) + +(use-package git-link + :defines git-link-remote-alist + :bind ("C-c Y" . git-link) + :commands (git-link git-link-commit git-link-homepage) + :custom + (git-link-open-in-browser t) + :config + ;; sets up roblox git enterprise as a git-link handler + (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))) + +(use-package elec-pair + :hook (prog-mode . electric-pair-mode)) + +(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 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 eglot + :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")))) + +(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")))) + +(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)) + +(provide 'init-programming) + +;;; init-programming.el ends here diff --git a/nix/users/fcuny/configs/emacs/site-lisp/init-ui.el b/nix/users/fcuny/configs/emacs/site-lisp/init-ui.el new file mode 100644 index 0000000..e239978 --- /dev/null +++ b/nix/users/fcuny/configs/emacs/site-lisp/init-ui.el @@ -0,0 +1,50 @@ +;;; init-ui.el --- User interface config. -*- lexical-binding: t -*- + +;;; Commentary: + +;; User interface settings. + +;;; Code: + +(use-package whitespace + :init + (global-whitespace-mode t) + :custom + (whitespace-style '(face + tabs + tab-mark + trailing + missing-newline-at-eof))) + +(use-package fringe + :custom (fringe-mode '(8 . 0))) + +;; | 数字 | アルファベット | 日本語 | 絵文字 | +;; | 0123 | abcdefghijklmn | あいう | 🍎🍎🍎 | +(set-face-attribute 'default nil :family "Source Code Pro" :height 150) + +(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 '()) + + :init + (load-theme 'modus-operandi-tinted t)) + +(provide 'init-ui) +;;; init-ui.el ends here diff --git a/nix/users/fcuny/emacs.nix b/nix/users/fcuny/emacs.nix index cc3dc3a..849c6b4 100644 --- a/nix/users/fcuny/emacs.nix +++ b/nix/users/fcuny/emacs.nix @@ -1,4 +1,4 @@ -{ pkgs, ... }: +{ pkgs, lib, ... }: let packages = epkgs: with epkgs; [ @@ -36,10 +36,23 @@ let yasnippet yasnippet-capf ]; + emacsFiles = [ + "early-init.el" + "init.el" + "site-lisp/init-base.el" + "site-lisp/init-completion.el" + "site-lisp/init-llm.el" + "site-lisp/init-programming.el" + "site-lisp/init-ui.el" + ]; + mkEmacsFile = file: { + ".config/emacs/${file}" = { + source = ./configs/emacs/${file}; + }; + }; in { - home.file.".config/emacs/early-init.el".source = ./configs/emacs/early-init.el; - home.file.".config/emacs/init.el".source = ./configs/emacs/init.el; + home.file = lib.mkMerge (map mkEmacsFile emacsFiles); programs.emacs = { enable = true; |
