diff --git a/core/cubes/elisp.el b/core/cubes/elisp.el index 8f26a75..8584e2d 100644 --- a/core/cubes/elisp.el +++ b/core/cubes/elisp.el @@ -28,16 +28,14 @@ (require 'fg42/cube) - - (defcube fg42/elisp-cube () - :keys nil :requires '() + ;;:modes '((emacs-lisp-mode . f42/elisp-cube-after-load)) ;;:hooks (list (lambda (system) '(emacs-lisp-mode-hook . fssd))) ;;:auto-modes (list (lambda (system) '("\\.el\\'" . fg42/elisp-cube-mmm))) + ;; :init #'iii :dependencies '((:name rainbow-delimiters :version :latest))) - (provide 'cubes/elisp) ;;; elisp.el ends here diff --git a/core/cubes/org.el b/core/cubes/org.el index a1776f7..377b0ac 100644 --- a/core/cubes/org.el +++ b/core/cubes/org.el @@ -29,7 +29,9 @@ (defcube fg42/org-cube () - :keys nil + :keys '((org-mode-map + :good (("s-s" . (lambda () (message "s-s")))) + :evil)) :dependencies '((:name org :version :latest))) diff --git a/core/fg42/cube.el b/core/fg42/cube.el index fea3d74..d8157fb 100644 --- a/core/fg42/cube.el +++ b/core/fg42/cube.el @@ -29,6 +29,7 @@ (require 'seq) (require 'fg42/utils) (require 'fg42/system/dependencies) +(require 'fg42/system/modes) (require 'fg42/system/keys) @@ -44,6 +45,13 @@ ,@body))))) +(defmacro active-cube? (name &rest body) + "Run the BODY if the given cube NAME is activated." + (declare (indent defun)) + (when (fg42/system-get-cube fg42/system name) + `(progn ,@body))) + + (defun fg42/cube-run (cube system) "Run the given CUBE with the given SYSTEM. @@ -74,6 +82,8 @@ Returns a pair of new system and the cube vlaue." (fg42/system-register-cube name cube) ;; Add the dependencies of the cube to the state (fg42/system-merge-dependencies name (plist-get cube :dependencies)) + ;; Merge the modes configuration of the cubes + (fg42/system-merge-modes name (plist-get cube :modes)) ;; Add the keybindings of the cube to the state (fg42/system-merge-keys name (plist-get cube :keys)))) system)) diff --git a/core/fg42/system.el b/core/fg42/system.el index a1ce2b3..abd833e 100644 --- a/core/fg42/system.el +++ b/core/fg42/system.el @@ -24,6 +24,9 @@ ;; Each system has to have a `start' function to start the setup process. ;; ;;; Code: +(defvar fg42/system '() + "The default system of FG42.") + ;;;###autoload (defun fg42/system-start (system) @@ -33,13 +36,15 @@ (require 'fg42/system/dependencies) (require 'fg42/system/cubes) - (let* ((system-map (funcall system '())) - (system (-> system-map - (fg42/system-install-dependencies) - (fg42/system-setup-cubes)))) - (message "SYSTEM: %s" - (fg42/system-get system :cubes)))) + (let* ((system-map (funcall system '()))) + ;; Weird right ? Well, I've tried the functional state passing style + ;; but as it turns out the performance isn't great in elisp + (setq fg42/system (fg42/system-install-dependencies system-map)) + (setq fg42/system (fg42/system-setup-cubes fg42/system)) + (setq fg42/system (fg42/system-setup-modes-hook fg42/system)) + (message "SYSTEM: %s" + (fg42/system-get fg42/system :cubes)))) (provide 'fg42/system) diff --git a/core/fg42/system/cubes.el b/core/fg42/system/cubes.el index f9435ab..c505dbc 100644 --- a/core/fg42/system/cubes.el +++ b/core/fg42/system/cubes.el @@ -67,8 +67,8 @@ ;; Run the init function the cube. ;; The init function is just for setup, the return value of it ;; and the changes that it might make to the system will be discarded. - (funcall (or (plist-get cube :init) (lambda (x) ())) - system) + (funcall (or (plist-get cube :init) (lambda () ()))) + ;; Setup the automods (fg42/system-cube-auto-modes system cube) @@ -91,16 +91,15 @@ (defun fg42/system-cube-auto-modes (system cube) "Setup the auto modes of the given CUBE using the given SYSTEM." - (dolist (automod (mapcar (lambda (pred) (funcall pred system)) (plist-get cube :auto-modes))) + (dolist (automod (plist-get cube :auto-modes)) (when automod (add-to-list 'auto-mode-alist automod)))) (defun fg42/system-cube-hooks (system cube) "Setup the auto modes of the given CUBE using the given SYSTEM." - (dolist (hook (mapcar (lambda (pred) (funcall pred system)) (plist-get cube :hooks))) + (dolist (hook (plist-get cube :hooks)) (when hook - (message "Settting up hook: %s === %s" (car hook) (cdr hook)) (add-hook (car hook) (cdr hook))))) diff --git a/core/fg42/system/keys.el b/core/fg42/system/keys.el index 5bfd657..405636a 100644 --- a/core/fg42/system/keys.el +++ b/core/fg42/system/keys.el @@ -24,15 +24,100 @@ ;; Each system has to have a `start' function to start the setup process. ;; ;;; Code: +(require 'seq) (require 'fg42/system/core) (defun fg42/system-merge-keys (system cube-name keys) - "Retun an updated SYSTEM with the given keys KEYS for CUBE-NAME." - (if keys - ;; TODO: Validate the deps here - (fg42/system-cons-to system :keys (cons cube-name keys)) - system)) + "Retun an updated SYSTEM with the given keys KEYS for CUBE-NAME. +It converts the `:keys' of the cube to the following format and adds +them to the system. (cube-nam mode (key f)s...)." + (let ((keyset :good)) + (if keys + ;; TODO: Validate the deps here + (fg42/system-cons-to system + :keys + (car + (seq-reduce + (lambda (bindings keys) + (let ((mode (car keys)) + (pair-list (plist-get (cdr keys) keyset))) + (cons + (list cube-name mode pair-list) + bindings))) + keys + '()))) + + system))) + +;; (defun fg42/system-merge-keys (system cube-name keys) +;; "Retun an updated SYSTEM with the given keys KEYS for CUBE-NAME. +;; It converts the `:keys' of the cube to the following format and adds +;; them to the system. (cube-nam mode (key f)s...)." +;; (let ((keyset :good)) +;; (if keys +;; ;; TODO: Validate the deps here +;; (fg42/system-cons-to system +;; :keys +;; (car +;; (seq-reduce +;; (lambda (bindings keys) +;; (let ((mode (car keys)) +;; (pair-list (plist-get (cdr keys) keyset))) +;; (cons +;; (list cube-name mode pair-list) +;; bindings))) +;; keys +;; (assoc)))) + +;; system))) + + +;; (defun fg42/system-setup-keys (system) +;; "Setup the key binding through out the SYSTEM." +;; (message "#$$$$$########### %s" (fg42/system-get system :keys)) +;; (let ((keyset :good)) +;; (mapcar +;; (lambda (key-desc) +;; (let ((cube-name (car key-desc)) +;; (map (cadr key-desc)) +;; (binding (caddr key-desc)) +;; (f (cadddr key-desc))) +;; (message "Set keybinding %s" key-desc) +;; (if (eq keyset :good) +;; (define-in-keymap map binding f) +;; (define-evil-in-keymap map binding f)))) +;; (fg42/system-get system :keys))) +;; system) + +(defun fg42/system-setup-keys (system) + "Setup the key binding through out the SYSTEM." + (let ((keyset :good)) + (mapcar + (lambda (key-desc) + (let ((cube-name (car key-desc)) + (map (cadr key-desc)) + (binding (caddr key-desc)) + (f (cadddr key-desc))) + (message "Set keybinding %s" key-desc) + (if (eq keyset :good) + (define-in-keymap map binding f) + (define-evil-in-keymap map binding f)))) + (fg42/system-get system :keys))) + system) + + +(defmacro define-in-keymap (map binding f) + "Set the given key BINDING in the given MAP to F." + (if (eq map :global) + `(global-set-key (kbd ,binding) ,f) + `(define-key ,map (kbd ,binding) ,f))) + + +(defmacro define-evil-in-keymap (map binding f) + "Set the given key BINDING in the given MAP to F (evil mode only)." + (message "TBD") + nil) (provide 'fg42/system/keys) diff --git a/core/fg42/system/modes.el b/core/fg42/system/modes.el new file mode 100644 index 0000000..9921700 --- /dev/null +++ b/core/fg42/system/modes.el @@ -0,0 +1,59 @@ +;;; dependencies --- System library of FG42 -*- lexical-binding: t; -*- +;; +;; Copyright (c) 2010-2021 Sameer Rahmani & Contributors +;; +;; Author: Sameer Rahmani +;; 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 . +;; +;;; Commentary: +;; `System' is just a state monad which holds the state of the editor. +;; Each system has to have a `start' function to start the setup process. +;; +;;; Code: + +(require 'fg42/system/core) + +(defun fg42/system-merge-modes (system cube-name modes) + "Retun an updated SYSTEM with the given mode config MODES for CUBE-NAME." + (if modes + ;; TODO: Validate the modes here + (fg42/system-cons-to system :modes (cons cube-name modes)) + system)) + + +(defun fg42/system-setup-mode-hook (system mode-pair) + "Setup the given MODE-PAIR which is a (mode . f) in SYSTEM." + (add-hook (intern (format "%s-hook" (car mode-pair))) + (lambda () + ;; TODO: Setup key bindings here + (funcall (cdr mode-pair))))) + + + +(defun fg42/system-setup-modes-hook (system) + "Setup the mode hook of every mode in the SYSTEM." + (mapcar + (lambda (cube-modes) + (let ((cube-name (car cube-modes)) + (modes (cdr cube-modes))) + (mapcar (lambda (x) (fg42/system-setup-mode-hook system x)) modes))) + (fg42/system-get system :modes)) + system) + + +(provide 'fg42/system/modes) +;;; modes.el ends here