Merge branch 'master' into master

This commit is contained in:
pouya-abbassi 2024-04-12 09:04:06 +01:00
commit 963dd42db4
16 changed files with 676 additions and 579 deletions

View File

@ -41,8 +41,9 @@
};
noether = inputs.noether.outputs.packages.${system}.default;
factory = params: pkgs.callPackage ./nix/factory.nix ({ inherit noether; } // params);
default = (factory {});
in {
default = (factory { });
in
{
packages = {
default = default.fg42;
} // (pkgs.lib.optionalAttrs (system == "x86_64-linux") {
@ -58,7 +59,21 @@
nativeBuildInputs = [ default.fg42 pkgs.fish test-x default.run-test-wm ];
buildInputs = [ default.fg42 ];
};
apps.wm = {
type = "app";
program = "${default.run-test-wm}/bin/run-test-wm";
};
apps.x = {
type = "app";
program = "${test-x}/bin/test-x";
};
apps.default = {
type = "app";
program = "${default.fg42}/bin/fg42";
};
};
};
}

View File

@ -124,7 +124,8 @@
forge
svg-tag-mode
base16-theme
consult)
consult
nerd-icons-completion)
(provide 'fg42/deps)
;;; deps.el ends here

View File

@ -26,6 +26,7 @@
;; Language support
(require 'fg42/autocomplete)
(require 'fg42/langs/langs)
(require 'fg42/eglot)
(require 'fg42/langs/cpp)
(require 'fg42/langs/verilog)
(require 'fg42/langs/python)
@ -198,12 +199,6 @@ contextual information."
"Yasnippet's snippets."
:after yasnippet)
;; Language Servers and friends
(use! eglot
"Eglot is a minimalistic yet powerful LSP replacement
shipped with Emacs."
:commands eglot
:autoload eglot-ensure)
(use! flycheck
"Flycheck is a modern on-the-fly syntax checking extension for GNU Emacs."

39
lisp/fg42/eglot.el Normal file
View File

@ -0,0 +1,39 @@
;;; 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))
;; Language Servers and friends
(use! eglot
"Eglot is a minimalistic yet powerful LSP replacement
shipped with Emacs."
:hook
(prog-mode . eglot-ensure)
(prog-mode . (lambda ()
(add-hook 'before-save-hook 'eglot-format nil t))))
(provide 'fg42/eglot)
;;; eglot.el ends here

View File

@ -24,13 +24,26 @@
(eval-when-compile
(require 'fpkg))
(use! nix-mode
"Nix language support for Emacs."
:mode "\\.nix\\'"
:hook
(nix-mode . eglot-ensure)
(nix-mode . company-mode)
(nix-mode . flyspell-prog-mode))
(nix-mode . flyspell-prog-mode)
:init
:config
(with-eval-after-load 'eglot
;; Force nil to use nixpkgs-fmt for formatting
(let ((nil-lsp '(nix-mode . ("nil"
:initializationOptions
(:formatting (:command ["nixpkgs-fmt"]))))))
(add-to-list 'eglot-server-programs nil-lsp))))
(provide 'fg42/langs/nix)
;;; nix.el ends here

View File

@ -196,5 +196,14 @@ match all of the components in any order."
:bind (("M-g e" . consult-compile-error)))
(use! nerd-icons-completion
"Nerd icons in marginalia"
:after marginalia
:config
(nerd-icons-completion-mode)
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup))
(provide 'fg42/minibuffer)
;;; minibuffer.el ends here

View File

@ -58,6 +58,7 @@ to Emacs modeline."
:commands noether-global-mode
:config
(require 'noether-views)
(require 'fg42/modeline/views)
(let ((active-border (get-base16-color-or :base0A "#bd93f9"))
(inactive-border (get-base16-color-or :base03 "#44475a")))
@ -73,14 +74,11 @@ to Emacs modeline."
(if fg42/modeline-inactive-face fg42/modeline-inactive-face 'fg42/-disabled-modeline-dective-border)
(default-value 'face-remapping-alist) face-remaps))
;; Setup modelines
(when-not-wm
(require 'fg42/modeline/views)
(when-not-wm
(setq-default noether-views (list fg42/modeline))))
(setq-default noether-views (list fg42/modeline)))
(when-wm
(setq-default noether-views (list fg42/minimal-exwm))))
(setq-default noether-views nil)))
(provide 'fg42/modeline)
;;; modeline.el ends here

View File

@ -64,9 +64,12 @@
"Set the EXWM input mode for the current buffer."
(setq fg42/-exwm-input-mode (format "%s" exwm--input-mode)))
(defun fg42/-format-exwm-input-mode (_ v _ _)
"Just return the input mode name V."
v)
(if (=string v "line")
(propertize "L" 'font-lock-face `(:foreground ,(get-base16-color-or :base07 "eeeeec")))
(propertize "C" 'font-lock-face `(:foreground ,(get-base16-color-or :base0A "eeeeec")))))
(noether-defunit fg42/exwm-input-mode-unit

View File

@ -31,6 +31,10 @@
"Keep the modeline at bottom right by using the data from INFO."
(cons -1 -1))
(defun fg42/--bottom-right-padded (info)
"Keep the modeline at bottom right by using the data from INFO."
(cons -70 -1))
(defun fg42/adjust-modeline (view)
"Adjust the VIEW after parent frame resize."
@ -58,7 +62,6 @@
(buffer-name-unit
:label (format "%s " (nerd-icons-codicon "nf-cod-layers"))
:len 20)
;; (mode-name-unit :label " " :len 4)
(projectile-project-unit
:label (format "%s " (nerd-icons-octicon "nf-oct-project"))
:len 20)
@ -66,31 +69,33 @@
:label (format "%s " (nerd-icons-devicon "nf-dev-git_branch"))
:len 20)
(fg42/mode-icon)
(line-unit :label (format "%s " (nerd-icons-codicon "nf-cod-location")))))
(line-unit :label (format "%s " (nerd-icons-codicon "nf-cod-location")))
(time-unit :label (format " %s " (nerd-icons-mdicon "nf-md-clock_time_three")))))
(when-wm
(noether-defview fg42/minimal-exwm
(noether-defview fg42/minimal-exwm
"A super simple bar containing the line number and column number that
Appears on the center of the current window."
:managed? t
:buffer "*exwm-status*"
:binding (kbd "C-c 3")
:separator "|"
:binding (kbd "C-c 1")
:separator " | "
:timeout 10
:frame
(list
;; Such a big numbers for X and Y will cause the frame to appear on the
;; bottom right corner and covering the minibuffer
:position '(-30 . -1)
:poshandler #'fg42/--bottom-right-padded
:border-width 0
:timeout 5
:border-color "#bd93f9")
:units
(list
(fg42/exwm-input-mode-unit :label "")
(buffer-name-unit :label "")
(time-unit :label ""))))
(fg42/exwm-input-mode-unit :label (format "%s " (nerd-icons-faicon "nf-fa-linux")))
(buffer-name-unit
:label (format "%s " (nerd-icons-codicon "nf-cod-layers"))
:len 30)
(time-unit :label (format "%s " (nerd-icons-mdicon "nf-md-clock_time_three")))))
(provide 'fg42/modeline/views)

View File

@ -13,14 +13,15 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
{ pkgs, 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
elispPkgs =
if length dependsOnForm == 0
then throw "Can't find the form 'depends-on' on 'deps.el'"
else tail (head dependsOnForm);
in elispPkgs
in
elispPkgs

View File

@ -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/>.
{ 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}
'';
}

View File

@ -73,7 +73,8 @@ let
matchSymbol =
let
symbolChar = ''([^${notInSymbol}]|\\.)'';
in mkMatcher ''(${symbolChar}+)([${notInSymbol}]|$).*'' symbolMaxLength;
in
mkMatcher ''(${symbolChar}+)([${notInSymbol}]|$).*'' symbolMaxLength;
maxTokenLength = foldl' max 0 [
commentMaxLength
@ -291,7 +292,8 @@ let
}
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;
in
(builtins.foldl' readToken { acc = [ ]; pos = 0; skip = 0; line = startLineNumber; mod = 0; } (stringToCharacters elisp)).acc;
tokenizeElisp = elisp:
tokenizeElisp' { inherit elisp; };
@ -302,14 +304,15 @@ let
# Convert literal value tokens in a flat list to their
# corresponding nix representation.
parseValues = tokens:
map (token:
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);
value = fromJSON (removeStrings [ "+" "." ] token.value);
}
else if token.type == "symbol" && token.value == "t" then
token // {
@ -319,12 +322,12 @@ let
let
initial = head (match "([+-]?([[:digit:]]*[.])?[[:digit:]]+(e([+-]?[[:digit:]]+|[+](INF|NaN)))?)" token.value);
isSpecial = (match "(.+(e[+](INF|NaN)))" initial) != null;
withoutPlus = removeStrings ["+"] initial;
withoutPlus = removeStrings [ "+" ] initial;
withPrefix =
if substring 0 1 withoutPlus == "." then
"0" + withoutPlus
else if substring 0 2 withoutPlus == "-." then
"-0" + removeStrings ["-"] withoutPlus
"-0" + removeStrings [ "-" ] withoutPlus
else
withoutPlus;
in
@ -336,7 +339,8 @@ let
token
else
token
) tokens;
)
tokens;
# Convert pairs of opening and closing tokens to their
# respective collection types, i.e. lists and vectors. Also,
@ -365,7 +369,7 @@ let
in
if openColl != null then
state // {
acc = [ [] ] ++ seq (head state.acc) state.acc;
acc = [ [ ] ] ++ seq (head state.acc) state.acc;
inColl = [ openColl ] ++ state.inColl;
depth = state.depth + 1;
line = [ token.line ] ++ state.line;
@ -397,7 +401,7 @@ let
emptyList = {
type = "list";
depth = state.depth + 1;
value = [];
value = [ ];
};
in
state // seq currColl { acc = [ (currColl ++ [ emptyList ]) ] ++ rest; }
@ -408,7 +412,7 @@ let
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,12 +438,14 @@ let
throw ''"Dotted pair notation"-dot outside list on line ${toString token.line}''
else if isList token.value then
let
collectionContents = foldl' parseToken {
acc = [];
collectionContents = foldl' parseToken
{
acc = [ ];
dotted = false;
inList = token.type == "list";
inherit (state) depthReduction;
} token.value;
}
token.value;
in
state // {
acc = state.acc ++ (
@ -457,10 +463,10 @@ let
}
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,7 +475,7 @@ 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';
@ -478,7 +484,7 @@ let
state // {
quotes = [ token ] ++ state.quotes;
}
else if state.quotes != [] then
else if state.quotes != [ ] then
let
quote = value: token:
token // {
@ -488,14 +494,14 @@ let
in
state // {
acc = state.acc ++ [ quotedValue ];
quotes = [];
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)));
@ -508,19 +514,19 @@ 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
@ -630,7 +636,8 @@ let
flags =
(foldl'
parseFlag
{ acc = state.block.flags;
{
acc = state.block.flags;
flag = null;
inherit (state) line;
}
@ -650,7 +657,7 @@ let
block = {
language = null;
body = "";
flags = {};
flags = { };
};
pos = state.pos + 1;
skip = (stringLength endCodeBlock) - 1;
@ -683,7 +690,8 @@ let
in
(foldl'
parseToken
{ acc = [];
{
acc = [ ];
mod = 0;
pos = 0;
skip = 0;
@ -691,7 +699,7 @@ let
block = {
language = null;
body = "";
flags = {};
flags = { };
};
leadingWhitespace = true;
readLanguage = false;
@ -723,7 +731,7 @@ let
inherit (codeBlock) startLineNumber;
})
)
[]
[ ]
codeBlocks;
tokenizeOrgModeBabelElisp =

View File

@ -13,10 +13,15 @@
#
# 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, stdenv, emacs29, callPackage, writeShellApplication, noether
, emacsParams ? {},
fg42Params ? {}
} :
{ lib
, stdenv
, emacs29
, callPackage
, writeShellApplication
, noether
, emacsParams ? { }
, fg42Params ? { }
}:
let
lemacs = emacs29.override ({
withTreeSitter = true;
@ -47,4 +52,5 @@ let
DISPLAY=:1 ${fg42}/bin/fg42-wm
'';
};
in { inherit fg42 run-test-wm; }
in
{ inherit fg42 run-test-wm; }

View File

@ -13,22 +13,49 @@
#
# 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, stdenv, elispPkgs, srcDir, emacsPackagesFor, ourPackages, direnv
, makeFontsConf, nix
, 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";
@ -44,7 +71,15 @@ let
dicts = aspellWithDicts (dicts: with dicts; [ en en-computers en-science ]);
runtimeBins = [
ripgrep git tree-sitter direnv nix nil dicts fd
ripgrep
git
tree-sitter
direnv
nix
nil
dicts
fd
nixpkgs-fmt
]
++ (lib.optional (!stdenv.buildPlatform.isRiscV) [
# Not supported on Risc-V
@ -84,7 +119,8 @@ let
];
};
in stdenv.mkDerivation (final: rec {
in
stdenv.mkDerivation (final: rec {
inherit version;
pname = "fg42";
src = srcDir;

View File

@ -22,16 +22,16 @@ let
(x: builtins.typeOf x == "string")
(builtins.split _sep _s);
in {
elispStr
in
{ elispStr
, alwaysEnsure ? false
}:
let
let
inherit (import ./elisp_reader.nix { inherit lib; }) fromElisp;
readFunction = fromElisp;
find = item: list:
if list == [] then [] else
if list == [ ] then [ ] else
if builtins.head list == item then
list
else
@ -41,11 +41,11 @@ in {
let
keywordList = find keyword list;
in
if keywordList != [] then
if keywordList != [ ] then
let
keywordValue = builtins.tail keywordList;
in
if keywordValue != [] then
if keywordValue != [ ] then
builtins.head keywordValue
else
true
@ -56,7 +56,7 @@ in {
let
disabledValue = getKeywordValue ":disabled" item;
in
if disabledValue == [] then
if disabledValue == [ ] then
false
else if builtins.isBool disabledValue then
disabledValue
@ -78,10 +78,10 @@ in {
else if ensureValue == true || (ensureValue == null && alwaysEnsure) then
usePackageName
else
[];
[ ];
recurse = item:
if builtins.isList item && item != [] then
if builtins.isList item && item != [ ] then
let
packageManager = builtins.head item;
in
@ -89,9 +89,10 @@ in {
if !(isDisabled item) then
[ packageManager (getName item) ] ++ map recurse item
else
[]
[ ]
else
map recurse item
else
[];
in lib.flatten (map recurse (readFunction elispStr))
[ ];
in
lib.flatten (map recurse (readFunction elispStr))