;;; 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 'seq) (require 'fg42/system/core) (defun fg42/system-is-good? (system) "Return non-nil if the keyset on the given SYSTEM is set to :good." (eq (or (fg42/system-get system :i-am) :good) :good)) (defun fg42/system-is-evil? (system) "Return non-nil if the keyset on the given SYSTEM is set to :good." (eq (or (fg42/system-get system :i-am) :good) :evil)) (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 '()))) 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) (defun fg42/defkey--good (map key fn) "Set the given KEY on key map MAP to FN." (message "SSSSSSSSSSSS %s %s" (type-of map) map) (funcall #'define-key map (kbd key) fn)) (defun fg42/defkey--evil (map state-keys fn) "Set the given STATE-KEYS on key map MAP to FN." (let ((normal-key (plist-get state-keys :normal)) (visual-key (plist-get state-keys :visual)) (insert-key (plist-get state-keys :insert)) (emacs-key (plist-get state-keys :emacs))) (cond ((not (null normal-key)) (evil-define-key 'normal map (kbd normal-key) fn)) ((not (null visual-key)) (evil-define-key 'visual map (kbd visual-key) fn)) ((not (null insert-key)) (evil-define-key 'insert map (kbd insert-key) fn)) ((not (null emacs-key)) (evil-define-key 'emacs map (kbd emacs-key) fn))))) (defmacro defkey (map fn &rest keys) "Defines a key binding for FG42 for different types. Defines a keybinding in the given MAP for the given KEYS that maps to the given FN with the given DOCSTRING. Example usage : \\(defkey `'global-map`' 'goto-line :evil \\(:normal \"SPC s u\"\\) :good \"\"\\)" (declare (indent defun)) (let ((good-key (plist-get keys :good)) (evil-state-key (plist-get keys :evil))) (when (and (fg42/system-is-evil? fg42/system) (null evil-state-key)) (error "You should pass :evil keys when you are evil user")) (when (and (fg42/system-is-good? fg42/system) (null good-key)) (error "You should pass :good keys when you are a good user")) (cond ((fg42/system-is-good? fg42/system) `(fg42/defkey--good ,map ,good-key ,fn)) ((fg42/system-is-evil? fg42/system) `(fg42/defkey-evil ,map (quote ,evil-state-key) ,fn))))) (provide 'fg42/system/keys) ;;; keys.el ends here