branch: externals/ergoemacs-mode commit ef2c71a1ae523011138fa14c5150d7a7f7c09ee1 Author: Matthew Fidler <514778+mattfid...@users.noreply.github.com> Commit: Matthew Fidler <514778+mattfid...@users.noreply.github.com>
Add back the advices to have the ctrl/alt keys --- ergoemacs-advice.el | 178 +++++++++++++++++++++++++++++++++++++++++++ ergoemacs-key-description.el | 62 +++++++-------- ergoemacs-macros.el | 52 +++++++++++++ ergoemacs-mode.el | 57 ++++++++++++-- 4 files changed, 308 insertions(+), 41 deletions(-) diff --git a/ergoemacs-advice.el b/ergoemacs-advice.el new file mode 100644 index 0000000..7af3d24 --- /dev/null +++ b/ergoemacs-advice.el @@ -0,0 +1,178 @@ +;;; ergoemacs-advice.el --- Ergoemacs advices -*- lexical-binding: t -*- + +;; Copyright © 2013-2021 Free Software Foundation, Inc. + +;; Filename: ergoemacs-advice.el +;; Description: +;; Author: Matthew L. Fidler +;; Maintainer: Matthew L. Fidler +;; Created: Sat Sep 28 20:10:56 2013 (-0500) +;; +;;; Commentary: +;; Advices for `ergoemacs-mode'. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; 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, 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/>. +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;;; Code: +(require 'cl-lib) + +(eval-when-compile + (require 'ergoemacs-macros)) + +(require 'mouse) + +(defvar ergoemacs-mode) +(defvar ergoemacs-keymap) +(defvar ergoemacs-map--unbound-keys) +(defvar ergoemacs-saved-global-map) +(defvar ergoemacs-user-keymap) + +(declare-function ergoemacs-map-- "ergoemacs-map") + +(declare-function ergoemacs-map-properties--hook-define-key "ergoemacs-map-properties") +(declare-function ergoemacs-map-properties--ignore-global-changes-p "ergoemacs-map-properties") +(declare-function ergoemacs-map-properties--installed-p "ergoemacs-map-properties") +(declare-function ergoemacs-map-properties--label "ergoemacs-map-properties") +(declare-function ergoemacs-map-properties--map-fixed-plist "ergoemacs-map-properties") +(declare-function ergoemacs-map-properties--original "ergoemacs-map-properties") +(declare-function ergoemacs-map-properties--original-user "ergoemacs-map-properties") +(declare-function ergoemacs-map-properties--global-submap-p "ergoemacs-map-properties") + +(declare-function ergoemacs-key-description--substitute-command-keys "ergoemacs-key-description") + +(declare-function ergoemacs-translate--define-key "ergoemacs-translate") +(declare-function ergoemacs-translate--apply-key "ergoemacs-translate") +(declare-function ergoemacs-major-mode-menu-map "ergoemacs-lib") +(declare-function ergoemacs-translate--get "ergoemacs-translate") +(declare-function ergoemacs-translate--keymap "ergoemacs-translate") +(declare-function ergoemacs-command-loop--modal-p "ergoemacs-command-loop") +(declare-function ergoemacs-translation-struct-keymap-modal "ergoemacs-translate") +(declare-function ergoemacs-command-loop--internal "ergoemacs-command-loop") +(declare-function ergoemacs-command-loop--temp-message "ergoemacs-command-loop") +(declare-function ergoemacs-key-description "ergoemacs-key-description") + +(defvar ergoemacs-advice--temp-replace-functions nil + "List of `ergoemacs-mode' temporary replacement functions. + +These replacement functions are are turned on when +`ergoemacs-mode' is turned on.") + +(defvar ergoemacs-advice--permanent-replace-functions nil + "List of `ergoemacs-mode' permanent replacement functions. + +These replacement functinos are turned on after `ergoemacs-mode' +is loaded, but not turned off.") + +(defun ergoemacs-advice--enable-replacement (ad &optional disable) + "Enable ergoemacs-c advice AD (or optionally DISABLE)." + (cond + (disable + (when (fboundp (intern (concat "ergoemacs-advice--real-" (symbol-name ad)))) + (defalias ad (intern (concat "ergoemacs-advice--real-" (symbol-name ad))) + (documentation (intern (concat "ergoemacs-advice--real-" (symbol-name ad))))))) + (t + (when (fboundp (intern (concat "ergoemacs-advice--" (symbol-name ad)))) + (defalias ad (intern (concat "ergoemacs-advice--" (symbol-name ad))) + (documentation (intern (concat "ergoemacs-advice--" (symbol-name ad))))))))) + +(defun ergoemacs-advice--enable-replacements (&optional disable permanent) + "Enable the function replacements. + +When DISABLE is non-nil, disable the replacements. + +When PERMANENT is non-nil, these replacements are permanent, not temporary." + (dolist (ad (or (and permanent ergoemacs-advice--permanent-replace-functions) + ergoemacs-advice--temp-replace-functions)) + (ergoemacs-advice--enable-replacement ad disable))) + +(add-hook 'ergoemacs-mode-startup-hook 'ergoemacs-advice--enable-replacements) + +(defun ergoemacs-advice--disable-replacements () + "Disable the function replacements." + (ergoemacs-advice--enable-replacements t)) + +(add-hook 'ergoemacs-mode-shutdown-hook 'ergoemacs-advice--disable-replacements) + +(defun ergoemacs-advice--enable-permanent-replacements () + "Enable permanent replacements." + (ergoemacs-advice--enable-replacements nil t)) + +(add-hook 'ergoemacs-mode-intialize-hook 'ergoemacs-advice--enable-permanent-replacements) + +(defvar ergoemacs--original-local-map nil + "Original keymap used with `use-local-map'.") + +;; FIXME for emacs 25 +(ergoemacs-advice substitute-command-keys (string) + "Use `ergoemacs-substitute-command-keys' when `ergoemacs-mode' is enabled" + :type :replace + (if ergoemacs-mode + (ergoemacs-key-description--substitute-command-keys string) + (ergoemacs-advice--real-substitute-command-keys string))) + + +(defun ergoemacs-mode--undefined-advice (&optional type) + "Advice for undefined. + +TYPE is the type of translation installed." + (let* ((keys (this-single-command-keys)) + (type (or type :normal)) + (translation (ergoemacs-translate--get type)) + (local-keymap (ergoemacs-translate--keymap translation)) + (local-key (substring keys -1)) + modal-p) + (when (setq modal-p (ergoemacs :modal-p)) + (setq local-keymap (ergoemacs-translation-struct-keymap-modal modal-p))) + (if (lookup-key local-keymap local-key) + (let ((i 1)) ;; Setup history + (setq ergoemacs-command-loop--history nil) + (while (<= i (- (length keys) 1)) + (push (list (substring keys 0 i) :normal nil + current-prefix-arg (aref (substring keys (- i 1) i) 0)) + ergoemacs-command-loop--history) + (setq i (+ 1 i))) + (ergoemacs-command-loop--internal keys nil nil nil ergoemacs-command-loop--history)) + (ding) + (ergoemacs-command-loop--temp-message "%s does not do anything!" + (ergoemacs-key-description (this-single-command-keys))) + (setq defining-kbd-macro nil) + (force-mode-line-update) + ;; If this is a down-mouse event, don't reset prefix-arg; + ;; pass it to the command run by the up event. + (setq prefix-arg + (when (memq 'down (event-modifiers last-command-event)) + current-prefix-arg))))) + +(ergoemacs-advice undefined () + "Allow `ergoemacs-mode' to display keys, and intercept ending <apps> keys." + :type :around + (if (not ergoemacs-mode) + ad-do-it + (ergoemacs-mode--undefined-advice))) + +(ergoemacs-advice handle-shift-selection () + "Allow `ergoemacs-mode' to do shift selection on keys like Alt+# to Alt+3." + :type :before + (when (eq 'ergoemacs-command-loop--shift-translate (key-binding (this-single-command-keys))) + (setq this-command-keys-shift-translated t))) + +(provide 'ergoemacs-advice) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; ergoemacs-advice.el ends here +;; Local Variables: +;; coding: utf-8-emacs +;; End: diff --git a/ergoemacs-key-description.el b/ergoemacs-key-description.el index 41ebad3..982f70b 100644 --- a/ergoemacs-key-description.el +++ b/ergoemacs-key-description.el @@ -52,8 +52,8 @@ (defvar ergoemacs-display-unicode-characters) (defvar ergoemacs-display-capitalize-keys) (defvar ergoemacs-display-key-use-face) -(defvar ergoemacs-display-small-symbols-for-key-modifiers) -(defvar ergoemacs-display-use-unicode-brackets-around-keys) +(defvar ergoemacs-display-small-symbols-for-key-modifiers nil) +(defvar ergoemacs-display-use-unicode-brackets-around-keys nil) (defvar ergoemacs-display-without-brackets nil "Display the key without brackets.") @@ -157,33 +157,31 @@ MOD ar the modifiers applied to the key." ((eq key 32) (setq ret "Space")) ((eq key 127) - (setq ret (format "%sBackspace" (ergoemacs :unicode-or-alt "←" "")))) + (setq ret "←Backspace")) ((eq key 'escape) (setq ret "Esc")) ((eq key 'tab) - (setq ret (format "Tab%s" - (ergoemacs :unicode-or-alt "↹" "")))) + (setq ret "Tab↹")) ((eq key 'return) - (setq ret (format "Enter%s" - (ergoemacs :unicode-or-alt "↵" "")))) + (setq ret "Enter↵")) ((memq key '(apps menu)) - (setq ret (ergoemacs :unicode-or-alt "▤" "Menu"))) + (setq ret "▤")) ((eq key 'left) - (setq ret (ergoemacs :unicode-or-alt "←" "left"))) + (setq ret "←")) ((eq key 'right) - (setq ret (ergoemacs :unicode-or-alt "→" "right"))) + (setq ret "→")) ((eq key 'up) - (setq ret (ergoemacs :unicode-or-alt "↑" "up"))) + (setq ret "↑")) ((eq key 'down) - (setq ret (ergoemacs :unicode-or-alt "↓" "down"))) + (setq ret "↓")) ((eq key 'prior) (setq ret "PgUp")) ((eq key 'next) (setq ret "PgDn")) ((eq key 'remap) - (setq ret (ergoemacs :unicode-or-alt "➩" "remap"))) + (setq ret "➩")) ((eq key 'ergoemacs-timeout) - (setq ret (ergoemacs :unicode-or-alt "⌚" "ergoemacs-timeout"))) + (setq ret "⌚")) ((integerp key) (setq ret (or (and (or (and (eq ergoemacs-display-capitalize-keys 'with-modifiers) mod) @@ -216,55 +214,47 @@ MOD ar the modifiers applied to the key." (eq mac-command-modifier 'meta)) (and (boundp 'ns-command-modifier) (eq ns-command-modifier 'meta)))) - (setq ret (format "%s" - (ergoemacs :unicode-or-alt "⌘" "+")))) + (setq ret "⌘")) ((and (eq mod 'meta) (eq system-type 'darwin) (or (and (boundp 'mac-command-modifier) (eq mac-command-modifier 'meta)) (and (boundp 'ns-command-modifier) (eq ns-command-modifier 'meta)))) - (setq ret (format "%sCmd+" - (ergoemacs :unicode-or-alt "⌘" "+")))) + (setq ret "⌘Cmd+")) ((and (eq mod 'meta) (eq system-type 'darwin) (or (and (boundp 'mac-alternate-modifier) (eq mac-alternate-modifier 'meta)) (and (boundp 'ns-alternate-modifier) (eq ns-alternate-modifier 'meta)))) - (setq ret (format "%sOpt+" (ergoemacs :unicode-or-alt "⌥" "+")))) + (setq ret "⌥Opt+")) ((and (eq mod 'meta) ergoemacs-display-small-symbols-for-key-modifiers (eq system-type 'darwin) (or (and (boundp 'mac-alternate-modifier) (eq mac-alternate-modifier 'meta)) (and (boundp 'ns-alternate-modifier) (eq ns-alternate-modifier 'meta)))) - (setq ret (format "%s" (ergoemacs :unicode-or-alt "⌥" "+")))) + (setq ret "⌥")) ((and ergoemacs-display-small-symbols-for-key-modifiers (eq mod 'shift)) - (setq ret (ergoemacs :unicode-or-alt "⇧" "+"))) + (setq ret "⇧")) ((and ergoemacs-display-small-symbols-for-key-modifiers (eq mod 'meta)) - (setq ret (ergoemacs :unicode-or-alt "♦" "!"))) + (setq ret "♦")) ((and (or (eq system-type 'darwin) ergoemacs-display-small-symbols-for-key-modifiers) (memq mod '(control ergoemacs-control))) (setq ret "^")) ((eq mod 'shift) - (setq ret (format "%sShift+" - (ergoemacs :unicode-or-alt "⇧" "")))) + (setq ret "⇧Shift+")) ((memq mod '(control ergoemacs-control)) - (setq ret (format "%sCtrl+" - (or (and (eq 'windows-nt system-type) - (ergoemacs :unicode "✲" "")) - (and (eq 'gnu/linux system-type) - (ergoemacs :unicode "⎈" "")) - "")))) + (setq ret "Ctrl+")) ((eq mod 'meta) (setq ret "Alt+")) ((and (eq mod 'super) ergoemacs-display-small-symbols-for-key-modifiers (eq system-type 'windows-nt)) - (setq ret (ergoemacs :unicode-or-alt "⊞" "#"))) + (setq ret "⊞")) ((and (eq mod 'super) (eq system-type 'windows-nt)) - (setq ret (format "%sWin+" (ergoemacs :unicode-or-alt "⊞" "#")))) + (setq ret "⊞Win+")) (t (setq ret (format "%s+" mod)) (when ergoemacs-display-key-use-face @@ -337,13 +327,13 @@ KBD is the keyboard code. LAYOUT is the layout that is used." (setq mod tmp)) (setq tmp (format "%s%s%s%s" (or (and (or ergoemacs-display-without-brackets ergoemacs-display-key-use-face) "") - (and ergoemacs-display-use-unicode-brackets-around-keys (ergoemacs :unicode-or-alt "【" "[")) + (and ergoemacs-display-use-unicode-brackets-around-keys "【") "[") (mapconcat #'ergoemacs-key-description--modifier mod "") (ergoemacs-key-description--key ev mod) (or (and (or ergoemacs-display-without-brackets ergoemacs-display-key-use-face) "") - (and ergoemacs-display-use-unicode-brackets-around-keys (ergoemacs :unicode-or-alt "】" "]")) + (and ergoemacs-display-use-unicode-brackets-around-keys "】") "]"))) (when (and ergoemacs-display-small-symbols-for-key-modifiers ergoemacs-display-key-use-face) (add-text-properties 0 (length tmp) @@ -412,7 +402,7 @@ KBD is the keyboard code. LAYOUT is the layout that is used." (ergoemacs-key-description item)) ((listp item) (cond - ((eq (car item) 'lambda) (cons nil (ergoemacs :unicode-or-alt "λ" "lambda"))) + ((eq (car item) 'lambda) (cons nil "λ" )) ((eq (car item) 'closure) (cons nil "#<closure>")) ((eq (car item) 'keymap) (cons nil "#<keymap>")) (t (format "%s" item)))) @@ -420,7 +410,7 @@ KBD is the keyboard code. LAYOUT is the layout that is used." (if (ignore-errors (commandp item t)) (cons 'help-function (format "%s" item)) (cons nil (format "%s" item)))) - (t (cons nil (format"#<byte compiled %s>" (ergoemacs :unicode-or-alt "λ" "lambda")))))) + (t (cons nil (format"#<byte compiled %s>" "λ"))))) (defun ergoemacs-key-description--keymap-blame (key map) "Find the source of KEY in MAP." diff --git a/ergoemacs-macros.el b/ergoemacs-macros.el index 69c8cea..49b8ef2 100644 --- a/ergoemacs-macros.el +++ b/ergoemacs-macros.el @@ -349,6 +349,58 @@ This also creates functions: (ergoemacs-translate--create :key ,(intern (concat ":" (plist-get (nth 0 kb) ':name))) ,@(nth 0 kb))) ergoemacs-translation-hash)))) +(defmacro ergoemacs-advice (function args &rest body-and-plist) + "Defines an `ergoemacs-mode' advice. + +The structure is (ergoemacs-advice function args tags body-and-plist) + +When the tag :type equals :replace, the advice replaces the function. + +When :type is :replace that replaces a function (like `define-key')" + (declare (doc-string 2) + (indent 2)) + (let ((kb (make-symbol "kb"))) + (setq kb (ergoemacs-theme-component--parse-keys-and-body `(nil nil ,@body-and-plist))) + (cond + ((eq (plist-get (nth 0 kb) :type) :around) + ;; FIXME: use `nadvice' for emacs 24.4+ + (macroexpand-all `(progn + (defadvice ,function (around ,(intern (format "ergoemacs-advice--%s" (symbol-name function))) ,args activate) + ,(plist-get (nth 0 kb) :description) + ,@(nth 1 kb))))) + ((eq (plist-get (nth 0 kb) :type) :after) + ;; FIXME: use `nadvice' for emacs 24.4+ + (macroexpand-all + `(progn + (defadvice ,function (after ,(intern (format "ergoemacs-advice--after-%s" (symbol-name function))) ,args activate) + ,(plist-get (nth 0 kb) :description) + ,@(nth 1 kb))))) + ((eq (plist-get (nth 0 kb) :type) :before) + ;; FIXME: use `nadvice' for emacs 24.4+ + (macroexpand-all `(progn + (defadvice ,function (before ,(intern (format "ergoemacs-advice--%s" (symbol-name function))) ,args activate) + ,(plist-get (nth 0 kb) :description) + ,@(nth 1 kb))))) + ((eq (plist-get (nth 0 kb) :type) :replace) + (macroexpand-all `(progn + (defalias ',(intern (format "ergoemacs-advice--real-%s" (symbol-name function))) + (symbol-function ',function) (concat ,(format "ARGS=%s\n\n" args) (documentation ',function) + ,(format "\n\n`ergoemacs-mode' preserved the real `%s' in this function." + (symbol-name function)))) + (defun ,(intern (format "ergoemacs-advice--%s--" function)) ,args + ,(format "%s\n\n%s\n\n`ergoemacs-mode' replacement function for `%s'.\nOriginal function is preserved in `ergoemacs-advice--real-%s'" + (documentation function) + (plist-get (nth 0 kb) :description) (symbol-name function) (symbol-name function)) + ,@(nth 1 kb)) + ;; Hack to make sure the documentation is in the function... + (defalias ',(intern (format "ergoemacs-advice--%s" function)) ',(intern (format "ergoemacs-advice--%s--" function)) + ,(format "ARGS=%s\n\n%s\n\n%s\n\n`ergoemacs-mode' replacement function for `%s'.\nOriginal function is preserved in `ergoemacs-advice--real-%s'" + args (documentation function) (plist-get (nth 0 kb) :description) (symbol-name function) (symbol-name function))) + ,(if (plist-get (nth 0 kb) :always) + `(push ',function ergoemacs-advice--permanent-replace-functions) + `(push ',function ergoemacs-advice--temp-replace-functions)))))))) + + (provide 'ergoemacs-macros) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/ergoemacs-mode.el b/ergoemacs-mode.el index 6ff6c73..eb27b2e 100644 --- a/ergoemacs-mode.el +++ b/ergoemacs-mode.el @@ -234,6 +234,42 @@ When defining keys these functions override "Default Ergoemacs Layout" :group 'ergoemacs-mode) +(defvar ergoemacs-mode-startup-hook nil + "Hook for starting `ergoemacs-mode'.") + +(defvar ergoemacs-mode-shutdown-hook nil + "Hook for shutting down `ergoemacs-mode'.") + +(defvar ergoemacs-mode-intialize-hook nil + "Hook for initializing `ergoemacs-mode'.") + +(defvar ergoemacs-mode-init-hook nil + "Hook for running after Emacs loads.") + +(defvar ergoemacs-mode-after-load-hook nil + "Hook for running after a library loads.") + +(defvar ergoemacs-pre-command-hook nil) +(defun ergoemacs-pre-command-hook () + "Run `ergoemacs-mode' pre command hooks." + (when ergoemacs-mode + (run-hooks 'ergoemacs-pre-command-hook))) + +(defvar ergoemacs-post-command-hook nil) +(defun ergoemacs-post-command-hook () + "Run `ergoemacs-mode' post command hooks." + (when ergoemacs-mode + (run-hooks 'ergoemacs-post-command-hook))) + +(defvar ergoemacs-after-load-functions nil) +(defun ergoemacs-after-load-functions (absoulte-file-name) + "Run `ergoemacs-mode' after load functions. + +ABSOULTE-FILE-NAME is the file name that will be passed to the +variable `ergoemacs-after-load-functions'." + (run-hook-with-args 'ergoemacs-after-load-functions absoulte-file-name)) + + (defcustom ergoemacs-theme-options '() "List of theme options." @@ -289,6 +325,11 @@ The `execute-extended-command' is now \\[execute-extended-command]. (if ergoemacs-mode (progn ;; Save frame parameters + (run-hooks 'ergoemacs-mode-startup-hook) + (add-hook 'pre-command-hook #'ergoemacs-pre-command-hook) + (add-hook 'post-command-hook #'ergoemacs-post-command-hook) + (add-hook 'after-load-functions #'ergoemacs-after-load-functions) + (setq ergoemacs-mode--default-frame-alist nil) (dolist (elt (reverse default-frame-alist)) (push elt ergoemacs-mode--default-frame-alist)) @@ -307,11 +348,11 @@ The `execute-extended-command' is now \\[execute-extended-command]. (ergoemacs-setup-override-keymap)) (t (ergoemacs-setup-override-keymap))) (setq ergoemacs-require--ini-p t) - (define-key key-translation-map (kbd "<apps>") (kbd "<menu>")) - (global-unset-key (kbd "<apps>")) - (global-unset-key (kbd "<menu>")) - (define-key ergoemacs-translate--parent-map [apps] 'ergoemacs-command-loop--swap-translation) - (define-key ergoemacs-translate--parent-map [menu] 'ergoemacs-command-loop--swap-translation) + ;;(define-key key-translation-map (kbd "<apps>") (kbd "<menu>")) + ;;(global-unset-key (kbd "<apps>")) + ;;(global-unset-key (kbd "<menu>")) + ;;(define-key ergoemacs-translate--parent-map [apps] 'ergoemacs-command-loop--swap-translation) + ;;(define-key ergoemacs-translate--parent-map [menu] 'ergoemacs-command-loop--swap-translation) (if refresh-p @@ -325,6 +366,11 @@ The `execute-extended-command' is now \\[execute-extended-command]. (setq ergoemacs-mode--default-frame-alist nil) (ergoemacs-command-loop--redefine-quit-key) + (run-hooks 'ergoemacs-mode-shutdown-hook) + (remove-hook 'post-command-hook #'ergoemacs-post-command-hook) + (remove-hook 'pre-command-hook #'ergoemacs-pre-command-hook) + (remove-hook 'after-load-functions #'ergoemacs-after-load-functions) + (unless refresh-p (message "Ergoemacs-mode turned OFF.") ) @@ -573,6 +619,7 @@ When STORE-P is non-nil, save the tables." (ergoemacs-mode--setup-hash-tables) (dolist (pkg '(ergoemacs-command-loop + ergoemacs-advice ergoemacs-component ergoemacs-functions ergoemacs-key-description