;;; newcomers-presets-theme.el --- Theme of user options for newcomers -*- lexical-binding:t -*- ;; Copyright (C) 2026 Free Software Foundation, Inc. ;; Author: Philip Kaludercic ;; This file is part of GNU Emacs. ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs. If not, see . ;;; Commentary: ;; This theme configures user options that we can reasonably expect the ;; average, new user to want to enable, but would otherwise be unlikely ;; to discover on their own. This includes support for convenience ;; features, adjustment of default settings that are in place for ;; historical reasons, aiding discoverability (at the potential cost of ;; more visual noise) and trying and follow common conventions that ;; other editors have established over the past decades. ;; The goal is to help providing a better starting point for users who ;; would otherwise feel overwhelmed when first starting to use Emacs, ;; without having to burden existing users with invasive changes to ;; Emacs' default behavior. Options in the theme should NOT hinder ;; developing a better understanding of Emacs (e.g. enabling emulation ;; modes) or make opinionated cosmetic changes. ;;; Code: ;; We define a `newcomers-presets-mode' that we can use to execute custom code ;; that we cannot express by setting existing users options. ;; FIXME: Themes should be able to define these kinds of mode-specific ;; customizations. (defvar newcomers-presets-mode-enabled-local-modes `((prog-mode-hook ,#'display-line-numbers-mode ,#'flymake-mode ,#'flyspell-prog-mode) (text-mode-hook ,#'display-line-numbers-mode ,#'flyspell-mode)) "Alist mapping hooks to a list of function to add to the hook. The functions are added to the corresponding hooks when enabling `newcomers-presets-mode', and removed when disabling the mode.") (defconst newcomers-presets--dnt-prop (make-symbol "newcomers-presets-no-not-touch") "A fresh constant to use as a symbol property. The symbol property is used by `newcomers-presets-mode'") ;;;###autoload (define-minor-mode newcomers-presets-mode "A minor mode associated with the `newcomers-presets' theme. This minor mode will enable and disable the theme on startup." :global t (cl-letf (((symbol-function 'newcomers-presets-mode) ;; As the theme enables/disables this mode we have to ;; prevent in indefinite mutual recursion to allow ;; `newcomers-presets-mode' to enable the `newcomers-presets' theme and ;; vice versa. #'ignore)) (if newcomers-presets-mode (enable-theme 'newcomers-presets) (disable-theme 'newcomers-presets))) ;; TODO: extend `custom-theme-set-variables' to support function local ;; hooks. (pcase-dolist (`(,hook . ,fns) newcomers-presets-mode-enabled-local-modes) (dolist (fn fns) (cond (newcomers-presets-mode ;; We check if a function is already in the hook, to avoid ;; removing it later if the user disables the theme. (when (run-hook-wrapped hook (lambda (ent &rest _) (eq fn ent))) (push fn (get hook newcomers-presets--dnt-prop))) (add-hook hook fn)) (t (unless (memq fn (get hook newcomers-presets--dnt-prop)) (remove-hook hook fn)) (put hook newcomers-presets--dnt-prop '())))))) ;;;###theme-autoload (deftheme newcomers-presets "Theme of user options settings interesting for newcomers." :kind 'user-options) (custom-theme-set-variables 'newcomers-presets '(newcomers-presets-mode t) ;;;; Appearance-related options '(font-use-system-font t) '(frame-resize-pixelwise t) '(window-resize-pixelwise t) '(mode-line-compact 'long) ;;;; Mouse-related options '(context-menu-mode t) '(save-interprogram-paste-before-kill t) '(mouse-yank-at-point t) '(pixel-scroll-mode t) ;; '(pixel-scroll-precision-mode t) ;; see bug#69972 '(mouse-drag-and-drop-region t) '(mouse-drag-and-drop-region-cross-program t) '(mouse-drag-mode-line-buffer t) '(global-xref-mouse-mode t) ;;;; Persistence-related options '(savehist-mode t) '(save-place-mode t) '(recentf-mode t) ;;;; Editing-related options '(electric-pair-mode t) '(repeat-mode t) '(delete-selection-mode t) '(editorconfig-mode t) '(indent-tabs-mode nil) '(imenu-auto-rescan t) '(view-read-only t) '(column-number-mode t) ;;;; Directory managment-related options '(dired-auto-revert-buffer t) '(dired-mouse-drag-files t) '(shell-command-prompt-show-cwd t) ;;;; File-related options '(etags-regen-mode t) '(vc-auto-revert-mode t) '(vc-deduce-backend-nonvc-modes t) '(vc-dir-save-some-buffers-on-revert t) '(vc-find-revision-no-save t) '(vc-follow-symlinks t) '(vc-use-incoming-outgoing-prefixes t) ;;;; Completion-related options '(minibuffer-visible-completions t) '(completions-detailed t) '(completions-group t) '(completion-auto-select 'second-tab) '(completion-eager-update t) '(completion-styles '(basic emacs22 flex)) '(global-completion-preview-mode t) '(tab-always-indent 'complete) '(which-key-mode t) ;;;; Package-related options '(package-autosuggest-mode t) '(package-menu-use-current-if-no-marks nil) ;;;; Frame- and window-related options '(frame-inhibit-implied-resize t) '(tab-bar-history-mode t) ;; FIXME: If you toggle off the theme, without having run any ;; tab-related commands, the tab bar remains visible. '(tab-bar-show 0) ;;;; Programming-related options '(compilation-scroll-output 'first-error)) (provide-theme 'newcomers-presets) ;;; newcomers-presets-theme.el ends here