diff --git a/nix/deps.nix b/nix/deps.nix
index dcbdf3a..6d65e0e 100644
--- a/nix/deps.nix
+++ b/nix/deps.nix
@@ -13,14 +13,15 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-
{ pkgs, lib, elispDepsFile }:
with builtins;
let
reader = import ./elisp_reader.nix { inherit lib; };
elispAst = reader.fromElisp (builtins.readFile elispDepsFile);
dependsOnForm = filter (x: head x == "depends-on") elispAst;
- elispPkgs = if length dependsOnForm == 0
- then throw "Can't find the form 'depends-on' on 'deps.el'"
- else tail (head dependsOnForm);
-in elispPkgs
+ elispPkgs =
+ if length dependsOnForm == 0
+ then throw "Can't find the form 'depends-on' on 'deps.el'"
+ else tail (head dependsOnForm);
+in
+elispPkgs
diff --git a/nix/desktop.nix b/nix/desktop.nix
deleted file mode 100644
index 1fca586..0000000
--- a/nix/desktop.nix
+++ /dev/null
@@ -1,33 +0,0 @@
-# Fg42 - Emacs Editor for advance users
-#
-# Copyright (c) 2010-2024 Sameer Rahmani
-#
-# 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 .
-{ pkgs, fg42, version }:
-{
- desktop = pkgs.writeText "FG42.desktop" ''
-[Desktop Entry]
-Encoding=UTF-8
-Name=FG42
-GenericName=FG42
-Comment=Emacs Editor for advance users
-MimeType=text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-java;application/x-shellscript;text/x-c;text/x-c++;text/x-ruby;text/x-python;text/x-clojure;text/css;text/html;text/x-javascript;
-Type=Application
-Terminal=false
-Categories=Development;TextEditor;
-StartupWMClass=FG42
-Exec=${fg42} %F
-Icon=fg42
-Version=${version}
- '';
-}
diff --git a/nix/elisp_reader.nix b/nix/elisp_reader.nix
index f41cf8e..a1958c3 100644
--- a/nix/elisp_reader.nix
+++ b/nix/elisp_reader.nix
@@ -25,18 +25,18 @@ let
# but only as far in as specified by maxLength.
mkMatcher = regex: maxLength:
string:
- let
- substr = substring 0 maxLength string;
- matched = match regex substr;
- in
- if matched != null then head matched else null;
+ let
+ substr = substring 0 maxLength string;
+ matched = match regex substr;
+ in
+ if matched != null then head matched else null;
removeStrings = stringsToRemove: string:
let
len = length stringsToRemove;
listOfNullStrings = genList (const "") len;
in
- replaceStrings stringsToRemove listOfNullStrings string;
+ replaceStrings stringsToRemove listOfNullStrings string;
# Split a string of elisp into individual tokens and add useful
# metadata.
@@ -73,7 +73,8 @@ let
matchSymbol =
let
symbolChar = ''([^${notInSymbol}]|\\.)'';
- in mkMatcher ''(${symbolChar}+)([${notInSymbol}]|$).*'' symbolMaxLength;
+ in
+ mkMatcher ''(${symbolChar}+)([${notInSymbol}]|$).*'' symbolMaxLength;
maxTokenLength = foldl' max 0 [
commentMaxLength
@@ -125,173 +126,174 @@ let
dot = matchDot rest;
symbol = matchSymbol rest;
in
- if state.skip > 0 then
- state // {
+ if state.skip > 0 then
+ state // {
+ pos = state.pos + 1;
+ skip = state.skip - 1;
+ line = if char == "\n" then state.line + 1 else state.line;
+ }
+ else if char == "\n" then
+ let
+ mod = state.line / 1000;
+ newState = {
pos = state.pos + 1;
- skip = state.skip - 1;
- line = if char == "\n" then state.line + 1 else state.line;
- }
- else if char == "\n" then
- let
- mod = state.line / 1000;
- newState = {
- pos = state.pos + 1;
- line = state.line + 1;
- inherit mod;
- };
- in
- state // (
- # Force evaluation of old state every 1000 lines. Nix
- # doesn't have a modulo builtin, so we have to save
- # the result of an integer division and compare
- # between runs.
- if mod > state.mod then
- seq state.acc newState
- else
- newState
- )
- else if elem char [ " " "\t" "\r" ] then
- state // {
- pos = state.pos + 1;
- inherit (state) line;
- }
- else if char == ";" then
- if comment != null then
- state // {
- pos = state.pos + 1;
- skip = (stringLength comment) - 1;
- }
- else throw "Unrecognized token on line ${toString state.line}: ${rest}"
- else if char == "(" then
- state // {
- acc = state.acc ++ [{ type = "openParen"; value = "("; inherit (state) line; }];
- pos = state.pos + 1;
- }
- else if char == ")" then
- state // {
- acc = state.acc ++ [{ type = "closeParen"; value = ")"; inherit (state) line; }];
- pos = state.pos + 1;
- }
- else if char == "[" then
- state // {
- acc = state.acc ++ [{ type = "openBracket"; value = "["; inherit (state) line; }];
- pos = state.pos + 1;
- }
- else if char == "]" then
- state // {
- acc = state.acc ++ [{ type = "closeBracket"; value = "]"; inherit (state) line; }];
- pos = state.pos + 1;
- }
- else if char == "'" then
- state // {
- acc = state.acc ++ [{ type = "quote"; value = "'"; inherit (state) line; }];
- pos = state.pos + 1;
- }
- else if char == ''"'' then
- if string != null then
- state // {
- acc = state.acc ++ [{ type = "string"; value = string; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength string) - 1;
- }
- else throw "Unrecognized token on line ${toString state.line}: ${rest}"
- else if char == "#" then
- let nextChar = substring 1 1 rest;
- in
- if nextChar == "'" then
- state // {
- acc = state.acc ++ [{ type = "function"; value = "#'"; inherit (state) line; }];
- pos = state.pos + 1;
- skip = 1;
- }
- else if nextChar == "&" then
- if boolVector != null then
- state // {
- acc = state.acc ++ [{ type = "boolVector"; value = boolVector; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength boolVector) - 1;
- }
- else throw "Unrecognized token on line ${toString state.line}: ${rest}"
- else if nextChar == "s" then
- if substring 2 1 rest == "(" then
- state // {
- acc = state.acc ++ [{ type = "record"; value = "#s"; inherit (state) line; }];
- pos = state.pos + 1;
- skip = 1;
- }
- else throw "List must follow #s in record on line ${toString state.line}: ${rest}"
- else if nextChar == "[" then
- state // {
- acc = state.acc ++ [{ type = "byteCode"; value = "#"; inherit (state) line; }];
- pos = state.pos + 1;
- }
- else if nonBase10Integer != null then
- state // {
- acc = state.acc ++ [{ type = "nonBase10Integer"; value = nonBase10Integer; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength nonBase10Integer) - 1;
- }
- else throw "Unrecognized token on line ${toString state.line}: ${rest}"
- else if elem char [ "+" "-" "." "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" ] then
- if integer != null then
- state // {
- acc = state.acc ++ [{ type = "integer"; value = integer; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength integer) - 1;
- }
- else if float != null then
- state // {
- acc = state.acc ++ [{ type = "float"; value = float; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength float) - 1;
- }
- else if dot != null then
- state // {
- acc = state.acc ++ [{ type = "dot"; value = dot; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength dot) - 1;
- }
- else if symbol != null then
- state // {
- acc = state.acc ++ [{ type = "symbol"; value = symbol; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength symbol) - 1;
- }
- else throw "Unrecognized token on line ${toString state.line}: ${rest}"
- else if char == "?" then
- if character != null then
- state // {
- acc = state.acc ++ [{ type = "character"; value = character; inherit (state) line; }];
- pos = state.pos + 1;
- skip = (stringLength character) - 1;
- }
- else throw "Unrecognized token on line ${toString state.line}: ${rest}"
- else if char == "`" then
- state // {
- acc = state.acc ++ [{ type = "backquote"; value = "`"; inherit (state) line; }];
- pos = state.pos + 1;
- }
- else if char == "," then
- if substring 1 1 rest == "@" then
- state // {
- acc = state.acc ++ [{ type = "slice"; value = ",@"; inherit (state) line; }];
- skip = 1;
- pos = state.pos + 1;
- }
+ line = state.line + 1;
+ inherit mod;
+ };
+ in
+ state // (
+ # Force evaluation of old state every 1000 lines. Nix
+ # doesn't have a modulo builtin, so we have to save
+ # the result of an integer division and compare
+ # between runs.
+ if mod > state.mod then
+ seq state.acc newState
else
+ newState
+ )
+ else if elem char [ " " "\t" "\r" ] then
+ state // {
+ pos = state.pos + 1;
+ inherit (state) line;
+ }
+ else if char == ";" then
+ if comment != null then
+ state // {
+ pos = state.pos + 1;
+ skip = (stringLength comment) - 1;
+ }
+ else throw "Unrecognized token on line ${toString state.line}: ${rest}"
+ else if char == "(" then
+ state // {
+ acc = state.acc ++ [{ type = "openParen"; value = "("; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if char == ")" then
+ state // {
+ acc = state.acc ++ [{ type = "closeParen"; value = ")"; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if char == "[" then
+ state // {
+ acc = state.acc ++ [{ type = "openBracket"; value = "["; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if char == "]" then
+ state // {
+ acc = state.acc ++ [{ type = "closeBracket"; value = "]"; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if char == "'" then
+ state // {
+ acc = state.acc ++ [{ type = "quote"; value = "'"; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if char == ''"'' then
+ if string != null then
+ state // {
+ acc = state.acc ++ [{ type = "string"; value = string; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = (stringLength string) - 1;
+ }
+ else throw "Unrecognized token on line ${toString state.line}: ${rest}"
+ else if char == "#" then
+ let nextChar = substring 1 1 rest;
+ in
+ if nextChar == "'" then
+ state // {
+ acc = state.acc ++ [{ type = "function"; value = "#'"; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = 1;
+ }
+ else if nextChar == "&" then
+ if boolVector != null then
state // {
- acc = state.acc ++ [{ type = "expand"; value = ","; inherit (state) line; }];
+ acc = state.acc ++ [{ type = "boolVector"; value = boolVector; inherit (state) line; }];
pos = state.pos + 1;
+ skip = (stringLength boolVector) - 1;
}
+ else throw "Unrecognized token on line ${toString state.line}: ${rest}"
+ else if nextChar == "s" then
+ if substring 2 1 rest == "(" then
+ state // {
+ acc = state.acc ++ [{ type = "record"; value = "#s"; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = 1;
+ }
+ else throw "List must follow #s in record on line ${toString state.line}: ${rest}"
+ else if nextChar == "[" then
+ state // {
+ acc = state.acc ++ [{ type = "byteCode"; value = "#"; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if nonBase10Integer != null then
+ state // {
+ acc = state.acc ++ [{ type = "nonBase10Integer"; value = nonBase10Integer; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = (stringLength nonBase10Integer) - 1;
+ }
+ else throw "Unrecognized token on line ${toString state.line}: ${rest}"
+ else if elem char [ "+" "-" "." "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" ] then
+ if integer != null then
+ state // {
+ acc = state.acc ++ [{ type = "integer"; value = integer; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = (stringLength integer) - 1;
+ }
+ else if float != null then
+ state // {
+ acc = state.acc ++ [{ type = "float"; value = float; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = (stringLength float) - 1;
+ }
+ else if dot != null then
+ state // {
+ acc = state.acc ++ [{ type = "dot"; value = dot; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = (stringLength dot) - 1;
+ }
else if symbol != null then
state // {
acc = state.acc ++ [{ type = "symbol"; value = symbol; inherit (state) line; }];
pos = state.pos + 1;
skip = (stringLength symbol) - 1;
}
+ else throw "Unrecognized token on line ${toString state.line}: ${rest}"
+ else if char == "?" then
+ if character != null then
+ state // {
+ acc = state.acc ++ [{ type = "character"; value = character; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = (stringLength character) - 1;
+ }
+ else throw "Unrecognized token on line ${toString state.line}: ${rest}"
+ else if char == "`" then
+ state // {
+ acc = state.acc ++ [{ type = "backquote"; value = "`"; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if char == "," then
+ if substring 1 1 rest == "@" then
+ state // {
+ acc = state.acc ++ [{ type = "slice"; value = ",@"; inherit (state) line; }];
+ skip = 1;
+ pos = state.pos + 1;
+ }
else
- throw "Unrecognized token on line ${toString state.line}: ${rest}";
- in (builtins.foldl' readToken { acc = []; pos = 0; skip = 0; line = startLineNumber; mod = 0; } (stringToCharacters elisp)).acc;
+ state // {
+ acc = state.acc ++ [{ type = "expand"; value = ","; inherit (state) line; }];
+ pos = state.pos + 1;
+ }
+ else if symbol != null then
+ state // {
+ acc = state.acc ++ [{ type = "symbol"; value = symbol; inherit (state) line; }];
+ pos = state.pos + 1;
+ skip = (stringLength symbol) - 1;
+ }
+ else
+ throw "Unrecognized token on line ${toString state.line}: ${rest}";
+ in
+ (builtins.foldl' readToken { acc = [ ]; pos = 0; skip = 0; line = startLineNumber; mod = 0; } (stringToCharacters elisp)).acc;
tokenizeElisp = elisp:
tokenizeElisp' { inherit elisp; };
@@ -302,41 +304,43 @@ let
# Convert literal value tokens in a flat list to their
# corresponding nix representation.
parseValues = tokens:
- map (token:
- if token.type == "string" then
- token // {
- value = substring 1 (stringLength token.value - 2) token.value;
- }
- else if token.type == "integer" then
- token // {
- value = fromJSON (removeStrings ["+" "."] token.value);
- }
- else if token.type == "symbol" && token.value == "t" then
- token // {
- value = true;
- }
- else if token.type == "float" then
- let
- initial = head (match "([+-]?([[:digit:]]*[.])?[[:digit:]]+(e([+-]?[[:digit:]]+|[+](INF|NaN)))?)" token.value);
- isSpecial = (match "(.+(e[+](INF|NaN)))" initial) != null;
- withoutPlus = removeStrings ["+"] initial;
- withPrefix =
- if substring 0 1 withoutPlus == "." then
- "0" + withoutPlus
- else if substring 0 2 withoutPlus == "-." then
- "-0" + removeStrings ["-"] withoutPlus
- else
- withoutPlus;
- in
+ map
+ (token:
+ if token.type == "string" then
+ token // {
+ value = substring 1 (stringLength token.value - 2) token.value;
+ }
+ else if token.type == "integer" then
+ token // {
+ value = fromJSON (removeStrings [ "+" "." ] token.value);
+ }
+ else if token.type == "symbol" && token.value == "t" then
+ token // {
+ value = true;
+ }
+ else if token.type == "float" then
+ let
+ initial = head (match "([+-]?([[:digit:]]*[.])?[[:digit:]]+(e([+-]?[[:digit:]]+|[+](INF|NaN)))?)" token.value);
+ isSpecial = (match "(.+(e[+](INF|NaN)))" initial) != null;
+ withoutPlus = removeStrings [ "+" ] initial;
+ withPrefix =
+ if substring 0 1 withoutPlus == "." then
+ "0" + withoutPlus
+ else if substring 0 2 withoutPlus == "-." then
+ "-0" + removeStrings [ "-" ] withoutPlus
+ else
+ withoutPlus;
+ in
if !isSpecial && withPrefix != null then
token // {
value = fromJSON withPrefix;
}
else
token
- else
- token
- ) tokens;
+ else
+ token
+ )
+ tokens;
# Convert pairs of opening and closing tokens to their
# respective collection types, i.e. lists and vectors. Also,
@@ -363,52 +367,52 @@ let
openColl = if token.type == "openParen" then "list" else if token.type == "openBracket" then "vector" else null;
closeColl = if token.type == "closeParen" then "list" else if token.type == "closeBracket" then "vector" else null;
in
- if openColl != null then
- state // {
- acc = [ [] ] ++ seq (head state.acc) state.acc;
- inColl = [ openColl ] ++ state.inColl;
- depth = state.depth + 1;
- line = [ token.line ] ++ state.line;
- }
- else if closeColl != null then
- if (head state.inColl) == closeColl then
- let
- outerColl = elemAt state.acc 1;
- currColl = {
- type = closeColl;
- value = head state.acc;
- line = head state.line;
- inherit (state) depth;
- };
- rest = tail (tail state.acc);
- in
- state // seq state.acc {
- acc = [ (outerColl ++ [ currColl ]) ] ++ rest;
- inColl = tail state.inColl;
- depth = state.depth - 1;
- line = tail state.line;
- }
- else
- throw "Unmatched ${token.type} on line ${toString token.line}"
- else if token.type == "symbol" && token.value == "nil" then
+ if openColl != null then
+ state // {
+ acc = [ [ ] ] ++ seq (head state.acc) state.acc;
+ inColl = [ openColl ] ++ state.inColl;
+ depth = state.depth + 1;
+ line = [ token.line ] ++ state.line;
+ }
+ else if closeColl != null then
+ if (head state.inColl) == closeColl then
let
- currColl = head state.acc;
- rest = tail state.acc;
- emptyList = {
- type = "list";
- depth = state.depth + 1;
- value = [];
+ outerColl = elemAt state.acc 1;
+ currColl = {
+ type = closeColl;
+ value = head state.acc;
+ line = head state.line;
+ inherit (state) depth;
};
+ rest = tail (tail state.acc);
in
- state // seq currColl { acc = [ (currColl ++ [ emptyList ]) ] ++ rest; }
+ state // seq state.acc {
+ acc = [ (outerColl ++ [ currColl ]) ] ++ rest;
+ inColl = tail state.inColl;
+ depth = state.depth - 1;
+ line = tail state.line;
+ }
else
- let
- currColl = head state.acc;
- rest = tail state.acc;
- in
- state // seq currColl { acc = [ (currColl ++ [ token ]) ] ++ rest; };
+ throw "Unmatched ${token.type} on line ${toString token.line}"
+ else if token.type == "symbol" && token.value == "nil" then
+ let
+ currColl = head state.acc;
+ rest = tail state.acc;
+ emptyList = {
+ type = "list";
+ depth = state.depth + 1;
+ value = [ ];
+ };
+ in
+ state // seq currColl { acc = [ (currColl ++ [ emptyList ]) ] ++ rest; }
+ else
+ let
+ currColl = head state.acc;
+ rest = tail state.acc;
+ in
+ state // seq currColl { acc = [ (currColl ++ [ token ]) ] ++ rest; };
in
- head (builtins.foldl' parseToken { acc = [ [] ]; inColl = [ null ]; depth = -1; line = []; } tokens).acc;
+ head (builtins.foldl' parseToken { acc = [ [ ] ]; inColl = [ null ]; depth = -1; line = [ ]; } tokens).acc;
# Handle dotted pair notation, a syntax where the car and cdr
# are represented explicitly. See
@@ -434,33 +438,35 @@ let
throw ''"Dotted pair notation"-dot outside list on line ${toString token.line}''
else if isList token.value then
let
- collectionContents = foldl' parseToken {
- acc = [];
- dotted = false;
- inList = token.type == "list";
- inherit (state) depthReduction;
- } token.value;
+ collectionContents = foldl' parseToken
+ {
+ acc = [ ];
+ dotted = false;
+ inList = token.type == "list";
+ inherit (state) depthReduction;
+ }
+ token.value;
in
- state // {
- acc = state.acc ++ (
- if state.dotted then
- collectionContents.acc
- else
- [
- (token // {
- value = collectionContents.acc;
- depth = token.depth - state.depthReduction;
- })
- ]
- );
- dotted = false;
- }
+ state // {
+ acc = state.acc ++ (
+ if state.dotted then
+ collectionContents.acc
+ else
+ [
+ (token // {
+ value = collectionContents.acc;
+ depth = token.depth - state.depthReduction;
+ })
+ ]
+ );
+ dotted = false;
+ }
else
state // {
- acc = state.acc ++ [token];
+ acc = state.acc ++ [ token ];
};
in
- (foldl' parseToken { acc = []; dotted = false; inList = false; depthReduction = 0; } tokens).acc;
+ (foldl' parseToken { acc = [ ]; dotted = false; inList = false; depthReduction = 0; } tokens).acc;
parseQuotes = tokens:
let
@@ -469,35 +475,35 @@ let
token =
if isList token'.value then
token' // {
- value = (foldl' parseToken { acc = []; quotes = []; } token'.value).acc;
+ value = (foldl' parseToken { acc = [ ]; quotes = [ ]; } token'.value).acc;
}
else
token';
in
- if elem token.type [ "quote" "expand" "slice" "backquote" "function" "record" "byteCode" ] then
- state // {
- quotes = [ token ] ++ state.quotes;
- }
- else if state.quotes != [] then
- let
- quote = value: token:
- token // {
- inherit value;
- };
- quotedValue = foldl' quote token state.quotes;
- in
- state // {
- acc = state.acc ++ [ quotedValue ];
- quotes = [];
- }
- else
- state // {
- acc = state.acc ++ [ token ];
- };
+ if elem token.type [ "quote" "expand" "slice" "backquote" "function" "record" "byteCode" ] then
+ state // {
+ quotes = [ token ] ++ state.quotes;
+ }
+ else if state.quotes != [ ] then
+ let
+ quote = value: token:
+ token // {
+ inherit value;
+ };
+ quotedValue = foldl' quote token state.quotes;
+ in
+ state // {
+ acc = state.acc ++ [ quotedValue ];
+ quotes = [ ];
+ }
+ else
+ state // {
+ acc = state.acc ++ [ token ];
+ };
in
- (foldl' parseToken { acc = []; quotes = []; } tokens).acc;
+ (foldl' parseToken { acc = [ ]; quotes = [ ]; } tokens).acc;
in
- parseQuotes (parseDots (parseCollections (parseValues tokens)));
+ parseQuotes (parseDots (parseCollections (parseValues tokens)));
parseElisp = elisp:
parseElisp' (tokenizeElisp elisp);
@@ -508,23 +514,23 @@ let
if isList object.value then
map readObject object.value
else if object.type == "quote" then
- ["quote" (readObject object.value)]
+ [ "quote" (readObject object.value) ]
else if object.type == "backquote" then
- ["`" (readObject object.value)]
+ [ "`" (readObject object.value) ]
else if object.type == "expand" then
- ["," (readObject object.value)]
+ [ "," (readObject object.value) ]
else if object.type == "slice" then
- [",@" (readObject object.value)]
+ [ ",@" (readObject object.value) ]
else if object.type == "function" then
- ["#'" (readObject object.value)]
+ [ "#'" (readObject object.value) ]
else if object.type == "byteCode" then
- ["#"] ++ (readObject object.value)
+ [ "#" ] ++ (readObject object.value)
else if object.type == "record" then
- ["#s"] ++ (readObject object.value)
+ [ "#s" ] ++ (readObject object.value)
else
object.value;
in
- map readObject ast;
+ map readObject ast;
fromElisp = elisp:
fromElisp' (parseElisp elisp);
@@ -570,135 +576,137 @@ let
force = expr: seq state.pos (seq state.line expr);
in
- if state.skip > 0 then
- state // force {
- pos = state.pos + 1;
- skip = state.skip - 1;
- line = if char == "\n" then state.line + 1 else state.line;
- leadingWhitespace = char == "\n" || (state.leadingWhitespace && elem char [ " " "\t" "\r" ]);
- }
- else if char == "#" && state.leadingWhitespace && !state.readBody && beginCodeBlock != null then
+ if state.skip > 0 then
+ state // force {
+ pos = state.pos + 1;
+ skip = state.skip - 1;
+ line = if char == "\n" then state.line + 1 else state.line;
+ leadingWhitespace = char == "\n" || (state.leadingWhitespace && elem char [ " " "\t" "\r" ]);
+ }
+ else if char == "#" && state.leadingWhitespace && !state.readBody && beginCodeBlock != null then
+ state // {
+ pos = state.pos + 1;
+ skip = (stringLength beginCodeBlock) - 1;
+ leadingWhitespace = false;
+ readLanguage = true;
+ }
+ else if char == "#" && state.leadingWhitespace && !state.readBody && header != null then
+ state // {
+ pos = state.pos + 1;
+ skip = (stringLength header) - 1;
+ leadingWhitespace = false;
+ readFlags = true;
+ }
+ else if state.readLanguage then
+ if language != null then
state // {
+ block = state.block // {
+ language = elemAt language 1;
+ };
pos = state.pos + 1;
- skip = (stringLength beginCodeBlock) - 1;
- leadingWhitespace = false;
- readLanguage = true;
- }
- else if char == "#" && state.leadingWhitespace && !state.readBody && header != null then
- state // {
- pos = state.pos + 1;
- skip = (stringLength header) - 1;
+ skip = (foldl' (total: string: total + (stringLength string)) 0 language) - 1;
leadingWhitespace = false;
+ readLanguage = false;
readFlags = true;
+ readBody = true;
}
- else if state.readLanguage then
- if language != null then
- state // {
- block = state.block // {
- language = elemAt language 1;
- };
- pos = state.pos + 1;
- skip = (foldl' (total: string: total + (stringLength string)) 0 language) - 1;
- leadingWhitespace = false;
- readLanguage = false;
- readFlags = true;
- readBody = true;
- }
- else throw "Language missing or invalid for code block on line ${toString state.line}!"
- else if state.readFlags then
- if flags != null then
- let
- parseFlag = state: item:
- let
- prefix = if isString item then substring 0 1 item else null;
- in
- if elem prefix [ ":" "-" "+" ] then
- state // {
- acc = state.acc // { ${item} = true; };
- flag = item;
- }
- else if state.flag != null then
- state // {
- acc = state.acc // { ${state.flag} = item; };
- flag = null;
- }
- else
- state;
- in
- state // {
- block = state.block // {
- flags =
- (foldl'
- parseFlag
- { acc = state.block.flags;
- flag = null;
- inherit (state) line;
- }
- (fromElisp flags)).acc;
- startLineNumber = state.line + 1;
- };
- pos = state.pos + 1;
- skip = (stringLength flags) - 1;
- line = if char == "\n" then state.line + 1 else state.line;
- leadingWhitespace = char == "\n";
- readFlags = false;
- }
- else throw "Arguments malformed for code block on line ${toString state.line}!"
- else if char == "#" && state.leadingWhitespace && endCodeBlock != null then
+ else throw "Language missing or invalid for code block on line ${toString state.line}!"
+ else if state.readFlags then
+ if flags != null then
+ let
+ parseFlag = state: item:
+ let
+ prefix = if isString item then substring 0 1 item else null;
+ in
+ if elem prefix [ ":" "-" "+" ] then
+ state // {
+ acc = state.acc // { ${item} = true; };
+ flag = item;
+ }
+ else if state.flag != null then
+ state // {
+ acc = state.acc // { ${state.flag} = item; };
+ flag = null;
+ }
+ else
+ state;
+ in
state // {
- acc = state.acc ++ [ state.block ];
- block = {
- language = null;
- body = "";
- flags = {};
+ block = state.block // {
+ flags =
+ (foldl'
+ parseFlag
+ {
+ acc = state.block.flags;
+ flag = null;
+ inherit (state) line;
+ }
+ (fromElisp flags)).acc;
+ startLineNumber = state.line + 1;
};
pos = state.pos + 1;
- skip = (stringLength endCodeBlock) - 1;
- leadingWhitespace = false;
- readBody = false;
+ skip = (stringLength flags) - 1;
+ line = if char == "\n" then state.line + 1 else state.line;
+ leadingWhitespace = char == "\n";
+ readFlags = false;
}
- else if state.readBody then
- let
- mod = state.pos / 100;
- newState = {
- block = state.block // {
- body = state.block.body + char;
- };
- inherit mod;
- pos = state.pos + 1;
- line = if char == "\n" then state.line + 1 else state.line;
- leadingWhitespace = char == "\n" || (state.leadingWhitespace && elem char [ " " "\t" "\r" ]);
+ else throw "Arguments malformed for code block on line ${toString state.line}!"
+ else if char == "#" && state.leadingWhitespace && endCodeBlock != null then
+ state // {
+ acc = state.acc ++ [ state.block ];
+ block = {
+ language = null;
+ body = "";
+ flags = { };
+ };
+ pos = state.pos + 1;
+ skip = (stringLength endCodeBlock) - 1;
+ leadingWhitespace = false;
+ readBody = false;
+ }
+ else if state.readBody then
+ let
+ mod = state.pos / 100;
+ newState = {
+ block = state.block // {
+ body = state.block.body + char;
};
- in
- if mod > state.mod then
- state // seq state.block.body (force newState)
- else
- state // newState
- else
- state // force {
+ inherit mod;
pos = state.pos + 1;
line = if char == "\n" then state.line + 1 else state.line;
leadingWhitespace = char == "\n" || (state.leadingWhitespace && elem char [ " " "\t" "\r" ]);
};
- in
- (foldl'
- parseToken
- { acc = [];
- mod = 0;
- pos = 0;
- skip = 0;
- line = 1;
- block = {
- language = null;
- body = "";
- flags = {};
+ in
+ if mod > state.mod then
+ state // seq state.block.body (force newState)
+ else
+ state // newState
+ else
+ state // force {
+ pos = state.pos + 1;
+ line = if char == "\n" then state.line + 1 else state.line;
+ leadingWhitespace = char == "\n" || (state.leadingWhitespace && elem char [ " " "\t" "\r" ]);
};
- leadingWhitespace = true;
- readLanguage = false;
- readFlags = false;
- readBody = false;
- }
- (stringToCharacters text)).acc;
+ in
+ (foldl'
+ parseToken
+ {
+ acc = [ ];
+ mod = 0;
+ pos = 0;
+ skip = 0;
+ line = 1;
+ block = {
+ language = null;
+ body = "";
+ flags = { };
+ };
+ leadingWhitespace = true;
+ readLanguage = false;
+ readFlags = false;
+ readBody = false;
+ }
+ (stringToCharacters text)).acc;
# Run tokenizeElisp' on all Elisp code blocks (with `:tangle yes`
# set) from an Org mode babel text. If the block doesn't have a
@@ -712,19 +720,19 @@ let
tangle = toLower (block.flags.":tangle" or defaultArgs.":tangle" or "no");
language = toLower block.language;
in
- elem language [ "elisp" "emacs-lisp" ]
- && elem tangle [ "yes" ''"yes"'' ])
+ elem language [ "elisp" "emacs-lisp" ]
+ && elem tangle [ "yes" ''"yes"'' ])
(parseOrgModeBabel text);
- in
- foldl'
- (result: codeBlock:
- result ++ (tokenizeElisp' {
- elisp = codeBlock.body;
- inherit (codeBlock) startLineNumber;
- })
- )
- []
- codeBlocks;
+ in
+ foldl'
+ (result: codeBlock:
+ result ++ (tokenizeElisp' {
+ elisp = codeBlock.body;
+ inherit (codeBlock) startLineNumber;
+ })
+ )
+ [ ]
+ codeBlocks;
tokenizeOrgModeBabelElisp =
tokenizeOrgModeBabelElisp' {
diff --git a/nix/factory.nix b/nix/factory.nix
index 34ddef5..d72e13f 100644
--- a/nix/factory.nix
+++ b/nix/factory.nix
@@ -13,10 +13,15 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-{ lib, stdenv, emacs29, callPackage, writeShellApplication, noether
-, emacsParams ? {},
- fg42Params ? {}
-} :
+{ lib
+, stdenv
+, emacs29
+, callPackage
+, writeShellApplication
+, noether
+, emacsParams ? { }
+, fg42Params ? { }
+}:
let
lemacs = emacs29.override ({
withTreeSitter = true;
@@ -44,7 +49,8 @@ let
runtimeInputs = [ fg42 ];
text = ''
- DISPLAY=:1 ${fg42}/bin/fg42-wm
+ DISPLAY=:1 ${fg42}/bin/fg42-wm
'';
};
-in { inherit fg42 run-test-wm; }
+in
+{ inherit fg42 run-test-wm; }
diff --git a/nix/fg42.nix b/nix/fg42.nix
index f70179d..97c126d 100644
--- a/nix/fg42.nix
+++ b/nix/fg42.nix
@@ -13,21 +13,49 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
-{ lib, stdenv, elispPkgs, srcDir, emacsPackagesFor, ourPackages, direnv
-, makeFontsConf, nix, nixpkgs-fmt
-, nil, # nix lsp server
+{ lib
+, stdenv
+, elispPkgs
+, srcDir
+, emacsPackagesFor
+, ourPackages
+, direnv
+, makeFontsConf
+, nix
+, nixpkgs-fmt
+, nil
+, # nix lsp server
# python deps
- python311, python3Packages,
- # This is a set of system tools required for FG42
+ python311
+, python3Packages
+, # This is a set of system tools required for FG42
# to work.
- pyright, emacs, ripgrep, git, texinfo, vazir-fonts, fira-code, nerdfonts
-, fira-mono, noto-fonts, gcc, ltex-ls, bash, tree-sitter, fd
-, aspellWithDicts,
-
- supportWM ? true, xorg, slock,
-
- supportPython ? true, supportVerilog ? true, svls, verilator, }:
+ pyright
+, emacs
+, ripgrep
+, git
+, texinfo
+, vazir-fonts
+, fira-code
+, nerdfonts
+, fira-mono
+, noto-fonts
+, gcc
+, ltex-ls
+, bash
+, tree-sitter
+, fd
+, aspellWithDicts
+, supportWM ? true
+, xorg
+, slock
+, supportPython ? true
+, supportVerilog ? true
+, svls
+, verilator
+,
+}:
with builtins;
let
version = "4.0.0";
@@ -43,7 +71,15 @@ let
dicts = aspellWithDicts (dicts: with dicts; [ en en-computers en-science ]);
runtimeBins = [
- ripgrep git tree-sitter direnv nix nil dicts fd nixpkgs-fmt
+ ripgrep
+ git
+ tree-sitter
+ direnv
+ nix
+ nil
+ dicts
+ fd
+ nixpkgs-fmt
]
++ (lib.optional (!stdenv.buildPlatform.isRiscV) [
# Not supported on Risc-V
@@ -83,7 +119,8 @@ let
];
};
-in stdenv.mkDerivation (final: rec {
+in
+stdenv.mkDerivation (final: rec {
inherit version;
pname = "fg42";
src = srcDir;
diff --git a/nix/maintainers.nix b/nix/maintainers.nix
index 35f0561..28f8ced 100644
--- a/nix/maintainers.nix
+++ b/nix/maintainers.nix
@@ -18,7 +18,7 @@
lxsameer = {
email = "lxsameer@lxsameer.com";
github = "lxsameer";
- git = "lxsameer";
+ git = "lxsameer";
matrix = "@lxsameer:matrix.org";
name = "Sameer Rahmani";
keys = [{
diff --git a/nix/parse.nix b/nix/parse.nix
index 0edb263..30db3ff 100644
--- a/nix/parse.nix
+++ b/nix/parse.nix
@@ -22,76 +22,77 @@ let
(x: builtins.typeOf x == "string")
(builtins.split _sep _s);
-in {
- elispStr
+in
+{ elispStr
, alwaysEnsure ? false
}:
- let
- inherit (import ./elisp_reader.nix { inherit lib; }) fromElisp;
+let
+ inherit (import ./elisp_reader.nix { inherit lib; }) fromElisp;
- readFunction = fromElisp;
- find = item: list:
- if list == [] then [] else
- if builtins.head list == item then
- list
- else
- find item (builtins.tail list);
+ readFunction = fromElisp;
+ find = item: list:
+ if list == [ ] then [ ] else
+ if builtins.head list == item then
+ list
+ else
+ find item (builtins.tail list);
- getKeywordValue = keyword: list:
+ getKeywordValue = keyword: list:
+ let
+ keywordList = find keyword list;
+ in
+ if keywordList != [ ] then
let
- keywordList = find keyword list;
+ keywordValue = builtins.tail keywordList;
in
- if keywordList != [] then
- let
- keywordValue = builtins.tail keywordList;
- in
- if keywordValue != [] then
- builtins.head keywordValue
- else
- true
- else
- null;
-
- isDisabled = item:
- let
- disabledValue = getKeywordValue ":disabled" item;
- in
- if disabledValue == [] then
- false
- else if builtins.isBool disabledValue then
- disabledValue
- else if builtins.isString disabledValue then
- true
- else
- false;
-
- getName = item:
- let
- ensureValue = getKeywordValue ":ensure" item;
- usePackageName = builtins.head (builtins.tail item);
- in
- if builtins.isString ensureValue then
- if lib.hasPrefix ":" ensureValue then
- usePackageName
- else
- ensureValue
- else if ensureValue == true || (ensureValue == null && alwaysEnsure) then
- usePackageName
- else
- [];
-
- recurse = item:
- if builtins.isList item && item != [] then
- let
- packageManager = builtins.head item;
- in
- if builtins.elem packageManager [ "depends-on" ] then
- if !(isDisabled item) then
- [ packageManager (getName item) ] ++ map recurse item
- else
- []
- else
- map recurse item
+ if keywordValue != [ ] then
+ builtins.head keywordValue
else
- [];
- in lib.flatten (map recurse (readFunction elispStr))
+ true
+ else
+ null;
+
+ isDisabled = item:
+ let
+ disabledValue = getKeywordValue ":disabled" item;
+ in
+ if disabledValue == [ ] then
+ false
+ else if builtins.isBool disabledValue then
+ disabledValue
+ else if builtins.isString disabledValue then
+ true
+ else
+ false;
+
+ getName = item:
+ let
+ ensureValue = getKeywordValue ":ensure" item;
+ usePackageName = builtins.head (builtins.tail item);
+ in
+ if builtins.isString ensureValue then
+ if lib.hasPrefix ":" ensureValue then
+ usePackageName
+ else
+ ensureValue
+ else if ensureValue == true || (ensureValue == null && alwaysEnsure) then
+ usePackageName
+ else
+ [ ];
+
+ recurse = item:
+ if builtins.isList item && item != [ ] then
+ let
+ packageManager = builtins.head item;
+ in
+ if builtins.elem packageManager [ "depends-on" ] then
+ if !(isDisabled item) then
+ [ packageManager (getName item) ] ++ map recurse item
+ else
+ [ ]
+ else
+ map recurse item
+ else
+ [ ];
+in
+lib.flatten (map recurse (readFunction elispStr))