Break up the nix modules even further

This commit is contained in:
Sameer Rahmani 2024-04-16 22:01:42 +01:00
parent 722a020352
commit 1e62751b69
Signed by: lxsameer
GPG Key ID: 8741FACBF412FFA5
17 changed files with 391 additions and 112 deletions

View File

@ -51,6 +51,7 @@
};
fg42 = pkgs.callPackage ./nix/fg42 {
inherit nixpkgs;
extraPackages = {
noether = inputs.noether.outputs.packages.${system}.default;
};

View File

@ -65,6 +65,7 @@
;; Since it is deprecated we can easily avoide other packages to use it
(provide 'cl)
(require 'fg42/pre)
")
(defvar file-footer "
@ -77,11 +78,12 @@
;; Elisp's hashtables are not functional so I have to store the
;; state like this, Ewwwwww!
(defvar build-state '()
"A list of expressions that will dump in the output at the end.")
(defvar vars ())
(defvar requires ())
(defvar vars ()
"Storage for the vars and const forms.")
(defvar requires ()
"Storage for the require forms.")
(defvar build-output (cadr command-line-args-left))
@ -98,18 +100,25 @@
,@body))))
(defun replace-in-string (what with s)
"Replace WHAT in string S with WITH."
(replace-regexp-in-string (regexp-quote what) with s nil 'literal))
(defun generate-compile-time-requires (elisp-pkgs)
"Generate a list of `require' forms of ELISP-PKGS for compile time."
(when (> (length elisp-pkgs) 0)
(add-to-list
'requires
`(eval-when-compile
,@(mapcar (lambda (pkg) `(require ',(intern pkg))) elisp-pkgs)))))
,@(mapcar (lambda (pkg) `(require ',(intern (replace-in-string "fg42-" "fg42/" pkg)))) elisp-pkgs)))))
(defun generate-generic-vars (k v doc)
"Generate a list of vars for K and value V with docstring DOC."
(add-to-list 'vars `(defvar ,(intern (format "fg42/config/%s" k)) ,v ,doc)))
(defun generate-generic-vars (k v doc &optional const)
"Generate a list of vars for K and value V with docstring DOC.
Generate a constant if CONST is non-nil."
(add-to-list 'vars `(,(if const 'defconst 'defvar)
,(intern (format "fg42/config/%s" k)) ,v ,doc)))
(defun fg42-config-key-handler (config)
@ -123,7 +132,20 @@
((member k keys-to-skip)
(message "[build.el]: Skipping %s..." k))
(t (generate-generic-vars k v (gethash k (gethash "docstrings" config)))))))
((and (string= k "vars") (> (length v) 0))
(mapc (lambda (x)
(generate-generic-vars (gethash "name" x)
(gethash "defaultValue" x)
(gethash "docstring" x)))
v))
((and (string= k "consts") (> (length v) 0))
(mapc (lambda (x)
(generate-generic-vars (gethash "name" x)
(gethash "defaultValue" x)
(gethash "docstring" x)
t))
v)))))
(defun fg42-handler (config)
"Handle the CONFIG for FG42.

View File

@ -18,6 +18,7 @@
# from FG42 modules that are structurally the same but used in
# different context
{ pkgs
, nixpkgs
, lib ? pkgs.lib
, modules ? null
, extraModules ? [ ]
@ -37,11 +38,14 @@ let
utils = pkgs.callPackage ./utils.nix { };
final = lib.evalModules {
modules = [ ./unit.nix ] ++ fg42Modules ++ extraModules;
# The unit module is mandatory and the bare min
# config that is necessary
modules = [ ../modules/unit ] ++ fg42Modules ++ extraModules;
specialArgs = {
inherit utils;
inherit (utils) makeFG42Drv;
inherit extraPackages;
lib = nixpkgs.lib.extend (import ./lib.nix { inherit pkgs; });
};
};
in

View File

@ -52,14 +52,18 @@ let
configFile = writeTextFile {
name = "config.json";
text = (toJSON config);
text = (toJSON {
fg42 = {
inherit (cfg) vars consts requires;
};
});
executable = false;
};
in
stdenv.mkDerivation rec {
inherit version;
pname = "FG42";
pname = builtins.trace ">>> ${configFile}" "FG42";
src = ../../.;

44
nix/fg42/lib.nix Normal file
View File

@ -0,0 +1,44 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program 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, version 2.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
{ pkgs, ... }:
final: prev:
rec {
defVar = name: defaultValue: docstring: {
inherit name defaultValue docstring;
};
defConst = defVar;
makeFG42Drv = { pname, version, ... }@args:
(pkgs.emacsPackages.trivialBuild args).overrideAttrs (old: {
pname = "fg42-${pname}";
installPhase = ''
runHook preInstall
LISPDIR=$out/share/emacs/
install -d $LISPDIR
cp -rv lisp/ $LISPDIR/site-lisp
emacs --batch -l package --eval "(package-generate-autoloads \"${args.pname}\" \"$LISPDIR/site-lisp\")"
runHook postInstall
'';
});
}

View File

@ -31,7 +31,6 @@ let
_module.args.baseModules = modules;
_module.args.pkgs = lib.mkDefault pkgs;
_module.check = true;
#inherit lib;
};
};
in

View File

@ -21,6 +21,8 @@
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, extraPackages, ... }:
let
cfg = config.fg42;
deps =
(with pkgs.emacsPackages; [
origami
@ -44,9 +46,6 @@ let
ctrlf
consult
marginalia
magit
forge
diff-hl
svg-tag-mode
all-the-icons
org
@ -69,15 +68,17 @@ let
};
dicts = pkgs.aspellWithDicts (dicts: with dicts; [ en en-computers en-science ]);
emojifyDocString = "Whether or not to use the `emojify' package.";
in
{
options = (with lib; {
fg42.emojify = mkOption {
type = types.bool;
default = false;
description = "Whether or not to use the `emojify' package.";
};
fg42.emojify = mkOption
{
type = types.bool;
default = false;
description = emojifyDocString;
};
});
config = {
@ -96,7 +97,9 @@ in
]);
fg42.font = lib.mkDefault '''("Fira Mono" 11)'';
fg42.theme = lib.mkDefault "base16-eighties";
fg42.theme-package-name = lib.mkDefault "base16-theme";
fg42.requires = [ drv.pname ];
fg42.vars = [
(lib.defVar "emojify" cfg.emojify emojifyDocString)
];
};
}

View File

@ -26,7 +26,6 @@
;; We build this file via the main FG42's Nix derivation. It
;; contains the final Nix configuration of FG42.
(require 'fg42/config)
(require 'fg42/themes)
;; ;; Language support
;; (require 'fg42/autocomplete)
;; (require 'fg42/langs/langs)
@ -37,12 +36,13 @@
;; (require 'fg42/langs/elisp)
;; (require 'fg42/langs/nix)
(require 'fg42/git)
;;(require 'fg42/git)
;; (require 'fg42/wm)
(require 'fg42/organize)
(require 'fg42/minibuffer)
(require 'fg42/graphics)
(require 'fg42/modeline))
;;(require 'fg42/minibuffer)
;;(require 'fg42/graphics)
;;(require 'fg42/modeline)
)
(require 'server)
(require 'fg42/utils)
@ -58,9 +58,6 @@
(defun fg42/setup-editor ()
"Setup the overall functionality of FG42."
(use! origami
"A text folding minor mode for Emacs."
:bind
@ -202,6 +199,10 @@ contextual information."
"Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs."
:config (global-flycheck-mode))
(defun fg42/setup-editor ()
"Setup the overall functionality of FG42."
;; In the following section we're setting some default behavior of FG42.
;; Most of these configuration are opiniated and I think most of people
;; shared the same opinion or don't care at all.
@ -246,25 +247,26 @@ contextual information."
(defalias 'yes-or-no-p 'y-or-n-p)
;; Hooks ---
(add-hook
'emacs-startup-hook
(lambda ()
;; It only applies to toolkit=no
(set-mouse-color (get-base16-color-or :base07 "#eeeeec"))
;; Switch from `dabbrev-expand' to `hippie-expand'
(global-set-key [remap dabbrev-expand] 'hippie-expand)
;; It only applies to toolkit=no
(column-number-mode t)
(show-paren-mode t)
(electric-pair-mode 1)
(set-mouse-color (get-base16-color-or :base07 "#eeeeec"))
;; Rectangular select
(cua-selection-mode t)
;; Switch from `dabbrev-expand' to `hippie-expand'
;; Yank the region on type
(delete-selection-mode 1)))
(global-set-key [remap dabbrev-expand] 'hippie-expand)
(column-number-mode t)
(show-paren-mode t)
(electric-pair-mode 1)
;; Rectangular select
(cua-selection-mode t)
;; Yank the region on type
(delete-selection-mode 1)
;; Deletel extra trailing white spaces on save
(add-hook 'before-save-hook 'delete-trailing-whitespace)
@ -288,5 +290,7 @@ contextual information."
(message "[FG42]: Use `fg42-help' to get help."))
(add-hook 'fg42/after-user-config-init-hook #'fg42/setup-editor)
(provide 'fg42/editor)
;;; editor.el ends here

View File

@ -0,0 +1,50 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program 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, version 2.
#
# This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.features;
deps =
(with pkgs.emacsPackages; [
magit
forge
diff-hl
]);
drv = makeFG42Drv {
pname = "git";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.features.git = mkEnableOption "git";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.paths = (with pkgs;[
git
]);
};
}

View File

@ -0,0 +1,61 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program 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.
;;
;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
(use! diff-hl
"This package highlights changes to the current buffer in respect to the
VC status of the file. For example if you're using `git' in your project
and you've made some changes to the current buffer that are not commited
yet it will highlihgt them for you.
For more info check out `https://github.com/dgutov/diff-hl'."
:commands global-diff-hl-mode
:config
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
(use! magit
"Git magic in FG42. For more info checkout `magit's documentation."
:bind (("C-x g" . magit-status)
("C-c b" . magit-blame)
("C-c l" . magit-log))
:config
(when (featurep 'diff-hl)
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh)))
(use! forge
"Forge allows you to work with Git forges, such as Github and Gitlab,
from the comfort of Magit and the rest of Emacs.
For more info: `https://magit.vc/manual/forge/'"
:after magit)
(provide 'fg42/git)
;;; git.el ends here

View File

@ -17,10 +17,19 @@
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
{ lib, pkgs, config, options, ... }:
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
nix2elispName = pkg: (builtins.replaceStrings [ "fg42-" ] [ "fg42/" ] pkg.pname);
cfg = config.fg42;
drv = makeFG42Drv {
pname = "unit";
version = config.fg42.version;
src = ./.;
};
in
{
options = {
@ -89,7 +98,7 @@ in
type = types.str;
description = ''
The theme package name to use with FG42. The package should be added
to `elispPackages` already;
to `elispPackages` already
'';
};
@ -104,6 +113,49 @@ in
'';
};
fg42.vars = mkOption {
type = types.listOf
(types.submodule {
options = {
name = mkOption {
type = types.str;
};
defaultValue = mkOption {
type = types.anything;
};
docstring = mkOption {
type = types.str;
};
};
});
default = [ ];
description = ''
Any element in this list will translate to an Elisp variable and will
be available to the Elisp code via the `fg42/config` interface.
'';
};
fg42.consts = mkOption {
type = types.listOf
(types.submodule {
options = {
name = mkOption {
type = types.str;
};
defaultValue = mkOption {
type = types.anything;
};
docstring = mkOption {
type = types.str;
};
};
});
default = [ ];
description = ''
Any element in this list will translate to an Elisp const and will
be available to the Elisp code via the `fg42/config` interface.
'';
};
fg42.modeline = mkOption {
type = types.enum [ "emacs" "noether" ];
default = "emacs";
@ -112,36 +164,35 @@ in
"noether" to disable Emacs's modeline and replace it by the noether mode.
'';
};
fg42.docstrings = mkOption {
type = types.attrsOf types.str;
readOnly = true;
description = ''
A list of Emacs packages to preload in compile time.
In general you want your entry point module in this list
to setup your autoloads, hooks, and everything.
'';
};
};
config = {
fg42.version = import ../version.nix { };
fg42.version = import ../../version.nix { };
fg42.elispPackages = [ drv ];
fg42.theme = lib.mkDefault "base16-eighties";
fg42.theme-package-name = lib.mkDefault "base16-theme";
fg42.vars = [
(lib.defVar "theme" cfg.theme "The default font for FG42")
(lib.defVar "theme-package-name" cfg.theme-package-name ''
The theme package name to use with FG42. The package should be added to `elispPackages` already.
'')
];
# Extract the package pname's to pass to elisp to `require` them in the init
# file, while compiling.
fg42.requires = map nix2elispName config.fg42.elispPackages;
fg42.docstrings = (with builtins;
let
desc = opt:
if hasAttr "description" opt
then opt.description
else "";
# fg42.requires = map nix2elispName config.fg42.elispPackages;
# fg42.docstrings = (with builtins;
# let
# desc = opt:
# if hasAttr "description" opt
# then opt.description
# else "";
in
lib.concatMapAttrs
(k: v: { ${k} = desc v; })
options.fg42);
# in
# lib.concatMapAttrs
# (k: v: { ${k} = desc v; })
# options.fg42);
};
}

View File

@ -21,43 +21,13 @@
;;
;;; Commentary:
;;; Code:
(require 'fg42/utils)
(eval-when-compile
(require 'fg42/utils)
(require 'fg42/pre)
(defvar package-archives)
(defvar use-package-ensure-function))
;; ============================================================================
;; Basic inital configuration for FG42's operations
;; ============================================================================
(defgroup fg42 nil
"Customize your FG42 instance via this group of configurations."
:group :editor)
(defvar fg42/disabled-features nil
"List of features to disable.")
(defvar fg42/after-init-hook nil
"The hook tha runs when FG42 finished running the user configuration.")
(defvar fg42/debug? nil
"It is t If FG42 is running in debug mode and nil otherwise.")
(defvar fg42/-gc-cons-threshold 16777216
"Value of GC threshold of FG42.")
(defvar fg42/initialized nil
"A variable that indicates whether FG42 is passed initialization.")
(defconst fg42/cache-dir (or (getenv "FG42_CACHE_DIR")
(path-join (or (getenv "XDG_CACHE_HOME") "~/.cache")
"fg42")))
(defconst fg42/config-dir (or (getenv "FG42_CONFIG_DIR")
(path-join (or (getenv "XDG_CONFIG_HOME") "~/.config")
"fg42")))
(defun defer-garbage-collection ()
"Disable garbage collection."
@ -106,17 +76,17 @@
(defun fg42/initialize ()
"Initialize FG42 after the Emacs window is rendered by loading the user init file."
;; (fg42/-startup-optimization)
(run-hooks 'fg42/before-user-config-init-hook)
(require 'fg42/editor)
;; Since the editor module imports all the submodules
;; on compile time we should be good to assume
;; everything that needed to be loaded or autoloaded
;; are there already.
(require 'fg42/themes)
(when (file-exists-p user-init-file)
(load user-init-file))
(run-hooks 'fg42/after-user-config-init-hook)
(fg42/setup-theme!)
(fg42/setup-editor)
;; (fg42/setup-editor)
(add-hook 'emacs-startup-hook
(lambda ()

View File

@ -0,0 +1,66 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program 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.
;;
;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
;; ============================================================================
;; Basic inital configuration for FG42's operations
;; ============================================================================
(require 'fg42/utils)
(defgroup fg42 nil
"Customize your FG42 instance via this group of configurations."
:group :editor)
(defvar fg42/disabled-features nil
"List of features to disable.")
(defvar fg42/after-init-hook nil
"The hook tha runs when FG42 finished running the user configuration.")
(defvar fg42/debug? nil
"It is t If FG42 is running in debug mode and nil otherwise.")
(defvar fg42/-gc-cons-threshold 16777216
"Value of GC threshold of FG42.")
(defvar fg42/initialized nil
"A variable that indicates whether FG42 is passed initialization.")
(defconst fg42/cache-dir (or (getenv "FG42_CACHE_DIR")
(path-join (or (getenv "XDG_CACHE_HOME") "~/.cache")
"fg42")))
(defconst fg42/config-dir (or (getenv "FG42_CONFIG_DIR")
(path-join (or (getenv "XDG_CONFIG_HOME") "~/.config")
"fg42")))
(defvar fg42/before-user-config-init-hook nil
"A hook that runs before loading user's configuration.")
(defvar fg42/after-user-config-init-hook nil
"A hook that runs after loading user's configuration.")
(provide 'fg42/pre)
;;; pre.el ends here