Add an Elisp script to convert Nix config to Elisp code
This commit is contained in:
parent
426c1d2dd1
commit
c9cdb0a83e
|
@ -0,0 +1,98 @@
|
||||||
|
;;; 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:
|
||||||
|
;; This is the builder script that takes the config.json from the input
|
||||||
|
;; (typically provided by Nix). And generates appropriate Elisp file
|
||||||
|
;; for the main FG42 Elsip code to load and use.
|
||||||
|
;;
|
||||||
|
;; Please note that this file runs with Emacs and not FG42.
|
||||||
|
;;; Code:
|
||||||
|
(when (not (json-available-p))
|
||||||
|
(error "Error: libjasson support is missing"))
|
||||||
|
|
||||||
|
|
||||||
|
;; 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.")
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro with-json (var &rest body)
|
||||||
|
"Read the json file from cli arguments, user VAR run the BODY on it."
|
||||||
|
(declare (indent defun))
|
||||||
|
`(let ((input-file (car command-line-args-left)))
|
||||||
|
(message "Reading the input file: %s" input-file)
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents input-file)
|
||||||
|
(let ((,var (json-parse-buffer)))
|
||||||
|
,@body))))
|
||||||
|
|
||||||
|
|
||||||
|
(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
|
||||||
|
'build-state
|
||||||
|
`(eval-when-compile
|
||||||
|
,@(mapcar (lambda (pkg) `(require ',(intern pkg))) elisp-pkgs)))))
|
||||||
|
|
||||||
|
(defun generate-generic-vars (k v)
|
||||||
|
"Generate a list of vars for K and value V."
|
||||||
|
(add-to-list 'build-state `(defvar ,(intern (format "fg42/%s" k)) ,v)))
|
||||||
|
|
||||||
|
|
||||||
|
(defun fg42-config-key-handler (k v)
|
||||||
|
"Handle the FG42 config K and its value V."
|
||||||
|
(cond
|
||||||
|
((string= k "requires")
|
||||||
|
(generate-compile-time-requires v))
|
||||||
|
|
||||||
|
(t (generate-generic-vars k v))))
|
||||||
|
|
||||||
|
(defun fg42-handler (config)
|
||||||
|
"Handle the CONFIG for FG42.
|
||||||
|
|
||||||
|
CONFIG maps to the collective `config' value of Nix modules."
|
||||||
|
(maphash #'fg42-config-key-handler config))
|
||||||
|
|
||||||
|
(defun handle-conifg-for (k v)
|
||||||
|
"Find the handler of K and its value V to it."
|
||||||
|
(funcall (intern (format "%s-handler" k)) v))
|
||||||
|
|
||||||
|
|
||||||
|
(defun handle-top-level (k v)
|
||||||
|
"Handle the key K and value V form the top level of the JSON data."
|
||||||
|
(when (not (string= k "fg42"))
|
||||||
|
(error "Don't know how to handle '%s'" k))
|
||||||
|
(handle-conifg-for k v))
|
||||||
|
|
||||||
|
(with-json j
|
||||||
|
;; TODO: To make it scale, may be let Nix modules
|
||||||
|
;; plug into this script. There is a security
|
||||||
|
;; rist though
|
||||||
|
(maphash #'handle-top-level j)
|
||||||
|
(with-temp-file (cadr command-line-args-left)
|
||||||
|
(mapc (lambda (x) (print x (current-buffer))) build-state)))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'build)
|
||||||
|
;;; build.el ends here
|
|
@ -1,219 +0,0 @@
|
||||||
# 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/>.
|
|
||||||
{ lib
|
|
||||||
, config
|
|
||||||
, stdenv
|
|
||||||
, git
|
|
||||||
, texinfo
|
|
||||||
, gcc
|
|
||||||
, bash
|
|
||||||
, utils
|
|
||||||
, emacsPackagesFor
|
|
||||||
, makeFontsConf
|
|
||||||
, xorg
|
|
||||||
, maintainers
|
|
||||||
, writeText
|
|
||||||
, writeShellApplication
|
|
||||||
, ...
|
|
||||||
}:
|
|
||||||
|
|
||||||
with builtins;
|
|
||||||
let
|
|
||||||
cfg = config.fg42;
|
|
||||||
emacs = cfg.emacs;
|
|
||||||
version = cfg.version;
|
|
||||||
|
|
||||||
emacsBundle = (emacsPackagesFor emacs).withPackages (_: cfg.elispPackages);
|
|
||||||
|
|
||||||
paths = map (x: "${x}/bin/") cfg.paths;
|
|
||||||
pathsStr = lib.strings.concatStrings (lib.strings.intersperse ":" paths);
|
|
||||||
|
|
||||||
mimeTypes = builtins.concatStringsSep ";" cfg.mimeTypes;
|
|
||||||
|
|
||||||
fontsConf = makeFontsConf { fontDirectories = cfg.fonts; };
|
|
||||||
|
|
||||||
# Whatever that needs to be in the PATH is considered a runtime
|
|
||||||
# dependency.
|
|
||||||
# Fonts are obviously runtime dependency as well
|
|
||||||
runtimeDependencies = cfg.paths ++ cfg.fonts ++ cfg.elispPackages;
|
|
||||||
|
|
||||||
buildConfig = generateBuildConfig cfg.buildConfig;
|
|
||||||
|
|
||||||
addToList = epkg: ''(add-to-list 'directories-to-autogen "${epkg}")'';
|
|
||||||
|
|
||||||
sexprs = [
|
|
||||||
''
|
|
||||||
(require 'loaddefs-gen)
|
|
||||||
(defvar directories-to-autogen '())
|
|
||||||
(defvar output-file (getenv "LOADEF_OUTPUT"))
|
|
||||||
''
|
|
||||||
] ++ (map addToList cfg.elispPackages) ++ [
|
|
||||||
''
|
|
||||||
(message ">> %s ----- %s" directories-to-autogen output-file)
|
|
||||||
(loaddefs-generate directories-to-autogen
|
|
||||||
output-file)
|
|
||||||
(provide 'loaddef-generator)
|
|
||||||
''
|
|
||||||
];
|
|
||||||
loaddefGenerator = writeText "loaddef-generator.el" (concatStringsSep "\n" sexprs);
|
|
||||||
loaddefScript = writeShellApplication {
|
|
||||||
name = "loaddef";
|
|
||||||
|
|
||||||
text = ''
|
|
||||||
#!${stdenv.shell}
|
|
||||||
set +x
|
|
||||||
LOADEF_OUTPUT="$1" ${emacsBundle}/bin/emacs -Q -q --batch -l ${loaddefGenerator}
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
startupPackage = cfg.startUp;
|
|
||||||
|
|
||||||
|
|
||||||
# elsipFiles = map (file: ) cfg.elispPackages;
|
|
||||||
# nativeCompiler = epkgs: ''
|
|
||||||
# emacs -L . --batch -f batch-native-compile ${elispFiles}
|
|
||||||
# '';
|
|
||||||
in
|
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
|
||||||
inherit version;
|
|
||||||
pname = "FG42";
|
|
||||||
|
|
||||||
src = ../../.;
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
LISPDIR=$out/share/fg42/
|
|
||||||
mkdir -p $out/bin
|
|
||||||
mkdir -p $out/share/applications/
|
|
||||||
|
|
||||||
install -d $LISPDIR
|
|
||||||
|
|
||||||
cp -rv ${src}/share $out/
|
|
||||||
cp -rv ${src}/snippets $LISPDIR/snippets
|
|
||||||
cp "${fontsConf}" $LISPDIR/fonts.conf
|
|
||||||
|
|
||||||
chmod 755 $LISPDIR -R
|
|
||||||
|
|
||||||
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
|
|
||||||
|
|
||||||
cat >> $out/share/applications/FG42.desktop << EOF
|
|
||||||
[Desktop Entry]
|
|
||||||
Encoding=UTF-8
|
|
||||||
Name=FG42
|
|
||||||
GenericName=FG42
|
|
||||||
Comment=The nix base Emacs bundle for advance users
|
|
||||||
MimeType=${mimeTypes}
|
|
||||||
Type=Application
|
|
||||||
Terminal=false
|
|
||||||
Categories=Development;TextEditor;
|
|
||||||
StartupWMClass=FG42
|
|
||||||
Exec=${placeholder "out"}/bin/fg42
|
|
||||||
Icon=fg42
|
|
||||||
Version=${version}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cat >> $out/share/runtime_deps << EOF
|
|
||||||
${lib.strings.concatLines runtimeDependencies}
|
|
||||||
${emacsBundle}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
cd $LISPDIR
|
|
||||||
#compile stuff
|
|
||||||
cd -
|
|
||||||
|
|
||||||
cat >> $out/bin/fg42 << EOF
|
|
||||||
#!${stdenv.shell}
|
|
||||||
|
|
||||||
export PATH=${pathsStr}:$PATH
|
|
||||||
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
|
|
||||||
|
|
||||||
LIBRARY_PATH="\$(${stdenv.cc}/bin/cc -print-file-name=libgccjit.so):\$LIBRARY_PATH" \
|
|
||||||
FG42_WM=fales ${emacsBundle}/bin/emacs \
|
|
||||||
--name FG42 \
|
|
||||||
-q --no-splash --title FG42 \
|
|
||||||
-l ${cfg.startUp} "\$@"
|
|
||||||
EOF
|
|
||||||
chmod +x $out/bin/fg42
|
|
||||||
|
|
||||||
|
|
||||||
LISPDIR=$out/share/fg42/lisp/
|
|
||||||
mkdir -p $LISPDIR
|
|
||||||
#emacs --batch -l package --eval "(package-generate-autoloads \"${pname}\" \"$LISPDIR\")"
|
|
||||||
# ${loaddefScript}/bin/loaddef ${placeholder "out"}/share/fg42/lisp/loaddefs.el
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
|
|
||||||
cat >> $out/bin/fg42-wm << EOF
|
|
||||||
#!${stdenv.shell}
|
|
||||||
|
|
||||||
export FG42_HOME=${placeholder "out"}/share/fg42/
|
|
||||||
export FG42_EMACSD=~/.fg42/v4/emacs.d
|
|
||||||
export FG42_USE_NIX=true;
|
|
||||||
export PATH=${pathsStr}:\$PATH
|
|
||||||
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
|
|
||||||
|
|
||||||
# Disable access control for the current user.
|
|
||||||
${xorg.xhost}/bin/xhost +SI:localuser:\$USER
|
|
||||||
|
|
||||||
# Make Java applications aware this is a non-reparenting window manager.
|
|
||||||
export _JAVA_AWT_WM_NONREPARENTING=1
|
|
||||||
|
|
||||||
# Set default cursor.
|
|
||||||
xsetroot -cursor_name left_ptr
|
|
||||||
|
|
||||||
# Set keyboard repeat rate.
|
|
||||||
xset r rate 400 30
|
|
||||||
|
|
||||||
# Uncomment the following block to use the exwm-xim module.
|
|
||||||
# export XMODIFIERS=@im=exwm-xim
|
|
||||||
# export GTK_IM_MODULE=xim
|
|
||||||
# export QT_IM_MODULE=xim
|
|
||||||
# export CLUTTER_IM_MODULE=xim
|
|
||||||
|
|
||||||
LIBRARY_PATH="\$(${stdenv.cc}/bin/cc -print-file-name=libgccjit.so):\$LIBRARY_PATH" \
|
|
||||||
FG42_WM=true ${emacsBundle}/bin/emacs \
|
|
||||||
--name FG42 \
|
|
||||||
-q --no-splash --title FG42 \
|
|
||||||
-l \$FG42_HOME/lisp/fg42/fg42.el "\$@"
|
|
||||||
EOF
|
|
||||||
chmod +x $out/bin/fg42-wm
|
|
||||||
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
|
|
||||||
buildInputs = [ emacs emacsBundle git texinfo gcc bash ];
|
|
||||||
|
|
||||||
addEmacsNativeLoadPath = true;
|
|
||||||
|
|
||||||
meta = {
|
|
||||||
broken = false;
|
|
||||||
platforms = emacs.meta.platforms;
|
|
||||||
homepage = "https://fg42.org/";
|
|
||||||
maintainers = [ maintainers.lxsameer ];
|
|
||||||
description = "The mighty editor for the Emacsians";
|
|
||||||
longDescription = ''
|
|
||||||
FG42 is a framework to create and editor and window manager based on GNU/Emacs.
|
|
||||||
It has a pre-defined setup as well which can be installed out of the box. But the
|
|
||||||
goal of this project is to provide the API necessary to create an integrated editor.
|
|
||||||
|
|
||||||
So you need to know about Emacs in advance.
|
|
||||||
'';
|
|
||||||
license = lib.licenses.gpl3Plus;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
lxsameer@majin.69922:1712871165
|
|
|
@ -25,7 +25,7 @@
|
||||||
, makeFontsConf
|
, makeFontsConf
|
||||||
, xorg
|
, xorg
|
||||||
, maintainers
|
, maintainers
|
||||||
, writeText
|
, writeTextFile
|
||||||
, writeShellApplication
|
, writeShellApplication
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
|
@ -50,35 +50,41 @@ let
|
||||||
# Fonts are obviously runtime dependency as well
|
# Fonts are obviously runtime dependency as well
|
||||||
runtimeDependencies = cfg.paths ++ cfg.fonts ++ cfg.elispPackages;
|
runtimeDependencies = cfg.paths ++ cfg.fonts ++ cfg.elispPackages;
|
||||||
|
|
||||||
buildConfig = generateBuildConfig cfg.buildConfig;
|
# addToList = epkg: ''(add-to-list 'directories-to-autogen "${epkg}")'';
|
||||||
|
|
||||||
addToList = epkg: ''(add-to-list 'directories-to-autogen "${epkg}")'';
|
# sexprs = [
|
||||||
|
# ''
|
||||||
|
# (require 'loaddefs-gen)
|
||||||
|
# (defvar directories-to-autogen '())
|
||||||
|
# (defvar output-file (getenv "LOADEF_OUTPUT"))
|
||||||
|
# ''
|
||||||
|
# ] ++ (map addToList cfg.elispPackages) ++ [
|
||||||
|
# ''
|
||||||
|
# (message ">> %s ----- %s" directories-to-autogen output-file)
|
||||||
|
# (loaddefs-generate directories-to-autogen
|
||||||
|
# output-file)
|
||||||
|
# (provide 'loaddef-generator)
|
||||||
|
# ''
|
||||||
|
# ];
|
||||||
|
# loaddefGenerator = writeText "loaddef-generator.el" (concatStringsSep "\n" sexprs);
|
||||||
|
# loaddefScript = writeShellApplication {
|
||||||
|
# name = "loaddef";
|
||||||
|
|
||||||
sexprs = [
|
# text = ''
|
||||||
''
|
# #!${stdenv.shell}
|
||||||
(require 'loaddefs-gen)
|
# set +x
|
||||||
(defvar directories-to-autogen '())
|
# LOADEF_OUTPUT="$1" ${emacsBundle}/bin/emacs -Q -q --batch -l ${loaddefGenerator}
|
||||||
(defvar output-file (getenv "LOADEF_OUTPUT"))
|
# '';
|
||||||
''
|
# };
|
||||||
] ++ (map addToList cfg.elispPackages) ++ [
|
|
||||||
''
|
|
||||||
(message ">> %s ----- %s" directories-to-autogen output-file)
|
|
||||||
(loaddefs-generate directories-to-autogen
|
|
||||||
output-file)
|
|
||||||
(provide 'loaddef-generator)
|
|
||||||
''
|
|
||||||
];
|
|
||||||
loaddefGenerator = writeText "loaddef-generator.el" (concatStringsSep "\n" sexprs);
|
|
||||||
loaddefScript = writeShellApplication {
|
|
||||||
name = "loaddef";
|
|
||||||
|
|
||||||
text = ''
|
|
||||||
#!${stdenv.shell}
|
configFile = writeTextFile {
|
||||||
set +x
|
name = "config.json";
|
||||||
LOADEF_OUTPUT="$1" ${emacsBundle}/bin/emacs -Q -q --batch -l ${loaddefGenerator}
|
text = (toJSON config);
|
||||||
'';
|
executable = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
startupPackage = cfg.startUp;
|
startupPackage = cfg.startUp;
|
||||||
|
|
||||||
|
|
||||||
|
@ -87,7 +93,6 @@ let
|
||||||
# emacs -L . --batch -f batch-native-compile ${elispFiles}
|
# emacs -L . --batch -f batch-native-compile ${elispFiles}
|
||||||
# '';
|
# '';
|
||||||
in
|
in
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
inherit version;
|
inherit version;
|
||||||
pname = "FG42";
|
pname = "FG42";
|
||||||
|
@ -103,15 +108,20 @@ stdenv.mkDerivation rec {
|
||||||
|
|
||||||
install -d $LISPDIR
|
install -d $LISPDIR
|
||||||
|
|
||||||
# cp -rv ${src}/lisp/ $LISPDIR
|
mkdir -p $LISPDIR/lisp
|
||||||
|
cp -rv ${src}/lisp/build.el $LISPDIR/lisp
|
||||||
|
|
||||||
cp -rv ${src}/share $out/
|
cp -rv ${src}/share $out/
|
||||||
cp -rv ${src}/snippets $LISPDIR/snippets
|
cp -rv ${src}/snippets $LISPDIR/snippets
|
||||||
cp "${fontsConf}" $LISPDIR/fonts.conf
|
cp "${fontsConf}" $LISPDIR/fonts.conf
|
||||||
|
cp "${configFile}" $LISPDIR/config.json
|
||||||
chmod 755 $LISPDIR -R
|
|
||||||
|
|
||||||
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
|
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
|
||||||
|
chmod 755 $LISPDIR -R
|
||||||
|
|
||||||
|
emacs --batch -l $LISPDIR/lisp/build.el $LISPDIR/config.json $LISPDIR/lisp/fg42_init.el
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cat >> $out/share/applications/FG42.desktop << EOF
|
cat >> $out/share/applications/FG42.desktop << EOF
|
||||||
[Desktop Entry]
|
[Desktop Entry]
|
||||||
|
@ -156,7 +166,6 @@ stdenv.mkDerivation rec {
|
||||||
LISPDIR=$out/share/fg42/lisp/
|
LISPDIR=$out/share/fg42/lisp/
|
||||||
mkdir -p $LISPDIR
|
mkdir -p $LISPDIR
|
||||||
#emacs --batch -l package --eval "(package-generate-autoloads \"${pname}\" \"$LISPDIR\")"
|
#emacs --batch -l package --eval "(package-generate-autoloads \"${pname}\" \"$LISPDIR\")"
|
||||||
# ${loaddefScript}/bin/loaddef ${placeholder "out"}/share/fg42/lisp/loaddefs.el
|
|
||||||
|
|
||||||
runHook postBuild
|
runHook postBuild
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,17 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fg42.requires = mkOption {
|
||||||
|
type = types.listOf types.str;
|
||||||
|
default = [ ];
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
fg42.paths = mkOption {
|
fg42.paths = mkOption {
|
||||||
type = types.listOf types.package;
|
type = types.listOf types.package;
|
||||||
default = [ ];
|
default = [ ];
|
||||||
|
@ -69,6 +80,12 @@ with lib;
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fg42.font = mkOption {
|
||||||
|
type = types.uniq types.str;
|
||||||
|
example = "fg42.font = ''(cons \"Fira Code\" 10) '';";
|
||||||
|
description = "The default font for FG42";
|
||||||
|
};
|
||||||
|
|
||||||
fg42.startUp = mkOption {
|
fg42.startUp = mkOption {
|
||||||
type = types.uniq types.path;
|
type = types.uniq types.path;
|
||||||
description = "The main startup file to load first. This is usually fg42.el";
|
description = "The main startup file to load first. This is usually fg42.el";
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
# 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, ... }:
|
|
||||||
with lib;
|
|
||||||
let
|
|
||||||
generateBuildConfig = configs:
|
|
||||||
let
|
|
||||||
defineConfig = cs: name:
|
|
||||||
let
|
|
||||||
config = builtins.getAttr name cs;
|
|
||||||
form = if config.const then "defconst" else "defvar";
|
|
||||||
in
|
|
||||||
''(${form} ${name} ${config.value} "${config.docs}")'';
|
|
||||||
|
|
||||||
configsList = builtins.map (defineConfig configs) (builtins.attrNames configs);
|
|
||||||
|
|
||||||
in
|
|
||||||
pkgs.writeTextFile {
|
|
||||||
name = "build-config";
|
|
||||||
text = ''
|
|
||||||
${builtins.concatStringsSep "\n" configsList}
|
|
||||||
(provide 'fg42/build-config)
|
|
||||||
'';
|
|
||||||
executable = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
buildConfig = generateBuildConfig (config.fg42.buildConfig);
|
|
||||||
drv = pkgs.emacsPackages.trivialBuild rec {
|
|
||||||
pname = "fg42-build-config";
|
|
||||||
version = config.fg42.version;
|
|
||||||
src = ./.;
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
runHook preBuild
|
|
||||||
|
|
||||||
LISPDIR=$out/share/emacs/site-lisp/fg42
|
|
||||||
install -d $LISPDIR
|
|
||||||
|
|
||||||
cp -v ${buildConfig} $LISPDIR/build-config.el
|
|
||||||
|
|
||||||
emacs -L . --batch -f batch-byte-compile *.el
|
|
||||||
|
|
||||||
runHook postBuild
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
runHook preInstall
|
|
||||||
|
|
||||||
LISPDIR=$out/share/emacs/site-lisp/fg42/
|
|
||||||
emacs --batch -l package --eval "(package-generate-autoloads \"${pname}\" \"$LISPDIR\")"
|
|
||||||
|
|
||||||
runHook postInstall
|
|
||||||
'';
|
|
||||||
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
fg42.buildConfig = mkOption {
|
|
||||||
type = types.attrsOf
|
|
||||||
(types.submodule {
|
|
||||||
options = {
|
|
||||||
value = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
default = "nil";
|
|
||||||
description = ''
|
|
||||||
The value should be quoted. For example the string "nil"
|
|
||||||
means the actual nil in elisp and the string "\"foo\""
|
|
||||||
means elisp string "foo".
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
docs = mkOption {
|
|
||||||
type = types.str;
|
|
||||||
description = "The docstring for the variable or constant (mandatory)";
|
|
||||||
};
|
|
||||||
const = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = false;
|
|
||||||
description = "defvar vs defconst";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
default = { };
|
|
||||||
example = ''
|
|
||||||
fg42.config = {
|
|
||||||
"fg42/some-var" = {
|
|
||||||
value = "foo";
|
|
||||||
docs = "The docstring";
|
|
||||||
const = false;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
description = ''
|
|
||||||
An attrset of configuration variables and their values
|
|
||||||
that should end up in `fg42/config` elisp module.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
config = {
|
|
||||||
fg42.elispPackages = [ drv ];
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -22,7 +22,6 @@
|
||||||
{ pkgs, lib }:
|
{ pkgs, lib }:
|
||||||
let
|
let
|
||||||
modules = [
|
modules = [
|
||||||
./build_config
|
|
||||||
./editor
|
./editor
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,6 @@ let
|
||||||
dicts = pkgs.aspellWithDicts (dicts: with dicts; [ en en-computers en-science ]);
|
dicts = pkgs.aspellWithDicts (dicts: with dicts; [ en en-computers en-science ]);
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
fg42.elispPackages = [ drv ] ++ deps;
|
fg42.elispPackages = [ drv ] ++ deps;
|
||||||
fg42.startUp = lib.mkDefault "${drv}/share/emacs/site-lisp/fg42.el";
|
fg42.startUp = lib.mkDefault "${drv}/share/emacs/site-lisp/fg42.el";
|
||||||
|
@ -66,14 +65,7 @@ in
|
||||||
dicts
|
dicts
|
||||||
]);
|
]);
|
||||||
|
|
||||||
fg42.buildConfig = {
|
fg42.font = lib.mkDefault '''("Fira Mono" 11)'';
|
||||||
"fg42/font" = {
|
fg42.requires = [ "fg42/cpp" ];
|
||||||
value = '''("Fira Mono" 11)'';
|
|
||||||
docs = ''
|
|
||||||
The default font for FG42. You can override it
|
|
||||||
in your configuration file.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,16 +106,18 @@
|
||||||
(defun fg42/initialize ()
|
(defun fg42/initialize ()
|
||||||
"Initialize FG42 after the Emacs window is rendered by loading the user init file."
|
"Initialize FG42 after the Emacs window is rendered by loading the user init file."
|
||||||
;; (fg42/-startup-optimization)
|
;; (fg42/-startup-optimization)
|
||||||
(require 'fg42/editor)
|
|
||||||
|
|
||||||
|
(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.
|
||||||
(when (file-exists-p user-init-file)
|
(when (file-exists-p user-init-file)
|
||||||
(load user-init-file))
|
(load user-init-file))
|
||||||
|
|
||||||
|
(fg42/setup-theme!)
|
||||||
(fg42/setup-editor)
|
(fg42/setup-editor)
|
||||||
;; ;; If user didn't select a theme, load the default stuff
|
|
||||||
;; (when (not (featurep 'fg42/themes))
|
|
||||||
;; (require 'fg42/themes))
|
|
||||||
|
|
||||||
(add-hook 'emacs-startup-hook
|
(add-hook 'emacs-startup-hook
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(run-hooks 'fg42/after-init-hook)
|
(run-hooks 'fg42/after-init-hook)
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
;; We build this file via the main FG42's Nix derivation. It
|
;; We build this file via the main FG42's Nix derivation. It
|
||||||
;; contains the final Nix configuration of FG42.
|
;; contains the final Nix configuration of FG42.
|
||||||
(require 'fg42/build-config)
|
(require 'fg42/build-config)
|
||||||
|
(require 'fg42/themes)
|
||||||
;; ;; Language support
|
;; ;; Language support
|
||||||
;; (require 'fg42/autocomplete)
|
;; (require 'fg42/autocomplete)
|
||||||
;; (require 'fg42/langs/langs)
|
;; (require 'fg42/langs/langs)
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
;;; Themes --- Theme library of FG42 -*- 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:
|
||||||
|
;; Cubes are the building blocks of any `FG42' editor. Each `cube' is a
|
||||||
|
;; unit which defines different abilities in a deterministic and idempotent
|
||||||
|
;; way. Cubes are composable and a composition of cubes creates an editor.
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(eval-when-compile
|
||||||
|
(require 'fpkg)
|
||||||
|
(require 'fg42/build-config))
|
||||||
|
|
||||||
|
(require 'fg42/utils)
|
||||||
|
|
||||||
|
(defvar fg42/ui-hook ()
|
||||||
|
"A hook that cubes can use via :ui-hook property.
|
||||||
|
It executes way before the rest of the cubes.")
|
||||||
|
|
||||||
|
(defvar fg42/before-initializing-theme-hook ()
|
||||||
|
"The hook to plug any configuration to before initialize event of themes.")
|
||||||
|
|
||||||
|
(defvar fg42/after-initializing-theme-hook ()
|
||||||
|
"The hook to plug any configuration to after initialize event of themes.")
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro fg42/setup-theme! (&rest body)
|
||||||
|
"Grab the them provided by `fg42/theme' and load it.
|
||||||
|
|
||||||
|
Load the theme via `use!' and pass the BODY to the `use!' macroro.
|
||||||
|
If the theme name and the theme package name are different the package
|
||||||
|
name can be set via `fg42/theme-package'".
|
||||||
|
|
||||||
|
(declare (indent defun))
|
||||||
|
(let ((pkg (if (not (null fg42/theme-package))
|
||||||
|
fg42/theme-package
|
||||||
|
fg42/theme)))
|
||||||
|
`(use! ,pkg
|
||||||
|
"Setting up the ,pkg package."
|
||||||
|
:config
|
||||||
|
(load-theme fg42/theme t)
|
||||||
|
,@body)))
|
||||||
|
|
||||||
|
;; (use! base16-theme
|
||||||
|
;; "Load base16 based themes in FG42."
|
||||||
|
;; :config
|
||||||
|
;; (load-theme 'base16-eighties t))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'fg42/themes)
|
||||||
|
;;; themes.el ends here
|
Loading…
Reference in New Issue