diff options
Diffstat (limited to 'home/programs')
25 files changed, 1396 insertions, 0 deletions
diff --git a/home/programs/alacritty/catppuccin-latte.toml b/home/programs/alacritty/catppuccin-latte.toml new file mode 100644 index 0000000..e9414ad --- /dev/null +++ b/home/programs/alacritty/catppuccin-latte.toml @@ -0,0 +1,65 @@ +[colors.primary] +background = "#eff1f5" +foreground = "#4c4f69" +dim_foreground = "#8c8fa1" +bright_foreground = "#4c4f69" + +[colors.cursor] +text = "#eff1f5" +cursor = "#dc8a78" + +[colors.vi_mode_cursor] +text = "#eff1f5" +cursor = "#7287fd" + +[colors.search.matches] +foreground = "#eff1f5" +background = "#6c6f85" + +[colors.search.focused_match] +foreground = "#eff1f5" +background = "#40a02b" + +[colors.footer_bar] +foreground = "#eff1f5" +background = "#6c6f85" + +[colors.hints.start] +foreground = "#eff1f5" +background = "#df8e1d" + +[colors.hints.end] +foreground = "#eff1f5" +background = "#6c6f85" + +[colors.selection] +text = "#eff1f5" +background = "#dc8a78" + +[colors.normal] +black = "#bcc0cc" +red = "#d20f39" +green = "#40a02b" +yellow = "#df8e1d" +blue = "#1e66f5" +magenta = "#ea76cb" +cyan = "#179299" +white = "#5c5f77" + +[colors.bright] +black = "#acb0be" +red = "#d20f39" +green = "#40a02b" +yellow = "#df8e1d" +blue = "#1e66f5" +magenta = "#ea76cb" +cyan = "#179299" +white = "#6c6f85" + +[[colors.indexed_colors]] +index = 16 +color = "#fe640b" + +[[colors.indexed_colors]] +index = 17 +color = "#dc8a78" diff --git a/home/programs/alacritty/default.nix b/home/programs/alacritty/default.nix new file mode 100644 index 0000000..18c5182 --- /dev/null +++ b/home/programs/alacritty/default.nix @@ -0,0 +1,54 @@ +{ config, ... }: +let + defaultFont = "Source Code Pro"; +in +{ + programs.alacritty = { + enable = true; + settings = { + env.TERM = "xterm-256color"; + general.import = [ + "${config.xdg.configHome}/alacritty/catppuccin-latte.toml" + ]; + selection.save_to_clipboard = true; + window = { + dimensions = { + columns = 120; + lines = 40; + }; + padding = { + x = 2; + y = 2; + }; + }; + scrolling = { + history = 10000; + multiplier = 3; + }; + font = { + normal.family = defaultFont; + bold = { + family = defaultFont; + style = "Bold"; + }; + italic = { + family = defaultFont; + style = "Italic"; + }; + size = 14; + offset = { + x = 0; + y = 0; + }; + glyph_offset = { + x = 0; + y = 0; + }; + }; + }; + }; + + home.file.".config/alacritty/catppuccin-latte.toml" = { + source = ./catppuccin-latte.toml; + }; +} diff --git a/home/programs/bat.nix b/home/programs/bat.nix new file mode 100644 index 0000000..fb27397 --- /dev/null +++ b/home/programs/bat.nix @@ -0,0 +1,10 @@ +{ ... }: +{ + programs.bat = { + enable = true; + config = { + theme = "ansi"; + pager = "less -FR"; + }; + }; +} diff --git a/home/programs/direnv.nix b/home/programs/direnv.nix new file mode 100644 index 0000000..54585ca --- /dev/null +++ b/home/programs/direnv.nix @@ -0,0 +1,11 @@ +{ ... }: +{ + programs.direnv = { + enable = true; + nix-direnv.enable = true; + config = { + global.disable_stdin = true; + global.strict_env = true; + }; + }; +} diff --git a/home/programs/emacs/default.nix b/home/programs/emacs/default.nix new file mode 100644 index 0000000..c20f3da --- /dev/null +++ b/home/programs/emacs/default.nix @@ -0,0 +1,88 @@ +{ + self, + pkgs, + lib, + ... +}: +let + packages = + epkgs: with epkgs; [ + aidermacs # pair programming in Emacs with Aider + cape + consult + consult-denote + corfu + denote + denote-journal + denote-markdown + denote-org + denote-silo + denote-sequence + diminish + direnv + docker + docker-compose-mode + dockerfile-mode + exec-path-from-shell + git-link + go-mode + gotest + gptel # LLM client for Emacs + hcl-mode + jq-mode + json-mode + json-reformat + magit + marginalia + markdown-mode + nix-mode + orderless + protobuf-mode + rg + terraform-mode + toml-mode + tree-sitter + tree-sitter-langs + treesit-grammars.with-all-grammars + yaml-mode + 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-text.el" + "site-lisp/init-ui.el" + ]; + mkEmacsFile = file: { + ".config/emacs/${file}" = { + source = "${self}/home/programs/emacs/${file}"; + }; + }; +in +{ + home.file = lib.mkMerge (map mkEmacsFile emacsFiles); + + programs.emacs = { + enable = true; + extraPackages = packages; + # FIXME: https://github.com/NixOS/nixpkgs/issues/395169 + package = pkgs.emacs.override { withNativeCompilation = false; }; + }; + + home.packages = with pkgs; [ + aspell + aspellDicts.en + aspellDicts.en-science + aspellDicts.en-computers + ]; + + home.sessionVariables = { + EDITOR = "${pkgs.emacs}/bin/emacsclient -a="; + ASPELL_CONF = "dict-dir ${pkgs.aspellDicts.en}/lib/aspell"; + }; +} diff --git a/home/programs/emacs/early-init.el b/home/programs/emacs/early-init.el new file mode 100644 index 0000000..3953c90 --- /dev/null +++ b/home/programs/emacs/early-init.el @@ -0,0 +1,45 @@ +;;; early-init.el --- Early initialization -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +;; Startup speed, annoyance suppression +(setq gc-cons-threshold 10000000) +(setq byte-compile-warnings '(not obsolete)) +(setq warning-suppress-log-types '((comp) (bytecomp))) +(setq native-comp-async-report-warnings-errors 'silent) + +;; Silence startup message +(setq inhibit-startup-echo-area-message (user-login-name)) + +;; Default frame configuration: full screen, good-looking title bar on macOS +(setq frame-resize-pixelwise t) +(setq default-frame-alist '((fullscreen . maximized) + ;; Setting the face in here prevents flashes of + ;; color as the theme gets activated + (ns-appearance . light) + (ns-transparent-titlebar . t))) + +;; disable GUI elements +(scroll-bar-mode -1) ; hide the scroll bar +(tool-bar-mode -1) ; hide the tool bar +(menu-bar-mode +1) ; show the menu +(blink-cursor-mode -1) ; don't blink the cursor + +(setq make-pointer-invisible t) ;; hide cursor while typing +(setq use-dialog-box nil) ;; do not show GUI dialogs +(setq inhibit-startup-screen t) ;; hide the startup screen + +;; use utf-8 everywhere +(set-default-coding-systems 'utf-8) + +;; `use-package' is builtin since 29. +;; These variables must be set before loading `use-package'. +(setq use-package-always-ensure nil + use-package-always-defer t + use-package-enable-imenu-support t) + +(set-face-attribute 'default nil :family "Source Code Pro" :height 150) + +;;; early-init.el ends here diff --git a/home/programs/emacs/init.el b/home/programs/emacs/init.el new file mode 100644 index 0000000..973e4ad --- /dev/null +++ b/home/programs/emacs/init.el @@ -0,0 +1,42 @@ +;;; init.el --- This is where all emacs start. -*- lexical-binding: t -*- + +;;; Commentary: + +;;; Code: + +(add-to-list 'load-path (concat user-emacs-directory (convert-standard-filename "site-lisp/"))) + +(use-package exec-path-from-shell + :custom + (exec-path-from-shell-variables '("PATH" "MANPATH" "GOPATH" "GOBIN" "ASPELL_CONF")) + :init (exec-path-from-shell-initialize)) + +(require 'init-base) +(require 'init-ui) +(require 'init-completion) +(require 'init-text) +(require 'init-programming) +(require 'init-llm) + +(use-package server + :config + (setq server-client-instructions nil) + (unless (server-running-p) + (server-start))) + +(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")) + +;;; init.el ends here +;; byte-compile-warnings: (not docstrings lexical noruntime) +;; End: diff --git a/home/programs/emacs/site-lisp/init-base.el b/home/programs/emacs/site-lisp/init-base.el new file mode 100644 index 0000000..0593833 --- /dev/null +++ b/home/programs/emacs/site-lisp/init-base.el @@ -0,0 +1,175 @@ +;;; 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-listing-switches "-alh --group-directories-first") + (ls-lisp-dirs-first t) + (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/home/programs/emacs/site-lisp/init-completion.el b/home/programs/emacs/site-lisp/init-completion.el new file mode 100644 index 0000000..2601756 --- /dev/null +++ b/home/programs/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: + +;; default completion behavior +(fido-mode 1) + +(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 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/home/programs/emacs/site-lisp/init-llm.el b/home/programs/emacs/site-lisp/init-llm.el new file mode 100644 index 0000000..48346e6 --- /dev/null +++ b/home/programs/emacs/site-lisp/init-llm.el @@ -0,0 +1,33 @@ +;;; init-llm.el --- Configure LLMs -*- lexical-binding: t -*- +;; Author: Franck Cuny <franck@fcuny.net> + +;;; Commentary: + +;; Configure completions + +;;; Code: +(require 's) + +(defun fcuny/read-anthropic-key () + "Read and return the API key for anthropic." + (with-temp-buffer + (insert-file-contents "~/.local/share/agenix/anthropic-api-key") + (s-trim (buffer-string)))) + +(use-package gptel + :custom + (gptel-default-mode 'org-mode) + :config + (gptel-make-anthropic "Claude" :stream t :key (lambda () (fcuny/read-anthropic-key)))) + +(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-anthropic-key))) + +(provide 'init-llm) + +;;; init-llm.el ends here diff --git a/home/programs/emacs/site-lisp/init-programming.el b/home/programs/emacs/site-lisp/init-programming.el new file mode 100644 index 0000000..a2299cf --- /dev/null +++ b/home/programs/emacs/site-lisp/init-programming.el @@ -0,0 +1,199 @@ +;;; 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) + :hook (git-commit-mode . (lambda () (setq fill-column 72))) + :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/home/programs/emacs/site-lisp/init-text.el b/home/programs/emacs/site-lisp/init-text.el new file mode 100644 index 0000000..4a5739b --- /dev/null +++ b/home/programs/emacs/site-lisp/init-text.el @@ -0,0 +1,200 @@ +;;; init-text.el --- Configure text modes -*- lexical-binding: t -*- +;; Author: Franck Cuny <franck@fcuny.net> + +;;; Commentary: + +;; Configure completions + +;;; Code: + +(use-package flyspell + :hook ((text-mode . flyspell-mode) + (org-mode . flyspell-mode) + (git-commit-mode . flyspell-mode) + (prog-mode . flyspell-prog-mode)) + :diminish flyspell-mode + :custom + (ispell-program-name "aspell") + (ispell-silently-savep t) + (ispell-dictionary "en_US") + (ispell-local-dictionary "en_US") + (ispell-extra-args '("--camel-case"))) + +(use-package markdown-mode + :mode (("\\`README\\.md\\'" . gfm-mode) + ("\\.md\\'" . markdown-mode) + ("\\.markdown\\'" . markdown-mode)) + :custom + (markdown-command "pandoc -f markdown_github+smart") + (markdown-command-needs-filename t) + (markdown-enable-math t) + (markdown-open-command "marked") + :init + (setq markdown-command "multimarkdown")) + +(use-package org + :hook + (org-mode . turn-on-flyspell) + (org-mode . visual-line-mode) + (org-mode . org-indent-mode) + + :custom + (org-directory "~/Documents/org") + (org-default-notes-file (expand-file-name "notes.org" org-directory)) + + (org-startup-folded t) + (org-startup-indented t) + (org-startup-with-inline-images t) + (org-adapt-indentation 'headline-data) + + ;; enable todo and checkbox dependencies + (org-enforce-todo-dependencies t) + (org-enforce-todo-checkbox-dependencies t) + + ;; quick access for todo states + (org-todo-keywords + '((sequence "TODO(t)" "NEXT(n)" "WAITING(w!)" "SOMEDAY(S!)" "|" "DONE(d)") + (sequence "|" "CANCELLED(c)"))) + + (org-tag-alist + '((:startgroup) + ("!Handson" . ?o) + (:grouptags) + ("write" . ?w) ("code" . ?c) + (:endgroup) + + (:startgroup) + ("_Handsoff" . ?f) + (:grouptags) + ("read" . ?r) ("watch" . ?W) + (:endgroup))) + + (org-log-done 'time) + (org-log-into-drawer t) + + ;; refile + (org-refile-use-outline-path t) + (org-refile-allow-creating-parent-nodes t) + (org-refile-use-cache t) + + ;; no empty lines between items + (org-blank-before-new-entry '((heading . nil) (plain-list-item . nil))) + + (org-hide-emphasis-markers t) + (org-hide-leading-stars t) + (org-pretty-entities t) + + (org-return-follows-link t) + + (org-export-backends '(html md)) + + (org-imenu-depth 4) + + (org-insert-heading-respect-content t) + + (org-outline-path-complete-in-steps nil) + + (org-src-fontify-natively t) + (org-src-preserve-indentation t) + (org-src-tab-acts-natively t) + (org-src-window-setup 'current-window) + + (org-yank-adjusted-subtrees t) + + (org-structure-template-alist + '(("s" . "src") + ("E" . "src emacs-lisp") + ("p" . "src python") + ("e" . "example") + ("q" . "quote")))) + +(use-package org-capture + :ensure nil + :after org + :bind + ("C-c c" . org-capture) + :custom + (org-capture-templates + '(("t" "Tasks" entry (file+headline "~/Documents/org/tasks.org" "Tasks") + "* TODO %?\n :PROPERTIES:\n :CAPTURED: %U\n :END:" :prepend t)))) + +(use-package org-agenda + :ensure nil + :after org + :bind + ("C-c a" . org-agenda) + :custom + (org-agenda-start-on-weekday 1) + (org-deadline-warning-days 3) + (org-agenda-inhibit-startup t) + (org-agenda-diary-file "~/Documents/org/tasks.org") + (org-agenda-files '("~/Documents/org/tasks.org")) + (org-agenda-restore-windows-after-quit t) + (org-agenda-skip-deadline-if-done t) + (org-agenda-skip-scheduled-if-done t) + (org-agenda-custom-commands + '(;; Todo and tags views for ongoing tasks by types of activity + ("#" "To archive" todo "DONE|SKIP") + ("A" "Hands on" tags-todo "+TAGS={write\\|code}+TODO={ONGO}") + ("Z" "Hands off" tags-todo "+TAGS={read\\|watch}+TODO={ONGO}") + + ;; Agenda view to see ONGO/NEXT tasks for this week + ("*" . "What's next?") + ("**" "ONGO/NEXT all" tags-todo "TODO={NEXT}") + + ;; Agenda view to see TODO tasks with no SCHEDULED/DEADLINE + (";" . "What's to do?") + (";;" "TODO all" tags-todo "TODO={TODO}+DEADLINE=\"\"+SCHEDULED=\"\"") + + ;; Agenda view to see WAIT tasks with no SCHEDULED/DEADLINE + (":" . "What's waiting?") + ("::" "WAIT all" tags-todo "TODO={WAITING}+DEADLINE=\"\"+SCHEDULED=\"\"") + + ;; Agenda view to see upcoming deadlines with 60 days of warning period + ("!" . "Upcoming deadlines") + ("!!" "Deadlines all" agenda "Past/upcoming deadlines" + ((org-agenda-span 1) + (org-deadline-warning-days 60) + (org-agenda-entry-types '(:deadline)))))) + (org-agenda-sorting-strategy + '((agenda time-up deadline-up scheduled-up todo-state-up priority-down) + (todo todo-state-down priority-down deadline-up) + (tags todo-state-down priority-down deadline-up) + (search todo-state-down priority-down deadline-up)))) + +(use-package denote + :hook + (dired-mode . denote-dired-mode) + + :custom-face + (denote-faces-link ((t (:slant italic)))) + + :init + (require 'denote-org) + + :bind + (("C-c w d b" . denote-find-backlink) + ("C-c w d d" . denote-date) + ("C-c w d l" . denote-find-link) + ("C-c w d h" . denote-org-link-to-heading) + ("C-c w d i" . denote-link-or-create) + ("C-c w d j" . denote-journal-extras-new-or-existing-entry) + ("C-c w d k" . denote-rename-file-keywords) + ("C-c w d n" . denote) + ("C-c w d N" . denote-open-or-create) + ("C-c w d r" . denote-rename-file) + ("C-c w d R" . denote-rename-file-using-front-matter)) + + :custom + (denote-sort-keywords t) + (denote-known-keywords '("journal" "projects" "ideas" "people" "interviews")) + (denote-directory "~/Documents/org")) + +(use-package consult-denote + :after (consult denote) + :config + (consult-denote-mode)) + +(provide 'init-text) + +;;; init-text.el ends here diff --git a/home/programs/emacs/site-lisp/init-ui.el b/home/programs/emacs/site-lisp/init-ui.el new file mode 100644 index 0000000..ea1cb5a --- /dev/null +++ b/home/programs/emacs/site-lisp/init-ui.el @@ -0,0 +1,47 @@ +;;; 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 + 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 140) + +(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-deuteranopia t)) + +(provide 'init-ui) +;;; init-ui.el ends here diff --git a/home/programs/eza.nix b/home/programs/eza.nix new file mode 100644 index 0000000..d0326f6 --- /dev/null +++ b/home/programs/eza.nix @@ -0,0 +1,20 @@ +{ ... }: +{ + programs.eza = { + enable = true; + icons = "never"; + enableFishIntegration = false; + extraOptions = [ + "--group-directories-first" + "--no-quotes" + "--git-ignore" + "--icons=never" + ]; + }; + + programs.fish.shellAliases = { + la = "eza -la --git --color=always --group-directories-first"; + ll = "eza -la -L=1 --git --color=always --group-directories-first"; + lt = "eza -aT -L=2 --git --color=always --group-directories-first"; + }; +} diff --git a/home/programs/fd.nix b/home/programs/fd.nix new file mode 100644 index 0000000..cdbae66 --- /dev/null +++ b/home/programs/fd.nix @@ -0,0 +1,12 @@ +{ ... }: +{ + # an alternative to find + programs.fd = { + enable = true; + hidden = true; + ignores = [ + ".git/" + ".direnv/" + ]; + }; +} diff --git a/home/programs/fish.nix b/home/programs/fish.nix new file mode 100644 index 0000000..e5a1013 --- /dev/null +++ b/home/programs/fish.nix @@ -0,0 +1,26 @@ +{ ... }: +{ + programs.fish = { + enable = true; + interactiveShellInit = '' + set fish_greeting "" + + fish_add_path -p ~/.cargo/bin/ + + # Add utmctl to PATH + fish_add_path /Applications/UTM.app/Contents/MacOS/ + ''; + shellAbbrs = { + ncg = "nix-collect-garbage --delete-older-than 7d"; + ndc = "nix develop --command"; + nfc = "nix flake check"; + ngcroot = "ls -al /nix/var/nix/gcroots/auto/"; + nph = "nix profile history --profile /nix/var/nix/profiles/system"; + nsn = "nix search nixpkgs"; + nsv = "nix store verify --all"; + + g = "git"; + gap = "git add --patch"; + }; + }; +} diff --git a/home/programs/gh.nix b/home/programs/gh.nix new file mode 100644 index 0000000..b194b35 --- /dev/null +++ b/home/programs/gh.nix @@ -0,0 +1,15 @@ +{ ... }: +{ + programs.gh = { + enable = true; + settings = { + version = 1; + git_protocol = "ssh"; + prompt = "enabled"; + aliases = { + co = "pr checkout"; + vw = "pr view --web"; + }; + }; + }; +} diff --git a/home/programs/git.nix b/home/programs/git.nix new file mode 100644 index 0000000..354dc71 --- /dev/null +++ b/home/programs/git.nix @@ -0,0 +1,90 @@ +{ + config, + lib, + pkgs, + ... +}: +let + inherit (config) userinfo; +in +{ + home.packages = with pkgs; [ + gitAndTools.pre-commit + git-credential-manager + ]; + + programs.git = { + enable = true; + + delta = { + enable = true; + options.features = "decorations side-by-side line-numbers"; + }; + + userName = lib.mkDefault userinfo.fullName; + userEmail = lib.mkDefault userinfo.email; + + aliases = { + amend = "commit --amend"; + a = "commit --amend --no-edit"; + st = "status"; + co = "checkout"; + br = "branch"; + rb = "pull --rebase"; + hist = "log --pretty=format:\"%Cgreen%h %Creset%cd %Cblue[%cn] %Creset%s%C(yellow)%d%C(reset)\" --graph --date=relative --decorate --all"; + llog = "log --graph --name-status --pretty=format:\"%C(red)%h %C(reset)(%cd) %C(green)%an %Creset%s %C(yellow)%d%Creset\" --date=relative"; + logo = "log --pretty=format:\"%C(yellow)%h%Cred%d %Creset%s%Cblue (%cn)\" --decorate"; + logf = "log --pretty=format:\"%C(yellow)%h%Cred%d %Creset%s%Cblue (%cn)\" --decorate --numstat"; + }; + + ignores = [ + ".DS_Store" + ".aider.*" + ".direnv" + ]; + + extraConfig = { + core.whitespace = "trailing-space,space-before-tab"; + color.ui = true; + + # nicer output + column.ui = "auto"; + + # https://adamj.eu/tech/2024/01/18/git-improve-diff-histogram/ + diff.algorithm = "histogram"; + + init.defaultBranch = "main"; + + # https://blog.gitbutler.com/how-git-core-devs-configure-git/ + push = { + # abort if the remote branch does not match the local one + default = "simple"; + autoSetupRemote = true; + followTags = true; + }; + + fetch = { + prune = true; + pruneTags = true; + all = true; + }; + + pull.rebase = true; + + rebase = { + autosquash = true; + updateRefs = true; + # Automatically create a temporary stash entry before the + # operation begins, and apply it after the operation ends. + autoStash = true; + # Print a warning if some commits are removed + missingCommitsCheck = "warn"; + }; + + branch = { + autosetuprebase = "remote"; + sort = "authordate"; + }; + }; + }; +} diff --git a/home/programs/go.nix b/home/programs/go.nix new file mode 100644 index 0000000..0ae1ec1 --- /dev/null +++ b/home/programs/go.nix @@ -0,0 +1,24 @@ +{ pkgs, config, ... }: +{ + programs.go = { + enable = true; + goPath = ".local/share/pkg.go"; + goBin = ".local/bin.go"; + goPrivate = [ + "github.rbx.com/*" + "github.com/fcuny/*" + ]; + }; + + home.packages = with pkgs; [ + delve + go-tools # collection of tools, https://github.com/dominikh/go-tools + golangci-lint + gopls + ]; + + home.sessionPath = [ + config.home.sessionVariables.GOBIN + "${config.home.homeDirectory}/.local/bin" + ]; +} diff --git a/home/programs/k9s.nix b/home/programs/k9s.nix new file mode 100644 index 0000000..2d60ab1 --- /dev/null +++ b/home/programs/k9s.nix @@ -0,0 +1,59 @@ +{ ... }: +{ + programs.k9s = { + enable = true; + settings = { + k9s = { + refreshRate = 1; + }; + }; + plugin = { + plugins = { + log-bat = { + shortCut = "Shift-L"; + description = "Logs (bat)"; + scopes = [ "po" ]; + command = "bash"; + background = false; + args = [ + "-c" + "\"$@\" | bat" + "dummy-arg" + "kubectl" + "logs" + "$NAME" + "-n" + "$NAMESPACE" + "--context" + "$CONTEXT" + "--kubeconfig" + "$KUBECONFIG" + ]; + }; + log-bat-container = { + shortCut = "Shift-L"; + description = "Logs (bat)"; + scopes = [ "containers" ]; + command = "bash"; + background = false; + args = [ + "-c" + "\"$@\" | bat" + "dummy-arg" + "kubectl" + "logs" + "-c" + "$NAME" + "$POD" + "-n" + "$NAMESPACE" + "--context" + "$CONTEXT" + "--kubeconfig" + "$KUBECONFIG" + ]; + }; + }; + }; + }; +} diff --git a/home/programs/kubie.nix b/home/programs/kubie.nix new file mode 100644 index 0000000..5ac8678 --- /dev/null +++ b/home/programs/kubie.nix @@ -0,0 +1,24 @@ +{ pkgs, ... }: +{ + home.packages = with pkgs; [ + kubie # kubeconfig browser https://github.com/sbstp/kubie + ]; + + home.file.kubie = { + target = ".kube/kubie.yaml"; + text = '' + shell: fish + configs: + include: + - ~/.kube/rksconfig + prompt: + fish_use_rprompt: false + ''; + }; + + programs.fish = { + shellAbbrs = { + kctx = "kubie ctx"; + }; + }; +} diff --git a/home/programs/onepassword.nix b/home/programs/onepassword.nix new file mode 100644 index 0000000..f364a9e --- /dev/null +++ b/home/programs/onepassword.nix @@ -0,0 +1,9 @@ +{ ... }: +{ + programs.onepassword = { + enable = true; + sshKeys = [ + { account = "my.1password.com"; } # All keys from personal account + ]; + }; +} diff --git a/home/programs/ssh.nix b/home/programs/ssh.nix new file mode 100644 index 0000000..c236904 --- /dev/null +++ b/home/programs/ssh.nix @@ -0,0 +1,33 @@ +{ pkgs, config, ... }: +{ + # https://github.com/nix-community/home-manager/blob/master/modules/programs/ssh.nix + programs.ssh = { + enable = true; + forwardAgent = true; + serverAliveInterval = 60; + controlMaster = "auto"; + controlPersist = "30m"; + controlPath = "${config.home.homeDirectory}/.ssh/sockets/S.%r@%h:%p"; + + matchBlocks = { + "git.fcuny.net" = { + proxyCommand = "${pkgs.cloudflared}/bin/cloudflared access ssh --hostname %h"; + }; + "github.com" = { + hostname = "github.com"; + user = "git"; + forwardAgent = false; + extraOptions = { + preferredAuthentications = "publickey"; + controlMaster = "no"; + controlPath = "none"; + }; + }; + }; + }; + + home.file = { + # we need this path to be created so that the control path can be used. + ".ssh/sockets/.keep".text = "# Managed by Home Manager"; + }; +} diff --git a/home/programs/starship.nix b/home/programs/starship.nix new file mode 100644 index 0000000..8a541ce --- /dev/null +++ b/home/programs/starship.nix @@ -0,0 +1,40 @@ +{ ... }: +{ + programs.starship = { + enable = true; + settings = { + add_newline = false; + character = { + success_symbol = "[›](bold green)"; + error_symbol = "[›](bold red)"; + }; + directory = { + fish_style_pwd_dir_length = 3; + }; + git_branch = { + symbol = "🌱 "; + }; + git_commit = { + commit_hash_length = 4; + }; + git_status = { + deleted = "✗"; + modified = "✶"; + staged = "✓"; + stashed = "≡"; + }; + "$schema" = "https://starship.rs/config-schema.json"; + hostname = { + ssh_only = true; + }; + username = { + disabled = true; + }; + kubernetes = { + disabled = false; + style = "bold blue"; + }; + nix_shell.disabled = false; + }; + }; +} diff --git a/home/programs/tmux.nix b/home/programs/tmux.nix new file mode 100644 index 0000000..9b84f5c --- /dev/null +++ b/home/programs/tmux.nix @@ -0,0 +1,21 @@ +{ pkgs, ... }: +{ + programs.tmux = { + enable = true; + terminal = "xterm-256color"; + escapeTime = 0; + aggressiveResize = true; + baseIndex = 1; + shortcut = "z"; + clock24 = true; + shell = "${pkgs.fish}/bin/fish"; + historyLimit = 50000; # Bigger buffer + extraConfig = '' + setw -g mouse on + # Avoid date/time taking up space + set -g status-right "" + set -g status-right-length 0 + set-option -g renumber-windows on + ''; + }; +} |
