Compare commits

...

57 Commits
v4.1 ... master

Author SHA1 Message Date
Sameer Rahmani f2e5440509
Activate all the packages (autoloads only). Closes #5 2024-05-20 19:13:15 +01:00
Sameer Rahmani 25bd1636c9
Add support for Haskell 2024-05-20 19:12:39 +01:00
Sameer Rahmani 701d2ec9d8
Replace cmake-ts-mode with cmake-mode
cmake-ts-mode is not mature enough yet.
2024-05-18 15:34:49 +01:00
Sameer Rahmani dda0f8ec92
Disable exwm modeline again. Sticky mode issue 2024-05-12 12:02:43 +01:00
Sameer Rahmani f113baa3e7
Make the exwm modeline minibuffer aware 2024-05-11 22:55:23 +01:00
Sameer Rahmani 92209e9e33
Remove the debug exprs from WM 2024-05-10 18:26:10 +01:00
Sameer Rahmani bbc0fad735
Remove the v3 related code 2024-05-10 18:22:31 +01:00
Sameer Rahmani b22eb08970
Disable the perspective mode on WM 2024-05-10 17:58:32 +01:00
Sameer Rahmani 26932adb9f
Update the window manager configuration order 2024-05-10 17:55:13 +01:00
Sameer Rahmani 29546f2b2a
Revert back to the previous nixpkgs version 2024-05-10 17:31:23 +01:00
Sameer Rahmani b5257f57d3
Add openssh as runtime dependency for the git module 2024-05-09 22:17:24 +01:00
Sameer Rahmani fa99f3b79c
Update the deps and the lock file 2024-05-09 22:13:06 +01:00
Sameer Rahmani 697ccf839c
Add document-viewer to the list of modules 2024-05-09 22:12:51 +01:00
Sameer Rahmani 1d702f610d
Add the transient lib to the editor 2024-05-09 22:12:31 +01:00
Sameer Rahmani 4ebf0810fe
Fix the citar and citar-embark loading issue 2024-05-09 22:11:55 +01:00
Sameer Rahmani aed2db4e48
Fix the derivation to properly use the PATH envvar 2024-05-09 22:10:58 +01:00
Sameer Rahmani 4b57b9cce7
Add a basic pdftools support 2024-05-07 19:51:45 +01:00
Sameer Rahmani e6df84a93a
Add a basic vterm support 2024-05-07 19:42:25 +01:00
Sameer Rahmani 03ea5ee8eb
Fix the org-capture default template levels 2024-05-07 18:54:16 +01:00
Sameer Rahmani 637a446daa
Remove the grid mode from vertico file mode 2024-05-07 18:36:55 +01:00
Sameer Rahmani 511467c1af
Improve the organize setup with org-roam 2024-05-07 18:15:12 +01:00
Sameer Rahmani 31271e90fc
Add a very basic embark support 2024-05-07 14:13:02 +01:00
Sameer Rahmani aeb4f1a6a2
Fix diff-hl to load at startup 2024-05-06 14:57:18 +01:00
Pouya Abbassi c8991a7868 move mode configs to their use-package, linting 2024-05-03 15:56:32 +01:00
Pouya Abbassi 6f55228872 Add Pouya to maintainers 2024-05-03 15:56:32 +01:00
Pouya Abbassi d94cf44762 Remove unnecessary code from Clojure module. 2024-05-03 15:56:32 +01:00
Pouya Abbassi 1e3c4be3a2 Add clojure-ts-mode with support for LSP 2024-05-03 15:56:32 +01:00
Sameer Rahmani d0ee179dc9
Extract organize into its own module and add org-roam 2024-05-02 21:08:37 +01:00
Sameer Rahmani 9453925e34
Map perspective mode to 'C-c w' to make room for rg's 'C-c p s' 2024-05-02 12:57:59 +01:00
Sameer Rahmani 5ebb68c2ef
Remove projectile to replace it with project.el 2024-05-02 12:48:10 +01:00
Sameer Rahmani b4162580da
Add a very basic rss module 2024-05-01 22:37:39 +01:00
Sameer Rahmani 5587149c09
Add a very basic workspace module using perspective.el 2024-05-01 20:54:30 +01:00
Sameer Rahmani 3f39847600
Add the beacon mode 2024-05-01 14:37:01 +01:00
Sameer Rahmani b6e6158df7
Change tempel-insert binding to M-= 2024-05-01 14:31:06 +01:00
Sameer Rahmani 7cd44271c1
Add tempel as the yasnippet replacement 2024-05-01 14:17:51 +01:00
Sameer Rahmani cd6cecdbbb
Remove yasnippet completely 2024-05-01 12:42:12 +01:00
Sameer Rahmani 4b6ca4a90e
Add support for [system]verilog 2024-05-01 11:18:14 +01:00
Sameer Rahmani a27f2bb795
Add the missing imports to the python and c-family modules 2024-04-30 21:59:02 +01:00
Sameer Rahmani 601d66c8b1
Add the maintainer and the doc config to most of the modules 2024-04-30 21:50:51 +01:00
Sameer Rahmani 81d82af796
Centeralize the lang server and buffer format setup using generic functions 2024-04-30 21:48:10 +01:00
Sameer Rahmani 01e9fbdf46
Create the a generic fn to let lisp modules override the language server behaviour 2024-04-30 19:34:48 +01:00
Sameer Rahmani a8f94e667f
Fix the remaining fg42/config= ref 2024-04-30 17:33:42 +01:00
Sameer Rahmani 741bb46566
Unify the fg42/config macros to follow the same naming convention 2024-04-30 17:14:11 +01:00
Sameer Rahmani 1531f31d62
Rename the old fg42/autocomplete function to its new name 2024-04-30 17:10:20 +01:00
Sameer Rahmani 63b5a3d8cf
Add cape alongside corfu 2024-04-30 16:52:09 +01:00
Sameer Rahmani a5305dec8b
Setup corfu indexed to work similar to company mode 2024-04-30 15:01:57 +01:00
Sameer Rahmani e67e3fbe1f
Add the meta.maintainers and meta.doc options in the unit module 2024-04-30 12:29:47 +01:00
Sameer Rahmani 73f574795a
Fix the fg42/config-when macro 2024-04-30 11:31:05 +01:00
Sameer Rahmani a163cdc33e
Add corfu as the main completion framework 2024-04-30 10:58:18 +01:00
Sameer Rahmani a9b7a40473
Make vertico available on the WM but not consult 2024-04-29 13:59:14 +01:00
Sameer Rahmani 09e32cc5a5
Replace vertico with fido on WM mode 2024-04-29 12:50:03 +01:00
Sameer Rahmani 9342a251d7
Disable noether on exwm 2024-04-28 20:31:40 +01:00
Sameer Rahmani edcf6b9b0a
Disable any other completion backend beside capf 2024-04-28 20:30:23 +01:00
Sameer Rahmani 87c5b868db
Improve the "try!" macro by embedding use-package 2024-04-28 19:18:05 +01:00
Sameer Rahmani b6abd6fce9
Add support for installing packages temporarily via Nix.
This patch creates a new macro on fpkg called `try!` which
is similar to `use!` but only for the running session.
2024-04-28 19:06:45 +01:00
Sameer Rahmani 5f2662ded6
Add the fg42-version 2024-04-19 21:04:52 +01:00
Sameer Rahmani 259379d20d
Include the wm module on the default package as well 2024-04-19 20:53:51 +01:00
88 changed files with 2015 additions and 3857 deletions

View File

@ -3,28 +3,30 @@
"emacs-overlay": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"nixpkgs": [
"nixpkgs"
],
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1707815184,
"narHash": "sha256-WFoDXgaPdhjgQB3ut+ZN+VT7e60Yw+KUyvUkOSu5Wto=",
"lastModified": 1715274454,
"narHash": "sha256-QnQwZXWFE9fj1Y/0DZPRcVQIY/J8ejP6QtWd5QhMpQ8=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "0f7f3b39157419f3035a2dad39fbaf8a4ba0448d",
"rev": "c6e7308733e76548d10615d74669919a243e93c8",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "0f7f3b39157419f3035a2dad39fbaf8a4ba0448d",
"rev": "c6e7308733e76548d10615d74669919a243e93c8",
"type": "github"
}
},
"emacs-overlay_2": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_3",
"nixpkgs": "nixpkgs_2",
"nixpkgs-stable": "nixpkgs-stable_2"
},
"locked": {
@ -47,11 +49,11 @@
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1712014858,
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
"lastModified": 1714641030,
"narHash": "sha256-yzcRNDoyVP7+SCNX0wmuDju1NUCt8Dz9+lyUXEI0dbI=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
"rev": "e5d10a24b66c3ea8f150e47dfdb0416ab7c3390e",
"type": "github"
},
"original": {
@ -83,11 +85,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"lastModified": 1710146030,
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
"type": "github"
},
"original": {
@ -116,36 +118,30 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1707689078,
"narHash": "sha256-UUGmRa84ZJHpGZ1WZEBEUOzaPOWG8LZ0yPg1pdDF/yM=",
"lastModified": 1707451808,
"narHash": "sha256-UwDBUNHNRsYKFJzyTMVMTF5qS4xeJlWoeyJf+6vvamU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f9d39fb9aff0efee4a3d5f4a6d7c17701d38a1d8",
"rev": "442d407992384ed9c0e6d352de75b69079904e4e",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"rev": "442d407992384ed9c0e6d352de75b69079904e4e",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"dir": "lib",
"lastModified": 1711703276,
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
"type": "github"
"lastModified": 1714640452,
"narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz"
},
"original": {
"dir": "lib",
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz"
}
},
"nixpkgs-lib_2": {
@ -168,11 +164,11 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1707650010,
"narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=",
"lastModified": 1715106579,
"narHash": "sha256-gZMgKEGiK6YrwGBiccZ1gemiUwjsZ1Zv49KYOgmX2fY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6",
"rev": "8be0d8a1ed4f96d99b09aa616e2afd47acc3da89",
"type": "github"
},
"original": {
@ -199,22 +195,6 @@
}
},
"nixpkgs_2": {
"locked": {
"lastModified": 1707451808,
"narHash": "sha256-UwDBUNHNRsYKFJzyTMVMTF5qS4xeJlWoeyJf+6vvamU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "442d407992384ed9c0e6d352de75b69079904e4e",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "442d407992384ed9c0e6d352de75b69079904e4e",
"type": "github"
}
},
"nixpkgs_3": {
"locked": {
"lastModified": 1707689078,
"narHash": "sha256-UUGmRa84ZJHpGZ1WZEBEUOzaPOWG8LZ0yPg1pdDF/yM=",
@ -230,39 +210,25 @@
"type": "github"
}
},
"nixpkgs_4": {
"locked": {
"lastModified": 1707451808,
"narHash": "sha256-UwDBUNHNRsYKFJzyTMVMTF5qS4xeJlWoeyJf+6vvamU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "442d407992384ed9c0e6d352de75b69079904e4e",
"type": "github"
},
"original": {
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "442d407992384ed9c0e6d352de75b69079904e4e",
"type": "github"
}
},
"noether": {
"inputs": {
"emacs-overlay": "emacs-overlay_2",
"flake-parts": "flake-parts_2",
"nixpkgs": "nixpkgs_4"
"nixpkgs": [
"nixpkgs"
]
},
"locked": {
"lastModified": 1713553841,
"narHash": "sha256-k0p6s7cbN3cAeOBeTpIaFWbHhma+yNisC7HwAo4aDuA=",
"ref": "refs/tags/v0.1.10",
"rev": "8164261df59f6a31cbbd72b19777b1023aa38448",
"revCount": 52,
"lastModified": 1715464233,
"narHash": "sha256-VPhsO6yVPq1h0pI+tBnH+/JCDWUZVaFrPy782dOmu2c=",
"ref": "refs/tags/v0.3.0",
"rev": "5c40c1a5783b0904fb106bd6cc70671e7b1e7320",
"revCount": 57,
"type": "git",
"url": "https://devheroes.codes/lxsameer/noether"
},
"original": {
"ref": "refs/tags/v0.1.10",
"ref": "refs/tags/v0.3.0",
"type": "git",
"url": "https://devheroes.codes/lxsameer/noether"
}
@ -271,7 +237,7 @@
"inputs": {
"emacs-overlay": "emacs-overlay",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_2",
"nixpkgs": "nixpkgs",
"noether": "noether"
}
},

View File

@ -17,9 +17,16 @@
description = "FG42 - Emacs Editor for advance users";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/442d407992384ed9c0e6d352de75b69079904e4e";
inputs.noether.url = "git+https://devheroes.codes/lxsameer/noether?ref=refs/tags/v0.1.10";
inputs.noether = {
url = "git+https://devheroes.codes/lxsameer/noether?ref=refs/tags/v0.3.0";
inputs.nixpkgs.follows = "nixpkgs";
};
inputs.emacs-overlay = {
url = "github:nix-community/emacs-overlay/c6e7308733e76548d10615d74669919a243e93c8"; #"github:nix-community/emacs-overlay/0f7f3b39157419f3035a2dad39fbaf8a4ba0448d";
inputs.nixpkgs.follows = "nixpkgs";
};
inputs.emacs-overlay.url = "github:nix-community/emacs-overlay/0f7f3b39157419f3035a2dad39fbaf8a4ba0448d";
inputs.flake-parts.url = "github:hercules-ci/flake-parts";
outputs = { self, nixpkgs, flake-parts, ... }@inputs: flake-parts.lib.mkFlake { inherit inputs; } {
@ -50,46 +57,34 @@
'';
};
fg42 = pkgs.callPackage ./nix/fg42 {
app = pkgs.callPackage ./nix/fg42 {
inherit nixpkgs;
extraPackages = {
noether = inputs.noether.outputs.packages.${system}.default;
};
};
fg42-wm = pkgs.callPackage ./nix/fg42 {
inherit nixpkgs;
modules = [
./nix/modules/editor
./nix/modules/elisp
./nix/modules/graphics
./nix/modules/noether
./nix/modules/wm
];
extraPackages = {
noether = inputs.noether.outputs.packages.${system}.default;
};
};
fg42 = app.drv;
run-test-wm = pkgs.writeShellApplication {
name = "run-test-wm";
runtimeInputs = [ fg42-wm ];
runtimeInputs = [ fg42 ];
text = ''
DISPLAY=:1 ${fg42-wm}/bin/fg42-wm
DISPLAY=:1 ${fg42}/bin/fg42-wm
'';
};
in
{
packages = {
packages = app.emacsPkgs // {
default = fg42;
wm = fg42-wm;
wm = fg42;
};
devShells.default = pkgs.mkShell {
nativeBuildInputs = [ fg42 fg42-wm pkgs.fish test-x run-test-wm ];
buildInputs = [ fg42 fg42-wm ];
nativeBuildInputs = [ fg42 pkgs.fish test-x run-test-wm ];
buildInputs = [ fg42 ];
};
apps.wm = {
@ -101,11 +96,11 @@
type = "app";
program = "${test-x}/bin/test-x";
};
apps.default = {
type = "app";
program = "${fg42}/bin/fg42";
};
};
};
}

View File

@ -31,7 +31,7 @@
(when (not (json-available-p))
(error "Error: libjasson support is missing"))
(defvar file-header " ;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
(defvar file-header ";;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;;
@ -66,6 +66,7 @@
;; Since it is deprecated we can easily avoide other packages to use it
(provide 'cl)
(require 'fg42/pre)
")
(defvar file-footer "
@ -128,10 +129,10 @@ Generate a constant if CONST is non-nil."
(cond
((string= k "requires")
(generate-compile-time-requires v))
((member k keys-to-skip)
(message "[build.el]: Skipping %s..." k))
((and (string= k "vars") (> (length v) 0))
(mapc (lambda (x)
(generate-generic-vars (gethash "name" x)
@ -166,18 +167,18 @@ CONFIG maps to the collective `config' value of Nix modules."
(with-json j
;; TODO: To make it scale, may be let Nix modules
;; plug into this script. There is a security
;; rist though
(maphash #'handle-top-level j)
(with-temp-file build-output
(insert file-header)
(insert ";; Vars ======")
(mapc (lambda (x) (print x (current-buffer))) vars)
(insert ";; Requires ======")
(mapc (lambda (x) (print x (current-buffer))) requires)
(insert file-footer))
(message "[build.el]: Done!"))
;; TODO: To make it scale, may be let Nix modules
;; plug into this script. There is a security
;; rist though
(maphash #'handle-top-level j)
(with-temp-file build-output
(insert file-header)
(insert ";; Vars ======")
(mapc (lambda (x) (print x (current-buffer))) vars)
(insert ";; Requires ======")
(mapc (lambda (x) (print x (current-buffer))) requires)
(insert file-footer))
(message "[build.el]: Done!"))
(provide 'build)

View File

@ -1,126 +0,0 @@
;;; 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/core)
(require 'fg42/utils)
(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.")
(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/initialize ()
"Initialize FG42 after the Emacs window is rendered by loading the user init file."
;; (fg42/-startup-optimization)
(require 'fpkg/core)
(fpkg/initialize)
(when (file-exists-p user-init-file)
(require 'fg42/cube)
(require 'fg42/flags)
(require 'fg42/cubes/fg42)
(load user-init-file))
(add-hook 'emacs-startup-hook
(lambda ()
(run-hooks 'fg42/-cubes-body-hook)
(run-hooks 'fg42/after-cubes-setup-hook)
(run-hooks 'fg42/after-init-hook)
(run-hooks 'fg42/after-initializing-theme-hook)
(run-hooks 'fg42/ui-hook)
(setq fg42/initialized t))))
(defun fg42/initialize-v4 ()
"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))
;; If user didn't select a theme, load the default stuff
(when (not (featurep 'fg42/themes))
(require 'fg42/themes))
(fg42/setup-editor)
(add-hook 'emacs-startup-hook
(lambda ()
(run-hooks 'fg42/after-init-hook)
(run-hooks 'fg42/after-initializing-theme-hook)
(run-hooks 'fg42/ui-hook)
(setq fg42/initialized t))))
(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 auto initilization of package.el
(setq package-enable-at-startup nil)
;; 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))
(provide 'fg42)
;;; fg42.el ends here

View File

@ -1,60 +0,0 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
(use! company
"Company is a modular text completion framework for GNU Emacs."
:commands global-company-mode
:bind (:map company-active-map
("M-n" . company-select-next)
("M-p" . company-select-previous)
("TAB" . company-complete-common-or-cycle)
("M-d" . company-show-doc-buffer))
:init
;; Use Company for completion
(setq company-show-numbers t)
(setq company-idle-delay 0)
(setq company-tooltip-limit 20)
(setq company-echo-delay 0)
(setq company-tooltip-align-annotations t)
(setq company-dabbrev-downcase nil)
:config
(setq-default company-backends
'((company-capf :with company-yasnippet :separate)
(company-keywords company-dabbrev company-ispell :separate)
company-files))
(bind-key [remap completion-at-point] #'company-complete company-mode-map))
(use! company-box
"A company front-end with icons."
:after company
:hook (company-mode . company-box-mode))
(provide 'fg42/autocomplete)
;;; autocomplete.el ends here

View File

@ -1,45 +0,0 @@
;;; 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:
(defgroup fg42 nil
"Customize your FG42 instance via this group of configurations.")
(defvar fg42/after-init-hook nil
"The hook tha runs when FG42 finished running the user configuration.")
(defvar fg42/debug-p nil
"The hook tha runs when FG42 finished running the user configuration.")
(defvar fg42-config-dir (or (getenv "FG42_CONFIG_DIR") "~/.fg42")
"Where to store installation specific data.")
(defvar fg42-home (getenv "FG42_HOME")
"The pass to fg42-home.")
(defvar fg42-tmp (concat fg42-config-dir "/tmp"))
(provide 'fg42/core)
;;; core.el ends here

View File

@ -1,129 +0,0 @@
;;; 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>
;; 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:
;; This file contains all the dependencies of FG42 v4 in no particular order.
;; Whether we use a package during runtime or not we will build everything
;; and decide what to load at runtime.
;;
;; We fetch these dependencies using Nix via the emacs-overlay.
;;
;;; Code:
(defmacro depends-on (&rest _)
"Just a placeholder."
nil)
(depends-on
bm
command-log-mode
dockerfile-mode
lsp-ltex
dracula-theme
lsp-julia
flycheck-julia
julia-formatter
julia-repl
julia-mode
nix-mode
noether-mode
ednc
idris-mode
company-coq
proof-general
msgpack
gdscript-mode
meson-mode
lsp-scheme
clojure-mode
cider
aggressive-indent
graphviz-dot-mode
terraform-mode
magit
diff-hl
rustic
yasnippet
yasnippet-snippets
ninja-mode
eldoc-cmake
cmake-mode
poetry
lsp-pyright
python-black
lsp-java
flycheck-gradle
gradle-mode
groovy-mode
use-package
vterm
projectile-ripgrep
go-mode
company-box
company
lsp-ui
lsp-mode
yaml-mode
flycheck
expand-region
eros
org
org-modern
org-super-agenda
org-ql
ctrlf
badwolf-theme
ace-window
avy
paredit
rainbow-delimiters
exec-path-from-shell
discover
emojify
alert
imenu-list
pinentry
helpful
which-key
dirvish
origami
f
projectile
mini-modeline
smart-mode-line
all-the-icons
exwm
verilog-ext
verilog-mode
pkg-info
envrc
vertico
orderless
eglot
marginalia
nerd-icons
forge
svg-tag-mode
base16-theme
consult
nerd-icons-completion)
(provide 'fg42/deps)
;;; deps.el ends here

View File

@ -1,33 +0,0 @@
;;; 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>
;; 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:
;; This file contains all the dependencies of FG42 v4 in no particular order.
;; Whether we use a package during runtime or not we will build everything
;; and decide what to load at runtime.
;;
;; We fetch these dependencies using Nix via the emacs-overlay.
;;
;;; Code:
(provide 'fg42/direnv)
;;; direnv.el ends here

View File

@ -1,300 +0,0 @@
;;; 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 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)
(defvar fg42/font '("Fira Mono" 12)
"Font name and size to be used with FG42. (Default (\"Fira Mono\" 12).")
(defvar fg42/snippet-dir nil
"Where to find user's snippets.")
(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
(expand-file-name
"snippets"
(file-name-directory (locate-library "yasnippet-snippets"))))
(local-snippet (expand-file-name "snippets" fg42-home))
(user-snippets (or fg42/snippet-dir local-snippet)))
(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-initializing-theme-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)
(global-company-mode)
;; git changes in the fringe
(global-diff-hl-mode)
;; Modeline replacement
(noether-global-mode)
;; 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

View File

@ -1,133 +0,0 @@
;;; Flags --- Flags library of FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
(require 'cl-lib)
(require 'seq)
(require 'fg42/core)
(defvar fg42/available-flags nil
"A list of defined flags.
Only use \\[defflag] to add a new flag to this list")
(defcustom fg42/flags nil
"A set of flags to mark the functionalities that expected from FG42.
Flags are defined using the \\[defflag] through out the source code.
To see a list of available flags use \\[fg42/show-all-flags] and to see
the documentation of each flag simply use \\[describe-flag]."
:group 'fg42
:package-version '(FG42 . "4.x")
:type '(symbol)
:tag "FG42 Flags")
(defmacro use-flags (flags)
"Set the given FLAGS to activate their functionalities in FG42."
`(progn
(setq fg42/flags ,flags)
t))
(defun fg42/-merge-flags (flags-set &rest new-flags)
"Merge the given NEW-FLAGS into the FLAGS-SET and return the result."
(cl-remove-duplicates
(seq-reduce
(lambda (result flag)
(let ((flag-str (symbol-name flag)))
(if (string-prefix-p "-" flag-str)
(let ((actual-flag (intern (substring flag-str 1))))
(if (member actual-flag result)
(remove actual-flag result)
result))
;; We don't want to check for duplicates here since we remove them
;; later
(cons flag result))))
new-flags
flags-set)))
(defmacro fg42/merge-flags (flags-set &rest new-flags)
"Merge the given NEW-FLAGS into the FLAGS-SET and return the result.
If any flag name in NEW-FLAGS list starts with `-' (a dash) it implies that
that functionality has to be disabled and removed from FLAGS-SET. For example,
`-lsp' implies that we DO NOT want to have `lsp' flag enabled and it should not
exist in the return value.
For example, `(fg42/merge-flags (list f1 f2 f3) f4 -f2)' will return `(f1 f3 f4)'"
`(fg42/-merge-flags ,flags-set ,@(mapcar (lambda (x) `',x) new-flags)))
(defmacro fg42/merge-with-default-flags (&rest new-flags)
"Merge the given list of NEW-FLAGS with default flags of FG42 and return the new set."
`(fg42/merge-flags fg42/flags ,@new-flags))
(defmacro defflag (flag-name docstring &optional default-value)
"Define a new flag FLAG-NAME with the given DOCSTRING.
If the DEFAULT-VALUE is a non nil value, then the flag will be
added to the active flags list."
(declare (doc-string 2) (indent defun))
(let ((var-name (intern (format "fg42/-flag-%s" (symbol-name flag-name))))
(set-default (when default-value
`((add-to-list 'fg42/flags ',flag-name)))))
`(if (boundp ',var-name)
(warn (format "Flag name `%s' already defined" ,(format "%s" flag-name)))
(progn
(defvar ,var-name t)
(add-to-list 'fg42/available-flags ',flag-name)
,@set-default))))
(defmacro when-flag (flag &rest body)
"Evaluate the BODY only if the given FLAG is active."
(declare (indent defun))
;; The `cube-local-flags' variable here is going to be
;; defined in cubes to hold the local flags for each cube
(if (not (and (boundp 'cube-local-flags)
(member flag cube-local-flags)))
`(progn ,@body)
`(when (member ',flag fg42/flags)
,@body)))
(defmacro if-flag (flag then else)
"Evaluate the THEN expr only if the given FLAG is active otherwise ELSE."
(declare (indent defun))
;; The `cube-local-flags' variable here is going to be
;; defined in cubes to hold the local flags for each cube
(if (and (boundp 'cube-local-flags)
(member flag cube-local-flags))
then
`(if (member ',flag fg42/flags)
,then
,else)))
(provide 'fg42/flags)
;;; flags.el ends here

View File

@ -1,84 +0,0 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;; This is the very first file that Emacs will load to setup FG42
;;; Code:
(when (string= (getenv "FG42_DEBUG") "1")
(setq debug-on-error t))
(eval-when-compile
(defvar package-archives)
(defvar use-package-ensure-function))
(defgroup fg42 nil
"Customize your FG42 instance via this group of configurations.")
(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-p nil
"The hook tha runs when FG42 finished running the user configuration.")
(defvar fg42-home (or (getenv "FG42_HOME") "~/.fg42")
"The pass to fg42-home.")
(defvar fg42-tmp (make-temp-file "fg42-" t))
(add-to-list 'load-path (concat (getenv "FG42_HOME") "/lisp"))
;; (when fg42-use-nix
;; (require 'site-start))
;; Prevent package.el to install anything at startup
(setq package-enable-at-startup nil)
(setq package-archives nil)
(setq use-package-ensure-function 'ignore)
(setq tab-width 2)
(let ((emacsd (or (getenv "FG42_EMACSD") (format "%s/emacs.d" (getenv "FG42_HOME")))))
(setq custom-file (format "%s/.fg42.custom.el" emacsd))
(setq user-emacs-directory emacsd)
(setq user-init-file
(or (getenv "FG42_CONFIG_FILE")
(format "%s/.fg42.el"
(getenv "HOME")))))
;; Load the customization file. In FG42 it is different than
;; the default `user-init-file'
(if (file-exists-p custom-file)
(load custom-file))
(require 'fg42)
(fg42/initialize-v4)
(provide 'fg42/init)
;;; init.el ends here

View File

@ -1,91 +0,0 @@
;;; 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))
(defvar fg42/clangd-args
(list
(format "-j=%s" (- (num-processors) 2))
"--clang-tidy"
"--header-insertion=iwyu"
"--pch-storage=memory"
"--background-index"
"--cross-file-rename"
"--completion-style=detailed")
"Arguments to pass to clangd.")
(use! cmake-ts-mode
"Enable cmake-ts-mode instead of the non-TS version.")
(use! eldoc-cmake
"ElDoc and cmake integration"
:hook (cmake-ts-mode . eldoc-cmake-enable))
(use! ninja-mode
"This cube enables Ninja integration with FG42. For more info checkout:
https://github.com/ninja-build/ninja/blob/master/misc/ninja-mode.el")
(defun fg42/c_cpp_ls (_)
"Return the proper lang server fo C/C++.
By default it will return `clangd' or `ccls' depends on what you have
installed. If you set `CPP_LS' env variable, then the value of that
var will be used instead. You can use `add-advice' to change the
return value of this function as well."
(let ((ls (getenv "CPP_LS")))
(if (null ls)
(eglot-alternatives `(("clangd" ,@fg42/clangd-args) ("ccls")))
(split-string ls " "))))
(defun fg42/c-ts-mode-setup ()
"A hook handler to setup cpp related configurations."
(message "[FG42][C/C++]: Make sure to setup clangd to fit your needs. For more info: https://clangd.llvm.org/config")
(setq-local company-backends
'((company-capf :with company-yasnippet) :separate
(company-keywords company-dabbrev company-ispell) :separate
company-files))
;; We set eglot's autoload command to `eglot-ensure'
(eglot-ensure)
(add-to-list 'eglot-server-programs
`(c++-ts-mode . ,#'fg42/c_cpp_ls)))
(use! c-ts-mode
"C++ setup. We're using treesitter version of c++ mode."
:init
;; Remap the standard C/C++ modes
(add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
(add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
(add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode))
:hook
(c++-ts-mode . company-mode)
(c++-ts-mode . fg42/c-ts-mode-setup)
(c++-ts-mode . flyspell-prog-mode))
(provide 'fg42/langs/cpp)
;;; cpp.el ends here

View File

@ -1,45 +0,0 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
(use! rainbow-delimiters
"rainbow-delimiters is a =rainbow parentheses= like mode which highlights delimiters
such as parentheses, brackets or braces according to their depth. Each successive level
is highlighted in a different color. This makes it easy to spot matching delimiters,
orient yourself in the code, and tell which statements are at a given depth."
;; It doesn't work due to a problem/conflict in rainbow-delimiters
;; But we use it any way they might fix it
:commands rainbow-delimiters-mode
:hook (prog-mode . rainbow-delimiters-mode))
(use! paredit
"`paredit' is a minor mode for performing structured editing of S-expression
data. The typical example of this would be Lisp or Scheme source code."
:commands paredit-mode)
(provide 'fg42/langs/langs)
;;; langs.el ends here

View File

@ -1,84 +0,0 @@
;;; 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:
(eval-when-compile
(require 'fpkg))
(require 'fg42/utils)
(defvar fg42/modeline-views nil
"A list of Noether views to use for modeline.")
(defvar fg42/modeline-active-face nil
"Override the active modeline face via this var.")
(defvar fg42/modeline-inactive-face nil
"Override the inactive modeline face via this var.")
(defface fg42/-disabled-modeline-active-border
'((t
:background "#bd93f9" :height 0.1 :box nil))
"A new face for modeline in active state."
:group 'fg42)
(defface fg42/-disabled-modeline-dective-border
'((t
:background "#44475a" :height 0.1 :box nil))
"A new face for modeline in active state."
:group 'fg42)
(use! noether
"Smart mode line is a pretty simple yet fantastic alternative
to Emacs modeline."
:if (display-graphic-p)
;;:after projectile
: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")))
(set-face-attribute 'fg42/-disabled-modeline-active-border nil :background active-border)
(set-face-attribute 'fg42/-disabled-modeline-dective-border nil :background inactive-border))
;; Disable the default modeline
(setq-default mode-line-format "")
(let ((face-remaps (default-value 'face-remapping-alist)))
(setf (alist-get 'mode-line face-remaps)
(if fg42/modeline-active-face fg42/modeline-active-face 'fg42/-disabled-modeline-active-border)
(alist-get 'mode-line-inactive face-remaps)
(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
(setq-default noether-views (list fg42/modeline)))
(when-wm
(setq-default noether-views nil)))
(provide 'fg42/modeline)
;;; modeline.el ends here

View File

@ -1,90 +0,0 @@
;;; 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:
(eval-when-compile
(require 'fpkg))
(require 'noether)
(require 'noether-units)
(require 'projectile)
(require 'nerd-icons)
(defvar fg42/-mode-icon)
(defun fg42/-update-mode-icon ()
"Set the current buffer name to the watched var."
(setq fg42/-mode-icon major-mode))
(defun fg42/-format-mode-icon (_ v _ _)
"Format the icon V."
(format " %s " (nerd-icons-icon-for-mode v)))
(noether-defunit fg42/mode-icon
"Draws an icon for the current major mode."
:label ""
:len 3
:init (lambda ()
(add-hook 'post-command-hook #'fg42/-update-mode-icon))
:deinit (lambda ()
(remove-hook 'post-command-hook #'fg42/-update-mode-icon))
:var 'fg42/-mode-icon
:fn #'fg42/-format-mode-icon)
;; ============================================================================
;; Exwm input mode
;; ============================================================================
(defvar fg42/-exwm-input-mode nil)
(defun fg42/-set-exwm-input-mode ()
"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."
(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
"Show the input mode of EXWM for the current buffer."
:label "I:"
:len 4
:init (lambda ()
(when (featurep 'exwm)
(add-hook 'noether-on-buffer-change-hook #'fg42/-set-exwm-input-mode)))
:deinit (lambda ()
(when (featurep 'exwm)
(remove-hook 'noether-on-buffer-change-hook #'fg42/-set-exwm-input-mode)))
:var 'fg42/-exwm-input-mode
:fn #'fg42/-format-exwm-input-mode)
(provide 'fg42/modeline/units)
;;; units.el ends here

View File

@ -1,102 +0,0 @@
;;; 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:
(eval-when-compile
(require 'fpkg))
(require 'fg42/modeline/units)
(defun fg42/--bottom-right (info)
"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."
(noether-show view))
(noether-defview fg42/modeline
"A simple and minimalist mode-line like status bar"
:managed? t
:binding (kbd "C-c 0")
:buffer "*modeline*"
:visible? t
:timeout 0
:on-parent-resize #'fg42/adjust-modeline
:frame
(list
:right-fringe 5
:poshandler #'fg42/--bottom-right
:border-width 0
:font (format "%s %s" (car fg42/font) (- (cadr fg42/font) 1))
:border-color "#bd93f9")
:units
(list
(buffer-name-unit
:label (format "%s " (nerd-icons-codicon "nf-cod-layers"))
:len 20)
(projectile-project-unit
:label (format "%s " (nerd-icons-octicon "nf-oct-project"))
:len 20)
(git-branch-unit
: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")))
(time-unit :label (format " %s " (nerd-icons-mdicon "nf-md-clock_time_three")))))
(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 1")
:separator " | "
:timeout 10
:frame
(list
:poshandler #'fg42/--bottom-right-padded
:border-width 0
:border-color "#bd93f9")
:units
(list
(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)
;;; views.el ends here

View File

@ -1,114 +0,0 @@
;;; 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:
;; `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:
(eval-when-compile
(require 'fpkg))
(fpkg/require 'f)
(defgroup fg42/project nil
"The customization group for the fg42-project-global-mode."
:group 'convenience)
(defvar fg42/visited-projects nil
"A plist of all the visited projects.
It's mapping of project name to the project datastructure")
(defmacro defproject (&rest props)
"Define a project with given PROPS to be used with FG42's project system."
(let* ((p (projectile-project-name))
(pr (projectile-project-root))
(f-name (intern (format "project/%s" p))))
(when (not p)
(error "Can't detect the projectile project. Is it a git repo?"))
`(progn
(defun ,f-name ()
,(format "Project '%s' configuration. Location: '%s'" p pr)
(list ,@props))
(when (not (plist-member fg42/visited-projects ,(symbol-name f-name)))
(plist-put fg42/visited-projects ,p #',f-name)))))
(defun fg42/-project-get-or-load-file ()
"Return the project plist either from the cache or by loading the `.fg42.el' file."
(let* ((p (projectile-project-name))
(f-name (intern (format "project/%s" p))))
(if (functionp f-name)
(funcall f-name)
(when (projectile-project-root)
(let ((file (f-join (projectile-project-root) ".fg42.el")))
(if (file-exists-p file)
(progn
(load file)
(if (functionp f-name)
(funcall f-name)
(progn
(warn "'%s' does not define a project." (f-join (projectile-project-root) ".fg42.el"))
nil)))
nil))))))
(defun fg42/project-run-slot (n)
"Run the slot number N of the current project."
(let ((p (fg42/-project-get-or-load-file)))
(funcall
(or (plist-get p (intern (format ":slot-%s" n)))
(lambda () (message "No task."))))))
(defmacro fg42/-project-define-slots (n)
"Define N slots."
`(progn
,@(mapcar
(lambda (x)
`(progn
(defun ,(intern (format "fg42/project-slot-%s" x)) ()
(format "Run the slot number %s of the current project." ,x)
(interactive)
(fg42/project-run-slot ,x))
(define-key fg42-project-global-mode-map (kbd ,(format "C-c C-%s" x))
(function ,(intern (format "fg42/project-slot-%s" x))))))
(number-sequence 0 n))))
;;;###autoload
(define-minor-mode fg42-project-global-mode
"A minor mode to activate FG42 project mode."
:global t
:lighter "Pj42"
:group 'fg42/project
:keymap (make-sparse-keymap)
(if fg42-project-global-mode
(fg42/-project-define-slots 9)
(message "Fg42 project is disabled")))
(provide 'fg42/project)
;;; project.el ends here

View File

@ -1,115 +0,0 @@
;;; 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:
;; `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 'seq)
(require 'fg42/utils)
(fpkg/require 's)
(defmacro ->commands (&rest body)
"Return a list of shell commands in the BODY.
Each element has to be list like `(cd \"..\")' the command is static but
the arguments get evaluated."
`(quote
,(mapcar
(lambda (x)
(when (not (listp x))
(error "Expect a list. Got %s" x))
(let ((command (car x))
(args (cdr x)))
(cond
((string= command "and") (s-join " && " (eval `(->commands ,@args))))
((string= command "or") (s-join " || " (eval `(->commands ,@args))))
(t (format "%s %s" command (mapconcat #'eval args " "))))))
body)))
(defun shell<- (commands &rest opts)
"Run the give list of COMMANDS via ssh on HOST with the given OPTS.
OPTS:
- `:shell' The shell to run the commands with. (default /bin/bash)
- `:buffer' The buffer name to use. (default '*ssh[SHELL]*')
- `:erase?' Whether or not erase the buffer. (default t)"
(let* ((sh (or (plist-get opts :shell) "/bin/bash"))
(buffer (or (plist-get opts :buffer) (format "*shell[%s]*" sh)))
(erase? (or (plist-get opts :erase-buffer?) t))
(cmds (format "'%s'" (mapconcat #'identity commands ";")))
(output-buffer (get-buffer-create buffer)))
(when erase?
(with-current-buffer output-buffer
(setq buffer-read-only nil)
(erase-buffer)))
(let ((p (start-process-shell-command
"shell<-"
(buffer-name output-buffer)
(format "%s -c %s"
sh
cmds))))
(set-process-sentinel p
(lambda (_ event)
(when (string= event "finished\n")
(message "Commands finished.")
;;(kill-process process)
))))))
(defun ssh<- (host commands &rest opts)
"Run the give list of COMMANDS via ssh on HOST with the given OPTS.
OPTS:
- `:shell' The shell to run the commands with. (default /bin/bash)
- `:buffer' The buffer name to use. (default '*ssh[HOST]*')
- `:erase?' Whether or not erase the buffer. (default t)"
(let* ((sh (or (plist-get opts :shell) "/bin/bash"))
(buffer (or (plist-get opts :buffer) (format "*ssh[%s]*" host)))
(erase? (or (plist-get opts :erase-buffer?) t))
(cmds (format "'%s'" (mapconcat #'identity commands ";")))
(output-buffer (get-buffer-create buffer)))
(when erase?
(with-current-buffer output-buffer
(setq buffer-read-only nil)
(erase-buffer)))
(let ((p (start-process-shell-command
(format "ssh-to-%s" host)
(buffer-name output-buffer)
(format "ssh -t %s %s -c %s"
host
sh
cmds))))
(set-process-sentinel p
(lambda (_ event)
(when (string= event "finished\n")
(message "Commands finished. Closing SSH connection.")
;;(kill-process process)
))))))
(provide 'fg42/shell)
;;; shell.el ends here

View File

@ -1,73 +0,0 @@
;;; 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:
;; Some of the functions in this module are borrowed from `mini-modeline'
;; at https://github.com/kiennq/emacs-mini-modeline (GPL). I modified to
;; fit my needs.
;;; Require
(require 'fpkg)
(fpkg/require 'all-the-icons)
(fpkg/require 'posframe)
(defvar fg42/status-buffer "*status-buffer*"
"The name of the status buffer to use.")
(defun fg42/status-show ()
(interactive)
(with-current-buffer fg42/status-buffer
(erase-buffer)
(insert (propertize (all-the-icons-octicon "package")
'face `(:family ,(all-the-icons-octicon-family) :height 1)
;; 'display '(raise -0.1)
) )
(insert "| A | B | C"))
(posframe-show
fg42/status-buffer
:min-height 1
:min-width 10
:position (cons (- (frame-outer-width) 10) (- (frame-outer-height) 10))
;;:poshandler #'posframe-poshandler-frame-bottom-right-corner
;;:border-width 1
:border-color "#aa00bb"
:accept-focus nil
:timeout 5
:refresh 1))
(posframe-delete-all)
(define-minor-mode fg42/global-statue-mode
"A minor mode that keep tracks of different status blocks.
It reports them back in a status bar like frame."
:global t
:lighter " ST42"
:keymap (let ((map (make-sparse-keymap)))))
(fg42/global-statue-mode)
(provide 'status.el)
;;; status.el ends here

View File

@ -1,501 +0,0 @@
;;; 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:
;; Some of the functions in this module are borrowed from `mini-modeline'
;; at https://github.com/kiennq/emacs-mini-modeline (GPL). I modified to
;; fit my needs.
;;; Require
(require 'minibuffer)
(require 'frame)
(require 'timer)
(require 'face-remap)
;; ============================================================================
;; customizations
;; ============================================================================
(defgroup fg42/statusbar nil
"Status bar group."
:group 'fg42/statusbar)
(defcustom fg42/statusbar-components
'("random" (buffer-name))
"Default active components."
:type 'list
:group 'fg42/statusbar)
(defcustom fg42/statusbar-truncate-p t
"Truncates fg42/statusbar or not."
:type 'boolean
:group 'fg42/statusbar)
(defcustom fg42/statusbar-echo-duration 5
"Duration to keep display echo."
:type 'integer
:group 'fg42/statusbar)
(defcustom fg42/statusbar-refresh-idle-delay 0.1
"Update idle delay of bar in seconds."
:type 'double
:group 'fg42/statusbar)
(defcustom fg42/statusbar-frame nil
"Frame to display fg42/statusbar on.
Nil means current selected frame."
:type 'sexp
:group 'fg42/statusbar)
(defcustom fg42/statusbar-display-gui-line t
"Display thin line at the bottom of the window."
:type 'boolean
:group 'fg42/statusbar)
(defvar fg42/statusbar-height 4)
(defcustom fg42/statusbar-face-attr `(:background ,(face-attribute 'mode-line :background))
"Plist of face attribute/value pair for fg42/statusbar."
:type '(plist)
:group 'fg42/statusbar)
;; ============================================================================
;; Faces
;; ============================================================================
(defface fg42/statusbar-mode-line
'((((background light))
:background "#55ced1" :height 0.1 :box nil)
(t
:background "#3f3f3f" :height 0.2 :box nil))
"Modeline face for active window."
:group 'fg42/statusbar)
(defface fg42/statusbar-components
'((t :inherit t :height 0.7))
"Modeline face for active window."
:group 'fg42/statusbar)
(defface fg42/statusbar-mode-line-inactive
'((((background light))
:background "#dddddd" :height 0.1 :box nil)
(t
:background "#333333" :height 0.1 :box nil))
"Modeline face for inactive window."
:group 'fg42/statusbar)
;; ============================================================================
;; Vars
;; ============================================================================
(defvar fg42/statusbar-info-padding-right 0)
(defvar fg42/statusbar--msg nil)
(defvar fg42/statusbar--msg-message nil
"Store the string from `message'.")
(defvar fg42/statusbar--last-update (current-time))
(defvar fg42/statusbar--last-change-size (current-time))
(defvar fg42/statusbar--last-echoed nil)
(defvar fg42/statusbar-timer nil)
(defvar fg42/statusbar-active-p nil)
(defvar fg42/statusbar--cache nil)
(defvar fg42/statusbar--orig-resize-mini-windows resize-mini-windows)
(defvar fg42/statusbar--minibuffer nil)
(defvar fg42/statusbar--echo-keystrokes echo-keystrokes)
(defvar fg42/statusbar-command-state 'begin
"The state of current executed command begin -> [exec exec-read] -> end.")
(defvar fg42/statusbar-enable-hook nil)
(defvar fg42/statusbar-disable-hook nil)
(defvar-local fg42/statusbar--orig-mode-line mode-line-format)
(defvar-local fg42/statusbar--face-cookie nil)
(defvar fg42/statusbar--orig-mode-line-remap
(or (alist-get 'mode-line face-remapping-alist) 'mode-line))
(defvar fg42/statusbar--orig-mode-line-inactive-remap
(or (alist-get 'mode-line-inactive face-remapping-alist) 'mode-line-inactive))
;; ============================================================================
;; Definitions
;; ============================================================================
(defmacro fg42/statusbar-wrap (func &rest body)
"Add an advice around FUNC with name fg42/statusbar--%s.
BODY will be supplied with orig-func and args."
(let ((name (intern (format "fg42/statusbar--%s" func))))
`(advice-add #',func :around
(lambda (orig-func &rest args)
,@body)
'((name . ,name)))))
(defmacro defbar-unit (name interval default &rest body)
"Create a status bar unit with a dedicated timer.
It will create a unit with the given NAME and DEFAULT value and a timer
that runs the given BODY at the given INTERVAL."
(declare (indent defun))
(let ((timer-name (intern (format "$%s-timer" name))))
`(progn
(defvar ,name ,default)
(defvar ,timer-name)
(let ((fn (lambda () ,@body)))
(add-hook 'fg42/statusbar-enable-hook
(lambda ()
(setq ,timer-name
(run-with-timer 0 ,interval
(lambda ()
(setq ,name (funcall fn))))))))
(add-hook 'fg42/statusbar-disable-hook
(lambda ()
(when (timerp ,timer-name)
(cancel-timer ,timer-name)))))))
(defsubst fg42/statusbar-pre-cmd ()
"Pre command hook of fg42/statusbar."
(setq fg42/statusbar-command-state 'begin))
(defsubst fg42/statusbar-post-cmd ()
"Post command hook of fg42/statusbar."
(setq fg42/statusbar-command-state 'end
echo-keystrokes fg42/statusbar--echo-keystrokes))
(defsubst fg42/statusbar-enter-minibuffer ()
"`minibuffer-setup-hook' of fg42/statusbar."
(fg42/statusbar--set-buffer-face)
(setq resize-mini-windows 'grow-only))
(defsubst fg42/statusbar-exit-minibuffer ()
"`minibuffer-exit-hook' of fg42/statusbar."
(with-current-buffer fg42/statusbar--minibuffer
(fg42/statusbar--set-buffer-face))
(setq resize-mini-windows nil))
(defun fg42/statusbar--set-buffer-face ()
"Set buffer default face for current buffer."
(setq fg42/statusbar--face-cookie
(face-remap-add-relative 'default fg42/statusbar-face-attr)))
(defun fg42/statusbar-enable ()
"Enable the statusbar."
;; Hide modeline for terminal, or use empty modeline for GUI.
(setq-default fg42/statusbar--orig-mode-line mode-line-format)
(setq-default mode-line-format (when (and fg42/statusbar-display-gui-line
(display-graphic-p))
'(" ")))
;; Do the same thing with opening buffers.
(mapc
(lambda (buf)
(with-current-buffer buf
(when (local-variable-p 'mode-line-format)
(setq fg42/statusbar--orig-mode-line mode-line-format)
(setq mode-line-format (when (and fg42/statusbar-display-gui-line
(display-graphic-p))
'(" "))))
(when (or (minibufferp buf)
(string-prefix-p " *Echo Area" (buffer-name)))
(fg42/statusbar--set-buffer-face))
;; Make the modeline in GUI a thin bar.
(when (and fg42/statusbar-display-gui-line
(local-variable-p 'face-remapping-alist)
(display-graphic-p))
(setf (alist-get 'mode-line face-remapping-alist)
'fg42/statusbar-mode-line
(alist-get 'mode-line-inactive face-remapping-alist)
'fg42/statusbar-mode-line-inactive))))
(buffer-list))
;; Make the modeline in GUI a thin bar.
(when (and fg42/statusbar-display-gui-line
(display-graphic-p))
(let ((face-remaps (default-value 'face-remapping-alist)))
(setf (alist-get 'mode-line face-remaps)
'fg42/statusbar-mode-line
(alist-get 'mode-line-inactive face-remaps)
'fg42/statusbar-mode-line-inactive
(default-value 'face-remapping-alist) face-remaps)))
(setq fg42/statusbar--orig-resize-mini-windows resize-mini-windows)
(setq resize-mini-windows nil)
(redisplay)
(advice-add #'message :around #'fg42/statusbar-message-advice)
;; Add update timer.
(setq fg42/statusbar-timer
(run-with-timer 0 fg42/statusbar-refresh-idle-delay #'fg42/statusbar-display))
(add-hook 'minibuffer-setup-hook #'fg42/statusbar-enter-minibuffer)
(add-hook 'minibuffer-exit-hook #'fg42/statusbar-exit-minibuffer)
(add-hook 'pre-command-hook #'fg42/statusbar-pre-cmd)
(add-hook 'post-command-hook #'fg42/statusbar-post-cmd)
;;(add-hook 'focus-in-hook 'fg42/statusbar-show-info)
(add-function :after after-focus-change-function #'fg42/statusbar-display)
;; read-key-sequence
(fg42/statusbar-wrap
read-key-sequence
(progn
(setq fg42/statusbar-command-state 'exec-read)
(apply orig-func args)))
(fg42/statusbar-wrap
read-key-sequence-vector
(progn
(setq fg42/statusbar-command-state 'exec-read)
(apply orig-func args)))
(run-hooks 'fg42/statusbar-enable-hook)
(setq fg42/statusbar-active-p t))
(defun fg42/statusbar-disable ()
"Disable the status bar."
(setq-default mode-line-format (default-value 'fg42/statusbar--orig-mode-line))
(when (display-graphic-p)
(let ((face-remaps (default-value 'face-remapping-alist)))
(setf (alist-get 'mode-line face-remaps)
fg42/statusbar--orig-mode-line-remap
(alist-get 'mode-line-inactive face-remaps)
fg42/statusbar--orig-mode-line-inactive-remap
(default-value 'face-remapping-alist) face-remaps)))
(mapc
(lambda (buf)
(with-current-buffer buf
(when (local-variable-p 'mode-line-format)
(setq mode-line-format fg42/statusbar--orig-mode-line))
(when fg42/statusbar--face-cookie
(face-remap-remove-relative fg42/statusbar--face-cookie))
(when (and (local-variable-p 'face-remapping-alist)
(display-graphic-p))
(setf (alist-get 'mode-line face-remapping-alist)
fg42/statusbar--orig-mode-line-remap
(alist-get 'mode-line-inactive face-remapping-alist)
fg42/statusbar--orig-mode-line-inactive-remap))))
(buffer-list))
(setq resize-mini-windows fg42/statusbar--orig-resize-mini-windows)
(redisplay)
(advice-remove #'message #'fg42/statusbar-message-advice)
(advice-remove #'read-key-sequence 'fg42/statusbar--read-key-sequence)
(advice-remove #'read-key-sequence-vector 'fg42/statusbar--read-key-sequence-vector)
(remove-hook 'minibuffer-setup-hook #'fg42/statusbar-enter-minibuffer)
(remove-hook 'minibuffer-exit-hook #'fg42/statusbar-exit-minibuffer)
(remove-hook 'pre-command-hook #'fg42/statusbar-pre-cmd)
(remove-hook 'post-command-hook #'fg42/statusbar-post-cmd)
;; Cancel timer.
(when (timerp fg42/statusbar-timer)
(cancel-timer fg42/statusbar-timer))
(remove-function after-focus-change-function #'fg42/statusbar-display)
;; Update mode-line.
(force-mode-line-update)
(redraw-display)
(with-current-buffer " *Minibuf-0*"
(erase-buffer))
(run-hooks 'fg42/statusbar-disable-hook)
(setq fg42/statusbar-active-p nil))
(defun fg42/statusbar-build-active-info ()
"Collect the information from active components."
(mapconcat
(lambda (form)
(let ((result (eval form)))
(when (not (stringp result))
(error "The result of %s is not string" result))
(when (> (length result) 0)
result)))
fg42/statusbar-components
""))
(defun fg42/statusbar-get-frame-width ()
"Only calculating a main Frame width, to avoid wrong width when new frame, such
as `snails'."
(if (display-graphic-p)
(with-selected-frame (car (last (frame-list)))
(frame-width))
(frame-width)))
(defun fg42/statusbar-get-echo-format-string (info message-string)
(let* ((blank-length (- (fg42/statusbar-get-frame-width)
(string-width info)
(string-width (or message-string ""))
fg42/statusbar-info-padding-right)))
(cond
;; Fill message's end with whitespace to keep the info at right of minibuffer.
((> blank-length 0)
(progn
(let* ((inhibit-message t))
(concat message-string
(make-string (max 0 (- (fg42/statusbar-get-frame-width)
(string-width (or message-string ""))
(string-width info)
fg42/statusbar-info-padding-right)) ?\ )
info))))
(t message-string))))
(defsubst fg42/statusbar--overduep (since duration)
"Check if time already pass DURATION from SINCE."
(>= (float-time (time-since since)) duration))
(defun fg42/statusbar--log (&rest args)
"Log message into message buffer with ARGS as same parameters in `message'."
(save-excursion
(with-current-buffer "*Messages*"
(let ((inhibit-read-only t))
(goto-char (point-max))
(insert (apply #'format args))))))
(defun fg42/statusbar-display (&optional arg)
"Update fg42/statusbar.
When ARG is:
- `force', force update the minibuffer.
- `clear', clear the minibuffer. This implies `force'."
(save-match-data
(let ((bar-info (fg42/statusbar-build-active-info)))
(condition-case err
(cl-letf (((symbol-function 'completion-all-completions) #'ignore))
(unless (or (active-minibuffer-window)
(input-pending-p))
(setq fg42/statusbar--minibuffer
(window-buffer (minibuffer-window fg42/statusbar-frame)))
(with-current-buffer fg42/statusbar--minibuffer
(let ((truncate-lines fg42/statusbar-truncate-p)
(inhibit-read-only t)
(inhibit-redisplay t)
(buffer-undo-list t)
modeline-content)
(when (or (memq arg '(force clear))
(fg42/statusbar--overduep fg42/statusbar--last-update
fg42/statusbar-refresh-idle-delay))
(when-let ((msg (or fg42/statusbar--msg-message (current-message))))
;; Clear echo area and start new timer for echo message
(message nil)
(setq fg42/statusbar--last-echoed (current-time))
;; we proritize the message from `message'
;; or the message when we're not in middle of a command running.
(when (or fg42/statusbar--msg-message
(eq fg42/statusbar-command-state 'begin))
(setq fg42/statusbar-command-state 'exec)
;; Don't echo keystrokes when in middle of command
(setq echo-keystrokes 0))
(setq fg42/statusbar--msg msg))
;; Reset echo message when timeout and not in middle of command
(when (and fg42/statusbar--msg
(not (memq fg42/statusbar-command-state '(exec exec-read)))
(fg42/statusbar--overduep fg42/statusbar--last-echoed
fg42/statusbar-echo-duration))
(setq fg42/statusbar--msg nil))
;; Showing fg42/statusbar
(if (eq arg 'clear)
(setq modeline-content nil)
(setq modeline-content
(fg42/statusbar-get-echo-format-string bar-info fg42/statusbar--msg))
(setq fg42/statusbar--last-update (current-time)))
;; write to minibuffer
(unless (equal modeline-content
fg42/statusbar--cache))
(setq fg42/statusbar--cache modeline-content)
(erase-buffer)
(when fg42/statusbar--cache
(let (
;;let fg42/statusbar take control of mini-buffer size
(resize-mini-windows t))
(insert fg42/statusbar--cache))))))))
((error debug)
(fg42/statusbar--log "fg42/statusbar: %s\n" err))))))
(defun fg42/statusbar-message-advice (f &rest args)
"Wrap `message' make status bar information visible always
even other plugins call `message' to flush minibufer."
(if inhibit-message
(apply f args)
(let* ((inhibit-message t)
(fg42/statusbar--msg-message (apply f args)))
(fg42/statusbar-display 'force)
fg42/statusbar--msg-message)))
;;;###autoload
(define-minor-mode fg42/statusbar-mode
"Super simple status bar for FG42."
:require 'fg42/statusbar-mode
:lighter "SB"
:global t
(if fg42/statusbar-mode
(fg42/statusbar-enable)
(fg42/statusbar-disable)))
(provide 'fg42/statusbar)
;;; statusbar.el ends here

View File

@ -1,98 +0,0 @@
;;; Themes --- Theme library of FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;;
;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;; Cubes are the building blocks of any `FG42' editor. Each `cube' is a
;; unit which defines different abilities in a deterministic and idempotent
;; way. Cubes are composable and a composition of cubes creates an editor.
;;
;;; Code:
(eval-when-compile
(require 'fpkg))
(require 'fg42/utils)
(defvar fg42/ui-hook ()
"A hook that cubes can use via :ui-hook property.
It executes way before the rest of the cubes.")
(defvar fg42/before-initializing-theme-hook ()
"The hook to plug any configuration to before initialize event of themes.")
(defvar fg42/after-initializing-theme-hook ()
"The hook to plug any configuration to after initialize event of themes.")
(defmacro fg42/setup-theme (&rest body)
"Run the BODY inside the FG42 theme setup context."
`(progn
;; TODO: This is a bad practice. Find a better solution
(run-hooks 'fg42/before-initializing-theme-hook)
,@body))
(defmacro use-theme! (name &rest body)
"Create a function to setup a them with the given NAME and BODY to customize it."
(declare (indent defun))
(let ((fn-name (intern (format "fg42/setup-%s" (symbol-name name)))))
`(defun ,fn-name ()
(use! ,name
"Setting up the ,name package."
:init
(fg42/setup-theme
(require ',name)
,@body)))))
;; (use-theme! dracula-theme
;; :init
;; (fg42/setup-theme
;; (require 'dracula-theme)
;; (load-theme 'dracula t)
;; (custom-theme-set-faces
;; 'dracula
;; '(match ((t (:background "#44475a"))))
;; '(all-the-icons-lgreen ((t (:background "#bd93f9"))))
;; '(all-the-icons-faicon ((t (:background "#bd93f9"))))
;; '(font-lock-comment-face ((t (:foreground "#8B9298"))))
;; ;; This fixes lsp-ui-sideline issue
;; '(lsp-ui-sideline-current-symbol ((t (:line-width -1 :foreground "#bd93f9"))))
;; '(font-lock-comment-delimiter-face ((t (:foreground "#5B6268")))))
;; (enable-theme 'dracula)
;; (set-face-attribute 'region nil :background "#888")))
(use-theme! badwolf-theme
:init
(fg42/setup-theme
(load-theme 'badwolf t)
(custom-theme-set-faces
'badwolf)
(enable-theme 'badwolf)))
(use! base16-theme
"Load base16 based themes in FG42."
:config
(load-theme 'base16-eighties t))
(provide 'fg42/themes)
;;; themes.el ends here

View File

@ -1,161 +0,0 @@
;;; 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

View File

@ -1,173 +0,0 @@
;;; 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))
(defvar workspace-configuration
'(0 "HDMI-1"
1 "HDMI-1"
2 "HDMI-1"
3 "HDMI-1"
4 "HDMI-1"
5 "HDMI-1"
6 "HDMI-1"
7 "HDMI-1"
8 "HDMI-1"
9 "HDMI-1")
"Workspace configuration for EXWM. (default 10 screens on HDMI-1).")
;; TODO: Document this
;; (add-hook 'exwm-randr-screen-change-hook
;; (lambda ()
;; (start-process-shell-command
;; "xrandr" nil "xrandr --output HDMI-1 --above eDP-1 --mode 1920x1080")))
(when-wm
(use! exwm-randr
"EXWM plugin to interact with xrandr."
:commands exwm-randr-enable
:config
(setq exwm-randr-workspace-output-plist workspace-configuration))
(use! exwm-systemtray
"Enables systemtray on EXWM"
:commands exwm-systemtray-enable)
;; (use! mini-frame
;; "Place minibuffer at the top of the current frame on `read-from-minibuffer'."
;; :hook (emacs-startup . mini-frame-mode)
;; :custom
;; (mini-frame-show-parameters
;; '((top . 10)
;; (width . 0.5)
;; (left . 0.5)
;; (height . 15))))
(use! exwm
"Emacs X Widnow manager."
:commands exwm-enable
:config
(require 'exwm-config)
(exwm-config-ido)
;; Set the initial number of workspaces (they can also be created later).
(setq exwm-workspace-number 10)
;; All buffers created in EXWM mode are named "*EXWM*". You may want to
;; change it in `exwm-update-class-hook' and `exwm-update-title-hook', which
;; are run when a new X window class name or title is available. Here's
;; some advice on this topic:
;; + Always use `exwm-workspace-rename-buffer` to avoid naming conflict.
;; + For applications with multiple windows (e.g. GIMP), the class names of
;; all windows are probably the same. Using window titles for them makes
;; more sense.
;; In the following example, we use class names for all windows except for
;; Java applications and GIMP.
(add-hook 'exwm-update-class-hook
(lambda ()
(unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-class-name))))
(add-hook 'exwm-update-title-hook
(lambda ()
(when (or (not exwm-instance-name)
(string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-title))))
;; Global keybindings can be defined with `exwm-input-global-keys'.
;; Here are a few examples:
(setq exwm-input-global-keys
`(
;; Bind "s-r" to exit char-mode and fullscreen mode.
([?\s-r] . exwm-reset)
([?\s-g] . keyboard-quit)
([8388640] . other-window)
;; Bind "s-w" to switch workspace interactively.
([?\s-w] . exwm-workspace-switch)
;; Bind "s-0" to "s-9" to switch to a workspace by its index.
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))
;; Bind "s-&" to launch applications ('M-&' also works if the output
;; buffer does not bother you).
([?\s-d] . (lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
;; Bind "s-<f2>" to "slock", a simple X display locker.
([s-f2] . (lambda ()
(interactive)
(start-process "" nil "slock")))))
;; To add a key binding only available in line-mode, simply define it in
;; `exwm-mode-map'. The following example shortens 'C-c q' to 'C-q'.
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
(push ?\C-c exwm-input-prefix-keys)
;; You can hide the minibuffer and echo area when they're not used, by
;; uncommenting the following line.
;;(setq exwm-workspace-minibuffer-position 'bottom)
;; The following example demonstrates how to use simulation keys to mimic
;; the behavior of Emacs. The value of `exwm-input-simulation-keys` is a
;; list of cons cells (SRC . DEST), where SRC is the key sequence you press
;; and DEST is what EXWM actually sends to application. Note that both SRC
;; and DEST should be key sequences (vector or string).
(setq exwm-input-simulation-keys
`(
;; movement
(,(kbd "C-b") . left)
(,(kbd "M-b") . ,(kbd "C-<left>"))
(,(kbd "C-f") . right)
(,(kbd "M-f") . ,(kbd "C-<right>"))
(,(kbd "C-p") . up)
(,(kbd "C-n") . down)
(,(kbd "C-a") . home)
(,(kbd "C-e") . end)
(,(kbd "M-v") . prior)
(,(kbd "C-v") . next)
(,(kbd "C-d") . delete)
;;(,(kbs "C-k") . [S-end delete])
;; navigation
(,(kbd "C-c b") . ,(kbd "M-<left>"))
(,(kbd "C-c f") . ,(kbd "M-<right>"))
(,(kbd "C-c w") . ,(kbd "C-w"))
(,(kbd "C-w") . ,(kbd "C-x"))
(,(kbd "M-w") . ,(kbd "C-c"))
(,(kbd "C-y") . ,(kbd "C-v"))
;; search
(,(kbd "C-s") . ,(kbd "C-f"))))))
(provide 'fg42/wm)
;;; wm.el ends here

View File

@ -1,66 +0,0 @@
;;; 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 'seq)
(defvar fg42/monitors nil
"A plist containing monitor resolution profiles.
for example:
'(:hdmi-only
(\"--output HDMI-1 --primary\"
\"--output eDP-1 --off\")
:hdmi-main
(\"--output HDMI-1 --primary\"
\"--output eDP-1 --mode 1920x1080 --left-of HDMI-1\")
:edp-only
(\"--output eDP-1 --mode 1920x1080\"
\"--output HDMI-1 --off\"))")
(defun fg42/get-x11-selection-text ()
"Return the X11 selection paste text."
(interactive)
(gui-get-selection 'PRIMARY))
(defun monitor-profiles ()
"Parse the `fg42/monitors' profiles."
(mapcar
#'car
(seq-partition fg42/monitors 2)))
(defun monitor (mon)
"Switch to the given monitor resolution profile MON."
(interactive
(list (completing-read
"Monitor Profole: "
(monitor-profiles))))
(let ((cmd (mapconcat (lambda (x) (format "xrandr %s" x))
(plist-get fg42/monitors (intern (format "%s" mon)))
" && ")))
(message "Setting monitor profile: %s" cmd)
(async-shell-command cmd "*xrandr*")))
(provide 'fg42/x)
;;; x.el ends here

View File

@ -1,69 +0,0 @@
;;; 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

View File

@ -1,66 +0,0 @@
;;; 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 'fg42/core)
(defvar bootstrap-version 5)
(defun fpkg/install-and-load-use-package ()
"Install and load the `use-package' in compile time."
;; TODO Enable use-package on compile time
;;(eval-when-compile)
(if fg42-use-nix
(setq use-package-always-ensure nil)
(progn
(setq use-package-always-ensure t)
(straight-use-package 'use-package)))
(require 'use-package))
(defun fpkg/initialize ()
"Initialize FPKG."
(if (null fg42-use-nix)
(let ((bootstrap-file
(expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory)))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/radian-software/straight.el/develop/install.el"
'silent 'inhibit-cookies)
(goto-char (point-max))
(eval-print-last-sexp)))
(load bootstrap-file nil 'nomessage)
(fpkg/install-and-load-use-package))
(fpkg/install-and-load-use-package)))
(provide 'fpkg/core)
;;; core.el ends here

View File

@ -1,85 +0,0 @@
;;; ob-gharphviz --- org-babel functions for gharphviz evaluation of FG42
;;
;; 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:
;; This file location is important and can't be under `fg42/' dir even
;; though it is part of the FG42. That's due to the `org-babel' mechanism
;; to automatically load the language backend. SO DO NOT MOVE IT.
;;; Code:
(require 'ob)
(require 'ob-ref)
(require 'ob-comint)
(require 'ob-eval)
(require 'ob-dot)
(add-to-list 'org-babel-tangle-lang-exts '("graphviz-dot" . "dot"))
(defvar org-babel-default-header-args:graphviz-dot
'((:results . "file") (:exports . "results")))
(defun org-babel-expand-body:ghraphviz-dot (body params &optional processed-params)
"Expand BODY according to PARAMS, return the expanded body."
(let ((vars (org-babel--get-vars params)))
(mapc
(lambda (pair)
(let ((name (symbol-name (car pair)))
(value (cdr pair)))
(setq body
(replace-regexp-in-string
(concat "$" (regexp-quote name))
(if (stringp value) value (format "%S" value))
body
t
t))))
vars)
body))
(defun org-babel-execute:graphviz-dot (body params)
"Execute a block of Template code with org-babel.
This function is called by `org-babel-execute-src-block'"
(let* ((out-file (cdr (or (assq :file params)
(error "You need to specify a :file parameter"))))
(cmdline (or (cdr (assq :cmdline params))
(format "-T%s" (file-name-extension out-file))))
(cmd (or (cdr (assq :cmd params)) "dot"))
(coding-system-for-read 'utf-8) ;use utf-8 with sub-processes
(coding-system-for-write 'utf-8)
(in-file (org-babel-temp-file "dot-")))
(with-temp-file in-file
(insert (org-babel-expand-body:dot body params)))
(org-babel-eval
(concat cmd
" " (org-babel-process-file-name in-file)
" " cmdline
" -o " (org-babel-process-file-name out-file)) "")
;; signal that output has already been written to file
nil))
(defun org-babel-prep-session:graphviz-dot (session params)
"Prepare SESSION according to the header arguments specified in PARAMS."
(error "Dot does not support sessions"))
(provide 'ob-graphviz-dot)
;;; ob-graphviz-dot.el ends here

View File

@ -32,6 +32,9 @@
with builtins;
let
src = ../../.;
pname = "FG42";
cfg = config.fg42;
emacs = cfg.emacs;
version = cfg.version;
@ -61,139 +64,162 @@ let
};
in
stdenv.mkDerivation rec {
inherit version;
pname = builtins.trace ">>> ${configFile}" "FG42";
{
emacsPkgs = (emacsPackagesFor emacs);
drv =
stdenv.mkDerivation rec {
inherit version src pname;
src = ../../.;
buildPhase = ''
runHook preBuild
buildPhase = ''
runHook preBuild
# =============================
# Building FG42 itself
# =============================
LISPDIR=$out/share/fg42/
STARTUP_FILE=$LISPDIR/lisp/fg42_init.el
LISPDIR=$out/share/fg42/
STARTUP_FILE=$LISPDIR/lisp/fg42_init.el
mkdir -p $out/bin
mkdir -p $out/share/applications/
mkdir -p $out/bin
mkdir -p $out/share/applications/
install -d $LISPDIR
install -d $LISPDIR
mkdir -p $LISPDIR/lisp
cp -rv ${src}/lisp/build.el $LISPDIR/lisp
mkdir -p $LISPDIR/lisp
cp -rv ${src}/lisp/build.el $LISPDIR/lisp
cp -rv ${src}/share $out/
cp "${fontsConf}" $LISPDIR/fonts.conf
cp "${configFile}" $LISPDIR/config.json
cp -rv ${src}/share $out/
cp -rv ${src}/snippets $LISPDIR/snippets
cp "${fontsConf}" $LISPDIR/fonts.conf
cp "${configFile}" $LISPDIR/config.json
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
chmod 755 $LISPDIR -R
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
chmod 755 $LISPDIR -R
emacs --batch -l $LISPDIR/lisp/build.el $LISPDIR/config.json $STARTUP_FILE
#emacs -Q --batch -l package --eval "(package-generate-autoloads \"fg42_init" \"$LISPDIR\")"
emacs --batch -l loaddefs-gen -f loaddefs-generate-batch $LISPDIR/lisp/ $LISPDIR/lisp/ ${emacsBundle}
cd $LISPDIR
#compile stuff
cd -
emacs --batch -l $LISPDIR/lisp/build.el $LISPDIR/config.json $STARTUP_FILE
#emacs -Q --batch -l package --eval "(package-generate-autoloads \"fg42_init" \"$LISPDIR\")"
emacs --batch -l loaddefs-gen -f loaddefs-generate-batch $LISPDIR/lisp/ $LISPDIR/lisp/ ${emacsBundle}
# =============================
# Creating the desktop file
# =============================
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/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"
export STARTUP_FILE=$LISPDIR/lisp/fg42_init.el
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 "$STARTUP_FILE" "\$@"
EOF
chmod +x $out/bin/fg42
# =============================
# Adding the runtime deps to
# runtime closure
# =============================
cat >> $out/share/runtime_deps << EOF
${lib.strings.concatLines runtimeDependencies}
${emacsBundle}
EOF
LISPDIR=$out/share/fg42/lisp/
mkdir -p $LISPDIR
#emacs --batch -l package --eval "(package-generate-autoloads \"${pname}\" \"$LISPDIR\")"
# =============================
# Creating fg42 command
# =============================
cat >> $out/bin/fg42 << EOF
#!${stdenv.shell}
runHook postBuild
export PATH=${pathsStr}:\$PATH
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
export STARTUP_FILE=$LISPDIR/lisp/fg42_init.el
export FG42_PATH=$out
cat >> $out/bin/fg42-wm << EOF
#!${stdenv.shell}
export PATH=${pathsStr}:\$PATH
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
export STARTUP_FILE=$LISPDIR/lisp/fg42_init.el
# 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 $STARTUP_FILE "\$@"
EOF
chmod +x $out/bin/fg42-wm
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 "$STARTUP_FILE" "\$@"
EOF
chmod +x $out/bin/fg42
runHook postBuild
'';
LISPDIR=$out/share/fg42/lisp/
mkdir -p $LISPDIR
#emacs --batch -l package --eval "(package-generate-autoloads \"${pname}\" \"$LISPDIR\")"
buildInputs = [ emacs emacsBundle git texinfo gcc bash ];
addEmacsNativeLoadPath = true;
# =============================
# Creating the fg42-wm command
# =============================
cat >> $out/bin/fg42-wm << EOF
#!${stdenv.shell}
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.
export PATH=${pathsStr}:/etc/profiles/per-user/\$USER/bin:\$PATH
export FONTCONFIG_FILE="$LISPDIR/fonts.conf"
export STARTUP_FILE=$LISPDIR/lisp/fg42_init.el
export FG42_PATH=$out
# 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 $STARTUP_FILE "\$@"
EOF
chmod +x $out/bin/fg42-wm
runHook postBuild
'';
postInstall = ''
nixDir=$out/share/fg42/;
mkdir -p $nixDir
cp -rv flake.nix flake.lock nix/ $nixDir
'';
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;
};
};
So you need to know about Emacs in advance.
'';
license = lib.licenses.gpl3Plus;
};
}

View File

@ -16,6 +16,8 @@
{ pkgs, ... }:
final: prev:
rec {
maintainers = import ../../maintainers.nix;
/*
Create a value to be accessable on the Elisp side as a variable.
*/

View File

@ -34,5 +34,4 @@
'';
});
}

View File

@ -25,4 +25,14 @@
fingerprint = "6F3F A93B 4BD9 C3CA EF38 77E6 384A 12C3 1023 3CC5";
}];
};
pouya = {
email = "me@pouyacode.net";
github = "pouya-abbassi";
git = "pouya-abbassi";
name = "Pouya Abbasi";
keys = [{
fingerprint = "8CC7 EB15 3563 4205 E9C2 AAD9 AF5A 5A4A D4FD 8797";
}];
};
}

View File

@ -1,73 +0,0 @@
;;; 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)
(require 'fg42/config))
(use! company
"Company is a modular text completion framework for GNU Emacs."
:hook (emacs-startup . global-company-mode)
:bind (:map company-active-map
("M-n" . company-select-next)
("M-p" . company-select-previous)
("TAB" . company-complete-common-or-cycle)
("M-d" . company-show-doc-buffer))
:init
;; Use Company for completion
(setq company-show-numbers t)
(setq company-idle-delay 0)
(setq company-tooltip-limit 20)
(setq company-echo-delay 0)
(setq company-tooltip-align-annotations t)
(setq company-dabbrev-downcase nil)
:config
(setq-default company-backends
'((company-capf :with company-yasnippet :separate)
(company-keywords :separate)
company-files))
(bind-key [remap completion-at-point] #'company-complete company-mode-map))
(use! company-box
"A company front-end with icons."
:after company
:hook (company-mode . company-box-mode))
;;;###autoload
(defun fg42/autocomplete ()
"Initialize FG42's auto complete.
This function is meant to be used with hooks."
;; Why? because if we end up with more auto completion alternatives
;; to company mode, then we can setup them here rather than walking
;; around fixing downstream modules.
(interactive)
(company-mode t))
(provide 'fg42/autocomplete)
;;; autocomplete.el ends here

View File

@ -28,6 +28,7 @@ let
(with pkgs.emacsPackages; [
eldoc-cmake
ninja-mode
cmake-mode
]);
drv = makeFG42Drv {
@ -38,6 +39,10 @@ let
};
in
{
imports = [
../language-server
];
options.fg42.c-family.enable = mkAndEnableOption "c-family";
config = mkIf cfg.enable {
@ -48,5 +53,9 @@ in
]);
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -35,12 +35,11 @@
"--completion-style=detailed")
"Arguments to pass to clangd.")
(use! cmake-ts-mode
"Enable cmake-ts-mode instead of the non-TS version."
:mode ("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-ts-mode)
(use! cmake-mode
"Enable cmake-mode instead of the non-TS version."
:mode ("\\(?:CMakeLists\\.txt\\|\\.cmake\\)\\'" . cmake-mode)
:hook
(cmake-ts-mode . fg42/autocomplete)
(cmake-ts-mode . fg42/ensure-lang-server)
(cmake-mode . fg42/setup-completion)
(before-save . fg42/lang-server-format))
@ -66,15 +65,13 @@ return value of this function as well."
(split-string ls " "))))
;;;###autoload
(defun fg42/c-ts-mode-setup ()
"A hook handler to setup cpp related configurations."
(cl-defmethod fg42/setup-lang-server-for ((mode (eql c++-ts-mode)))
"Setup the language server for MODE `c++ts-mode'."
(message "[FG42][C/C++]: Make sure to setup clangd to fit your needs. For more info: https://clangd.llvm.org/config")
(fg42/ensure-lang-server)
(when (and (boundp 'eglot-managed-p) (eglot-managed-p))
(add-to-list 'eglot-server-programs
`(c++-ts-mode . ,#'fg42/c_cpp_ls))))
(require 'eglot)
(add-to-list 'eglot-server-programs
`(c++-ts-mode . ,#'fg42/c_cpp_ls))
(eglot-ensure))
(use! c-ts-mode
@ -86,10 +83,8 @@ return value of this function as well."
(add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode))
:hook
(c++-ts-mode . fg42/autocomplete)
(c++-ts-mode . fg42/c-ts-mode-setup)
(c++-ts-mode . flyspell-prog-mode)
(before-save . fg42/lang-server-format))
(c++-ts-mode . fg42/setup-completion)
(c++-ts-mode . flyspell-prog-mode))
(provide 'fg42/c-family)

View File

@ -0,0 +1,59 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.clojure;
deps =
(with pkgs.emacsPackages; [
cider
clojure-ts-mode
flycheck-clj-kondo
]);
drv = makeFG42Drv {
pname = "clojure";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.clojure.enable = mkAndEnableOption "clojure";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.paths = (with pkgs;[
clojure-lsp
clojure
leiningen
]);
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ maintainers.pouya ];
doc = ./README.md;
};
};
}

View File

@ -21,26 +21,30 @@
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
;; emacs --batch --eval=(require 'ox-texinfo) --eval=(find-file "README.org\") --eval=(org-texinfo-export-to-info)
(require ox-texinfo)
(use! flycheck-clj-kondo
"flycheck linter for clojure using `clj-kondo'."
:after clojure-ts-mode)
(org-texinfo-export-to-info)
(use! paredit
"Minor mode for editing parenthesis."
:commands enable-paredit-mode)
(defun build-manual ()
"Build FG42's manual."
(interactive)
(with-temp-buffer
(find-file (file-name-concat (expand-file-name fg42-home) "docs/fg42.org"))
(org-texinfo-export-to-info)))
(use! cider
"Clojure(Script) Interactive Development Environment that Rocks!"
:after clojure-ts-mode)
(use! clojure-ts-mode
"Clojure mode"
:mode (("\\.clj\\'" . clojure-ts-mode)
("\\.cljs\\'" . clojure-ts-mode)
("\\.cljc\\'" . clojure-ts-mode))
(defun fg42-manual ()
"Show FG42's manual."
(interactive)
;; TODO: move this to the init script
(add-to-list 'Info-default-directory-list (file-name-concat (expand-file-name fg42-home) "docs/"))
(info "(fg42)"))
:hook
(clojure-ts-mode . enable-paredit-mode)
)
(provide 'fg42/help)
;;; help.el ends here
(provide 'fg42/clojure)
;;; clojure.el ends here

View File

@ -0,0 +1,69 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.completion;
deps =
(with pkgs.emacsPackages;
optionals (cfg.backend == "corfu") [
corfu
cape
] ++ optionals (config.fg42.graphics.enable && cfg.backend == "corfu") [
nerd-icons-corfu
]
++ optionals (cfg.backend == "company") [
company
company-box
]);
drv = makeFG42Drv {
pname = "completion";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
backendDesc = ''
The backend to use for the completion. (default corfu)
'';
in
{
options.fg42.completion = {
enable = mkAndEnableOption "completion";
backend = mkOption {
type = types.str;
default = "corfu";
description = backendDesc;
};
};
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.requires = [ drv.pname ];
fg42.vars = [
(defVar "completion" cfg.enable "Completion for FG42.")
(defVar "completion-backend" cfg.backend backendDesc)
];
};
}

View File

@ -0,0 +1,154 @@
;;; 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)
(require 'fg42/config))
(config-when "completion-backend" "company"
(use! company
"Company is a modular text completion framework for GNU Emacs."
:hook (emacs-startup . global-company-mode)
:bind (:map company-active-map
("M-n" . company-select-next)
("M-p" . company-select-previous)
("TAB" . company-complete-common-or-cycle)
("M-d" . company-show-doc-buffer))
:init
;; Use Company for completion
(setq company-show-numbers t)
(setq company-idle-delay 0)
(setq company-tooltip-limit 20)
(setq company-echo-delay 0)
(setq company-tooltip-align-annotations t)
(setq company-dabbrev-downcase nil)
:config
(setq-default company-backends
'(company-capf (company-keywords :separate) company-files))
(bind-key [remap completion-at-point] #'company-complete company-mode-map))
(use! company-box
"A company front-end with icons."
:after company
:hook (company-mode . company-box-mode)))
(config-when "completion-backend" "corfu"
(use! corfu
"Corfu enhances in-buffer completion with a small completion popup.
The current candidates are shown in a popup below or above the point. The candidates
can be selected by moving up and down. Corfu is the minimalistic in-buffer completion
counterpart of the Vertico minibuffer UI."
:custom
(corfu-cycle t) ;; Enable cycling for `corfu-next/previous'
(corfu-auto t) ;; Enable auto completion
(corfu-separator ?*) ;; Orderless field separator
(corfu-quit-no-match 'separator)
(corfu-quit-at-boundary 'separator)
(corfu-quit-no-match t)
(corfu-preview-current 'insert) ;; Disable current candidate preview
(corfu-preselect 'first) ;; Preselect the prompt
(corfu-on-exact-match 'insert) ;; Configure handling of exact matches
(corfu-scroll-margin 5) ;; Use scroll margin
(corfu-left-margin-width 2.0)
(corfu-right-margin-width 2.0)
:bind
(:map corfu-map ("<escape>" . corfu-quit))
(:map corfu-map ("M-SPC" . corfu-insert-separator))
:hook
(emacs-startup . global-corfu-mode)
(corfu-mode . (lambda ()
(require 'corfu-popupinfo)
(require 'corfu-indexed)
(corfu-popupinfo-mode)
(corfu-indexed-mode)
(dotimes (i 10)
(define-key corfu-mode-map
(kbd (format "M-%s" i))
(kbd (format "C-%s <tab>" i)))))))
(use! cape
"Cape provides Completion At Point Extensions which can be used
in combination with Corfu, Company or the default completion UI."
:bind (("C-c p p" . completion-at-point) ;; capf
("C-c p t" . complete-tag) ;; etags
("C-c p d" . cape-dabbrev) ;; or dabbrev-completion
("C-c p h" . cape-history)
("C-c p f" . cape-file)
("C-c p k" . cape-keyword)
("C-c p s" . cape-elisp-symbol)
("C-c p e" . cape-elisp-block)
("C-c p a" . cape-abbrev)
("C-c p l" . cape-line)
("C-c p w" . cape-dict)
("C-c p :" . cape-emoji)
("C-c p \\" . cape-tex)
("C-c p _" . cape-tex)
("C-c p ^" . cape-tex)
("C-c p &" . cape-sgml)
("C-c p r" . cape-rfc1345))
:init
;; Add to the global default value of `completion-at-point-functions' which is
;; used by `completion-at-point'. The order of the functions matters, the
;; first function returning a result wins. Note that the list of buffer-local
;; completion functions takes precedence over the global list.
;;(add-to-list 'completion-at-point-functions #'cape-history)
;;(add-to-list 'completion-at-point-functions #'cape-tex)
;;(add-to-list 'completion-at-point-functions #'cape-sgml)
;;(add-to-list 'completion-at-point-functions #'cape-rfc1345)
;;(add-to-list 'completion-at-point-functions #'cape-abbrev)
;;(add-to-list 'completion-at-point-functions #'cape-dict)
;;(add-to-list 'completion-at-point-functions #'cape-line)
;;(add-to-list 'completion-at-point-functions #'cape-keyword)
(add-to-list 'completion-at-point-functions #'cape-elisp-symbol)
(add-to-list 'completion-at-point-functions #'cape-dabbrev)
(add-to-list 'completion-at-point-functions #'cape-file)
(add-to-list 'completion-at-point-functions #'cape-elisp-block))
(with-config "graphics"
(use! nerd-icons-corfu
"Nerd icon integration with corfu."
:after corfu
:config
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))))
;;;###autoload
(defun fg42/setup-completion ()
"Initialize FG42's completion system.
This function is meant to be used with hooks."
;; Why? because if we end up with more auto completion alternatives
;; to corfu or company mode, then we can setup them here rather than walking
;; around fixing downstream modules.
(interactive)
(config-when "completion-backend" "company"
(company-mode t)))
(provide 'fg42/completion)
;;; completion.el ends here

View File

@ -28,11 +28,20 @@ let
./minibuffer-vertico
./graphics
./noether
./autocomplete
./completion
./language-server
./nix
./c-family
./python
./clojure
./haskell
./wm
./verilog
./workspace
./rss
./organize
./terminals
./document-viewer
];
in
modules

View File

@ -0,0 +1,59 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.document-viewer;
deps =
(with pkgs.emacsPackages; [
pdf-tools
]);
drv = makeFG42Drv {
pname = "document-viewer";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.document-viewer.enable = mkAndEnableOption "document-viewer";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.paths = (with pkgs;[
poppler
imagemagick
]);
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -25,18 +25,14 @@
(require 'fpkg))
(use! eros
"Evaluation Result OverlayS for Emacs Lisp."
:commands eros-mode)
(use! elisp-mode
"Elisp mode."
:hook
((emacs-lisp-mode . rainbow-delimiters-mode)
(emacs-lisp-mode . paredit-mode)
(emacs-lisp-mode . company-mode)
(emacs-lisp-mode . eros-mode)))
(use! pdf-tools
"A complete pdf suit for Emacs."
:config
;; open pdfs scaled to fit page
(setq-default pdf-view-display-size 'fit-page)
;; automatically annotate highlights
(setq pdf-annot-activate-created-annotations t))
(provide 'fg42/langs/elisp)
;;; elisp.el ends here
(provide 'fg42/document-viewer)
;;; document-viewer.el ends here

View File

@ -26,9 +26,6 @@ let
deps =
(with pkgs.emacsPackages; [
origami
which-key
projectile
projectile-ripgrep
pkg-info
expand-region
direnv
@ -39,15 +36,16 @@ let
exec-path-from-shell
avy
ace-window
yasnippet
yasnippet-snippets
flycheck
org
org-super-agenda
rainbow-delimiters
org-ql
org-modern
base16-theme
tempel
tempel-collection
beacon
hydra
transient
rg
embark
]);
drv = makeFG42Drv {
@ -80,5 +78,10 @@ in
size = 11;
};
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ lib.maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -25,71 +25,63 @@
(require 'fpkg)
;; We build this file via the main FG42's Nix derivation. It
;; contains the final Nix configuration of FG42.
(require 'fg42/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/wm)
(require 'fg42/organize))
(require 'fg42/config))
(require 'server)
(require 'fg42/utils)
(defun fg42/setup-font ()
"Set the default font of `FG42' to FONT-NAME and FONT-SIZE."
(let ((name (fg42/config-get font-name))
(size (fg42/config-get font-size)))
(let ((name (config-get font-name))
(size (config-get font-size)))
(add-to-list 'default-frame-alist
(cons 'font (format "%s-%d" name size)))
(set-face-attribute 'default t :font name)))
(use! origami
"A text folding minor mode for Emacs."
(use! embark
"Emacs Mini-Buffer Actions Rooted in Keymaps."
:bind
(("C-c TAB" . origami-toggle-node))
(("C--" . embark-act) ;; pick some comfortable binding
("C-;" . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
;; Optionally replace the key help with a completing-read interface
(setq prefix-help-command #'embark-prefix-help-command)
;; Show the Embark target at point via Eldoc. You may adjust the
;; Eldoc strategy, if you want to see the documentation from
;; multiple providers. Beware that using this can be a little
;; jarring since the message shown in the minibuffer can be more
;; than one line, causing the modeline to move up and down:
;; (add-hook 'eldoc-documentation-functions #'embark-eldoc-first-target)
;; (setq eldoc-documentation-strategy #'eldoc-documentation-compose-eagerly)
: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)))
;; Hide the mode line of the Embark live/completions buffers
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
(use! projectile-ripgrep
"Use ripgrep with projectile"
:after projectile)
(use! origami
"A text folding minor mode for Emacs."
:bind
(("C-c TAB" . origami-toggle-node))
:config
(global-origami-mode t))
(use! rg
"A ripgrep based search utility."
:commands rg-menu
:bind
("C-c s" . rg-menu)
("C-c p s" . rg-dwim-project-dir))
(use! pkg-info
@ -112,44 +104,53 @@ contextual information."
("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))
:bind ("C-c g" . 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"
@ -165,35 +166,18 @@ contextual information."
: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))
(use! rainbow-delimiters
"It is a rainbow parentheses like mode which highlights delimiters such as
parentheses, brackets or braces according to their depth."
@ -207,6 +191,55 @@ contextual information."
(direnv-mode))
(use! tempel
"Tempel is a tiny template package for Emacs, which uses the syntax
of the Emacs Tempo library."
:bind (("M-=" . tempel-complete) ;; Alternative tempel-expand
("M-*" . tempel-insert)
("C-," . tempel-previous)
("C-." . tempel-next))
:init
;; Setup completion at point
(defun tempel-setup-capf ()
;; Add the Tempel Capf to `completion-at-point-functions'.
;; `tempel-expand' only triggers on exact matches. Alternatively use
;; `tempel-complete' if you want to see all matches, but then you
;; should also configure `tempel-trigger-prefix', such that Tempel
;; does not trigger too often when you don't expect it. NOTE: We add
;; `tempel-expand' *before* the main programming mode Capf, such
;; that it will be tried first.
(setq-local completion-at-point-functions
(cons #'tempel-expand
completion-at-point-functions)))
(add-hook 'conf-mode-hook 'tempel-setup-capf)
(add-hook 'prog-mode-hook 'tempel-setup-capf)
(add-hook 'text-mode-hook 'tempel-setup-capf))
(use! tempel-collection
"A collection of tempel templates.")
(use! hydra
"Once you summon the Hydra through the prefixed binding (the
body+ any one head), all heads can be called in succession with only a
short extension."
:init
(require 'hydra)
:hook (emacs-startup . hydra-add-imenu)
:config
(defhydra hydra-zoom (global-map "<f2>")
"zoom"
("g" text-scale-increase "in")
("l" text-scale-decrease "out")))
(use! beacon
"Never lose sight of your curser."
:hook (emacs-startup . beacon-mode))
(defun fg42/setup-editor ()
"Setup the overall functionality of FG42."
@ -242,6 +275,12 @@ contextual information."
(setq tooltip-use-echo-area t)
(setq x-gtk-use-system-tooltips nil)
;; Emacs 30 and newer: Disable Ispell completion function.
(setq text-mode-ispell-word-completion nil)
;; Enable indentation+completion using the TAB key.
;; `completion-at-point' is often bound to M-TAB.
(setq tab-always-indent 'complete)
;; Global configurations
(tool-bar-mode -1)
(tooltip-mode nil)
@ -253,14 +292,9 @@ contextual information."
(scroll-bar-mode -1))
(defalias 'yes-or-no-p 'y-or-n-p)
;; 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)
@ -268,11 +302,9 @@ contextual information."
(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
@ -283,14 +315,8 @@ contextual information."
(when (not (server-running-p))
(when-wm
(setq server-name "fg42-wm"))
(server-start)
(require 'org-protocol))
(server-start))
(when-wm
;; Activating the WM mode
(exwm-enable)
(exwm-systemtray-enable)
(exwm-randr-enable))
(message "[FG42]: Use `fg42-help' to get help."))

View File

@ -1,158 +0,0 @@
;;; 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))
(defvar fg42/org-super-agenda-groups nil)
(defvar fg42/org-home "~/.orgs"
"The location to the org file repository.")
(defvar fg42/default-org-journal-heder
"
#+TITLE: Yearly Journal
#+STARTUP: folded logdrawer logdone logreschedule indent content align constSI entitiespretty
"
"Org journal header.")
(defvar fg42/notes-file "notes.org")
(defvar fg42/global-tags nil)
(defvar fg42/agenda-files "main.org")
(use! org-ql
"This package provides a query language for Org files. It offers two
syntax styles: Lisp-like sexps and search engine-like keywords.
It includes three libraries: The `org-ql' library is flexible and may
be used as a backend for other tools. The libraries `org-ql-search' and
`helm-org-ql' (a separate package) provide interactive search commands
and saved views."
:after org)
(use! org-super-agenda
"This package lets you supercharge your Org daily/weekly agenda. The idea is
to group items into sections, rather than having them all in one big list.
Now you can sort-of do this already with custom agenda commands, but when you
do that, you lose the daily/weekly aspect of the agenda: items are no longer
shown based on deadline/scheduled timestamps, but are shown no-matter-what.
h
For more information checkout `https://github.com/alphapapa/org-super-agenda'"
:after org-agenda
:config
(setq org-agenda-skip-scheduled-if-done t
org-agenda-skip-deadline-if-done t
org-agenda-include-deadlines t
org-agenda-compact-blocks t
org-agenda-start-day nil ;; Today
org-agenda-span 1
org-super-agenda-groups fg42/org-super-agenda-groups)
(org-super-agenda-mode))
(use! org-capture
"Quickly capture what is in your head."
:bind (("<f6>" . org-capture))
:init
(setq-default
org-capture-templates
(eval
`(list
'("t" "Todo" entry (file+headline ,(expand-file-name "main.org" fg42/org-home) "New Tasks")
(file ,(expand-file-name "templates/todo" fg42/org-home))
:prepend t)
'("l" "Link" entry (file+headline ,(expand-file-name "bookmarks.org" fg42/org-home) "Links")
(file ,(expand-file-name "templates/links" fg42/org-home))
:prepend t
:immediate-finish t
:empty-lines 1)
'("h" "Thoughts" entry (file+datetree ,(expand-file-name "journal.org" fg42/org-home))
(file ,(expand-file-name "templates/thoughts" fg42/org-home)))))))
(use! org-protocol
"`org-protocol' intercepts calls from emacsclient to trigger custom actions without external
dependencies. Only one protocol has to be configured with your external applications or
the operating system, to trigger an arbitrary number of custom actions. Just register
your custom sub-protocol and handler with the variable `org-protocol-protocol-alist'.")
(use! org
"A GNU Emacs major mode for keeping notes, authoring documents, computational notebooks,
literate programming, maintaining to-do lists, planning projects, and more in a fast
and effective plain text system.
For more info on ~org-mode~ check out `https://orgmode.org/'"
:hook (org-mod . flyspell-mode)
:init
(setq
org-auto-align-tags nil
org-tags-column 0
org-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t)
org-tag-alist fg42/global-tags
;; Org styling, hide markup etc.
org-hide-emphasis-markers t
org-pretty-entities t
org-ellipsis ""
;; Agenda styling
org-agenda-tags-column 0
org-agenda-block-separator ?─
org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
org-agenda-current-time-string
"<── now ─────────────────────────────────────────────────"
org-agenda-files (concat (file-name-as-directory fg42/org-home)
fg42/agenda-files)
org-directory fg42/org-home
org-default-notes-file (concat (file-name-as-directory fg42/org-home)
fg42/notes-file)
org-refile-targets '((org-agenda-files :maxlevel . 3))
(with-eval-after-load "ox-latex"
(setq org-latex-default-packages-alist
(append '(("hidelinks" "hyperref" nil))
org-latex-default-packages-alist))))
(use! org-modern
"A modern look for the old org."
:hook ((org-mode . org-modern-mode)
(org-agenda-finalize . org-modern-mode)))
(provide 'fg42/organize)
;;; organize.el ends here

View File

@ -40,4 +40,10 @@ in
fg42.elispPackages = [ drv ] ++ deps;
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ lib.maintainers.lxsameer ];
doc = ./README.md;
};
}

View File

@ -24,6 +24,15 @@
(eval-when-compile
(require 'fpkg))
(cl-defmethod fg42/format-buffer-for ((mode (eql emacs-lisp-mode)))
"Disable the language server formatting for `emacs-lisp-mode' MODE.
Since we're using `Emacs' itself to handle formatting, we don't need
to use this feature. So we can do nothing in this function.")
(cl-defmethod fg42/setup-lang-server-for ((mode (eql emacs-lisp-mode)))
"Disable lang server for `emacs-lisp-mode' MODE.")
(use! eros
"Evaluation Result OverlayS for Emacs Lisp."
@ -38,7 +47,6 @@
"Elisp mode."
:hook
(emacs-lisp-mode . enable-paredit-mode)
(emacs-lisp-mode . fg42/lang-server-format)
(emacs-lisp-mode . eros-mode))

View File

@ -46,8 +46,16 @@ in
fg42.paths = (with pkgs;[
git
openssh
]);
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -32,7 +32,7 @@ and you've made some changes to the current buffer that are not commited
yet it will highlihgt them for you.
For more info check out `https://github.com/dgutov/diff-hl'."
:commands global-diff-hl-mode
:hook (emacs-startup . global-diff-hl-mode)
:config
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))

View File

@ -0,0 +1,60 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.haskell;
deps =
(with pkgs.emacsPackages; [
haskell-mode
]);
drv = makeFG42Drv {
pname = "haskell";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
imports = [
../language-server
];
options.fg42.haskell.enable = mkAndEnableOption "haskell";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.paths = (with pkgs;[
haskell-language-server
ghc
]);
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -25,36 +25,35 @@
(require 'fpkg))
(use! python-black
"This cube reformats python code using black formatter tool."
:commands (python-black-on-save-mode
python-black-buffer
python-black-region
python-black-statement)
:hook (python-mode . python-black-on-save-mode))
(cl-defmethod fg42/setup-lang-server-for ((mode (eql haskell-mode)))
"Setup the language server for MODE `haskell-mode'."
(require 'eglot)
;; This is just a referece for the future
;; (setq-default eglot-workspace-configuration
;; '((haskell
;; (plugin
;; (stan
;; (globalOn . :json-false))))))
(eglot-ensure))
(use! poetry
"Poetry support for FG42. To use it, just use `M-x poetry'."
:config
(setq poetry-tracking-strategy 'switch-buffer)
:hook (python-mode . poetry-tracking-mode))
(use! python-ts-mode
"Python setup. We're using treesitter version of python mode."
:init
;; Remap the standard python mode
(add-to-list 'major-mode-remap-alist '(python-mode . python-ts-mode))
:config
(setq python-indent-guess-indent-offset-verbose nil)
(use! haskell-mode
"Haskell support for FG42."
:mode ("\\.hs\\'" "\\.lhs\\'" "\\.hsc\\'" "\\.cpphs\\'" "\\.c2hs\\'")
:custom
(eglot-autoshutdown t) ;; shutdown language server after closing last file
(eglot-confirm-server-initiated-edits nil) ;; allow edits without confirmation
:hook
(python-ts-mode . eglot-ensure)
(python-ts-mode . company-mode)
(python-ts-mode . flyspell-prog-mode))
(haskell-mode . fg42/ensure-lang-server)
(haskell-mode . fg42/setup-completion)
(haskell-mode . flyspell-prog-mode))
(provide 'fg42/langs/python)
;;; python.el ends here
(use! haskell-cabal-mode
"Cabal integration."
:mode ("\\.cabal\\'"))
(provide 'fg42/haskell)
;;; haskell.el ends here

View File

@ -23,7 +23,8 @@
;;; Code:
(eval-when-compile
(require 'fpkg)
(require 'fg42/config))
(require 'fg42/config)
(require 'cl-lib))
;; Language Servers and friends
@ -32,6 +33,8 @@
shipped with Emacs."
:commands eglot-ensure)
(use! eldoc-box
"View eldoc stuff in a frame."
:commands eldoc-box-hover-mode
@ -43,6 +46,20 @@ shipped with Emacs."
:init (setq markdown-command "multimarkdown"))
;;;###autoload
(cl-defgeneric fg42/setup-lang-server-for (mode)
"Setup a language server for the given MODE.
Other Nix modules can specialize this function to alter
the default behaviour. For example for C++:
\(cl-defmethod fg42/setup-lang-server-for ((mode (eql c-ts-mode)))
;; Do whatever you want here
)
The default implementation sets up Eglot."
(eglot-ensure))
;;;###autoload
(defun fg42/ensure-lang-server ()
"Setup the appropriate language server for the current buffer.
@ -50,26 +67,49 @@ This function is supposed to be run using a hook.
For example:
(add-hook 'foo-mode-hook #'fg42/enruse-lang-server)
\(add-hook 'foo-mode-hook #'fg42/enruse-lang-server)
or via `use!' `:hook'."
(interactive)
;; TODO: Configure LSP here as an alternative here by looking at
;; the configs in `fg42/config'
(add-hook 'eglot-managed-mode-hook #'eldoc-box-hover-mode t)
(eglot-ensure))
(fg42/setup-lang-server-for major-mode))
;;;###autoload
(cl-defgeneric fg42/format-buffer-for (mode)
"Format the current buffer that managed by major MODE.
By default if the buffer is managed by `eglot' it will
use `eglot-format-buffer' to format the buffer.
Other Nix modules can specialize this function to alter
the default behaviour. For example for C++:
\(cl-defmethod fg42/format-buffer-for ((mode (eql c-ts-mode)))
;; Do whatever you want here
)
The default implementation sets up Eglot."
(when(and (functionp 'eglot-managed-p) (eglot-managed-p))
(eglot-format-buffer)))
;;;###autoload
(defun fg42/lang-server-format ()
"Format the current buffer using the current language server.
This function is supposed to be run as a hook handler."
(interactive)
(cond
((and (functionp 'eglot-managed-p) (eglot-managed-p))
(eglot-format-buffer))))
(fg42/format-buffer-for major-mode))
;; Setup the language server and the formatter
;; On emacs startup
(add-hook 'emacs-startup-hook
(lambda ()
(add-hook 'prog-mode-hook #'fg42/ensure-lang-server)
(add-hook 'before-save-hook #'fg42/lang-server-format)))
(provide 'fg42/language-server)

View File

@ -31,6 +31,9 @@ let
ctrlf
consult
marginalia
embark-consult
] ++ lib.optionals (cfg.floating) [
vertico-posframe
]);
drv = makeFG42Drv {
@ -39,13 +42,26 @@ let
buildInputs = deps;
src = ./.;
};
floatingDocString = "nt";
in
{
options.fg42.minibuffer.vertico.enable = mkAndEnableOption "vertico";
options.fg42.minibuffer.vertico = {
enable = mkAndEnableOption "vertico";
floating = mkOption {
type = types.bool;
default = false;
description = floatingDocString;
};
};
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.requires = [ drv.pname ];
fg42.vars = [
(defVar "floating-vertico" cfg.floating floatingDocString)
];
};
}

View File

@ -25,7 +25,6 @@
(require 'fpkg)
(require 'fg42/config))
(use! vertico
"Vertico provides a performant and minimalistic vertical completion UI
based on the default completion system. The focus of Vertico is to provide
@ -46,12 +45,6 @@
(setq vertico-multiform-commands
'((imenu buffer indexed)))
;; Configure the display per completion category.
;; Use the grid display for files and a buffer
;; for the consult-grep commands.
(setq vertico-multiform-categories
'((file grid)))
(setq vertico-count 10)
(setq vertico-cycle t)
@ -81,127 +74,134 @@ match all of the components in any order."
(use! ctrlf
"Single buffer text search."
:config
(ctrlf-mode +1)))
(ctrlf-mode +1))
(use! consult
"Consult provides search and navigation commands based on the Emacs completion
(use! consult
"Consult provides search and navigation commands based on the Emacs completion
function completing-read. "
;; C-c bindings in `mode-specific-map'
:bind (("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab
("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings in `goto-map'
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line)
("M-g M-g" . consult-goto-line)
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
;; M-s bindings in `search-map'
("M-s d" . consult-fd)
("M-s c" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history) ;; orig. next-matching-history-element
("M-r" . consult-history)) ;; orig. previous-matching-history-element
;; C-c bindings in `mode-specific-map'
:bind (("C-c M-x" . consult-mode-command)
("C-c h" . consult-history)
("C-c k" . consult-kmacro)
("C-c m" . consult-man)
("C-c i" . consult-info)
([remap Info-search] . consult-info)
;; C-x bindings in `ctl-x-map'
("C-x M-:" . consult-complex-command) ;; orig. repeat-complex-command
("C-x b" . consult-buffer) ;; orig. switch-to-buffer
("C-x 4 b" . consult-buffer-other-window) ;; orig. switch-to-buffer-other-window
("C-x 5 b" . consult-buffer-other-frame) ;; orig. switch-to-buffer-other-frame
("C-x t b" . consult-buffer-other-tab) ;; orig. switch-to-buffer-other-tab
("C-x r b" . consult-bookmark) ;; orig. bookmark-jump
("C-x p b" . consult-project-buffer) ;; orig. project-switch-to-buffer
;; Custom M-# bindings for fast register access
("M-#" . consult-register-load)
("M-'" . consult-register-store) ;; orig. abbrev-prefix-mark (unrelated)
("C-M-#" . consult-register)
;; Other custom bindings
("M-y" . consult-yank-pop) ;; orig. yank-pop
;; M-g bindings in `goto-map'
("M-g f" . consult-flymake) ;; Alternative: consult-flycheck
("M-g g" . consult-goto-line)
("M-g M-g" . consult-goto-line)
("M-g o" . consult-outline) ;; Alternative: consult-org-heading
("M-g m" . consult-mark)
("M-g k" . consult-global-mark)
;; M-s bindings in `search-map'
("M-s d" . consult-fd)
("M-s c" . consult-locate)
("M-s g" . consult-grep)
("M-s G" . consult-git-grep)
("M-s r" . consult-ripgrep)
("M-s l" . consult-line)
("M-s L" . consult-line-multi)
("M-s k" . consult-keep-lines)
("M-s u" . consult-focus-lines)
;; Isearch integration
("M-s e" . consult-isearch-history)
:map isearch-mode-map
("M-e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s e" . consult-isearch-history) ;; orig. isearch-edit-string
("M-s l" . consult-line) ;; needed by consult-line to detect isearch
("M-s L" . consult-line-multi) ;; needed by consult-line to detect isearch
;; Minibuffer history
:map minibuffer-local-map
("M-s" . consult-history) ;; orig. next-matching-history-element
("M-r" . consult-history)) ;; orig. previous-matching-history-element
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
;; Enable automatic preview at point in the *Completions* buffer. This is
;; relevant when you use the default completion UI.
:hook (completion-list-mode . consult-preview-at-point-mode)
:init
;; Configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
:init
;; Configure the register formatting. This improves the register
;; preview for `consult-register', `consult-register-load',
;; `consult-register-store' and the Emacs built-ins.
(setq register-preview-delay 0.5
register-preview-function #'consult-register-format)
;; Tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
;; Tweak the register preview window.
;; This adds thin lines, sorting and hides the mode line of the window.
(advice-add #'register-preview :override #'consult-register-window)
:config
(when-wm
:config
(when-wm
(consult-customize
;; Set preview for `consult-buffer' to key `M-.'
consult-buffer :preview-key nil))
;; For some reason `consult's autoloads do not work
(require 'consult-xref)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
;; Set preview for `consult-buffer' to key `M-.'
consult-buffer :preview-key nil))
;; For some reason `consult's autoloads do not work
(require 'consult-xref)
;; Use Consult to select xref locations with preview
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
;; Configure preview. The default value
;; is 'any, such that any key triggers the preview.
;; (setq consult-preview-key 'any)
;; (setq consult-preview-key "M-.")
;; (setq consult-preview-key '("S-<down>" "S-<up>"))
;; For some commands and buffer sources it is useful to configure the
;; :preview-key on a per-command basis using the `consult-customize' macro.
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
;; :preview-key "M-."
:preview-key '(:debounce 0.4 any))
;; Configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; "C-+"
(autoload 'projectile-project-root "projectile")
(setq consult-project-function (lambda (_) (projectile-project-root)))
;; Configure the narrowing key.
;; Both < and C-+ work reasonably well.
(setq consult-narrow-key "<") ;; "C-+"
(setq consult-project-function (lambda (_) (when (project-current)
(project-root (project-current)))))
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
)
;; Optionally make narrowing help available in the minibuffer.
;; You may want to use `embark-prefix-help-command' or which-key instead.
;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)
)
;; For some reason `consult's autoloads do not work
(use! consult-imenu
"Setup the `consult-imenu' stuff."
:after consult
:bind (("M-i" . consult-imenu)
("M-I" . consult-imenu-multi)))
;; For some reason `consult's autoloads do not work
(use! consult-imenu
"Setup the `consult-imenu' stuff."
:after consult
:bind (("M-i" . consult-imenu)
("M-I" . consult-imenu-multi)))
(use! consult-compile
"Setup the `consult-compile' stuff."
:after consult
:bind (("M-g e" . consult-compile-error)))
(use! consult-compile
"Setup the `consult-compile' stuff."
:after consult
:bind (("M-g e" . consult-compile-error))))
(use! embark-consult
"Embark integration for consult"
:hook
(embark-collect-mode . consult-preview-at-point-mode))
(with-config "graphics"
@ -213,5 +213,16 @@ match all of the components in any order."
(add-hook 'marginalia-mode-hook #'nerd-icons-completion-marginalia-setup)))
(with-config "floating-vertico"
(use! vertico-posframe
"This is an vertico extension, which lets vertico use posframe to show
its candidate menu."
:hook (emacs-startup . vertico-posframe-mode)
:config
(setq vertico-posframe-parameters
'((left-fringe . 1)
(right-fringe . 1)
(border . 1)))))
(provide 'fg42/minibuffer-vertico)
;;; minibuffer-vertico.el ends here

View File

@ -55,5 +55,9 @@ in
]);
fg42.requires = [ "${drv.pname}-support" ];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -23,7 +23,19 @@
;;; Code:
(eval-when-compile
(require 'fpkg)
(require 'fg42/config))
(require 'fg42/config)
(require 'cl-lib))
(cl-defmethod fg42/setup-lang-server-for ((mode (eql nix-mode)))
"Setup the lang server for the `nix-mode' as MODE."
(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)))
(eglot-ensure))
(use! nix-mode
@ -31,18 +43,7 @@
:mode ("\\.nix\\'" "\\.nix.in\\'")
:hook
(nix-mode . fg42/ensure-lang-server)
(nix-mode . fg42/autocomplete)
(nix-mode . flyspell-prog-mode)
: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)
(add-hook 'before-save-hook #'fg42/lang-server-format))))
(nix-mode . flyspell-prog-mode))
(use! nix-drv-mode

View File

@ -27,13 +27,13 @@
(require 'noether)
(require 'noether-units)
(require 'projectile)
(require 'project)
(with-config "graphics"
(require 'nerd-icons)
(defvar fg42/-mode-icon)
(defun fg42/-update-mode-icon ()
"Set the current buffer name to the watched var."
(setq fg42/-mode-icon major-mode))

View File

@ -48,6 +48,7 @@
:binding (kbd "C-c 0")
:buffer "*modeline*"
:visible? t
:separator " "
:timeout 0
:on-parent-resize #'fg42/adjust-modeline
:frame
@ -55,7 +56,7 @@
:right-fringe 5
:poshandler #'fg42/--bottom-right
:border-width 0
:font (format "%s %s" (fg42/config-get font-name) (- (fg42/config-get font-size) 1))
:font (format "%s %s" (config-get font-name) (- (config-get font-size) 1))
:border-color "#bd93f9")
:units
@ -67,7 +68,7 @@
(buffer-name-unit
:label (format "%s " (nerd-icons-codicon "nf-cod-layers"))
:len 20)
(projectile-project-unit
(project-unit
:label (format "%s " (nerd-icons-octicon "nf-oct-project"))
:len 20)
(git-branch-unit
@ -81,7 +82,7 @@
(buffer-name-unit
:label "B: "
:len 20)
(projectile-project-unit
(project-unit
:label "P: "
:len 20)
(git-branch-unit
@ -103,7 +104,35 @@ Appears on the center of the current window."
(list
:poshandler #'fg42/--bottom-right-padded
:border-width 0
:font (format "%s %s" (fg42/config-get font-name) (fg42/config-get font-size))
:font (format "%s %s" (config-get font-name) (config-get font-size))
:border-color "#bd93f9")
:units
(list
(buffer-name-unit
:label (format "%s " (nerd-icons-codicon "nf-cod-layers"))
:len 30)
(fg42/exwm-input-mode-unit :label (format "%s " (nerd-icons-faicon "nf-fa-linux")))
(date-unit :label (format "%s " (nerd-icons-codicon "nf-cod-calendar")))
(time-unit :label (format " %s " (nerd-icons-mdicon "nf-md-clock_time_three")))))
(noether-defview fg42/exwm-modeline
"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 0")
:separator " "
:visible? t
:sticky t
:hide-when-minibuffer? t
:timeout 0
:on-parent-resize #'fg42/adjust-modeline
:frame
(list
:poshandler #'fg42/--bottom-right-padded
:border-width 0
:font (format "%s %s" (config-get font-name) (config-get font-size))
:border-color "#bd93f9")
:units

View File

@ -53,7 +53,6 @@
"Smart mode line is a pretty simple yet fantastic alternative
to Emacs modeline."
:if (display-graphic-p)
;;:after projectile
:commands noether-global-mode
:hook (emacs-startup . noether-global-mode)
:config
@ -76,13 +75,14 @@ to Emacs modeline."
(default-value 'face-remapping-alist) face-remaps))
(add-to-list 'fg42/noether-views fg42/modeline))
;; Setup modelines
(when-not-wm
(setq-default noether-views fg42/noether-views))
(when-wm
(setq-default noether-views (list fg42/minimal-exwm))))
;; TODO: Fix `fg42/minimal-exwm' to pop up on every workspace (list fg42/exwm-modeline)
(setq-default noether-views nil)))
(provide 'fg42/noether)

View File

@ -0,0 +1,86 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.organize;
deps =
(with pkgs.emacsPackages; [
org
org-super-agenda
org-ql
org-modern
org-roam
org-roam-ui
websocket
simple-httpd
citar
citar-embark
citar-org-roam
citeproc
f
]);
drv = makeFG42Drv {
pname = "organize";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
imports = [
../editor
];
options.fg42.organize = {
enable = mkAndEnableOption "organize";
org-dir = mkOption {
type = types.str;
default = "~/orgs";
example = literalExpression ''"~/orgs"'';
description = mdDoc ''
A non-nix `path` (string `path`) of the location your want org-mode
to store you org files.
'';
};
};
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.requires = [ drv.pname ];
fg42.vars = [
(defVar "org-home" cfg.org-dir "Where to store org files.")
];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -0,0 +1,325 @@
;;; 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)
(require 'fg42/utils)
(require 'fg42/config)
(require 'hydra))
;;=============================================================================
;; Vars that user meant to set
;;=============================================================================
(defvar org-home "~/orgs"
"The location to the org file repository.")
(defvar fg42/bibliograhpy-file nil
"A list of `.bib' files no use with citar.
The nil value will force FG42 to look inside `org-home' for a `bibliograghy.bib'
file.")
(defvar fg42/org-main-template "#+TITLE: Main
#+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) CANCELLED(c@/!) FAILED(f@/!)
#+TAGS:
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty
#+ARCHIVE: ./archive.org::
* Inbox
** Tasks
** Thoughts
"
"The template to use to create the main org file.")
(defvar fg42/org-main-file "main.org")
(defvar fg42/org-agenda-files "main.org")
(defvar fg42/global-tags nil)
;;=============================================================================
;; Helper functions
;;=============================================================================
(defun fg42/org-home ()
"Return the directory path to store everthing org related."
(config-get-or "org-dir" org-home))
(defun fg42/create-org-home ()
"Create the org-files directory directory."
(make-directory (fg42/org-home) t))
(defun fg42/organize-setup ()
"Setup all the necessary files and directories to use `org' and `org-roam'."
(interactive)
(fg42/create-org-home)
(let ((main (path-join (fg42/org-home)
fg42/org-main-file)))
(when (not (file-exists-p main))
(with-temp-file main
(insert fg42/org-main-template)))))
;;=============================================================================
;; Package defs
;;=============================================================================
(use! org-ql
"This package provides a query language for Org files. It offers two
syntax styles: Lisp-like sexps and search engine-like keywords.
It includes three libraries: The `org-ql' library is flexible and may
be used as a backend for other tools. The libraries `org-ql-search' and
`helm-org-ql' (a separate package) provide interactive search commands
and saved views."
:after org)
(use! org-super-agenda
"This package lets you supercharge your Org daily/weekly agenda. The idea is
to group items into sections, rather than having them all in one big list.
Now you can sort-of do this already with custom agenda commands, but when you
do that, you lose the daily/weekly aspect of the agenda: items are no longer
shown based on deadline/scheduled timestamps, but are shown no-matter-what.
For more information checkout `https://github.com/alphapapa/org-super-agenda'"
:after org-agenda
:config
(setq org-agenda-skip-scheduled-if-done t
org-agenda-skip-deadline-if-done t
org-agenda-include-deadlines t
org-agenda-compact-blocks t
org-agenda-start-day nil ;; Today
org-agenda-span 1)
(org-super-agenda-mode))
(use! org-capture
"Quickly capture what is in your head."
:bind (("<f6>" . org-capture))
:init
(setq-default
org-capture-templates
`(("t" "Todo" entry
(file+olp ,(path-join (fg42/org-home) fg42/org-main-file) "Inbox" "Tasks")
"*** TODO %^{title}
:PROPERTIES:
:Timestamp: %T
:Context: %x
:END:
%?"
:unnarrowed t
:prepend t)
("f" "Thoughts (Fleeting Notes)" entry
(file+olp ,(path-join (fg42/org-home) fg42/org-main-file) "Inbox" "Thoughts")
"*** %^{Title}
:PROPERTIES:
:Timestamp: %T
:Context: %x
:END:
%?"
:unnarrowed th
:prepend t))))
(use! org-protocol
"`org-protocol' intercepts calls from emacsclient to trigger custom actions without external
dependencies. Only one protocol has to be configured with your external applications or
the operating system, to trigger an arbitrary number of custom actions. Just register
your custom sub-protocol and handler with the variable `org-protocol-protocol-alist'."
:init
(require 'org-protocol))
(use! org
"A GNU Emacs major mode for keeping notes, authoring documents, computational notebooks,
literate programming, maintaining to-do lists, planning projects, and more in a fast
and effective plain text system.
For more info on ~org-mode~ check out `https://orgmode.org/'"
:hook
(org-mod . flyspell-mode)
(org-mode . fg42/organize-setup)
:init
(setq
org-catch-invisible-edits 'show-and-error
org-special-ctrl-a/e t
org-insert-heading-respect-content t
org-tag-alist fg42/global-tags
;; Org styling, hide markup etc.
org-hide-emphasis-markers t
org-pretty-entities t
org-ellipsis ""
;; Agenda styling
org-agenda-tags-column 0
org-agenda-block-separator ?─
org-agenda-time-grid
'((daily today require-timed)
(800 1000 1200 1400 1600 1800 2000)
" ┄┄┄┄┄ " "┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄")
org-agenda-current-time-string
"<── now ─────────────────────────────────────────────────"
org-agenda-files (path-join (fg42/org-home)
fg42/org-agenda-files)
org-directory (fg42/org-home)
org-default-notes-file (path-join (fg42/org-home)
fg42/org-main-file)
org-refile-targets '((org-agenda-files :maxlevel . 3)))
(with-eval-after-load "ox-latex"
(setq org-latex-default-packages-alist
(append '(("hidelinks" "hyperref" nil))
org-latex-default-packages-alist))))
(use! org-modern
"A modern look for the old org."
:hook
(org-mode . org-modern-mode)
(org-agenda-finalize . org-modern-mode))
(use! org-roam
"Create a second brain for yourself with this great knowledge base tool."
:after org
:commands (org-roam-node-find org-roam-node-insert org-roam-capture
org-roam-capture org-roam-ui-mode)
:bind ("C-<f6>" . org-roam-capture)
:hook (server-mode . (lambda () (require 'org-roam-protocol)))
:config
(let ((roam-path (fg42/org-home)))
(make-directory roam-path t)
(setq-default
org-roam-directory (file-truename roam-path)
org-roam-db-update-on-save t
org-roam-completion-everywhere t
org-roam-capture-templates
'(("n" "Note" plain "%?"
:if-new (file+head "%<%Y%m%d%H%M%S>-${slug}.org" "#+title: ${Title}\n")
:unnarrowed t
:empty-lines-before 1)
("r" "Reference Note" entry
:target (file+heading (path-join roam-path "refs" "${citekey}.org") "Litrature Notes")
"* TODO %^{Note title}\nREF: %(org-cite-insert)\n%?\n%?")))
;; Since we control Emacs itself, we can be sure
;; that it is built with SQLite support
(setq org-roam-database-connector 'sqlite-builtin)
(org-roam-db-autosync-mode)))
(use! org-roam-node
"The builtin node module of org-roam"
:after org-roam)
(use! websocket
"Websocket support for Elisp."
:after org-roam)
(use! org-roam-ui
"A nice web UI for `org-roam'"
:after org-roam
:config
(setq org-roam-ui-sync-theme t
org-roam-ui-follow t
org-roam-ui-update-on-save t
org-roam-ui-open-on-start t))
(use! ebib
"A program with which you can manage biblatex and BibTeX database files
without having to edit the raw .bib files"
:bind ("C-c e" . ebib))
(use! citar
"Citar provides a highly-configurable completing-read front-end to browse
and act on BibTeX, BibLaTeX, and CSL JSON bibliographic data, and LaTeX,
markdown, and org-cite editing support."
:init
(setq citar-org-local-bib-files
(or
fg42/bibliograhpy-file
(list (path-join (fg42/org-home) "bibliography.bib"))))
:custom
;; citar-bibliography
(org-cite-global-bibliography
(or
fg42/bibliograhpy-file
(list (path-join (fg42/org-home) "bibliography.bib"))))
(org-cite-insert-processor 'citar)
(org-cite-follow-processor 'citar)
(org-cite-activate-processor 'citar)
(citar-bibliography org-cite-global-bibliography)
:config
(setq citar-at-point-function 'embark-act)
:bind
(:map org-mode-map :package org ("C-c i" . #'org-cite-insert))
:hook
(LaTeX-mode . (lambda ()
(require 'citar-latex)
(require 'citar-capf)
(citar-capf-setup)))
(org-mode . (lambda ()
(require 'citar-capf)
(citar-capf-setup))))
(use! citar-embark
"Citar and embark integration."
:after org
:config (citar-embark-mode))
;; Suprisingly citar won't load `citar-org' on its own.
(use! citar-org
"Citar and org integration."
:after citar)
(use! citar-org-roam
"A package to provide tighter Citar and Org-Roam integration."
:after citar
:config (citar-org-roam-mode))
(defhydra hydra-org-roam (:exit t)
"Org Roam"
("i" org-roam-node-insert "Insert")
("f" org-roam-node-find "Find")
("c" org-roam-capture "Capture")
("u" org-roam-ui-mode "Web UI"))
(global-set-key (kbd "C-c o") 'hydra-org-roam/body)
(provide 'fg42/organize)
;;; organize.el ends here

View File

@ -51,6 +51,10 @@ let
]);
in
{
imports = [
../language-server
];
options.fg42.python-support.enable = mkAndEnableOption "python-support";
config = mkIf cfg.enable {
@ -59,5 +63,9 @@ in
fg42.paths = tools;
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -24,6 +24,11 @@
(eval-when-compile
(require 'fpkg))
(cl-defmethod fg42/format-buffer-for ((mode (eql python-ts-mode)))
"Disable the language server formatting for `python-ts-mode' MODE.
Since we're using `python-black', we don't need to use this feature.
So we can do nothing in this function.")
(use! python-black
"This cube reformats python code using black formatter tool."
@ -51,8 +56,7 @@
(setq python-indent-guess-indent-offset-verbose nil)
:hook
(python-ts-mode . fg42/ensure-lang-server)
(python-ts-mode . fg42/autocomplete)
(python-ts-mode . fg42/setup-completion)
(python-ts-mode . flyspell-prog-mode))

View File

@ -0,0 +1,59 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.rss;
deps =
(with pkgs.emacsPackages; [
elfeed
elfeed-goodies
]);
drv = makeFG42Drv {
pname = "rss";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.rss.enable = mkAndEnableOption "rss";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.requires = [ drv.pname ];
fg42.paths = (with pkgs;[
curl
]);
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -25,15 +25,12 @@
(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))))
(use! elfeed
"The best rss reader you can ask for."
:commands elfeed
:bind
("C-x w" . elfeed))
(provide 'fg42/eglot)
;;; eglot.el ends here
(provide 'fg42/rss)
;;; rss.el ends here

View File

@ -0,0 +1,57 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.terminal;
deps =
(with pkgs.emacsPackages; [
vterm
vterm-toggle
]);
drv = makeFG42Drv {
pname = "terminal";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.terminal.enable = mkAndEnableOption "terminal";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.requires = [ drv.pname ];
fg42.paths = [
pkgs.libvterm
];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -25,25 +25,18 @@
(require 'fpkg))
(use! vterm
"A real terminal emulator in Emacs."
:hook (vterm-mode . (lambda ()
(display-line-numbers-mode -1))))
(use! nix-mode
"Nix language support for Emacs."
:mode "\\.nix\\'"
:hook
(nix-mode . eglot-ensure)
(nix-mode . company-mode)
(nix-mode . flyspell-prog-mode)
(use! vterm-toggle
"Automatically toggle to vterm and back. Quak style (kinda)."
: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))))
(require 'vterm-toggle)
(global-set-key (kbd "<f2>") #'vterm-toggle))
(provide 'fg42/langs/nix)
;;; nix.el ends here
(provide 'fg42/terminal)
;;; terminal.el ends here

View File

@ -0,0 +1 @@
# Unit Module

View File

@ -34,9 +34,60 @@ let
src = ./.;
};
maintainer = mkOptionType {
name = "maintainer";
check = email: elem email (attrValues lib.maintainers);
merge = loc: defs: listToAttrs (singleton (nameValuePair (last defs).file (last defs).value));
};
listOfMaintainers = types.listOf maintainer // {
# Returns list of
# { "module-file" = [
# "maintainer1 <first@nixos.org>"
# "maintainer2 <second@nixos.org>" ];
# }
merge = loc: defs:
zipAttrs
(flatten (imap1
(n: def: imap1
(m: def':
maintainer.merge (loc ++ [ "[${toString n}-${toString m}]" ])
[{ inherit (def) file; value = def'; }])
def.value)
defs));
};
docFile = types.path // {
# Returns tuples of
# { file = "module location"; value = <path/to/doc.xml>; }
merge = loc: defs: defs;
};
in
{
options = {
meta = {
maintainers = mkOption {
type = listOfMaintainers;
internal = true;
default = [ ];
example = literalExpression ''[ lib.maintainers.all ]'';
description = lib.mdDoc ''
List of maintainers of each module. This option should be defined at
most once per module.
'';
};
doc = mkOption {
type = docFile;
internal = true;
example = "./meta.chapter.md";
description = lib.mdDoc ''
Documentation prologue for the set of options of each module. This
option should be defined at most once per module.
'';
};
};
fg42.version = mkOption {
type = types.str;
visible = true;
@ -49,6 +100,7 @@ in
default = pkgs.emacs29.override ({
withTreeSitter = true;
toolkit = "no";
withSQLite3 = true;
});
description = "What Emacs package to use.";
};
@ -188,6 +240,7 @@ in
fg42.theme-package-name = lib.mkDefault "base16-theme";
fg42.vars = [
(lib.defConst "version" cfg.version "FG42's version")
(lib.defVar "font-name" cfg.font.name "The default font for FG42")
(lib.defVar "font-size" cfg.font.size "The default font size for FG42")
(lib.defVar "theme" cfg.theme "The default theme for FG42")
@ -196,6 +249,10 @@ in
'')
];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -25,10 +25,22 @@
(eval-when-compile
(require 'fg42/utils)
(require 'fg42/pre)
(require 'fg42/config)
(defvar package-archives)
(defvar use-package-ensure-function))
(defun fg42-version ()
"Return FG42's version."
(interactive)
(message "FG42 Version %s" (config-get "version")))
(defun fg42-path ()
"Return the path to FG42's installation."
(or (getenv "FG42_PATH") (error "'FG42_PATH' is not set!")))
(defun defer-garbage-collection ()
"Disable garbage collection."
(setq gc-cons-threshold fg42/-gc-cons-threshold))
@ -79,15 +91,15 @@
(run-hooks 'fg42/before-user-config-init-hook)
(require 'fg42/themes)
(when (file-exists-p user-init-file)
(load user-init-file))
(run-hooks 'fg42/after-user-config-init-hook)
(fg42/setup-theme!)
;; (fg42/setup-editor)
(add-hook 'emacs-startup-hook
(lambda ()
(run-hooks 'fg42/after-init-hook)
@ -99,8 +111,10 @@
"The entry point of FG42."
(when (string= (getenv "FG42_DEBUG") "1")
(setq debug-on-error t
edebug-all-forms 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
@ -118,10 +132,21 @@
(or (getenv "FG42_CONFIG_FILE")
(path-join fg42/config-dir "fg42.el")))
(when (boundp 'native-comp-eln-load-path)
(setcar native-comp-eln-load-path fg42/cache-dir))
(when (file-exists-p user-init-file)
(message "[FG42]: Loading user's init file")
(load user-init-file))
;; Load the customization file. In FG42 it is different than
;; the default `user-init-file'
(if (file-exists-p custom-file)
(load custom-file))
(when (file-exists-p custom-file)
(message "[FG42]: Loading user's custom file")
(load custom-file))
;; Load all the autoloads
(package-activate-all)
;; From point forward we can use normal Elisp stuff without
;; interfering with user's Emacs configuration

View File

@ -22,14 +22,14 @@
;;; Commentary:
;;; Code:
(defmacro fg42/config-get (key)
(defmacro config-get (key)
"Return the value for KEY or raise an error."
(let ((sym (intern (format "fg42/config/%s" key))))
(if (boundp sym)
`,sym
`(error "Can't find config '%s'" ,key))))
(defmacro fg42/config-get-or (key &optional default)
(defmacro config-get-or (key &optional default)
"Return the value for KEY or DEFAULT."
(let ((sym (intern (format "fg42/config/%s" key))))
(if (boundp sym)
@ -37,10 +37,23 @@
`,default)))
(defmacro config= (key value)
"Check whether config name KEY has the VALUE or not."
`(string= (config-get-or ,key) ,value))
(defmacro config-when (key value &rest body)
"Run the BODY only if config KEY has the VALUE."
(declare (indent defun))
(when (eval `(config= ,key ,value))
`(progn
,@body)))
(defmacro with-config (name &rest body)
"Run the BODY only if the config NAME is set to t."
(declare (indent defun))
(if (string= (format "%s" (eval `(fg42/config-get-or ,name ""))) "t")
(if (string= (format "%s" (eval `(config-get-or ,name ""))) "t")
`(progn
,@body)
nil))
@ -49,7 +62,7 @@
(defmacro if-config (name then else)
"Eval THEN if the config NAME was t, otherwise ELSE."
(declare (indent defun))
(if (string= (eval `(fg42/config-get-or ,name "")) "t")
(if (string= (eval `(config-get-or ,name "")) "t")
`,then
`,else))

View File

@ -48,11 +48,11 @@ It executes way before the rest of the cubes.")
Load the theme via `use!' and pass the BODY to the `use!' macroro.
If the theme name and the theme package name are different the package
name can be set via `fg42/theme-package'."
`(use! ,(intern (fg42/config-get-or theme-package-name (fg42/config-get theme)))
`(use! ,(intern (config-get-or theme-package-name (config-get theme)))
"Setting up the ,pkg package."
:config
(progn
(load-theme ',(intern (fg42/config-get theme)) t))))
(load-theme ',(intern (config-get theme)) t))))
(provide 'fg42/themes)

View File

@ -74,5 +74,46 @@ same NAME is set to t."
(use! ,name ,docs ,@details)))
(defun add-to-emacs-load-path (p)
"Add the path P to Emacs's load path."
(when (file-directory-p p)
(add-to-list 'load-path p)))
(defun add-emacs-vars (p)
"Make the path P available to Emacs."
(require 'f)
(require 'seq)
(seq-reduce
(lambda (acc x)
(when (not (member x acc))
(when (f-glob "*.el" x)
(cons x acc)
(add-to-emacs-load-path x))))
(append
(f-directories (format "%s/share/emacs/site-lisp" p) nil t)
(f-directories (format "%s/share/emacs/native-lisp" p) nil t))
nil))
(defmacro try! (pkg &rest details)
"Try the PKG with the given DETAILS in the running session.
It will install the package using Nix and make it available to the current
running session. For a persistant installation use `use!'."
(declare (indent defun))
(let ((flake-dir (format "%s/share/fg42" (fg42-path)))
(cwd (getenv "PWD")))
(cd flake-dir)
(let* ((output (shell-command-to-string
(format "nix build '.#%s' --no-link --print-out-paths" pkg)))
(out (car (string-split output "\n" t))))
(add-emacs-vars out)
(cd cwd)
`(use-package ,pkg ,@details))))
(provide 'fpkg)
;;; fpkg.el ends here

View File

@ -0,0 +1,60 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
# A list of default FG42 modules to build FG42 with.
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.verilog;
deps =
(with pkgs.emacsPackages; [
verilog-ext
verilog-mode
]);
drv = makeFG42Drv {
pname = "verilog";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.verilog.enable = mkAndEnableOption "verilog";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.paths = (with pkgs;[
verible
verilator
]);
fg42.requires = [ drv.pname ];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -24,7 +24,6 @@
(eval-when-compile
(require 'fpkg))
(use! verilog-mode
"Add support for verilog and system verilog to FG42. More info at
https://www.veripool.org/verilog-mode/")
@ -55,12 +54,11 @@ https://www.veripool.org/verilog-mode/")
block-end-comments
ports))
:config
(setq verilog-ext-eglot-default-server 've-svls)
(setq verilog-ext-eglot-default-server 've-verible-ls)
;; I care more about ace-window than verilog-hs-toggle.
(define-key verilog-ext-mode-map (kbd "C-<tab>") #'ace-window)
(verilog-ext-eglot-set-server 've-svls)
(verilog-ext-eglot-set-server 've-verible-ls)
(verilog-ext-mode-setup))
(provide 'fg42/langs/verilog)
(provide 'fg42/verilog)
;;; verilog.el ends here

View File

@ -45,6 +45,10 @@
;; (start-process-shell-command
;; "xrandr" nil "xrandr --output HDMI-1 --above eDP-1 --mode 1920x1080")))
(defun fg42/run (command)
"Start a new process by executing the given COMMAND."
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command))
(when-wm
(use! exwm-randr
@ -70,104 +74,116 @@
;; (height . 15))))
(defun fg42/start-wm ()
"The entry point for the WM mode."
(interactive)
(when-wm
(message "[FG42]: Starting the window manager.")
(require 'exwm-config)
;; Set the initial number of workspaces (they can also be created later).
(setq exwm-workspace-number 9)
;; All buffers created in EXWM mode are named "*EXWM*". You may want to
;; change it in `exwm-update-class-hook' and `exwm-update-title-hook', which
;; are run when a new X window class name or title is available. Here's
;; some advice on this topic:
;; + Always use `exwm-workspace-rename-buffer` to avoid naming conflict.
;; + For applications with multiple windows (e.g. GIMP), the class names of
;; all windows are probably the same. Using window titles for them makes
;; more sense.
;; In the following example, we use class names for all windows except for
;; Java applications and GIMP.
(add-hook 'exwm-update-class-hook
(lambda ()
(unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-class-name))))
(add-hook 'exwm-update-title-hook
(lambda ()
(when (or (not exwm-instance-name)
(string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-title))))
;; Global keybindings can be defined with `exwm-input-global-keys'.
;; Here are a few examples:
(setq exwm-input-global-keys
`(
;; Bind "s-r" to exit char-mode and fullscreen mode.
([?\s-r] . exwm-reset)
([?\s-g] . keyboard-quit)
([8388640] . other-window)
;; Bind "s-w" to switch workspace interactively.
([?\s-w] . exwm-workspace-switch)
;; Bind "s-0" to "s-9" to switch to a workspace by its index.
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))
;; Bind "s-&" to launch applications ('M-&' also works if the output
;; buffer does not bother you).
([?\s-d] . fg42/run)
;; Bind "s-<f2>" to "slock", a simple X display locker.
([s-f2] . (lambda ()
(interactive)
(start-process "" nil "slock")))))
;; To add a key binding only available in line-mode, simply define it in
;; `exwm-mode-map'. The following example shortens 'C-c q' to 'C-q'.
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
(push ?\C-c exwm-input-prefix-keys)
;; You can hide the minibuffer and echo area when they're not used, by
;; uncommenting the following line.
;;(setq exwm-workspace-minibuffer-position 'bottom)
;; The following example demonstrates how to use simulation keys to mimic
;; the behavior of Emacs. The value of `exwm-input-simulation-keys` is a
;; list of cons cells (SRC . DEST), where SRC is the key sequence you press
;; and DEST is what EXWM actually sends to application. Note that both SRC
;; and DEST should be key sequences (vector or string).
(setq exwm-input-simulation-keys
`(
;; movement
(,(kbd "C-b") . left)
(,(kbd "M-b") . ,(kbd "C-<left>"))
(,(kbd "C-f") . right)
(,(kbd "M-f") . ,(kbd "C-<right>"))
(,(kbd "C-p") . up)
(,(kbd "C-n") . down)
(,(kbd "C-a") . home)
(,(kbd "C-e") . end)
(,(kbd "M-v") . prior)
(,(kbd "C-v") . next)
(,(kbd "C-d") . delete)
;;(,(kbs "C-k") . [S-end delete])
;; navigation
(,(kbd "C-c b") . ,(kbd "M-<left>"))
(,(kbd "C-c f") . ,(kbd "M-<right>"))
(,(kbd "C-c w") . ,(kbd "C-w"))
(,(kbd "C-w") . ,(kbd "C-x"))
(,(kbd "M-w") . ,(kbd "C-c"))
(,(kbd "C-y") . ,(kbd "C-v"))
;; search
(,(kbd "C-s") . ,(kbd "C-f"))))
;; Activating the WM moder
(exwm-enable)
(exwm-systemtray-enable)
(exwm-randr-enable)
(message "[FG42]: Finished loading the window manager.")))
(use! exwm
"Emacs X Widnow manager."
:commands exwm-enable
:config
(require 'exwm-config)
(exwm-config-ido)
:hook (emacs-startup . fg42/start-wm)))
;; Set the initial number of workspaces (they can also be created later).
(setq exwm-workspace-number 10)
;; All buffers created in EXWM mode are named "*EXWM*". You may want to
;; change it in `exwm-update-class-hook' and `exwm-update-title-hook', which
;; are run when a new X window class name or title is available. Here's
;; some advice on this topic:
;; + Always use `exwm-workspace-rename-buffer` to avoid naming conflict.
;; + For applications with multiple windows (e.g. GIMP), the class names of
;; all windows are probably the same. Using window titles for them makes
;; more sense.
;; In the following example, we use class names for all windows except for
;; Java applications and GIMP.
(add-hook 'exwm-update-class-hook
(lambda ()
(unless (or (string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-class-name))))
(add-hook 'exwm-update-title-hook
(lambda ()
(when (or (not exwm-instance-name)
(string-prefix-p "sun-awt-X11-" exwm-instance-name)
(string= "gimp" exwm-instance-name))
(exwm-workspace-rename-buffer exwm-title))))
;; Global keybindings can be defined with `exwm-input-global-keys'.
;; Here are a few examples:
(setq exwm-input-global-keys
`(
;; Bind "s-r" to exit char-mode and fullscreen mode.
([?\s-r] . exwm-reset)
([?\s-g] . keyboard-quit)
([8388640] . other-window)
;; Bind "s-w" to switch workspace interactively.
([?\s-w] . exwm-workspace-switch)
;; Bind "s-0" to "s-9" to switch to a workspace by its index.
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .
(lambda ()
(interactive)
(exwm-workspace-switch-create ,i))))
(number-sequence 0 9))
;; Bind "s-&" to launch applications ('M-&' also works if the output
;; buffer does not bother you).
([?\s-d] . (lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
;; Bind "s-<f2>" to "slock", a simple X display locker.
([s-f2] . (lambda ()
(interactive)
(start-process "" nil "slock")))))
;; To add a key binding only available in line-mode, simply define it in
;; `exwm-mode-map'. The following example shortens 'C-c q' to 'C-q'.
(define-key exwm-mode-map [?\C-q] #'exwm-input-send-next-key)
(push ?\C-c exwm-input-prefix-keys)
;; You can hide the minibuffer and echo area when they're not used, by
;; uncommenting the following line.
;;(setq exwm-workspace-minibuffer-position 'bottom)
;; The following example demonstrates how to use simulation keys to mimic
;; the behavior of Emacs. The value of `exwm-input-simulation-keys` is a
;; list of cons cells (SRC . DEST), where SRC is the key sequence you press
;; and DEST is what EXWM actually sends to application. Note that both SRC
;; and DEST should be key sequences (vector or string).
(setq exwm-input-simulation-keys
`(
;; movement
(,(kbd "C-b") . left)
(,(kbd "M-b") . ,(kbd "C-<left>"))
(,(kbd "C-f") . right)
(,(kbd "M-f") . ,(kbd "C-<right>"))
(,(kbd "C-p") . up)
(,(kbd "C-n") . down)
(,(kbd "C-a") . home)
(,(kbd "C-e") . end)
(,(kbd "M-v") . prior)
(,(kbd "C-v") . next)
(,(kbd "C-d") . delete)
;;(,(kbs "C-k") . [S-end delete])
;; navigation
(,(kbd "C-c b") . ,(kbd "M-<left>"))
(,(kbd "C-c f") . ,(kbd "M-<right>"))
(,(kbd "C-c w") . ,(kbd "C-w"))
(,(kbd "C-w") . ,(kbd "C-x"))
(,(kbd "M-w") . ,(kbd "C-c"))
(,(kbd "C-y") . ,(kbd "C-v"))
;; search
(,(kbd "C-s") . ,(kbd "C-f"))))))
(provide 'fg42/wm)

View File

@ -22,30 +22,33 @@
{ lib, config, pkgs, makeFG42Drv, ... }:
with lib;
let
cfg = config.fg42.auto-complete;
cfg = config.fg42.workspace;
deps =
(with pkgs.emacsPackages; [
company
company-box
perspective
]);
drv = makeFG42Drv {
pname = "autocomplete";
pname = "workspace";
version = config.fg42.version;
buildInputs = deps;
src = ./.;
};
in
{
options.fg42.auto-complete.enable = mkAndEnableOption "auto-complete";
options.fg42.workspace.enable = mkAndEnableOption "workspace";
config = mkIf cfg.enable {
fg42.elispPackages = [ drv ] ++ deps;
fg42.requires = [ drv.pname ];
fg42.vars = [
(defVar "auto-complete" cfg.enable "Auto completion for FG42.")
];
meta = {
maintainers = [ maintainers.lxsameer ];
doc = ./README.md;
};
};
}

View File

@ -1,4 +1,4 @@
;;; ElispCube --- The elisp cube for FG42 -*- lexical-binding: t; -*-
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;;
@ -21,18 +21,21 @@
;;
;;; Commentary:
;;; Code:
(require 'fpkg)
(eval-when-compile
(require 'fpkg))
(when-not-wm
(use! perspective
"The Perspective package provides multiple named workspaces (or perspectives)
in Emacs"
:commands persp-mode
:hook (emacs-startup . persp-mode)
:bind
("C-x C-b" . persp-list-buffers)
:custom
;; This has a conflict with wm's C-c w
(persp-mode-prefix-key (kbd "C-c w"))))
(defun fg42/setup-elisp ()
"Setup the Emacs Lisp development environment."
(use! eros
:init
(require 'eros)
(eros-mode))
(add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode))
(provide 'fg42/cubes/elisp)
;;; elisp.el ends here
(provide 'fg42/workspace)
;;; workspace.el ends here

View File

@ -17,4 +17,4 @@
# This is the home manager module that exposes FG42. It differs
# from FG42 modules that are structurally the same but used in
# different context
_: "4.0.0"
_: "4.1.1"

View File

@ -1,8 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: C++-mode section
# key: sec
# --
// ----------------------------------------------------------------------------
// $0
// ----------------------------------------------------------------------------

View File

@ -1,8 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex begin block
# key: al*
# --
\begin{align*}
$0
\end{align*}

View File

@ -1,8 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex begin block
# key: begin
# --
\begin{$1}
$0
\end{$1}

View File

@ -1,8 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex begin block
# key: block
# --
#+BEGIN_{$1}
$0
#+END_{$1}

View File

@ -1,8 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex equation* block
# key: eq*
# --
\begin{equation*}
$0
\end{equation*}

View File

@ -1,6 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex frac
# key: fr
# --
\frac{$1}{$2} $0

View File

@ -1,9 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex Definition box
# key: def
# --
#+attr_latex: :options {Definition}
#+BEGIN_infobox
$0
#+END_infobox

View File

@ -1,6 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex \prod
# key: prod
# --
\prod ^{$1} _{$2} $0

View File

@ -1,6 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: Latex \sum
# key: sum
# --
\sum ^{$1} _{$2} $0

View File

@ -1,11 +0,0 @@
# -*- mode: snippet -*-
# contributor: lxsameer <lxsameer@gnu.org>
# name: to write block
# key: tw
# Adds a TOWRITE block to org file. Your exporter has to
# know how to deal with this block. For example for latex you need
# to include this header `#+LATEX_HEADER: \newenvironment{TOWRITE}{...}{...}`
# --
#+BEGIN_TOWRITE
$0
#+END_TOWRITE