Compare commits

..

1 Commits
master ... ep10

Author SHA1 Message Date
Sameer Rahmani e21c5b47d1 Add org-journal support 2022-09-25 17:20:32 +01:00
290 changed files with 14012 additions and 8542 deletions

3
.gitignore vendored
View File

@ -1,4 +1,3 @@
emacs.dmastodon.plstore
kuso.config.el
kuso.d/*
.build/*
@ -39,5 +38,3 @@ emacs.d/
docs/site/orgs/cubes/
**/*/sitemap.inc
result
v4/

7
Dockerfile Normal file
View File

@ -0,0 +1,7 @@
FROM debian:11-slim
RUN apt update && apt install -y emacs build-essential sudo git
COPY . /root/.fg42
WORKDIR /root/.fg42
RUN make install

65
Makefile Normal file
View File

@ -0,0 +1,65 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2022 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/>.
my_dir := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
.PHONY: update
update:
@git pull origin master
.PHONY: install
install:
/bin/sh $(my_dir)/scripts/install_files.sh runners
@echo " "
@echo "------------------------------------------------------------------------------------"
@echo "Make sure to install external dependencies of FG42. For more info checkout README.org"
@echo "Enjoy the bless of GNU/Emacs and FG42 :)"
.PHONY: install-fonts
install-fonts:
/bin/sh $(my_dir)/scripts/install_files.sh fonts
.PHONY: install-extras
install-extras:
/bin/sh $(my_dir)/scripts/install_files.sh extras
.PHONY: doc-clean
clean:
@rm -rf $(shell find `pwd` -iname "*~")
@rm -rf build
.PHONY: dev-docs
dev-docs: clean
./build.el docs :d
.PHONY: docs
docs:
./build.el docs
serve: build
npx http-server ./build/site-build/
.PHONY: deploy-docs
deploy-docs: clean docs
rsync -vlcr --delete-after ./build/site-build/* core.lxsameer.com:/home/www/public/fg42/
.PHONY: dummy-x
dummy-x:
Xephyr -br -ac -noreset -screen 800x600 :1
.PHONY: test-wm
test-wm:
DISPLAY=:1 FG42_WM=true FG42_V3=true ./fg42-wm

View File

@ -1,82 +1,66 @@
* Future Gadgets 42
*FG42* is an Emacs based editor that utilizes [[https://nixos.org/][Nix]], and shipped preconfigured. While it
is the Emacs that you love :heart:, it breaks the tradition by not using any of Emace's
package managers (More on that later). It provides a self-contained program and
contains all the runtime dependencies including Emacs itself.
*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.
** Requirements
The only requirement to install *FG42*, is [[https://nixos.org/][Nix]]. If you don't use Nix, try it today.
It's amazing.
In order to use *FG42* you need *Emacs >= 27.1* and the =texinfo= package. If you're on a
debian based distro you can install it using =apt install texinfo=.
** Install from source
In order to install *FG42*, issue the following commands:
** Installation
If you're using Nix (and not NixOS), then you can install *FG42* like:
#+BEGIN_SRC bash
# Install emacs, make and texinfo
$ nix profile install "git+https://devheroes.codes/FG42/FG42#"
# Or via nix build like:
nix build "git+https://devheroes.codes/FG42/FG42#"
# Install emacs, make and texinfo
# clone the FG42 repository in ~/.fg42 directory
$ git clone https://devheroes.codes/FG42/FG42.git ~/.fg42/
# You can clone it where ever your want
$ cd ~/.fg42/
$ make install
# Run fg42, It will download and build some lisp dependencies on the first execution.
$ fg42
#+END_SRC
If you're using NixOS or HomeManager you can use *FG42* as an input
to your flake. If your not using flakes, I'm pretty sure you know
what you are doing so I leave it to your experience.
#+BEGIN_SRC nix
{
description = "Exmaple flake";
inputs = {
fg42.url = "git+https://devheroes.codes/FG42/FG42";
};
outputs = { self, fg42, ... } @ inputs:
let
# I just use linux and currently only x86_64
system = "x86_64-linux";
# Grab the default package of FG42
fg42 = fg42.outputs.packages.${system}.default;
in {
# Now you can use the 'fg42' package in your package list
....
};
}
#+END_SRC
Since the installer script uses =sudo=, during the installation process,
you'll have to enter your password. Make sure that you're user account has
a =sudo= access.
After installing *FG42* you should be able to start the default editor via =fg42= script.
The very first time that you start =fg42= it will download all the necessary packages to
operate, so it will take a while for all the packages to install. You can tell when it is
finished by a message in the minibuffer and the fact that the look of emacs changes.
Enjoy using **FG42** ;)
** Configuration
FG42 comes pre-configured, but if you need to add your own configuration you can
do it in =~/.fg42.el=.
After installation there would be a file at =~/.fg42.el= which is the user specific
configuration of *FG42*. You can configure your copy of *FG42* using this file.
Also you can generally use this file to configure Emacs as well.
** Flags
** Terms & Concepts
FG42 introduced some new features to the Vanilla *Gnu/Emacs*. So you migh encounter several of these features during your
journey. It's a good idea to at least know what you're dealing with.
*** Cubes
*FG42*'s design is very similar to *Gentoo*. The abstraction unit of functionality in FG42
is a **Cube**. Cubes are function like entities that you can call in order to activate them.
They get activated just once and multiple calls don't have any effect on them.
*** Flags
** Documentation
TBD
** Debugging
Debugging is *OFF* by default in *FG42*. You can turn it on by setting the ~FG42_DEBUG~
environment variable to ~1~.
If you ran into an issue and want to debug FG42, the best and easiest way is to turn on
debugging by uncommenting =(setq debug-on-error t)= in your configuration (=~/.fg42.el=)
and restarting FG42. After that you'll get a traceback for any exception in FG42.
** FAQ
*** Why Nix? Have you tried Emacsian package manager?
Yes we tried many of them. We started by a manual solution that the name ~fpkg~ remains
as remembrance of that effort. We moved to [[https://github.com/dimitri/el-get][el-get]], then [[https://github.com/cask/cask][Cask]], [[https://github.com/emacs-eldev/eldev][ElDev]] and finally we
landed on [[https://github.com/radian-software/straight.el][straight.el]] on ~V3~. But none of the provided the stability that we need.
But on ~V4~ (Current version), We've change the approach by disabling all the package managers
(don't worry you can still use them if you want to) and used *Nix* to manage everything. Both
elisp dependencies and system dependencies. This way we get reproducible builds that gives
us stability and reliability. Also we get to pin every single dependency version even Emacs
itself. So no more ":shrug: But it works on my computer".
*** what's with the name?
** what's with the name?
I'm a huge fan of [Steins Gate](https://en.wikipedia.org/wiki/Steins;Gate) anime and I follow its
naming convensions on *Future Gadgets 42*.
*** Why we moved from Github ?
** Why we moved from Github ?
We're not happy with Microsoft buying Github and we don't trust a company like Microsoft because of their history and
their strategies (For more information take a look at [[https://en.wikipedia.org/wiki/Halloween_documents][Halloween documents]].
So we decided to move to Devheroes as an alternative and we are happy here so far.
@ -105,4 +89,4 @@ with this program; if not, write to the Free Software Foundation, Inc.,
All the documents of FG42 that locate in 'doc' directories release
under the term of GNU FDL.
Copyright (C) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
Copyright (C) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>

96
build.el Executable file
View File

@ -0,0 +1,96 @@
:;exec `echo $EMACS_PATH` --no-site-file --no-site-lisp --batch -L ./ -l "$0" -f main "$(cd "$(dirname "$0")/." >/dev/null 2>&1 ; pwd -P)" "$@"
;;; Buid --- The builder for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 thnis 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:
(setq debug-on-error t)
(defconst fg42/CORE_DIR (concat (getenv "HOME") "/.fg42/core"))
(add-to-list 'load-path fg42/CORE_DIR)
(setenv "FG42_HOME" (concat (getenv "HOME") "/.fg42/"))
(setq user-emacs-directory (concat (getenv "FG42_HOME") "emacs.d"))
(require 'fg42/build/core)
(require 'fg42/build/utils)
(defvar FG42-VERSION "3.0.0-snapshot"
"The version number of the current build of FG42.")
(defconst build/usage "
Usage:
build.el [PARAMS] COMMAND [...]
COMMANDS:
clean [DIRS] - Clean up the given list of directories (default: \"code\" \"fbt\").
docs - Build the documents and convert them to HTML
PARAMS:
:d - Turns on the debug mode.
:e expr - Run the given `expr' before any operation.
")
(defun print-help (command)
"Print out a usage instructions and print out the invalid msg for COMMAND."
(when command
(warn "I don't know about '%s' command.\n" command))
(message build/usage))
(defproject FG42
project-root (nth 2 command-line-args-left)
docs-actions '(fg42/build-prepare-docs))
(command-> command args
((string= command "docs")
(do-command
(require 'fg42/build/docs)
(fg42/build-docs build-dir)))
;; TODO: create a new command to update the license headers for
;; the copyright years. Hint: just run:
;; sed 's/2010-2021/2010-2022/' -i ` grep '2010-2021' . -R --color --exclude-dir=emacs.d/|cut -d':' -f1`
((string= commad "compile")
(do-command
(native-compile-async fg42/CORE_DIR 'recursively)
(native-compile-async "~/.fg42.v3.el")
(print "Compiling FG42 files ...")
(while (or comp-files-queue
(> (comp-async-runnings) 0))
(print ".")
(sleep-for 1))
(message "Done"))))
(provide 'build)
;;; build.el ends here

199
config/fg42.user.el Normal file
View File

@ -0,0 +1,199 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2020 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2020 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
;; Uncomment this line for debugging
;; (setq debug-on-error t)
(require 'fg42/flags)
(require 'cubes/editor)
(require 'cubes/org)
(require 'cubes/elisp)
(require 'cubes/region-expansion)
(require 'cubes/wm)
(require 'cubes/modeline)
(require 'cubes/autocompletion)
(require 'cubes/golang)
(require 'cubes/project)
(require 'cubes/irc)
(require 'cubes/terminal)
(require 'cubes/java)
(require 'cubes/python)
(require 'cubes/cpp)
(require 'cubes/snippets)
(require 'cubes/git)
(require 'cubes/bookmark)
(require 'cubes/terraform)
(require 'cubes/graph)
(require 'cubes/clojure)
(defvar global-font-size 12)
(custom-set-faces
'(mini-modeline-mode-line
((((background light))
:background "#aa0000" :height 0.1 :box nil)
(t
:background "#bd93f9" :height 0.1 :box nil))))
(use-flags
(fg42/merge-with-default-flags
wm
python
golang
rcirc
vterm
company
lsp
flycheck
fg42/region-expansion-cube))
;TODO: Move this block to a macro or something ===========
(when-wm
(setq global-font-size 8)
(custom-set-faces
'(mini-modeline-mode-line
((((background light))
:background "#aa0000" :height 0.1 :box nil)
(t
:background "#6272a4" :height 0.1 :box nil))))
(fg42/wm-cube :number-of-workspaces 9)
;; Change the resolution and monitors to your need
(defvar monitors
'(: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")))
(require 'seq)
(defun monitor-profiles ()
(mapcar
#'car
(seq-partition monitors 2)))
(defun monitor (mon)
(interactive
(list (completing-read
"Monitor Profole: "
(monitor-profiles))))
(let ((cmd (mapconcat (lambda (x) (format "xrandr %s" x))
(plist-get monitors (intern (format "%s" mon)))
" && ")))
(message "Setting monitor profile: %s" cmd)
(async-shell-command cmd "*xrandr*")))
(comment
;; how to run it via elisp
(monitor :hdmi-only))
(use-flags
(fg42/merge-with-default-flags
wm
-python
-golang
rcirc
vterm
-company
-projectile
-lsp
-flycheck
fg42/region-expansion-cube)))
;; Both are part of the editor cube but we want to override
;; their behavior
(fg42/org-cube)
(fg42/cursor-cube :type 'bar :color "#bd93f9")
(fg42/font-cube :font-name "Fira code" :font-size global-font-size)
(fg42/editor-cube)
;;(fg42/imenu-cube)
(fg42/elisp-cube)
(fg42/region-expansion-cube)
(fg42/graphviz-cube)
(fg42/company-cube)
(fg42/lsp-cube)
(fg42/c++-cube)
(fg42/python-cube)
(fg42/yaml-cube)
(fg42/flycheck-cube)
(fg42/golang-cube)
(fg42/clojure-cube)
(fg42/projectile-cube)
(fg42/vterm-cube)
(fg42/git-cube)
(fg42/alert-cube)
(fg42/bookmark-cube)
(fg42/terraform-cube)
(fg42/java-cube)
(fg42/yasnippet-cube)
;; Themes should be the last cube and anything that wants to manipulate a face
;; has to use either `fg42/before-initializing-theme-hook' or
;; `fg42/after-initializing-theme-hook' hooks.
(fg42/dracula-theme-cube)
(set-face-attribute 'region nil :background "#888")
(when (file-exists-p "~/.fg42.user.el")
(load "~/.fg42.user.el"))
(provide 'fg42.user)
;;; fg42.user.el ends here

45
core/cubes/all.el Normal file
View File

@ -0,0 +1,45 @@
;;; AllCubes --- An index to use import all the cubes at once -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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/flags)
(require 'cubes/editor)
(require 'cubes/elisp)
(require 'cubes/region-expansion)
(require 'cubes/wm)
(require 'cubes/modeline)
(require 'cubes/autocompletion)
(require 'cubes/golang)
(require 'cubes/project)
(require 'cubes/irc)
(require 'cubes/terminal)
(require 'cubes/java)
(require 'cubes/python)
(require 'cubes/snippets)
(require 'cubes/org)
(require 'cubes/git)
(require 'cubes/bookmark)
(require 'cubes/terraform)
(provide 'cubes/all)
;;; all.el ends here

View File

@ -0,0 +1,96 @@
;;; AutocompletionCubes --- The completion related cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/flycheck-cube
"This cube adds the `flycheck' support to fg42."
(:title "Flycheck cube"
:flag flycheck)
(fpkg/use flycheck
:defer ()
:init
(global-flycheck-mode)))
(defcube fg42/yaml-cube
"Yaml Support"
(:title "Yaml Support"
:no-flag t)
(fpkg/use yaml-mode))
(defcube fg42/lsp-cube
"LSP cube"
(:title "LSP cube"
:flag lsp)
(fpkg/use lsp-mode
:commands lsp
:init
(setq lsp-headerline-breadcrumb-enable nil))
;; TODO: Create a flag for lsp-ui or move it
;; to a new cube
(fpkg/use lsp-ui
:init
(progn
(setq lsp-ui-doc-enable t
lsp-ui-doc-show-with-cursor t))
:config
(add-hook 'lsp-mode-hook 'lsp-ui-mode)))
(defcube fg42/company-cube
"Auto complete using company mode"
(:title "Company cube"
:flag company)
(fpkg/use company
: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))
:config
(progn
;; Use Company for completion
(bind-key [remap completion-at-point] #'company-complete company-mode-map)
(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)
(global-company-mode)))
;; TODO: Move company box to a new cube
(fpkg/use company-box
:after company
:config
(add-hook 'company-mode-hook 'company-box-mode)))
(provide 'cubes/autocompletion)
;;; autocompletion.el ends here

100
core/cubes/bookmark.el Normal file
View File

@ -0,0 +1,100 @@
;;; Bookmark --- Bookmarks within the code -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 thnis 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:
(require 'fpkg)
(require 'fg42/cube)
(defcube fg42/bookmark-cube
"bookmark cube"
(:title "cubes/fg42/bookmark-cube.org"
:flag bookmark
:flag-default t)
(let* ((bnext (or (plist-get fg42/bookmark-cube-params :bm-next-key) "M-]"))
(bprev (or (plist-get fg42/bookmark-cube-params :bm-previous-key) "M-["))
(btoggle (or (plist-get fg42/bookmark-cube-params :bm-toggel-key) "M-p"))
(keys `(list (,bnext . bm-next)
(,bprev . bm-previous)
(,btoggle . bm-toggle))))
(eval
`(fpkg/use bm
:init
;; restore on load (even before you require bm)
(setq bm-restore-repository-on-load t)
:config
;; Allow cross-buffer 'next'
(setq bm-cycle-all-buffers t)
;; where to store persistant files
(setq bm-repository-file (expand-file-name "bm-repository" user-emacs-directory))
;; save bookmarks
(setq-default bm-buffer-persistence t)
;; Loading the repository from file when on start up.
(add-hook 'after-init-hook 'bm-repository-load)
;; Saving bookmarks
(add-hook 'kill-buffer-hook #'bm-buffer-save)
;; Saving the repository to file when on exit.
;; kill-buffer-hook is not called when Emacs is killed, so we
;; must save all bookmarks first.
(add-hook 'kill-emacs-hook #'(lambda nil
(bm-buffer-save-all)
(bm-repository-save)))
;; The `after-save-hook' is not necessary to use to achieve persistence,
;; but it makes the bookmark data in repository more in sync with the file
;; state.
(add-hook 'after-save-hook #'bm-buffer-save)
;; Restoring bookmarks
(add-hook 'find-file-hooks #'bm-buffer-restore)
(add-hook 'after-revert-hook #'bm-buffer-restore)
;; The `after-revert-hook' is not necessary to use to achieve persistence,
;; but it makes the bookmark data in repository more in sync with the file
;; state. This hook might cause trouble when using packages
;; that automatically reverts the buffer (like vc after a check-in).
;; This can easily be avoided if the package provides a hook that is
;; called before the buffer is reverted (like `vc-before-checkin-hook').
;; Then new bookmarks can be saved before the buffer is reverted.
;; Make sure bookmarks is saved before check-in (and revert-buffer)
(add-hook 'vc-before-checkin-hook #'bm-buffer-save)
:bind ((,bnext . bm-next)
(,bprev . bm-previous)
(,btoggle . bm-toggle))))))
(provide 'cubes/bookmark)
;;; bookmark.el ends here

52
core/cubes/clojure.el Normal file
View File

@ -0,0 +1,52 @@
;;; ClojureCubes --- The Clojure cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2021 Sameer Rahmani & Contributors
;;
;; Author: Pouya Abbassi <abbassi.pouya@gmail.com>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(require 'fg42/utils)
(autoload-cube 'fg42/clojure-init "clojure/core.el" "Initalize the Clojure mode.")
(defcube fg42/clojure-cube
"Clojure support cube for fg42.
Installs and activates clojure-mode, cider, paredit and rainbow-delimiters.
Also activates LSP and converts `fn` to λ."
(:title "Clojure cube"
:flag clojure
:flag-default t)
(fpkg/use aggressive-indent-mode
:config (paredit-mode +1))
(fpkg/use rainbow-delimiters
:config (rainbow-delimiters-mode +1))
(fpkg/use cider)
(fpkg/use clojure-mode
:hook (clojure-mode . fg42/clojure-init)
:config (when-flag clojure
(setq lsp-enable-indentation nil))))
(provide 'cubes/clojure)
;;; clojure.el ends here

View File

@ -0,0 +1,42 @@
;;; ClojureCubes --- The Clojure cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2021 Sameer Rahmani & Contributors
;;
;; Author: Pouya Abbassi <abbassi.pouya@gmail.com>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(defun fg42/fn-greek-lambda ()
(font-lock-add-keywords nil `(("\\<fn\\>"
(0 (progn (compose-region (match-beginning 0) (match-end 0)
,(make-char 'greek-iso8859-7 107))
nil))))))
(defun fg42/clojure-init ()
(paredit-mode 1)
(aggressive-indent-mode 1)
(rainbow-delimiters-mode 1)
(when-flag lsp (lsp))
(fg42/fn-greek-lambda))
(provide 'cubes/clojure/core)
;;; core.el ends here

53
core/cubes/cpp.el Normal file
View File

@ -0,0 +1,53 @@
;;; CPPCubes --- The C/C++ cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(require 'fg42/utils)
(defcube fg42/cmake-cube
"This cube enable CMake integration with FG42"
(:title "CMake cube"
:flag-default t
:flag cmake)
(fpkg/use cmake-mode)
(fpkg/use eldoc-cmake))
(defcube fg42/c++-cube
"C++ cube"
(:title "C++ cube"
:no-flag t)
(fg42/cmake-cube)
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
(add-hook 'c++-mode-hook (lambda ()
(lsp)
(require 'company-capf)
(require 'company-box)
(setq company-backends
'((company-capf
company-keywords))))))
(provide 'cubes/cpp)
;;; cpp.el ends here

295
core/cubes/editor.el Normal file
View File

@ -0,0 +1,295 @@
;;; EditorCubes --- The common cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'server)
(require 'fpkg)
(require 'fg42/cube)
(require 'fg42/utils)
(require 'fg42/modeline)
(require 'cubes/modeline)
(defflag font-icons
"Enable the support for font icones in FG42." t)
(defflag server
"Enable the support for server mode in FG42." t)
(defcube fg42/folding-cube
"This cube install ~origami~ which let you collapse and expand regions of text.
For more info checkout [[https://github.com/gregsexton/origami.el]]"
(:title "Folding cube"
:flag folding
:flag-default t)
(fpkg/use origami
:bind
(("C-c TAB" . origami-toggle-node))
:config
(global-origami-mode t)))
(defcube fg42/pinentry-cube
"Pinentry cube with setup the =pinentry= program to be used within FG42."
(:title "Pinentry cube"
:flag pinentry
:flag-default t)
(fpkg/use pinentry
:init
(progn
(setq epa-pinentry-mode 'loopback)
(pinentry-start))))
(defcube fg42/imenu-cube
"Imenu support"
(:title "Imenu cube"
:flag imenu
:flag-default t)
(fpkg/use imenu-list
:init
(global-set-key (kbd "C-'") #'imenu-list-smart-toggle)))
(defcube fg42/alert-cube
"alert support"
(:title "Alert cube"
:flag alert
:flag-default t)
(fpkg/use alert))
(defcube fg42/exec-path-cube
"This cube fixes the =exec-path-from-shell= issue on MacOS."
(:title "Exec path cube"
:flag exec-path-from-shell
:flag-default t)
(fpkg/use exec-path-from-shell
:init
(when (memq window-system '(mac ns x))
(exec-path-from-shell-initialize))))
(defcube fg42/hl-cube
"This cube highlight the curret line."
(:title "Current line highlight cube"
:flag hl-line
:flag-default t)
(require 'hl-line)
(global-hl-line-mode))
(defcube fg42/cursor-cube
"This cube controls the shape of the cursor."
(:title "Cursor cube"
:flag cursor-type
:flag-default t)
(let ((ctype (or (plist-get fg42/cursor-cube-params :type) 'box))
(ccolor (or (plist-get fg42/cursor-cube-params :color) "#aa0000")))
(add-hook 'fg42/after-initializing-theme-hook
(lambda ()
(set-default 'cursor-type ctype)
(set-cursor-color ccolor)))))
(defcube fg42/buffer-navigation-cube
"This cube controls the different aspect of buffer navigation"
(:title "Buffer navigation cube"
:flag buffer-navigation
:flag-default t)
(fpkg/use avy
:bind ("M-1" . avy-goto-word-1)))
(defcube fg42/window-navigation-cube
"This cube controls the different aspect of buffer navigation"
(:title "Window navigation cube"
:flag window-navigation
:flag-default t)
(fpkg/use ace-window
:bind ("C-<tab>" . ace-window)))
(defcube fg42/font-cube
"This cube controls the font configuration of *FG42*"
(:title "Font Cube"
:no-flag t
:flag-default t)
(let ((font (or (plist-get fg42/font-cube-params :font-name)
"Fira Mono"))
(size (or (plist-get fg42/font-cube-params :font-size)
12)))
(when font
;; Sets the default font to fg42 font
(add-to-list 'default-frame-alist
(cons 'font (format "%s-%d" font size)))
(set-face-attribute 'default t :font font))))
;TODO: Replace this cube with a `theme-cube'
(defcube fg42/dracula-theme-cube
"Replace this with a theme cube"
(:title "Dracula theme"
:no-flag t)
(require 'fg42/themes)
(fpkg/use dracula-theme
:init
(fg42/setup-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"))))
'(font-lock-comment-delimiter-face ((t (:foreground "#5B6268")))))
(enable-theme 'dracula))))
(defcube fg42/badwolf-theme-cube
"Badwolf theme cube. An Emacs port of Bad Wolf theme for Vim.
https://emacsthemes.com/themes/badwolf-theme.html"
(:title "Badwolf theme"
:no-flag t)
(require 'fg42/themes)
(fpkg/use badwolf-theme
:init
(fg42/setup-theme
(load-theme 'badwolf t)
(custom-theme-set-faces
'badwolf)
(enable-theme 'badwolf))))
(defcube fg42/selectrum-cube
"This cube adds support for `selectrum' to FG42"
(:title "Selectrum cube"
:flag selectrum
:flag-default t)
(fpkg/use selectrum
:defer nil
:init
(selectrum-mode +1))
(fpkg/use selectrum-prescient
:defer t
:init
(progn
(setq prescient-filter-method '(literal fuzzy regexp initialism))
(selectrum-prescient-mode +1)
(prescient-persist-mode +1)))
;; TODO: Disbale ctrlf in WM mode
(fpkg/use ctrlf
:defer t
:init
(ctrlf-mode +1)))
(defcube fg42/editor-cube
"This is a meta cube that sets up the basic functionalities of an Editor"
(:title "Editor cube"
:no-flag t)
(fpkg/use rainbow-delimiters
;; It doesn't work due to a problem/conflict in rainbow-delimiters
;; But we use it any way they might fix it
:hook (prog-mode . rainbow-delimiters-mode))
(when-flag font-icon
(fpkg/use all-the-icons))
;; 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.
;; 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)
;; Global configurations
(tool-bar-mode -1)
(scroll-bar-mode -1)
(menu-bar-mode -1)
(column-number-mode t)
(show-paren-mode t)
(electric-pair-mode 1)
;; Rectangular select
(cua-selection-mode t)
;; Yank the region on type
(delete-selection-mode 1)
(defalias 'yes-or-no-p 'y-or-n-p)
;; Hooks ---
;; 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)
(when-flag server
(when (not (server-running-p))
(when-wm
(setq server-name "fg42-wm"))
(server-start)))
;; Call the editor related cubes. They will be run only if
;; their flag is active otherwise they will be skipped
(let ((mline (or (plist-get fg42/editor-cube-params :modeline)
#'fg42/default-modeline)))
;;(fg42/statusbar-cube)
(fg42/modeline-cube)
(fg42/setup-modeline-format mline))
(fg42/folding-cube)
(fg42/font-cube)
(fg42/pinentry-cube)
(fg42/exec-path-cube)
(fg42/buffer-navigation-cube)
(fg42/window-navigation-cube)
(fg42/selectrum-cube)
(fg42/cursor-cube)
(fg42/hl-cube))
(provide 'cubes/editor)
;;; editor.el ends here

45
core/cubes/eldoc.el Normal file
View File

@ -0,0 +1,45 @@
;;; eldoc --- The eldoc cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(require 'fpkg)
(require 'fg42/cube)
(defcube fg42/eldoc-box-cube
"This cube sets up the =eldoc-box= system to show documentations on demand in
a box."
(:title "Eldoc box Cube"
:flag eldoc-box
:flag-default t
:modes '(eldoc-box-hover-mode eldoc-box-hover-at-point-mode))
(fpkg/use eldoc-box
:config
(add-hook 'eldoc-mode-hook 'eldoc-box-hover-at-point-mode)))
(provide 'cubes/eldoc)
;;; eldoc.el ends here

View File

@ -1,10 +1,10 @@
;;; ElispCube --- The elisp cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -22,17 +22,24 @@
;;; Commentary:
;;; Code:
(require 'fpkg)
(require 'fg42/cube)
(defun fg42/setup-elisp ()
"Setup the Emacs Lisp development environment."
(use! eros
:init
(require 'eros)
(eros-mode))
(defcube fg42/elisp-cube
"Elisp cube"
(:title "cubes/fg42/elisp-cube.org"
:no-flag t)
(fpkg/use rainbow-delimiters
;; It doesn't work due to a problem/conflict in rainbow-delimiters
;; But we use it any way they might fix it
:hook (prog-mode . rainbow-delimiters-mode))
(fpkg/use paredit
:hook (emacs-lisp-mode . paredit-mode))
(add-hook 'emacs-lisp-mode-hook #'rainbow-delimiters-mode))
(provide 'fg42/cubes/elisp)
(provide 'cubes/elisp)
;;; elisp.el ends here

40
core/cubes/elisp/core.el Normal file
View File

@ -0,0 +1,40 @@
;;; ElispCube --- The elisp cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(defun fg42/elisp-hook-handler ()
"Configure the elisp mode."
(require 'rainbow-delimiters)
(require 'paredit)
(rainbow-delimiters-mode t)
(paredit-mode t)
(message "Elisp cube is done"))
(provide 'cubes/elisp/core)
;;; core.el ends here

68
core/cubes/fm.el Normal file
View File

@ -0,0 +1,68 @@
;;; FMCubes --- The file manager cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
;; TODO: Move this to an autoload file
(defun fg42/dired-external-open ()
"In dired, open the file named on this line."
(interactive)
(let ((file (dired-get-filename nil t)))
(call-process "xdg-open" nil 0 nil file)))
(defcube fg42/fm-cube
"file manager"
(:title "cubes/fg42/fm-cube.org"
:flag fm
:flag-default t)
;; Linux only
;; TODO: change this to support OS X
(setq dired-listing-switches "-lFaGh1v --group-directories-first")
;; Show directories first
(setq ls-lisp-dirs-first t)
(setq dired-recursive-copies 'always)
(setq dired-recursive-deletes 'always)
(define-key dired-mode-map (kbd "E") 'fg42/dired-external-open)
(fpkg/use dired+)
(add-to-list 'dired-mode-hook
(lambda ()
(require 'dired-x)
(require 'dired-aux)))
(when-flag async
(dired-async-mode 1))
(fpkg/use dired-narrow
:bind (:map dired-mode-map
("/" . dired-narrow))))
(provide 'cubes/fm)
;;; fm.el ends here

69
core/cubes/git.el Normal file
View File

@ -0,0 +1,69 @@
;;; GitCube --- The Git cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(require 'fpkg)
(require 'fg42/cube)
(defcube fg42/diff-hl-cube
"This cube highlights changes to the current buffer in respect to the
VC status of the file. For example if you're using *git* in your project
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][diff-hl]] 's page."
(:title "Diff Highlight Cube"
:flag diff-hl
:flag-default t)
(fpkg/use diff-hl
:init
(progn
(when-flag git
(add-hook 'magit-pre-refresh-hook 'diff-hl-magit-pre-refresh)
(add-hook 'magit-post-refresh-hook 'diff-hl-magit-post-refresh))
(global-diff-hl-mode))))
(defcube fg42/git-cube
"This cube integrates *git* into *FG42*."
(:title "Git Cube"
:flag git
:flag-default t)
(fpkg/use magit
:bind (("C-x g" . magit-status)))
(fpkg/use magit-todos
:after magit
:init (require 'magit-todos))
(fg42/diff-hl-cube))
(provide 'cubes/git)
;;; git.el ends here

50
core/cubes/golang.el Normal file
View File

@ -0,0 +1,50 @@
;;; GolangCubes --- The Golang cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(require 'fg42/utils)
(autoload-cube 'fg42/initialize-golang "golang/core.el" "Initalize the go mode.")
(defcube fg42/golang-cube
"Golang support cube for fg42."
(:title "Golang cube" :flag golang)
(fpkg/use go-mode
:defer t
:mode "\\.go\\'"
:config
(progn
(add-hook 'go-mode-hook 'fg42/initialize-golang)
(when-flag lsp
(add-hook 'go-mode-hook
(lambda ()
(when (not (boundp 'lsp))
(require 'lsp)
(lsp-deferred))))))))
(provide 'cubes/golang)
;;; golang.el ends here

64
core/cubes/golang/core.el Normal file
View File

@ -0,0 +1,64 @@
;;; GolangCubes --- The Golang cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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/flags)
(defun fg42/go-path-from-env ()
"Gets gopath from OS env."
(exec-path-from-shell-copy-env "GOPATH"))
(defun fg42/go-path-binary (gopath)
"Gets Go binaries path with respect to the given GOPATH."
;; TODO: Use `expand-file-name' here
(concat gopath "/bin"))
(defun fg42/initialize-golang ()
"Setup Emacs hooks and turn necessary modes on."
(when-flag lsp
(lsp-register-custom-settings
'(("gopls.completeUnimported" t t)
("gopls.staticcheck" t t)))
(add-hook 'before-save-hook
(lambda ()
(when (eq major-mode 'go-mode)
(lsp-format-buffer t)
(lsp-organize-imports t)))))
(when-flag company
(setq-local company-backends
'(company-capf
company-dabbrev
company-dabbrev-code)))
(let ((go-path (or (plist-get fg42/golang-cube-params :go-path)
(fg42/go-path-from-env))))
(add-to-list 'exec-path (fg42/go-path-binary go-path)))
(local-set-key (kbd "M-.") #'godef-jump)
(local-set-key (kbd "M-*") 'pop-tag-mark))
(provide 'cubes/golang/core)
;;; core.el ends here

59
core/cubes/graph.el Normal file
View File

@ -0,0 +1,59 @@
;;; GraphCube --- The Graph utility cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(require 'fpkg)
(require 'fg42/cube)
(defcube fg42/graphviz-cube
"This cube enable =dot= file editing in *FG42*. Using this cube you should
be able to edit =dot= files and use =C-c C-p= to see a preview of your =dot=
file. Use =C-c C-c= to compile the =dot= file.
If =company= flag is enabled then =dot= autocomplete will be enabled as well."
(:title "Graphviz Cube"
:flag graphviz
:flag-default t
:modes 'graphviz-dot-mode)
(let ((indent-size (or (plist-get fg42/graphviz-cube-params :indent-size) 4)))
(fg42/after-cubes
(when-flag org
(add-hook 'org-mode-hook
(lambda ()
(org-babel-do-load-languages
'org-babel-load-languages
'((dot . t)
(graphviz-dot . t)))))))
(fpkg/use graphviz-dot-mode
:config
(setq graphviz-dot-indent-width indent-size))))
(provide 'cubes/graph)
;;; graph.el ends here

View File

@ -1,10 +1,10 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;; GroovyCubes --- The Groovy cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; Keywords: lisp fg42 IDE package manager
;; Version: 1.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -20,14 +20,19 @@
;; 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:
(require 'fpkg)
(require 'fg42/cube)
(require 'fg42/utils)
(defcube fg42/groovy-cube
"Groovy support for FG42."
(:title "Groovy cube"
:flag groovy
:flag-default t)
(provide 'fg42/direnv)
;;; direnv.el ends here
(fpkg/use groovy-emacs-mode
:defer t))
(provide 'cubes/groovy)
;;; groovy.el ends here

41
core/cubes/haml.el Normal file
View File

@ -0,0 +1,41 @@
;;; HamlCubes --- The Haml cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Behnam Khan Beigi <yottanami@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/haml-cube
"This cube provides syntax highlighting and syntax-aware indentation
for haml files"
(:title "Haml Cube"
:flag haml
:flag-default t)
(fpkg/use haml-mode
:mode "\\.haml\\'"))
(provide 'cubes/haml)
;;; haml.el ends here

41
core/cubes/icons.el Normal file
View File

@ -0,0 +1,41 @@
;;; IconsCubes --- The modeline related cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
;; TODO: Break this into two cubes
(defcube fg42/all-the-icons-cube
"Install the [[https://github.com/domtronn/all-the-icons.el][all-the-icons.el]]
package."
(:title "All the icons cube"
:flag all-the-icons
:flag-default t)
(fpkg/use all-the-icons
:if (display-graphic-p)))
(provide 'cubes/icons)
;;; icons.el ends here

View File

@ -1,10 +1,10 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;; IrcCubes --- The IRC related cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -21,19 +21,20 @@
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
(require 'fpkg)
(require 'fg42/cube)
;; 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))))
(defcube fg42/rcirc-cube
"IRC cube"
(:title "cubes/fg42/rcirc-cube.org"
:flag rcirc)
(autoload-cube 'fg42/rcirc-connect "irc/core.el" "Connect to IRC via RCIRC." t)
(defun fg42/connect-to-irc ()
(interactive)
(fg42/rcirc-connect)))
(provide 'fg42/eglot)
;;; eglot.el ends here
(provide 'cubes/irc)
;;; irc.el ends here

46
core/cubes/irc/core.el Normal file
View File

@ -0,0 +1,46 @@
;;; IrcCubes --- The IRC related cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(defvar fg42/default-rcirc-servers
'(("irc.libera.chat/6697"
:channels ("#fg42"))))
(defun fg42/rcirc-connect ()
"Connect to IRC servers."
(interactive)
(require 'rcirc)
(let ((servers (or (plist-get fg42/rcirc-cube-params :server)
fg42/default-rcirc-servers)))
(setq rcirc-enable-authinfo-support t)
(setq rcirc-server-alist servers)
(add-hook 'rcirc-mode-hook
(lambda ()
(rcirc-track-minor-mode 1)))
(irc nil)))
(provide 'cubes/irc/core)
;;; core.el ends here

69
core/cubes/java.el Normal file
View File

@ -0,0 +1,69 @@
;;; JavaCubes --- The Java cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/gradle-cube
"Gradle support"
(:title "cubes/fg42/java-cube.org"
:flag gradle
:flag-default t)
(fpkg/use groovy-mode
:mode "\\.gradle\\'")
(fpkg/use gradle-mode
:hook (java-mode-hook . gradle-mode))
(when-flag flycheck
(fpkg/use flycheck-gradle)))
(defcube fg42/java-cube
"Java cube"
(:title "cubes/fg42/java-cube.org"
:flag java
:flag-default t)
(add-hook 'java-mode-hook
(lambda()
;; To fix the indentation of function arguments
(c-set-offset 'arglist-intro '+)
(setq java-basic-offset 2)
(setq c-basic-offset 2)
(when-flag lsp-java
(setq lsp-java-server-install-dir fg42-tmp)
(lsp))))
(when-flag gradle
(fg42/gradle-cube))
(when-flag lsp
(fpkg/use lsp-java)))
(provide 'cubes/java)
;;; java.el ends here

28
core/cubes/keyboard.el Normal file
View File

@ -0,0 +1,28 @@
;;; KeyboardCubes --- The keyboard related cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
;; TODO: Add support for HALMAK layout
(provide 'cubes/keyboard)
;;; keyboard.el ends here

113
core/cubes/modeline.el Normal file
View File

@ -0,0 +1,113 @@
;;; ModelineCubes --- The modeline related cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(require 'cubes/icons)
(autoload-cube 'fg42/statusbar-default
"modeline/statusbar-default.el"
"The default StatusBar modeline.")
;; TODO: Break this into two cubes
(defcube fg42/modeline-cube
"Modeline cube"
(:title "Mini modeline"
:flag mini-mode-line
:group modeline
:flag-default t)
(defun fg42/mini-modeline-setter (def)
(if (null def)
(let ((def-list (funcall def)))
(setq-default mini-modeline-l-format (plist-get def-list :long))
(setq-default mini-modeline-r-format (plist-get def-list :brief)))
(setq-default
mini-modeline-r-format
'("%e"
mode-line-front-space
mode-line-mule-info
mode-line-client
mode-line-modified
mode-line-remote
mode-line-frame-identification
mode-line-buffer-identification
mode-line-position
evil-mode-line-tag
(:eval (string-trim (format-mode-line mode-line-modes)))
mode-line-misc-info ))))
(fpkg/use smart-mode-line
:straight (smart-mode-line :source melpa)
:defer nil
:init
(progn
(setq sml/theme 'respectful)
(setq sml/no-confirm-load-theme t)
(sml/setup)))
(fpkg/use mini-modeline
:straight (mini-modeline :repo "kiennq/emacs-mini-modeline"
:host github
:type git)
:after smart-mode-line
:init
(progn
(setq mini-modeline-enhance-visual nil)
(setq fg42/modeline-setter #'fg42/mini-modeline-setter))
:defer nil
:config
(add-hook 'fg42-after-init-hook #'mini-modeline-mode)))
(defcube fg42/statusbar-cube
"Status bar replaces the default mode line aned merges with
the mini buffer to provide a minimal interface for displaying
valuable information."
(:title "Status bar cube"
:flag status-bar
:group modeline
:flag-default t)
(fg42/all-the-icons-cube)
(defun fg42/statusbar-setter (def)
(unless (null def)
(setq-default fg42/statusbar-components
(plist-get (funcall def) :brief))
(setq-default fg42/statusbar-components
(plist-get (funcall #'fg42/statusbar-default) :brief))))
(setq fg42/modeline-setter #'fg42/statusbar-setter)
(add-hook 'fg42-after-init-hook
(lambda ()
(require 'fg42/statusbar)
(fg42/statusbar-mode t))))
(provide 'cubes/modeline)
;;; modeline.el ends here

View File

@ -0,0 +1,147 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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/modeline)
(require 'fg42/statusbar)
(defmacro fg42/percentage-face (value err warn)
"Return the correct face with repect to VALUE and the given
thresholds ERR adn WARN"
`(cond ((> ,value ,err) 'error) ((> ,value ,warn) 'warning) (t 'success)))
(defbar-unit fg42/statusbar-battery 30 "B--"
(format "B%s"
(string-trim
(with-temp-buffer
(insert-file-contents "/sys/class/power_supply/BAT0/capacity")
(buffer-string)))))
(defbar-unit fg42/statusbar-memory 3 "M--S--"
(let* ((struct (string-trim
(shell-command-to-string "free -k|tail -n 2|awk '{printf(\"%s,%s,\", $3, $2)}'")))
(vals (mapcar #'cl-parse-integer (butlast (split-string struct ","))))
;; TODO: Check for division by zero
(m (* 100 (/ (float(car vals)) (cadr vals))))
;; TODO: Check for division by zero
(s (* 100 (/ (float(caddr vals)) (cadddr vals))))
(x ))
(format
"M%sS%s"
(propertize (format "%02d" m) 'face (fg42/percentage-face m 90 75))
(propertize (format "%02d" s) 'face (fg42/percentage-face s 90 75)))))
(defface fg42/statusbar-project-face
'((t :inherit font-lock-type-face :bold t))
"Project name face on status bar"
:group 'fg42/statusbar)
(defface fg42/statusbar-buffer-name-face
'((t :inherit font-lock-variable-name-face))
"Buffer name face on status line"
:group 'fg42/statusbar)
(defun fg42/statusbar-project-name ()
(when-flag projectile
(projectile-project-name)))
(defun fg42/statusbar-buffer-and-project ()
(format "%s:%s"
(propertize (fg42/statusbar-project-name) 'face 'fg42/statusbar-project-face)
(propertize (buffer-name) 'face 'fg42/statusbar-buffer-name-face)))
;; (defvar fg42/statusbar-git-branch "-")
;; (defvar fg42/statusbar--last-branch "-")
;; (defun fg42/statusbar-update-git-branch()
;; (message "eeoeeeeee")
;; (setq fg42/statusbar-git-branch
;; (shell-command-to-string "git symbolic-ref --short HEAD")))
;; (defun fg42/statusbar-setup-git-branch-updater ()
;; ;;(add-function :after after-focus-change-function #'fg42/statusbar-update-git-branch)
;; (add-hook 'window-configuration-change-hook (lambda () (message "window-configuration-change-hook")))
;; (add-hook 'window-state-change-hook (lambda () (message "window-state-change-hook")))
;; (advice-add :after 'ace-select-window #'fg42/statusbar-update-git-branch)
;; 'fg42/statusbar-git-branch)
(defmode-line fg42/statusbar-default
(list
:brief (list
;;'(buffer-name)
;;'fg42/statusbar-battery
"|"
'(substring-no-properties (vc-mode vc-mode))
"|"
'(fg42/statusbar-buffer-and-project)
"|"
'fg42/statusbar-memory
"|"
'(format-mode-line "%03l:%02c")
;;'(format-time-string "%m-%d %H:%M")
;; (let ((bar (format "%s" fg42/statusbar-memory))) (add-text-properties 0 (string-width bar) (cons 'face (cons '(:size 0.3) (or (get-text-property 0 'face bar) 'default-face))) bar)
;; bar)
)
:long " ")
;; No GUI
)
;; The default modeline for FG42 WM that is compatible with
;; the FG42's status bar only
(defmode-line fg42/statusbar-default-wm
(progn
;; We are in the graphical world
(require 'all-the-icons)
;;(format "%s|%s|%s|%s|%s")
(list
:brief (list
;;'(buffer-name)
;;'fg42/statusbar-battery
'fg42/statusbar-memory
'(format-mode-line "%03l:%02c")
;;'(format-time-string "%m-%d %H:%M")
;; (let ((bar (format "%s" fg42/statusbar-memory))) (add-text-properties 0 (string-width bar) (cons 'face (cons '(:size 0.3) (or (get-text-property 0 'face bar) 'default-face))) bar)
;; bar)
)
:long " "))
;; No GUI
)
(provide 'fg42/modeline/statusbar-default)
;;; statusbar-default.el ends here

229
core/cubes/org.el Normal file
View File

@ -0,0 +1,229 @@
;;; OrgCube --- The org cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(require 'fpkg)
(require 'fg42/cube)
(defflag org-journal
"Enable the support for org-journal in FG42." t)
(defvar fg42/default-org-journal-heder
"#+TITLE: Yearly Journal
#+STARTUP: folded logdrawer logdone logreschedule indent content align constSI entitiespretty")
(defcube fg42/org-ql-cube
"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 installation, you can use the commands without additional configuration.
To use the functions and macros in your own Elisp code, use libraries ~org-ql~
and ~org-ql-view~."
(:title "Org Qurey Language"
:flag org-ql
:flag-default t)
(fpkg/use org-ql
:after org))
(defcube fg42/org-super-agenda-cube
"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.
You can set your groups via the ~:groups~ parameter. Check out the code
for more parameters.
For more information checkout [[https://github.com/alphapapa/org-super-agenda]]"
(:title "Org Super Agenda"
:flag org-super-agenda
:flag-default t)
(defconst fg42/org-super-agenda-groups
nil)
(let* ((params fg42/org-super-agenda-cube-params)
(groups (plist-get params :groups)))
(fpkg/use org-super-agenda
:after org-agenda
:init
(progn
(setq org-agenda-skip-scheduled-if-done (or (plist-get params :skip-scheduled-if-done) t)
org-agenda-skip-deadline-if-done (or (plist-get params :skip-deadline-if-done) t)
org-agenda-include-deadlines (or (plist-get params :include-deadline) t)
org-agenda-block-separator (plist-get params :block-separator)
org-agenda-compact-blocks (or (plist-get params :compact-blocks) t)
org-agenda-start-day (plist-get params :start-day) ;; nil == today
org-agenda-span (or (plist-get params :span) 1)
org-agenda-start-on-weekday (plist-get params :start-on-week)
org-super-agenda-groups groups))
:config
(org-super-agenda-mode))))
(defcube fg42/org-sidebar
"This package presents helpful sidebars for Org buffers. Sidebars are customizable using
~org-ql~ queries and ~org-super-agenda~ grouping.
The default sidebar includes a chronological list of scheduled and deadlined items in the
current buffer (similar to the Org agenda, but without all its features) at the top, and
a list of all other non-done to-do items below. If the buffer is narrowed, the sidebar only
shows items in the narrowed portion; this allows seeing an overview of tasks in a subtree."
(:title "Org Sidebar"
:flag org-sidebar
:flag-default t)
(let ((default-file (or (plist-get fg42/org-sidebar-params :default-file) "~/orgs/main.org"))
(fns (plist-get fg42/org-sidebar-params :sidebar-fns)))
(defun fg42/org-sidebar--default (buf)
(let ((main-org-buf (get-buffer-create "*main-org*")))
(with-current-buffer main-org-buf
(insert-file default-file))
main-org-buf))
(defun fg42/org-sidebar-toggle-sidebar-default ()
(interactive)
(message "here")
(org-sidebar #'fg42/org-sidebar--default))
(if-flag org-super-agenda
(if-flag org-ql
(fpkg/use org-sidebar
:init
(setq org-sidebar-default-fns fns)
:bind
(("<f9>" . fg42/org-sidebar-toggle-sidebar-default)))
(error "`fg42/org-ql-cube' is required for `fg42/org-sidebar'"))
(error "`fg42/org-sugper-agenda-cube' is required for `fg42/org-sidebar'"))))
(defcube fg42/org-cube
"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.
This cube contains ~fg42/org-super-agenda-cube~, ~fg42/org-ql-cube~ and ~fg42/org-sidebar~
cubes and you can pass parameters to them via ~:super-agenda~, ~:ql~ and ~:sidebar~ keys.
For more info on ~org-mode~ check out [[https://orgmode.org/]]"
(:title "Org-mode"
:flag org
:flag-default t)
(let ((capture-key (or (plist-get fg42/org-cube-params :capture-key)
(kbd "<f6>")))
(org-home (or (plist-get fg42/org-cube-params :org-home) "~/orgs"))
(notes-file (or (plist-get fg42/org-cube-params :org-home) "~/orgs/notes.org"))
(journal-header (or (plist-get fg42/org-cube-params :journal-header) fg42/default-org-journal-heder))
(journal-type (or (plist-get fg42/org-cube-params :journal-type) 'yearly))
(global-tags (plist-get fg42/org-cube-params :global-tags))
(agenda-files (or (plist-get fg42/org-cube-params :agenda-files) '("~/orgs/main.org"))))
(fpkg/use org-bullets
:hook (org-mode . org-bullets-mode))
(fg42/org-super-agenda-cube (plist-get fg42/org-cube-params :super-agenda))
(fg42/org-ql-cube)
(fg42/org-sidebar)
(when-flag org-journal
;; This function will handle the org-capture integration only if org-journal
;; flag is set
(defun fg42/org-journal-find-location ()
;; Open today's journal, but specify a non-nil prefix argument in order to
;; inhibit inserting the heading; org-capture will insert the heading.
(org-journal-new-entry t)
(unless (eq org-journal-file-type 'daily)
(org-narrow-to-subtree))
(goto-char (point-max)))
(fpkg/use org-journal
:defer t
:init
;; Change default prefix key; needs to be set before loading org-journal
(setq org-journal-prefix-key "C-c j ")
:config
(setq org-journal-file-type journal-type
org-journal-file-header journal-header
org-journal-dir (expand-file-name "journal" org-home)
org-journal-date-format "%Y-%m-%d (%A): ")))
(fpkg/use org-mode
:init
(progn
(require 'org-capture)
(global-set-key capture-key 'org-capture)
(setq org-tag-alist global-tags)
(setq org-agenda-files agenda-files)
(setq org-directory org-home)
(setq org-default-notes-file notes-file)
(setq org-capture-templates
(eval
`(list
'("t" "Todo" entry (file+headline ,(expand-file-name "main.org" org-home) "New Tasks")
(file ,(expand-file-name "templates/todo" org-home))
:prepend t)
'("l" "Link" entry (file+headline ,(expand-file-name "bookmarks.org" org-home) "Links")
(file ,(expand-file-name "templates/links" org-home))
:prepend t
:immediate-finish t
:empty-lines 1)
,@(when-flag org-journal
'((quote ("j" "Journal Entry" plain #'fg42/org-journal-find-location
"** %(format-time-string org-journal-time-format)%^{Title} %^G\n %?\n\n*** Context:\n %i\n From: %a"
:jump-to-captured t
:immediate-finish nil))))
'("h" "Thoughts" entry (file+datetree ,(expand-file-name "journal.org" org-home))
(file ,(expand-file-name "templates/thoughts" org-home))))))
(setq 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)))
(unless (server-running-p)
(require 'org-protocol))))))
(provide 'cubes/org)
;;; org.el ends here

57
core/cubes/project.el Normal file
View File

@ -0,0 +1,57 @@
;;; ProjectCubes --- The project management cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/projectile-cube
"Projectile Cube"
(:title "cubes/fg42/projectile-cube.org"
:flag projectile
:flag-default t)
(let ((project-dirs (or (plist-get fg42/projectile-cube-params :project-dirs)
())))
(fpkg/use projectile
:init
(projectile-mode +1)
:config
(progn
;; We don't want the auto discovery on startup
(setq projectile-auto-discover nil)
(setq projectile-enable-caching t)
(setq projectile-project-search-path project-dirs))
:bind (:map projectile-mode-map
("s-p" . projectile-command-map)
("C-c p" . projectile-command-map)))
(fpkg/use projectile-ripgrep
:after projectile)))
(provide 'cubes/project)
;;; project.el ends here

129
core/cubes/python.el Normal file
View File

@ -0,0 +1,129 @@
;;; PythonCubes --- The Python cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(require 'fg42/utils)
(defun fg42/py-workon-project-venv ()
"Call pyenv-workon with the current projectile project name.
This will return the full path of the associated virtual
environment found in $WORKON_HOME, or nil if the environment does
not exist."
(require 'pyenv)
(let ((pname (projectile-project-name)))
(pyvenv-workon pname)
(if (file-directory-p pyvenv-virtual-env)
pyvenv-virtual-env
(pyvenv-deactivate))))
(defun fg42/py-auto-lsp ()
"Turn on lsp mode in a Python project with some automated logic.
Try to automatically determine which pyenv virtual environment to
activate based on the project name, using
`dd/py-workon-project-venv'. If successful, call `lsp'. If we
cannot determine the virtualenv automatically, first call the
interactive `pyvenv-workon' function before `lsp'"
(interactive)
(let ((pvenv (fg42/py-workon-project-venv)))
(if pvenv
(lsp)
(progn
(call-interactively #'pyvenv-workon)
(lsp)))))
(defcube fg42/python-black-cube
"This cube reformats python code using black formatter tool."
(:title "Python lang server via pyls"
:flag python-black
:flag-default t)
(fpkg/use python-black
:demand t
:after python
:hook (python-mode . (lambda ()
(python-black-on-save-mode)))))
(defcube fg42/python-cube-pyls
"Python language server using pyls"
(:title "Python lang server via pyls"
:flag python-pyls)
(when-flag lsp
(with-eval-after-load "lsp"
(lsp-register-custom-settings
'(("pyls.plugins.pyls_mypy.enabled" t t)
("pyls.plugins.flake8.enabled" t t)
("pyls.plugins.pyls_mypy.live_mode" nil t)
("pyls.plugins.pyls_black.enabled" t t)
("pyls.plugins.pyls_isort.enabled" t t)))
(add-hook 'python-mode #'fg42/py-auto-lsp))))
(defcube fg42/python-cube-pyright
"Python language server using pyright."
(:title "Python lang server via pyright"
:flag python-pyright)
(fpkg/use lsp-pyright
:ensure t
:after (python lsp-mode)
:hook
(python-mode . (lambda ()
;; Pyls and pylsp can be annoying
(add-to-list 'lsp-disabled-clients 'pyls)
(add-to-list 'lsp-disabled-clients 'pylsp)
;;(fg42/py-auto-lsp)
(require 'lsp-pyright)
(lsp)))))
(defcube fg42/python-cube
"Python support cube."
(:title "Python cube"
:flag python)
(fpkg/use pyvenv
:defer t
:after python
:custom
(pyvenv-workon "env")
:hook
((python-mode-hook . pyvenv-mode)
(pyvenv-post-activate-hooks . pyvenv-restart-python)
(pyvenv-post-deactivate-hooks . pyvenv-restart-python)))
(fpkg/use pyenv-mode
:ensure t
:after python
:hook
(python-mode-hook . pyenv-mode))
(fg42/python-black-cube)
(fg42/python-cube-pyls)
(fg42/python-cube-pyright))
(provide 'cubes/python)
;;; python.el ends here

View File

@ -0,0 +1,36 @@
;;; RegionExpansionCube --- The elisp cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/region-expansion-cube
"RE cube"
(:title "cubes/fg42/region-expansion.org")
(fpkg/use expand-region
:bind ("C-=" . er/expand-region)))
(provide 'cubes/region-expansion)
;;; region-expansion.el ends here

58
core/cubes/rigel.el Normal file
View File

@ -0,0 +1,58 @@
;;; RigelCube --- Rigel client for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://ziglab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/rigel-cube
"This is a [Rigel](https://devheroes.codes/lxsameer/Orion/src/branch/master/rigel)
for *FG42*. Refer to *Rigel* docs to set it up.
This cube exposes few functions that interact with regel. Checkout the docstrings of
functions in `fg42/rigel/` namespace. For example `fg42/rigel/read` function."
(:title "rigel Cube"
:flag rigel
:flag-default t)
(autoload-cube
'fg42/rigel/read
"rigel/core.el"
"Send the given text to the Rigel server to read it out load" t)
(autoload-cube
'fg42/rigel/read-region
"rigel/core.el"
"Send the text of selected region to the Rigel server to read it out load" t)
(autoload-cube
'fg42/rigel/read-clipboard
"rigel/core.el"
"Send the text from the clipboadr to the Rigel server to read it out load" t)
(defun fg42/rigel/-sentinel (process event)
(message "[Rigel] %s" event)))
(provide 'cubes/rigel)
;;; rigel.el ends here

105
core/cubes/rigel/core.el Normal file
View File

@ -0,0 +1,105 @@
;;; RigelCube --- Rigel client for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://ziglab.com/FG42/FG42
;; Version: 3.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 'bindat)
(eval-when-compile
(defvar fg42/rigel-cube-params))
(defconst fg42/rigel/protocol
(bindat-type (len uint 32) (payload str (+ 32 len))))
(defvar fg42/rigel/client-process nil
"The process for the client.")
(defvar fg42/rigel/host (or (plist-get fg42/rigel-cube-params :host) "127.0.0.1")
"The hostname or ip address of the Rigel server.")
(defvar fg42/rigel/port (or (plist-get fg42/rigel-cube-params :port) "6666")
"The port number of the target Rigel server.")
(defun fg42/rigel/-pack-struct (str)
"Pack the given STR in an alist representing a message."
(list (cons 'len (length (eval str))) (cons 'payload (eval str))))
(defun fg42/rigel/-pack (str)
"Pack the give STR into binary format according to the `fg42/rigel/protocol'
protocol."
(bindat-pack fg42/rigel/protocol (fg42/rigel/-pack-struct str)))
(defun fg42/rigel/-sentinel (process event)
(message "[Rigel] %s: %s" process event))
(defun fg42/rigel/-connect ()
(when (null fg42/rigel/client-process)
(message "[Rigel] Connecting to server at %s:%s" fg42/rigel/host fg42/rigel/port)
(setq fg42/rigel/client-process
(make-network-process
:name "rigel-client"
:type nil
:server nil
:host fg42/rigel/host
:service fg42/rigel/port
:nowait t
:buffer (get-buffer-create "*Rigel*")
:sentinel 'fg42/rigel/-sentinel))))
(defun fg42/rigel/close ()
"Shutdown the Rigel client"
(interactive)
(message "[Rigel] Status: %s" (process-status "rigel-client"))
(when (process-status "rigel-client")
(process-send-string fg42/rigel/client-process (fg42/rigel/-pack "//close"))
(stop-process fg42/rigel/client-process))
(setq fg42/rigel/client-process nil)
(kill-buffer "*Rigel*"))
(defun fg42/rigel/read (txt)
"Send the given text to the Rigel server to read it out load"
(interactive "sRead: ")
(fg42/rigel/-connect)
(process-send-string fg42/rigel/client-process (fg42/rigel/-pack txt)))
(defun fg42/rigel/read-region (beg end)
"Send the text of selected region to the Rigel server to read it out load"
(interactive (if (use-region-p)
(list (region-beginning) (region-end))
(list nil nil)))
(fg42/rigel/read
(if (and beg end) (buffer-substring-no-properties beg end) "")))
(defun fg42/rigel/read-clipboard ()
"Send the text from the clipboadr to the Rigel server to read it out load"
(interactive)
(fg42/rigel/read
(or (current-kill 0) "")))
(provide 'cubes/rigel/core)
;;; core.el ends here

50
core/cubes/snippets.el Normal file
View File

@ -0,0 +1,50 @@
;;; JavaCubes --- The Java cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/yasnippet-cube
"Yasnippet cube"
(:title "cubes/fg42/yasnippet-cube.org"
:flag yasnippet
:flag-default t)
(fpkg/use yasnippet-snippets)
(fpkg/use yasnippet
:init
(let* ((snippet-home (expand-file-name "snippets"
(file-name-directory (locate-library "yasnippet-snippets"))))
(local-snippet (expand-file-name "core/cubes/snippets" fg42-home))
(user-snippets (or (plist-get fg42/yasnippet-cube-params :snippets-dir)
;; Just to make sure that we don't return nil. Since
;; yas-snippet-dirs shoud not contain nil value
local-snippet)))
(setq yas-snippet-dirs `(,user-snippets ,local-snippet ,snippet-home))
(yas-global-mode 1))))
(provide 'cubes/snippets)
;;; snippets.el ends here

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1,11 @@
# -*- 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

40
core/cubes/terminal.el Normal file
View File

@ -0,0 +1,40 @@
;;; TerminalCubes --- The terminal related cubes for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/vterm-cube
"Vterm cube"
(:title "cubes/fg42/vterm-cube.org"
:flag vterm)
(let ((_shell (or (plist-get fg42/vterm-cube-params :shell)
(getenv "SHELL"))))
(fpkg/use vterm
:init
(progn
(setq vterm-shell _shell)))))
(provide 'cubes/terminal)
;;; terminal.el ends here

57
core/cubes/terraform.el Normal file
View File

@ -0,0 +1,57 @@
;;; Terraform --- The terraform cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(require 'fpkg)
(require 'fg42/cube)
(defcube fg42/terraform-cube
"terraform cube"
(:title "cubes/fg42/terraform-cube.org"
:flag terraform
:flag-default t)
;; https://github.com/juliosueiras/terraform-lsp is required
(let ((terraform-lsp (or (plist-get fg42/terraform-cube-params :terraform-lsp-path) "terraform-lsp"))
(lsp-flags (or (plist-get fg42/terraform-cube-params :terraform-lsp-flags) "-enable-log-file")))
(fpkg/use terraform-mode
:config
(progn
(when-flag lsp
(require 'lsp)
(add-to-list 'lsp-language-id-configuration '(terraform-mode . "terraform"))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection (list terraform-lsp lsp-flags))
:major-modes '(terraform-mode)
:server-id 'terraform-ls))
(add-hook 'terraform-mode-hook #'lsp))))))
(provide 'cubes/terraform)
;;; terraform.el ends here

49
core/cubes/wm.el Normal file
View File

@ -0,0 +1,49 @@
;;; WMCube --- The elisp cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/flags)
(require 'fg42/cube)
(require 'fg42/utils)
(autoload-cube 'fg42/initialize-wm "wm/core.el" "Initalize the WM mode.")
(defflag wm
"The flag to enable WM mode in FG42.")
(defcube fg42/wm-cube
"This cube will setup *FG42* to act as a window manager."
(:title "Window manager cube"
:no-flag t)
(if-flag wm
(when-wm
(message "[WM] Initilizing...")
(fpkg/use exwm)
(fg42/initialize-wm))
(error "[SKIP] WM flag is not active")))
(provide 'cubes/wm)
;;; wm.el ends here

161
core/cubes/wm/core.el Normal file
View File

@ -0,0 +1,161 @@
;;; WMCube --- The elisp cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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/flags)
(defun wm-randr ()
"RandR support for wm."
(when-wm
(require 'exwm-randr)
(setq exwm-randr-workspace-output-plist '(0 "HDMI-1"
1 "HDMI-1"
2 "HDMI-1"
3 "HDMI-1"
4 "HDMI-1"
5 "HDMI-1"
6 "eDP-1"
7 "HDMI-1"
8 "HDMI-1"
9 "HDMI-1"))
(add-hook 'exwm-randr-screen-change-hook
(lambda ()
(start-process-shell-command
"xrandr" nil "xrandr --output HDMI-1 --above eDP-1 --mode 1920x1080")))
(exwm-randr-enable)))
(defun fg42/initialize-wm ()
"Initilize EXWM window manager with the given PARAMS."
(interactive)
(require 'exwm)
(require 'exwm-config)
(require 'exwm-systemtray)
(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 "/usr/bin/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)
;; 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"))))
;; You can hide the minibuffer and echo area when they're not used, by
;; uncommenting the following line.
;;(setq exwm-workspace-minibuffer-position 'bottom)
;; Do not forget to enable EXWM. It will start by itself when things are
;; ready. You can put it _anywhere_ in your configuration.
(exwm-enable)
(exwm-systemtray-enable)
(wm-randr)
;; (with-flag nlinum
;; (add-hook 'exwm-mode-hook 'disable-nlinum))
)
(provide 'cubes/wm/core)
;;; core.el ends here

43
core/cubes/zig.el Normal file
View File

@ -0,0 +1,43 @@
;;; ZigCube --- The Zig cube for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://ziglab.com/FG42/FG42
;; Version: 3.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 'fpkg)
(require 'fg42/cube)
(defcube fg42/zig-cube
"This cube integrates *zig* into *FG42*."
(:title "Zig Cube"
:flag zig
:flag-default t)
(fpkg/use zig-mode
:mode ("\\.zig?\\'" . zig-mode))
(when-flag lsp
(let ((zls-path (or (plist-get fg42/zig-cube-params :zls) "zls")))
(setq lsp-zig-zls-executable zls-path))))
(provide 'cubes/zig)
;;; zig.el ends here

View File

@ -1,10 +1,10 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -21,22 +21,21 @@
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
(require 'fg42/core)
(require 'fg42/utils)
(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)))
(defun fg42/before-initialize ()
"Initialize the package manager before rendering the window instance."
(require 'fpkg/core)
(fpkg/initialize))
(provide 'fg42/langs/elisp)
;;; elisp.el ends here
(defun fg42/initialize ()
"Initialize FG42 after the Emacs window is rendered by loading the user init file."
(when (file-exists-p user-init-file)
(load user-init-file)))
(provide 'fg42)
;;; fg42.el ends here

197
core/fg42/build/core.el Normal file
View File

@ -0,0 +1,197 @@
;;; Buid --- The builder for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 thnis 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:
(require 'seq)
(defvar fg42/build-project-name "FG42"
"The name to be uesd with in the output as as the project name")
(defvar fg42/build-project-root nil
"Root directory of the website source code.")
(defvar fg42/build-debug-mode nil)
(defvar fg42/build-author-name "Sameer Rahmani")
(defvar fg42/build-author-email "lxsameer@gnu.org")
(defvar fg42/build-docs-root "/docs/site"
"Where to find the docs. It sould be relative to the
project root.")
(defvar fg42/build-dev-base-url "http://localhost:3003"
"The base url to use with the docs for dev.")
(defvar fg42/build-prod-base-url "https://fg42.org"
"The base url to use with the docs for production.")
(defvar fg42/build-docs-pages-dir "/pages"
"Where to find the pages (relative to docs dir)")
(defvar fg42/build-docs-ignore-category-check nil
"A list of files that should be ignored by category/tag checks")
(defvar fg42/build-docs-actions nil
"Set of actions to run before building the
main docs.")
(defvar fg42/build-output-dir "/build"
"The path to the build directory.")
(defvar fg42/build-docs-title "FG42"
"Title of the generated docs. Like the website title")
(defvar fg42/build-docs-desc "The ultimate editor for true believers"
"Description of the generated docs. Like the website description")
(defvar fg42/build-usage "./builder.el SUBCOMMAND"
"Title of the generated docs. Like the website title")
(defmacro defproject (prject-name &rest details)
"Create a project with the given DETAILS.
The build system will consum these details for various purposes."
(declare (indent defun))
(cons 'progn
(cons `(setq fg42/bulid-project-name
,(symbol-name prject-name))
(seq-reduce
(lambda (forms pair)
(let* ((varname (intern (format "fg42/build-%s" (car pair))))
(val (cadr pair))
(form `(setq ,varname ,val)))
(cons form forms)))
(seq-partition details 2)
nil))))
(defmacro command-> (command-var args-var &rest body)
(declare (indent defun))
`(defun main ()
"The entry point to the build script."
(message (fg42/version))
(message "\nFG42 Build tool v%s\n\n" (fg42/version))
;; UTF-8 as default encoding
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(let* ((fg42-home (car command-line-args-left))
(build-dir (from-root ,fg42/build-output-dir))
(parsed-args (read-args (cdr command-line-args-left)))
(eval-string (plist-get (car parsed-args) :e))
(,command-var (caadr parsed-args))
(,args-var (cdadr parsed-args)))
;; Evaluate the expression provided by :e
(when eval-string
(eval (car (read-from-string eval-string))))
(setq fg42/build-debug-mode (plist-get (car parsed-args) :d))
(cond
,@body
(t (print-help ,command-var))))))
(defun print-help (_)
"Print out the usage for the build script"
(message fg42/build-usage))
(defun from-root (path)
"Return the full path of the given PATH in the project root."
(concat fg42/build-project-root path))
(defun from-docs (path)
"Return the full path of the given PATH in the docs root."
(concat (from-root fg42/build-docs-root) path))
(defun prod-p ()
"Return non-nil if debug mode is turned off"
(not fg42/build-debug-mode))
(defun read-args (args)
"Parse the give ARGS list and return a list in the following
format:
(FLAGS (COMMAND ARGES))"
(seq-reduce
(lambda (acc arg)
(let ((flags (car acc))
(commands (cadr acc))
(i (caddr acc))
(skip (cadddr acc)))
(if skip
(list flags commands (1+ i) ())
(progn
(cond
((string= arg ":d") (plist-put flags :d t))
((string= arg ":e") (progn
(plist-put flags :e (nth (1+ i) args))
(setq skip (1+ i))))
(t (push arg commands)))
(list flags commands (1+ i) skip)))))
args
'((:d () :e ()) () 0 ())))
(defun replace-in-buffer (str replacement)
"Replace the given STR with its REPLACEMENT in current buffer."
(with-current-buffer (current-buffer)
(goto-char (point-min))
(while (search-forward str nil t)
(replace-match replacement))))
(defun copy-template (src dest context)
"Replace the placeholder in SRC with list of pairs given in CONTEXT
and write it to DEST."
(make-directory (file-name-directory dest) t)
(message "Copy template: '%s' -> '%s'" src dest)
(with-temp-file dest
(insert-file-contents src)
(dolist (pair context)
(replace-in-buffer (format "<<<%s>>>" (car pair)) (cdr pair)))))
(defmacro do-command (&rest body)
"Run the BODY after loading FG42."
`(progn
(require 'fg42)
(fg42/before-initialize)
,@body))
(provide 'fg42/build/core)
;;; core.el ends here

434
core/fg42/build/docs.el Normal file
View File

@ -0,0 +1,434 @@
;;; Buid --- The builder for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 thnis 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:
(require 'fpkg)
(fpkg/use dash)
(fpkg/use mustache)
(fpkg/use ht)
(fpkg/use htmlize)
(require 'ox-html)
(require 'cubes/all)
(require 'fg42/build/core)
(require 'fg42/build/utils)
(require 'fg42/build/ox-template)
(require 'fg42/build/rss)
(defvar cube-template (from-root "/docs/site/templates/cube.org"))
(defvar cubes-index-template (from-root "/docs/site/templates/cubes.org"))
(defun fg42/build-docs-for-cube (build-dir cube)
"Build the given CUBE's doc in BUILD-DIR"
(let* ((cubes-dir (expand-file-name "site/cubes/" build-dir))
(props (symbol-plist cube))
(docs (plist-get props :docs))
(cube-file (concat (expand-file-name (symbol-name cube) cubes-dir)
".org")))
(copy-template cube-template
cube-file
`((:title . ,(plist-get props :title))
(:docs . ,docs)))))
(defun fg42/build-docs-copy-base (build-dir)
"Copy the base structure of the website to the BUILD-DIR."
(copy-directory (from-docs fg42/build-docs-pages-dir)
(expand-file-name (format "site/%s" fg42/build-docs-pages-dir)
build-dir)
nil t))
(defun fg42/build-prepare-docs (build-dir host)
"Prepare the documents and the website in the given BUILD-DIR."
;; Build the org files for each cube
(message "Processing the docs for all the cubes")
(mapcar (lambda (cube)
(fg42/build-docs-for-cube build-dir cube))
fg42/available-cubes)
;; Build the cubes list index file
(message "Processing cubes index file")
(copy-template cubes-index-template
(expand-file-name "site/cubes/index.org" build-dir)
(list
(cons :links (mapconcat (lambda (c)
(format "- [[%s][%s]]\n"
;; href
(format "%s/cubes/%s.html" host c)
;; title
(plist-get (symbol-plist c) :title)))
(sort fg42/available-cubes 'string<))))))
(defun all-org-files ()
"Return a list of all the org files in the orgs directory."
(split-string
(shell-command-to-string (format "find %s -iname \"*.org\"" org-directory))
"\n" t))
(defun get-all-tags ()
"Return a list of all the tags in the org files."
(seq-reduce
;; all-tags is in (tags . tags->files) form
(lambda (all-tags file)
(if (get-file-global-props file "PAGE")
;; Ignore pages
all-tags
(with-temp-buffer
(insert-file-contents file)
(let ((tags (mapcar #'car (org-get-buffer-tags))))
(seq-reduce
(lambda (result tag)
(let ((tag-list (car result))
(tag->file (cdr result)))
(cons
;; Tag list
(if (member tag tag-list) tag-list (sort (cons tag tag-list) 'string<))
;; tag->file
(cons (cons tag
;; Current value of the the given tag (all the files
;; that contain that tag)
(append (list file) (cdr (assoc tag tag->file))))
tag->file))))
tags
all-tags)))))
(all-org-files)
'()))
(defun get-all-posts ()
"Return all the post org files.
Not pages."
(let ((files (all-org-files)))
(seq-reduce
(lambda (result file)
(let ((is-page? (string= (get-file-global-props file "PAGE") "true")))
(if (not is-page?)
;; It's a post
(cons
(list
;; This is not effecient since we parse the file
;; on each query, but who cares :D ?
(->epoch (get-file-global-props file "DATE"))
(get-file-global-props file "TITLE")
(replace-regexp-in-string "\\.org" ".html"
(file-name-nondirectory file))
(list file (fg42/exctract-keywords file '("TITLE" "DATE" "DESC" "AUTHOR" "CATEGORY"))))
result)
result)))
files
'())))
(defun get-all-posts-files ()
"Return all the post org files.
Not pages."
(let ((files (all-org-files)))
(seq-reduce
(lambda (result file)
(let ((is-page? (string= (get-file-global-props file "PAGE") "true")))
(if (not is-page?)
;; It's a post
(cons
file
result)
result)))
files
'())))
(defun get-all-sorted-posts ()
"Return all posts in sorted order."
(sort
(get-all-posts)
(lambda (x y) (> (car x) (car y)))))
(defun latest-org-list (base-url)
"Return a list of links (using BASE-URL) to the tags in org format."
(let ((posts (get-all-sorted-posts)))
(mapconcat
(lambda (post)
(format " - [[%s%s/%s?%s][%s]]"
base-url
fg42/build-docs-pages-dir
;; Path
(nth 2 post)
;; Hash
(car post)
;; Title
(nth 1 post)))
posts
"\n")))
(defun get-all-categories ()
"Return all the categories of the org files."
(seq-reduce
;; all-cats is in (cats . cat->files) form
(lambda (all-cats file)
(if (not (member (file-relative-name file org-directory)
fg42/build-docs-ignore-category-check))
(let ((is-page? (string= (get-file-global-props file "PAGE") "true"))
(cat (get-file-global-props file "CATEGORY"))
(cat-list (car all-cats))
(cat->file (cdr all-cats)))
(if (not is-page?)
(cons
;; Category list
(if (member cat cat-list) cat-list (sort (cons cat cat-list) 'string<))
;; cat->file
(cons (cons cat
;; Current value of the the given cat (all the files
;; under that category)
(append (list file) (cdr (assoc cat cat->file))))
cat->file))
all-cats))
all-cats))
(all-org-files)
'()))
(defun category-org-list ()
"Return a list of links to the categories in org format."
(let ((categories (get-all-categories)))
(mapconcat
(lambda (cat)
(let ((count (length (cdr (assoc cat (cdr categories))))))
(format " - [[./%s.html][%s(%s)]]" cat cat count)))
(car categories)
"\n")))
(defun tags-org-list ()
"Return a list of links to the tags in org format."
(let ((tags (get-all-tags)))
(mapconcat
(lambda (tag)
(let ((count (length (cdr (assoc tag (cdr tags))))))
(format " - [[./%s.html][%s(%s)]]" tag tag count)))
(car tags)
"\n")))
(defun create-tag-pages (build-dir)
"Create all the tag files in the BUILD-DIR."
(let ((tags (get-all-tags)))
(mapcar
(lambda (tag)
(let ((out (format "%s/site/tags/%s.org" build-dir (or tag "Uncategorized")))
(files (cdr (assoc tag (cdr tags)))))
(copy-template
(from-docs "/templates/links_template.org")
out
(list
(cons :links
(mapconcat
(lambda (file-pair)
(format "- [[file:..%s][%s]]"
(replace-regexp-in-string (regexp-quote (from-root "/build/site"))
""
(cdr file-pair)
nil
'literal)
(get-file-global-props (cdr file-pair) "TITLE")))
(sort
(mapcar #'pair-file-with-date files)
(lambda (x y) (> (car x) (car y))))
"\n"))
(cons :title (or tag "Uncategorized"))))))
(car tags))))
(defun create-category-pages (build-dir)
"Create all the category files in the BUILD-DIR."
(let ((tags (get-all-categories)))
(mapcar
(lambda (tag)
(let ((out (format "%s/site/categories/%s.org" build-dir (or tag "Uncategorized")))
(files (cdr (assoc tag (cdr tags)))))
(when (null tag)
(message "[Error]: The following files are missig a category: %s"
(mapconcat
(lambda (x) (format " %s" x))
(sort
(mapcar #'pair-file-with-date files)
(lambda (x y) (> (car x) (car y))))
"\n"))
(error "The above list of files are missing a category"))
(copy-template
(from-docs "/templates/links_template.org")
out
(list
(cons :links
(mapconcat
(lambda (file-pair)
(format "- [[file:..%s][%s]]"
(replace-regexp-in-string (regexp-quote (from-root "/build/site"))
"" (cdr file-pair) nil 'literal)
(get-file-global-props (cdr file-pair) "TITLE")))
(sort
(mapcar #'pair-file-with-date files)
(lambda (x y) (> (car x) (car y))))
"\n"))
(cons :title (or tag "Uncategorized"))))))
(car tags))))
(defun fg42/build-docs (build-dir)
"Build the documents and the website in the given BUILD-DIR."
(let ((base-url (if (prod-p) fg42/build-prod-base-url fg42/build-dev-base-url))
(stage1-dir (expand-file-name "site" build-dir))
(final-dir (expand-file-name "site-build" build-dir)))
(fg42/build-docs-copy-base build-dir)
;; Apply all the actions
(mapcar (lambda (f)
(funcall f build-dir base-url))
fg42/build-docs-actions)
;; Copy the assets
(copy-directory (from-docs "/assets")
(expand-file-name "assets" stage1-dir) nil t)
;; We will use the org-agenda to extract all the tags
;;; Set the dir containing org the org-files
(setq org-directory (expand-file-name "site" build-dir))
;;; Discover all the org files
(setq org-agenda-files (all-org-files))
(setf user-full-name fg42/build-author-name)
(setf user-mail-address fg42/build-author-email)
;; Disable default header links (top, next)
(setf org-html-home/up-format "")
(setf org-html-link-up "")
(setf org-html-link-home "")
(setf org-html-scripts "")
(copy-template (from-docs "/config.org")
(expand-file-name "config.org" build-dir)
'())
(message "Creating the main index file")
(copy-template (from-docs "/templates/index.org")
(expand-file-name "site/index.org" build-dir)
`((:links . ,(latest-org-list base-url))
(:base-url . ,base-url)))
(message "Creating categories")
(copy-template (from-docs "/templates/categories.org")
(expand-file-name "site/categories/index.org" build-dir)
`((:links . ,(category-org-list))))
(create-category-pages build-dir)
(message "Creating tags")
(copy-template (from-docs "/templates/tags.org")
(expand-file-name "site/tags/index.org" build-dir)
`((:links . ,(tags-org-list))))
(create-tag-pages build-dir)
(setq org-html-preamble #'preamble-fn)
(setq org-html-htmlize-output-type nil)
(setq org-latex-listings t)
(setq org-publish-project-alist
`(("website"
:base-directory ,stage1-dir
:root-directory ,stage1-dir
:recursive t
:base-extension "org"
:publishing-directory ,final-dir
;; Exclude the blog archive index autogenerated below
;; Note that the regexp is relative to :base-directory
;; :exclude "^index.org"
:section-numbers nil
:with-author t
:with-drawers t
:html-format-drawer-function custom-drawer-format
:with-properties t
:with-tags t
:with-timestamps t
:with-toc nil
:base-url ,base-url
:html-link-home "/"
:html-template ,(from-docs "/templates/blog.html")
:html-page-preamble-template ,(from-docs "/templates/page-preamble.html")
:html-post-preabmle-template ,(from-docs "/templates/post-preamble.html")
:html-tags-template ,(from-docs "/templates/tags.html")
:publishing-function org-html-publish-to-templated-html
:auto-sitemap t
:htmlized-source nil
:sitemap-folders ignore
:sitemap-style list
:sitemap-title ,fg42/build-docs-title
:sitemap-filename "sitemap.inc"
:sitemap-sort-files anti-chronologically
:html-format-headline-function headline-format
:exclude "rss.org"
:makeindex nil)
("rss"
:base-directory ,stage1-dir
:base-extension "org"
:html-link-home ,base-url
:html-link-use-abs-url t
:rss-extension "xml"
:publishing-directory ,final-dir
:publishing-function (org-rss-publish-to-rss)
:org-rss-use-entry-url-as-guid t
:section-numbers nil
:exclude ".*" ;; To exclude all files...
:include ("rss.org") ;; ... except index.org.
:table-of-contents nil)
("statics"
:base-directory ,stage1-dir
:base-extension "css\\|js\\|png\\|jpg\\|gif\\|pdf\\|svg"
:publishing-directory ,final-dir
:recursive t
:publishing-function org-publish-attachment)
("build" :components ("website" "statics"))))
(org-publish-project "build" t nil)
(fg42/rss-create (get-all-sorted-posts) base-url (expand-file-name "rss.xml" final-dir))
(message "Build complete.")))
(provide 'fg42/build/docs)
;;; docs.el ends here

View File

@ -0,0 +1,163 @@
;;; ox-template.el --- A HTML exporter via templates for org-mode
;; Copyright (C) 2021-2022 Sameer Rahmani
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/lxsameer/lxhome
;;
;; 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:
;; Inspired by Juan Jose Garcia Ripoll work.
;;; Code:
;; We ensure the org infrastructure
(require 'org)
(require 'seq)
(require 'ox-publish)
(require 'mustache)
(require 'pp)
(require 'ht)
(require 'fg42/build/utils)
(defun use-html (path-to-template)
"Use the given template at PATH-TO-TEMPLATE as a template."
(with-temp-buffer
(insert-file-contents path-to-template)
(buffer-string)))
(defun render-tags (tags)
"Return a string representing TAGS html."
(if tags
(mapconcat (lambda (x) (format "<a href=\"/tags/%s.html\" class=\"tag-link\">#%s</a>" x x))
tags
" | ")
""))
(defun preamble-fn (info)
"Return a string for the header section of pages using INFO plist."
(let* ((file (plist-get info :input-file))
(page-template (or (plist-get info :html-page-preamble-template) "page-preamble.html"))
(post-template (or (plist-get info :html-post-preabmle-template) "post-preamble.html"))
(is-page? (string= (get-file-global-props file "PAGE") "true"))
(tags (get-file-tags file)))
(let ((title (get-file-global-props file "TITLE"))
(date (get-file-global-props file "DATE")))
(when (not title)
(message "'#+TITLE' is missing from '%s'" file)
(error "'#+TITLE' is missing from '%s'" file))
(if is-page?
(mustache-render (use-html page-template)
(ht ("title" title)))
(progn
(mustache-render (use-html post-template)
(ht
("title" title)
("date" (or date ""))
("tags" (render-tags tags)))))))))
(defun org-html-render-tag-template (tags info)
"Render the given TAGS and INFO using the :html-headline-template."
(let ((template (plist-get info :html-tags-template))
(ctx (ht ("tags" (format "%s" tags))
("base-url" (plist-get info :base-url)))))
(if (null tags)
""
(mustache-render (use-html template) ctx))))
;; Replace org-html--tags with our impelementation if the
;; `:html-headline-template' configuration exists
(advice-add 'org-html--tags :around 'org-html-tag-template)
(defun org-html-tag-template (orig-fn &rest args)
"Decide whether to run ORIG-FN with ARGS or the org-html-render-tag-template.
It looks for `:html-tags-template' in the info and if i exists it will
call `org-html-render-tag-template' otherwise will call ORIG-FN."
(let ((template (plist-get (cadr args) :html-tags-template)))
(if template
(apply #'org-html-render-tag-template args)
(apply orig-fn args))))
(org-export-define-derived-backend 'templated-html 'html
:translate-alist '((template . templated-html-template-fn)))
(defun headline-format (todo todo-type priority text tags info)
"Format the headline using TODO TODO-TYPE PRIORITY TEXT TAGS and INFO."
(let ((todo (org-html--todo todo info))
(priority (org-html--priority priority info))
;; We don't care about the tags here since we put the in the preamble
(tags nil))
(concat todo (and todo " ")
priority (and priority " ")
text
(and tags "&#xa0;&#xa0;&#xa0;") tags)))
(defun render-template (template-name contents info)
"Render the given template TEMPLATE-NAME using CONTENTS and INFO."
(let ((ctx (ht ("content" contents)
("head" (plist-get info :html-head-extra))
("base-url" (plist-get info :base-url))
("preamble" (org-html--build-pre/postamble 'preamble info))
("title" (get-file-global-props (plist-get info :input-file) "TITLE"))
("version" (fg42/version))
("description" (or (get-file-global-props (plist-get info :input-file) "DESC")
""))
("postamble" (org-html--build-pre/postamble 'postamble info)))))
(mustache-render (use-html template-name) ctx)))
(defun templated-html-template-fn (contents info)
"Return the finalized html CONTENTS using the INFO and templates."
(let ((template (plist-get info :html-template)))
(if template
(render-template template contents info)
(org-html-template contents info))))
(defun custom-drawer-format (name content)
"Return the drawer format for the given drawer NAME and CONTENT."
(format "<section class='%s-drawer'><p>%s</p>%s</section>"
(downcase name)
(capitalize name)
content))
(defun org-html-publish-to-templated-html (plist filename pub-dir)
"Publish an org file to HTML.
FILENAME is the filename of the Org file to be published. PLIST
is the property list for the given project. PUB-DIR is the
publishing directory.
Return output file name."
(org-publish-org-to 'templated-html filename
(concat "." (or (plist-get plist :html-extension)
org-html-extension
"html"))
plist pub-dir))
(provide 'fg42/build/ox-template)
;;; ox-template.el ends here

93
core/fg42/build/rss.el Normal file
View File

@ -0,0 +1,93 @@
;;; Buid --- The builder for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 thnis 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:
(require 'seq)
(require 'fg42/build/core)
(defun fg42/rss-map-items (file-and-props link)
"Create a RSS item from the given org FILE with the give http LINK"
(let* ((file (car file-and-props))
(values (cadr file-and-props)))
(format
(concat
" <item>\n"
" <title>%s</title>\n"
" <link>%s</link>\n"
" <author>%s</author>\n"
" <guid isPermaLink=\"false\">%s</guid>\n"
" <pubDate>%s</pubDate>\n"
" <description><![CDATA[%s]]></description>\n"
" </item>\n")
(cadr (assoc "TITLE" values))
link
(or
(cadr (assoc "AUTHOR" values))
fg42/build-author-name)
link
(or
(cadr (assoc "DATE" values))
(error "'DATE' is missing from '%s'" file))
(or
(cadr (assoc "DESC" values))
(error "'DESC' is missing from '%s'" file)))))
(defun fg42/rss-create-item (post base-url)
(fg42/rss-map-items
(car (last post))
(format "%s%s/%s"
base-url
fg42/build-docs-pages-dir
;; Path
(nth 2 post))))
(defun fg42/rss-create (posts base-url dest)
"Create a RSS xml file via POSTS for the give BASE-URL and save to DEST"
(with-temp-file dest
(insert
(format
(concat
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
"<rss version=\"2.0\">\n"
"<channel>\n"
" <title>%s</title>\n"
" <link>%s</link>\n"
" <description>%s</description>\n"
"%s\n"
"</channel>\n"
"</rss>\n")
fg42/build-docs-title
base-url
fg42/build-docs-desc
(mapconcat
(lambda (post)
(fg42/rss-create-item post base-url))
posts)))))
(provide 'fg42/build/rss)
;;; docs.el ends here

101
core/fg42/build/utils.el Normal file
View File

@ -0,0 +1,101 @@
;;; Buid --- The builder for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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 thnis 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:
(require 'org-element)
(require 'fg42/build/core)
(defmacro comment (&rest _)
"Ignore the given BODY."
nil)
(defun ->epoch (date-str)
"Convert the given DATE-STR to epoch seconds."
;; Just because it's easier to deal with date in bash rather than elisp
(string-to-number
(shell-command-to-string (concat (format "date -d %s" date-str) " +%s"))))
(defun get-buffer-global-props (prop)
"Get a plists of global org properties PROP of current buffer."
(car
(org-element-map
(org-element-parse-buffer)
'keyword
(lambda (el)
(when (string-match prop (org-element-property :key el))
(org-element-property :value el))))))
(defun get-file-global-props (file prop)
"Return the value of the given global PROP in the given org FILE."
(with-temp-buffer
(insert-file-contents file)
(get-buffer-global-props prop)))
(defun fg42/exctract-keywords (file keys)
"Create a RSS item from the given org FILE"
(let ((cwd (getenv "PWD"))
(old-org-directory org-directory))
(cd fg42/build-project-root)
(prog1
(with-temp-buffer
(insert-file-contents file)
(org-collect-keywords keys))
(cd cwd))))
(defun pair-file-with-date (file)
"Return a pair for the given FILE with date as car and file as cdr."
(cons
(->epoch (get-file-global-props file "DATE"))
file))
(defun get-file-tags (file)
"Returna list of tags for the given FILE."
(with-temp-buffer
(insert-file-contents file)
(mapcar #'car (org-get-buffer-tags))))
(defun fg42/git-branch ()
(cd fg42/build-project-root)
(shell-command-to-string "git branch --show-current"))
(defun fg42/version ()
"Returns the current version of FG42."
(cd fg42/build-project-root)
(shell-command-to-string (format "git describe %s" (fg42/git-branch))))
(provide 'fg42/build/utils)
;;; utils.el ends here

View File

@ -1,10 +1,10 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -25,20 +25,17 @@
(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-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.")
"The hook tha runs when FG42 finished running the user configuration")
(defvar fg42-home (getenv "FG42_HOME")
"The pass to fg42-home.")
(defvar fg42-tmp (concat fg42-config-dir "/tmp"))
(defvar fg42-tmp (concat fg42-home "/tmp"))
(provide 'fg42/core)

170
core/fg42/cube.el Normal file
View File

@ -0,0 +1,170 @@
;;; Cube --- Cube library of FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(require 'seq)
(require 'fg42/utils)
(defvar fg42/after-cubes-setup-hook nil
"A hook that will be run after all the active cubes got setup.
This hook is dedicated for the codes that needs to do stuff based on other cubes
presence. With this hook we eliminate the need for cube ordering.
It will be called in the `fg42-config' and the proper way to use
it is to use `fg42/after-cubes' macro.")
(defvar fg42/available-cubes '()
"A list of all the registered cubes.")
(defmacro defcube (cube-name docs props &rest body)
"Define a cube with the given CUBE-NAME, a list of PROPS, DOCS and a BODY."
(declare (indent defun) (doc-string 2))
;; Make sure that props is a plist and contains the `:docs' key
;; TODO: Maybe use `cl-check-type' here
(when (not (stringp docs))
(error "Missing docstring for '%s' cube" cube-name))
(when (not (plist-get props :title))
(error "Missing :titel key for '%s' cube" cube-name))
(let ((complete-props (plist-put props :docs docs))
(cube-name-internal (intern (format "%s-internal" cube-name)))
(params-var (intern (format "%s-params" cube-name)))
(active-var (intern (format "%s-active-p" cube-name)))
(pre-lang-server-up-hook (intern (format "%s-pre-lang-server-up-hook" cube-name)))
(post-lang-server-up-hook (intern (format "%s-post-lang-server-up-hook" cube-name)))
(pre-lang-server-down-hook (intern (format "%s-pre-lang-server-down-hook" cube-name)))
(post-lang-server-down-hook (intern (format "%s-post-lang-server-down-hook" cube-name)))
(pre-init-hook (intern (format "%s-pre-init-hook" cube-name)))
(post-init-hook (intern (format "%s-post-init-hook" cube-name)))
(post-init-hook (intern (format "%s-post-init-hook" cube-name)))
(flag-var (or (plist-get props :flag) cube-name))
(flag-docstring-var (or (plist-get props :flag-doc)
(format "The flag to enable/disable the '%s' cube." cube-name)))
(flag-default (plist-get props :flag-default))
(flag-conflict (plist-get props :conflicts-with))
(no-flag? (or (plist-get props :no-flag) ())))
(add-to-list 'fg42/available-cubes cube-name)
`(progn
;; Create a new flag for each cube to control the cubes systemwide.
(when (not ,no-flag?)
(defflag ,flag-var ,flag-docstring-var ,flag-default))
;; Params variable contains the list of params the is passed to
;; the current cube call
(defvar ,params-var nil
,(format "Parameters for the '%s' cube." cube-name))
;; * Hooks
;; This hook can be used by others to run code just before running that
;; code body
(defvar ,pre-init-hook nil
,(format "The hook that runs befor the '%s' cube initialization." cube-name))
;; This hook can be used by others to run code just after the body of
;; the cube
(defvar ,post-init-hook nil
,(format "The hook that runs after the '%s' cube initialization." cube-name))
;; TODO: Move language server related hooks to lang-server
;; TODO: Provide a way to let different parts of the
;; codebase to create cube hooks
;; ** Language Server
;;; The hook that enables users to change the language server configuration
;;; of the current cube before activating the server
(defvar ,pre-lang-server-up-hook nil
,(format "The hook that runs befor the '%s' cube's language server activates ." cube-name))
;;; The hook to do any post configuration for the lang server of the cube
(defvar ,post-lang-server-up-hook nil
,(format "The hook that runs after the '%s' cube's language server activates." cube-name))
;;; The hook to run code just before the language server is about to shutdown
(defvar ,pre-lang-server-down-hook nil
,(format "The hook that runs befor the '%s' cube's language server shuts down." cube-name))
;;; The hook to run code after the language server successfully shuts down
(defvar ,post-lang-server-down-hook nil
,(format "The hook that runs after the '%s' cube's language server shuts down." cube-name))
;; This way we can bypass the flag system if we really really want to.
(defun ,cube-name-internal (params)
(if (or (not (boundp (quote ,active-var)))
(not ,active-var))
(progn
;; Mark this cube as active
(setq ,active-var t)
;; Set the parameters in CUBE-NAME-params to be accessable
;; in the body
(setq ,params-var params)
;; Run the pre init hook
(run-hooks (quote ,pre-init-hook))
(fg42/info "Initializing '%s' cube." (quote ,cube-name))
;; Run the body
(let ((result (progn ,@body)))
;; Run the post init hook
(run-hooks (quote ,post-init-hook))
result))
(fg42/info "The '%s' cube is already active." ',cube-name)))
(defun ,cube-name (&rest params)
(interactive)
(if ,no-flag?
;; If no flag is need to control this cube
(,cube-name-internal params)
;; Otherwise check for the flag to be active
(if-flag ,flag-var
(,cube-name-internal params)
(fg42/info "The flag for '%s' cube is disabled. Skiping." ,(symbol-name cube-name)))))
;; Set the symbol-plist of the cube-name to its props
(setplist ',cube-name ',complete-props))))
(defmacro fg42/after-cubes (&rest body)
"Add the BODY to `fg42/after-cubes-setup-hook' hook."
(declare (indent defun))
`(add-hook 'fg42/after-cubes-setup-hook
(lambda ()
,@body)))
(provide 'fg42/cube)
;;; cube.el ends here

View File

@ -1,10 +1,10 @@
;;; Flags --- Flags library of FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -40,7 +40,7 @@ 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")
:package-version '(FG42 . "3.x")
:type '(symbol)
:tag "FG42 Flags")

View File

@ -1,10 +1,10 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;; Flags --- Flags library of FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -21,16 +21,10 @@
;;
;;; Commentary:
;;; Code:
(eval-when-compile
(require 'fpkg))
(require 'fg42/flags)
(use! elfeed
"The best rss reader you can ask for."
:commands elfeed
:bind
("C-x w" . elfeed))
(provide 'fg42/rss)
;;; rss.el ends here
(provide 'lang-servers)
;;; lang-servers.el ends here

51
core/fg42/modeline.el Normal file
View File

@ -0,0 +1,51 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(defvar fg42/modeline-setter #'fg42/default-mode-line-setter)
(defmacro defmode-line (name &rest body)
`(defun ,name () ,@body))
;; The default modeline has to be nil to let the
;; modeline setters know that they can use their
;; default modeline
(defmode-line fg42/default-modeline)
(defun fg42/default-mode-line-setter (def)
"Set the modeline definition in X to the `fg42-modeline'."
(unless (null def)
(setq mode-line-format (plist-get def :brief))
(setq mode-line-format (plist-get (fg42/default-modeline) :brief))))
(defun fg42/setup-modeline-format (definition)
"Setup the modeline by calling the setter function and passing the DEFINITION."
(funcall fg42/modeline-setter definition))
(provide 'fg42/modeline)
;;; modeline.el ends here

View File

@ -1,10 +1,10 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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

View File

@ -1,10 +1,10 @@
;;; Themes --- Theme library of FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -25,16 +25,8 @@
;; way. Cubes are composable and a composition of cubes creates an editor.
;;
;;; Code:
(eval-when-compile
(require 'fpkg)
(require 'fg42/config))
(require 'fg42/utils)
(defvar fg42/ui-hook ()
"A hook that cubes can use via :ui-hook property.
It executes way before the rest of the cubes.")
(defvar fg42/before-initializing-theme-hook ()
"The hook to plug any configuration to before initialize event of themes.")
@ -42,17 +34,12 @@ It executes way before the rest of the cubes.")
"The hook to plug any configuration to after initialize event of themes.")
(defmacro fg42/setup-theme! ()
"Grab the them provided by `fg42/theme' and load it.
Load the theme via `use!' and pass the BODY to the `use!' macroro.
If the theme name and the theme package name are different the package
name can be set via `fg42/theme-package'."
`(use! ,(intern (config-get-or theme-package-name (config-get theme)))
"Setting up the ,pkg package."
:config
(progn
(load-theme ',(intern (config-get theme)) t))))
(defmacro fg42/setup-theme (&rest body)
"Run the BODY inside the FG42 theme setup context."
`(progn
(run-hooks 'fg42/before-initializing-theme-hook)
,@body
(run-hooks 'fg42/after-initializing-theme-hook)))
(provide 'fg42/themes)

View File

@ -1,10 +1,10 @@
;;; Utils --- Utils library of FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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
@ -97,6 +97,29 @@ with is the buffer."
,@form))
;; TODO: A good candidate for an inline function
(defun find-value-for (lst key)
"Return the value of the given KEY in the given LST.
For example for a list like (list :x 4 :y 5) we can find the value of
`:x' by doing `(get-value-for lst :x)'."
(let ((pairs (seq-partition lst 2)))
(let ((pair (assq key pairs)))
(when pair
(cadr pair)))))
(defun comp (&rest fns)
"Compose the given list of FNS into one function that accepts multiple values.
For example:
(funcall (compose (lambda (x) (+ 1 x)) (lambda (x) (* x s))) 5)
or
(funcall (compose #'some-fn #'message) some-value)"
(lambda (&rest values)
(cl-reduce 'funcall (butlast fns)
:from-end t
:initial-value (apply (car (last fns)) values))))
(defun path-join (&rest paths)
"Join the given PATHS."
(apply #'concat
@ -134,6 +157,20 @@ last item in second form, etc."
(:else `(->> (->> ,x ,form) ,@more))))
(defun load-user-config (file)
"Load the given FILE as user config file."
(if (file-exists-p file)
(load-file file)))
(defmacro autoload-cube (fn file docstring &optional interactive)
"A wrapper for autloading FN at FILE with the given DOCSTRING.
This macro looks inside of the cubes directories. If the INTERACTIVE param
is non-nil value it means that the function can be called interactively."
`(autoload ,fn (expand-file-name (format "core/cubes/%s" ,file) fg42-home)
,docstring ,interactive))
(defmacro when-wm (&rest body)
"Run the BODY only if in wm mode."
(if (string= (getenv "FG42_WM") "true")
@ -147,14 +184,17 @@ last item in second form, etc."
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))))
(defmacro fg42/log (tag args)
"If the debug is enabled log the give ARGS."
(if fg42/debug-p
`(message "[%s]: %s" ,tag (apply #'format ,args))
nil))
(defmacro fg42/info (&rest args)
"If the debug is enabled log the give ARGS."
(fg42/log "INFO" args))
(if (boundp theme-sym)
(or (eval `(plist-get ,theme-sym ,color-name)) default)
default)))
(provide 'fg42/utils)

View File

@ -1,6 +1,6 @@
;;; fpkg --- a simple package manager for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;; Copyright (C) 2010-2021 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; Keywords: lisp fg42 IDE package manager
@ -24,45 +24,32 @@
;; Simple package manager for FG42
;;
;;; Code:
(require 'map)
(defvar package-names ())
(eval-when-compile
(defvar fg42/disabled-features '())
(require 'use-package))
;;(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)))
(defun inject-straight (args)
"Inject `:straight t' to ARGS it the key was missing."
(if (member :straight args)
args
(append args '(:straight t))))
(defun inject-defer (args)
"Inject `:defer t' to ARGS it the key was missing."
(if (member :defer args)
args
(append args '(:defer t))))
(defmacro fpkg/use (pkg &rest details)
"Install the given package DETAILS PKG via `use-package' and straight."
"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))))
(let ((params (inject-straight (inject-defer details))))
(progn
`(use-package ,pkg ,@params)))
`(use-package ,pkg :straight t :defer t)))
(provide 'fpkg)

View File

@ -1,6 +1,6 @@
;;; fpkg --- a simple package manager for FG42 -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
;; Copyright (C) 2010-2021 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; Keywords: lisp fg42 IDE package manager
@ -29,38 +29,36 @@
(defvar bootstrap-version 5)
(defcustom fpkg-package-directory (concat fg42-home "/.fpkg")
"Specify the directory to store all the dependencies."
:group 'fpkg
:type 'string)
(defun fpkg/install-and-load-use-package ()
"Install and load the `use-package' in compile time."
"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)))
(straight-use-package 'use-package)
(setq use-package-always-ensure t)
(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)))
(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))
(unless (file-exists-p bootstrap-file)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/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)))
(provide 'fpkg/core)
;;; core.el ends here

View File

@ -1,10 +1,10 @@
;;; ob-gharphviz --- org-babel functions for gharphviz evaluation of FG42
;;
;; Copyright (c) 2010-2024 Sameer Rahmani & Contributors
;; Copyright (c) 2010-2022 Sameer Rahmani & Contributors
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://devheroes.codes/FG42/FG42
;; Version: 4.0.0
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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

71
dev.org Normal file
View File

@ -0,0 +1,71 @@
#+TITLE: FG42 Development
#+AUTHOR: Sameer Rahmani
#+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) WONT_DO(c@/!) FAILED(f@/!)
#+TAGS: DOCS(d) EXAMPLES(e) Misc(m) Lib(l)
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty nolatexpreview
#+OPTIONS: tex:t
#+HTML_MATHJAX: align: left indent: 5em tagside: left font: Neo-Eule
#+LATEX_CLASS: article
#+LATEX_CLASS_OPTIONS: [a4paper]
#+LATEX_HEADER: \usepackage{tcolorbox}
#+LATEX_HEADER: \usepackage{mathabx}
#+LATEX_HEADER: \newtcolorbox{infobox}[2][]{colback=cyan!5!white,before skip=14pt,after skip=8pt,colframe=cyan!75!black,sharp corners,title={#2},#1}
This document is dedicated to the resources, TODOs, research summary, ideas and whatever that is
part of the development process.
* Development Goals
In the past we tried many different ideas and features but since we didn't have a clear goal set,
we couldn't really make it work and differentiate good ideas from bad ones.
** Who are the target audience?
On the first level, I should feel comfortable with it.
** What set of features are important to us?
* Tools
** Straight
We gave it a shot before and it didn't work out but our requirements were different back then.
We should give it a shot again
* Libraries
** Midnight mode
It's a cool library that run some action every midnight, we can use it to clean up old buffers
or other maintenance jobs
* Tasks
** TODO =fpkg/use= doesn't work with =:init=
** TODO Add a =:default= key to the cube indicating whether it should be enabled by default or not
** TODO Reformat the modeline
** TODO Create a macro similar to =with-ability= to run a block of code only if the given cube was active
** TODO Enable =straight= and =use-package= integration on compile time. Checout out =fpkg/core.el=
** TODO Check the =dracula= theme settings and configurations
** TODO Add support for MacOS by create a cube with the following content
#+BEGIN_SRC elisp
(package-install 'exec-path-from-shell)
(exec-path-from-shell-initialize)
#+END_SRC
** TODO Integrate window-purpose mode
** TODO Turn on yasnippet mode for Go mode
* Things that didn't work out
- rbenv
- helm
- linum
- tabbar
- ido
- ivy
- spaceline
- doom-modeline
- smart-mode-line
- desktop-mode
- jedi
- file-browser
- dired+
- guru
- emoji
- elpy
- github
- versioned-backup

0
docs/images/.keep Normal file
View File

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,73 @@
/*
Date: 17.V.2011
Author: pumbur <pumbur@pumbur.net>
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #222;
}
.hljs,
.hljs-subst {
color: #aaa;
}
.hljs-section {
color: #fff;
}
.hljs-comment,
.hljs-quote,
.hljs-meta {
color: #666;
}
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-regexp {
color: #ffcc33;
}
.hljs-number,
.hljs-addition {
color: #00cc66;
}
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-template-variable,
.hljs-attribute,
.hljs-link {
color: #32aaee;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #8866cc;
}
.hljs-title,
.hljs-variable,
.hljs-deletion,
.hljs-template-tag {
color: #bb1166;
}
.hljs-section,
.hljs-doctag,
.hljs-strong {
font-weight: bold;
}
.hljs-emphasis {
font-style: italic;
}

View File

@ -0,0 +1,800 @@
/**
* Forced dark theme version
*/
:root {
--background-body: #202b38;
--background: #161f27;
--background-alt: #1a242f;
--selection: #1c76c5;
--text-main: #dbdbdb;
--text-bright: #fff;
--text-muted: #a9b1ba;
--links: #41adff;
--focus: #0096bfab;
--border: #526980;
--code: #ffbe85;
--animation-duration: 0.1s;
--button-hover: #324759;
--scrollbar-thumb: var(--button-hover);
--scrollbar-thumb-hover: rgb(65, 92, 115);
--form-placeholder: #a9a9a9;
--form-text: #fff;
--variable: #d941e2;
--highlight: #efdb43;
--select-arrow: url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E");
}
html {
scrollbar-color: #324759 #202b38;
scrollbar-color: var(--scrollbar-thumb) var(--background-body);
scrollbar-width: thin;
}
body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 'Segoe UI Emoji', 'Apple Color Emoji', 'Noto Color Emoji', sans-serif;
line-height: 1.4;
max-width: 800px;
margin: 20px auto;
padding: 0 10px;
word-wrap: break-word;
color: #dbdbdb;
color: var(--text-main);
background: #202b38;
background: var(--background-body);
text-rendering: optimizeLegibility;
}
button {
transition:
background-color 0.1s linear,
border-color 0.1s linear,
color 0.1s linear,
box-shadow 0.1s linear,
transform 0.1s ease;
transition:
background-color var(--animation-duration) linear,
border-color var(--animation-duration) linear,
color var(--animation-duration) linear,
box-shadow var(--animation-duration) linear,
transform var(--animation-duration) ease;
}
input {
transition:
background-color 0.1s linear,
border-color 0.1s linear,
color 0.1s linear,
box-shadow 0.1s linear,
transform 0.1s ease;
transition:
background-color var(--animation-duration) linear,
border-color var(--animation-duration) linear,
color var(--animation-duration) linear,
box-shadow var(--animation-duration) linear,
transform var(--animation-duration) ease;
}
textarea {
transition:
background-color 0.1s linear,
border-color 0.1s linear,
color 0.1s linear,
box-shadow 0.1s linear,
transform 0.1s ease;
transition:
background-color var(--animation-duration) linear,
border-color var(--animation-duration) linear,
color var(--animation-duration) linear,
box-shadow var(--animation-duration) linear,
transform var(--animation-duration) ease;
}
h1 {
font-size: 2.2em;
margin-top: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin-bottom: 12px;
margin-top: 24px;
}
h1 {
color: #fff;
color: var(--text-bright);
}
h2 {
color: #fff;
color: var(--text-bright);
}
h3 {
color: #fff;
color: var(--text-bright);
}
h4 {
color: #fff;
color: var(--text-bright);
}
h5 {
color: #fff;
color: var(--text-bright);
}
h6 {
color: #fff;
color: var(--text-bright);
}
strong {
color: #fff;
color: var(--text-bright);
}
h1,
h2,
h3,
h4,
h5,
h6,
b,
strong,
th {
font-weight: 600;
}
q::before {
content: none;
}
q::after {
content: none;
}
blockquote {
border-left: 4px solid #0096bfab;
border-left: 4px solid var(--focus);
margin: 1.5em 0;
padding: 0.5em 1em;
font-style: italic;
}
q {
border-left: 4px solid #0096bfab;
border-left: 4px solid var(--focus);
margin: 1.5em 0;
padding: 0.5em 1em;
font-style: italic;
}
blockquote > footer {
font-style: normal;
border: 0;
}
blockquote cite {
font-style: normal;
}
address {
font-style: normal;
}
a[href^='mailto\:']::before {
content: '📧 ';
}
a[href^='tel\:']::before {
content: '📞 ';
}
a[href^='sms\:']::before {
content: '💬 ';
}
mark {
background-color: #efdb43;
background-color: var(--highlight);
border-radius: 2px;
padding: 0 2px 0 2px;
color: #000;
}
button,
select,
input[type='submit'],
input[type='button'],
input[type='checkbox'],
input[type='range'],
input[type='radio'] {
cursor: pointer;
}
input:not([type='checkbox']):not([type='radio']),
select {
display: block;
}
input {
color: #fff;
color: var(--form-text);
background-color: #161f27;
background-color: var(--background);
font-family: inherit;
font-size: inherit;
margin-right: 6px;
margin-bottom: 6px;
padding: 10px;
border: none;
border-radius: 6px;
outline: none;
}
button {
color: #fff;
color: var(--form-text);
background-color: #161f27;
background-color: var(--background);
font-family: inherit;
font-size: inherit;
margin-right: 6px;
margin-bottom: 6px;
padding: 10px;
border: none;
border-radius: 6px;
outline: none;
}
textarea {
color: #fff;
color: var(--form-text);
background-color: #161f27;
background-color: var(--background);
font-family: inherit;
font-size: inherit;
margin-right: 6px;
margin-bottom: 6px;
padding: 10px;
border: none;
border-radius: 6px;
outline: none;
}
select {
color: #fff;
color: var(--form-text);
background-color: #161f27;
background-color: var(--background);
font-family: inherit;
font-size: inherit;
margin-right: 6px;
margin-bottom: 6px;
padding: 10px;
border: none;
border-radius: 6px;
outline: none;
}
input[type='checkbox'],
input[type='radio'] {
height: 1em;
width: 1em;
}
input[type='radio'] {
border-radius: 100%;
}
input {
vertical-align: top;
}
label {
vertical-align: middle;
margin-bottom: 4px;
display: inline-block;
}
input:not([type='checkbox']):not([type='radio']),
input[type='range'],
select,
button,
textarea {
-webkit-appearance: none;
}
textarea {
display: block;
margin-right: 0;
box-sizing: border-box;
resize: vertical;
}
textarea:not([cols]) {
width: 100%;
}
textarea:not([rows]) {
min-height: 40px;
height: 140px;
}
select {
background: #161f27 url("data:image/svg+xml;charset=utf-8,%3C?xml version='1.0' encoding='utf-8'?%3E %3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' height='62.5' width='116.9' fill='%23efefef'%3E %3Cpath d='M115.3,1.6 C113.7,0 111.1,0 109.5,1.6 L58.5,52.7 L7.4,1.6 C5.8,0 3.2,0 1.6,1.6 C0,3.2 0,5.8 1.6,7.4 L55.5,61.3 C56.3,62.1 57.3,62.5 58.4,62.5 C59.4,62.5 60.5,62.1 61.3,61.3 L115.2,7.4 C116.9,5.8 116.9,3.2 115.3,1.6Z'/%3E %3C/svg%3E") calc(100% - 12px) 50% / 12px no-repeat;
background: var(--background) var(--select-arrow) calc(100% - 12px) 50% / 12px no-repeat;
padding-right: 35px;
}
select::-ms-expand {
display: none;
}
select[multiple] {
padding-right: 10px;
background-image: none;
overflow-y: auto;
}
button,
input[type='submit'],
input[type='button'] {
padding-right: 30px;
padding-left: 30px;
}
button:hover {
background: #324759;
background: var(--button-hover);
}
input[type='submit']:hover {
background: #324759;
background: var(--button-hover);
}
input[type='button']:hover {
background: #324759;
background: var(--button-hover);
}
input:focus {
box-shadow: 0 0 0 2px #0096bfab;
box-shadow: 0 0 0 2px var(--focus);
}
select:focus {
box-shadow: 0 0 0 2px #0096bfab;
box-shadow: 0 0 0 2px var(--focus);
}
button:focus {
box-shadow: 0 0 0 2px #0096bfab;
box-shadow: 0 0 0 2px var(--focus);
}
textarea:focus {
box-shadow: 0 0 0 2px #0096bfab;
box-shadow: 0 0 0 2px var(--focus);
}
input[type='checkbox']:active,
input[type='radio']:active,
input[type='submit']:active,
input[type='button']:active,
input[type='range']:active,
button:active {
transform: translateY(2px);
}
input:disabled,
select:disabled,
button:disabled,
textarea:disabled {
cursor: not-allowed;
opacity: 0.5;
}
::-moz-placeholder {
color: #a9a9a9;
color: var(--form-placeholder);
}
:-ms-input-placeholder {
color: #a9a9a9;
color: var(--form-placeholder);
}
::-ms-input-placeholder {
color: #a9a9a9;
color: var(--form-placeholder);
}
::placeholder {
color: #a9a9a9;
color: var(--form-placeholder);
}
fieldset {
border: 1px #0096bfab solid;
border: 1px var(--focus) solid;
border-radius: 6px;
margin: 0;
margin-bottom: 12px;
padding: 10px;
}
legend {
font-size: 0.9em;
font-weight: 600;
}
input[type='range'] {
margin: 10px 0;
padding: 10px 0;
background: transparent;
}
input[type='range']:focus {
outline: none;
}
input[type='range']::-webkit-slider-runnable-track {
width: 100%;
height: 9.5px;
-webkit-transition: 0.2s;
transition: 0.2s;
background: #161f27;
background: var(--background);
border-radius: 3px;
}
input[type='range']::-webkit-slider-thumb {
box-shadow: 0 1px 1px #000, 0 0 1px #0d0d0d;
height: 20px;
width: 20px;
border-radius: 50%;
background: #526980;
background: var(--border);
-webkit-appearance: none;
margin-top: -7px;
}
input[type='range']:focus::-webkit-slider-runnable-track {
background: #161f27;
background: var(--background);
}
input[type='range']::-moz-range-track {
width: 100%;
height: 9.5px;
-moz-transition: 0.2s;
transition: 0.2s;
background: #161f27;
background: var(--background);
border-radius: 3px;
}
input[type='range']::-moz-range-thumb {
box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d;
height: 20px;
width: 20px;
border-radius: 50%;
background: #526980;
background: var(--border);
}
input[type='range']::-ms-track {
width: 100%;
height: 9.5px;
background: transparent;
border-color: transparent;
border-width: 16px 0;
color: transparent;
}
input[type='range']::-ms-fill-lower {
background: #161f27;
background: var(--background);
border: 0.2px solid #010101;
border-radius: 3px;
box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d;
}
input[type='range']::-ms-fill-upper {
background: #161f27;
background: var(--background);
border: 0.2px solid #010101;
border-radius: 3px;
box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d;
}
input[type='range']::-ms-thumb {
box-shadow: 1px 1px 1px #000, 0 0 1px #0d0d0d;
border: 1px solid #000;
height: 20px;
width: 20px;
border-radius: 50%;
background: #526980;
background: var(--border);
}
input[type='range']:focus::-ms-fill-lower {
background: #161f27;
background: var(--background);
}
input[type='range']:focus::-ms-fill-upper {
background: #161f27;
background: var(--background);
}
a {
text-decoration: none;
color: #41adff;
color: var(--links);
}
a:hover {
text-decoration: underline;
}
code {
background: #161f27;
background: var(--background);
color: #ffbe85;
color: var(--code);
padding: 2.5px 5px;
border-radius: 6px;
font-size: 1em;
}
samp {
background: #161f27;
background: var(--background);
color: #ffbe85;
color: var(--code);
padding: 2.5px 5px;
border-radius: 6px;
font-size: 1em;
}
time {
background: #161f27;
background: var(--background);
color: #ffbe85;
color: var(--code);
padding: 2.5px 5px;
border-radius: 6px;
font-size: 1em;
}
pre > code {
padding: 10px;
display: block;
overflow-x: auto;
}
var {
color: #d941e2;
color: var(--variable);
font-style: normal;
font-family: monospace;
}
kbd {
background: #161f27;
background: var(--background);
border: 1px solid #526980;
border: 1px solid var(--border);
border-radius: 2px;
color: #dbdbdb;
color: var(--text-main);
padding: 2px 4px 2px 4px;
}
img,
video {
max-width: 100%;
height: auto;
}
hr {
border: none;
border-top: 1px solid #526980;
border-top: 1px solid var(--border);
}
table {
border-collapse: collapse;
margin-bottom: 10px;
width: 100%;
table-layout: fixed;
}
table caption {
text-align: left;
}
td,
th {
padding: 6px;
text-align: left;
vertical-align: top;
word-wrap: break-word;
}
thead {
border-bottom: 1px solid #526980;
border-bottom: 1px solid var(--border);
}
tfoot {
border-top: 1px solid #526980;
border-top: 1px solid var(--border);
}
tbody tr:nth-child(even) {
background-color: #1a242f;
background-color: var(--background-alt);
}
::-webkit-scrollbar {
height: 10px;
width: 10px;
}
::-webkit-scrollbar-track {
background: #161f27;
background: var(--background);
border-radius: 6px;
}
::-webkit-scrollbar-thumb {
background: #324759;
background: var(--scrollbar-thumb);
border-radius: 6px;
}
::-webkit-scrollbar-thumb:hover {
background: rgb(65, 92, 115);
background: var(--scrollbar-thumb-hover);
}
::-moz-selection {
background-color: #1c76c5;
background-color: var(--selection);
color: #fff;
color: var(--text-bright);
}
::selection {
background-color: #1c76c5;
background-color: var(--selection);
color: #fff;
color: var(--text-bright);
}
details {
display: flex;
flex-direction: column;
align-items: flex-start;
background-color: #1a242f;
background-color: var(--background-alt);
padding: 10px 10px 0;
margin: 1em 0;
border-radius: 6px;
overflow: hidden;
}
details[open] {
padding: 10px;
}
details > :last-child {
margin-bottom: 0;
}
details[open] summary {
margin-bottom: 10px;
}
summary {
display: list-item;
background-color: #161f27;
background-color: var(--background);
padding: 10px;
margin: -10px -10px 0;
cursor: pointer;
outline: none;
}
summary:hover,
summary:focus {
text-decoration: underline;
}
details > :not(summary) {
margin-top: 0;
}
summary::-webkit-details-marker {
color: #dbdbdb;
color: var(--text-main);
}
footer {
border-top: 1px solid #526980;
border-top: 1px solid var(--border);
padding-top: 10px;
color: #a9b1ba;
color: var(--text-muted);
}
body > footer {
margin-top: 40px;
}
@media print {
body,
pre,
code,
summary,
details,
button,
input,
textarea {
background-color: #fff;
}
button,
input,
textarea {
border: 1px solid #000;
}
body,
h1,
h2,
h3,
h4,
h5,
h6,
pre,
code,
button,
input,
textarea,
footer,
summary,
strong {
color: #000;
}
summary::marker {
color: #000;
}
summary::-webkit-details-marker {
color: #000;
}
tbody tr:nth-child(even) {
background-color: #f2f2f2;
}
a {
color: #00f;
text-decoration: underline;
}
}
/*# sourceMappingURL=dark.css.map */

View File

@ -0,0 +1,40 @@
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
body {
margin: 20px auto;
max-width: 800px;
padding: 0 10px;
background: var(--background-body);
}
pre.src {
background: #1a242f;
padding: 10px 20px;
border-radius: 2px;
}
.timestamp {
background: #161f27;
background: var(--background);
color: #ffbe85;
color: var(--code);
padding: 2.5px 5px;
border-radius: 6px;
font-size: 1em;
}
.footdef {
display: flex;
flex-direction: row;
align-items: start;
}
p.footpara {
margin: 2px 5px;
}

10
docs/site/config.org Normal file
View File

@ -0,0 +1,10 @@
#+AUTHOR: Sameer Rahmani
#+EMAIL: lxsameer@gnu.org
#+LANGUAGE: en
#+OPTIONS: toc:nil <:t
#+options: html5-fancy:t tex:t
#+html_doctype: html5
#+HTML_CONTAINER: div class="column"
#+HTML_CONTENT_CLASS: row
#+creator: <a href="https://www.gnu.org/software/emacs/">Emacs</a> 27.1 (<a href="https://orgmode.org">Org</a> mode )
#+HTML_LINK_HOME: https://fg42.org/

View File

@ -0,0 +1,65 @@
#+SETUPFILE: ../../config.org
#+OPTIONS: toc:nil
#+EXPORT_FILE_NAME: code-of-conduct.html
#+DATE: 2021-07-01
#+TITLE: Contributor Covenant Code of Conduct
#+PAGE: true
#+DESC: An GNU/Emacs based editor for hackers
** Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers
pledge to making participation in our project and our community a harassment-free experience for everyone,
regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience,
nationality, personal appearance, race, religion, or sexual identity and orientation.
** Our Standards
Examples of behavior that contributes to creating a positive environment include:
- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
- The use of sexualized language or imagery and unwelcome sexual attention or advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a professional setting
** Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to
take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits,
code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.
** Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing
the project or its community. Examples of representing a project or community include using an official project
e-mail address, posting via an official social media account, or acting as an appointed representative at an
online or offline event. Representation of a project may be further defined and clarified by project maintainers.
** Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project
team at devs@codamic.tech. The project team will review and investigate all complaints, and will respond in
a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality
with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent
repercussions as determined by other members of the project's leadership.
** Attribution
This Code of Conduct is adapted from the [[http://contributor-covenant.org][Contributor Covenant]], version [[http://contributor-covenant.org/version/1/4/][1.4]], available
at http://contributor-covenant.org/version/1/4

View File

@ -0,0 +1,22 @@
#+SETUPFILE: ../../config.org
#+OPTIONS: toc:nil
#+EXPORT_FILE_NAME: contributors.html
#+DATE: 2021-07-01
#+TITLE: Contributors
#+PAGE: true
#+DESC: An GNU/Emacs based editor for hackers
People how contributed to *FG42* sorted by their number of contribution at the time
of generating the list:
- Sameer Rahmani ([[https://twitter.com/lxsameer][@lxsameer]])
- Amir Reza Askarpour ([[https://twitter.com/amirrezaask][@amirrezaask]])
- Mary Salehi
- Amir Hooshangi ([[https://twitter.com/amirhoshangi][@amirhoshangi]])
- Behnam Ahmad Khan Beigi ([[https://twitter.com/yottanami][@yottanami]])
- Danial Parsi ([[https://twitter.com/intuxticated][@intuxticated]])
- Pouya Abbassi
- Keyvan Hedayati ([[https://twitter.com/k1-hedayati][@k1-hedayati]])
- Nima Nazari ([[https://twitter.com/mandrivan][@mandrivan]])
- Pouria
- Delaram Sobhani ([[https://twitter.com/DelaRam90][@DelaRam90]])
- Ehsan Mahmoudi ([[https://twitter.com/jeyem90][@jeyem90]])

View File

@ -0,0 +1,59 @@
#+SETUPFILE: ../../config.org
#+OPTIONS: toc:nil
#+EXPORT_FILE_NAME: how-to-contribute.html
#+DATE: 2021-07-01
#+TITLE: How to contribute to FG42
#+PAGE: true
#+DESC: An GNU/Emacs based editor for hackers
Wow, thanks for your interest in helping out with FG42. Let this document
serve as your guide.
** Looking for work?
If you're looking for a task to work on, check out [[https://devheroes.codes/FG42/FG42/src/branch/master/dev.org][the dev]] file. We keepe our
big TODOs there. Or reach out to [[https://lxsameer.com][@lxsameer]] to talk about the possiblities.
** New Features
FG42 is the thinking persons editor, so for major contribution, start with some *deeeep*
thoughts. Finished?
Alright, your next step is to start a discussion.
Create an [[https://devheroes.codes/FG42/FG42/issues][issue]] to start a conversation. Tell us what you're trying to accomplish
and how you think you might do it. If all is well, we will collaborate on delivering
the feature.
** Bugs
Of course, if you run into any straight-up bugs or weirdness feel free to skip
the thinking (or at least too much of it) and immediately submit an [[https://devheroes.codes/FG42/FG42/issues][issue]].
We have an issue template in place that will ask you some details
about the platform you are running and how to reproduce the bug. (If
you can reproduce it reliably. If not, go ahead and file the issue
anyway so we can start looking at it.)
Some of the usual stuff we'll want to know:
- What happened?
"I manifested a being from the outer dimensions."
- What did you expect to happen?
"Hello, world."
- How can you reprodice it?
"I created a new FG42 cube with the template, then installed some code that Bob Howard gave me."
- What operating system and version are you using?
e.g. "Gentoo stable"
- What version of Emacs are you using?
e.g. "Emacs 27.1"
- What FG42 version are you using?
e.g. "3.0.0"
Even better, include a link to a gist or repository where we can jump straight
to the problem.

View File

@ -0,0 +1,52 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
<meta name="description" content="FG42, The ultimate editor for true believers">
<meta name="keywords" content="Emacs, GNU, Editor, Hackers, software, lisp">
<meta name="author" content="Sameer Rahmani">
<meta property="og:title" content="{{title}}" />
<meta property="og:description" content="{{description}}" />
{{{head}}}
<link rel="stylesheet" href="{{base-url}}/assets/styles/dark.css?{{version}}">
<link rel="stylesheet" href="{{base-url}}/assets/styles/main.css?{{version}}">
<link rel="stylesheet" href="{{base-url}}/assets/styles/arta.css?{{version}}">
</head>
<body>
<header>
<nav style="text-align: center;">
<a href="/">HOME</a> | <a href="/cubes/">Cubes</a> | <a href="https://devheroes.codes/FG42/FG42">Source</a> | <a href="/categories/">Categories</a> | <a href="/tags/">Tags</a> | <a href="/index.xml">RSS</a>
</nav>
<hr/>
</header>
<article>
{{{preamble}}}
</article>
<main id="content">
{{{content}}}
</main>
<footer>
<span>© 2010-2022 Sameer Rahmani</span><br/>
<span>Version: {{version}}</span><br/>
<span>Built with <a href="https://www.gnu.org/software/emacs/">Emacs Lisp</a> and <a href="https://orgmode.org/">org-mode</a>.</span><br/>
</footer>
</div>
<script src="{{base-url}}/assets/js/highlight.pack.js"></script>
<script>
document.addEventListener('DOMContentLoaded', (event) => {
hljs.configure({languageDetectRe: /\bsrc-([\w-]+)\b/i})
document.querySelectorAll('pre.src').forEach((block) => {
console.dir(block);
hljs.highlightBlock(block);
});
});
</script>
</body>
</html>

View File

@ -0,0 +1,7 @@
#+SETUPFILE: ../../config.org
#+OPTIONS: toc:nil
#+EXPORT_FILE_NAME: index.html
#+PAGE: true
#+TITLE: Categories
<<<:links>>>

View File

@ -0,0 +1,6 @@
#+SETUPFILE: ../../../config.org
#+OPTIONS: toc:nil
#+TITLE: <<<:title>>>
#+PAGE: true
<<<:docs>>>

View File

@ -0,0 +1,13 @@
#+SETUPFILE: ../../config.org
#+OPTIONS: toc:nil
#+EXPORT_FILE_NAME: index.html
#+PAGE: true
#+TITLE: Cubes
*FG42* is built on top of an abstraction unit called *Cube* that logically groups a set of feature related
to a functionality in a single callable and function like entity. For more info on cubes check out their
[[../manual/cube.html
][documentation]]. Here is a list of available cubes:
<<<:links>>>

View File

@ -0,0 +1 @@

View File

@ -0,0 +1 @@
<div class="container">

View File

@ -0,0 +1,21 @@
#+SETUPFILE: ../config.org
#+OPTIONS: toc:nil
#+EXPORT_FILE_NAME: index.html
#+DATE: 2021-07-01
#+TITLE: FG42, The ultimate editor for true believers
#+PAGE: true
#+DESC: An GNU/Emacs based editor for hackers
#+INCLUDE: "../../README.org::*Future Gadgets 42" :only-contents t
* Contribute
FG42 made possible by the effort of the community of [[<<<:base-url>>>/pages/contributors.html][Contributors]].
If you're interested in *FG42* and wants to contribute to the project please follow
the [[<<<:base-url>>>/pages/how-to-contribute.html][How to Contribute Guitd]]. Also please read our [[<<<:base-url>>>/pages/code-of-conduct.html][Code of Conduct]] as well.
* Recent updates:
<<<:links>>>
#+INCLUDE: "../../README.org::*License"

View File

@ -0,0 +1,7 @@
#+SETUPFILE: ../../config.org
#+OPTIONS: toc:nil
#+TITLE: <<<:title>>>
#+PAGE: true
<<<:links>>>

View File

@ -0,0 +1 @@
<h1>{{title}}</h1>

View File

@ -0,0 +1,2 @@
<h1 class="title">{{title}}</h1>
<span class="tags">{{{tags}}}</span> - <time>{{date}}</time>

View File

@ -0,0 +1,3 @@
<div class="tags">
<span>{{tags}}</span>
</div>

View File

@ -0,0 +1,8 @@
#+SETUPFILE: ../../config.org
#+OPTIONS: toc:nil
#+EXPORT_FILE_NAME: index.html
#+PAGE: true
#+TITLE: Tags
<<<:links>>>

View File

@ -1,4 +1,4 @@
#+TITLE: Emacs From Scratch - An Emacs tutorial for beginners
#+TITLE: How to build an editor with Emacs Lisp
#+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) CANCELLED(c@/!) FAILED(f@/!)
#+TAGS: READER(r) MISC(m)
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty overview
@ -598,8 +598,7 @@ CLOSED: [2022-09-11 Sun 11:08]
- https://lxsameer.com
- [[https://twitter.com/lxsameer][@lxsameer]] on Twitter
* DONE Episode 10 - More on Macros
CLOSED: [2022-11-04 Fri 15:25]
* Episode 10 - More on Macros
** Quasiquote aka backquote (`)
- Backquote constructs allow us to quote an expression, but selectively evaluate sub-expressions
- Similar to a template engine for lisp expressions
@ -628,268 +627,4 @@ CLOSED: [2022-11-04 Fri 15:25]
** Real Examples
Let's discuss ~defflag~ and ~when-flag~ macros in [[file:../core/fg42/flags.el]]
* DONE Episode 11 - Common pitfalls of Macros
CLOSED: [2022-12-04 Sun 12:15]
** Compiletime vs runtime
#+BEGIN_SRC emacs-lisp
;; `do-something-with-side-effect' evaluates on compile time
;; in the macro's context
(defmacro wrong (x)
(when x
(do-something-with-side-effect x)))
;; `do-something-with-side-effect' evaluates on run time
;; in the caller's context
(defmacro correct (x)
(when x
`(do-something-with-side-effect ,x)))
#+END_SRC
** Variable Capture
#+BEGIN_SRC emacs-lisp
;; `result' will hide any binding with the same name in the
;; parent scope
(defmacro wrong (f &rest body)
`(let ((result ,f))
(if result
,@body
(message "Failed: %s" result))))
(defvar result 1)
(wrong 200 (message "> %s" result))
;; Instead we need to generate a local binding
(defmacro correct (f &rest body)
(let ((var (gensym)))
`(let ((,var ,f))
(if ,var
,@body
(message "Failed: %s" ,var)))))
(defvar result 1)
(correct 200 (message "%s" result))
#+END_SRC
More on *uninterned* symbols: https://www.gnu.org/software/emacs/manual/html_node/elisp/Creating-Symbols.html
** Many evaluation
#+BEGIN_SRC emacs-lisp
;; The argument `x' will be evaluated 2 times in this example.
;; what if it contains side effects?
(defmacro wrong (x)
`(if ,x
(do-something-with ,x)
(do-somthing-else ,x)))
;; It's better to use a local binding for it and evaluate it
;; just once
(defmacro correct (x)
(let ((var (gensym)))
`(let ((,var ,x))
(if ,var
(do-something-with ,var)
(do-somthing-else ,var)))))
#+END_SRC
** Evaluating arguments of a macro
Never evaluate the arguments of a macro manually. E.g. with =eval=
#+BEGIN_SRC emacs-lisp
;; `eval' here will be evaluated before the caller context
;; is even populated
(defmacro wrong (x)
(list 'setq (eval x) 'blah))
;; The correct way is to mark `x' for evaluation instead
(defmacro correct (x)
`(setq ,x 'blah))
#+END_SRC
More info: https://www.gnu.org/software/emacs/manual/html_node/elisp/Eval-During-Expansion.html
** What's next?
* DONE Episode 12 - Features & Load Paths
CLOSED: [2023-01-14 Sat 11:44]
** Emacs Lisp files
Write elisp code in files with =.el= suffix.
*** Batch mode
Execute an elisp file via Emacs in a non-interactive (script like) fashion:
#+BEGIN_SRC bash
emacs --batch -l /path/to/the/file
#+END_SRC
*** =load= function
Loads an elisp file into the running Emacs process. For more info ~C-h f load~.
#+BEGIN_SRC emacs-lisp
(load "/path/to/the/file")
(load "PATH1")
#+END_SRC
- It first looks for the =PATH + .elc= combination
- If not successful, looks for the =PATH + .el= combination
- If not successful, looks for platform dependent suffixes
- If not successful, tries to load the =PATH= as it is
** Load Path
*** =load-path=
List of directories to search for files to load.
#+BEGIN_SRC emacs-lisp
(add-to-list 'load-path "/path/to/a/directory")
#+END_SRC
*** =EMACSLOADPATH= environment variable
** Emacs =feature=
Emacs tracks loaded packages and file via =features=. Each elisp file can =provide=, zero or
more =features=.
Features are just symbols.
*** =features= list
A list of all loaded features. For more info, try ~C-h v features~.
*** =featurep=
A predicate function to check whether a feature is loaded or not.
#+BEGIN_SRC emacs-lisp
(featurep 'some-feature)
#+END_SRC
*** =provide=
#+BEGIN_SRC emacs-lisp
(provide 'some-feature)
#+END_SRC
*** =require=
If the given feature as the parameter is not loaded yet, loads it via the =load=
function. For more info, ~C-h f require~.
#+BEGIN_SRC emacs-lisp
(require 'some-feature)
;; Or
(require 'some-feature "/path/to/file")
#+END_SRC
** Installing Emacs packages the hard way
We can clone a library somewhere on the disk and add the path to it to the =load-path= list
and load the library files.
But that would be tedious to do so for all the libraries. That's why we use a package manager
* DONE Episode 13 - Editing Modes, Part 1
CLOSED: [2023-06-10 Sat 15:44]
Emacs provides a concept called ~editing mode~ that allows
us to control different aspect of the editor.
** Major Modes
Major modes are mutually exclusive, so each Buffer has exactly on
major mode and just one major mode can be active at any given
time. So, it is possible to switch between different major modes.
Major modes control the main behaviour of your editor for each buffer.
For example, The active major mode might:
- Provide syntax highlighter
- Control the indentation
- Provide a local =keymap=
- ...
To put it simply, major modes are specialized to handle certain files
and buffers.
*** Naming Convenstion
Usually, the name of a major mode is like =<major-mode-name>-mode= which is
an interactive function that we can call either directly or via =M-x= interface.
For example:
- python-mode
- fundamental-mode
- emacs-lisp-mode
- ...
**** Keymap
*We will take about Keymaps in the future*
Major modes usually have a keymap to hold their local keybindings that has the
the =-map= suffix.
**** Hooks
*We will take about Hooks in the future*
Hooks are lists of functions that can be called on certain occasions. For example,
after a major mode activates.
Usually major modes come with at least one hook called =<major-mode-name>-hook= that
runs after the major mode activates. E.g. =emacs-lisp-mode-hook= or =python-mode-hook=.
*** How Emacs choose a major mode for a buffer?
When we open a file, Emacs goes through some hoops to figure out what major mode
should it choose for that buffer.
To put it simply and avoid a lot of details, Emacs will try to match the buffer name
against the keys in ~auto-mode-alist~ and uses the mode provided by that key as a value.
#+BEGIN_SRC emacs-lisp
(("\\`/tmp/fol/" . text-mode)
("\\.texinfo\\'" . texinfo-mode)
("\\.texi\\'" . texinfo-mode)
("\\.el\\'" . emacs-lisp-mode)
("\\.c\\'" . c-mode)
("\\.h\\'" . c-mode)
…)
#+END_SRC
For more info check out:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Auto-Major-Mode.html
*** How to switch the major mode
Just call the other mode or
- ~major-mode-suspend~: Kills all the buffer local variables and record them
- ~major-mode-restore~: This function restores the major mode recorded by ~major-mode-suspend~
For more info:
https://www.gnu.org/software/emacs/manual/html_node/elisp/Major-Modes.html
** Minor Modes
A minor mode provides optional features that users may enable or disable independently of
the choice of major mode. Minor modes can be enabled individually or in combination.
The main difference with major modes is that minor modes are not mutually exclusive and
are not tied to buffers. They can operate globally or local to buffers.
*** How to enable/disable minor modes?
In order to toggle a minor mode we just have to call its function with no argument
*interactively*. In order to disable a minor mode we can pass a negative integer,
and to enable it we can pass a positive integer.
#+BEGIN_SRC emacs-lisp
;; Enable
(blah-mode 1)
;; Disable
(blah-mode -1)
#+END_SRC
** Useful functions and variables
- ~describe-mode~: Display documentation of current major mode and minor modes and a brief
summary of the state of the current buffer.
- ~local-minor-modes~: This buffer-local variable lists the currently enabled minor modes
in the current buffer, and is a list of symbols.
- ~global-minor-modes~: This variable lists the currently enabled global minor modes,
and is a list of symbols.
- ~minor-mode-list~: The value of this variable is a list of all minor mode commands.
* Episode 14 - Editing Modes, Part 2
** Quick overview:
*** A simple minor mode
*** Interactive functions
*** Hooks
*** Keymaps
** Let's do it
** Resources:
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Library-Headers
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Hooks.html
- https://www.gnu.org/software/emacs/manual/html_node/elisp/Keymaps.html
* Episode 11 - Common pitfalls of Macros

55
fg42-config.el Normal file
View File

@ -0,0 +1,55 @@
;;; FG42 --- The mighty editor for the emacsians -*- lexical-binding: t; -*-
;;
;; Copyright (c) 2010-2022 Sameer Rahmani <lxsameer@gnu.org>
;;
;; Author: Sameer Rahmani <lxsameer@gnu.org>
;; URL: https://gitlab.com/FG42/FG42
;; Version: 3.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:
(setq debug-on-error t)
(defvar fg42-v3 "true")
(add-to-list 'load-path (concat (getenv "FG42_HOME") "/core"))
;; Prevent package.el to install anything at startup
(setq package-enable-at-startup nil)
(setq tab-width 2)
(setq custom-file (format "%s/.fg42.custom.el" (getenv "HOME")))
(setq user-emacs-directory "~/.fg42/emacs.d")
(setq user-init-file
(format "%s/.fg42.el"
(getenv "HOME")))
;; Load the custom ization file. In FG42 it is different than
;; the default `user-init-file'
(if (file-exists-p custom-file)
(load custom-file))
(require 'fg42)
(fg42/before-initialize)
(fg42/initialize)
(run-hooks 'fg42/after-cubes-setup-hook)
(run-hooks 'fg42-after-init-hook)
(provide 'fg42-config)
;;; fg42-config.el ends here

4
fg42.app Executable file
View File

@ -0,0 +1,4 @@
#! /bin/sh
#export FG42_HOME=/Users/sameer.rahmani/.fg42
#open -a emacs --args ' --no-splash --title FG42 -l $FG42_HOME/fg42-config.el "$@"'
do shell script "/usr/bin/emacs --name FG42 --no-splash --title FG42 -l /Users/sameer.rahmani/.fg42/fg42-config.el"

View File

@ -1,305 +0,0 @@
{
"nodes": {
"emacs-overlay": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs",
"nixpkgs-stable": "nixpkgs-stable"
},
"locked": {
"lastModified": 1707815184,
"narHash": "sha256-WFoDXgaPdhjgQB3ut+ZN+VT7e60Yw+KUyvUkOSu5Wto=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "0f7f3b39157419f3035a2dad39fbaf8a4ba0448d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "0f7f3b39157419f3035a2dad39fbaf8a4ba0448d",
"type": "github"
}
},
"emacs-overlay_2": {
"inputs": {
"flake-utils": "flake-utils_2",
"nixpkgs": "nixpkgs_3",
"nixpkgs-stable": "nixpkgs-stable_2"
},
"locked": {
"lastModified": 1707815184,
"narHash": "sha256-WFoDXgaPdhjgQB3ut+ZN+VT7e60Yw+KUyvUkOSu5Wto=",
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "0f7f3b39157419f3035a2dad39fbaf8a4ba0448d",
"type": "github"
},
"original": {
"owner": "nix-community",
"repo": "emacs-overlay",
"rev": "0f7f3b39157419f3035a2dad39fbaf8a4ba0448d",
"type": "github"
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib"
},
"locked": {
"lastModified": 1714641030,
"narHash": "sha256-yzcRNDoyVP7+SCNX0wmuDju1NUCt8Dz9+lyUXEI0dbI=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "e5d10a24b66c3ea8f150e47dfdb0416ab7c3390e",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": "nixpkgs-lib_2"
},
"locked": {
"lastModified": 1712014858,
"narHash": "sha256-sB4SWl2lX95bExY2gMFG5HIzvva5AVMJd4Igm+GpZNw=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "9126214d0a59633752a136528f5f3b9aa8565b7d",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"flake-utils_2": {
"inputs": {
"systems": "systems_2"
},
"locked": {
"lastModified": 1705309234,
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1707689078,
"narHash": "sha256-UUGmRa84ZJHpGZ1WZEBEUOzaPOWG8LZ0yPg1pdDF/yM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f9d39fb9aff0efee4a3d5f4a6d7c17701d38a1d8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-lib": {
"locked": {
"lastModified": 1714640452,
"narHash": "sha256-QBx10+k6JWz6u7VsohfSw8g8hjdBZEf8CFzXH1/1Z94=",
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://github.com/NixOS/nixpkgs/archive/50eb7ecf4cd0a5756d7275c8ba36790e5bd53e33.tar.gz"
}
},
"nixpkgs-lib_2": {
"locked": {
"dir": "lib",
"lastModified": 1711703276,
"narHash": "sha256-iMUFArF0WCatKK6RzfUJknjem0H9m4KgorO/p3Dopkk=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "d8fe5e6c92d0d190646fb9f1056741a229980089",
"type": "github"
},
"original": {
"dir": "lib",
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1707650010,
"narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"nixpkgs-stable_2": {
"locked": {
"lastModified": 1707650010,
"narHash": "sha256-dOhphIA4MGrH4ElNCy/OlwmN24MsnEqFjRR6+RY7jZw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "809cca784b9f72a5ad4b991e0e7bcf8890f9c3a6",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-23.11",
"repo": "nixpkgs",
"type": "github"
}
},
"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=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f9d39fb9aff0efee4a3d5f4a6d7c17701d38a1d8",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"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"
},
"locked": {
"lastModified": 1714648678,
"narHash": "sha256-CxLSUYRk2quey0skgxa+v8mVE+pGSSPcxtK0uFq6YkQ=",
"ref": "refs/tags/v0.1.11",
"rev": "b4e667a73a0de7d83f78910d6fa3acc3b3044675",
"revCount": 53,
"type": "git",
"url": "https://devheroes.codes/lxsameer/noether"
},
"original": {
"ref": "refs/tags/v0.1.11",
"type": "git",
"url": "https://devheroes.codes/lxsameer/noether"
}
},
"root": {
"inputs": {
"emacs-overlay": "emacs-overlay",
"flake-parts": "flake-parts",
"nixpkgs": "nixpkgs_2",
"noether": "noether"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

100
flake.nix
View File

@ -1,100 +0,0 @@
# Fg42 - Emacs Editor for advance users
#
# Copyright (c) 2010-2024 Sameer Rahmani <lxsameer@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
{
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.11";
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; } {
systems = [
"aarch64-darwin"
"riscv64-linux"
"x86_64-linux"
];
flake = {
# The home-manager integration. The can use FG42 with home-manager by including
# this module.
hm-module = rec {
fg42 = import ./nix/hm;
default = fg42;
};
};
perSystem = { config, self', inputs', pkgs, system, ... }:
let
test-x = pkgs.writeShellApplication {
name = "test-x";
runtimeInputs = [ pkgs.xorg.xorgserver ];
text = ''
${pkgs.xorg.xorgserver.out}/bin/Xephyr -br -ac -noreset -screen 800x600 :1
'';
};
app = pkgs.callPackage ./nix/fg42 {
inherit nixpkgs;
extraPackages = {
noether = inputs.noether.outputs.packages.${system}.default;
};
};
fg42 = app.drv;
run-test-wm = pkgs.writeShellApplication {
name = "run-test-wm";
runtimeInputs = [ fg42 ];
text = ''
DISPLAY=:1 ${fg42}/bin/fg42-wm
'';
};
in
{
packages = app.emacsPkgs // {
default = fg42;
wm = fg42;
};
devShells.default = pkgs.mkShell {
nativeBuildInputs = [ fg42 pkgs.fish test-x run-test-wm ];
buildInputs = [ fg42 ];
};
apps.wm = {
type = "app";
program = "${run-test-wm}/bin/run-test-wm";
};
apps.x = {
type = "app";
program = "${test-x}/bin/test-x";
};
apps.default = {
type = "app";
program = "${fg42}/bin/fg42";
};
};
};
}

30
lib/extensions/arduino.el Normal file
View File

@ -0,0 +1,30 @@
;; Important Note: On linux you need to add your user to 'dialout' group
;; OS reqyurements: You need to install these utilities:
;; * arduino-mk
;; * python-serial
;; * avrdude
;; * libdevice-serialport-perl
;; * libyaml-perl
;;
;; You need following environments veriables:
;; export ARDUINO_DIR=$HOME/bin/arduino-1.6.8
;; export ARDMK_DIR=/usr/share/arduino
;; export ARDMK_PATH=/usr/bin
;;; Code:
(require 'fpkg)
(require 'fg42/extension)
(require 'extensions/arduino/init)
;; Dependencies ----------------------------------
(depends-on 'arduino-mode)
(depends-on 'company-arduino)
(depends-on 'mustache)
;; Extension -------------------------------------
(extension arduino
:version "2.31"
:on-initialize extensions/arduino-initialize)
(provide 'extensions/arduino)
;;; arduino.el ends here

View File

@ -0,0 +1,10 @@
# If you didn't define these environment variables, uncomment these and fix the paths
#ARDUINO_DIR=$HOME/bin/arduino-1.6.8
#ARDMK_DIR=/usr/share/arduino
#ARDMK_PATH=/usr/bin
BOARD_TAG=uno
ARDUINO_PORT=/dev/ttyACM0
ARDUINO_LIBS=
include $(ARDMK_DIR)/Arduino.mk

View File

@ -0,0 +1,67 @@
;;; Code:
;; Functions -------------------------------------------------
;;;###autoload
(defun create-makefile ()
"Create the arduino make file in the same directory as the ino file if doesn't exits."
(let ((makefile (concat (file-name-directory buffer-file-name) "Makefile"))
(makefile-src (concat fg42-home "/lib/extensions/arduino/Makefile")))
(if (not (file-exists-p makefile))
(progn (message "Creating arduino make file")
(copy-file makefile-src makefile)))))
;;;###autoload
(defun arduino/compilation-finished (buffer result)
(cond ((string-match "finished" result)
(bury-buffer "*compilation*")
(message "Compilation done."))
(t
(message "Compilation field."))))
;;;###autoload
(defun arduino/compilation-and-upload-finished (buffer result)
(cond ((string-match "finished" result)
(bury-buffer "*compilation*")
(message "Compilation done.")
(message "Uploading")
(arduino/upload))
(t
(message "Compilation field."))))
;;;###autoload
(defun arduino/compile ()
"Compile the current arduino project."
(interactive)
(let ((compilation-finish-functions 'arduino/compilation-finished))
(recompile)))
(defun arduino/upload ()
(interactive)
(let ((compile-command "make upload"))
(recompile)))
;;;###autoload
(defun arduino/compile-and-upload ()
"Compile and upload the current arduino project."
(interactive)
(let ((compilation-finish-functions 'arduino/compilation-and-upload-finished))
(recompile)))
;;;###autoload
(defun extensions/arduino-initialize ()
"Arduino development plugin initialization."
(ability arduino-editor ('flycheck)
"Gives FG42 the ability to edit arduino related contents."
(add-hook 'arduino-mode-hook 'create-makefile)
(setq auto-mode-alist (cons '("\\.\\(pde\\|ino\\)$" . arduino-mode) auto-mode-alist))
(global-set-key (kbd "C-c c") 'arduino/compile)
(global-set-key (kbd "C-c u") 'arduino/upload)
(autoload 'arduino-mode "arduino-mode" "Arduino editing mode." t))
(message "'arduino' extension has been initialized."))
(provide 'extensions/arduino/init)

22
lib/extensions/auth.el Normal file
View File

@ -0,0 +1,22 @@
;;; Auth --- Secret management extension for FG42
;;; Commentary:
;;; Code:
(require 'fpkg)
(require 'fg42/extension)
(require 'extensions/auth/init)
;; Dependencies ----------------------------------
(depends-on 'rcauth-notify)
(defun auth-doc ()
"TBD"
"TBD")
;; Extension -------------------------------------
(extension auth
:version "2.32"
:on-initialize extensions/auth-initialize
:docs "lib/extensions/auth/readme.org")
(provide 'extensions/auth)
;;; auth.el ends here

Some files were not shown because too many files have changed in this diff Show More