Create a modular Nix system to build FG42
This commit is contained in:
parent
1a0f2a31d2
commit
426c1d2dd1
|
@ -0,0 +1,219 @@
|
||||||
|
# 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;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
lxsameer@majin.69922:1712871165
|
|
@ -30,14 +30,20 @@ let
|
||||||
lib = lib;
|
lib = lib;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
utils = pkgs.callPackage ./utils.nix { };
|
||||||
|
|
||||||
unitModule = import ./unit.nix { inherit pkgs lib; };
|
unitModule = import ./unit.nix { inherit pkgs lib; };
|
||||||
final = lib.evalModules {
|
final = lib.evalModules {
|
||||||
modules = [ unitModule ] ++ fg42Modules ++ extraModules;
|
modules = [ unitModule ] ++ fg42Modules ++ extraModules;
|
||||||
|
specialArgs = {
|
||||||
|
inherit utils;
|
||||||
|
inherit (utils) makeFG42Drv;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
in
|
in
|
||||||
pkgs.callPackage ./derivation.nix {
|
pkgs.callPackage ./derivation.nix {
|
||||||
inherit (final) config options;
|
inherit (final) config options;
|
||||||
|
inherit utils;
|
||||||
maintainers = import ../maintainers.nix;
|
maintainers = import ../maintainers.nix;
|
||||||
utils = pkgs.callPackage ./utils.nix { };
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,11 @@
|
||||||
, makeFontsConf
|
, makeFontsConf
|
||||||
, xorg
|
, xorg
|
||||||
, maintainers
|
, maintainers
|
||||||
|
, writeText
|
||||||
|
, writeShellApplication
|
||||||
, ...
|
, ...
|
||||||
}:
|
}:
|
||||||
|
|
||||||
with builtins;
|
with builtins;
|
||||||
let
|
let
|
||||||
cfg = config.fg42;
|
cfg = config.fg42;
|
||||||
|
@ -42,8 +45,49 @@ let
|
||||||
|
|
||||||
fontsConf = makeFontsConf { fontDirectories = cfg.fonts; };
|
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
|
in
|
||||||
|
|
||||||
stdenv.mkDerivation rec {
|
stdenv.mkDerivation rec {
|
||||||
inherit version;
|
inherit version;
|
||||||
pname = "FG42";
|
pname = "FG42";
|
||||||
|
@ -51,13 +95,15 @@ stdenv.mkDerivation rec {
|
||||||
src = ../../.;
|
src = ../../.;
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
|
runHook preBuild
|
||||||
|
|
||||||
LISPDIR=$out/share/fg42/
|
LISPDIR=$out/share/fg42/
|
||||||
mkdir -p $out/bin
|
mkdir -p $out/bin
|
||||||
mkdir -p $out/share/applications/
|
mkdir -p $out/share/applications/
|
||||||
|
|
||||||
install -d $LISPDIR
|
install -d $LISPDIR
|
||||||
|
|
||||||
cp -rv ${src}/lisp/ $LISPDIR
|
# cp -rv ${src}/lisp/ $LISPDIR
|
||||||
|
|
||||||
cp -rv ${src}/share $out/
|
cp -rv ${src}/share $out/
|
||||||
cp -rv ${src}/snippets $LISPDIR/snippets
|
cp -rv ${src}/snippets $LISPDIR/snippets
|
||||||
|
@ -83,18 +129,18 @@ stdenv.mkDerivation rec {
|
||||||
Version=${version}
|
Version=${version}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
runHook preBuild
|
cat >> $out/share/runtime_deps << EOF
|
||||||
|
${lib.strings.concatLines runtimeDependencies}
|
||||||
|
${emacsBundle}
|
||||||
|
EOF
|
||||||
|
|
||||||
cd $LISPDIR
|
cd $LISPDIR
|
||||||
emacs -L . --batch -f batch-byte-compile *.el
|
#compile stuff
|
||||||
cd -
|
cd -
|
||||||
|
|
||||||
cat >> $out/bin/fg42 << EOF
|
cat >> $out/bin/fg42 << EOF
|
||||||
#!${stdenv.shell}
|
#!${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 PATH=${pathsStr}:$PATH
|
||||||
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
|
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
|
||||||
|
|
||||||
|
@ -102,9 +148,16 @@ stdenv.mkDerivation rec {
|
||||||
FG42_WM=fales ${emacsBundle}/bin/emacs \
|
FG42_WM=fales ${emacsBundle}/bin/emacs \
|
||||||
--name FG42 \
|
--name FG42 \
|
||||||
-q --no-splash --title FG42 \
|
-q --no-splash --title FG42 \
|
||||||
-l \$FG42_HOME/lisp/fg42/init.el "\$@"
|
-l ${cfg.startUp} "\$@"
|
||||||
EOF
|
EOF
|
||||||
chmod +x $out/bin/fg42
|
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
|
runHook postBuild
|
||||||
|
|
||||||
cat >> $out/bin/fg42-wm << EOF
|
cat >> $out/bin/fg42-wm << EOF
|
||||||
|
@ -137,23 +190,15 @@ stdenv.mkDerivation rec {
|
||||||
LIBRARY_PATH="\$(${stdenv.cc}/bin/cc -print-file-name=libgccjit.so):\$LIBRARY_PATH" \
|
LIBRARY_PATH="\$(${stdenv.cc}/bin/cc -print-file-name=libgccjit.so):\$LIBRARY_PATH" \
|
||||||
FG42_WM=true ${emacsBundle}/bin/emacs \
|
FG42_WM=true ${emacsBundle}/bin/emacs \
|
||||||
--name FG42 \
|
--name FG42 \
|
||||||
-q --no-splash --title FG42 \
|
-q --no-splash --title FG42 \
|
||||||
-l \$FG42_HOME/lisp/fg42/init.el "\$@"
|
-l \$FG42_HOME/lisp/fg42/fg42.el "\$@"
|
||||||
EOF
|
EOF
|
||||||
chmod +x $out/bin/fg42-wm
|
chmod +x $out/bin/fg42-wm
|
||||||
|
|
||||||
LISPDIR=$out/share/fg42/lisp/
|
|
||||||
emacs --batch -l package --eval "(package-generate-autoloads \"${pname}\" \"$LISPDIR\")"
|
|
||||||
|
|
||||||
runHook postBuild
|
runHook postBuild
|
||||||
'';
|
'';
|
||||||
|
|
||||||
# installPhase = ''
|
|
||||||
# runHook preInstall
|
|
||||||
|
|
||||||
# runHook postInstall
|
|
||||||
# '';
|
|
||||||
|
|
||||||
buildInputs = [ emacs emacsBundle git texinfo gcc bash ];
|
buildInputs = [ emacs emacsBundle git texinfo gcc bash ];
|
||||||
|
|
||||||
addEmacsNativeLoadPath = true;
|
addEmacsNativeLoadPath = true;
|
||||||
|
|
|
@ -59,7 +59,6 @@ with lib;
|
||||||
A list of mineType strings that FG42 should handle via
|
A list of mineType strings that FG42 should handle via
|
||||||
desktop file.
|
desktop file.
|
||||||
'';
|
'';
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
fg42.fonts = mkOption {
|
fg42.fonts = mkOption {
|
||||||
|
@ -69,6 +68,12 @@ with lib;
|
||||||
A list of font packages that should be included in FG42
|
A list of font packages that should be included in FG42
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fg42.startUp = mkOption {
|
||||||
|
type = types.uniq types.path;
|
||||||
|
description = "The main startup file to load first. This is usually fg42.el";
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,26 @@
|
||||||
#
|
#
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
{ ... }:
|
{ emacsPackages, writeTextFile, ... }:
|
||||||
{
|
{
|
||||||
makeDesktopFile = { };
|
makeDesktopFile = { };
|
||||||
|
|
||||||
|
makeFG42Drv = { pname, version, ... }@args:
|
||||||
|
(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
|
||||||
|
'';
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
# 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,8 @@
|
||||||
{ pkgs, lib }:
|
{ pkgs, lib }:
|
||||||
let
|
let
|
||||||
modules = [
|
modules = [
|
||||||
./editor.nix
|
./build_config
|
||||||
|
./editor
|
||||||
];
|
];
|
||||||
|
|
||||||
pkgsModule = { config, ... }: {
|
pkgsModule = { config, ... }: {
|
||||||
|
|
|
@ -1,33 +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, ... }:
|
|
||||||
{
|
|
||||||
options = {
|
|
||||||
fg42.editor = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "blah";
|
|
||||||
description = ''
|
|
||||||
FG42's version1.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
# 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, ... }:
|
||||||
|
let
|
||||||
|
deps = (with pkgs.emacsPackages; [
|
||||||
|
origami
|
||||||
|
which-key
|
||||||
|
projectile
|
||||||
|
projectile-ripgrep
|
||||||
|
pkg-info
|
||||||
|
expand-region
|
||||||
|
helpful
|
||||||
|
envrc
|
||||||
|
pinentry
|
||||||
|
discover
|
||||||
|
exec-path-from-shell
|
||||||
|
avy
|
||||||
|
ace-window
|
||||||
|
yasnippet
|
||||||
|
yasnippet-snippets
|
||||||
|
flycheck
|
||||||
|
]);
|
||||||
|
drv = makeFG42Drv {
|
||||||
|
pname = "fg42-editor";
|
||||||
|
version = config.fg42.version;
|
||||||
|
buildInputs = deps;
|
||||||
|
src = ./.;
|
||||||
|
};
|
||||||
|
|
||||||
|
dicts = pkgs.aspellWithDicts (dicts: with dicts; [ en en-computers en-science ]);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
|
||||||
|
config = {
|
||||||
|
fg42.elispPackages = [ drv ] ++ deps;
|
||||||
|
fg42.startUp = lib.mkDefault "${drv}/share/emacs/site-lisp/fg42.el";
|
||||||
|
|
||||||
|
fg42.fonts = (with pkgs;[
|
||||||
|
vazir-fonts
|
||||||
|
fira-code
|
||||||
|
fira-mono
|
||||||
|
noto-fonts
|
||||||
|
]);
|
||||||
|
|
||||||
|
fg42.paths = (with pkgs;[
|
||||||
|
ripgrep
|
||||||
|
dicts
|
||||||
|
]);
|
||||||
|
|
||||||
|
fg42.buildConfig = {
|
||||||
|
"fg42/font" = {
|
||||||
|
value = '''("Fira Mono" 11)'';
|
||||||
|
docs = ''
|
||||||
|
The default font for FG42. You can override it
|
||||||
|
in your configuration file.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
;;; 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:
|
||||||
|
(require 'fg42/utils)
|
||||||
|
(eval-when-compile
|
||||||
|
(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."
|
||||||
|
(setq gc-cons-threshold fg42/-gc-cons-threshold))
|
||||||
|
|
||||||
|
|
||||||
|
(defun restore-garbage-collection ()
|
||||||
|
"Restore garbage collection to it's default value."
|
||||||
|
(run-at-time
|
||||||
|
1 nil (lambda () (setq gc-cons-threshold most-positive-fixnum))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun fg42/-startup-optimization ()
|
||||||
|
"Optimized FG42 startup."
|
||||||
|
;; by setting gc threshold to the largest number
|
||||||
|
;; Emacs can understand we are basically disabling it :).
|
||||||
|
(setq gc-cons-threshold most-positive-fixnum
|
||||||
|
gc-cons-percentage 0.6)
|
||||||
|
;; after initilization phase restore cons threshold to normal
|
||||||
|
(add-hook 'emacs-startup-hook
|
||||||
|
(lambda ()
|
||||||
|
(setq gc-cons-threshold fg42/-gc-cons-threshold ; 16mb
|
||||||
|
gc-cons-percentage 0.1)))
|
||||||
|
|
||||||
|
;; disable gc when we are in minibuffer using the same method we
|
||||||
|
;; use for initilization time
|
||||||
|
(add-hook 'minibuffer-setup-hook #'defer-garbage-collection)
|
||||||
|
;; just enable gc when exiting minibuffer
|
||||||
|
(add-hook 'minibuffer-exit-hook #'restore-garbage-collection)
|
||||||
|
;; we dont need Emacs to check every file type and look for file
|
||||||
|
;; handlers when we are initializing so we backup the original
|
||||||
|
;; value and set it to nil
|
||||||
|
(setq --file-name-handler-alist file-name-handler-alist)
|
||||||
|
|
||||||
|
(setq file-name-handler-alist nil)
|
||||||
|
;; after initialization we can restore that file-name-handler-alist
|
||||||
|
;; to original value.
|
||||||
|
(add-hook 'emacs-startup-hook
|
||||||
|
(lambda ()
|
||||||
|
(setq file-name-handler-alist
|
||||||
|
--file-name-handler-alist)))
|
||||||
|
;; initial mode for emacs can be fundamental mode we have nothing to lose
|
||||||
|
(setq initial-major-mode 'fundamental-mode))
|
||||||
|
|
||||||
|
|
||||||
|
(defun fg42/initialize ()
|
||||||
|
"Initialize FG42 after the Emacs window is rendered by loading the user init file."
|
||||||
|
;; (fg42/-startup-optimization)
|
||||||
|
(require 'fg42/editor)
|
||||||
|
|
||||||
|
(when (file-exists-p user-init-file)
|
||||||
|
(load user-init-file))
|
||||||
|
|
||||||
|
(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
|
||||||
|
(lambda ()
|
||||||
|
(run-hooks 'fg42/after-init-hook)
|
||||||
|
(run-hooks 'fg42/ui-hook)
|
||||||
|
(setq fg42/initialized t))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun fg42/main ()
|
||||||
|
"The entry point of FG42."
|
||||||
|
(when (string= (getenv "FG42_DEBUG") "1")
|
||||||
|
(setq debug-on-error t
|
||||||
|
fg42/debug? t))
|
||||||
|
|
||||||
|
;; We don't use any Emacs package manager, so
|
||||||
|
;; prevent package.el to install anything at startup
|
||||||
|
(setq package-enable-at-startup nil
|
||||||
|
package-archives nil
|
||||||
|
use-package-ensure-function 'ignore
|
||||||
|
|
||||||
|
;; Setup the path for the custom.el file, We don't want
|
||||||
|
;; to touch user's Emacs configuration.
|
||||||
|
custom-file (path-join fg42/config-dir "custom.el")
|
||||||
|
|
||||||
|
;; Change the config dir to `~/.config/fg42/' by default
|
||||||
|
;; again, we don't want to temper with user's Emacs
|
||||||
|
user-emacs-directory fg42/config-dir
|
||||||
|
user-init-file
|
||||||
|
(or (getenv "FG42_CONFIG_FILE")
|
||||||
|
(path-join fg42/config-dir "fg42.el")))
|
||||||
|
|
||||||
|
;; Change the eln file cache to leave Emacs alone.
|
||||||
|
(startup-redirect-eln-cache
|
||||||
|
(or (getenv "FG42_ELN_DIR")
|
||||||
|
(path-join fg42/cache-dir "fg42.el")))
|
||||||
|
|
||||||
|
;; Load the customization file. In FG42 it is different than
|
||||||
|
;; the default `user-init-file'
|
||||||
|
(if (file-exists-p custom-file)
|
||||||
|
(load custom-file))
|
||||||
|
|
||||||
|
;; From point forward we can use normal Elisp stuff without
|
||||||
|
;; interfering with user's Emacs configuration
|
||||||
|
(fg42/initialize))
|
||||||
|
|
||||||
|
(fg42/main)
|
||||||
|
|
||||||
|
(provide 'fg42)
|
||||||
|
;;; fg42.el ends here
|
|
@ -0,0 +1,293 @@
|
||||||
|
;;; 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)
|
||||||
|
;; We build this file via the main FG42's Nix derivation. It
|
||||||
|
;; contains the final Nix configuration of FG42.
|
||||||
|
(require 'fg42/build-config)
|
||||||
|
;; ;; Language support
|
||||||
|
;; (require 'fg42/autocomplete)
|
||||||
|
;; (require 'fg42/langs/langs)
|
||||||
|
;; (require 'fg42/eglot)
|
||||||
|
;; (require 'fg42/langs/cpp)
|
||||||
|
;; (require 'fg42/langs/verilog)
|
||||||
|
;; (require 'fg42/langs/python)
|
||||||
|
;; (require 'fg42/langs/elisp)
|
||||||
|
;; (require 'fg42/langs/nix)
|
||||||
|
|
||||||
|
;; (require 'fg42/git)
|
||||||
|
;; (require 'fg42/wm)
|
||||||
|
;; (require 'fg42/org)
|
||||||
|
;; (require 'fg42/minibuffer)
|
||||||
|
;; (require 'fg42/graphics)
|
||||||
|
;; (require 'fg42/modeline)
|
||||||
|
)
|
||||||
|
|
||||||
|
(require 'server)
|
||||||
|
(require 'fg42/utils)
|
||||||
|
|
||||||
|
|
||||||
|
(defun fg42/setup-font ()
|
||||||
|
"Set the default font of `FG42' to FONT-NAME and FONT-SIZE."
|
||||||
|
(let ((name (car fg42/font))
|
||||||
|
(size (cadr fg42/font)))
|
||||||
|
(add-to-list 'default-frame-alist
|
||||||
|
(cons 'font (format "%s-%d" name size)))
|
||||||
|
|
||||||
|
(set-face-attribute 'default t :font name)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defun fg42/setup-editor ()
|
||||||
|
"Setup the overall functionality of FG42."
|
||||||
|
|
||||||
|
(use! origami
|
||||||
|
"A text folding minor mode for Emacs."
|
||||||
|
:bind
|
||||||
|
(("C-c TAB" . origami-toggle-node))
|
||||||
|
:config
|
||||||
|
(global-origami-mode t))
|
||||||
|
|
||||||
|
(use! which-key
|
||||||
|
"which-key is a minor mode for Emacs that displays the key bindings following
|
||||||
|
your currently entered incomplete command (a prefix) in a popup. For example,
|
||||||
|
after enabling the minor mode if you enter ~C-x~ and wait for the default of
|
||||||
|
1 second the minibuffer will expand with all of the available key bindings
|
||||||
|
that follow ~C-x~ (or as many as space allows given your settings).
|
||||||
|
This includes prefixes like ~C-x 8~ which are shown in a different face."
|
||||||
|
:config
|
||||||
|
(which-key-setup-side-window-bottom)
|
||||||
|
(which-key-mode))
|
||||||
|
|
||||||
|
(use! projectile
|
||||||
|
"Projectile is a project interaction library for Emacs. Its goal is to provide
|
||||||
|
a nice set of features operating on a project level without introducing
|
||||||
|
external dependencies."
|
||||||
|
:hook (emacs-startup . projectile-mode)
|
||||||
|
:config
|
||||||
|
;; We don't want the auto discovery on startup
|
||||||
|
(setq projectile-auto-discover nil)
|
||||||
|
(setq projectile-enable-caching t)
|
||||||
|
|
||||||
|
:bind (:map projectile-mode-map
|
||||||
|
("s-p" . projectile-command-map)
|
||||||
|
("C-c p" . projectile-command-map)))
|
||||||
|
|
||||||
|
|
||||||
|
(use! projectile-ripgrep
|
||||||
|
"Use ripgrep with projectile"
|
||||||
|
:after projectile)
|
||||||
|
|
||||||
|
|
||||||
|
(use! pkg-info
|
||||||
|
"`pkg-info' integration.")
|
||||||
|
|
||||||
|
|
||||||
|
(use! expand-region
|
||||||
|
"Expand region increases the selected region by semantic units.
|
||||||
|
Just keep pressing the key until it selects what you want."
|
||||||
|
:bind ("C-=" . er/expand-region))
|
||||||
|
|
||||||
|
|
||||||
|
(use! helpful
|
||||||
|
"Helpful is an alternative to the built-in Emacs help that provides much more
|
||||||
|
contextual information."
|
||||||
|
:bind
|
||||||
|
(("C-h f" . helpful-callable)
|
||||||
|
("C-h v" . helpful-variable)
|
||||||
|
("C-h k" . helpful-key)
|
||||||
|
("C-h x" . helpful-command)
|
||||||
|
("C-c C-d" . helpful-at-point)))
|
||||||
|
|
||||||
|
(use! envrc
|
||||||
|
"Activate direnv whenever encounter a `.envrc' file"
|
||||||
|
:config
|
||||||
|
(envrc-global-mode))
|
||||||
|
|
||||||
|
(use! pinentry
|
||||||
|
"Pinentry cube with setup the =pinentry= program to be used within FG42."
|
||||||
|
:commands pinentry-start
|
||||||
|
:init
|
||||||
|
(setq epa-pinentry-mode 'loopback))
|
||||||
|
|
||||||
|
(use! imenu-list
|
||||||
|
"his Emacs minor-mode creates an automatically updated buffer
|
||||||
|
called `Ilist' that is populated with the current buffer's imenu entries.
|
||||||
|
The `Ilist' buffer is typically shown as a sidebar (Emacs vertically splits the window)."
|
||||||
|
:bind (("C-'" . imenu-list-smart-toggle)))
|
||||||
|
|
||||||
|
(use! discover
|
||||||
|
"Adds support for the discover.el `https://github.com/mickeynp/discover.el'.")
|
||||||
|
|
||||||
|
(use! exec-path-from-shell
|
||||||
|
"This package fixes the =exec-path-from-shell= issue on MacOS."
|
||||||
|
:config
|
||||||
|
(when (memq window-system '(mac ns x))
|
||||||
|
(exec-path-from-shell-initialize)))
|
||||||
|
|
||||||
|
(use! hl-line
|
||||||
|
"Highlights the current line."
|
||||||
|
:hook (emacs-startup . global-hl-line-mode))
|
||||||
|
|
||||||
|
(use! avy
|
||||||
|
"This cube controls the different aspect of buffer navigation"
|
||||||
|
:bind ("M-1" . avy-goto-word-1))
|
||||||
|
|
||||||
|
(use! ace-window
|
||||||
|
"This cube controls the different aspect of buffer navigation"
|
||||||
|
:bind ("C-<tab>" . ace-window))
|
||||||
|
|
||||||
|
(when-not-wm
|
||||||
|
|
||||||
|
(use! flyspell
|
||||||
|
"Spell checking on the fly"
|
||||||
|
:commands (flyspell-mode flyspell-prog-mode)
|
||||||
|
:init
|
||||||
|
(setq-default ispell-program-name "aspell")
|
||||||
|
(setq-default ispell-extra-args '("--sug-mode=ultra"
|
||||||
|
"--lang=en_US"
|
||||||
|
"--camel-case")))
|
||||||
|
|
||||||
|
(use! savehist
|
||||||
|
"Persist history over Emacs restarts. Vertico sorts by history position."
|
||||||
|
:init
|
||||||
|
(savehist-mode))
|
||||||
|
|
||||||
|
(use! display-line-numbers
|
||||||
|
"The builtin replacement of linum. It's is pretty fast."
|
||||||
|
:config
|
||||||
|
(global-display-line-numbers-mode 1)))
|
||||||
|
|
||||||
|
|
||||||
|
(use! yasnippet
|
||||||
|
"A Snippet is a template system for Emacs. "
|
||||||
|
:config
|
||||||
|
(let* ((snippet-home
|
||||||
|
(path-join
|
||||||
|
(file-name-directory
|
||||||
|
(locate-library "yasnippet-snippets")) "snippets"))
|
||||||
|
(local-snippet (path-join (file-name-directory
|
||||||
|
(locate-library "fg42")) "../snippets"))
|
||||||
|
(user-snippets (path-join fg42/config-dir "snippets")))
|
||||||
|
|
||||||
|
(setq yas-snippet-dirs `(,user-snippets ,local-snippet ,snippet-home))
|
||||||
|
(yas-global-mode 1)))
|
||||||
|
|
||||||
|
(use! yasnippet-snippets
|
||||||
|
"Yasnippet's snippets."
|
||||||
|
:after yasnippet)
|
||||||
|
|
||||||
|
|
||||||
|
(use! flycheck
|
||||||
|
"Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs."
|
||||||
|
:config (global-flycheck-mode))
|
||||||
|
|
||||||
|
;; 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.
|
||||||
|
(fg42/setup-font)
|
||||||
|
(add-hook 'fg42/after-init-hook
|
||||||
|
(lambda ()
|
||||||
|
(set-default 'cursor-type 'bar)
|
||||||
|
(set-cursor-color "#eeeeec")))
|
||||||
|
|
||||||
|
;; Remove splash screen
|
||||||
|
(setq inhibit-splash-screen t)
|
||||||
|
;; scratch should be scratch
|
||||||
|
(setq initial-scratch-message nil)
|
||||||
|
;; Don't allow tab as indent
|
||||||
|
(setq-default indent-tabs-mode nil)
|
||||||
|
;; Default indent width
|
||||||
|
(setq tab-width 2)
|
||||||
|
;; Share the clipboard with X applications
|
||||||
|
(setq x-select-enable-clipboard t)
|
||||||
|
;; Automatically removed excess backups of the file
|
||||||
|
(setq delete-old-versions t)
|
||||||
|
;; Emacs 28 and newer: Hide commands in M-x which do not work in the current
|
||||||
|
;; mode. Vertico commands are hidden in normal buffers. This setting is
|
||||||
|
;; useful beyond Vertico.
|
||||||
|
(setq read-extended-command-predicate #'command-completion-default-include-p)
|
||||||
|
|
||||||
|
;; Support opening new minibuffers from inside existing minibuffers.
|
||||||
|
(setq enable-recursive-minibuffers t)
|
||||||
|
|
||||||
|
(setq tooltip-use-echo-area t)
|
||||||
|
(setq x-gtk-use-system-tooltips nil)
|
||||||
|
|
||||||
|
;; Global configurations
|
||||||
|
(tool-bar-mode -1)
|
||||||
|
(tooltip-mode nil)
|
||||||
|
(menu-bar-mode -1)
|
||||||
|
|
||||||
|
(when (display-graphic-p)
|
||||||
|
;; Smoother scrolling
|
||||||
|
(pixel-scroll-precision-mode)
|
||||||
|
(scroll-bar-mode -1))
|
||||||
|
|
||||||
|
(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)
|
||||||
|
|
||||||
|
(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)
|
||||||
|
|
||||||
|
;; Enable rainbow-delimiters for programming
|
||||||
|
(add-hook 'prog-mode-hook #'rainbow-delimiters-mode)
|
||||||
|
|
||||||
|
;; With this section we will have two emacs server running
|
||||||
|
;; this way we can interact with the wm via emacsclient as well
|
||||||
|
(when (not (server-running-p))
|
||||||
|
(when-wm
|
||||||
|
(setq server-name "fg42-wm"))
|
||||||
|
(server-start)
|
||||||
|
(require 'org-protocol))
|
||||||
|
|
||||||
|
(when-wm
|
||||||
|
;; Activating the WM mode
|
||||||
|
(exwm-enable)
|
||||||
|
(exwm-systemtray-enable)
|
||||||
|
(exwm-randr-enable))
|
||||||
|
(message "[FG42]: Use `fg42-help' to get help."))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'fg42/editor)
|
||||||
|
;;; editor.el ends here
|
|
@ -0,0 +1,161 @@
|
||||||
|
;;; Utils --- Utils library of FG42 -*- 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:
|
||||||
|
;; `System' is just a state monad which holds the state of the editor.
|
||||||
|
;; Each system has to have a `start' function to start the setup process.
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
|
|
||||||
|
(autoload 'seq-partition "seq")
|
||||||
|
(autoload 'cl-reduce "cl-seq")
|
||||||
|
|
||||||
|
|
||||||
|
(defun buffer-mode (buffer-or-string)
|
||||||
|
"Return the major mode associated with a the given BUFFER-OR-STRING."
|
||||||
|
(with-current-buffer buffer-or-string
|
||||||
|
major-mode))
|
||||||
|
|
||||||
|
|
||||||
|
(defun ->buffer (buffer-name data &optional fn)
|
||||||
|
"Insert the given DATA into the given buffer provided by BUFFER-NAME.
|
||||||
|
|
||||||
|
It will create a the buffer if it doesn't exist. It will call the given FN
|
||||||
|
at the end in context of the buffer. This function accepts only one argument
|
||||||
|
with is the buffer."
|
||||||
|
(let ((buf (get-buffer-create buffer-name)))
|
||||||
|
(with-current-buffer buf
|
||||||
|
(insert data)
|
||||||
|
(when fn
|
||||||
|
(funcall fn buf)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defun ->str (&rest args)
|
||||||
|
"Convert the given ARGS into string."
|
||||||
|
(funcall #'pp-to-string args))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro inspect-expression (&rest body)
|
||||||
|
"Pretty prints the result of the given BODY."
|
||||||
|
`(pp-display-expression ,@body (get-buffer-create fg42/inspect-buffer)))
|
||||||
|
|
||||||
|
|
||||||
|
(defun inspect-data-append (data)
|
||||||
|
"Append the given DATA to the inspection buffer with padding."
|
||||||
|
;; TODO: Move 'fg42/inspect-buffer' to the somewhere propriate
|
||||||
|
;; possiblly the system.
|
||||||
|
(->buffer
|
||||||
|
"fg42/inspect-buffer"
|
||||||
|
(format
|
||||||
|
"\n;; START ======================================================\n%s%s"
|
||||||
|
(pp-to-string data)
|
||||||
|
";; END.\n")))
|
||||||
|
|
||||||
|
|
||||||
|
(defun apply-face (face-symbol text)
|
||||||
|
"Apply the given FACE-SYMBOL to the given TEXT."
|
||||||
|
(put-text-property 0 (length text) 'face face-symbol text))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro comment (&rest _body)
|
||||||
|
"A macro similar to Clojure's comment macro that ignore the BODY."
|
||||||
|
(declare (indent 0))
|
||||||
|
`nil)
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro debug-message (&rest params)
|
||||||
|
"Print out the given PARAMS only if debug mode is on."
|
||||||
|
(if debug-on-error
|
||||||
|
`(message ,@params)
|
||||||
|
nil))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro deprecated (msg &rest form)
|
||||||
|
"Mark the given FORM as deprecated with the given MSG."
|
||||||
|
(declare (indent 0))
|
||||||
|
`(progn
|
||||||
|
(warn (format "[DEPRECATED]: %s" ,msg))
|
||||||
|
,@form))
|
||||||
|
|
||||||
|
|
||||||
|
(defun path-join (&rest paths)
|
||||||
|
"Join the given PATHS."
|
||||||
|
(apply #'concat
|
||||||
|
(append
|
||||||
|
(mapcar #'file-name-as-directory (butlast paths))
|
||||||
|
(last paths))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro -> (x &optional form &rest more)
|
||||||
|
"Thread the expr through the forms FORM and rest of form in MORE.
|
||||||
|
Insert X as the second item in the first form, making a list of
|
||||||
|
it if it is not a list already. If there are more forms, insert
|
||||||
|
the first form as the second item in second form, etc."
|
||||||
|
(declare (debug (form &rest [&or symbolp (sexp &rest form)])))
|
||||||
|
(cond
|
||||||
|
((null form) x)
|
||||||
|
((null more) (if (listp form)
|
||||||
|
`(,(car form) ,x ,@(cdr form))
|
||||||
|
(list form x)))
|
||||||
|
(:else `(-> (-> ,x ,form) ,@more))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro ->> (x &optional form &rest more)
|
||||||
|
"Thread the expr through the forms FORM and the rest at MORE.
|
||||||
|
Insert X as the last item in the first form, making a list of
|
||||||
|
it if it is not a list already. If there are more forms, insert
|
||||||
|
the first form as the
|
||||||
|
last item in second form, etc."
|
||||||
|
(declare (debug ->))
|
||||||
|
(cond
|
||||||
|
((null form) x)
|
||||||
|
((null more) (if (listp form)
|
||||||
|
`(,@form ,x)
|
||||||
|
(list form x)))
|
||||||
|
(:else `(->> (->> ,x ,form) ,@more))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro when-wm (&rest body)
|
||||||
|
"Run the BODY only if in wm mode."
|
||||||
|
(if (string= (getenv "FG42_WM") "true")
|
||||||
|
`(progn ,@body)
|
||||||
|
nil))
|
||||||
|
|
||||||
|
(defmacro when-not-wm (&rest body)
|
||||||
|
"Run the BODY only if not in the wm mode."
|
||||||
|
(if (not (string= (getenv "FG42_WM") "true"))
|
||||||
|
`(progn ,@body)
|
||||||
|
nil))
|
||||||
|
|
||||||
|
|
||||||
|
(defun get-base16-color-or (color-name default)
|
||||||
|
"Return the color for COLOR-NAME if a base16 theme is loade otherwise DEFAULT."
|
||||||
|
(let* ((theme (car custom-enabled-themes))
|
||||||
|
(theme-sym (intern (format "%s-theme-colors" theme))))
|
||||||
|
|
||||||
|
(if (boundp theme-sym)
|
||||||
|
(or (eval `(plist-get ,theme-sym ,color-name)) default)
|
||||||
|
default)))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'fg42/utils)
|
||||||
|
;;; utils.el ends here
|
|
@ -0,0 +1,69 @@
|
||||||
|
;;; fpkg --- a simple package manager for FG42 -*- lexical-binding: t; -*-
|
||||||
|
;;
|
||||||
|
;; Copyright (C) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
;;
|
||||||
|
;; Author: Sameer Rahmani <lxsameer@gnu.org>
|
||||||
|
;; Keywords: lisp fg42 IDE package manager
|
||||||
|
;; Version: 1.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:
|
||||||
|
;;
|
||||||
|
;; Simple package manager for FG42
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
(require 'map)
|
||||||
|
|
||||||
|
(defvar package-names ())
|
||||||
|
|
||||||
|
(eval-when-compile
|
||||||
|
(defvar fg42/disabled-features '())
|
||||||
|
(require 'use-package))
|
||||||
|
|
||||||
|
|
||||||
|
(defun inject-params (args)
|
||||||
|
"Inject required `use-package' params to ARGS if the key is missing."
|
||||||
|
;; (if (member :defer args)
|
||||||
|
;; (append '(:ensure nil) args)
|
||||||
|
(append args '(:ensure nil)))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro fpkg/use (pkg &rest details)
|
||||||
|
"Install the given package DETAILS PKG via `use-package' and straight."
|
||||||
|
(declare (indent defun))
|
||||||
|
(if (and (listp details) (< 0 (length details)))
|
||||||
|
(let ((p (inject-params details)))
|
||||||
|
`(progn
|
||||||
|
(use-package ,pkg ,@p)))
|
||||||
|
`(progn
|
||||||
|
(use-package ,pkg :defer t :ensure nil))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro use! (pkg docs &rest details)
|
||||||
|
"Loading the given package DETAILS PKG via `use-package'.
|
||||||
|
|
||||||
|
DOCS is the documentation of the package."
|
||||||
|
(declare (indent defun) (doc-string 2))
|
||||||
|
|
||||||
|
(when (not (stringp docs))
|
||||||
|
(error "Missing docstring for '%s' package" pkg))
|
||||||
|
|
||||||
|
(let ((disabled (or (member pkg fg42/disabled-features) nil)))
|
||||||
|
(when (not disabled)
|
||||||
|
`(use-package ,pkg ,@details))))
|
||||||
|
|
||||||
|
|
||||||
|
(provide 'fpkg)
|
||||||
|
;;; fpkg.el ends here
|
Loading…
Reference in New Issue