add emacs configuration

This commit is contained in:
Ray Andrew 2025-03-08 23:50:50 -06:00
parent 61b96849f8
commit 9fbf291a20
No known key found for this signature in database
23 changed files with 1466 additions and 65 deletions

View file

@ -36,7 +36,11 @@
inherit system; inherit system;
config.allowUnfree = true; config.allowUnfree = true;
}; };
lib = nixpkgs.lib; lib = import ./lib.nix {
inherit (nixpkgs) lib;
inherit pkgs;
inherit (inputs) home-manager;
};
createCommonArgs = system: { createCommonArgs = system: {
inherit inherit
self self
@ -122,6 +126,8 @@
} }
); );
packages = forAllSystems (commonArgs': (import ./packages commonArgs'));
formatter = forAllSystems ({ system, ... }: treefmtEval.${system}.config.build.wrapper); formatter = forAllSystems ({ system, ... }: treefmtEval.${system}.config.build.wrapper);
}; };

View file

@ -8,29 +8,85 @@
}: { }: {
imports = [ imports = [
./email ./email
./ssh ./emacs
./git.nix ./git.nix
./gui.nix ./gui.nix
./latex.nix ./latex.nix
./ssh
./shell.nix
]; ];
programs.neovim.enable = true; config = {
home.packages = with pkgs; [ home.packages =
gpclient with pkgs;
openconnect [
emacs fd
fd fx
ripgrep jq
yazi sd
tree ugrep
gnumake unzip
texinfo gpclient
]; openconnect
fd
ripgrep
yazi
tree
gnumake
texinfo
]
++ (lib.attrValues config.custom.shell.packages);
fonts.fontconfig.enable = true; services = {
gpg-agent = {
enable = true;
# enableSshSupport = true;
};
};
programs.home-manager.enable = true; fonts.fontconfig.enable = true;
# https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion programs = {
home.stateVersion = "25.05"; home-manager.enable = true;
neovim.enable = true;
bash = {
enable = true;
enableVteIntegration = true;
};
gpg = {
enable = true;
};
bat = {
enable = true;
extraPackages = [
(pkgs.symlinkJoin {
name = "batman";
paths = [ pkgs.bat-extras.batman ];
postBuild = ''
mkdir -p $out/share/bash-completion/completions
echo 'complete -F _comp_cmd_man batman' > $out/share/bash-completion/completions/batman
mkdir -p $out/share/fish/vendor_completions.d
echo 'complete batman --wraps man' > $out/share/fish/vendor_completions.d/batman.fish
mkdir -p $out/share/zsh/site-functions
cat << EOF > $out/share/zsh/site-functions/_batman
#compdef batman
_man "$@"
EOF
'';
meta.mainProgram = "batman";
})
];
};
fzf = {
enable = true;
enableBashIntegration = config.programs.bash.enable;
enableFishIntegration = config.programs.fish.enable;
};
};
# https://nixos.wiki/wiki/FAQ/When_do_I_update_stateVersion
home.stateVersion = "25.05";
};
} }

2
home/emacs/config/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
var
undo

View file

@ -0,0 +1,182 @@
;;; naysayer-theme.el --- The naysayer color theme
;; Author: Nick Aversano <nickav@users.noreply.github.com>
;; Version: 0.33
;; Filename: naysayer-theme.el
;; Package-Requires: ((emacs "24"))
;; URL: https://github.com/nickav/naysayer-theme.el
;; License: GPL-3+
;;; Commentary:
;; Dark green blue color scheme with tan colors. Inspired by Jonathan Blow's compiler livestreams.
;;; Code:
(unless (>= emacs-major-version 24)
(error "The naysayer theme requires Emacs 24 or later!"))
(deftheme naysayer "The naysayer color theme")
;; Monokai colors
(defcustom naysayer-theme-yellow "#E6DB74" "Primary colors - yellow" :type 'string :group 'monokai)
(defcustom naysayer-theme-orange "#FD971F" "Primary colors - orange" :type 'string :group 'monokai)
(defcustom naysayer-theme-red "#F92672" "Primary colors - red" :type 'string :group 'monokai)
(defcustom naysayer-theme-magenta "#FD5FF0" "Primary colors - magenta" :type 'string :group 'monokai)
(defcustom naysayer-theme-blue "#66D9EF" "Primary colors - blue" :type 'string :group 'monokai)
(defcustom naysayer-theme-green "#A6E22E" "Primary colors - green" :type 'string :group 'monokai)
(defcustom naysayer-theme-cyan "#A1EFE4" "Primary colors - cyan" :type 'string :group 'monokai)
(defcustom naysayer-theme-violet "#AE81FF" "Primary colors - violet" :type 'string :group 'monokai)
(let ((background "#072626")
(gutters "#072626")
(gutter-fg "#d3b58d")
(gutters-active "#062329")
(builtin "#ffffff")
(selection "blue")
(text "#d3b58d")
(comments "#3fdf1f")
(punctuation "#8cde94")
(keywords "#ffffff")
(variables "#d3b58d")
(functions "#ffffff")
(methods "#ffffff")
(strings "#0fdfaf")
(constants "#79ffcf")
(macros "lightgreen")
(numbers "#79ffcf")
(white "#ffffff")
(error "#504038")
(warning "#504038")
(highlight-line "#0b3335")
(line-fg "#126367"))
(custom-theme-set-faces
'naysayer
;; Default colors
;; *****************************************************************************
`(default ((t (:foreground ,text :background ,background, :weight normal))))
`(region ((t (:foreground nil :background ,selection))))
`(cursor ((t (:background ,white ))))
`(fringe ((t (:background ,background :foreground ,white))))
`(linum ((t (:background ,background :foreground ,gutter-fg))))
`(highlight ((t (:foreground nil :background ,selection))))
;; Font lock faces
;; *****************************************************************************
`(font-lock-keyword-face ((t (:foreground ,keywords))))
`(font-lock-type-face ((t (:foreground ,punctuation))))
`(font-lock-constant-face ((t (:foreground ,constants))))
`(font-lock-variable-name-face ((t (:foreground ,variables))))
`(font-lock-builtin-face ((t (:foreground ,builtin))))
`(font-lock-string-face ((t (:foreground ,strings))))
`(font-lock-comment-face ((t (:foreground ,comments))))
`(font-lock-comment-delimiter-face ((t (:foreground ,comments))))
`(font-lock-doc-face ((t (:foreground ,comments))))
`(font-lock-function-name-face ((t (:foreground ,functions))))
`(font-lock-doc-string-face ((t (:foreground ,strings))))
`(font-lock-preprocessor-face ((t (:foreground ,macros))))
`(font-lock-warning-face ((t (:foreground ,warning))))
;; Plugins
;; *****************************************************************************
`(trailing-whitespace ((t (:foreground nil :background ,warning))))
`(whitespace-trailing ((t (:background nil :foreground ,warning :inverse-video t))))
`(linum ((t (:foreground ,line-fg :background ,background))))
`(linum-relative-current-face ((t (:foreground ,white :background ,background))))
`(line-number ((t (:foreground ,line-fg :background ,background))))
`(line-number-current-line ((t (:foreground ,white :background ,background))))
;; hl-line-mode
`(hl-line ((t (:background ,highlight-line))))
`(hl-line-face ((t (:background ,highlight-line))))
;; rainbow-delimiters
`(rainbow-delimiters-depth-1-face ((t (:foreground ,naysayer-theme-violet))))
`(rainbow-delimiters-depth-2-face ((t (:foreground ,naysayer-theme-blue))))
`(rainbow-delimiters-depth-3-face ((t (:foreground ,naysayer-theme-green))))
`(rainbow-delimiters-depth-4-face ((t (:foreground ,naysayer-theme-yellow))))
`(rainbow-delimiters-depth-5-face ((t (:foreground ,naysayer-theme-orange))))
`(rainbow-delimiters-depth-6-face ((t (:foreground ,naysayer-theme-red))))
`(rainbow-delimiters-depth-7-face ((t (:foreground ,naysayer-theme-violet))))
`(rainbow-delimiters-depth-8-face ((t (:foreground ,naysayer-theme-blue))))
`(rainbow-delimiters-depth-9-face ((t (:foreground ,naysayer-theme-green))))
`(rainbow-delimiters-depth-10-face ((t (:foreground ,naysayer-theme-yellow))))
`(rainbow-delimiters-depth-11-face ((t (:foreground ,naysayer-theme-orange))))
`(rainbow-delimiters-depth-12-face ((t (:foreground ,naysayer-theme-red))))
;; which-func
`(which-func ((t (:inverse-video unspecified
:underline unspecified
:foreground ,background
:weight bold
:box nil))))
;; mode-line and powerline
`(mode-line-buffer-id ((t (:foreground ,background :distant-foreground ,text :text ,text :weight bold))))
`(mode-line ((t (:inverse-video unspecified
:underline unspecified
:foreground ,background
:background ,text
:box nil))))
`(powerline-active1 ((t (:background ,text :foreground ,background))))
`(powerline-active2 ((t (:background ,text :foreground ,background))))
`(mode-line-inactive ((t (:inverse-video unspecified
:underline unspecified
:foreground ,text
:background ,background
:box nil))))
`(powerline-inactive1 ((t (:background ,background :foreground ,text))))
`(powerline-inactive2 ((t (:background ,background :foreground ,text))))
;; better compatibility with default DOOM mode-line
`(error ((t (:foreground nil :weight normal))))
`(doom-modeline-project-dir ((t (:foreground nil :weight bold))))
;; js2-mode
`(js2-function-call ((t (:inherit (font-lock-function-name-face)))))
`(js2-function-param ((t (:foreground ,text))))
`(js2-jsdoc-tag ((t (:foreground ,keywords))))
`(js2-jsdoc-type ((t (:foreground ,constants))))
`(js2-jsdoc-value((t (:foreground ,text))))
`(js2-object-property ((t (:foreground ,text))))
`(js2-external-variable ((t (:foreground ,constants))))
`(js2-error ((t (:foreground ,error))))
`(js2-warning ((t (:foreground ,warning))))
;; highlight numbers
`(highlight-numbers-number ((t (:foreground ,numbers))))
;; tab-bar-mode
`(tab-bar ((t (:inherit modeline))))
`(tab-bar-tab ((t (:foreground ,background :background ,text))))
`(tab-bar-tab-inactive ((t (:foreground ,text :background ,background))))
)
(custom-theme-set-variables
'naysayer
'(linum-format " %5i ")
)
)
;;;###autoload
(when (and (boundp 'custom-theme-load-path) load-file-name)
(add-to-list 'custom-theme-load-path
(file-name-as-directory (file-name-directory load-file-name))))
;; *****************************************************************************
(provide-theme 'naysayer)
;; Local Variables:
;; no-byte-compile: t
;; End:
(provide 'naysayer-theme)
;;; naysayer-theme.el ends here

View file

@ -0,0 +1,53 @@
{
"name": "Witness Color Scheme",
"globals": {
"accent": "#d3b58d",
"background": "#072626",
"block_caret": "rgba(144, 238, 144, 0.6)",
"brackets_options": "underline",
"caret": "rgba(144, 238, 144, 1)",
"fold_marker": "#d3b58d",
"foreground": "#d3b58d",
"gutter": "#072626",
"gutter_foreground": "#d3b58d",
"inactive_selection": "#0049f5",
"line_highlight": "#072626",
"selection": "blue",
"tags_options": "underline"
},
"rules": [
{
"scope": "comment",
"foreground": "#3fdf1f"
},
{
"scope": "constant.language",
"foreground": "#79ffcf"
},
{
"scope": "entity.name, keyword.declaration, meta.annotation, meta.path, meta.struct meta.block, meta.tag, support.variable, variable, variable.other.readwrite",
"foreground": "lightblue"
},
{
"scope": "entity.name.constant, keyword.control, meta.class entity.name.class, meta.constant, meta.function.parameters, meta.struct entity.name.struct, meta.struct meta.group, storage.type, support.constant, support.type, variable.type",
"foreground": "lightgreen"
},
{
"scope": "entity.name.enum, keyword.operator, meta.block meta.method entity.name.function, meta.block storage.modifier, meta.class storage.type, meta.function-call variable.function, meta.preprocessor, meta.struct storage.type - meta.block, meta.template storage.type, punctuation.section, variable.other",
"foreground": "#d3b58d"
},
{
"scope": "entity.name.function, keyword, storage",
"foreground": "white"
},
{
"scope": "invalid",
"foreground": "darkseagreen",
"background": "#504038"
},
{
"scope": "string",
"foreground": "#0fdfaf"
}
]
}

View file

@ -0,0 +1,609 @@
;;; post-init.el --- Post Initalization -*- no-byte-compile: t; lexical-binding: t; -*-
;; Auto-revert in Emacs is a feature that automatically updates the
;; contents of a buffer to reflect changes made to the underlying file
;; on disk.
(add-hook 'elpaca-after-init-hook #'global-auto-revert-mode)
;; recentf is an Emacs package that maintains a list of recently
;; accessed files, making it easier to reopen files you have worked on
;; recently.
(add-hook 'elpaca-after-init-hook #'(lambda()
(let ((inhibit-message t))
(recentf-mode 1))))
(add-hook 'kill-emacs-hook #'recentf-cleanup)
;; savehist is an Emacs feature that preserves the minibuffer history between
;; sessions. It saves the history of inputs in the minibuffer, such as commands,
;; search strings, and other prompts, to a file. This allows users to retain
;; their minibuffer history across Emacs restarts.
(add-hook 'elpaca-after-init-hook #'savehist-mode)
;; save-place-mode enables Emacs to remember the last location within a file
;; upon reopening. This feature is particularly beneficial for resuming work at
;; the precise point where you previously left off.
(add-hook 'elpaca-after-init-hook #'save-place-mode)
(use-package emacs
:elpaca nil
:ensure nil
:custom
(delete-selection-mode t) ;; Select text and delete it by typing.
(electric-indent-mode nil) ;; Turn off the weird indenting that Emacs does by default.
(electric-pair-mode t) ;; Turns on automatic parens pairing
(blink-cursor-mode nil) ;; Don't blink cursor
(global-auto-revert-mode t) ;; Automatically reload file and show changes if the file has changed
(indent-tabs-mode nil)
;;(dired-kill-when-opening-new-dired-buffer t) ;; Dired don't create new buffer
(recentf-mode t) ;; Enable recent file mode
(recentf-max-saved-items 50)
;;(global-visual-line-mode t) ;; Enable truncated lines
;;(display-line-numbers-type 'relative) ;; Relative line numbers
(global-display-line-numbers-mode t) ;; Display line numbers
(split-width-threshold nil) ;; Splitting behavior
:bind (([escape] . keyboard-escape-quit)
("C-x c" . compile)))
;; =========================
;; Theme
;; =========================
(use-package naysayer-theme
:ensure nil
;; :defer t
;; :elpaca nil
:config
(load-theme 'naysayer t)
:load-path rs/lib-dir)
(global-font-lock-mode 1)
(set-cursor-color "lightgreen")
(set-background-color "#072626")
;; (global-set-key [C-return] 'save-buffer)
;(set-face-attribute 'default nil :font "Anonymous Pro-14")
;; (set-face-attribute 'default nil :font "Consolas-174")
(set-face-foreground 'font-lock-builtin-face "lightgreen")
;; =========================
;; Better UX
;; =========================
(use-package vertico
;; (Note: It is recommended to also enable the savehist package.)
:ensure t
:defer t
:commands (vertico-mode vertico-multiform-mode)
:custom
(vertico-cycle t)
(vertico-multiform-commands
'((consult-imenu buffer indexed)
(find-file flat (vertico-cycle . t))
(execute-extended-command flat (vertico-cycle . t))))
(vertico-multiform-categories
'((consult-grep buffer)))
:hook
(elpaca-after-init . vertico-mode)
(elpaca-after-init . vertico-multiform-mode))
(use-package orderless
;; Vertico leverages Orderless' flexible matching capabilities, allowing users
;; to input multiple patterns separated by spaces, which Orderless then
;; matches in any order against the candidates.
:ensure t
:custom
(completion-styles '(orderless basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles partial-completion)))))
(use-package marginalia
;; Marginalia allows Embark to offer you preconfigured actions in more contexts.
;; In addition to that, Marginalia also enhances Vertico by adding rich
;; annotations to the completion candidates displayed in Vertico's interface.
:ensure t
:defer t
:commands (marginalia-mode marginalia-cycle)
:hook (elpaca-after-init . marginalia-mode))
(use-package embark
;; Embark is an Emacs package that acts like a context menu, allowing
;; users to perform context-sensitive actions on selected items
;; directly from the completion interface.
:ensure t
:defer t
:commands (embark-act
embark-dwim
embark-export
embark-collect
embark-bindings
embark-prefix-help-command)
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
(setq prefix-help-command #'embark-prefix-help-command)
:config
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
(use-package embark-consult
:ensure t
:hook
(embark-collect-mode . consult-preview-at-point-mode))
(use-package consult
:ensure t
:bind (;; C-c bindings in `mode-specific-map'
("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command)
("C-x b" . consult-buffer)
("C-x 4 b" . consult-buffer-other-window)
("C-x 5 b" . consult-buffer-other-frame)
("C-x t b" . consult-buffer-other-tab)
("C-x r b" . consult-bookmark)
("C-x p b" . consult-project-buffer)
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop)
;; M-g bindings in `goto-map'
("M-g e" . consult-compile-error)
("M-g f" . consult-flymake)
("M-g g" . consult-goto-line)
("M-g M-g" . consult-goto-line)
("M-g o" . consult-outline)
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
("M-g i" . consult-imenu)
("M-g I" . consult-imenu-multi)
;; M-s bindings in `search-map'
("M-s d" . consult-find)
("M-s c" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history)
("M-s e" . consult-isearch-history)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history)
("M-r" . consult-history))
;; Enable automatic preview at point in the *Completions* buffer.
:hook (completion-list-mode . consult-preview-at-point-mode)
:init
;; Optionally configure the register formatting. This improves the register
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Optionally tweak the register preview window.
(advice-add #'register-preview :override #'consult-register-window)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:config
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
(setq consult-narrow-key "<"))
;; Outline Indent
(use-package outline-indent
:ensure t
:defer t
:commands outline-indent-minor-mode
:init
;; The minor mode can also be automatically activated for a certain modes.
;; For example for Python and YAML:
(add-hook 'python-mode-hook #'outline-indent-minor-mode)
(add-hook 'python-ts-mode-hook #'outline-indent-minor-mode)
(add-hook 'yaml-mode-hook #'outline-indent-minor-mode)
(add-hook 'yaml-ts-mode-hook #'outline-indent-minor-mode)
:custom
(outline-indent-ellipsis ""))
;; Dired
(defun rs/dired-copy-path-at-point ()
(interactive)
(dired-copy-filename-as-kill 0))
(use-package dired
:ensure nil
:bind (("C-x -" . dired-jump)
("C-x e" . dired-jump)
(:map dired-mode-map
("-" . dired-up-directory)
("W" . rs/dired-copy-path-at-point)))
:custom
(dired-deletion-confirmer #'y-or-n-p)
(dired-dwim-target t)
;; (dired-listing-switches "-Alh")
(dired-listing-switches "-AlhcF --group-directories-first")
(dired-auto-revert-buffer t))
(use-package dired-x
:after dired
:ensure nil)
;; Dired buffers: Automatically hide file details (permissions, size,
;; modification date, etc.) and all the files in the `dired-omit-files' regular
;; expression for a cleaner display.
(add-hook 'dired-mode-hook #'dired-hide-details-mode)
;; Hide files from dired
(setq dired-omit-files (concat "\\`[.]\\'"
"\\|\\(?:\\.js\\)?\\.meta\\'"
"\\|\\.\\(?:elc|a\\|o\\|pyc\\|pyo\\|swp\\|class\\)\\'"
"\\|^\\.DS_Store\\'"
"\\|^\\.\\(?:svn\\|git\\)\\'"
"\\|^\\.ccls-cache\\'"
"\\|^__pycache__\\'"
"\\|^\\.project\\(?:ile\\)?\\'"
"\\|^flycheck_.*"
"\\|^flymake_.*"))
(add-hook 'dired-mode-hook #'dired-omit-mode)
;; Undo Tree
(use-package undo-tree
:ensure t
:defer t
;; :demand t
:diminish
:bind (("C-M-u" . undo-tree-visualize)
("M-_" . undo-tree-redo)
("M--" . go-back-to-last-edit)
:map undo-tree-map
(("C-x u" . nil)))
:custom
(undo-tree-visualizer-diff t)
(undo-tree-enable-undo-in-region t)
;; (undo-tree-auto-save-history nil)
(undo-tree-history-directory-alist `((".*" . ,(expand-file-name "undo" rs/emacs-dir))))
;; (setq undo-tree-visualizer-relative-timestamps nil)
;; (setq undo-tree-visualizer-timestamps t)
:config
(defun go-back-to-last-edit ()
"Jump back to the last change in the current buffer."
(interactive)
(ignore-errors
(let ((inhibit-message t))
(undo-tree-undo)
(undo-tree-redo))))
(defun undo-tree-split-side-by-side (original-function &rest args)
"Split undo-tree side-by-side"
(let ((split-height-threshold nil)
(split-width-threshold 0))
(apply original-function args)))
(advice-add 'undo-tree-visualize :around #'undo-tree-split-side-by-side)
:hook
(elpaca-after-init . global-undo-tree-mode))
(use-package multiple-cursors
:bind (("C-S-c C-S-c" . mc/edit-lines)
("C-M-SPC" . set-rectangular-region-anchor)
("C->" . mc/mark-next-like-this)
("C-<" . mc/mark-previous-like-this)
("C-c C-<" . mc/mark-all-like-this)
("C-\"" . mc/skip-to-next-like-this)
("C-:" . mc/skip-to-previous-like-this)))
(use-package move-text
:bind (("M-p" . move-text-up)
("M-n" . move-text-down)))
;; =========================
;; Magit
;; =========================
(use-package magit
:commands magit-status
:bind ("C-x g" . magit))
;; =========================
;; Programming Languages
;; =========================
(use-package nix-mode
:mode "\\.nix\\'")
(use-package python-mode
:mode ("\\.py\\'" . python-mode))
(use-package markdown-mode
:mode ("\\.md\\'" . markdown-mode))
(use-package lua-mode
:mode ("\\.lua\\'" . lua-mode))
(use-package yaml-mode
:mode (("\\.yml\\'" . yaml-mode)
("\\.yaml\\'" . yaml-mode)))
(use-package yasnippet
:commands (yas-minor-modeb yas-reload-all)
:config
(yas-reload-all)
:hook
;; (elpaca-after-init . yas-reload-all)
(prog-mode . yas-minor-mode))
(use-package yasnippet-snippets
:after yasnippet)
(use-package clipetty
:hook (elpaca-after-init . global-clipetty-mode))
;; =========================
;; Miscellaneous
;; =========================
(global-unset-key (kbd "C-M-_")) ;; unbind redo-undo
(use-package diminish)
(use-package rainbow-mode
:commands (rainbow-mode))
(use-package rainbow-delimiters
:hook (prog-mode . rainbow-delimiters-mode))
(use-package term-keys
:ensure (:host github :repo "CyberShadow/term-keys")
:config (unless (display-graphic-p) (term-keys-mode t)))
(use-package windmove
:elpaca nil
:bind (("C-c <left>" . windmove-left)
("C-c <right>" . windmove-right)
("C-c <up>" . windmove-up)
("C-c <down>" . windmove-down)))
(use-package ace-window
:defer t
:commands (ace-window)
:bind ("C-x C-o" . ace-window))
(use-package compat)
(use-package transient)
(use-package compile-angel
:diminish
:ensure t
:demand t
:config
;; Set `compile-angel-verbose` to nil to suppress output from compile-angel.
;; Drawback: The minibuffer will not display compile-angel's actions.
(setq compile-angel-verbose nil)
(compile-angel-on-load-mode)
(add-hook 'emacs-lisp-mode-hook #'compile-angel-on-save-local-mode))
(use-package which-key
;; :elpaca nil
:defer t
:commands which-key-mode
:hook (elpaca-after-init . which-key-mode)
:custom
(which-key-idle-delay 1.5)
(which-key-idle-secondary-delay 0.25)
(which-key-add-column-padding 1)
(which-key-max-description-length 40))
(unless (and (eq window-system 'mac)
(bound-and-true-p mac-carbon-version-string))
;; Enables `pixel-scroll-precision-mode' on all operating systems and Emacs
;; versions, except for emacs-mac.
;;
;; Enabling `pixel-scroll-precision-mode' is unnecessary with emacs-mac, as
;; this version of Emacs natively supports smooth scrolling.
;; https://bitbucket.org/mituharu/emacs-mac/commits/65c6c96f27afa446df6f9d8eff63f9cc012cc738
(setq pixel-scroll-precision-use-momentum nil) ; Precise/smoother scrolling
(pixel-scroll-precision-mode 1))
(unless (display-graphic-p)
(xterm-mouse-mode 1)
(global-set-key (kbd "<mouse-4>") 'scroll-down-line)
(global-set-key (kbd "<mouse-5>") 'scroll-up-line))
;; Display the time in the modeline
(display-time-mode 1)
;; Paren match highlighting
(show-paren-mode 1)
;; Track changes in the window configuration, allowing undoing actions such as
;; closing windows.
(winner-mode 1)
;; Replace selected text with typed text
(delete-selection-mode 1)
;; Configure Emacs to ask for confirmation before exiting
(setq confirm-kill-emacs 'y-or-n-p)
(use-package uniquify
:ensure nil
:custom
(uniquify-buffer-name-style 'reverse)
(uniquify-separator "")
(uniquify-after-kill-buffer-p t)
(uniquify-ignore-buffers-re "^\\*"))
;; Window dividers separate windows visually. Window dividers are bars that can
;; be dragged with the mouse, thus allowing you to easily resize adjacent
;; windows.
;; https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Dividers.html
(add-hook 'elpaca-after-init-hook #'window-divider-mode)
;; Enable on-the-fly spell checking (Flyspell mode).
(add-hook 'text-mode-hook #'flyspell-mode)
;; Change split behavior
(defun delete-window-evenly ()
(interactive)
(command-execute 'delete-window)
(command-execute 'balance-windows))
(global-set-key (kbd "C-x 0") 'delete-window-evenly)
(defun split-vertical-evenly ()
(interactive)
(command-execute 'split-window-vertically)
(command-execute 'balance-windows))
(global-set-key (kbd "C-x 2") 'split-vertical-evenly)
(defun split-horizontal-evenly ()
(interactive)
(command-execute 'split-window-horizontally)
(command-execute 'balance-windows))
(global-set-key (kbd "C-x 3") 'split-horizontal-evenly)
;; Increase/Decrease Font
(defun rs/zoom-frame (&optional amt frame)
"Increaze FRAME font size by amount AMT. Defaults to selected
frame if FRAME is nil, and to 1 if AMT is nil."
(interactive "p")
(let* ((frame (or frame (selected-frame)))
(font (face-attribute 'default :font frame))
(size (font-get font :size))
(amt (or amt 1))
(new-size (+ size amt)))
(set-frame-font (font-spec :size new-size) t `(,frame))
(message "Frame's font new size: %d" new-size)))
(defun rs/zoom-frame-out (&optional amt frame)
"Call `rs/zoom-frame' with negative argument."
(interactive "p")
(rs/zoom-frame (- (or amt 1)) frame))
(global-set-key (kbd "C-=") 'rs/zoom-frame)
(global-set-key (kbd "C--") 'rs/zoom-frame-out)
(global-set-key (kbd "<C-down-mouse-4>") 'rs/zoom-frame)
(global-set-key (kbd "<C-down-mouse-5>") 'rs/zoom-frame-out)
(global-set-key (kbd "<C-wheel-up>") 'rs/zoom-frame)
(global-set-key (kbd "<C-wheel-down>") 'rs/zoom-frame-out)
;; =========================
;; Org
;; =========================
;; Agenda variables
(setq org-directory "~/Documents/org/") ; Non-absolute paths for agenda and
; capture templates will look here.
(setq org-agenda-files '("inbox.org" "work.org"))
;; Default tags
(setq org-tag-alist '(
;; locale
(:startgroup)
("home" . ?h)
("work" . ?w)
("school" . ?s)
(:endgroup)
(:newline)
;; scale
(:startgroup)
("one-shot" . ?o)
("project" . ?j)
("tiny" . ?t)
(:endgroup)
;; misc
("meta")
("review")
("reading")))
;; Org-refile: where should org-refile look?
(setq org-refile-targets 'FIXME)
;;; Phase 3 variables
;; Org-roam variables
(setq org-roam-directory "~/Documents/org-roam/")
(setq org-roam-index-file "~/Documents/org-roam/index.org")
;;; Optional variables
;; Advanced: Custom link types
;; This example is for linking a person's 7-character ID to their page on the
;; free genealogy website Family Search.
(setq org-link-abbrev-alist
'(("family_search" . "https://www.familysearch.org/tree/person/details/%s")))
(use-package org
:elpaca nil
:hook ((org-mode . visual-line-mode) ; wrap lines at word breaks
(org-mode . flyspell-mode)) ; spell checking!
:bind (:map global-map
("C-c l s" . org-store-link) ; Mnemonic: link → store
("C-c l i" . org-insert-link-global)) ; Mnemonic: link → insert
:config
(require 'oc-csl) ; citation support
(add-to-list 'org-export-backends 'md)
(setf (cdr (assoc 'file org-link-frame-setup)) 'find-file)
(setq org-export-with-smart-quotes t)
(setq org-todo-keywords
'((sequence "TODO(t)" "WAITING(w@/!)" "STARTED(s!)" "|" "DONE(d!)" "OBSOLETE(o@)")))
(setq org-outline-path-complete-in-steps nil)
(setq org-refile-use-outline-path 'file)
(setq org-capture-templates
'(("c" "Default Capture" entry (file "inbox.org")
"* TODO %?\n%U\n%i")
;; Capture and keep an org-link to the thing we're currently working with
("r" "Capture with Reference" entry (file "inbox.org")
"* TODO %?\n%U\n%i\n%a")
;; Define a section
("w" "Work")
("wm" "Work meeting" entry (file+headline "work.org" "Meetings")
"** TODO %?\n%U\n%i\n%a")
("wr" "Work report" entry (file+headline "work.org" "Reports")
"** TODO %?\n%U\n%i\n%a")))
(setq org-agenda-custom-commands
'(("n" "Agenda and All Todos"
((agenda)
(todo)))
("w" "Work" agenda ""
((org-agenda-files '("work.org")))))))

View file

@ -0,0 +1,26 @@
;;; pre-early-init.el --- Pre Early Initalization -*- no-byte-compile: t; lexical-binding: t; -*-
(defconst rs/emacs-dir minimal-emacs-user-directory)
(defconst rs/lib-dir (concat (expand-file-name "lib" minimal-emacs-user-directory) "/"))
;; Reducing clutter in ~/.emacs.d by redirecting files to ~/emacs.d/var/
(setq minimal-emacs-var-dir (expand-file-name "var/" minimal-emacs-user-directory))
(setq package-user-dir (expand-file-name "elpa" minimal-emacs-var-dir))
(setq user-emacs-directory minimal-emacs-var-dir)
;; By default, minimal-emacs-package-initialize-and-refresh is set to t, which
;; makes minimal-emacs.d call the built-in package manager. Since Elpaca will
;; replace the package manager, there is no need to call it.
(setq minimal-emacs-package-initialize-and-refresh nil)
(setq minimal-emacs-gc-cons-threshold (* 64 1024 1024))
(setq custom-file null-device)
;; disable screen flashing because bg color hasn't initialized yet from theme
;; (setq default-frame-alist '((background-color . "#062329")
;; (ns-appearance . dark)
;; (ns-transparent-titlebar . t)))
(setq default-frame-alist '((background-color . "#072626")
(ns-appearance . dark)
(ns-transparent-titlebar . t)))

View file

@ -0,0 +1,56 @@
;;; pre-init.el --- Pre Initalization -*- no-byte-compile: t; lexical-binding: t; -*-
(defvar elpaca-installer-version 0.10)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
:ref nil :depth 1 :inherit ignore
:files (:defaults "elpaca-test.el" (:exclude "extensions"))
:build (:not elpaca--activate-package)))
(let* ((repo (expand-file-name "elpaca/" elpaca-repos-directory))
(build (expand-file-name "elpaca/" elpaca-builds-directory))
(order (cdr elpaca-order))
(default-directory repo))
(add-to-list 'load-path (if (file-exists-p build) build repo))
(unless (file-exists-p repo)
(make-directory repo t)
(when (< emacs-major-version 28) (require 'subr-x))
(condition-case-unless-debug err
(if-let* ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
((zerop (apply #'call-process `("git" nil ,buffer t "clone"
,@(when-let* ((depth (plist-get order :depth)))
(list (format "--depth=%d" depth) "--no-single-branch"))
,(plist-get order :repo) ,repo))))
((zerop (call-process "git" nil buffer t "checkout"
(or (plist-get order :ref) "--"))))
(emacs (concat invocation-directory invocation-name))
((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
"--eval" "(byte-recompile-directory \".\" 0 'force)")))
((require 'elpaca))
((elpaca-generate-autoloads "elpaca" repo)))
(progn (message "%s" (buffer-string)) (kill-buffer buffer))
(error "%s" (with-current-buffer buffer (buffer-string))))
((error) (warn "%s" err) (delete-directory repo 'recursive))))
(unless (require 'elpaca-autoloads nil t)
(require 'elpaca)
(elpaca-generate-autoloads "elpaca" repo)
(load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))
;; Optional: Install use-package support
(elpaca elpaca-use-package
(elpaca-use-package-mode))
(defun rs/get-default-font ()
(cond
((eq system-type 'windows-nt) "Consolas-11")
((eq system-type 'gnu/linux) "Consolas-11")
((eq system-type 'darwin) "Consolas-11")))
;; Font settings
;; (set-frame-font (font-spec :size 13))
(set-face-font 'default (rs/get-default-font))
;; (add-to-list 'default-frame-alist `(font . ,(rs/get-default-font)))
;; (setq-default line-spacing 0.11)

26
home/emacs/default.nix Normal file
View file

@ -0,0 +1,26 @@
{
lib,
pkgs,
inputs,
config,
dots,
...
}: {
options.custom = with lib; {
emacs = {
enable = mkEnableOption "Enable emacs";
};
};
config = lib.mkIf config.custom.emacs.enable {
home.packages = with pkgs; [
emacs
];
home.file.".emacs.d" = {
source = "${pkgs.custom.minimal-emacs-d}";
};
xdg.configFile."emacs".source = config.lib.file.mkOutOfStoreSymlink "${dots}/home/emacs/config";
};
}

View file

@ -11,6 +11,7 @@
imports = [ imports = [
./davmail.nix ./davmail.nix
./neomutt ./neomutt
./mailcap.nix
]; ];
options.custom.email = with lib; { options.custom.email = with lib; {

59
home/shell.nix Normal file
View file

@ -0,0 +1,59 @@
{
config,
lib,
pkgs,
dots,
...
}:
{
options.custom = with lib; {
shell = {
packages = mkOption {
type =
with types;
attrsOf (oneOf [
str
attrs
package
]);
default = { };
apply = custom.mkShellPackages;
description = ''
Attrset of shell packages to install and add to pkgs.custom overlay (for compatibility across multiple shells).
Both string and attr values will be passed as arguments to writeShellApplicationCompletions
'';
example = ''
shell.packages = {
myPackage1 = "echo 'Hello, World!'";
myPackage2 = {
runtimeInputs = [ pkgs.hello ];
text = "hello --greeting 'Hi'";
};
}
'';
};
# additionalSourceFile = mkOption {
# type =
# with types;
# nullOr (oneOf [
# path
# str
# ]);
# default = "${dots}/src/home/shell/custom.sh";
# };
};
};
config = {
# programs.bash = lib.mkIf (config.custom.shell.additionalSourceFile != null) {
# bashrcExtra = lib.mkAfter ''
# source ${config.custom.shell.additionalSourceFile}
# '';
# };
# programs.zsh = lib.mkIf (config.custom.shell.additionalSourceFile != null) {
# initExtra = lib.mkAfter ''
# source ${config.custom.shell.additionalSourceFile}
# '';
# };
};
}

View file

@ -30,6 +30,7 @@ let
./${host} ./${host}
./${host}/hardware.nix ./${host}/hardware.nix
../nixos ../nixos
../overlays
({config, ...}: { ({config, ...}: {
home-manager = { home-manager = {
useGlobalPkgs = true; useGlobalPkgs = true;

View file

@ -43,6 +43,7 @@
# home manager # home manager
hm.custom = { hm.custom = {
emacs.enable = true;
latex.enable = false; latex.enable = false;
gui = { gui = {
default.enable = true; default.enable = true;

View file

@ -45,6 +45,7 @@
# home manager # home manager
hm.custom = { hm.custom = {
emacs.enable = true;
latex.enable = true; latex.enable = true;
gui = { gui = {
default.enable = true; default.enable = true;

67
lib.nix Normal file
View file

@ -0,0 +1,67 @@
{
lib,
pkgs,
...
}:
lib.extend (
_: libprev: {
custom = rec {
# taken from https://github.com/iynaix/dotfiles/blob/main/lib.nix
# writeShellApplication with support for completions
writeShellApplicationCompletions =
{
name,
bashCompletion ? null,
zshCompletion ? null,
fishCompletion ? null,
...
}@shellArgs:
let
inherit (pkgs) writeShellApplication writeTextFile symlinkJoin;
# get the needed arguments for writeShellApplication
app = writeShellApplication (lib.intersectAttrs (lib.functionArgs writeShellApplication) shellArgs);
completions =
lib.optional (bashCompletion != null) (writeTextFile {
name = "${name}.bash";
destination = "/share/bash-completion/completions/${name}.bash";
text = bashCompletion;
})
++ lib.optional (zshCompletion != null) (writeTextFile {
name = "${name}.zsh";
destination = "/share/zsh/site-functions/_${name}";
text = zshCompletion;
})
++ lib.optional (fishCompletion != null) (writeTextFile {
name = "${name}.fish";
destination = "/share/fish/vendor_completions.d/${name}.fish";
text = fishCompletion;
});
in
if lib.length completions == 0 then
app
else
symlinkJoin {
inherit name;
inherit (app) meta;
paths = [ app ] ++ completions;
};
# taken from https://github.com/iynaix/dotfiles/blob/main/lib.nix
# produces an attrset shell package with completions from either a string / writeShellApplication attrset / package
mkShellPackages = lib.mapAttrs (
name: value:
if lib.isString value then
pkgs.writeShellApplication {
inherit name;
text = value;
}
# packages
else if lib.isDerivation value then
value
# attrs to pass to writeShellApplication
else
writeShellApplicationCompletions (value // { inherit name; })
);
};
}
)

View file

@ -14,61 +14,79 @@
./displaymanager.nix ./displaymanager.nix
./keyd.nix ./keyd.nix
./gnupg.nix ./gnupg.nix
./nix.nix
./sops.nix ./sops.nix
]; ];
nix = let options.custom = with lib; {
flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs; shell = {
in { packages = mkOption {
settings = { type =
# Enable flakes and new 'nix' command with types;
experimental-features = "nix-command flakes"; attrsOf (oneOf [
# Opinionated: disable global registry str
flake-registry = ""; attrs
# Workaround for https://github.com/NixOS/nix/issues/9574 package
nix-path = config.nix.nixPath; ]);
apply = custom.mkShellPackages;
default = { };
description = ''
Attrset of shell packages to install and add to pkgs.custom overlay (for compatibility across multiple shells).
Both string and attr values will be passed as arguments to writeShellApplicationCompletions
'';
example = ''
shell.packages = {
myPackage1 = "echo 'Hello, World!'";
myPackage2 = {
runtimeInputs = [ pkgs.hello ];
text = "hello --greeting 'Hi'";
};
}
'';
};
}; };
# Opinionated: disable channels symlinks = mkOption {
channel.enable = false; type = types.attrsOf types.str;
default = { };
# Opinionated: make flake registry and nix path match flake inputs description = "Symlinks to create in the format { dest = src;}";
registry = lib.mapAttrs (_: flake: {inherit flake;}) flakeInputs;
nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs;
};
# networking
networking.hostName = host;
networking.hostId = builtins.substring 0 8 (builtins.hashString "md5" config.networking.hostName);
networking.networkmanager.enable = true;
programs.dconf.enable = true;
services.libinput = {
enable = true;
touchpad = {
disableWhileTyping = true;
naturalScrolling = true;
}; };
}; };
security.rtkit.enable = true; config = {
security.polkit.enable = true; # networking
networking.hostName = host;
networking.hostId = builtins.substring 0 8 (builtins.hashString "md5" config.networking.hostName);
networking.networkmanager.enable = true;
services.openssh = { programs.dconf.enable = true;
enable = true;
settings = { services.libinput = {
# Opinionated: forbid root login through SSH. enable = true;
PermitRootLogin = "no"; touchpad = {
# Opinionated: use keys only. disableWhileTyping = true;
# Remove if you want to SSH using passwords naturalScrolling = true;
PasswordAuthentication = false; };
}; };
security.rtkit.enable = true;
security.polkit.enable = true;
services.openssh = {
enable = true;
settings = {
# Opinionated: forbid root login through SSH.
PermitRootLogin = "no";
# Opinionated: use keys only.
# Remove if you want to SSH using passwords
PasswordAuthentication = false;
};
};
environment.systemPackages = with pkgs; [
vim
htop
] ++ (lib.attrValues config.custom.shell.packages);
system.stateVersion = "25.05";
}; };
environment.systemPackages = with pkgs; [
vim
htop
];
system.stateVersion = "25.05";
} }

138
nixos/nix.nix Normal file
View file

@ -0,0 +1,138 @@
{
config,
host,
inputs,
lib,
pkgs,
self,
user,
dots,
...
}:
{
# execute shebangs that assume hardcoded shell paths
services.envfs.enable = true;
# run unpatched binaries on nixos
programs.nix-ld.enable = true;
environment = {
# for nixlang / nixpkgs
systemPackages = with pkgs; [
nix-init
nix-update
nixfmt-rfc-style
];
};
# make a symlink of flake within the generation (e.g. /run/current-system/src)
system.extraSystemBuilderCmds = "ln -s ${self.sourceInfo.outPath} $out/src";
systemd.tmpfiles.rules = [
# cleanup nixpkgs-review cache on boot
"D! ${config.hm.xdg.cacheHome}/nixpkgs-review 1755 ${user} users 1d"
# cleanup channels so nix stops complaining
"D! /nix/var/nix/profiles/per-user/root 1755 root root 1d"
];
custom.shell.packages = {
# list all installed packages
nix-list-packages = {
text =
let
allPkgs = map (p: p.name) (
config.environment.systemPackages ++ config.users.users.${user}.packages ++ config.hm.home.packages
);
in
''sort -ui <<< "${lib.concatLines allPkgs}"'';
};
};
nix =
let
flakeInputs = lib.filterAttrs (_: lib.isType "flake") inputs;
nixPath = lib.mapAttrsToList (n: _: "${n}=flake:${n}") flakeInputs;
in
{
inherit nixPath;
channel.enable = false;
# required for nix-shell -p to work
registry = lib.mapAttrs (_: flake: {inherit flake;}) flakeInputs;
gc = {
# Automatic garbage collection
automatic = true;
dates = "daily";
options = "--delete-older-than 7d";
};
package = pkgs.nixVersions.latest;
settings = {
auto-optimise-store = true; # Optimise symlinks
# re-evaluate on every rebuild instead of "cached failure of attribute" error
# eval-cache = false;
# required to be set, for some reason nix.nixPath does not write to nix.conf
nix-path = nixPath;
warn-dirty = false;
# removes ~/.nix-profile and ~/.nix-defexpr
use-xdg-base-directories = true;
# use flakes
experimental-features = [
"nix-command"
"flakes"
];
substituters = [
"https://hyprland.cachix.org"
"https://nix-community.cachix.org"
"https://ghostty.cachix.org"
"https://rayandrew.cachix.org"
];
# allow building and pushing of laptop config from desktop
trusted-users = [ user ];
trusted-public-keys = [
"hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc="
"nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
"ghostty.cachix.org-1:QB389yTa6gTyneehvqG58y0WnHjQOqgnA+wBnpWWxns="
"rayandrew.cachix.org-1:kJnvdWgUyErPGaQWgh/yyu91szgRYD+V/WQ4Dbc4n9M="
];
};
# // lib.optionalAttrs (config.nix.package.pname == "lix") {
# repl-overlays = [ ./repl-overlays.nix ];
# };
};
# better nixos generation label
# https://reddit.com/r/NixOS/comments/16t2njf/small_trick_for_people_using_nixos_with_flakes/k2d0sxx/
system.nixos.label = lib.concatStringsSep "-" (
(lib.sort (x: y: x < y) config.system.nixos.tags)
++ [ "${config.system.nixos.version}.${self.sourceInfo.shortRev or "dirty"}" ]
);
# add nixos-option workaround for flakes
# https://github.com/NixOS/nixpkgs/issues/97855#issuecomment-1075818028
nixpkgs.overlays = [
(_: prev: {
nixos-option =
let
flake-compat = prev.fetchFromGitHub {
owner = "edolstra";
repo = "flake-compat";
rev = "12c64ca55c1014cdc1b16ed5a804aa8576601ff2";
hash = "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=";
};
prefix = ''(import ${flake-compat} { src = ${dots}; }).defaultNix.nixosConfigurations.${host}'';
in
prev.runCommandNoCC "nixos-option" { buildInputs = [ prev.makeWrapper ]; } ''
makeWrapper ${lib.getExe prev.nixos-option} $out/bin/nixos-option \
--add-flags --config_expr \
--add-flags "\"${prefix}.config\"" \
--add-flags --options_expr \
--add-flags "\"${prefix}.options\""
'';
})
];
# enable man-db cache for fish to be able to find manpages
# https://discourse.nixos.org/t/fish-shell-and-manual-page-completion-nixos-home-manager/15661
documentation.man.generateCaches = true;
}

27
overlays/default.nix Normal file
View file

@ -0,0 +1,27 @@
{
inputs,
pkgs,
...
}:
{
nixpkgs.overlays = [
(_: prev: {
# include nixpkgs stable
stable = import inputs.nixpkgs-stable {
inherit (prev.pkgs) system;
config.allowUnfree = true;
};
# include custom packages
custom =
(prev.custom or { })
// (import ../packages {
inherit (prev) pkgs;
inherit inputs;
});
# use nixfmt-rfc-style as the default
nixfmt = prev.nixfmt-rfc-style;
})
];
}

10
packages/default.nix Normal file
View file

@ -0,0 +1,10 @@
{
inputs,
pkgs,
...
}:
let
inherit (pkgs) lib callPackage;
in rec {
minimal-emacs-d = callPackage ./minimal-emacs-d { };
}

1
packages/minimal-emacs-d/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
*.elc

View file

@ -0,0 +1,13 @@
diff --git a/early-init.el b/early-init.el
index dfea2f0..d60b6ef 100644
--- a/early-init.el
+++ b/early-init.el
@@ -32,7 +32,7 @@ turned on.")
(defvar minimal-emacs-frame-title-format "%b Emacs"
"Template for displaying the title bar of visible and iconified frame.")
-(defvar minimal-emacs-debug (bound-and-true-p init-file-debug)
+(defvar minimal-emacs-debug nil
"Non-nil to enable debug.")
(defvar minimal-emacs-gc-cons-threshold (* 16 1024 1024)

View file

@ -0,0 +1,35 @@
{ lib, stdenv, pkgs }:
let
pre-early-init = ./pre-early-init.el;
in
stdenv.mkDerivation {
pname = "minimal-emacs.d";
version = "02-08-2025";
src = pkgs.fetchFromGitHub {
owner = "jamescherti";
repo = "minimal-emacs.d";
rev = "e44aa459d5eb5af2f868dc490e4d05efca308915";
# rev = "08f077545a0f45a1701333406fd1afe8be77a752";
sha256 = "sha256-ABHv+TUQpBoXkg75iL2ROJoGjT+iUZQHZD9b4Z8Q4kQ=";
};
patches = [
./030825-init-file-debug.patch
];
installPhase = ''
mkdir $out
cp -r * "$out/"
cp -r ${pre-early-init} "$out/pre-early-init.el"
'';
meta = with lib; {
description = "A Customizable Emacs init.el and early-init.el that Provides Better Defaults and Faster Startup";
homepage = "https://github.com/jamescherti/minimal-emacs.d";
platforms = platforms.all;
maintainers = [ maintainers.rayandrew ];
license = licenses.gpl3;
};
}

View file

@ -0,0 +1,13 @@
;;; pre-early-init.el --- Pre Early Initalization -*- no-byte-compile: t; lexical-binding: t; -*-
(setq minimal-emacs-user-directory (expand-file-name "~/.config/emacs"))
(minimal-emacs-load-user-init "pre-early-init.el")
(defun display-startup-time ()
"Display the startup time and number of garbage collections."
(message "Emacs loaded in %.2f seconds (Init only: %.2fs) with %d garbage collections."
(time-to-seconds (time-since before-init-time))
(float-time (time-subtract after-init-time before-init-time))
gcs-done))
(add-hook 'emacs-startup-hook #'display-startup-time 100)