ergoemacs-mode-5.16.10.12/ 0000755 0001752 0001753 00000000000 13332404643 013427 5 ustar elpa elpa ergoemacs-mode-5.16.10.12/ergoemacs-command-loop.el 0000644 0001752 0001753 00000306410 13332260074 020303 0 ustar elpa elpa ;;; ergoemacs-command-loop.el --- Keyboard translation functions -*- lexical-binding: t -*-
;; Copyright © 2013-2018 Free Software Foundation, Inc.
;; Filename: ergoemacs-command-loop.el
;; Description:
;; Author: Matthew L. Fidler
;; Maintainer: Matthew L. Fidler
;; Created: Sat Sep 28 20:08:09 2013 (-0500)
;;
;;; Commentary:
;; This is the functions for the `ergoemacs-mode' command loop.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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 .
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(require 'cl-lib)
(eval-when-compile
(require 'ergoemacs-macros))
(declare-function ergoemacs-warn "ergoemacs-lib")
(declare-function guide-key/close-guide-buffer "guide-key")
(declare-function guide-key/popup-function "guide-key")
(declare-function ergoemacs-key-description "ergoemacs-key-description")
(declare-function ergoemacs-key-description--unicode-char "ergoemacs-key-description")
(declare-function ergoemacs-mode-line "ergoemacs-mode")
(declare-function ergoemacs-layout--regexp "ergoemacs-layouts")
(declare-function ergoemacs-layouts--list "ergoemacs-layouts")
(declare-function ergoemacs-map-properties--movement-p "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--put "ergoemacs-map-properties")
(declare-function ergoemacs-translate--define-key "ergoemacs-translate")
(declare-function ergoemacs-translate--escape-to-meta "ergoemacs-translate")
(declare-function ergoemacs-translate--event-basic-type "ergoemacs-translate")
(declare-function ergoemacs-translate--event-convert-list "ergoemacs-translate")
(declare-function ergoemacs-translate--event-modifiers "ergoemacs-translate")
(declare-function ergoemacs-translate--event-mods "ergoemacs-translate")
(declare-function ergoemacs-translate--get "ergoemacs-translate")
(declare-function ergoemacs-translate--keymap "ergoemacs-translate")
(declare-function ergoemacs-translate--meta-to-escape "ergoemacs-translate")
(declare-function ergoemacs-translate--trials "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-key "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-keymap "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-keymap-modal "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-modal-always "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-modal-color "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-p "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-text "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-translation "ergoemacs-translate")
(declare-function ergoemacs-translation-struct-unchorded "ergoemacs-translate")
(declare-function ergoemacs-key-description--modifier "ergoemacs-key-description")
(declare-function ergoemacs-posnp "ergoemacs-command-loop")
(if (fboundp 'posnp)
(defalias 'ergoemacs-posnp #'posnp)
;; For emacs 24.1
(defun ergoemacs-posnp (obj)
"Return non-nil if OBJ appears to be a valid `posn' object."
(and (windowp (car-safe obj))
(atom (car-safe (setq obj (cdr obj)))) ;AREA-OR-POS.
(integerp (car-safe (car-safe (setq obj (cdr obj))))) ;XOFFSET.
(integerp (car-safe (cdr obj))))))
(defvar ergoemacs-command-loop-echo-keystrokes)
(defvar ergoemacs-default-cursor-color)
(defvar ergoemacs-echo-function)
(defvar ergoemacs-map--quit-map)
(defvar ergoemacs-modal-emacs-state-modes)
(defvar ergoemacs-modal-ignored-buffers)
(defvar ergoemacs-modal-ignored-keymap)
(defvar ergoemacs-mode-started-p)
(defvar guide-key/guide-key-sequence)
(defvar keyfreq-mode)
(defvar keyfreq-table)
(defvar universal-argument-num-events) ;; Not in Emacs 24.5
(defvar ergoemacs-command-loop--mark-active nil
"Determines if mark was active before ergoemacs command loop.")
(defvar ergoemacs-command-loop--universal-functions '(universal-argument ergoemacs-universal-argument ergoemacs-command-loop--universal-argument)
"List of `ergoemacs-mode' recognized functions.")
(define-obsolete-variable-alias 'ergoemacs-universal-fns 'ergoemacs-command-loop--universal-functions "Ergoemacs-v5.16")
(defvar ergoemacs-command-loop--next-key-hash
(let ((hash (make-hash-table)))
(puthash 'event-apply-shift-modifier (list '(shift) :force) hash)
(puthash 'event-apply-alt-modifier (list '(alt) :force) hash)
(puthash 'event-apply-control-modifier (list '(control) :force) hash)
(puthash 'event-apply-hyper-modifier (list '(hyper) :force) hash)
(puthash 'event-apply-meta-modifier (list '(meta) :force) hash)
(puthash 'event-apply-super-modifier (list '(super) :force) hash)
hash)
"Hash table of how functions force the unchorded next key translation to behave.")
(defvar ergoemacs-command-loop--undo-functions
'(ergoemacs-read-key-undo-last
ergoemacs-command-loop--undo-last ergoemacs-read-key-force-undo-last ergoemacs-command-loop--force-undo-last)
"Undo functions recognized by `ergoemacs-mode'.")
(defvar ergoemacs-command-loop--help-last-key nil)
(defvar ergoemacs-command-loop--decode-event-delay 0.01
"Timeout for `ergoemacs-command-loop--decode-event'.
This is to distinguish events in a terminal, like xterm.
It needs to be less than `ergoemacs-command-loop-blink-rate'.")
(define-obsolete-variable-alias 'ergoemacs-read-key-delay 'ergoemacs-command-loop--decode-event-delay "Ergoemacs-v5.16")
(defvar ergoemacs-command-loop--history nil
"History of command loop locations.")
(defvar ergoemacs-command-loop--last-event-time nil
"Stores the last event time.")
(defvar ergoemacs-command-loop--first-type nil
"This is the first type for the `ergoemacs-mode' command loop.")
(defvar ergoemacs-command-loop--current-type nil
"This is the current translation type for the `ergoemacs-mode' command loop.")
(defvar ergoemacs-command-loop--universal nil
"This determines if `ergoemacs-mode' will start editing/completing universal arguments.")
(defvar ergoemacs-command-loop--self-insert-command-count 0
"The count of `self-insert-command' to allow inserting correct undo boundaries.")
;; (defvar ergoemacs-command-loop--mouse-event nil)
(defvar ergoemacs-command-loop--exit nil
"External variable controlling if the `ergoemacs-command-loop' will exit.
:ignore-post-command-hook means that the command will exit, and
ignore the post-command hooks.")
(defvar ergoemacs-command-loop--execute-modify-command-list
'(last-repeatable-command
this-command
this-original-command
mc--this-command)
"Commands that will be set to what `ergoemacs-command-loop' executes.")
(defun ergoemacs-command-loop--execute-modify-command-list (command)
"Set variables in `ergoemacs-command-loop--execute-modify-command-list' to COMMAND."
(ergoemacs-save-buffer-state
(dolist (var ergoemacs-command-loop--execute-modify-command-list)
(set var command))))
(defvar ergoemacs-command-loop--single-command-keys nil
"If defined, a vector of the command keys pressed in the `ergoemacs-command-loop'.")
(defvar ergoemacs-command-loop--echo-keystrokes-complete nil
"Echoed keystrokes, keep echoing active.")
(defvar ergoemacs-command-loop--modal-stack '()
"The Modal Stack.")
(defvar ergoemacs-command-loop-swap-translation)
(defvar ergoemacs-command-loop-time-before-blink)
(defvar ergoemacs-command-loop-blink-character)
(defvar ergoemacs-command-loop-blink-rate)
(defvar ergoemacs-command-loop-hide-shift-translations)
(defvar ergoemacs-mode)
(defvar ergoemacs-command-loop-type)
(defvar ergoemacs-keymap)
(defvar ergoemacs-handle-ctl-c-or-ctl-x)
(defvar ergoemacs-ctl-c-or-ctl-x-delay)
(defun ergoemacs-command-loop--modal-show ()
"Show modal translation.
Returns the mode-line text."
(let (tmp color text)
(ergoemacs-save-buffer-state
(cond
((setq tmp (ergoemacs :modal-p))
(setq color (ergoemacs-translation-struct-modal-color tmp))
(if color
(set-cursor-color color)
(when ergoemacs-default-cursor-color
(set-cursor-color ergoemacs-default-cursor-color)))
(setq text (ergoemacs-translation-struct-text tmp))
(when (functionp text)
(setq text (funcall text)))
(if text
(ergoemacs-mode-line ;; Indicate Alt+ in mode-line
text)
(ergoemacs-mode-line))
(or text "Unnamed"))
(t
(when ergoemacs-default-cursor-color
(set-cursor-color ergoemacs-default-cursor-color))
(ergoemacs-mode-line)
nil)))))
(defun ergoemacs-command-loop--modal-p ()
"Determine if the command should be modal.
If so return the translation."
(if (not ergoemacs-command-loop--modal-stack) nil
(let* ((translation (nth 0 ergoemacs-command-loop--modal-stack))
(always)
ret)
(when (ergoemacs-translation-struct-p translation)
(setq always (ergoemacs-translation-struct-modal-always translation))
(cond
((and (minibufferp)
(not always)))
((and (not always)
(memq major-mode ergoemacs-modal-emacs-state-modes)))
((and (not always)
(catch 'match-modal
(dolist (reg ergoemacs-modal-ignored-buffers)
(when (string-match reg (buffer-name))
(throw 'match-modal t)))
nil)))
(t
(setq ret translation))))
ret)))
(defun ergoemacs-command-loop--modal-pop ()
"Turn off the last ergoemacs modal in the modal-stack."
(when ergoemacs-command-loop--modal-stack
(ergoemacs-command-loop--modal (ergoemacs-translation-struct-key (nth 0 ergoemacs-command-loop--modal-stack)))))
(defun ergoemacs-command-loop--modal (type)
"Toggle ergoemacs command modes.
The TYPE is the type of command translation/modal keymaps that are installed."
(cond
((or (not ergoemacs-command-loop--modal-stack) ;; First time to turn on
(not (eq (ergoemacs-translation-struct-key (nth 0 ergoemacs-command-loop--modal-stack)) type)) ;; New modal
)
(push (ergoemacs-translate--get type) ergoemacs-command-loop--modal-stack)
(unless ergoemacs-default-cursor-color
(setq ergoemacs-default-cursor-color
(or (frame-parameter nil 'cursor-color) "black")))
(ergoemacs-command-loop--message "%s command mode installed" (ergoemacs-command-loop--modal-show)))
(t ;; Turn off.
(setq ergoemacs-command-loop--modal-stack (cdr ergoemacs-command-loop--modal-stack))
(if (ergoemacs :modal-p)
(ergoemacs-command-loop--message "%s command mode resumed." (ergoemacs-command-loop--modal-show))
(ergoemacs-command-loop--modal-show)
(ergoemacs-command-loop--message "Resume regular ergoemacs-mode")))))
(defun ergoemacs-command-loop--redefine-quit-key (&optional key)
"Redefines the quit-key in Emacs to KEY or Ctrl+g.
Typically the Emacs quit key is Ctrl+g, but it can be redefined
with this function."
(let ((cur-input (current-input-mode))
(new-key (listify-key-sequence (or key [7]))))
(when (> 1 (length new-key))
(error "Will not set a key sequence to the emacs key sequence"))
(setf (nth 3 cur-input) new-key)
(and (ignore-errors (apply 'set-input-mode cur-input))
(message "Redefined Emacs quit key to %s"
(ergoemacs-key-description (or key [7])))
t)))
(defun ergoemacs-command-loop--setup-quit-key ()
"Setup the `ergoemacs-mode' quit key."
(let (quit-keys vect-key)
(dolist (key (reverse (append (where-is-internal 'keyboard-quit)
(where-is-internal 'ergoemacs-keyboard-quit))))
(setq vect-key (vconcat key))
(unless (or (symbolp (aref vect-key 0))
(not (= 1 (length vect-key)))
(member key quit-keys))
(push vect-key quit-keys)))
(when quit-keys
(catch 'found-quit
(dolist (key quit-keys)
(when (ergoemacs-command-loop--redefine-quit-key key)
(throw 'found-quit t)))
nil))))
(add-hook 'ergoemacs-mode-startup-hook #'ergoemacs-command-loop--setup-quit-key)
(add-hook 'ergoemacs-mode-shutdown-hook #'ergoemacs-command-loop--redefine-quit-key)
(defun ergoemacs-command-loop--universal-argument (&rest _ignore)
"`ergoemacs-mode' universal argument.
This is called through `ergoemacs-command-loop'"
(interactive)
(cond
;; ((not (ergoemacs :command-loop-p))
;; ;; Command loop hasn't started.
;; (setq current-prefix-arg '(4))
;; (ergoemacs-command-loop nil type nil t))
((not current-prefix-arg)
(setq current-prefix-arg '(4)
ergoemacs-command-loop--universal t
ergoemacs-command-loop--exit :ignore-post-command-hook))
((listp current-prefix-arg)
;; Change current prefix argument
(setq current-prefix-arg (list (* (nth 0 current-prefix-arg) 4))
ergoemacs-command-loop--universal t
ergoemacs-command-loop--exit :ignore-post-command-hook))
(t
(setq ergoemacs-command-loop--universal t
ergoemacs-command-loop--exit :ignore-post-command-hook))))
(defalias 'ergoemacs-read-key--universal-argument 'ergoemacs-command-loop--universal-argument)
(defalias 'ergoemacs-universal-argument 'ergoemacs-command-loop--universal-argument)
(defun ergoemacs-command-loop--digit-argument (&optional type)
"Ergoemacs digit argument.
This is called through `ergoemacs-command-loop'.
TYPE is the keyboard translation type, defined by `ergoemacs-translate'.
Ergoemacs-mode sets up: :ctl-to-alt :unchorded :normal."
(interactive)
(let* ((char (if (integerp last-command-event)
last-command-event
(get last-command-event 'ascii-character)))
(digit (- (logand char ?\177) ?0)))
(setq current-prefix-arg digit))
(ergoemacs-command-loop nil type nil t))
(defalias 'ergoemacs-digit-argument 'ergoemacs-command-loop--digit-argument)
(defun ergoemacs-command-loop--negative-argument (&optional type)
"Ergoemacs negative argument.
This is called through `ergoemacs-command-loop'.
TYPE is the keyboard translation type, defined by `ergoemacs-translate'
Ergoemacs-mode sets up: :ctl-to-alt :unchorded :normal."
(setq current-prefix-arg '-)
(ergoemacs-command-loop nil type nil t))
(defalias 'ergoemacs-negative-argument 'ergoemacs-command-loop--negative-argument)
(dolist (arg '((next-key-is-alt (meta))
(next-key-is-meta (meta))
(next-key-is-ctl (control))
(next-key-is-control (control))
(next-key-is-alt-ctl (control meta))
(next-key-is-ctl-alt (control meta))
(next-key-is-control-meta (control meta))
(next-key-is-meta-control (control meta))
(next-key-is-quoted nil)))
(eval (macroexpand-all
`(progn
(defun ,(intern (concat "ergoemacs-command-loop--" (symbol-name (nth 0 arg)))) ()
,(format "Ergoemacs function to allow %s to be the emacs modifiers" (nth 1 arg))
(interactive)
(message "Dummy Function for %s" (ergoemacs :modifier-desc ,(nth 1 arg))))
(defalias ',(intern (concat "ergoemacs-read-key-" (symbol-name (nth 0 arg)))) ',(intern (concat "ergoemacs-command-loop--" (symbol-name (nth 0 arg)))))
(puthash ',(intern (concat "ergoemacs-command-loop--" (symbol-name (nth 0 arg)))) '(,(nth 1 arg) nil) ergoemacs-command-loop--next-key-hash)
(puthash ',(intern (concat "ergoemacs-read-key-" (symbol-name (nth 0 arg)))) '(,(nth 1 arg) nil) ergoemacs-command-loop--next-key-hash)
(defun ,(intern (concat "ergoemacs-command-loop--force-" (symbol-name (nth 0 arg)))) ()
,(format "Ergoemacs function to allow %s to be the emacs modifiers" (nth 1 arg))
(interactive)
(message "Dummy Function for %s" (ergoemacs :modifier-desc ,(nth 1 arg))))
(defalias ',(intern (concat "ergoemacs-read-key-force-" (symbol-name (nth 0 arg)))) ',(intern (concat "ergoemacs-command-loop--force-" (symbol-name (nth 0 arg)))))
(puthash ',(intern (concat "ergoemacs-command-loop--force-" (symbol-name (nth 0 arg)))) '(,(nth 1 arg) :force) ergoemacs-command-loop--next-key-hash)
(puthash ',(intern (concat "ergoemacs-read-key-force-" (symbol-name (nth 0 arg)))) '(,(nth 1 arg) :force) ergoemacs-command-loop--next-key-hash)))))
(defvar ergoemacs-last-command-event nil
"`ergoemacs-mode' command loop last read command.")
(defun ergoemacs-command-loop--undo-last ()
"Function to undo the last key-press.
Uses the `ergoemacs-command-loop--history' variable/function."
(interactive)
(if ergoemacs-command-loop--history
(let ((tmp (pop ergoemacs-command-loop--history)))
(setq ergoemacs-command-loop--single-command-keys (nth 0 tmp)
ergoemacs-command-loop--current-type (nth 1 tmp)
ergoemacs-command-loop--universal (nth 2 tmp)
current-prefix-arg (nth 3 tmp)
last-command-event (nth 4 tmp)
last-input-event last-command-event
ergoemacs-last-command-event last-command-event))
;; Nothing to undo, exit the command loop.
(setq ergoemacs-command-loop--exit t)))
(defalias 'ergoemacs-read-key-undo-last 'ergoemacs-command-loop--undo-last)
(defun ergoemacs-command-loop--force-undo-last ()
"Function to undo the last key-press.
Unlike `ergoemacs-command-loop--undo-last', this ignores any bindings like \\[backward-kill-sentence]
This is actually a dummy function. The actual work is done in `ergoemacs-command-loop'"
(interactive)
(call-interactively 'ergoemacs-command-loop--undo-last))
(put 'ergoemacs-command-loop--force-undo-last :ergoemacs-local :force)
(defalias 'ergoemacs-read-key-force-undo-last 'ergoemacs-command-loop--force-undo-last)
(put 'ergoemacs-read-key-force-undo-last :ergoemacs-local :force)
(defun ergoemacs-command-loop--swap-translation ()
"Function to swap translations.
Uses the `ergoemacs-command-loop-swap-translation' variable."
(interactive)
(let ((next-swap (assoc (list ergoemacs-command-loop--first-type ergoemacs-command-loop--current-type) ergoemacs-command-loop-swap-translation)))
(setq ergoemacs-command-loop--current-type
(if next-swap
(nth 1 next-swap)
:normal))))
(defalias 'ergoemacs-read-key-swap 'ergoemacs-command-loop--swap-translation)
(defun ergoemacs-command-loop--help ()
"Show help for the current sequence KEY."
(interactive)
;; Eventually...
(if (not ergoemacs-command-loop--single-command-keys) nil
(cond
;; TEST:
;; ((and (boundp 'icicle-mode) icicle-mode)
;; (let ((key (vconcat ergoemacs-command-loop--single-command-keys [ergoemacs-ignore])))
;; (ergoemacs-read-key-call 'icicle-complete-keys nil key)))
;; FIXME:
((and (boundp 'guide-key-mode) guide-key-mode)
(let ((key ergoemacs-command-loop--single-command-keys))
(cond
((equal ergoemacs-command-loop--help-last-key ergoemacs-command-loop--single-command-keys)
(setq ergoemacs-command-loop--help-last-key nil
guide-key/guide-key-sequence (delete (key-description ergoemacs-command-loop--single-command-keys) guide-key/guide-key-sequence))
(guide-key/close-guide-buffer))
(t
;; Not using pushnew because the test is equal and
;; guide-key/guide-key-sequence is a global variable.
(setq ergoemacs-command-loop--help-last-key ergoemacs-command-loop--single-command-keys)
(unless (member (key-description ergoemacs-command-loop--single-command-keys) guide-key/guide-key-sequence)
(push (key-description ergoemacs-command-loop--single-command-keys) guide-key/guide-key-sequence))
(guide-key/popup-function key)))))
(t (let ((cb (current-buffer))
(key ergoemacs-command-loop--single-command-keys))
(save-excursion
(with-help-window (help-buffer)
(set-buffer (help-buffer))
(describe-buffer-bindings cb key)))
(setq ergoemacs-command-loop--exit t))))))
(defalias 'ergoemacs-read-key-help 'ergoemacs-command-loop--help)
;; Command Loop
;; (1) Read Key sequence
(defvar ergoemacs-command-loop--read-key-prompt ""
"Extra prompt for `ergoemacs-command-loop--read-key'.")
(defun ergoemacs-command-loop--read-key-help-text-prefix-argument (&optional blink-on universal)
"Display prefix argument portion of the `ergoemacs-mode' help text.
BLINK-ON
UNIVERSAL"
(or (and (not current-prefix-arg)
(concat (or
(and (not universal) "")
(or (and (string= ergoemacs-command-loop--read-key-prompt "") "") " ")
(and ergoemacs-command-loop-blink-character
(or (and blink-on (ergoemacs :unicode-or-alt ergoemacs-command-loop-blink-character "-"))
" "))
" ")
(or
(and (not universal) "")
(ergoemacs :unicode-or-alt "▸" ">"))))
(format
"%s%s%s %s "
(cond
((listp current-prefix-arg)
(make-string (round (log (nth 0 current-prefix-arg) 4)) ?u))
(t current-prefix-arg))
(or (and (not universal) "")
(and ergoemacs-command-loop-blink-character
(or (and blink-on (ergoemacs :unicode-or-alt ergoemacs-command-loop-blink-character "-"))
" "))
" ")
(or (and (listp current-prefix-arg)
(format "%s" current-prefix-arg))
"")
(ergoemacs :unicode-or-alt "▸" ">"))))
(defun ergoemacs-command-loop--ensure-sane-variables ()
"Make sure that certain variables won't lock up Emacs.
Currently this ensures:
`ergoemacs-command-loop--decode-event-delay' is less than `ergoemacs-command-loop-blink-rate'."
(when (>= ergoemacs-command-loop--decode-event-delay ergoemacs-command-loop-blink-rate)
(ergoemacs-warn "ergoemacs-command-loop--decode-event-delay >= ergoemacs-command-loop-blink-rate; Reset to ergoemacs-command-loop-blink-rate / 1000")
(setq ergoemacs-command-loop--decode-event-delay (/ ergoemacs-command-loop-blink-rate 1000))))
(add-hook 'ergoemacs-mode-startup-hook #'ergoemacs-command-loop--ensure-sane-variables)
(defun ergoemacs-command-loop--combine (current-key next-event)
"Combine CURRENT-KEY and NEXT-EVENT into a vector."
(let (tmp)
(cond
((and (vectorp current-key)
(eventp (setq tmp (aref current-key 0)))
(consp tmp)
(memq (event-basic-type (car tmp))
'(mouse-1 mouse-2 mouse-3 mouse-4 mouse-5 mouse-6 mouse-7 mouse-8 mouse-9)))
(push next-event unread-command-events))
(t (vconcat current-key (vector next-event))))))
(defvar ergoemacs-comand-loop--untranslated-event nil)
(declare-function ergoemacs--real-read-key-sequence "ergoemacs-command-loop")
(fset 'ergoemacs--real-read-key-sequence (symbol-function #'read-key-sequence))
(declare-function ergoemacs--real-describe-key "ergoemacs-command-loop")
(fset 'ergoemacs--real-describe-key (symbol-function #'describe-key))
(defun ergoemacs-command-loop--input-method (event)
"Call `input-method-function' on EVENT.
Ensure that `read-key-sequence' is the original function (not
`ergoemacs-command-loop--read-key-sequence')."
(ergoemacs-no-specials
(ignore-errors (funcall input-method-function event))))
(defun ergoemacs-command-loop--history (&optional prompt seconds current-key)
"Read event and add to event history.
PROMPT is the prompt that will be displayed.
SECONDS is the number of seconds between cursor blink.
CURRENT-KEY is the current key being read. This is used
inconjunction with `input-method-function' to translate keys if
`set-input-method' is using a different keyboard layout.
Also add to `last-command-event' to allow `self-insert-character'
to work appropriately. I'm not sure the purpose of
`last-event-frame', but this is modified as well.
This is not done when the event is [ergoemacs-ignore]"
(or (let ((event (pop unread-command-events))
translate)
(setq ergoemacs-comand-loop--untranslated-event event)
(when (and current-input-method (not current-key)
(not overriding-local-map) (not overriding-terminal-local-map)
(setq translate (ergoemacs-command-loop--input-method event)))
(setq event (pop translate))
(when translate
(setq unread-command-events (append translate unread-command-events))))
(unless (eq event 'ergoemacs-ignore)
(setq last-command-event event
last-input-event last-command-event
ergoemacs-last-command-event last-command-event
last-event-frame (selected-frame)))
event)
(let* ((last-event-time (or (and ergoemacs-command-loop--last-event-time
(- (float-time) ergoemacs-command-loop--last-event-time))
(and (setq ergoemacs-command-loop--last-event-time (float-time)) 0)))
(prompt (cond
((not prompt) nil)
((not (string= "" ergoemacs-command-loop--read-key-prompt)) prompt)
((or (string= prompt " ")
(string-match-p prompt (concat " *" (ergoemacs :unicode-or-alt ergoemacs-command-loop-blink-character "-") " *"))) nil)
(ergoemacs-command-loop--universal prompt)
(ergoemacs-command-loop--echo-keystrokes-complete prompt)
((not (numberp ergoemacs-command-loop-echo-keystrokes)) prompt)
((= 0 ergoemacs-command-loop-echo-keystrokes) prompt)
((< last-event-time ergoemacs-command-loop-echo-keystrokes) nil)
;; ((and (not ergoemacs-command-loop--echo-keystrokes-complete)
;; (numberp ergoemacs-command-loop-echo-keystrokes)
;; (or (= 0 ergoemacs-command-loop-echo-keystrokes)
;; (< last-event-time ergoemacs-command-loop-echo-keystrokes))) nil)
;; ((and (< last-event-time ergoemacs-command-loop-time-before-blink) (string= prompt "")) nil)
;; ((and (< last-event-time ergoemacs-command-loop-time-before-blink) ) nil)
(t
(setq ergoemacs-command-loop--echo-keystrokes-complete t)
prompt)))
(echo-keystrokes 0)
;; Run (with-timeout) so that idle timers will work.
(event (cond
(prompt (with-timeout (seconds nil)
(progn
(ergoemacs-command-loop--message prompt)
(ignore-errors (read-event)))))
((and (not ergoemacs-command-loop--echo-keystrokes-complete)
ergoemacs-command-loop--single-command-keys)
(with-timeout (ergoemacs-command-loop-echo-keystrokes nil)
(ignore-errors (read-event))))
(t (ignore-errors (read-event)))))
translate)
(when (eventp event)
(setq ergoemacs-comand-loop--untranslated-event event)
(unless (consp event) ;; Don't record mouse events
(when (and current-input-method (not current-key)
(not overriding-local-map) (not overriding-terminal-local-map)
(setq translate (ergoemacs-command-loop--input-method event)))
(setq event (pop translate))
(when translate
(setq unread-command-events (append translate unread-command-events))))
(push (list ergoemacs-command-loop--single-command-keys
ergoemacs-command-loop--current-type
ergoemacs-command-loop--universal
current-prefix-arg
last-command-event)
ergoemacs-command-loop--history))
(unless (eq event 'ergoemacs-ignore)
(setq ergoemacs-command-loop--last-event-time (float-time)
last-command-event event
last-input-event last-command-event
ergoemacs-last-command-event last-command-event
last-event-frame (selected-frame))))
event)))
(defvar ergoemacs-command-loop--decode-event-timeout-p nil
"Determines if `ergoemacs-command-loop--decode-event' timed out.")
(defun ergoemacs-command-loop--decode-event (event keymap &optional current-key)
"Change EVENT based on KEYMAP.
Used to help with translation keymaps like `input-decode-map'.
CURRENT-KEY is the current key being read. This is used
inconjunction with `input-method-function' to translate keys if
`set-input-method' is using a different keyboard layout."
(let* ((new-event event)
(old-ergoemacs-input unread-command-events)
new-ergoemacs-input
(current-test-key (or (and (listp event)
(vector (ergoemacs-translate--event-convert-list
(append (ergoemacs-translate--event-modifiers event)
(list (ergoemacs-translate--event-basic-type event))))))
(vector event)))
(test-ret (lookup-key keymap current-test-key))
(timeout-key (key-binding (vconcat current-test-key [ergoemacs-timeout])))
next-key)
(while (and current-test-key
(ergoemacs-keymapp test-ret))
;; The translation needs more keys...
(if timeout-key
(setq next-key (with-timeout (ergoemacs-ctl-c-or-ctl-x-delay
(progn
(setq ergoemacs-command-loop--decode-event-timeout-p t)
nil))
(ergoemacs-command-loop--history nil ergoemacs-command-loop--decode-event-delay current-key)))
(setq next-key (ergoemacs-command-loop--history nil ergoemacs-command-loop--decode-event-delay current-key)))
(when next-key ;; Since a key was read, save it to be read later.
(push last-command-event new-ergoemacs-input))
(if next-key
(setq current-test-key (ergoemacs :combine current-test-key next-key)
timeout-key (key-binding (vconcat current-test-key [ergoemacs-timeout]))
test-ret (lookup-key keymap current-test-key))
(setq current-test-key nil)))
;; Change strings to emacs keys.
(when (stringp test-ret)
;; Should it be read-kbd-macro?
(setq test-ret (vconcat test-ret)))
(when (functionp test-ret)
(when (memq test-ret '(xterm-mouse-translate xterm-mouse-translate-extended))
(message "xterm-mouse-translate: %s->%s" current-test-key (funcall test-ret nil)))
(setq last-input-event event
test-ret (if (or (eq keymap input-decode-map)
(eq keymap key-translation-map)
(eq keymap local-function-key-map))
(funcall test-ret nil) ;; Pretend emacs called this from command loop.
(funcall test-ret)))
(when (not (equal unread-command-events old-ergoemacs-input))
(push (pop unread-command-events) new-ergoemacs-input)))
(if (and (vectorp test-ret)
(= (length test-ret) 1))
(progn
(setq new-event (elt test-ret 0)))
;; Not a new event, restore anything that was popped off the
;; unread command events.
(when old-ergoemacs-input
(setq unread-command-events old-ergoemacs-input))
;; Add anything read to the
;; unread-command-events
(when new-ergoemacs-input
(setq unread-command-events (append new-ergoemacs-input unread-command-events))))
new-event))
(defun ergoemacs-command-loop--read-event (prompt &optional current-key)
"Read a single event.
PROMPT is the prompt used when reading an event.
CURRENT-KEY is the current key sequence that has alerady been
read.
This respects `input-decode-map', `local-function-key-map' and
`key-translation-map'.
It also inputs real read events into the history with
`ergoemacs-command-loop--history'
It will timeout after `ergoemacs-command-loop-blink-rate' and
return nil."
(let ((input (ergoemacs-command-loop--history prompt ergoemacs-command-loop-blink-rate current-key))
last-input
basic mods
binding gui)
;; Fix issues with `input-decode-map'
(when input
;; Fix input as if you defined C-i -> on `input-decode-map'
;; http://emacs.stackexchange.com/questions/10271/how-to-bind-c-for-real-seriously-for-real-this-time/15174
(if (and (display-graphic-p)
(setq basic (event-basic-type input))
(memq basic (list 'i 'm '\[ ?i ?m ?\[))
(setq mods (event-modifiers input))
(memq 'control mods)
(setq gui (ergoemacs-translate--event-convert-list (append (list 'ergoemacs-gui) mods (list basic))))
(setq binding (key-binding (ergoemacs :combine current-key input) t)))
(setq input gui)
(setq input (ergoemacs-command-loop--decode-event input input-decode-map current-key)
binding (key-binding (ergoemacs :combine current-key input) t)))
;; These should only be replaced if they are not bound.
(unless binding
(setq last-input input
input (ergoemacs-command-loop--decode-event input local-function-key-map current-key))
(unless (eq last-input input)
(setq binding (key-binding (ergoemacs :combine current-key input) t))))
(setq last-input input
input (ergoemacs-command-loop--decode-event input key-translation-map current-key))
(unless (eq last-input input)
(setq binding (key-binding (ergoemacs :combine current-key input) t))))
input))
(defun ergoemacs-command-loop--read-key (&optional current-key type universal)
"Read a key for the `ergoemacs-mode' command loop.
This uses `ergoemacs-command-loop--read-event'.
CURRENT-KEY is the current key that is being read, the next key
read will be appended to this key.
TYPE is the type of translation being applied. By default,
the :normal traslation is used.
UNIVERSAL flag telss if this is a univeral argument that is being
read."
(let* ((universal universal)
(type (or type :normal))
(translation (ergoemacs-translate--get type))
(local-keymap (ergoemacs-translate--keymap translation))
(text (ergoemacs-translation-struct-text translation))
(unchorded (ergoemacs-translation-struct-unchorded translation))
(trans (ergoemacs-translation-struct-translation translation))
(modal (ergoemacs :modal-p))
(keys nil)
(blink-on nil)
input
raw-input
mod-keys tmp
reset-key-p
double)
;; Setup modal translation
(when (and (eq type :normal) modal)
(setq type (ergoemacs-translation-struct-key modal)
local-keymap (ergoemacs-translation-struct-keymap-modal modal)
text (ergoemacs-translation-struct-text modal)
unchorded (ergoemacs-translation-struct-unchorded modal)
trans (ergoemacs-translation-struct-translation modal)
tmp translation
translation modal
modal tmp
tmp nil))
;; (ergoemacs-command-loop--read-key (read-kbd-macro "C-x" t) :unchorded-ctl)
(when (functionp text)
(setq text (funcall text)))
(when trans
;; Don't echo the uncommon hyper/super/alt translations (alt is
;; not the alt key...)
(dolist (tr trans)
(unless (or (memq 'hyper (nth 0 tr)) (memq 'super (nth 0 tr)) (memq 'alt (nth 0 tr))
(and ergoemacs-command-loop-hide-shift-translations (memq 'shift (nth 0 tr))))
(if (member (list (nth 1 tr) (nth 0 tr)) trans)
(when (not (member (list (nth 1 tr) (nth 0 tr)) double))
(push tr double))
(push tr tmp))))
(setq trans tmp))
(setq trans (or (and (or trans double)
(concat "\nTranslations: "
(or (and double
(mapconcat
(lambda(elt)
;; (and (setq tmp (elt current-key 0))
;; (or (and (consp tmp) (symbolp (setq tmp (car tmp)))))
;; (stringp tmp)
;; (string-match-p "\\" tmp))
(format "%s%s%s"
(ergoemacs :modifier-desc (nth 0 elt))
(ergoemacs :unicode-or-alt "↔" "<->")
(ergoemacs :modifier-desc (nth 1 elt))))
double ", "))
"")
(or (and double trans ", ") "")
(mapconcat
(lambda(elt)
(format "%s%s%s"
(ergoemacs :modifier-desc (nth 0 elt))
(ergoemacs :unicode-or-alt "→" "->")
(ergoemacs :modifier-desc (nth 1 elt))))
trans ", "))) ""))
(maphash
(lambda(key item)
(let ((local-key (where-is-internal key local-keymap t))
tmp)
(when local-key
(setq tmp (format "%s%s%s"
(ergoemacs-key-description local-key)
(if (eq (nth 1 item) :force)
(ergoemacs :unicode-or-alt "⇒" "=>")
(ergoemacs :unicode-or-alt "→" "->"))
(ergoemacs :modifier-desc (nth 0 item))))
(push (elt local-key 0) mod-keys)
(setq keys (or (and (not keys) tmp)
(and keys (concat keys ", " tmp)))))))
ergoemacs-command-loop--next-key-hash)
(setq keys (or (and keys (concat "\nKeys: " keys)) ""))
(setq unchorded (or (and unchorded (concat " " (ergoemacs :modifier-desc unchorded))) ""))
(while (not input)
(while (not input)
(setq blink-on (not blink-on)
input (ergoemacs-command-loop--read-event
(format
"%s" (concat
ergoemacs-command-loop--read-key-prompt
(ergoemacs-command-loop--read-key-help-text-prefix-argument blink-on universal)
text
(ergoemacs-key-description current-key)
unchorded
;; Cursor
(or (and (string= ergoemacs-command-loop--read-key-prompt "") "") " ")
(or (and universal "")
(and ergoemacs-command-loop-blink-character
(or (and blink-on (ergoemacs :unicode-or-alt ergoemacs-command-loop-blink-character "-"))
" "))
" ")
trans
keys))
current-key)))
(cond
((and (setq trans (or (and (memq input mod-keys)
(ergoemacs-gethash (lookup-key local-keymap (vector input)) ergoemacs-command-loop--next-key-hash))
(setq reset-key-p (ergoemacs-gethash (lookup-key local-function-key-map (ergoemacs :combine current-key input)) ergoemacs-command-loop--next-key-hash))))
(or (eq :force (nth 1 trans)) ;; Override any keys
(not (key-binding (vconcat current-key (ergoemacs-translate--event-mods input trans)) t)) ;; Don't use if bound.
))
(setq trans (nth 0 trans)
unchorded (concat " " (ergoemacs :modifier-desc trans))
input nil)
;; Changed behavior.
(while (not input)
(setq blink-on (not blink-on)
input (ergoemacs-command-loop--read-event
(format
"%s" (concat
ergoemacs-command-loop--read-key-prompt
(ergoemacs-command-loop--read-key-help-text-prefix-argument blink-on universal)
text
(or (and reset-key-p "") (ergoemacs-key-description current-key))
unchorded
;; Cursor
(or (and (string= ergoemacs-command-loop--read-key-prompt "") "") " ")
(or (and universal "")
(and ergoemacs-command-loop-blink-character
(or (and blink-on (ergoemacs :unicode-or-alt ergoemacs-command-loop-blink-character "-"))
" "))
" ")
"\n"
"\n"))
current-key)))
(setq raw-input input
input (ergoemacs-translate--event-mods input trans)
last-command-event input
last-input-event input
ergoemacs-last-command-event last-command-event))
(t
;; Translate the key appropriately.
(when (and modal (lookup-key ergoemacs-modal-ignored-keymap (vector input)))
;; Swap back, or ignore the modal translation.
(setq type (ergoemacs-translation-struct-key modal)
local-keymap (ergoemacs-translation-struct-keymap-modal modal)
text (ergoemacs-translation-struct-text modal)
unchorded (ergoemacs-translation-struct-unchorded modal)
trans (ergoemacs-translation-struct-translation modal)
tmp translation
translation modal
modal tmp
tmp nil))
(setq raw-input input
input (ergoemacs-translate--event-mods input type)
last-command-event input
last-input-event input
ergoemacs-last-command-event last-command-event)))
(cond
((and input (not universal)
(not (key-binding (ergoemacs :combine current-key raw-input)))
(and local-keymap
(memq (lookup-key local-keymap (vector raw-input))
ergoemacs-command-loop--universal-functions)))
(setq universal t
raw-input nil
input nil
ergoemacs-command-loop--echo-keystrokes-complete t))
((and raw-input universal) ;; Handle universal arguments.
(setq ergoemacs-command-loop--echo-keystrokes-complete t)
(cond
((eq raw-input 45) ;; Negative argument
(cond
((integerp current-prefix-arg)
(setq current-prefix-arg (- current-prefix-arg)))
((eq current-prefix-arg '-)
(setq current-prefix-arg nil))
(t
(setq current-prefix-arg '-)))
(setq raw-input nil
input nil))
((memq raw-input (number-sequence 48 57)) ;; Number
(setq raw-input (- raw-input 48)) ;; Actual Number.
(cond
((and (integerp current-prefix-arg) (< 0 current-prefix-arg))
(setq current-prefix-arg (+ raw-input (* current-prefix-arg 10))))
((and (integerp current-prefix-arg) (> 0 current-prefix-arg))
(setq current-prefix-arg (+ (- raw-input) (* current-prefix-arg 10))))
((and (eq current-prefix-arg '-) (> raw-input 0))
(setq current-prefix-arg (- raw-input)))
(t
(setq current-prefix-arg raw-input)))
(setq input nil
raw-input nil))
((and local-keymap
(memq (lookup-key local-keymap (vector raw-input))
ergoemacs-command-loop--universal-functions)) ;; Toggle to key-sequence.
(setq raw-input nil
universal nil))
((or (memq (key-binding (ergoemacs :combine current-key input) t) ergoemacs-command-loop--universal-functions)
(not (key-binding (ergoemacs :combine current-key raw-input) t))
(and local-keymap (memq (lookup-key local-keymap (vector raw-input)) ergoemacs-command-loop--universal-functions)))
;; Universal argument called.
(cond
((not current-prefix-arg)
(setq current-prefix-arg '(4)
raw-input nil
input nil))
((listp current-prefix-arg)
(setq current-prefix-arg (list (* (nth 0 current-prefix-arg) 4))
raw-input nil
input nil))
(t
(setq universal nil
input nil
raw-input nil))))
((and local-keymap
(memq (lookup-key local-keymap (vector raw-input))
ergoemacs-command-loop--undo-functions))
;; Allow backspace to edit universal arguments.
(cond
((not current-prefix-arg)) ;; Exit universal argument
((and (integerp current-prefix-arg)
(= 0 (truncate current-prefix-arg 10))
(< 0 current-prefix-arg))
(setq current-prefix-arg nil
input nil
raw-input nil))
((and (integerp current-prefix-arg)
(= 0 (truncate current-prefix-arg 10))
(> 0 current-prefix-arg))
(setq current-prefix-arg '-
input nil
raw-input nil))
((integerp current-prefix-arg)
(setq current-prefix-arg (truncate current-prefix-arg 10)
input nil
raw-input nil))
((listp current-prefix-arg)
(setq current-prefix-arg
(list (expt 4 (- (round (log (nth 0 current-prefix-arg) 4)) 1))))
(when (equal current-prefix-arg '(1))
(setq current-prefix-arg nil))
(setq input nil
raw-input nil))
((eq current-prefix-arg '-)
(setq current-prefix-arg nil
input nil
raw-input nil))))))))
;; Return list of raw key, and translated current key
(list (vector raw-input) (ergoemacs :combine (if reset-key-p nil current-key) input))))
(defun ergoemacs-command-loop--listify-key-sequence (key &optional type)
"Return a key sequence from KEY.
TYPE is the keyboard translation type, defined by `ergoemacs-translate'.
This sequence is compatible with `listify-key-sequence'."
(let (input
(type (or type :normal)))
(cond
((not key)) ;; Not specified.
((vectorp key) ;; Actual key sequence
(setq input (listify-key-sequence key)))
((consp key) ;; Listified key sequence
(setq input key))
((stringp key) ;; Kbd code
(setq input (listify-key-sequence (read-kbd-macro key t)))))
(setq input (mapcar
(lambda(elt)
(ergoemacs-translate--event-mods elt type))
input))
input))
(defun ergoemacs-command-loop-p ()
"Determine if `ergoemacs-mode' is running its command loop.
This is done by looking at the current `backtrace' and making
sure that `ergoemacs-command-loop--internal' hasn't been called."
(eq ergoemacs-last-command-event last-command-event))
(defvar ergoemacs-command-loop-start nil)
(defun ergoemacs-command-loop (&optional key type initial-key-type universal)
"Process `ergoemacs-command-loop'.
KEY is the key being read, or sequence being read.
TYPE is the translation being used.
INITIAL-KEY-TYPE ist he key type that is used fot the initial
translation.
UNIVERSAL is if the function will be calling a universal
argument.
The true work is done in `ergoemacs-command-loop--internal'."
(interactive)
(cond
((and ergoemacs-command-loop-start (not (ergoemacs-command-loop-p)))
;; (ergoemacs-command-loop--message "Start ergoemacs-mode command loop." )
(ergoemacs-command-loop--internal key type initial-key-type universal))
(t
(setq ergoemacs-command-loop--exit :ignore-post-command-hook
prefix-arg current-prefix-arg
ergoemacs-command-loop--single-command-keys (or (and key (read-kbd-macro key t))
ergoemacs-command-loop--single-command-keys)
unread-command-events (or (and key (ergoemacs-command-loop--listify-key-sequence key initial-key-type))
unread-command-events)
ergoemacs-command-loop--universal (if (and ergoemacs-command-loop--universal (not universal)) nil
universal)
ergoemacs-command-loop--current-type (or type ergoemacs-command-loop--current-type)))))
(defvar ergoemacs-command-loop--running-pre-command-hook-p nil
"Variable to tell if ergoemacs-command loop is running the `pre-command-hook'.")
(defvar ergoemacs-command-loop--excluded-variables
'(defining-kbd-macro executing-kbd-macro)
"List of variables stopping the command loop.
While these variables are non-nil, the `ergoemacs-command-loop'
will stop and not be started agin.")
(defvar ergoemacs-command-loop--excluded-major-modes
'(calc-mode calc-trail-mode calc-edit-mode)
"List of major modes where the command loop is incompatible.")
(defvar ergoemacs-command-loop--minibuffer-unsupported-p nil)
(defun ergoemacs-command-loop--minibuffer-supported-p (&optional command)
"Determine if the current minibuffer supports the full command loop.
When COMMAND is non-nil, set
`ergoemacs-command-loop--minibuffer-unsupported-p' to the
appropriate value based on the COMMAND."
(if (not command)
(or (not (minibufferp))
(not ergoemacs-command-loop--minibuffer-unsupported-p))
(when (or (and command (symbolp command) (string-match-p "^\\(calc\\|math\\)" (symbol-name command)))
(and (stringp command) (string-match-p "^[^:]*:\\(calc\\|math\\)" command)))
(set (make-local-variable 'ergoemacs-command-loop--minibuffer-unsupported-p) t))
(ergoemacs-command-loop--minibuffer-supported-p)))
(defun ergoemacs-command-loop-full-p ()
"Determines if the full command loop should be run."
(and
(eq ergoemacs-command-loop-type :full)
(ergoemacs-command-loop--minibuffer-supported-p)
(catch 'excluded-variables
(dolist (var ergoemacs-command-loop--excluded-variables)
(when (and var (ergoemacs-sv var))
(throw 'excluded-variables nil)))
t)
(not (memq major-mode ergoemacs-command-loop--excluded-major-modes))))
(defun ergoemacs-command-loop--start-with-pre-command-hook ()
"Start ergoemacs command loop.
This is done by replacing `this-command' with
`ergoemacs-command-loop-start' and then running `this-command'
from within the ergoemacs-mode command loop."
(when (and (not ergoemacs-command-loop--running-pre-command-hook-p)
(ergoemacs-command-loop-full-p)
(not unread-command-events)
(not (ergoemacs-command-loop-p)))
(setq ergoemacs-command-loop-start this-command
ergoemacs-command-loop--single-command-keys (this-single-command-keys)
this-command 'ergoemacs-command-loop-start)))
(add-hook 'ergoemacs-pre-command-hook #'ergoemacs-command-loop--start-with-pre-command-hook)
(defvar ergoemacs-command-loop--internal-end-command-p nil)
(defvar ergoemacs-last-command-was-ergoemacs-ignore-p nil
"Last command was `ergoemacs-ignore'.")
(defun ergoemacs-command-loop--start-with-post-command-hook ()
"Start ergoemacs command loop.
This is done by pushing the key [ergoemacs-ignore] on the
`unread-command-events' stack. This then forces `ergoemacs-mode'
to start with
`ergoemacs-command-loop--start-with-pre-command-hook'."
(when (and (not ergoemacs-command-loop--internal-end-command-p)
(ergoemacs-command-loop-full-p))
(if ergoemacs-last-command-was-ergoemacs-ignore-p
(unless (eq ergoemacs-last-command-was-ergoemacs-ignore-p :idle)
(run-with-idle-timer 0.05 nil (lambda()
(setq ergoemacs-last-command-was-ergoemacs-ignore-p :idle)
(ergoemacs-command-loop-start))))
(push 'ergoemacs-ignore unread-command-events))))
(add-hook 'ergoemacs-post-command-hook #'ergoemacs-command-loop--start-with-post-command-hook)
(defvar ergoemacs-command-loop--point-motion-last-point nil
"Record the last point.")
(defun ergoemacs-command-loop--point-motion-hooks ()
"Emlulate Emacs' command-loop portion of the point-motion hooks.
The properties `point-entered' and `point-left' are handled by C internals."
(unless (or disable-point-adjustment global-disable-point-adjustment inhibit-point-motion-hooks)
;; Only the adjustment of the point in fishy areas is done in the
;; command loop.
(let* ((props '(intangible composition display invisible))
(last-point (or ergoemacs-command-loop--point-motion-last-point (point)))
(cur-point (point))
(found-prop (catch 'found-prop
(dolist (p props)
(when (get-char-property (point) p)
(throw 'found-prop p)))
nil)))
;; Adjust the point in fishy areas.
(when found-prop
(goto-char (or (and (>= cur-point last-point)
(next-single-char-property-change cur-point found-prop))
(previous-single-char-property-change cur-point found-prop)))
(setq last-point cur-point
cur-point (point)))))
(setq disable-point-adjustment nil)
(set (make-local-variable 'ergoemacs-command-loop--point-motion-last-point) (point)))
(defun ergoemacs-command-loop--sync-point ()
"Sometimes the window buffer and selected buffer are out of sync.
Fix this issue."
(unless (eq (current-buffer) (window-buffer))
(ignore-errors (switch-to-buffer (window-buffer) t t))
(goto-char (window-point))))
(defun ergoemacs-command-loop--update-primary-selection ()
"Update primary clipboard in X based systems."
(when (and mouse-drag-copy-region
(eventp last-command-event)
(consp last-command-event)
(memq (event-basic-type (car last-command-event))
'(mouse-1))
(region-active-p))
(ergoemacs :set-selection 'PRIMARY (buffer-substring-no-properties (region-beginning) (region-end)))))
(defun ergoemacs-command-loop--internal-end-command ()
"Simulates the end of a command."
;; Simulate the end of an emacs command, since we are not
;; exiting the loop.
(setq ergoemacs-command-loop--internal-end-command-p t)
(unwind-protect
(run-hooks 'post-command-hook)
(setq ergoemacs-command-loop--internal-end-command-p nil))
;; Deactivate mark.
(when deactivate-mark
(deactivate-mark)
(setq deactivate-mark nil))
;; Create undo-boundary like emacs does.
;; The undo boundary is created every 20 characters.
(when (eq this-command 'self-insert-command)
;; Adapted from `org-self-insert-command'
(if (not (eq last-command 'self-insert-command))
(setq ergoemacs-command-loop--self-insert-command-count 1)
(if (>= ergoemacs-command-loop--self-insert-command-count 20)
(setq ergoemacs-command-loop--self-insert-command-count 1)
(and (> ergoemacs-command-loop--self-insert-command-count 0)
buffer-undo-list (listp buffer-undo-list)
(not (cadr buffer-undo-list)) ; remove nil entry
(setcdr buffer-undo-list (cddr buffer-undo-list)))
(setq ergoemacs-command-loop--self-insert-command-count
(1+ ergoemacs-command-loop--self-insert-command-count))))
;; See: http://stackoverflow.com/questions/6590889/how-emacs-determines-a-unit-of-work-to-undo
;; FIXME:
;; Certain "hairy" insertions (as determined by
;; internal_self_insert) cause an an undo boundary to be added
;; immediately, and the character count to be reset. Reading the
;; code, it looks as though these are: (1) in overwrite-mode, if you
;; overwrote a character with one that has a different width,
;; e.g. typing over a tab; (2) if the character you inserted caused
;; an abbreviation to be expanded; (3) if the character you typed
;; caused auto-fill-mode to insert indentation.
)
;; After executing, the emacs loop should copy `this-command' into
;; `last-command'.
;; It should also change `last-prefix-arg'
(setq last-command this-command
real-last-command this-command ;; Hopefully doesn't throw an error.
last-prefix-arg prefix-arg
current-prefix-arg prefix-arg
prefix-arg nil
this-command nil
deactivate-mark nil
ergoemacs-command-loop--echo-keystrokes-complete nil)
(undo-boundary)
;; This (sort of) fixes `this-command-keys'
;; But it doesn't fix it for keyboard macros.
(clear-this-command-keys t)
(setq ergoemacs-command-loop--decode-event-timeout-p nil)
(ergoemacs-command-loop--sync-point)
(ergoemacs-command-loop--point-motion-hooks)
(ergoemacs-command-loop--update-primary-selection))
(defun ergoemacs-command-loop--mouse-command-drop-first (args &optional fn-arg-p)
"Internal function for processing mouse commands.
This function drops the first argument of a function, which is
usually an event for mouse functions.
ARGS are the function's arguments.
FN-ARG-P can be nil, :drop-rest or :rest"
(let (ret)
(cond
((eq fn-arg-p :drop-rest)
(if (and (<= 2 (length args))
(eq (nth (- (length args) 2) args) '&rest))
(if (= (length args) 2)
nil
(ergoemacs-command-loop--mouse-command-drop-first (butlast args 2)))
(ergoemacs-command-loop--mouse-command-drop-first args)))
((eq fn-arg-p :rest)
(if (and (<= 2 (length args))
(eq (nth (- (length args) 2) args) '&rest))
(nth (- (length args) 1) args)
nil))
((eq (car args) '&rest)
;;(&rest arg)
(if fn-arg-p args
(cdr args)))
((eq (car args) '&optional)
;;(&optional ...)
(if fn-arg-p
(cond
((not (cdr (cdr args)))
;; (&optional arg) -> nil
nil)
((eq '&rest (car (cdr (cdr args))))
;; (&optional arg &rest rest) -> (&rest rest)
(cdr (cdr args)))
(t
;; (&optional arg1 arg2 &rest rest)-> (&optional arg2 &rest rest)
;; (&optional arg1 arg2 arg3)-> (&optional arg2 arg3)
`(&optional ,@(cdr (cdr args)))))
(dolist (a (cdr (cdr args)))
(unless (eq a '&rest)
(push a ret)))
(reverse ret)))
(t
(if fn-arg-p
(cdr args)
(dolist (a (cdr args))
(unless (memq a '(&rest &optional))
(push a ret)))
(reverse ret))))))
(defun ergoemacs-command-loop--modify-mouse-command (command)
"Modify mouse COMMAND to work with ergoemacs command loop."
(let* ((iform (interactive-form command))
(form (and iform (consp iform) (= 2 (length iform)) (stringp (nth 1 iform)) (nth 1 iform)))
(args (help-function-arglist command t))
(fn-args (ergoemacs-command-loop--mouse-command-drop-first args t))
(strip-args (ergoemacs-command-loop--mouse-command-drop-first args))
(rest-p (ergoemacs-command-loop--mouse-command-drop-first args :rest))
(drop-rest (ergoemacs-command-loop--mouse-command-drop-first args :drop-rest))
(select-window-p (and form (string-match-p "^[*^]*[@]" form)))
(event-p (and form (string-match-p "^[*@^]*e" form)))
(new-form (and form
(or (and (not event-p) form)
(and event-p (replace-regexp-in-string "^\\([*@^]*\\)e\n*\\(.*\\)" "\\1\\2" form))))))
(when (and new-form (string= new-form ""))
(setq new-form nil))
(cond
((not event-p)
command)
(rest-p
`(lambda ,fn-args
,(if new-form
`(interactive ,new-form)
`(interactive))
,(when select-window-p
'(select-window (posn-window (event-start last-command-event))))
(if ,rest-p
(apply ',command last-command-event ,@strip-args)
(,command last-command-event ,@drop-rest))
(ergoemacs-command-loop--execute-modify-command-list ',command)))
((not rest-p)
`(lambda ,fn-args
,(if new-form
`(interactive ,new-form)
`(interactive))
,(when select-window-p
'(select-window (posn-window (event-start last-command-event))))
(,command last-command-event ,@strip-args)
(ergoemacs-command-loop--execute-modify-command-list ',command))))))
(defun ergoemacs-command-loop--call-mouse-command (command &optional record-flag keys)
"Call a possible mouse COMMAND.
The COMMAND is modified to take out any event information and
replace it with `last-event-command' information. This
modifciation isd one by
`ergoemacs-command-loop--modify-mouse-command'.
Mouse commands are also wrapped in `ignore-errors'. This takes
care of `window-live-p' errors that occur when running the
Emacs detects keys when outside of Emacs.
The RECORD-FLAG and KEYS arguments are passed to
`ergoemacs-command-loop--grow-interactive' for the mouse command."
(cond
((ergoemacs-keymapp command)
(popup-menu command nil current-prefix-arg))
(t
(ignore-errors
(ergoemacs-command-loop--grow-interactive (ergoemacs-command-loop--modify-mouse-command command) record-flag keys)))))
(defvar ergoemacs-command-loop-describe-key-functions
'(describe-key describe-function)
"Functions like `describe-key'.
These functions will:
- Replace `key-description' with `ergoemacs-key-description'.
- Replace `read-key-sequence' with `ergoemacs-command-loop--read-key-sequence'.")
(defcustom ergoemacs-comand-loop-grow-max-sizes-p t
"Grow the max sizes if needed.
This grows `max-specpdl-size' and `max-lisp-eval-depth' if
`ergoemacs-command-loop--call-interactively' throws an error
about `max-specpdl-size' or `max-lisp-eval-depth'.
The overall maximum that these are set to are controlled by
`ergoemacs-max-specpdl-size' and
`ergoemacs-max-lisp-eval-depth.'"
:type 'boolean
:group 'ergoemacs-mode)
(defvar ergoemacs-command-loop--grow-command nil)
(defvar ergoemacs-command-loop--grow-record nil)
(defvar ergoemacs-command-loop--grow-keys nil)
(defvar ergoemacs-command-loop--grow-special nil)
(defcustom ergoemacs-max-specpdl-size (* 8 max-specpdl-size)
"Maximum `max-specpdl-size' that `ergoemacs-mode' increases to..."
:type 'boolean
:group 'ergoemacs-mode)
(defcustom ergoemacs-max-lisp-eval-depth (* 8 max-lisp-eval-depth)
"Maximum `max-lisp-eval-depth' that `ergoemacs-mode' increases to..."
:type 'boolean
:group 'ergoemacs-mode)
(defcustom ergoemacs-command-loop-dont-grow-commands
'(org-agenda)
"List of commands where the command loop will not adjust sizes."
:type '(repeat (sexp :tag "Command"))
:group 'ergoemacs-mode)
(defun ergoemacs-command-loop--grow-interactive (command &optional record-flag keys)
"Call the COMMAND interactively.
The RECORD-FLAG and KEYS are sent to `ergoemacs--real-call-interactively'.
This will grow `max-lisp-eval-depth' and `max-specpdl-size' if
needed (and resotre them to the original values)."
(setq ergoemacs-command-loop--grow-command nil
ergoemacs-command-loop--grow-record nil
ergoemacs-command-loop--grow-keys nil
ergoemacs-command-loop--grow-special nil)
(if (memq command ergoemacs-command-loop-dont-grow-commands)
(call-interactively command record-flag keys)
(let ((grow-max-lisp-p t)
(orig-max-specpdl-size max-specpdl-size)
(orig-max-lisp-eval-depth max-lisp-eval-depth))
(while grow-max-lisp-p
(condition-case err
(cond
(ergoemacs-command-loop--grow-command
(command-execute ergoemacs-command-loop--grow-command
ergoemacs-command-loop--grow-record
ergoemacs-command-loop--grow-keys
ergoemacs-command-loop--grow-special)
(setq grow-max-lisp-p nil))
(t
(call-interactively command record-flag keys)
(setq grow-max-lisp-p nil)))
(error
(if (and (consp err)
(eq (car err) 'error)
(stringp (nth 1 err))
(string-match "max-specpdl-size\\|max-lisp-eval-depth"
(nth 1 err))
ergoemacs-comand-loop-grow-max-sizes-p
(<= max-specpdl-size ergoemacs-max-specpdl-size)
(<= max-lisp-eval-depth ergoemacs-max-lisp-eval-depth))
(progn
(setq max-specpdl-size (* 2 max-specpdl-size)
max-lisp-eval-depth (* 2 max-lisp-eval-depth))
(ergoemacs-warn "Increased max-specpdl-size to %s and max-lisp-eval-depth to %s for %s"
max-specpdl-size max-lisp-eval-depth command))
(setq grow-max-lisp-p nil
max-specpdl-size orig-max-specpdl-size
max-lisp-eval-depth orig-max-lisp-eval-depth)
(if (and err (consp err))
(signal (car err) (cdr err))
(signal err "Unknown error"))))))
(setq max-specpdl-size orig-max-specpdl-size
max-lisp-eval-depth orig-max-lisp-eval-depth))))
(defun ergoemacs-command-loop--call-interactively (command &optional record-flag keys)
"Call the COMMAND interactively. Also handle mouse events (if possible.)
The RECORD-FLAG and KEYS are sent to `ergoemacs-command-loop--grow-interactive'."
(ergoemacs-command-loop--sync-point)
(setq ergoemacs-last-command-was-ergoemacs-ignore-p nil)
(cond
((and (eventp last-command-event)
(consp last-command-event)
(memq (event-basic-type (car last-command-event))
'(mouse-1 mouse-2 mouse-3 mouse-4 mouse-5 mouse-6 mouse-7 mouse-8 mouse-9)))
(ergoemacs-command-loop--call-mouse-command command record-flag keys))
((and (symbolp command) (not (fboundp command)))
(ergoemacs-command-loop--message "Command `%s' is not found" command))
((and (symbolp command) (not (commandp command)))
(ergoemacs-command-loop--message "Command `%s' cannot be called from a key" command))
((and (consp ergoemacs-command-loop-describe-key-functions)
(memq command ergoemacs-command-loop-describe-key-functions))
(ergoemacs-specials
(ergoemacs-command-loop--grow-interactive command record-flag keys)))
(t
(ergoemacs-command-loop--grow-interactive command record-flag keys))))
(defun ergoemacs-command-loop-start ()
"Start `ergoemacs-command-loop'."
(interactive)
;; Should work...
(unless ergoemacs-command-loop-start
(setq ergoemacs-command-loop-start t))
(ergoemacs-command-loop))
(defvar ergoemacs-command-loop--spinner nil)
(defvar ergoemacs-command-loop--spinner-i nil)
(defvar ergoemacs-command-loop--spinner-list nil)
(defvar ergoemacs-command-loop-spinner)
(defvar ergoemacs-command-loop-spinners)
(defvar ergoemacs-command-loop--spinner-display-message nil
"Use spinner messages with history.")
(defvar ergoemacs-command-loop--message-log-max nil
"Determine `message-log-max' for `ergoemacs-command-loop--message'.")
(defcustom ergoemacs-message-level :start
"Message Level for `ergoemacs-mode'."
:type '(choice
(const :tag "No ergoemacs-mode messages" nil)
(const :tag "New ergoemacs-mode messages" :new)
(const :tag "Mesages on startup" :start)
(const :tag "Maximum debugging messages" :max))
:group 'ergoemacs-mode)
(defvar ergoemacs-command-loop--spinner-display :max
"Variable to control level of spinner display.")
(defun ergoemacs-command-loop--spinner-display (&optional string &rest args)
"Spinner display.
Display STRING with a spinner pre-pended. Additional
arguments (ARGS) will be applied with `format'.
STRING can also be a list of strings. The string selected for
use with `format' will be selecting using
`ergoemacs-key-description--unicode-char'.
STRING can also be a symbol representing the level of message to
be displayed. This is used in conjunction with
`ergoemacs-message-level' to only display messages that should be
displayed. When the message should be displayed addional ARGS
are then passed to `ergoemacs-command-loop--spinner-display'
instead of `format'."
(prog1 t
(if (symbolp string)
(cond
((eq ergoemacs-message-level :max)
(apply #'ergoemacs-command-loop--spinner-display args))
((and (eq string :start) ergoemacs-mode-started-p))
((and (eq string :start) (not ergoemacs-mode-started-p))
(setq ergoemacs-message-level :max)
(unwind-protect
(apply #'ergoemacs-command-loop--spinner-display args))
(setq ergoemacs-message-level :start))
((and (eq string :new)
(memq ergoemacs-message-level '(:new)))
(setq ergoemacs-command-loop--spinner-display :new)
(unwind-protect
(apply #'ergoemacs-command-loop--spinner-display args))
(setq ergoemacs-command-loop--spinner-display :max)))
(when (eq ergoemacs-message-level ergoemacs-command-loop--spinner-display)
(let* ((string (or (and (listp string)
(eq (car string) 'quote)
(eval string))
string))
(rest (or (and (listp string)
(concat " " (apply #'format (apply #'ergoemacs-key-description--unicode-char string) args)))
(and (not string) "")
(concat " " (apply #'format string args))))
(ergoemacs-command-loop--message-log-max (and ergoemacs-command-loop--spinner-display-message message-log-max)))
(when (not ergoemacs-command-loop--spinner-list)
(setq ergoemacs-command-loop--spinner-list (nth 1 (assoc ergoemacs-command-loop-spinner ergoemacs-command-loop-spinners))
ergoemacs-command-loop--spinner-i 0))
(ergoemacs-command-loop--message "%s%s" (nth (mod (setq ergoemacs-command-loop--spinner-i (+ 1 ergoemacs-command-loop--spinner-i))
(length ergoemacs-command-loop--spinner-list)) ergoemacs-command-loop--spinner-list)
rest))))))
(defun ergoemacs-command-loop--spinner-end ()
"Cancel the `ergoemacs-command-loop--spinner' timer."
(when ergoemacs-command-loop--spinner
(cancel-timer ergoemacs-command-loop--spinner)
(setq ergoemacs-command-loop--spinner-list nil
ergoemacs-command-loop--spinner nil
ergoemacs-command-loop--spinner-i nil)))
(defvar ergoemacs-command-loop--this-command-keys (symbol-function 'this-command-keys))
(defun ergoemacs-command-loop--this-command-keys ()
"Return `ergoemacs-command-loop--single-command-keys'.
Used to replace:
- `this-command-keys-vector'
- `this-command-keys'
- `this-single-command-keys'
- `this-single-command-raw-keys'
Currently these are all vectors and all ingore prefix arguments.
They don't exactly behave like their Emacs equivalents."
(or (and ergoemacs-mode ergoemacs-command-loop--single-command-keys)
(funcall ergoemacs-command-loop--this-command-keys)))
(defvar ergoemacs-command-loop--timer nil
"Timer to startup `ergoemacs-mode' command loop.")
(defun ergoemacs-command-loop--timer ()
"Start `ergoemacs-command-loop--internal' if not currently running."
(unless (and (ergoemacs-command-loop-full-p)
(ergoemacs-command-loop-p))
(ergoemacs-command-loop--internal)))
(defun ergoemacs-command-loop--install-timer ()
"Install the `ergoemacs-command-loop--timer'."
(setq ergoemacs-command-loop--timer
(run-with-idle-timer 0.05 nil #'ergoemacs-command-loop--timer)))
(defun ergoemacs-command-loop--remove-timer ()
"Remove `ergoemacs-command-loop--timer'."
(when ergoemacs-command-loop--timer
(cancel-timer ergoemacs-command-loop--timer)
(setq ergoemacs-command-loop--timer nil)))
(add-hook 'ergoemacs-mode-startup-hook #'ergoemacs-command-loop--install-timer)
(add-hook 'ergoemacs-mode-shutdown-hook #'ergoemacs-command-loop--remove-timer)
(defun ergoemacs-command-loop--ignore (&rest _ignore)
"Do nothing and return nil.
This function accepts any number of arguments, but ignores them.
Unlike `ignore', this command pretends `ergoemacs-command-loop--ignore' command was never
run, by changing `this-command' to `last-command'"
(interactive)
(setq ergoemacs-last-command-was-ergoemacs-ignore-p t)
(ergoemacs-command-loop--execute-modify-command-list last-command)
;; FIXME: Somehow change the output of `this-single-command-raw-keys'
nil)
(defun ergoemacs-command-loop--read-key-sequence (prompt &rest _ignore)
"Read key sequence in ergoemacs-mode with PROMPT.
Ignore all the other options."
(let ((old ergoemacs-command-loop-type)
(old-prompt ergoemacs-command-loop--read-key-prompt)
ret)
(setq ergoemacs-command-loop-type :read-key-sequence
ergoemacs-command-loop--read-key-prompt prompt)
(unwind-protect
(setq ret (ergoemacs-command-loop--internal))
(setq ergoemacs-command-loop-type old
ergoemacs-command-loop--read-key-prompt old-prompt))
ret))
(defun ergoemacs-command-loop--internal (&optional key type initial-key-type universal)
"Read keyboard input and execute command.
The KEY is the keyboard input where the reading begins. If nil,
read the whole keymap.
TYPE is the keyboard translation type, defined by `ergoemacs-translate'
Ergoemacs-mode sets up: :ctl-to-alt :unchorded :normal.
INITIAL-KEY-TYPE represents the translation type for the initial KEY.
UNIVERSAL allows ergoemacs-read-key to start with universal
argument prompt.
While in the loop, every command resets the keys typed every time
a command is completed (by `clear-this-command-keys')
Also in the loop, `universal-argument-num-events' is set to
0. (Allows commands like `isearch' to work correctly in older
Emacs versions)."
(interactive)
(when ergoemacs-mode
(ergoemacs-command-loop--execute-rm-keyfreq 'ergoemacs-command-loop)
;; Call the startup command
(when (commandp ergoemacs-command-loop-start)
(ergoemacs-command-loop--call-interactively ergoemacs-command-loop-start)
(ergoemacs-command-loop--internal-end-command))
;; Replace functions temporarily
(cl-letf (((symbol-function 'this-command-keys) #'ergoemacs-command-loop--this-command-keys)
((symbol-function 'this-single-command-keys) #'ergoemacs-command-loop--this-command-keys)
((symbol-function 'this-command-keys-vector) #'ergoemacs-command-loop--this-command-keys)
((symbol-function 'this-single-command-raw-keys) #'ergoemacs-command-loop--this-command-keys)
;; ((symbol-function 'read-key-sequence) #'ergoemacs-command-loop--read-key-sequence)
)
(let* ((type (or type :normal))
(from-start-p ergoemacs-command-loop-start)
(continue-read t)
(first-type type)
raw-key current-key last-current-key
(translation (ergoemacs-translate--get type))
(local-keymap (ergoemacs-translate--keymap translation))
modal-p
tmp command)
(unwind-protect
(progn
;; Set these to nil when entering the command loop;
;;
;; For some reason `inhibit-point-motion-hooks' on emacs
;; 25.1 is t when the command loop is entered.
;;
;; To allow the point motion hooks to work as
;; advertised, set these on starting the command loop.
(setq inhibit-point-motion-hooks nil
disable-point-adjustment nil
global-disable-point-adjustment nil)
;; Setup initial unread command events, first type and history
(setq tmp (ergoemacs-command-loop--listify-key-sequence key initial-key-type)
unread-command-events (or (and unread-command-events tmp (append tmp unread-command-events)) tmp)
ergoemacs-command-loop--first-type first-type
ergoemacs-command-loop--history nil
ergoemacs-command-loop-start nil)
(while continue-read
(setq ergoemacs-last-command-was-ergoemacs-ignore-p nil)
(unless (eq ergoemacs-command-loop-type :read-key-sequence)
(setq inhibit-quit t))
(while continue-read
(setq ergoemacs-last-command-was-ergoemacs-ignore-p nil)
;; Read key
(setq ergoemacs-command-loop--single-command-keys current-key
ergoemacs-command-loop--current-type type
ergoemacs-command-loop--universal universal
raw-key (ergoemacs-command-loop--read-key
current-key
(or (and unread-command-events :normal) type)
(and (not unread-command-events) universal))
ergoemacs-command-loop--single-command-keys nil
universal-argument-num-events 0
last-current-key current-key
current-key (nth 1 raw-key)
raw-key (nth 0 raw-key)
continue-read nil)
(when (setq modal-p (ergoemacs :modal-p))
(setq local-keymap (ergoemacs-translation-struct-keymap-modal modal-p)))
(cond
;; Handle quit commands
((and last-current-key
(or (lookup-key ergoemacs-map--quit-map raw-key)
(and (equal raw-key [27])
(lookup-key ergoemacs-map--quit-map [escape]))))
(ergoemacs-command-loop--message
"Key sequence %s aborted by %s"
(ergoemacs-key-description last-current-key)
(ergoemacs-key-description raw-key))
(setq quit-flag t))
;; Handle local commands.
((and (or modal-p
(not (equal current-key raw-key)))
(setq command (lookup-key local-keymap raw-key))
(not (ergoemacs-keymapp command)) ;; Ignore locally
;; Already handled by `ergoemacs-command-loop--read-key'
(not (ergoemacs-gethash command ergoemacs-command-loop--next-key-hash))
;; If a command has :ergoemacs-local property of :force, don't
;; worry about looking up a key, just run the function.
(or modal-p
(and (symbolp command) (eq (get command :ergoemacs-local) :force))
(not (key-binding current-key t))))
(pop ergoemacs-command-loop--history) ;; Don't recored local events
(setq ergoemacs-command-loop--single-command-keys last-current-key
universal-argument-num-events 0
ergoemacs-command-loop--current-type type
ergoemacs-command-loop--universal universal
ergoemacs-command-loop--exit nil)
(unless (eq ergoemacs-command-loop-type :test)
(setq tmp this-command
this-command command)
(ergoemacs-command-loop--call-interactively this-command)
(setq command this-command
this-command tmp))
;; If the command changed anything, fix it here.
(unless (equal type ergoemacs-command-loop--current-type)
(setq type ergoemacs-command-loop--current-type
translation (ergoemacs-translate--get type)
local-keymap (ergoemacs-translate--keymap translation)))
(setq current-key ergoemacs-command-loop--single-command-keys
universal ergoemacs-command-loop--universal
ergoemacs-command-loop--single-command-keys nil
continue-read (not ergoemacs-command-loop--exit)))
;; Handle any keys that are bound in some translatable way.
((setq command (ergoemacs-command-loop--key-lookup current-key))
;; Setup external indicators of how the loop currently behaves.
(setq ergoemacs-command-loop--single-command-keys current-key
universal-argument-num-events 0
ergoemacs-command-loop--current-type type
ergoemacs-command-loop--universal nil
ergoemacs-command-loop--exit t)
(if (setq continue-read (and (not (and (consp (aref current-key 0))
(memq (event-basic-type (car (aref current-key 0)))
'(mouse-1 mouse-2 mouse-3 mouse-4 mouse-5 mouse-6 mouse-7 mouse-8 mouse-9))))
(ergoemacs-keymapp command)))
(setq universal nil)
(unless (memq ergoemacs-command-loop-type '(:test :read-key-sequence))
(with-local-quit
(ergoemacs-command-loop--execute command)))
(when quit-flag
(ergoemacs-command-loop--message "Quit!"))
;; Change any information (if needed)
(unless (equal type ergoemacs-command-loop--current-type)
(setq type ergoemacs-command-loop--current-type
translation (ergoemacs-translate--get type)
local-keymap (ergoemacs-translate--keymap translation)))
(when (eq ergoemacs-command-loop-type :read-key-sequence)
(setq ergoemacs-command-loop--exit t
continue-read nil
command current-key))
(setq current-key ergoemacs-command-loop--single-command-keys
universal ergoemacs-command-loop--universal
ergoemacs-command-loop--single-command-keys nil
continue-read (not ergoemacs-command-loop--exit)
current-prefix-arg (if ergoemacs-command-loop--universal current-prefix-arg prefix-arg))
(when (and (not continue-read)
(eq ergoemacs-command-loop--exit :ignore-post-command-hook))
(setq continue-read t)))
(when (or (not ergoemacs-command-loop--exit)
(and (not continue-read) (setq continue-read unread-command-events)))
(ergoemacs-command-loop--internal-end-command)))
(quit-flag
(ergoemacs-command-loop--message "Quit!")
(setq quit-flag nil
type :normal
first-type :normal
raw-key nil
current-key nil
translation (ergoemacs-translate--get type)
local-keymap (ergoemacs-translate--keymap translation)
ergoemacs-command-loop--first-type first-type
ergoemacs-command-loop--history nil))
((consp (aref current-key 0))) ;; don't complain about mouse keys
(t ;; Command not found exit.
(ergoemacs-command-loop--message "Key %s doesn't do anything." (ergoemacs-key-description current-key)))))
(unless quit-flag
(ergoemacs-command-loop--internal-end-command))
(setq quit-flag nil
type :normal
continue-read (or unread-command-events (and from-start-p (ergoemacs-command-loop-full-p)))
first-type :normal
raw-key nil
current-key nil
translation (ergoemacs-translate--get type)
local-keymap (ergoemacs-translate--keymap translation)
ergoemacs-command-loop--first-type first-type
ergoemacs-command-loop--history nil)
(when (or (not ergoemacs-mode) (eq :read-key-sequence ergoemacs-command-loop-type))
(setq continue-read nil)))
(setq inhibit-quit nil)))
command))))
(defcustom ergoemacs-message-in-mode-line t
"Display ergoemacs information in mode-line."
:type 'boolean
:group 'ergoemacs-mode)
(defconst ergoemacs-command-loop--mode-line-format
'(:eval (ergoemacs-command-loop--update-mode-line)))
(defvar ergoemacs-command-loop--update-mode-line nil
"Message to display in mode-line.")
(defun ergoemacs-command-loop--update-mode-line ()
"Update mode line.
This displays `ergoemacs-command-loop--update-mode-line' in the mode line."
(or (and ergoemacs-command-loop--update-mode-line
(concat ergoemacs-command-loop--update-mode-line " ")) ""))
(defun ergoemacs-command-loop--mode-line-not-set-p ()
"Is the `ergoemacs-mode' mode line present?"
(and (listp mode-line-format)
(member ergoemacs-command-loop--mode-line-format mode-line-format)))
(defun ergoemacs-command-loop--reset-mode-line ()
"Reset the mode line."
(when (and ergoemacs-message-in-mode-line (ergoemacs-command-loop--mode-line-not-set-p))
(setq mode-line-format (delete ergoemacs-command-loop--mode-line-format mode-line-format))
(force-mode-line-update)))
(defun ergoemacs-command-loop--refresh-mode-line ()
"Update mode line."
(when (and ergoemacs-message-in-mode-line
(not (ergoemacs-command-loop--mode-line-not-set-p)))
(setq mode-line-format (cons ergoemacs-command-loop--mode-line-format mode-line-format)))
(when ergoemacs-message-in-mode-line
(force-mode-line-update)))
(defun ergoemacs-command-loop--mode-line-message (&rest args)
"Message in mode-line.
ARGS are applied with `format'."
(setq ergoemacs-command-loop--update-mode-line
(apply #'format args))
(ergoemacs-command-loop--refresh-mode-line)
(run-with-timer minibuffer-message-timeout nil
#'ergoemacs-command-loop--reset-mode-line))
(defvar ergoemacs-command-loop-message-sit-for 3
"Command loop message sit for.")
(defun ergoemacs-command-loop--message (str &rest args)
"Message facility for `ergoemacs-mode' command loop.
STR is the formatting string and ARGS are the arguments applied
to the `format' like: (format str args)."
(setq ergoemacs-command-loop--last-event-time (float-time))
(cond
((string= str ""))
((or (minibufferp) isearch-mode)
(apply #'ergoemacs-command-loop--mode-line-message
(append (list str) args)))
(t
(let ((message-log-max ergoemacs-command-loop--message-log-max))
(apply #'message (append (list str) args))))))
(defvar ergoemacs-command-loop--temp-message-timer-secs 0.5
"Timer to ensure minibuffer isn't active.")
(defvar ergoemacs-command-loop--temp-message-timer nil
"Timer to ensure minibuffer isn't active.")
(defvar ergoemacs-command-loop--temp-message-timer-str nil
"Message string.")
(defun ergoemacs-command-loop--temp-message-timer-echo ()
"Echos `ergoemacs-command-loop--temp-message-timer-str' if minibuffer isn't active."
(if (or (minibufferp) isearch-mode)
(setq ergoemacs-command-loop--temp-message-timer
(run-with-idle-timer ergoemacs-command-loop--temp-message-timer-secs
nil #'ergoemacs-command-loop--temp-message-timer-echo))
(cancel-timer ergoemacs-command-loop--temp-message-timer)
(let (message-log-max)
(with-temp-message ergoemacs-command-loop--temp-message-timer-str
(sit-for (or (and (numberp ergoemacs-command-loop-message-sit-for) ergoemacs-command-loop-message-sit-for) 2))))))
(defun ergoemacs-command-loop--temp-message (str &rest args)
"Message facility for `ergoemacs-mode' command loop.
STR is the format string
ARGS is the format arguments
These are passed to `format' as (format str args)."
(setq ergoemacs-command-loop--last-event-time (float-time))
(cond
((string= str ""))
((or (minibufferp) isearch-mode)
(apply #'ergoemacs-command-loop--mode-line-message
(append (list str) args)))
(t
(setq ergoemacs-command-loop--temp-message-timer-str (apply #'format (append (list str) args))
ergoemacs-command-loop--temp-message-timer
(run-with-idle-timer ergoemacs-command-loop--temp-message-timer-secs
nil #'ergoemacs-command-loop--temp-message-timer-echo)))))
;; (2) Key sequence translated to command
(defun ergoemacs-command-loop--message-binding (key &optional lookup translated-key)
"Optionally messages information about the translation.
KEY is the original key.
LOOKUP is what will be run.
TRANSLATED-KEY is what the assumed key is actually bound."
(cond
((and lookup (ergoemacs-keymapp lookup)))
((consp (elt key 0))) ;; Don't message mouse translations
((and (or (eq ergoemacs-echo-function :multi-key)
(not (and translated-key (eq ergoemacs-echo-function :on-translation)))
(not (eq ergoemacs-echo-function t)))
(vectorp key) (or (= (length key) 1) ;; Don't message single keys
(and (eq 27 (elt key 0)) (= (length key) 2)))))
((and lookup
(or (eq ergoemacs-echo-function t)
(and translated-key (eq ergoemacs-echo-function :on-translation))
(eq ergoemacs-echo-function :multi-key)))
(ergoemacs-command-loop--temp-message "%s%s%s%s"
(ergoemacs-key-description key)
(ergoemacs :unicode-or-alt "→" "->")
lookup
(or (and translated-key
(format " (from %s)" (ergoemacs-key-description translated-key)))
"")))
((not lookup)
(ergoemacs-command-loop--temp-message "%s is undefined!"
(ergoemacs-key-description key)))
((and ergoemacs-echo-function
(not (or (= (length key) 1) ;; Clear command completing message
(and (eq 27 (elt key 0)) (= (length key) 2)))))
(ergoemacs-command-loop--message ""))))
(defun ergoemacs-command-loop--key-lookup (key)
"Find the KEY's function based on current bindings.
If `ergoemacs-mode' has translated this, make Emacs think you
pressed the translated key by changing
`ergoemacs-command-loop--single-command-keys'."
(if (and (vectorp key)
(consp (aref key 0))
(memq (event-basic-type (car (aref key 0)))
'(mouse-1 mouse-2 mouse-3 mouse-4 mouse-5 mouse-6 mouse-7 mouse-8 mouse-9)))
(let* ((event (aref key 0))
(posn (car (cdr last-command-event)))
(area (and posn (ergoemacs-posnp posn) (posn-area posn)))
(obj (and posn (ergoemacs-posnp posn) (posn-object posn)))
(original-command (key-binding key t))
command tmp)
;; From `read-key-sequence':
;; /* Clicks in non-text areas get prefixed by the symbol
;; in their CHAR-ADDRESS field. For example, a click on
;; the mode line is prefixed by the symbol `mode-line'.
;; Furthermore, key sequences beginning with mouse clicks
;; are read using the keymaps of the buffer clicked on, not
;; the current buffer. So we may have to switch the buffer
;; here.
;; When we turn one event into two events, we must make sure
;; that neither of the two looks like the original--so that,
;; if we replay the events, they won't be expanded again.
;; If not for this, such reexpansion could happen either here
;; or when user programs play with this-command-keys. */
;;
;; /* Arrange to go back to the original buffer once we're
;; done reading the key sequence. Note that we can't
;; use save_excursion_{save,ore} here, because they
;; save point as well as the current buffer; we don't
;; want to save point, because redisplay may change it,
;; to accommodate a Fset_window_start or something. We
;; don't want to do this at the top of the function,
;; because we may get input from a subprocess which
;; wants to change the selected window and stuff (say,
;; emacsclient). */
(when area
(setq command (key-binding (vconcat (list area event)) t))
(when (and obj (consp obj)
(setq tmp (ignore-errors (get-text-property (cdr obj) 'local-map (car obj))))
(setq tmp (or (and (symbolp tmp) (ergoemacs-sv tmp)) tmp))
(ergoemacs-keymapp tmp)
(setq tmp (lookup-key tmp (vconcat (list area event)))))
(setq command tmp)))
(unless command
(setq command original-command))
;; (ergoemacs-command-loop--call-mouse-command command record-flag keys)
command)
;; Make sure to lookup the keys in the selected buffer
(ergoemacs-command-loop--sync-point)
(let ((trials (ergoemacs-translate--trials key))
tmp tmp2 ret)
(setq this-command-keys-shift-translated nil)
(catch 'found-command
(dolist (cur-key trials)
(when cur-key
(let* ((orig-key cur-key)
(bind (key-binding orig-key t))
(meta-key (ergoemacs-translate--meta-to-escape cur-key))
(esc-key (ergoemacs-translate--escape-to-meta cur-key))
(new-key (or meta-key esc-key))
(new-binding (and new-key (key-binding new-key)))
(global (and new-key
(list (lookup-key ergoemacs-keymap orig-key t)
(lookup-key ergoemacs-keymap new-key t)))))
;; Prefer non-global keys.
(when (eq bind 'undefined)
(setq bind nil))
(when (eq new-binding 'undefined)
(setq new-binding nil))
(cond
((not new-key)
(setq new-key orig-key))
((not (memq bind global))
(setq new-key orig-key))
((and new-binding (not (memq new-binding global)))
(setq bind new-binding)))
(unless bind
(cond
((or (ergoemacs-keymapp (setq tmp (lookup-key input-decode-map orig-key)))
(and (not (integerp tmp)) (commandp tmp)))
(setq bind tmp))
((or (ergoemacs-keymapp (setq tmp (lookup-key local-function-key-map orig-key)))
(and (not (integerp tmp)) (commandp tmp)))
(setq bind tmp))
((or (ergoemacs-keymapp (setq tmp (lookup-key key-translation-map orig-key)))
(and (not (integerp tmp)) (commandp tmp)))
(setq bind tmp))))
(when (and orig-key
(setq ret bind
ret (if (and (eq ret 'ergoemacs-map-undefined)
(equal orig-key (nth 0 trials))
(nth 1 trials)) nil ret)))
(cond
((equal orig-key (nth 0 trials))
(setq ergoemacs-command-loop--single-command-keys new-key)
;; (message "History %s" (length ergoemacs-command-loop--history))
(when (and (not (eq ergoemacs-handle-ctl-c-or-ctl-x 'only-C-c-and-C-x))
(ergoemacs-keymapp ret)
(setq tmp (lookup-key ret [ergoemacs-timeout])))
(cond
((eq ergoemacs-handle-ctl-c-or-ctl-x 'only-copy-cut)
(setq ret tmp))
((< 1 (length ergoemacs-command-loop--history)))
((not (region-active-p))) ;; its a key sequence.
((and this-command-keys-shift-translated
(eq ergoemacs-handle-ctl-c-or-ctl-x 'both)))
;; Immediate
((and (not ergoemacs-ctl-c-or-ctl-x-delay)
(eq ergoemacs-handle-ctl-c-or-ctl-x 'both))
(setq ret tmp))
(t ;; with delay
(if ergoemacs-command-loop--decode-event-timeout-p
(setq tmp2 nil
ergoemacs-command-loop--decode-event-timeout-p nil))
(setq tmp2 (with-timeout (ergoemacs-ctl-c-or-ctl-x-delay nil)
(ergoemacs-command-loop--read-event nil key)))
(if (not tmp2)
(setq ret tmp) ;; timeout, use copy/cut
;; Actual key
(setq ret (ergoemacs-command-loop--key-lookup (vconcat key (vector tmp2))))))))
(ergoemacs-command-loop--message-binding new-key ret))
((equal orig-key (nth 1 trials)) ;; `ergoemacs-mode' shift translation
(setq this-command-keys-shift-translated t
ergoemacs-command-loop--single-command-keys (nth 0 trials))
;; Shift+Control+c
(when (and (ergoemacs-keymapp ret)
(setq tmp (lookup-key ret [ergoemacs-timeout]))
(eq ergoemacs-handle-ctl-c-or-ctl-x 'both))
(setq ret tmp))
(ergoemacs-command-loop--message-binding new-key ret key))
(t
(ergoemacs-command-loop--message-binding new-key ret key)
(setq ergoemacs-command-loop--single-command-keys new-key)))
(throw 'found-command ret))))))
ret)))
(defun ergoemacs-command-loop--execute-handle-shift-selection (function)
"Allow `ergoemacs-mode' command loop to handle shift selection.
This will apply `handle-shift-selection' when FUNCTION is
considered a shift-selection compatible function.
This allows shift-selection of non-letter keys.
For instance in QWERTY M-> is shift translated to M-."
(when (ergoemacs :movement-p function)
(handle-shift-selection)))
(defun ergoemacs-command-loop--execute-rm-keyfreq (command)
"Remove COMMAND from `keyfreq-mode' counts."
(when (featurep 'keyfreq)
(when keyfreq-mode
(let (count)
(setq count (ergoemacs-gethash (cons major-mode command) keyfreq-table))
(cond
((not count))
((= count 1)
(remhash (cons major-mode command) keyfreq-table))
(count
(puthash (cons major-mode command) (- count 1)
keyfreq-table)))
;; Add local-fn to counter.
(setq count (ergoemacs-gethash (cons major-mode command) keyfreq-table))
(puthash (cons major-mode command) (if count (+ count 1) 1)
keyfreq-table)))))
;; (3) execute command
(defun ergoemacs-command-loop--execute (command &optional keys)
"Execute COMMAND pretending that KEYS were pressed."
(unwind-protect
(let ((keys (or keys ergoemacs-command-loop--single-command-keys)))
;; (ergoemacs-command-loop--spinner)
(cond
((or (stringp command) (vectorp command))
;; If the command is a keyboard macro (string/vector) then execute
;; it by adding it to `unread-command-events'
(let ((tmp (prefix-numeric-value current-prefix-arg)))
(cond
((<= tmp 0) ;; Unsure what to do here.
(ergoemacs-command-loop--message "The %s keyboard macro was not run %s times" (ergoemacs-key-description (vconcat command)) tmp))
(t
(dotimes (_i tmp unread-command-events)
(setq unread-command-events
(append (listify-key-sequence command)
unread-command-events))))))
(setq ergoemacs-command-loop--single-command-keys nil))
(t
;; This should be a regular command.
;; Remove counting of `this-command' in `keyfreq-mode'
;; Shouldn't be needed any more...
;; (ergoemacs-command-loop--execute-rm-keyfreq this-command)
;; This command execute should modify the following variables:
;; - `last-repeatable-command'
;; - `this-command'
;; - `this-original-command'
;; In addition, other minor modes may store the command, so these
;; should be modified as well.
;; These are stored in `ergoemacs-command-loop--execute-modify-command-list'
(ergoemacs-command-loop--execute-modify-command-list command)
;; Handle Shift Selection
(ergoemacs-command-loop--execute-handle-shift-selection this-command)
(when keys
(setq ergoemacs-command-loop--single-command-keys keys)
;; Modify the output for these functions when `keys' is not nil.
;; Assume this is a nonmenu event if it isn't a mouse event
(unless (consp last-command-event)
(setq last-nonmenu-event last-command-event)))
(unwind-protect
(progn
(setq ergoemacs-command-loop--running-pre-command-hook-p t)
(run-hooks 'pre-command-hook))
(setq ergoemacs-command-loop--running-pre-command-hook-p nil))
(unwind-protect
(ergoemacs-command-loop--call-interactively this-command t)
(setq ergoemacs-command-loop--single-command-keys nil)))))
;; (ergoemacs-command-loop--spinner-end)
))
(provide 'ergoemacs-command-loop)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ergoemacs-command-loop.el ends here
;; Local Variables:
;; coding: utf-8-emacs
;; End:
ergoemacs-mode-5.16.10.12/el-get/ 0000755 0001752 0001753 00000000000 12337175720 014611 5 ustar elpa elpa ergoemacs-mode-5.16.10.12/el-get/ergoemacs-mode 0000644 0001752 0001753 00000000260 12337175720 017421 0 ustar elpa elpa (:name ergoemacs-mode
:description "ergoemacs-mode"
:website "https://github.com/ergoemacs/ergoemacs-mode"
:type git
:url "https://github.com/ergoemacs/ergoemacs-mode.git") ergoemacs-mode-5.16.10.12/ergoemacs-component.el 0000644 0001752 0001753 00000253746 13332260074 017735 0 ustar elpa elpa ;;; ergoemacs-component.el --- Ergoemacs map interface -*- lexical-binding: t -*-
;; Copyright © 2013-2015 Free Software Foundation, Inc.
;; Filename: ergoemacs-component.el
;; Description:
;; Author: Matthew L. Fidler
;; Maintainer: Matthew L. Fidler
;; Created: Sat Sep 28 20:10:56 2013 (-0500)
;;
;;; Commentary:
;;
;; Code for ergoemacs components.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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 .
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
;; (require 'guide-key nil t)
(require 'cl-lib)
(eval-when-compile
(require 'ergoemacs-macros))
(require 'help-mode)
(require 'find-func)
(defvar ergoemacs-command-loop--minibuffer-unsupported-p)
(defvar ergoemacs-map-properties--label-atoms-maps)
(defvar ergoemacs--last-start-emacs-state-2)
(defvar ergoemacs--start-emacs-state-2)
(defvar ergoemacs-component-hash)
(defvar ergoemacs-display-key-use-face-p)
(defvar ergoemacs-keyboard-layout)
(defvar ergoemacs-keymap)
(defvar ergoemacs-map-properties--known-maps)
(defvar ergoemacs-mode--fast-p)
(defvar ergoemacs-mode-version)
(defvar ergoemacs-saved-global-map)
(defvar ergoemacs-theme-hash)
(defvar ergoemacs-theme-version)
(defvar ergoemacs-translate--translation-hash)
(defvar ergoemacs-translation-hash)
(defvar package--initialized)
(declare-function diminish "diminish")
(declare-function diminish-undo "diminish")
(declare-function ergoemacs--emacs-state "ergoemacs-mode")
(declare-function ergoemacs-timing-- "ergoemacs-mode")
(declare-function ergoemacs-mode--setup-hash-tables--setq "ergoemacs-mode")
(declare-function ergoemacs-mode-clear-cache "ergoemacs-mode")
(declare-function ergoemacs-set "ergoemacs-lib")
(declare-function ergoemacs-reset "ergoemacs-lib")
(declare-function ergoemacs-warn "ergoemacs-lib")
(declare-function ergoemacs-theme-components "ergoemacs-theme-engine")
(declare-function ergoemacs-theme--regexp "ergoemacs-theme-engine")
(declare-function ergoemacs-translate "ergoemacs-translate")
(declare-function ergoemacs-translate--apply-key "ergoemacs-translate")
(declare-function ergoemacs-translate--define-key "ergoemacs-translate")
(declare-function ergoemacs-map-properties--label-known "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--original "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--map-list "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--put "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--key-hash "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--map-regexp "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--empty-p "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--label "ergoemacs-map-properties")
(declare-function ergoemacs-theme--get-version "ergoemacs-theme-engine")
(declare-function ergoemacs-map-- "ergoemacs-map")
(declare-function ergoemacs-map-keymap "ergoemacs-mapkeymap")
(declare-function ergoemacs-key-description "ergoemacs-key-description")
(declare-function ergoemacs-key-description--keymap "ergoemacs-key-description")
(declare-function ergoemacs-key-description--unicode-char "ergoemacs-key-description")
(declare-function package-installed-p "package")
(declare-function ergoemacs-layout--regexp "ergoemacs-layouts")
(declare-function ergoemacs-layouts--list "ergoemacs-layouts")
;; ergoemacs-translate
(defcustom ergoemacs-ignore-prev-global t
"If non-nil, the ergoemacs-mode will ignore previously defined global keybindings."
:type 'boolean
:group 'ergoemacs-mode)
;; for compatability
;;;###autoload
(defun ergoemacs-ignore-prev-global ()
"Ignore previously defined global keys."
(setq ergoemacs-ignore-prev-global t))
(defun ergoemacs-remap (function)
"Remap the FUNCTION to the appropriate key and then call that function."
(let ((key (where-is-internal function ergoemacs-keymap t)))
(call-interactively (key-binding key t nil (point)))))
;;; Translation between layouts
(cl-defstruct ergoemacs-component-struct
"A basic ergoemacs component map structure."
(name "default-name")
(plist '())
(map nil)
(maps (make-hash-table))
(cond-maps (make-hash-table))
(hook-maps (make-hash-table))
(hook-plists (make-hash-table))
(when-condition nil)
(hook nil)
(dynamic-keys '())
(version nil)
(versions '())
(undefined '())
(unbind '())
(variables nil)
(just-first-keys nil :read-only t)
(variable-modifiers '(meta) :read-only t)
(variable-prefixes '([apps] [menu] [27]) :read-only t)
(package-name nil)
(autoloads nil)
(ensure nil)
(layout "us" :read-only t)
(calculated-layouts (make-hash-table :test 'equal))
(relative-to 'global-map)
(defer nil))
(defvar ergoemacs-component-struct--define-key-current nil)
(defvar ergoemacs-component-struct--ensure-refreshed-p nil)
(defun ergoemacs-component-struct--ensure (package &optional defer autoloads)
"Ensure PACKAGE is installed.
When DEFER is non-nil, dont `require' the package, just make sure
it is installed.
The AUTOLOADS is a list of functions that need to be autoloaded
if the package is deferred."
(when package
(ergoemacs-timing ensure
(ergoemacs-timing (intern (format "ensure-%s" package))
(let ((package (or (and (symbolp package) package)
(and (stringp package) (intern package)))))
(unless (or defer (featurep package))
(require package nil t))
(when (and package (not (featurep package)) (numberp defer))
(run-with-idle-timer defer nil #'require package ;; `(lambda()
;; (message ,(format "Defer: %s %s" package defer))
;; (require ,package)
;; (ergoemacs-component-struct--apply-inits))
)
)
(when (and defer autoloads)
(dolist (c autoloads)
(unless (fboundp (car c))
(autoload (car c) (format "%s" (cdr c)) nil t))))
(unless (featurep package)
(unless package--initialized
(package-initialize))
(if (package-installed-p package) t
(unless ergoemacs-component-struct--ensure-refreshed-p
(package-refresh-contents)
(setq ergoemacs-component-struct--ensure-refreshed-p t))
(unless (progn (ignore-errors (package-install package))
(package-installed-p package))
(ergoemacs-warn "ergoemacs-mode could not install %s." package))
(unless defer
(require package nil t)))))))))
(defun ergoemacs-component-struct--parse-list (list function &rest args)
"Handle :bind and :mode LIST and call FUNCTION.
The FUNCTION calls the with the first argument as the string
piece and the second argument the symbol piece of the definition.
It also passes ARGS if any are specified."
(let (arg1 arg2)
(cond
;; :list ("a" b "c" d)
((ignore-errors (and (consp list) (> (length list) 2)
(stringp (car list))
(setq arg1 (pop list))
(setq arg2 (pop list))))
(while (and arg1 arg2)
(apply function arg1 arg2 args)
(setq arg1 (pop list)
arg2 (pop list))))
((and (consp list) (stringp (car list)))
;; :list ("C-." . ace-jump-mode)
;; :list ("C-." ace-jump-mode)
(apply function (car list)
(or (and (consp (cdr list)) (nth 1 list))
(cdr list))
args))
((and (consp list) (consp (car list)))
(dolist (elt list)
(when (and (consp elt) (stringp (car elt)))
(apply function (car elt)
(or (and (consp (cdr elt)) (nth 1 elt))
(cdr elt))
args)))))))
(defun ergoemacs-component-struct--handle-bind-1 (kbd-str def keymap)
"Tell `ergoemacs-mode' to bind KBD-STR to DEF in KEYMAP."
(ergoemacs-component-struct--define-key keymap (read-kbd-macro kbd-str) def))
(defun ergoemacs-component-struct--handle-bind (bind &optional keymap)
"Handle :bind and related properties.
BIND is the property list from the component definition.
KEYMAP is the symbol of a bound keymap. If unspecified, the
binding assumes KEYMAP is `global-map'."
(let ((keymap (or keymap 'global-map)))
(ergoemacs-component-struct--parse-list
bind #'ergoemacs-component-struct--handle-bind-1 keymap)))
(defun ergoemacs-component-struct--handle-mode-1 (regexpr mode)
"Add (cons REGEXPR MODE) to `auto-mode-alist'.
Also autoload MODE.
Requires `ergoemacs-component-struct--define-key-current' to be
an `ergoemacs-component-struct' object."
;; (message "Handle Mode #2: %s %s" regexpr mode)
(when (ergoemacs-component-struct-p ergoemacs-component-struct--define-key-current)
(let* ((c (cons regexpr mode))
(obj ergoemacs-component-struct--define-key-current)
(package-name (ergoemacs-component-struct-package-name obj)))
(ergoemacs-component-struct--deferred
`(unless (member ',c auto-mode-alist)
(push ',c auto-mode-alist)))
(when (and package-name mode (not (fboundp mode)))
;; Create autoload.
(autoload mode (format "%s, a major mode defined in %s" mode package-name) nil t)
(setq c (cons mode package-name))
(unless (member c (ergoemacs-component-struct-autoloads obj))
(push (cons mode package-name) (ergoemacs-component-struct-autoloads obj)))))))
(defun ergoemacs-component-struct--handle-mode (mode)
"Handle MODE list from :mode keyword."
(when mode
(ergoemacs-component-struct--parse-list mode #'ergoemacs-component-struct--handle-mode-1)))
(defun ergoemacs-component-struct--create-component (plist body file)
"Create ergoemacs component.
PLIST is the component properties
BODY is the body of function.
FILE is the file name where the component was created."
(ergoemacs-timing (intern (format "create-component-%s" (plist-get plist :name)))
(unwind-protect
(progn
(setq ergoemacs-component-struct--define-key-current
(make-ergoemacs-component-struct
:name (plist-get plist :name)
:plist (plist-put plist :file file)
:just-first-keys (or (plist-get plist :just-first-keys) nil)
:variable-modifiers (or (plist-get plist :variable-modifiers) '(meta))
:variable-prefixes (or (plist-get plist :variable-prefixes) '([apps] [menu] [27]))
:package-name (plist-get plist :package-name)
:ensure (plist-get plist :ensure)
:layout (or (plist-get plist :layout) "us")
:defer (plist-get plist :defer)))
(let* ((tmp (plist-get plist :bind-keymap))
(package-name (plist-get plist :package-name))
(demand (plist-get plist :demand))
(defer (if demand nil (plist-get plist :defer)))
(defer-present-p (or demand defer (memq :defer plist))))
;; Handle :bind-keymap commands
(when (and tmp (not defer-present-p) (not defer))
(setq defer-present-p t defer t)
(setf (ergoemacs-component-struct-defer ergoemacs-component-struct--define-key-current) t))
(ergoemacs-component-struct--handle-bind tmp)
;; Handle :bind-keymap* commands
(setq tmp (plist-get plist :bind-keymap*))
(when (and tmp (not defer-present-p) (not defer))
(setq defer-present-p t defer t)
(setf (ergoemacs-component-struct-defer ergoemacs-component-struct--define-key-current) t))
(ergoemacs-component-struct--handle-bind tmp 'ergoemacs-override-keymap)
;; Handle :bind keys
(setq tmp (plist-get plist :bind))
(when (and tmp (not defer-present-p) (not defer))
(setq defer-present-p t defer t)
(setf (ergoemacs-component-struct-defer ergoemacs-component-struct--define-key-current) t))
(ergoemacs-component-struct--handle-bind tmp)
;; Handle :bind* commands
(setq tmp (plist-get plist :bind*))
(when (and tmp (not defer-present-p) (not defer))
(setq defer-present-p t defer t)
(setf (ergoemacs-component-struct-defer ergoemacs-component-struct--define-key-current) t))
(ergoemacs-component-struct--handle-bind tmp 'ergoemacs-override-keymap)
;; Handle :mode
(setq tmp (plist-get plist :mode))
(when (and tmp (not defer-present-p) (not defer))
(setq defer-present-p t defer t)
(setf (ergoemacs-component-struct-defer ergoemacs-component-struct--define-key-current) t))
(ergoemacs-component-struct--handle-mode tmp)
;; Handle :commands
(setq tmp (plist-get plist :commands))
(when (and tmp (not defer-present-p) (not defer))
(setq defer-present-p t defer t)
(setf (ergoemacs-component-struct-defer ergoemacs-component-struct--define-key-current) t))
(when package-name
(cond
((and tmp (symbolp tmp))
(autoload tmp (format "%s" package-name) nil t)
(push (cons tmp package-name) (ergoemacs-component-struct-autoloads ergoemacs-component-struct--define-key-current)))
((consp tmp)
(dolist (f tmp)
(when (and f (symbolp f))
(autoload f (format "%s" package-name) nil t)
(push (cons f package-name) (ergoemacs-component-struct-autoloads ergoemacs-component-struct--define-key-current))))))))
(funcall body)
(setf (ergoemacs-component-struct-variables ergoemacs-component-struct--define-key-current)
(reverse (ergoemacs-component-struct-variables ergoemacs-component-struct--define-key-current))))
(puthash (concat (ergoemacs-component-struct-name ergoemacs-component-struct--define-key-current)
(and (ergoemacs-component-struct-version ergoemacs-component-struct--define-key-current)
(concat "::" (ergoemacs-component-struct-version ergoemacs-component-struct--define-key-current))))
ergoemacs-component-struct--define-key-current ergoemacs-component-hash)
(setq ergoemacs-component-struct--define-key-current nil))))
(defun ergoemacs-component-struct--with-hook (when-condition plist body &optional object)
"How the (when...) conditions in an ergoemacs-mode theme are handled.
WHEN-CONDITION is the when condition that is defined in a theme.
PLIST is the theme's property
BODY is the (when ...) body.
OBJECT is the ergoemacs component object, and defaults to
`ergoemacs-component-struct--define-key-current'."
(cond
((and (not ergoemacs-component-struct--define-key-current) (not object)) ;; Old
(error "`ergoemacs-component-struct--with-hook' is confused"))
(t
(let ((obj (or object ergoemacs-component-struct--define-key-current))
(hook
(or (and (string-match-p "\\(-hook\\|-mode\\|\\`mark-active\\)\\'" (symbol-name when-condition)) when-condition)
(and (string-match-p "mode-.*" (symbol-name when-condition))
(save-match-data
(intern-soft
(replace-regexp-in-string
"-mode-.*" "mode-hook"
(symbol-name when-condition)))))
(and (string-match-p "(key)?map" (symbol-name when-condition))
(save-match-data
(intern-soft
(replace-regexp-in-string
"(key)?map.*" "hook"
(symbol-name when-condition))))))))
(if (not (ergoemacs-component-struct-p obj))
(error "OBJECT is not an ergoemacs-component-structure")
(puthash hook plist (ergoemacs-component-struct-hook-plists obj))
(setf (ergoemacs-component-struct-when-condition obj) when-condition)
(setf (ergoemacs-component-struct-hook obj) hook)
(funcall body)
(setf (ergoemacs-component-struct-when-condition obj) nil)
(setf (ergoemacs-component-struct-hook obj) nil))))))
(defun ergoemacs-component-struct--component-description (component)
"Gets the description of a COMPONENT.
Allows the component not to be calculated."
(let* ((comp-name (or (and (symbolp component) (symbol-name component))
component))
(comp (ergoemacs-gethash comp-name ergoemacs-component-hash)))
(cond
((functionp comp)
(replace-regexp-in-string "[\n ]*(fn)[ \n]*\\'" "" (documentation comp t)))
((ergoemacs-component-struct-p comp)
(plist-get (ergoemacs-component-struct-plist comp) :description))
(t ""))))
(defun ergoemacs-component-struct--new-version (version &optional object)
"Add VERSION to component OBJECT."
(cond
((and (not ergoemacs-component-struct--define-key-current) (not object)) ;; Old
(error "`ergoemacs-component-struct--new-version' is confused"))
(t
(let ((obj (or object ergoemacs-component-struct--define-key-current))
new-obj tmp)
(if (not (ergoemacs-component-struct-p obj))
(error "OBJECT is not an ergoemacs-component-structure")
(puthash (concat (ergoemacs-component-struct-name obj)
(and (ergoemacs-component-struct-version obj)
(concat "::" (ergoemacs-component-struct-version obj))))
ergoemacs-component-struct--define-key-current ergoemacs-component-hash)
;; Get the base object without version changes
(setq new-obj (ergoemacs-gethash (ergoemacs-component-struct-name obj) ergoemacs-component-hash))
;; Update all versions to include the new version information.
(dolist (old-version (ergoemacs-component-struct-versions new-obj))
(setq tmp (ergoemacs-gethash (concat (ergoemacs-component-struct-name new-obj) "::" old-version) ergoemacs-component-hash))
(when (ergoemacs-component-struct-p tmp)
(push version (ergoemacs-component-struct-versions tmp))))
(push version (ergoemacs-component-struct-versions new-obj))
;; Use the last object as the base of the new object
(setq ergoemacs-component-struct--define-key-current (copy-tree obj t))
(setf (ergoemacs-component-struct-version ergoemacs-component-struct--define-key-current) version))))))
(defvar ergoemacs-component-struct--define-key-temp-map nil)
(defun ergoemacs-component-struct--define-key-get-def (def)
"Gets the `ergoemacs-mode' function definition for DEF."
(let (tmp)
(cond
((and (consp def) (memq (nth 0 def) '(kbd read-kbd-macro))
(stringp (nth 1 def)))
(read-kbd-macro (nth 1 def)))
((and (consp def) (= 1 (length def)) (symbolp (nth 0 def)))
(nth 0 def))
((and (consp def) (= 1 (length def)) (consp (nth 0 def))
(= 2 (length (nth 0 def)))
(eq (nth 0 (nth 0 def)) 'quote)
(symbolp (nth 1 (nth 0 def))))
(nth 1 (nth 0 def)))
((and (consp def) (= 2 (length def)) (eq (nth 1 def) 'quote) (symbolp (nth 1 def)))
(nth 1 def))
((and (consp def)
(= 2 (length def))
(stringp (nth 0 def))
(eq (nth 1 def) :emacs)
(setq tmp (lookup-key global-map (read-kbd-macro (nth 0 def))))
(commandp tmp))
tmp)
((and (consp def)
(= 2 (length def))
(stringp (nth 0 def))
(or (not (nth 1 def))
(ergoemacs-gethash (nth 1 def) ergoemacs-translation-hash)))
`(lambda(&optional arg)
(interactive "P")
(ergoemacs-command-loop ,(nth 0 def) ',(nth 1 def))))
((ergoemacs-keymapp (ergoemacs-sv def))
(ergoemacs-sv def))
(t def))))
(defun ergoemacs-component-struct--refresh-keys (&optional obj)
"Refreshes the keys in OBJ based on any new interactive functions found."
(let ((obj (or obj (ergoemacs-theme-components))))
(if (consp obj)
(dolist (cur-obj (ergoemacs-component-struct--lookup-hash obj))
(ergoemacs-component-struct--refresh-keys cur-obj))
(let* ((obj (ergoemacs-component-struct--lookup-hash obj))
(cur-dynamic (ergoemacs-component-struct-dynamic-keys obj))
new-dynamic keymap key global-map-p cur-map
fn-lst new-fn-lst new-fn cur-layout)
(dolist (cur-lst cur-dynamic)
(setq keymap (nth 0 cur-lst)
key (nth 1 cur-lst)
fn-lst (nth 2 cur-lst)
global-map-p (eq keymap 'global-map)
cur-map (or (and global-map-p (ergoemacs-component-struct-map obj))
(ergoemacs-gethash keymap (ergoemacs-component-struct-maps obj)))
new-fn-lst '())
(if (catch 'found-fn
(dolist (fn fn-lst)
(if (not (commandp fn t))
(push new-fn-lst fn)
(setq new-fn fn)
(throw 'found-fn nil)))
t) (push cur-lst new-dynamic)
(when new-fn-lst ;; For later checks
(push (list keymap key (reverse new-fn-lst)) new-dynamic))
(ergoemacs :define-key cur-map key new-fn)
;; Now fix cached layouts
(maphash
(lambda(key value)
(setq cur-layout (nth 1 key))
(when (or (and global-map-p (not (nth 0 key)))
(eq (nth 0 key) keymap))
;; Update keymap (in place).
(ergoemacs :define-key value
(ergoemacs-translate
key (ergoemacs-component-struct-just-first-keys obj)
(ergoemacs-component-struct-variable-modifiers obj)
(ergoemacs-component-struct-variable-prefixes obj) cur-layout
(ergoemacs-component-struct-layout obj)) new-fn)))
(ergoemacs-component-struct-calculated-layouts obj))))
;; Update dynamic/deferred keys
(fset (ergoemacs-component-struct-dynamic-keys obj) new-dynamic)))))
(defun ergoemacs-component-struct--ini-map (obj)
"Initilize keymap in OBJ.
OBJ is an `egoemacs-component-struct' object.
Returns the map, if it hasn't been initialized, initialize
with the label, and then return."
(or (ergoemacs-component-struct-map obj)
(let ((map (make-sparse-keymap)))
(ergoemacs map :label
(list (ergoemacs (ergoemacs :global-map) :key-hash)
(intern (format "%s%s" (ergoemacs-component-struct-name obj) (or (ergoemacs-component-struct-version obj) "")))
(intern (ergoemacs-component-struct-layout obj))))
(setf (ergoemacs-component-struct-map obj) map)
map)))
(defun ergoemacs-component-struct--define-key (keymap key def &optional object)
"In KEYMAP, define KEY to be DEF for OBJECT.
If not specified, OBJECT is `ergoemacs-component-struct--define-key-current'."
(cond
((and (not ergoemacs-component-struct--define-key-current) (not object)) ;; Old
(error "`ergoemacs-component-struct--define-key' is confused"))
(t
(let ((obj (or object ergoemacs-component-struct--define-key-current))
(key (or (and (consp key) (memq (car key) '(kbd read-kbd-macro))
(stringp (nth 1 key)) (read-kbd-macro (nth 1 key)))
key))
(def (ergoemacs-component-struct--define-key-get-def def)))
(if (not (ergoemacs-component-struct-p obj))
(error "OBJECT not a ergoemacs-component-structure")
(setq key (vconcat key))
(let* ((global-map-p (or (eq keymap 'global-map) (eq keymap 'ergoemacs-mode-map)
(eq keymap 'ergoemacs-keymap)))
(when-condition (ergoemacs-component-struct-when-condition obj))
(hook (ergoemacs-component-struct-hook obj))
(cur-map (or (and global-map-p (not when-condition)
(ergoemacs-component-struct--ini-map obj))
(and (not when-condition) (ergoemacs-gethash keymap (ergoemacs-component-struct-maps obj)))
(and global-map-p when-condition (ergoemacs-gethash when-condition (ergoemacs-component-struct-cond-maps obj)))
(and when-condition hook (ignore-errors (ergoemacs-gethash keymap (ergoemacs-gethash hook (ergoemacs-component-struct-hook-maps obj)))))))
(package-name (ergoemacs-component-struct-package-name obj))
fn-lst
(key (or (and (vectorp key) key)
(and (stringp key) (vconcat key))))
tmp)
(cond
((and (not cur-map) (not when-condition))
(cl-pushnew keymap ergoemacs-map-properties--known-maps)
(cl-pushnew keymap ergoemacs-map-properties--label-atoms-maps)
(setq cur-map (make-sparse-keymap))
(puthash keymap cur-map (ergoemacs-component-struct-maps obj)))
((and (not cur-map) when-condition global-map-p)
(setq cur-map (make-sparse-keymap))
(puthash when-condition cur-map (ergoemacs-component-struct-cond-maps obj)))
((and (not cur-map) when-condition hook)
(unless (ergoemacs-gethash hook (ergoemacs-component-struct-hook-maps obj))
(puthash hook (make-hash-table) (ergoemacs-component-struct-hook-maps obj)))
(cl-pushnew keymap ergoemacs-map-properties--known-maps)
(cl-pushnew keymap ergoemacs-map-properties--label-atoms-maps)
(setq cur-map (make-sparse-keymap))
(puthash keymap cur-map (ergoemacs-gethash hook (ergoemacs-component-struct-hook-maps obj)))))
(cond
((and global-map-p (not when-condition) (not def) (setq tmp (lookup-key (ergoemacs-component-struct-map obj) key))
(not (integerp tmp)))
;; Remove the key from the keymap, do not set it to
;; nil; Its as if it was never defined
(setq ergoemacs-component-struct--define-key-temp-map (make-sparse-keymap))
(ergoemacs-timing remove-global-map-map-keymap
(ergoemacs-map-keymap
(lambda (cur-key item)
(if (consp cur-key)
(ergoemacs-warn "Keymap range currently not supported %s %s" cur-key item)
(unless (eq item 'ergoemacs-prefix)
(unless (equal key cur-key)
(ergoemacs :define-key ergoemacs-component-struct--define-key-temp-map cur-key item)))))
cur-map))
(setf (ergoemacs-component-struct-map obj)
(copy-keymap ergoemacs-component-struct--define-key-temp-map))
(setq ergoemacs-component-struct--define-key-temp-map nil))
((and global-map-p (not (eq keymap 'global-map)) (not when-condition) (not def));; Add to unbind keys
(unless (member key (ergoemacs-component-struct-unbind obj))
(push key (ergoemacs-component-struct-unbind obj))))
((and global-map-p (not when-condition) (not def)) ;; Add to undefined keys
(unless (member key (ergoemacs-component-struct-undefined obj))
(push key (ergoemacs-component-struct-undefined obj))))
((and (not when-condition) (lookup-key cur-map key) (not def))
;; Remove the key from the keymap. Do not set it to nil.
;; Its as if it was never defined.
(setq ergoemacs-component-struct--define-key-temp-map (make-sparse-keymap))
(ergoemacs-timing remove-local-keymap-map-keymap
(ergoemacs-map-keymap
(lambda (cur-key item)
(if (consp cur-key)
(message "Key range not supported %s, %s" cur-key item)
(unless (eq item 'ergoemacs-prefix)
(unless (equal key cur-key)
(ergoemacs :define-key ergoemacs-component-struct--define-key-temp-map cur-key item)))))
cur-map))
(puthash keymap (copy-keymap ergoemacs-component-struct--define-key-temp-map) (ergoemacs-component-struct-maps obj))
(setq ergoemacs-component-struct--define-key-temp-map nil))
((and (consp def) (stringp (nth 0 def)) (symbolp (nth 1 def)) (eq (nth 1 def) 'keymap))
(ergoemacs :define-key cur-map key def))
((and (consp def) (symbolp (nth 1 def))) ;; (fn1 fn2 fn3 fn4)
(unless (catch 'found-fn
(dolist (cur-def def)
(if (not (commandp cur-def t))
(push cur-def fn-lst)
(if (ergoemacs-keymapp cur-def)
(ergoemacs :define-key cur-map key (copy-keymap cur-def))
(ergoemacs :define-key cur-map key cur-def))
(throw 'found-fn t)))
nil)
;; Not found
(ergoemacs :define-key cur-map key `(lambda() (interactive) (error ,(format "This key is undefined without one of the following functions: %s" fn-lst)))))
(when fn-lst ;; Test for later
(push (list keymap key fn-lst)
(ergoemacs-component-struct-dynamic-keys obj))))
(t
(if (ergoemacs-keymapp def)
(ergoemacs :define-key cur-map key (copy-keymap def))
(ergoemacs :define-key cur-map key def))
(when (and package-name def (not (fboundp def)))
;; Create autoload.
(autoload def (format "%s" package-name) nil t)
(push (cons def package-name) (ergoemacs-component-struct-autoloads obj)))))))))))
(defun ergoemacs-component-struct--clear-cache (struct-map)
"Clears STRUCT-MAP's cache of keymaps.
STRUCT-MAP can be a list of `ergoemacs-component-struct' structures as well."
(cond
((ergoemacs-component-struct-p struct-map)
(setf (ergoemacs-component-struct-calculated-layouts struct-map) (make-hash-table :test 'equal)))
((consp struct-map)
(dolist (cur-map struct-map)
(ergoemacs-component-struct--clear-cache cur-map)))))
(defun ergoemacs-component-struct--closest-version (version version-list)
"Return the closest version to VERSION in VERSION-LIST.
Formatted for use with `ergoemacs-theme-component-hash' it will return ::version or an empty string"
(if (or (not version) (string= "nil" version)) ""
(if version-list
(let ((use-version (version-to-list version))
biggest-version
biggest-version-list
smallest-version
smallest-version-list
best-version
best-version-list
test-version-list
ret)
(dolist (v version-list)
(setq test-version-list (version-to-list v))
(if (not biggest-version)
(setq biggest-version v
biggest-version-list test-version-list)
(when (version-list-< biggest-version-list test-version-list)
(setq biggest-version v
biggest-version-list test-version-list)))
(if (not smallest-version)
(setq smallest-version v
smallest-version-list test-version-list)
(when (version-list-< test-version-list smallest-version-list)
(setq smallest-version v
smallest-version-list test-version-list)))
(cond
((and (not best-version)
(version-list-<= test-version-list use-version))
(setq best-version v
best-version-list test-version-list))
((and (version-list-<= best-version-list test-version-list) ;; Better than best
(version-list-<= test-version-list use-version))
(setq best-version v
best-version-list test-version-list))))
(if (version-list-< biggest-version-list use-version)
(setq ret "")
(if best-version
(setq ret (concat "::" best-version))
(setq ret (concat "::" smallest-version))))
ret)
"")))
(defun ergoemacs-component-struct--lookup-closest (comp &optional current-version)
"Look up closest component version from `ergoemacs-component-hash'.
COMP is the component where the version information should be stored.
Optionally assume that CURRENT-VERSION is active"
(if (not (ergoemacs-component-struct-p comp)) nil
(let (versions)
(cond
((not (setq versions (ergoemacs-component-struct-versions comp)))
comp)
((string= "" (setq versions (ergoemacs-component-struct--closest-version
(or current-version (ergoemacs :current-version)) versions)))
comp)
(t
(ergoemacs-component-struct--lookup-hash (concat (ergoemacs-component-struct-name comp) versions)))))))
(defun ergoemacs-component-struct--lookup-hash (map-or-map-list &optional version)
"Lookup `ergoemacs-component-hash' from MAP-OR-MAP-LIST if necessary.
VERSION is the version of the `ergoemacs-mode' keys that you wish
to lookup.
This takes into consideration any versions defined, and the
closest `ergoemacs-theme-version' calculated from
`ergoemacs-component-struct--closest-version' by using
`ergoemacs-component-struct--lookup-closest'"
(if (consp map-or-map-list)
(mapcar #'ergoemacs-component-struct--lookup-hash map-or-map-list)
(if (ergoemacs-component-struct-p map-or-map-list)
(ergoemacs-component-struct--lookup-closest map-or-map-list version)
(let ((map map-or-map-list)
ret)
(when (symbolp map) ;; If map is a symbol, change to string.
(setq map (symbol-name map)))
(when (stringp map) ;; If map is a string, get the component from `ergoemacs-component-hash'
(setq ret (ergoemacs-gethash map ergoemacs-component-hash))
(when (and ret (functionp ret))
(funcall ret)
(setq ret (ergoemacs-gethash map ergoemacs-component-hash))))
(if (string-match-p "::" map) ret
(ergoemacs-component-struct--lookup-closest ret version))))))
(defvar ergoemacs-component-struct--get-keymap nil)
(defvar ergoemacs-component-struct--get-keymap-extra nil)
(defun ergoemacs-component-struct--lookup-list (lookup-keymap &optional layout obj map-list)
"Get list of extra maps based on LOOKUP-KEYMAP.
The LAYOUT argument specifies the ergoemacs layout to use.
Otherwise, the layout used is `ergoemacs-keyboard-layout'.
The OBJ list is the list of ergoemacs theme components to use.
If it is nil, it is the components specifed by
`ergoemacs-theme-components'.
The MAP-LIST is the list symbols that LOOKUP-KEYMAP is bound to.
If unspecified, use `ergoemacs-map-properties--map-list' to try
to figure out what variables LOOKUP-KEYMAP is bound to."
(let ((obj (ergoemacs-component-struct--lookup-hash (or obj (reverse (ergoemacs-theme-components)))))
(cur-layout (or layout ergoemacs-keyboard-layout))
(map-list (or map-list (ergoemacs lookup-keymap :map-list)))
;; (ergoemacs-component-struct--lookup-list org-mode-map)
extra-hash
ret extra-map)
(if (consp obj)
(dolist (cobj obj)
(setq extra-hash (ergoemacs-component-struct-maps cobj))
(dolist (map-name map-list)
(setq extra-map (ergoemacs-gethash map-name extra-hash))
(when extra-map
(push (ergoemacs-component-struct--get cobj cur-layout map-name extra-map) ret)))))
ret))
(defun ergoemacs-component-struct--get (map cur-layout &optional lookup-key translate-map)
"Get component MAP and return keymap updating MAP cache.
CUR-LAYOUT is the current keymboard layout used.
This keymap is cached using LOOKUP-KEY.
The keymap to translate is TRANSLATE-MAP, otherwise it is the
`ergoemacs-component-struct-map' for MAP."
(let* (ret
(cmap (or translate-map (ergoemacs-component-struct-map map)))
(just-first-keys (ergoemacs-component-struct-just-first-keys map))
(variable-modifiers (ergoemacs-component-struct-variable-modifiers map))
(variable-prefixes (ergoemacs-component-struct-variable-prefixes map))
(layout-from (ergoemacs-component-struct-layout map))
(hash (ergoemacs-component-struct-calculated-layouts map)))
(cond
((string= layout-from cur-layout)
(setq ret (copy-keymap cmap))
ret)
((setq ret (ergoemacs-gethash (list lookup-key (intern cur-layout)) hash))
ret)
(t
(setq ergoemacs-component-struct--get-keymap (make-sparse-keymap))
(ergoemacs-timing translate-keymap
(ergoemacs-timing (intern (format "translate-keymap-%s" (ergoemacs-component-struct-name map)))
(ergoemacs-map-keymap
(lambda (key item)
(if (consp key)
(ergoemacs-warn "Keymap range currently not supported %s,%s" key item)
(unless (eq item 'ergoemacs-prefix)
(ergoemacs :define-key
ergoemacs-component-struct--get-keymap
(ergoemacs-translate
key just-first-keys variable-modifiers
variable-prefixes cur-layout layout-from) item))))
cmap)))
(setq ret (copy-keymap ergoemacs-component-struct--get-keymap))
(ergoemacs ret :label (list (or lookup-key (ergoemacs (ergoemacs :global-map) :key-hash)) (intern (format "%s%s" (ergoemacs-component-struct-name map) (or (ergoemacs-component-struct-version map) ""))) (intern cur-layout)))
(puthash (list lookup-key (intern cur-layout)) ret hash)
(setq ergoemacs-component-struct--get-keymap nil)
ret))))
(defun ergoemacs-component-struct--minor-mode-map-alist-hash (&optional obj layout)
"Get `minor-mode-map-alist' additions in hash-table form.
OBJ is the ergoemacs theme components. Defaults to the value
returned from the function `ergoemacs-theme-components'.
LAYOUT is the current keyboard layout. Defaults to
`ergoemacs-keyboard-layout'"
(let ((obj (ergoemacs-component-struct--lookup-hash (or obj (ergoemacs-theme-components))))
(cur-layout (or layout ergoemacs-keyboard-layout))
(hash (make-hash-table)))
(cond
((consp obj)
(dolist (cur-obj obj)
(maphash
(lambda(key value)
(puthash key (append (ergoemacs-gethash key hash) value) hash))
(ergoemacs-component-struct--minor-mode-map-alist-hash cur-obj)))
hash)
(t
(maphash
(lambda(key value)
;; Put the translated keymap in a list in the hash.
(puthash key (list (ergoemacs-component-struct--get obj cur-layout (list 'cond-map key) value)) hash))
(ergoemacs-component-struct-cond-maps obj))
hash))))
(defun ergoemacs-component-struct--minor-mode-map-alist (&optional obj)
"Get the ending maps for `minor-mode-map-alist' using the ergoemacs structures OBJ."
(let (ret map parent)
(maphash
(lambda(key value)
(setq parent (make-composed-keymap value)
map (make-sparse-keymap))
(ergoemacs map :label (list 'cond-map key (intern ergoemacs-keyboard-layout)))
(set-keymap-parent map parent)
(push (cons key map) ret))
(ergoemacs-component-struct--minor-mode-map-alist-hash obj))
ret))
(defun ergoemacs-component-struct--hooks (&optional obj ret)
"Gets a list of hooks that need to be defined eor OBJ.
You can prespecify RET so that new hooks are pushed to the list."
(let ((obj (ergoemacs-component-struct--lookup-hash (or obj (ergoemacs-theme-components))))
tmp
(ret ret))
(cond
((consp obj)
(dolist (cur-obj obj)
(setq ret (ergoemacs-component-struct--hooks cur-obj ret)))
ret)
(t
(when (and (setq tmp (ergoemacs-component-struct-hook-maps obj))
(hash-table-p tmp))
(maphash
(lambda(hook _value)
(cl-pushnew hook ret))
tmp))
ret))))
(defun ergoemacs-component-struct--hook-hash (hook &optional layout obj)
"Get HOOK hash.
LAYOUT is the keyboard layout, defaulting to `ergoemacs-keyboard-layout'.
OBJ is the theme components, defaulting to `ergoemacs-theme-components'."
(let ((obj (ergoemacs-component-struct--lookup-hash (or obj (ergoemacs-theme-components))))
(cur-layout (or layout ergoemacs-keyboard-layout))
tmp
(hash (make-hash-table)))
(cond
((consp obj)
(dolist (cur-obj obj)
(maphash
(lambda(key value)
(puthash key (append (ergoemacs-gethash key hash) value) hash))
(ergoemacs-component-struct--hook-hash hook layout cur-obj)))
hash)
(t
(when (and (setq tmp (ergoemacs-gethash hook (ergoemacs-component-struct-hook-maps obj)))
(hash-table-p tmp))
(maphash
(lambda(key value)
;; Put the translated keymap in a list in the hash.
(puthash key (list (ergoemacs-component-struct--get obj cur-layout (list 'hook-maps hook key) value)) hash))
tmp))
hash))))
(defun ergoemacs-component-struct--hook (hook &optional layout obj)
"Get keymaps applied in an alist similiar to `minor-mode-map-alist'.
The `car' of the alist should be the keymap that should be
modified, the `cdr' of the alsit should be the keymap that should
be composed over the keymap. This is done in
`ergoemacs-component-struct--composed--composed-hook'.
HOOK is the hook that is being run. In the
`ergoemacs-theme-component', these are defined as:
\(when icicle-minibuffer-setup-hook
...)
LAYOUT is the current keyboard layout, or the layout of the
current keyboard theme.
OBJ is the curent ergoemacs-mode object being modified."
(let* (ret tmp label parent)
(maphash
(lambda(key value)
(setq tmp (when (ergoemacs-keymapp (ergoemacs-sv key))
(ergoemacs-sv key))
label (list 'hook-maps key (or layout ergoemacs-keyboard-layout) (if tmp t nil))
parent (make-composed-keymap value tmp)
tmp (make-sparse-keymap))
(ergoemacs tmp :label label)
(set-keymap-parent tmp parent)
(push (cons key tmp) ret))
(ergoemacs-component-struct--hook-hash hook layout obj))
ret))
(defvar ergoemacs-component-struct--composed-hook-minibuffer nil
"`ergoemacs-mode' hooks deferred until after `ergoemacs-mode' modifies the current minibuffer map.")
(defun ergoemacs-component-struct--composed-hook (hook &optional layout obj)
"Apply keymaps defined in HOOK.
LAYOUT is the current keyboard layout.
OBJ is the current object being modified, passed to
`ergoemacs-component-struct--hook'."
(dolist (elt (ergoemacs-component-struct--hook hook layout obj))
(if (minibufferp)
(progn
(unless ergoemacs-command-loop--minibuffer-unsupported-p
(catch 'unsupported-p
(dolist (elt (ergoemacs-component-struct--lookup-hash (or obj (ergoemacs-theme-components))))
(let ((plist (gethash hook (ergoemacs-component-struct-hook-plists elt))))
(when (and plist (plist-get plist :command-loop-unsupported-p))
(set (make-local-variable 'ergoemacs-command-loop--minibuffer-unsupported-p) t)
(throw 'unsupported-p t))))))
(if ergoemacs-component-struct--composed-hook-minibuffer
(push elt ergoemacs-component-struct--composed-hook-minibuffer)
(set (make-local-variable 'ergoemacs-component-struct--composed-hook-minibuffer)
(list elt))))
(set (make-local-variable (car elt)) (make-composed-keymap (cdr elt) (symbol-value (car elt)))))))
(defvar ergoemacs-component-struct--create-hooks nil)
(defun ergoemacs-component-struct--create-hooks (&optional obj)
"Gets a list of hooks that need to be defined eor OBJ."
(dolist (hook (ergoemacs-component-struct--hooks obj))
(eval `(progn
(defun ,(intern (concat "ergoemacs--" (symbol-name hook))) ()
,(format "`ergoemacs-mode' hook for `%s'" (symbol-name hook))
(ergoemacs-component-struct--composed-hook ',hook))
;; (push )
(push ',hook ergoemacs-component-struct--create-hooks)
(add-hook ',hook #',(intern (concat "ergoemacs--" (symbol-name hook))))))))
(defun ergoemacs-component-struct--rm-hooks ()
"Remove hooks.
These hooks are those created with
`ergoemacs-component-struct--create-hooks'."
(dolist (hook ergoemacs-component-struct--create-hooks)
(remove-hook hook (intern (concat "ergoemacs--" (symbol-name hook)))))
(setq ergoemacs-component-struct--create-hooks nil))
(defun ergoemacs-component-struct--translated-list (obj list &optional layout)
"Base on OBJ translation, Translate LIST using LAYOUT."
(let ((cur-layout (or layout ergoemacs-keyboard-layout))
new-list)
(dolist (key list)
(ergoemacs :apply-key key
(lambda(trans-key)
(push (ergoemacs-translate
trans-key (ergoemacs-component-struct-just-first-keys obj)
(ergoemacs-component-struct-variable-modifiers obj)
(ergoemacs-component-struct-variable-prefixes obj) cur-layout
(ergoemacs-component-struct-layout obj))
new-list))))
new-list))
(defvar ergoemacs-component-struct--refresh-variables nil
"To reset a current theme, the variables are refreshed when this is non-nil.")
;;; Change variable values.
(defun ergoemacs-component-struct--set (symbol newval &optional hook object)
"Set variables up for components.
SYMBOL is the symbol being set.
NEWVAL is the new value that will be used.
HOOK tells if this was called in the (with ..-hook ...) syntax.
OBJECT is the object being modified, defaulting to
`ergoemacs-component-struct--define-key-current'."
(cond
((and (not ergoemacs-component-struct--define-key-current) (not object)) ;; Old
(error "`ergoemacs-component-struct--set' is confused"))
(t
(let ((obj (or object ergoemacs-component-struct--define-key-current)))
(if (not (ergoemacs-component-struct-p obj))
(error "OBJECT is not an ergoemacs-component-structure")
(push (list symbol newval hook) (ergoemacs-component-struct-variables obj)))))))
(defun ergoemacs-component-struct--deferred (what &optional object)
"Setup deferred initilizations.
WHAT is the defered initilization list.
OBJECT is the `ergoemacs-component-struct' object being changed."
(cond
((and (not ergoemacs-component-struct--define-key-current) (not object)) ;; Old
(error "`ergoemacs-component-struct--deferred' is confused"))
(t
(let ((obj (or object ergoemacs-component-struct--define-key-current)))
(if (not (ergoemacs-component-struct-p obj))
(error "OBJECT is not an ergoemacs-component-structure")
(push (list what nil nil) (ergoemacs-component-struct-variables obj)))))))
(defun ergoemacs-component-struct--variables (&optional obj)
"Get a list of variables for the OBJ."
(let ((obj (or obj (ergoemacs-theme-components))))
(cond
((consp obj)
(let (ret)
(dolist (cur-obj (ergoemacs-component-struct--lookup-hash obj))
(setq ret (append ret (ergoemacs-component-struct--variables cur-obj))))
ret))
((ergoemacs-component-struct-p obj)
(mapcar (lambda(x)
(append x (list (ergoemacs-component-struct-name obj))))
(ergoemacs-component-struct-variables obj)))
(t (ergoemacs-component-struct--variables (ergoemacs-component-struct--lookup-hash obj))))))
(defvar ergoemacs-component-struct--refresh-variables nil)
(defvar ergoemacs-component-struct--applied-inits '())
(defvar ergoemacs-component-struct--deferred-functions '())
(defvar ergoemacs-component-struct--apply-inits-first-p t)
(defvar ergoemacs-component-struct--apply-ensure-p nil)
(defvar ergoemacs-component-struct--applied-plists nil)
(defvar ergoemacs-component-echo-loaded-file-p nil)
(defvar ergoemacs-component-struct--apply-inits nil)
(defun ergoemacs-component-struct--apply-inits (&optional file obj)
"Apply the initializations after loading FILE from the object OBJ.
This is a wrapper for `ergoemacs-component-struct--apply-inits--'
to prevent infinite recursion."
(unless ergoemacs-component-struct--apply-inits
(setq ergoemacs-component-struct--apply-inits t)
(unwind-protect
(ergoemacs-component-struct--apply-inits-- file obj))
(setq ergoemacs-component-struct--apply-inits nil)))
(defun ergoemacs-component-struct--apply-inits-- (&optional file obj)
"Apply the initializations after loading FILE from the object OBJ."
(ergoemacs-map-properties--label-known)
(when (and ergoemacs-component-echo-loaded-file-p file)
(message "`ergoemacs-mode' Loaded %s" file))
(when (eq ergoemacs-component-struct--refresh-variables t)
(setq ergoemacs-component-struct--refresh-variables ergoemacs-component-struct--applied-inits))
(let* ((obj (or obj (ergoemacs-theme-components)))
package-name ensure defer comp tmp autoloads)
(when ergoemacs-component-struct--apply-inits-first-p
(setq ergoemacs-component-struct--apply-inits-first-p nil
ergoemacs-component-struct--apply-ensure-p t)
(if (not ergoemacs-mode--fast-p)
(setq ergoemacs--start-emacs-state-2 (ergoemacs--emacs-state))
;; Check to see if emacs state has changed.
(setq ergoemacs--start-emacs-state-2 (ergoemacs--emacs-state))
(ergoemacs-mode--setup-hash-tables--setq
nil
'ergoemacs--last-start-emacs-state-2 nil)
(unless (equal ergoemacs--last-start-emacs-state-2 ergoemacs--start-emacs-state-2)
(if (not ergoemacs--last-start-emacs-state-2)
(progn
(message "Saving fast startup state.")
(setq ergoemacs--last-start-emacs-state-2 ergoemacs--start-emacs-state-2)
(ergoemacs-mode--setup-hash-tables--setq
t
'ergoemacs--last-start-emacs-state-2 ergoemacs--last-start-emacs-state-2))
(ergoemacs-mode-clear-cache t)
(ergoemacs-warn "ergoemacs-mode cache reset AFTER loading; Keys may be slightly inconsistent until emacs restart.")))))
(when ergoemacs-component-struct--apply-ensure-p
(setq ergoemacs-component-struct--apply-ensure-p nil)
;; Ensure packages
(dolist (elt obj)
(setq comp (ergoemacs-component-struct--lookup-hash elt)
package-name (ergoemacs-component-struct-package-name comp)
ensure (ergoemacs-component-struct-ensure comp)
autoloads (ergoemacs-component-struct-autoloads comp)
defer (ergoemacs-component-struct-defer comp))
(cond
((eq ensure t)
(ergoemacs-component-struct--ensure package-name defer autoloads))
((and ensure (symbolp ensure))
(ergoemacs-component-struct--ensure ensure defer autoloads))
((and (consp ensure) (memq (car ensure) '(memq member and or if when = string= not string< eq equal)))
(when (ignore-errors (eval ensure))
(ergoemacs-component-struct--ensure package-name defer autoloads)))
((consp ensure)
(dolist (elt ensure)
(cond
((and elt (symbolp elt))
(ergoemacs-component-struct--ensure elt defer autoloads))
((stringp elt)
(ergoemacs-component-struct--ensure (intern elt) defer autoloads)))
(setq autoloads nil)))
((stringp ensure)
(ergoemacs-component-struct--ensure (intern ensure) defer autoloads)))))
;; Turn on plist options (like :diminish)
(dolist (elt obj)
(unless (memq elt ergoemacs-component-struct--applied-plists)
(let* ((comp (ergoemacs-component-struct--lookup-hash elt))
(plist (ergoemacs-component-struct-plist comp))
fn)
(dolist (elt plist)
(when (and (symbolp elt)
(setq fn (intern (format "ergoemacs-component--%s-on"
(substring (symbol-name elt) 1))))
(fboundp fn))
(funcall fn plist)))
(push elt ergoemacs-component-struct--applied-plists))))
;; Turn off plist options
(setq tmp nil)
(dolist (elt ergoemacs-component-struct--applied-plists)
(if (memq elt obj)
(push elt tmp)
(let* ((comp (ergoemacs-component-struct--lookup-hash elt))
(plist (ergoemacs-component-struct-plist comp))
fn)
(dolist (elt plist)
(when (and (symbolp elt)
(setq fn (intern (format "ergoemacs-component--%s-off"
(substring (symbol-name elt) 1))))
(fboundp fn))
(funcall fn plist))))))
(setq ergoemacs-component-struct--applied-plists tmp)
(dolist (cur-obj obj)
(ergoemacs-timing (intern (format "initialize-%s" cur-obj))
(dolist (init (ergoemacs-component-struct--variables cur-obj))
(if (and (consp (nth 0 init)) (not (nth 1 init)) (not (nth 2 init)))
(unless (member (nth 0 init) ergoemacs-component-struct--deferred-functions)
(cond
((eq (car (nth 0 init)) 'add-to-list)
(when (ignore-errors (boundp (nth 1 (nth 0 init))))
(ignore-errors
(apply (car (nth 0 init)) (cdr (nth 0 init)))
(push (nth 0 init) ergoemacs-component-struct--deferred-functions)))
(when (ignore-errors (eq 'quote (nth 0 (nth 1 (nth 0 init)))))
(if (ignore-errors (eq 'quote (nth 0 (nth 2 (nth 0 init)))))
(when (ignore-errors (boundp (nth 1 (nth 1 (nth 0 init)))))
(apply 'add-to-list (nth 1 (nth 2 (nth 0 init))) (cdr (cdr (cdr (nth 0 init)))))
(push (nth 0 init) ergoemacs-component-struct--deferred-functions))
(when (ignore-errors (boundp (nth 1 (nth 1 (nth 0 init)))))
(apply 'add-to-list (nth 1 (nth 1 (nth 0 init))) (cdr (cdr (nth 0 init))))
(push (nth 0 init) ergoemacs-component-struct--deferred-functions)))))
((memq (car (nth 0 init)) '(push pushnew cl-pushnew))
(when (ignore-errors (boundp (nth 2 (nth 0 init))))
(if (ignore-errors (eq 'quote (nth 1 (nth 1 (nth 0 init)))))
(ignore-errors
(apply (car (nth 0 init)) (nth 1 (nth 1 (nth 0 init))) (cdr (cdr (nth 0 init))))
(push (nth 0 init) ergoemacs-component-struct--deferred-functions))
(ignore-errors
(apply (car (nth 0 init)) (cdr (nth 0 init)))
(push (nth 0 init) ergoemacs-component-struct--deferred-functions)))
(ignore-errors
(apply (car (nth 0 init)) (cdr (nth 0 init)))
(push (nth 0 init) ergoemacs-component-struct--deferred-functions))))
((eq (car (nth 0 init)) 'require)
(require (nth 1 (nth 1 (nth 0 init))) nil t)
(when (not (featurep (nth 1 (nth 1 (nth 0 init)))))
;; Attempt to ensure the feature, if specified.
(ergoemacs-warn "Could not load %s; %s" (nth 1 (nth 1 (nth 0 init)))
(nth 3 init))))
(t
(condition-case err
(eval (nth 0 init))
(error (progn
(ergoemacs-warn "%s while evaluating %s" err (nth 0 init))
(debug err))))
(push (nth 0 init) ergoemacs-component-struct--deferred-functions))
;; (t (ergoemacs-warn "Theme did not handle: %s" (nth 0 init)))
))
(let ((x (and ergoemacs-component-struct--refresh-variables (boundp (nth 0 init))
(assq (nth 0 init) ergoemacs-component-struct--refresh-variables)))
add-hook-p append-p local-p)
(cond
((and x
(not (nth 2 init))
(not
(equal (ergoemacs-sv (nth 0 init))
(funcall (nth 1 init)))))
;; Values have changed, so reapply.
(setq ergoemacs-component-struct--refresh-variables (delq x ergoemacs-component-struct--refresh-variables)
x nil))
((and x (nth 2 init))
;; Reapply hooks
(setq ergoemacs-component-struct--refresh-variables (delq x ergoemacs-component-struct--refresh-variables)
x nil)))
(cond
(x ;; Values have not changed
(setq ergoemacs-component-struct--refresh-variables (delq x ergoemacs-component-struct--refresh-variables)))
((not (boundp (nth 0 init))) ;; Do nothing, not bound yet.
)
((and (nth 2 init) ;; Already applied hook?
(setq add-hook-p (nth 0 (nth 2 init))
append-p (nth 1 (nth 2 init))
local-p (nth 2 (nth 2 init)))
(member (list (nth 0 init) (nth 1 init)
(list (not add-hook-p) append-p local-p))
ergoemacs-component-struct--applied-inits)))
((nth 2 init)
;; Hook
(if add-hook-p
(progn
(funcall 'add-hook (nth 0 init) (nth 1 init) append-p local-p)
;; (message "%s: (add-hook %s %s %s %s)"
;; cur-obj (nth 0 init) (nth 1 init)
;; append-p local-p)
)
(funcall 'remove-hook (nth 0 init) (nth 1 init) local-p)
;; (message "%s: (remove-hook %s %s %s %s)"
;; cur-obj (nth 0 init) (nth 1 init)
;; append-p local-p)
)
(push (list (nth 0 init) (nth 1 init)
(list (not add-hook-p) append-p local-p))
ergoemacs-component-struct--applied-inits))
((and (not (nth 2 init)) (assq (nth 0 init) ergoemacs-component-struct--applied-inits))
;; Already applied, Do nothing for now.
)
(t
;; (Nth 0 Init)iable state change
(when (ergoemacs-set (nth 0 init) (funcall (nth 1 init))
(ergoemacs-component-struct-defer (ergoemacs-component-struct--lookup-hash cur-obj)))
(push (list (nth 0 init) (ergoemacs-sv (nth 0 init)))
ergoemacs-component-struct--applied-inits)
)))))))))
;; Now remove things that were not set
(when ergoemacs-component-struct--refresh-variables
(let ((tmp ergoemacs-component-struct--applied-inits))
(setq ergoemacs-component-struct--applied-inits ergoemacs-component-struct--refresh-variables)
(setq ergoemacs-component-struct--refresh-variables nil)
(unwind-protect
(ergoemacs-component-struct--remove-inits)
(setq ergoemacs-component-struct--applied-inits tmp)))))
(add-hook 'ergoemacs-mode-startup-hook #'ergoemacs-component-struct--apply-inits)
(add-hook 'ergoemacs-after-load-functions #'ergoemacs-component-struct--apply-inits)
(defun ergoemacs-component-struct--remove-inits ()
"Remove the applied initializations of modes and variables.
This assumes the variables are stored in `ergoemacs-component-struct--applied-inits'"
(if ergoemacs-component-struct--refresh-variables
(setq ergoemacs-component-struct--refresh-variables ergoemacs-component-struct--applied-inits)
(dolist (init ergoemacs-component-struct--applied-inits)
(let ((var (nth 0 init))
;; (val (nth 1 init))
(hook (nth 2 init)))
(cond
(hook
(let ((add-hook-p (nth 0 hook))
(append-p (nth 1 hook))
(local-p (nth 2 hook)))
(if add-hook-p
(funcall 'add-hook (nth 0 init) (nth 1 init) append-p local-p)
(funcall 'remove-hook (nth 0 init) (nth 1 init) local-p))))
(t
(ergoemacs-reset var))))))
(setq ergoemacs-component-struct--applied-inits '()))
(add-hook 'ergoemacs-mode-shutdown-hook #'ergoemacs-component-struct--remove-inits)
(defun ergoemacs-component-struct--versions (&optional obj)
"Get Versions available for OBJ.
If Object isn't specified assume it is for the current ergoemacs theme."
(let ((obj (or obj (ergoemacs-theme-components obj))))
(if (not obj)
(error "`ergoemacs-theme-components' could not be detected")
(sort (cond
((consp obj)
(let (ret)
(dolist (cur-obj (ergoemacs-component-struct--lookup-hash obj))
(dolist (ver (ergoemacs-component-struct-versions cur-obj))
(unless (member ver ret)
(push ver ret))))
ret))
(t (ergoemacs-component-struct--versions (ergoemacs-component-struct--lookup-hash obj))))
'string<))))
(defun ergoemacs-component--regexp (&optional at-end)
"Return a regexp of `ergoemacs-mode' components.
AT-END will append a \"$\" to the end of the regular expression."
(let (ret)
(maphash
(lambda(key _item) (push key ret))
ergoemacs-component-hash)
(setq ret (regexp-opt ret 'symbols))
(when at-end
(setq ret (concat ret "$")))
ret))
(defun ergoemacs-component--help-link-1 ()
"Setup crosreferences for help."
(let (tmp)
;; Link commands
(goto-char (match-beginning 0))
(when (and (re-search-backward "\\_<\\(.*?\\)\\_> *\\=" nil t)
(setq tmp (intern (match-string 1)))
(fboundp tmp)
(commandp tmp))
(help-xref-button 1 'help-function tmp))
;; Add button properties back
(when (and tmp ergoemacs-display-key-use-face-p)
(setq tmp (point))
(beginning-of-line)
(while (and (not (looking-at "Relative To:")) (re-search-forward "\\(.*?\\)[ +]" tmp t))
(add-text-properties (match-beginning 1) (match-end 1) '(face ergoemacs-display-key-face))))
(end-of-line)))
(defun ergoemacs-component--help-link ()
"Links `ergoemacs-mode' components in `help-mode' buffer."
(when (eq major-mode 'help-mode)
(save-excursion
(goto-char (point-min))
(let ((inhibit-read-only t)
(ree (format "^ - %s -- " (ergoemacs-component--regexp)))
(ret (format "^\"%s\" - " (ergoemacs-theme--regexp)))
(re (ergoemacs-component--regexp t))
(rem (ergoemacs-map-properties--map-regexp t))
(rel1 (ergoemacs-layout--regexp))
(rel2 (ergoemacs-layout--regexp 2))
tmp)
(with-syntax-table emacs-lisp-mode-syntax-table
(when (re-search-forward "^\\(\\_<.*\\_>\\) is .* component defined in `\\(.*\\)'" nil t)
(help-xref-button 2 'ergoemacs-component-def (match-string 1)))
(goto-char (point-min))
(while (re-search-forward rel1 nil t)
(help-xref-button 1 'ergoemacs-layout-help (match-string 1)))
(goto-char (point-min))
(while (re-search-forward rel2 nil t)
(help-xref-button 1 'ergoemacs-layout-help (match-string 1)))
(goto-char (point-min))
(when (re-search-forward "^\\(\\_<.*\\_>\\) is .* component defined in `\\(.*\\)'" nil t)
(help-xref-button 2 'ergoemacs-component-def (match-string 1)))
(goto-char (point-min))
(while (re-search-forward "\\(Variable Prefixes:\\|Unbound keys:\\|Masked emacs keys:\\) +" nil t)
(while (and (not (looking-at " *$")) (re-search-forward "\\(.*?\\)\\(, +\\| *$\\|[+ ]+\\)" (point-at-eol) t))
(add-text-properties (match-beginning 1) (match-end 1) '(face ergoemacs-display-key-face))))
(goto-char (point-min))
(when (re-search-forward "^\\(\\_<.*\\_>\\) is .* theme defined in `\\(.*\\)'" nil t)
(help-xref-button 2 'ergoemacs-theme-def (match-string 1)))
(goto-char (point-min))
(when (re-search-forward "^This theme is based on: *\\(\\_<.*\\_>\\)" nil t)
(help-xref-button 1 'ergoemacs-theme-help (match-string 1)))
(goto-char (point-min))
(while (re-search-forward ret nil t)
(help-xref-button 1 'ergoemacs-theme-help (match-string 1)))
(goto-char (point-min))
(while (re-search-forward ree nil t)
(help-xref-button 1 'ergoemacs-component-help (match-string 1)))
(goto-char (point-min))
(while (re-search-forward re nil t)
(help-xref-button 1 'ergoemacs-component-help (match-string 1))
(ergoemacs-component--help-link-1))
(goto-char (point-min))
(while (re-search-forward rem nil t)
(when (and (setq tmp (intern (match-string 1)))
(boundp tmp))
(help-xref-button 1 'help-variable tmp))
(ergoemacs-component--help-link-1))
(goto-char (point-min))
(when (search-forward "an `ergoemacs-mode' layout defined" nil t)
(setq bidi-display-reordering nil)))))))
(define-button-type 'ergoemacs-component-help
:supertype 'help-xref
'help-function #'ergoemacs-component-describe
'help-echo (purecopy "mouse-2, RET: describe this ergoemacs component"))
(define-button-type 'ergoemacs-component-def
:supertype 'help-xref
'help-function #'ergoemacs-component-find-definition
'help-echo (purecopy "mouse-2, RET: find this ergoemacs component's definition"))
(defcustom ergoemacs-component-find-regexp
(concat"^\\s-*(ergoemacs-\\(?:theme-?\\)?\\(?:component\\|package\\|autoload\\)?" find-function-space-re "%s\\(\\s-\\|$\\)")
"The regexp used to search for a component definition.
This is used by `ergoemacs-find-component' and it must contain a
`%s' at the place where `format' should insert the compenent
name."
:type 'regexp
:group 'find-function
:version "22.1")
(unless (assoc 'ergoemacs-component find-function-regexp-alist)
(push (cons 'ergoemacs-component 'ergoemacs-component-find-regexp) find-function-regexp-alist))
(defun ergoemacs-component-find-no-select (component &optional type)
"Find COMPONENT of TYPE.
TYPE can be 'ergoemacs-theme, if not it defaults to a single component."
(let* ((comp (or (and (eq type 'ergoemacs-theme)
(ergoemacs-gethash (format "%s" (or component "standard")) ergoemacs-theme-hash))
(ergoemacs-component-struct--lookup-hash (or component ""))))
(plist (and comp (or (and (eq type 'ergoemacs-theme) comp)
(ergoemacs-component-struct-plist comp))))
(file (and comp (plist-get plist :file)))
(el-file (and file (concat (file-name-sans-extension file) ".el")))
(name (plist-get plist :name))
(sym (intern name))
loc)
(if (not comp)
(message "Invalid %s %s" (or (and (eq type 'ergoemacs-theme) "theme")
"component") component)
(setq loc (find-function-search-for-symbol sym (or type 'ergoemacs-component) el-file))
(when (and (eq type 'ergoemacs-component) (not (cdr loc)) (< 6 (length name)))
(setq sym (intern (substring name 0 -6))
loc (find-function-search-for-symbol
sym (or type 'ergoemacs-component) el-file)))
loc)))
(defun ergoemacs-component-find-1 (symbol type switch-fn &optional buffer-point)
"Find `ergoemacs-mode' component or theme.
SYMBOL is the symbol representing the component or theme.
TYPE is nil to search for a component definition, or
'ergoemacs-theme, to find the theme.
The variable `find-function-recenter-line' controls how
to recenter the display. SWITCH-FN is the function to call
to display and select the buffer.
See also `find-function-after-hook'.
BUFFER-POINT is the point to move to. If it isn't specified,
find it with `ergoemacs-component-find-no-select'.
Modified from `find-definition-noselect'.
Set mark before moving, if the buffer already existed."
(let* ((orig-point (point))
(orig-buffers (buffer-list))
(buffer-point (or buffer-point
(save-excursion
(ergoemacs-component-find-no-select symbol type))))
(new-buf (car buffer-point))
(new-point (cdr buffer-point)))
(when buffer-point
(when (memq new-buf orig-buffers)
(push-mark orig-point))
(funcall switch-fn new-buf)
(when new-point (goto-char new-point))
(recenter find-function-recenter-line)
(run-hooks 'find-function-after-hook))))
(defun ergoemacs-component-find-definition (component)
"Find the definition of COMPONENT. COMPONENT defaults to the name near point.
Finds the `ergoemacs-mode' containing the definition of the component
near point (selected by `ergoemacs-component-at-point') in a buffer and
places point before the definition.
Set mark before moving, if the buffer already existed.
The library where FACE is defined is searched for in
`find-function-source-path', if non-nil, otherwise in `load-path'.
See also `find-function-recenter-line' and `find-function-after-hook'."
(interactive (list (ergoemacs-component-at-point)))
(ergoemacs-component-find-1 component 'ergoemacs-component 'switch-to-buffer))
(defun ergoemacs-component-at-point (&optional theme-instead)
"Get the `ergoemacs-component' defined at or before point.
When THEME-INSTEAD is non-nil, return the theme defined at that
point instead.
Return 0 if there is no such symbol. Based on
`variable-at-point'."
(let ((hash-table (or (and theme-instead ergoemacs-theme-hash)
ergoemacs-component-hash)))
(with-syntax-table emacs-lisp-mode-syntax-table
(or (condition-case ()
(save-excursion
(skip-chars-forward "'")
(or (not (zerop (skip-syntax-backward "_w")))
(eq (char-syntax (following-char)) ?w)
(eq (char-syntax (following-char)) ?_)
(forward-sexp -1))
(skip-chars-forward "'")
(let ((obj (read (current-buffer))))
(and (symbolp obj)
(ergoemacs-gethash (symbol-name obj) hash-table) obj)))
(error nil))
(let* ((str (find-tag-default))
(sym (if str (intern str))))
(if (and sym (ergoemacs-gethash (symbol-name sym) hash-table))
sym
(save-match-data
(when (and str (string-match "\\`\\W*\\(.*?\\)\\W*\\'" str))
(setq sym (intern (match-string 1 str)))
(and (ergoemacs-gethash (symbol-name sym) hash-table) sym)))))
0))))
(defun ergoemacs-component--prompt (&optional theme-instead)
"Prompt for component or theme (when THEME-INSTEAD is non-nil)."
(let ((c (or (and (eq theme-instead :layout) ergoemacs-keyboard-layout)
(ergoemacs-component-at-point theme-instead)))
(enable-recursive-minibuffers t)
val)
(setq val (completing-read (if (or (symbolp c) (stringp c))
(format
"Describe ergoemacs %s (default %s): "
(or (and (eq theme-instead :layout) "layout")
(and theme-instead "theme") "component")
c)
(format
"Describe ergoemacs %s: "
(or (and (eq theme-instead :layout) "layout")
(and theme-instead "theme") "component")))
(or (and (eq theme-instead :layout) (ergoemacs-layouts--list))
(and theme-instead ergoemacs-theme-hash)
ergoemacs-component-hash)
nil
;; (lambda (vv)
;; (or (get vv 'variable-documentation)
;; (and (boundp vv) (not (keywordp vv)))))
t nil nil
(format "%s" c)))
(list (or (and (equal val "") (format "%s" c)) val))))
(defun ergoemacs-component-cached-p (component)
"Determine if COMPONENT is cached instead of loaded."
(let* ((component (and component
(or (and (stringp component) component)
(and (symbolp component) (symbol-name component)))))
(comp (ergoemacs-component-struct--lookup-hash (or component "")))
(plist (ergoemacs-component-struct-plist comp))
(file (plist-get plist :file))
(el-file (and file (concat (file-name-sans-extension file) ".el")))
(elc-file (and file (concat (file-name-sans-extension file) ".elc"))))
(when file
(catch 'loaded
(dolist (load load-history)
(when (or (string= elc-file (car load))
(string= el-file (car load)))
(throw 'loaded nil))) t))))
(defun ergoemacs-component-describe (component)
"Display the full documentation of COMPONENT (a symbol or string)."
(interactive (ergoemacs-component--prompt))
(let* ((component (and component
(or (and (stringp component) component)
(and (symbolp component) (symbol-name component)))))
(comp (ergoemacs-component-struct--lookup-hash (or component "")))
(plist (ergoemacs-component-struct-plist comp))
(file (plist-get plist :file))
(el-file (and file (concat (file-name-sans-extension file) ".el")))
tmp vers
lst)
(if (not comp)
(message "You did not specify a valid ergoemacs component %s" component)
(help-setup-xref (list #'ergoemacs-component-describe (or component ""))
(called-interactively-p 'interactive))
(with-help-window (help-buffer)
(with-current-buffer standard-output
(insert (or component ""))
;; Use " is " instead of a colon so that
;; it is easier to get out the function name using forward-sexp.
(insert " is an `ergoemacs-mode' component")
(when (and el-file (file-readable-p el-file))
(insert " defined in `")
(insert (file-name-nondirectory el-file))
(when (looking-back "`\\(.*\\)" nil)
(help-xref-button 1 'ergoemacs-component-def component))
(insert "'."))
(insert "\n\n")
(insert "Documentation:\n")
(insert (plist-get plist :description))
(insert "\n\n")
(insert (format "Cached instead of loaded: %s\n" (or (and (ergoemacs-component-cached-p component) "Yes") "No")))
(insert "\nKnown component properties:\n")
(dolist (prop ergoemacs-theme-component-properties)
(when (setq tmp (plist-get plist prop))
(insert (format " %s -- %s\n" prop tmp))))
(insert "\n")
(insert (format "Plist: %s\n" plist))
(insert (format "Base Layout: %s\n" (ergoemacs-component-struct-layout comp)))
(when (looking-back ": \\(.*\\)\n" nil)
(help-xref-button 1 'ergoemacs-layout-help (match-string 1)))
(insert (format "Relative To: %s\n" (ergoemacs-component-struct-relative-to comp)))
(when (looking-back ": \\(.*\\)\n" nil)
(help-xref-button 1 'ergoemacs-layout-help (match-string 1)))
(insert (format "Variable Modifiers: %s\n" (ergoemacs-component-struct-variable-modifiers comp)))
(insert (format "Variable Prefixes: %s\n"
(mapconcat
(lambda(x) (ergoemacs-key-description x))
(ergoemacs-component-struct-variable-prefixes comp) ", ")))
(when (setq tmp (ergoemacs-component-struct-unbind comp))
(insert (format "Unbound keys: %s\n"
(mapconcat
(lambda(x) (ergoemacs-key-description x)) tmp ", "))))
(when (setq tmp (ergoemacs-component-struct-undefined comp))
(insert (format "Masked emacs keys: %s\n"
(mapconcat
(lambda(x) (ergoemacs-key-description x)) tmp ", "))))
;; FIXME: Describe major-mode / minor-mode differences
;; FIXME: Describe what keys are deferred, and what they would
;; possibly bind to...
(if (not (setq vers (ergoemacs-component-struct-versions comp)))
(setq lst `(("Specified Keymap" ,(ergoemacs-component-struct-map comp))
(,(format "Translated Keymap (%s)" ergoemacs-keyboard-layout) ,(ergoemacs-component-struct--get comp ergoemacs-keyboard-layout))))
(insert (format "Versions: %s, %s\n" ergoemacs-mode-version
(mapconcat
(lambda(x) x) vers ", ")))
(setq lst `((,(format "Specified Keymap (%s)" (or (ergoemacs-theme--get-version) ergoemacs-mode-version))
,(ergoemacs-component-struct-map comp))
,@(mapcar
(lambda(ver)
(unless (string= ver (ergoemacs-theme--get-version))
;; (ergoemacs-component-struct--get (ergoemacs-component-struct--lookup-hash 'search "5.7.5"))
`(,(format "Specified keymap for Version %s" ver)
,(ergoemacs-component-struct-map (ergoemacs-component-struct--lookup-hash component ver)))))
vers)
(,(format "Translated Keymap (%s; %s)" ergoemacs-keyboard-layout (or (ergoemacs-theme--get-version) ergoemacs-mode-version))
,(ergoemacs-component-struct--get comp ergoemacs-keyboard-layout))
,@(mapcar
(lambda(ver)
(unless (string= ver (ergoemacs-theme--get-version))
`(,(format "Translated keymap for Version %s" ver)
,(ergoemacs-component-struct--get (ergoemacs-component-struct--lookup-hash component ver) ergoemacs-keyboard-layout))))
vers)
)))
(dolist (elt lst)
(unless (or (not elt) (ergoemacs (nth 1 elt) :empty-p))
(insert "\n")
(insert (nth 0 elt))
(insert ":\n")
(insert (make-string 78 ?-))
(ergoemacs-key-description--keymap (nth 1 elt) t)
(insert "\n")))
(with-current-buffer standard-output
;; Return the text we displayed.
(buffer-string)))))))
(defalias 'describe-ergoemacs-component 'ergoemacs-component-describe)
(defun ergoemacs-component--diminish-on (plist &optional dim type)
"Apply `diminish' to PLIST for theme component.
The :dimininish tag can be of the form:
- t -- Removes the package name (PLIST :package-name) from the
minor mode display list.
- minor-mode symbol -- Removes the symbol from the minor mode
display list.
- string -- Replace the minor mode symbol with a string.
- (string1 string2) -- Unicode (string1) and terminal (string2)
displays. The display is determined by
`ergoemacs-key-description--unicode-char'.
- (minor-mode-symbol) -- Suppress minor mode symbol
- (minor-mode-symbol string) -- Replace minor mode symbol
modeline indicator with string
- (minor-mode-symbol string1 string2) -- Replace
minor-mode-symbol indicator with unicode (string1) or
terminal (string2) indicators. The display is determined by
`ergoemacs-key-description--unicode-char'.
- List of minor mode symbols, or list specifications that include
the minor- mode symbol, so that multiple minor modes may be
processed by a single :diminish specifciation.
DIM is the replacement for the PLIST :diminish, this is used in
recursive calls to `ergoemacs-component--diminish-on' to process
lists. It can also be the symbol name of the package.
uu
When TYPE is non-nil, the function turns off the diminish
modifications with `diminish-undo'"
(ignore-errors (ergoemacs-component-struct--ensure 'diminish))
(require 'diminish nil t)
(if (not (featurep 'diminish))
(message "Error installing diminish package.")
(let ((diminish-symbol (or (plist-get plist :package-name)
(plist-get plist :name)
plist))
(dim (or dim (plist-get plist :diminish))))
(when (and diminish-symbol (stringp diminish-symbol))
(setq diminish-symbol (intern diminish-symbol)))
(cond
((not dim))
;; :diminish t
((eq t dim)
(cond
(type (diminish-undo diminish-symbol))
((ignore-errors (and (commandp diminish-symbol t) (not (ergoemacs-autoloadp diminish-symbol))
(diminish diminish-symbol)))
)
(t (eval-after-load diminish-symbol
`(diminish ',diminish-symbol)))))
;; :diminish mode
((symbolp dim)
(cond
(type (diminish-undo dim))
((ignore-errors (and (commandp diminish-symbol t) (not (ergoemacs-autoloadp diminish-symbol))
(diminish dim))))
(t (eval-after-load diminish-symbol
`(diminish ',dim)))))
;; :diminish " g"
((stringp dim)
(cond
(type (diminish-undo diminish-symbol))
((ignore-errors (and (commandp diminish-symbol t) (not (ergoemacs-autoloadp diminish-symbol))
(diminish diminish-symbol dim))))
(t (eval-after-load diminish-symbol
`(diminish ',diminish-symbol ,dim)))))
((and (consp dim)
(= 1 (length dim))
(symbolp (nth 0 dim)))
(cond
(type (diminish-undo (nth 0 dim)))
((ignore-errors (and (commandp (nth 0 dim) t) (not (ergoemacs-autoloadp (nth 0 dim)))
(diminish (nth 0 dim) dim))))
(t (eval-after-load diminish-symbol
`(diminish ',(nth 0 dim))))))
;; :diminish (" " " g")
((and (consp dim)
(= 2 (length dim))
(stringp (nth 0 dim))
(stringp (nth 1 dim)))
(cond
(type (diminish-undo diminish-symbol))
((ignore-errors (and (commandp diminish-symbol t) (not (ergoemacs-autoloadp diminish-symbol))
(diminish diminish-symbol (ergoemacs :unicode (nth 0 dim) (nth 1 dim))))))
(t (eval-after-load diminish-symbol
`(ignore-errors
(diminish ',diminish-symbol
,(ergoemacs :unicode (nth 0 dim) (nth 1 dim))))))))
;;:diminish (" 🌈" " ⓡ" " r")
((and (consp dim)
(= 3 (length dim))
(stringp (nth 0 dim))
(stringp (nth 1 dim))
(stringp (nth 3 dim)))
(cond
(type (diminish-undo diminish-symbol))
((ignore-errors (and (commandp diminish-symbol t) (not (ergoemacs-autoloadp diminish-symbol))
(diminish diminish-symbol (ergoemacs :unicode (nth 0 dim) (ergoemacs :unicode (nth 1 dim) (nth 2 dim)))))))
(t (eval-after-load diminish-symbol
`(ignore-errors
(diminish ',diminish-symbol
,(ergoemacs :unicode (nth 0 dim) (ergoemacs :unicode (nth 1 dim) (nth 2 dim)))))))))
;; :diminish (mode " " " g")
((and (consp dim)
(= 3 (length dim))
(symbolp (nth 0 dim))
(stringp (nth 1 dim))
(stringp (nth 2 dim)))
(cond
(type (diminish-undo (nth 0 dim)))
((ignore-errors (and (commandp (nth 0 dim) t) (not (ergoemacs-autoloadp (nth 0 dim)))
(diminish (nth 0 dim) (ergoemacs :unicode (nth 1 dim) (nth 2 dim))))))
(t (eval-after-load diminish-symbol
`(ignore-errors
(diminish ',(nth 0 dim)
,(ergoemacs :unicode (nth 1 dim) (nth 2 dim))))))))
;; :diminish (rainbow-mode " 🌈" " ⓡ" " r")
((and (consp dim)
(= 4 (length dim))
(symbolp (nth 0 dim))
(stringp (nth 1 dim))
(stringp (nth 2 dim))
(stringp (nth 3 dim)))
(cond
(type (diminish-undo (nth 0 dim)))
((ignore-errors (and (commandp (nth 0 dim) t) (not (ergoemacs-autoloadp (nth 0 dim)))
(diminish (nth 0 dim) (ergoemacs :unicode (nth 1 dim) (ergoemacs :unicode (nth 2 dim) (nth 3 dim)))))))
(t (eval-after-load diminish-symbol
`(ignore-errors
(diminish ',(nth 0 dim)
,(ergoemacs :unicode (nth 1 dim) (ergoemacs :unicode (nth 2 dim) (nth 3 dim)))))))))
;; :diminish (mode " ")
((and (consp dim)
(= 2 (length dim))
(symbolp (nth 0 dim))
(stringp (nth 1 dim)))
(cond
(type (diminish-undo (nth 0 dim)))
((ignore-errors (and (commandp (nth 0 dim) t) (not (ergoemacs-autoloadp (nth 0 dim)))
(diminish (nth 0 dim) (nth 1 dim)))))
(t (eval-after-load diminish-symbol
`(diminish ',(nth 0 dim) ,(nth 1 dim))))))
((consp dim)
(dolist (elt dim)
(ergoemacs-component--diminish-on plist elt type)))))))
(defun ergoemacs-component--diminish-off (plist)
"Remove `diminish' top PLIST for theme component.
Wrapper for `ergoemacs-component--diminish-on'."
(ergoemacs-component--diminish-on plist nil t))
(provide 'ergoemacs-component)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ergoemacs-component.el ends here
;; Local Variables:
;; coding: utf-8-emacs
;; End:
ergoemacs-mode-5.16.10.12/ergoemacs-mapkeymap.el 0000644 0001752 0001753 00000020611 13332260074 017676 0 ustar elpa elpa ;;; ergoemacs-mapkeymap.el --- Ergoemacs map interface -*- lexical-binding: t -*-
;; Copyright © 2013-2015 Free Software Foundation, Inc.
;; Filename: ergoemacs-mapkeymap.el
;; Description:
;; Author: Matthew L. Fidler
;; Maintainer: Matthew L. Fidler
;; Created: Sat Sep 28 20:10:56 2013 (-0500)
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;;
;; Function to map over a KEYMAP
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Change Log:
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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 .
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(require 'cl-lib)
(eval-when-compile
(require 'ergoemacs-macros))
(declare-function ergoemacs-map-properties--all-sparse-p "ergoemacs-map-properties")
(declare-function ergoemacs-map-properties--composed-list "ergoemacs-map-properties")
(declare-function ergoemacs-setcdr "ergoemacs-lib")
(declare-function ergoemacs-map-properties--original "ergoemacs-map-properties")
(defun ergoemacs-map-force-full-keymap (keymap)
"Force KEYMAP to be a full keymap."
(if (ignore-errors (char-table-p (nth 1 keymap))) keymap
(ergoemacs-setcdr keymap (cons (nth 1 (make-keymap)) (cdr keymap)))
keymap))
(defun ergoemacs-map-set-char-table-range (keymap range value)
"Set the KEYMAP's char-table RANGE to VALUE.
If KEYMAP is sparse keymap, make it a full keymap."
(set-char-table-range
(nth 1 (ergoemacs-map-force-full-keymap keymap)) range value))
(defvar ergoemacs-map-keymap--load-autoloads-p t
"Determines if `ergoemacs-map-keymap' will load autoloads when mapping over a keymap.")
(defun ergoemacs-map-keymap--expose-keymap (keymap)
"Change KEYMAP into the keymap value.
This accepts symbols, functions, or autoloads.
If `ergoemacs-mode' cant determine the value, return nil."
(let (tmp)
(or (and (listp keymap) keymap)
(and (symbolp keymap) (boundp keymap) (setq tmp (symbol-value keymap))
(ergoemacs-keymapp tmp) tmp)
(and (symbolp keymap) (fboundp keymap)
(setq tmp (symbol-function keymap))
(or (and (ergoemacs-keymapp tmp) tmp)
(and (eq 'autoload (car tmp))
ergoemacs-map-keymap--load-autoloads-p
;; load required keymap.
(load (nth 1 tmp))
(or (and (boundp keymap) (setq tmp (symbol-value keymap))
(ergoemacs-keymapp tmp) tmp)
(and (fboundp keymap) (setq tmp (symbol-function keymap))
(ergoemacs-keymapp tmp) tmp))))))))
(defun ergoemacs-map-keymap--map-submap (sub-keymap function &optional original prefix flat-keymap nil-keys)
"Expose SUB-KEYMAP, then apply `ergoemacs-map-keymap'.
The sub-keymap is exposed by
`ergoemacs-map-keymap--expose-keymap'.
The `ergoemacs-map-keymap' uses the FUNCTION, ORIGINAL PREFIX
FLAT-KEYMAP and NIL-KEYS arguments. It is missing the keymap
argument, since it is calculated from the exposed sub-keymap."
(let ((tmp (ergoemacs-map-keymap--expose-keymap sub-keymap)))
(when tmp
(ergoemacs-map-keymap function
(cond
((eq original :setcdr)
(ergoemacs-setcdr (cdr tmp)
(cdr (ergoemacs :original tmp))))
(original
(ergoemacs :original tmp))
(t tmp))
original prefix flat-keymap nil-keys))))
(defun ergoemacs-map-keymap (function keymap &optional original prefix flat-keymap nil-keys)
"Call FUNCTION for all keys in hash table KEYMAP.
This is different from `map-keymap' because it sends keys instead
of events, and recurses into keymaps.
If ORIGINAL is :setcdr, use `ergoemacs-setdcdr' to modify the
subkeymaps to have the original keymaps.
If ORIGINAL is non-nil, use the original keys in all submaps, but
don't modify the sub-keymaps.
If ORIGINAL is nil, use the subkeymaps as they stand.
This function is called recursively, so PREFIX represents the
prefix key that is being explored in the keymap.
When non-nil, FLAT-KEYMAP will changed a composed keymap, or a
keymap with parent to a un-composed keymap without any parent keymaps.
NIL-KEYS is a list of keys that are defined as nil. This allows
them to be masked when mapping over the keymap."
(let ((flat-keymap (or flat-keymap
(if (ergoemacs-map-properties--all-sparse-p keymap)
(make-sparse-keymap)
(make-keymap))))
composed-list
parent
calc-parent-p
prefix-map
tmp)
(when (ergoemacs-keymapp keymap)
(map-keymap
(lambda(event item)
(let ((key (or (and (consp event)
(cons (vconcat prefix (vector (car event)))
(vconcat prefix (vector (cdr event)))))
(vconcat prefix (or (and (stringp event) event)
(vector event))))))
(cond
((and (not (consp event));; Defined as nil.
(member key nil-keys)))
((and (not (consp event))
(setq tmp (lookup-key flat-keymap key))
(not (integerp tmp)))
;; Already defined; don't define again.
)
((and (consp event) (ergoemacs-keymapp item))
;; Unclear what to do here...
)
((ergoemacs-keymapp item)
(when function
(funcall function key 'ergoemacs-prefix))
(ergoemacs-map-keymap--map-submap item function original key flat-keymap nil-keys)
(unless calc-parent-p
(setq composed-list (ergoemacs :composed-list keymap)
parent (keymap-parent keymap)))
(if composed-list
(dolist (map composed-list)
(when (and (ergoemacs-keymapp map)
(setq prefix-map (lookup-key map key))
(ergoemacs-keymapp prefix-map))
(ergoemacs-map-keymap--map-submap prefix-map function original key flat-keymap nil-keys)))
(unwind-protect
(progn
(when parent
(set-keymap-parent keymap nil))
(when (and (ergoemacs-keymapp prefix-map)
(setq prefix-map (lookup-key keymap key))
(ergoemacs-keymapp prefix-map))
(ergoemacs-map-keymap--map-submap prefix-map function original key flat-keymap nil-keys)))
(when parent
(set-keymap-parent keymap parent))))
(when parent
(when (and (ergoemacs-keymapp parent)
(setq prefix-map (lookup-key parent key))
(ergoemacs-keymapp prefix-map))
(ergoemacs-map-keymap--map-submap prefix-map function original key flat-keymap nil-keys))))
(t
(when function
(funcall function key item))
(cond
((consp event)
(ergoemacs-map-set-char-table-range
(or (and prefix (lookup-key flat-keymap prefix))
flat-keymap) event item))
(t
(define-key flat-keymap key item)
(unless item
(push key nil-keys))))))))
keymap))
flat-keymap))
(provide 'ergoemacs-mapkeymap)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ergoemacs-mapkeymap.el ends here
;; Local Variables:
;; coding: utf-8-emacs
;; End:
ergoemacs-mode-5.16.10.12/.gitignore 0000644 0001752 0001753 00000000314 13332260074 015413 0 ustar elpa elpa *~
~*
out/*
ChangeLog
*-autoloads.el
*-pkg.el
*.elc
\#*\#
.\#*
/out/
*-autoloads.el
*-pkg.el
flycheck_*
ergoemacs-global*.el
ergoemacs-global*.el.gz
ergoemacs-global*.elc.gz
ergoemacs-global*.elc
/.cask/
ergoemacs-mode-5.16.10.12/ergoemacs-score.el 0000644 0001752 0001753 00000042732 13332260074 017035 0 ustar elpa elpa ;;; ergoemacs-score.el --- Ergoemacs ergonomic score -*- lexical-binding: t -*-
;; Copyright © 2013-2015 Free Software Foundation, Inc.
;; Filename: ergoemacs-score.el
;; Author: Matthew L. Fidler
;; Maintainer:
;;
;;; Commentary:
;;
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Change Log:
;;
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 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 .
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Code:
(defvar ergoemacs-track-hand
'(0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
0 0 0 0 0 0 0 1 1 1 1 1 1 1 1)
"Based on ergoemcs-layouts, which hand is typing?
0 represents left, 1 represents right.")
(defvar ergoemacs-track-row
'(1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4)
"Based on ergoemacs-layouts, what row is being used?
1 = 1st row/number row
2 = 2nd row
3 = 3rd row/home row
4 = 4th row")
(defvar ergoemacs-track-finger
' (0 0 0 1 2 3 3 4 4 5 6 7 7 7 7
0 0 0 1 2 3 3 4 4 5 6 7 7 7 7
0 0 0 1 2 3 3 4 4 5 6 7 7 7 7
0 0 0 1 2 3 3 4 4 5 6 7 7 7 7
0 0 0 1 2 3 3 4 4 5 6 7 7 7 7
0 0 0 1 2 3 3 4 4 5 6 7 7 7 7
0 0 0 1 2 3 3 4 4 5 6 7 7 7 7
0 0 0 1 2 3 3 4 4 5 6 7 7 7 7)
"Track the finger based on the ergoemacs-layout.
0 = left pinky,
1 = left ring
2 = left middle
3 = left pointer
4 = right pointer
5 = right middle
6 = right ring
7 = right pinky
")
;; These are taken from http://www.colemak.com/wiki/index.php?title=Compare
(defvar ergoemacs-key-width 18.0
"Assumption of key width (in px)")
(defvar ergoemacs-key-height 22.0
"Assumption of key height (in px)")
(defvar ergoemacs-tab-key-width 28.0
"Assumption of key width (in px)")
(defvar ergoemacs-lock-key-width 34.0
"Assumption of lock key width (in px)")
(defvar ergoemacs-shift-key-width 26.0
"Assumption of shift key width (in px)")
(defvar ergoemacs-return-key-width 36.0
"Assumption of return key width (in px)")
(defvar ergoemacs-tab-key-width 28.0
"Assumption of tab key width (in px)")
(defvar ergoemacs-key-width-m 0.010
"Default key width (in m)")
(defvar ergoemacs-keyboard-coordinates-x nil
"Keyboard x-coordinates (in m)")
(defvar ergoemacs-keyboard-coordinates-y nil
"Keyboard y-coordinates (in m)")
(defun ergoemacs-calculate-keyboard-coordinates ()
"Calculates `ergoemacs-keyboard-coordinates-x' and
`ergoemacs-keyboard-coordintes-y'"
(setq ergoemacs-keyboard-coordinates-x
(let ((i 0)
(last 0)
curr)
(mapcar
(lambda(_x)
(setq i (+ i 1))
(setq curr (+ last (/ ergoemacs-tab-key-width 2)))
(cond
((or (= 17 i) (= 58 i))
(setq last ergoemacs-tab-key-width))
((or (= 34 i) (= 75 i))
(setq last ergoemacs-lock-key-width))
((or (= 41 i) (= 92 i))
(setq last ergoemacs-shift-key-width))
(t
(setq last (+ last ergoemacs-key-width))))
(* (/ ergoemacs-key-width-m ergoemacs-key-width) curr))
ergoemacs-track-finger)))
(setq ergoemacs-keyboard-coordinates-y
(let ((i 0)
(last 0)
curr)
(mapcar
(lambda(_x)
(setq i (+ i 1))
(setq curr (+ last (/ ergoemacs-tab-key-width 2)))
(cond
((= 58 i)
(setq last 0))
((or (= 17 i) (= 34 i) (= 75 i)(= 41 i) (= 92 i))
(setq last (+ last ergoemacs-tab-key-width))))
(* (/ ergoemacs-key-width-m ergoemacs-key-width) curr))
ergoemacs-track-finger))))
(ergoemacs-calculate-keyboard-coordinates)
(defun ergoemacs-key-properties (key layout &optional curr-i)
"Key the KEY properties based on ergoemacs LAYOUT"
(let ((i 0)
(lay (intern-soft (format "ergoemacs-layout-%s" layout)))
wi xh yh xc yc
dx dy
ret)
(when lay
(if curr-i
(setq wi curr-i)
(dolist (x (ergoemacs-sv lay))
(when (string= key x)
(setq wi i))
(setq i (+ i 1))))
(setq i wi)
(setq xh (nth (if (<= (nth i ergoemacs-track-finger) 3)
(+ 32 (nth i ergoemacs-track-finger))
(+ 38 (- (nth i ergoemacs-track-finger) 4)))
ergoemacs-keyboard-coordinates-x))
(setq yh (nth (if (<= (nth i ergoemacs-track-finger) 3)
(+ 32 (nth i ergoemacs-track-finger))
(+ 38 (- (nth i ergoemacs-track-finger) 4)))
ergoemacs-keyboard-coordinates-y))
(setq xc (nth i ergoemacs-keyboard-coordinates-x))
(setq yc (nth i ergoemacs-keyboard-coordinates-y))
(setq dx (- xc xh))
(setq dy (- yc yh))
(setq ret
`(:x ,xc
:y ,yc
:x-home ,xh
:y-home ,yh
:d-home ,(sqrt (+ (* dx dx) (* dy dy)))
:hand ,(if (= 0 (nth i ergoemacs-track-hand))
'left
'right)
:finger ,(cond
((or (= 0 (nth i ergoemacs-track-finger))
(= 7 (nth i ergoemacs-track-finger)))
'pinky)
((or (= 1 (nth i ergoemacs-track-finger))
(= 6 (nth i ergoemacs-track-finger)))
'ring)
((or (= 2 (nth i ergoemacs-track-finger))
(= 5 (nth i ergoemacs-track-finger)))
'middle)
(t
'pointer))
:finger-n ,(nth i ergoemacs-track-finger)
:row-n ,(nth i ergoemacs-track-row)
:row ,(cond
((= 1 (nth i ergoemacs-track-row))
'number)
((= 2 (nth i ergoemacs-track-row))
'top)
((= 3 (nth i ergoemacs-track-row))
'home)
((= 4 (nth i ergoemacs-track-row))
'bottom))))
ret)))
(defvar ergoemacs-key-hash nil
"Key hash")
(defvar ergoemacs-distance-hash nil
"Distance hash.")
(setq ergoemacs-distance-hash (make-hash-table :test 'equal))
(setq ergoemacs-key-hash (make-hash-table :test 'equal))
(declare-function ergoemacs-get-layouts "ergoemacs-layouts.el")
(dolist (layout (ergoemacs-get-layouts t))
(let ((lay (intern-soft (format "ergoemacs-layout-%s" layout))))
(when lay
(dolist (key (ergoemacs-sv lay))
(unless (string= key "")
(puthash (cons layout key)
(ergoemacs-key-properties key layout)
ergoemacs-key-hash))))))
(defun ergoemacs-key-distance (key1 key2 &optional last-plist layout)
"Gets the key distance based on the layout.
KEY1 is the first key pressed.
KEY2 is the second key pressed.
LAYOUT is the ergoemacs-layout used.
LAST-PLIST is the last property list returned by this function or nil if nothing was returned previously."
(if layout
(let ((ret (ergoemacs-gethash (cons (cons key1 key2) (cons last-plist layout)) ergoemacs-key-hash)))
(if ret
ret
(let ((kp1 (ergoemacs-gethash (cons layout key1) ergoemacs-key-hash))
(kp2 (ergoemacs-gethash (cons layout key2) ergoemacs-key-hash))
kpl kpl1
(kp12 (ergoemacs-gethash (cons layout (cons key1 key2)) ergoemacs-key-hash))
dx dy)
(when (and (not kp12) kp1 kp2
(eq (plist-get kp1 :finger-n) (plist-get kp2 :finger-n)))
(setq dx (- (plist-get kp1 :x) (plist-get kp2 :x)))
(setq dy (- (plist-get kp1 :y) (plist-get kp2 :y)))
(setq kp12 (sqrt (+ (* dx dx) (* dy dy))))
(puthash (cons layout (cons key1 key2)) kp12 ergoemacs-key-hash))
(cond
((and (not last-plist) (not kp1) (not kp2))
(setq ret `(:d 0 :dh 0
:finger-n -10
:key ,key2)))
((and last-plist (not kp1) (not kp2))
(setq ret `(:d ,(plist-get last-plist :dh) :dh 0
:finger-n -10
:key ,key2)))
((and (not last-plist) kp1 (not kp2))
;; kp2 is not defined. Assume space or no-length character.
(setq ret `(:d ,(* 2 (plist-get kp1 :d-home)) :dh 0
:finger-n -10
:key ,key2)))
((and (not last-plist) (not kp1) kp2)
;; kp1 is not defined. Assume space or no-length character.
(setq ret `(:d ,(plist-get kp2 :d-home) :dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))
((and last-plist (not kp1) kp2)
;; kp1 is not defined. Assume space or no-length character.
(setq ret `(:d ,(+ (plist-get last-plist :dh)
(plist-get kp2 :d-home))
:dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))
((and last-plist kp1 (not kp2)
(eq (plist-get last-plist :finger-n) (plist-get kp1 :finger-n)))
;; Last keypress was on the same finger as kp1. kp2 is a reset.
(setq kpl (ergoemacs-gethash (cons layout (plist-get last-plist :key)) ergoemacs-key-hash))
(setq kpl1 (ergoemacs-gethash (cons layout (cons (plist-get last-plist :key) key1))
ergoemacs-key-hash))
(when (not kpl1)
(setq dx (- (plist-get kpl :x) (plist-get kp1 :x)))
(setq dy (- (plist-get kpl :y) (plist-get kp1 :y)))
(setq kpl1 (sqrt (+ (* dx dx) (* dy dy))))
(puthash (cons layout
(cons (plist-get last-plist :key)
key1)) kp12 ergoemacs-key-hash))
(setq ret `(:d ,(+ kpl1 (plist-get kp1 :d-home)) :dh 0
:finger-n -10
:key ,key2)))
((and last-plist kp1 (not kp2))
;; last keypress was not on the same finger as kp1. kp2 is a
;; reset
(setq ret `(:d ,(+ (plist-get last-plist :dh)
(* 2 (plist-get kp1 :d-home)))
:dh 0
:finger-n -10
:key ,key2)))
((and (not last-plist)
(eq (plist-get kp1 :finger-n) (plist-get kp2 :finger-n)))
;; Distance when key1 and key2 are on the same finger is:
;; D(Home,Key1)+D(Key1,Key2)
;; Residual is D(Key2, Home)
(setq ret `(:d ,(+ (plist-get kp1 :d-home) kp12) :dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))
((not last-plist)
;; Distance when key1 and key2 are on a different finger is:
;; 2*D(Home,Key1)+D(Home,Key2)
;; Residual is D(Key2,Home)
(setq ret `(:d ,(+ (* 2 (plist-get kp1 :d-home))
(plist-get kp2 :d-home))
:dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))
((and (eq (plist-get last-plist :finger-n) (plist-get kp1 :finger-n))
(eq (plist-get last-plist :finger-n) (plist-get kp2 :finger-n)))
;; The last finger called is the same as the current finger
;; Key1 and Key 2 are on the same finger
;; Distance is D(Last-Key,Key1)+D(Key1,Key2)
;; Residual Distance is D(Key2,Home)
(setq kpl (ergoemacs-gethash (cons layout (plist-get last-plist :key)) ergoemacs-key-hash))
(setq kpl1 (ergoemacs-gethash (cons layout (cons (plist-get last-plist :key) key1))
ergoemacs-key-hash))
(when (not kpl1)
(setq dx (- (plist-get kpl :x) (plist-get kp1 :x)))
(setq dy (- (plist-get kpl :y) (plist-get kp1 :y)))
(setq kpl1 (sqrt (+ (* dx dx) (* dy dy))))
(puthash (cons layout
(cons (plist-get last-plist :key)
key1)) kp12 ergoemacs-key-hash))
(setq ret `(:d ,(+ kpl1 kp12)
:dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))
((and (eq (plist-get last-plist :finger-n) (plist-get kp1 :finger-n)))
;; The last finger is the same as kp1. the kp1 finger is
;; different from kp2.
;;
;; Distance is D(Last,kp1)+D(kp1,home)+D(kp2,home)
;; Residual is D(kp2,home)
(setq kpl (ergoemacs-gethash (cons layout (plist-get last-plist :key)) ergoemacs-key-hash))
(setq kpl1 (ergoemacs-gethash (cons layout (cons (plist-get last-plist :key) key1))
ergoemacs-key-hash))
(when (not kpl1)
(setq dx (- (plist-get kpl :x) (plist-get kp1 :x)))
(setq dy (- (plist-get kpl :y) (plist-get kp1 :y)))
(setq kpl1 (sqrt (+ (* dx dx) (* dy dy))))
(puthash (cons layout
(cons (plist-get last-plist :key)
key1)) kp12 ergoemacs-key-hash))
(setq ret `(:d ,(+ kpl1 (plist-get kp1 :d-home) (plist-get kp2 :d-home))
:dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))
((and
(not (eq (plist-get last-plist :finger-n) (plist-get kp1 :finger-n)))
(eq (plist-get kp1 :finger-n) (plist-get kp2 :finger-n)))
;; The last finger called not the same as kp1
;; key1 and key2 are on the same finger.
;; Distance is D(Last-Key,home)+D(Key1,Key2)
;; Residual Distance is D(Key2,Home)
(setq ret `(:d ,(+ (plist-get last-plist :dh) kp12)
:dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))
(t
;; The three fingers are on different hands or the last finger
;; pressed and kp2 are on the same hand. For this layout the
;; distance is given by:
;; d(Last,Home)+2*D(home,kp1)+D(home,kp2)
;; Residual distance is D(kp2,home)
(setq ret `(:d ,(+ (plist-get last-plist :dh)
(* 2 (plist-get kp1 :d-home))
(plist-get kp2 :d-home))
:dh ,(plist-get kp2 :d-home)
:finger-n ,(plist-get kp2 :finger-n)
:key ,key2)))))
(puthash (cons (cons key1 key2) (cons last-plist layout)) ret ergoemacs-key-hash)
ret))
(let (ret)
(setq ret
(mapcar
(lambda(lay)
(let (last-p
(dist (ergoemacs-gethash lay ergoemacs-distance-hash 0))
ret)
(when last-plist
(setq last-p (assoc lay last-plist))
(when last-p
(setq last-p (cadr last-p))))
(setq ret (ergoemacs-key-distance key1 key2 last-p lay))
(puthash lay (+ dist (plist-get ret :d)) ergoemacs-distance-hash)
`(,lay ,ret)))
(ergoemacs-get-layouts)))
ret)))
(defvar ergoemacs-last-distance-plist nil
"Last distance plist")
(defvar ergoemacs-last-key-press nil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; ergoemacs-score.el ends here
;; Local Variables:
;; coding: utf-8-emacs
;; End:
ergoemacs-mode-5.16.10.12/os_x_qwerty.dict.txt 0000644 0001752 0001753 00000004045 12337175720 017505 0 ustar elpa elpa /*
DATE: 2010-06-15
VERSION: 1.0
AUTHOR: Xah Lee
DESCRIPTION: Mac OS X keybinding file for the ErgoEmacs keybinding for QWERTY layout.
INSTALL:
Rename this file to “DefaultKeyBinding.dict”
Then, place the file in this dir:
“~/Library/KeyBindings/DefaultKeyBinding.dict”
Create the “KeyBindings” dir if you don't have it already.
Go to your system preference, “Keyboard & Mouse” panel, and swap
Control and Command key positions. So, Control is right under your
thumb.
Now, launch or re-launch any Cocoa application, such as TextEdit. The app should now use ErgoEmacs keybinding.
If you are using emacs, you might want to put the following lines in your “.emacs”:
(setq mac-control-modifier 'meta)
(setq mac-command-modifier 'control)
These lines works for Cocoa emacs, may not work for Carbon Emacs.
Some references:
• How To Create Keybinding In Mac OS X
http://xahlee.org/emacs/osx_keybinding.html
• ErgoEmacs Keybinding
http://xahlee.org/emacs/ergonomic_emacs_keybinding.html
• How to Swap Modifier Keys on OS X
http://xahlee.org/emacs/osx_swapping_modifier_keys.html
If you like to use Option key instead of Control, you can change all ^
to ~ in this file. However, due to some limitations of the OS X
keybinding system, the following won't work:
• Opt+n for move cursor right
• Opt+e for deleting a char to the left
• Opt+u for deleting a char to the right
*/
{
"^i" = "moveUp:";
"^k" = "moveDown:";
"^j" = "moveLeft:";
"^l" = "moveRight:";
"^o" = "moveWordRight:";
"^u" = "moveWordLeft:";
"^h" = "moveToBeginningOfLine:";
"^H" = "moveToEndOfLine:";
"^I" = "pageUp:";
"^K" = "pageDown:";
"^U" = "moveToBeginningOfParagraph:";
"^O" = "moveToEndOfParagraph:";
"^J" = "moveToBeginningOfDocument:";
"^L" = "moveToEndOfDocument:";
"^d" = "deleteBackward:";
"^f" = "deleteForward:";
"^e" = "deleteWordBackward:";
"^r" = "deleteWordForward:";
"^Z" = "redo:";
"^z" = "undo:";
"^x" = "cut:";
"^X" = ("selectAll:", "cut:");
"^c" = "copy:";
"^C" = ("selectAll:", "copy:");
"^v" = "paste:";
"^8" = "selectWord:";
"^ " = "setMark:";
}
ergoemacs-mode-5.16.10.12/ergoemacs-mode-pkg.el 0000644 0001752 0001753 00000000450 13332404643 017416 0 ustar elpa elpa ;; Generated package description from ergoemacs-mode.el
(define-package "ergoemacs-mode" "5.16.10.12" "Emacs mode based on common modern interface and ergonomics." '((emacs "24.1") (undo-tree "0.6.5") (cl-lib "0.5")) :url "https://github.com/ergoemacs/ergoemacs-mode" :keywords '("convenience"))
ergoemacs-mode-5.16.10.12/kbd-ergo.html 0000644 0001752 0001753 00000716476 12337175720 016041 0 ustar elpa elpa
SVG TO HTML Converter 0.8
ergoemacs-mode-5.16.10.12/ergoemacs-themes.el 0000644 0001752 0001753 00000337113 13332260074 017207 0 ustar elpa elpa ;;; ergoemacs-themes.el --- ErgoEmacs keybindings and themes -*- lexical-binding: t -*-
;; Copyright © 2013-2018 Free Software Foundation, Inc.
;; Maintainer: Matthew L. Fidler
;; Authors: Matthew L. Fidler, Xah Lee, Drew Adams
;; Keywords: convenience
;; ErgoEmacs 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.
;; ErgoEmacs 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 ErgoEmacs. If not, see .
;;; Commentary:
;;
;; Todo:
;;
;;; Code:
(eval-when-compile
(require 'cl)
(require 'ergoemacs-macros))
(declare-function ergoemacs-theme-component--create-component "ergoemacs-theme")
(declare-function ergoemacs-component-struct--create-component "ergoemacs-component")
(declare-function ergoemacs-translate--create "ergoemacs-translate")
(declare-function ergoemacs-key-description--unicode-char "ergoemacs-key-description")
(declare-function ergoemacs-require "ergoemacs-lib")
(defvar ergoemacs-theme-hash)
(defvar ergoemacs-theme-component-hash)
(defvar ergoemacs-translation-hash)
(defvar ergoemacs-component-hash)
(defvar ergoemacs--component-file-mod-time-list)
(autoload 'dired-jump "dired-x" nil t)
(require 'advice)
(ergoemacs-package undo-tree
:ensure t
(global-undo-tree-mode 1))
(ergoemacs-package persistent-soft
:ensure t)
(ergoemacs-component standard-vars ()
"Enabled/changed variables/modes"
(setq org-CUA-compatible t
org-support-shift-select t
set-mark-command-repeat-pop t
org-special-ctrl-a/e t
ido-vertical-define-keys 'C-n-C-p-up-down-left-right
scroll-error-top-bottom t
initial-scratch-message (substitute-command-keys ";; This buffer is for notes you don't want to save, and for Lisp evaluation.\n;; If you want to create a file, visit that file with \\[find-file],\n;; then enter the text in that file's own buffer.")
;; Remove tutorial and guided tour, since the keys don't apply...
fancy-startup-text
`((:face (variable-pitch font-lock-comment-face)
"Welcome to "
:link ("GNU Emacs"
,(lambda (_button) (browse-url "http://www.gnu.org/software/emacs/"))
"Browse http://www.gnu.org/software/emacs/")
", one component of the "
:link
,(lambda ()
(if (eq system-type 'gnu/linux)
`("GNU/Linux"
,(lambda (_button) (browse-url "http://www.gnu.org/gnu/linux-and-gnu.html"))
"Browse http://www.gnu.org/gnu/linux-and-gnu.html")
`("GNU" ,(lambda (_button) (describe-gnu-project))
"Display info on the GNU project")))
" operating system.\n\n"
"\n"
;; :link ("Emacs Guided Tour"
;; ,(lambda (_button)
;; (browse-url "http://www.gnu.org/software/emacs/tour/"))
;; "Browse http://www.gnu.org/software/emacs/tour/")
;; "\tOverview of Emacs features at gnu.org\n"
:link ("View Emacs Manual" ,(lambda (_button) (info-emacs-manual)))
"\tView the Emacs manual using Info\n"
:link ("Absence of Warranty" ,(lambda (_button) (describe-no-warranty)))
"\tGNU Emacs comes with "
:face (variable-pitch (:slant oblique))
"ABSOLUTELY NO WARRANTY\n"
:face variable-pitch
:link ("Copying Conditions" ,(lambda (_button) (describe-copying)))
"\tConditions for redistributing and changing Emacs\n"
:link ("Ordering Manuals" ,(lambda (_button) (view-order-manuals)))
"\tPurchasing printed copies of manuals\n"
"\n"))
;;
fancy-about-text
`((:face (variable-pitch font-lock-comment-face)
"This is "
:link ("GNU Emacs"
,(lambda (_button) (browse-url "http://www.gnu.org/software/emacs/"))
"Browse http://www.gnu.org/software/emacs/")
", one component of the "
:link
,(lambda ()
(if (eq system-type 'gnu/linux)
`("GNU/Linux"
,(lambda (_button)
(browse-url "http://www.gnu.org/gnu/linux-and-gnu.html"))
"Browse http://www.gnu.org/gnu/linux-and-gnu.html")
`("GNU" ,(lambda (_button) (describe-gnu-project))
"Display info on the GNU project.")))
" operating system.\n"
:face (variable-pitch font-lock-builtin-face)
"\n"
,(lambda () (emacs-version))
"\n"
:face (variable-pitch (:height 0.8))
,(lambda () emacs-copyright)
"\n\n"
:face variable-pitch
:link ("Authors"
,(lambda (_button)
(view-file (expand-file-name "AUTHORS" data-directory))
(goto-char (point-min))))
"\tMany people have contributed code included in GNU Emacs\n"
:link ("Contributing"
,(lambda (_button)
(view-file (expand-file-name "CONTRIBUTE" data-directory))
(goto-char (point-min))))
"\tHow to contribute improvements to Emacs\n"
"\n"
:link ("GNU and Freedom" ,(lambda (_button) (describe-gnu-project)))
"\tWhy we developed GNU Emacs, and the GNU operating system\n"
:link ("Absence of Warranty" ,(lambda (_button) (describe-no-warranty)))
"\tGNU Emacs comes with "
:face (variable-pitch (:slant oblique))
"ABSOLUTELY NO WARRANTY\n"
:face variable-pitch
:link ("Copying Conditions" ,(lambda (_button) (describe-copying)))
"\tConditions for redistributing and changing Emacs\n"
:link ("Getting New Versions" ,(lambda (_button) (describe-distribution)))
"\tHow to obtain the latest version of Emacs\n"
:link ("Ordering Manuals" ,(lambda (_button) (view-order-manuals)))
"\tBuying printed manuals from the FSF\n"
"\n"
;; :link ("Emacs Guided Tour"
;; ,(lambda (_button)
;; (browse-url "http://www.gnu.org/software/emacs/tour/"))
;; "Browse http://www.gnu.org/software/emacs/tour/")
;; "\tSee an overview of Emacs features at gnu.org"
)))
(add-hook 'dirtrack-directory-change-hook 'ergoemacs-shell-here-directory-change-hook)
(add-hook 'kill-buffer-hook 'ergoemacs-save-buffer-to-recently-closed)
(add-hook 'shell-mode-hook 'ergoemacs-shell-here-hook)
(add-hook 'eshell-post-command-hook 'ergoemacs-shell-here-directory-change-hook)
;; (dolist (hook '(dired-after-readin-hook after-change-major-mode-hook))
;; (add-hook hook 'ergoemacs-setup-local-prefixes))
(shift-select-mode t)
(delete-selection-mode 1)
(setq recentf-menu-before "Close"
recentf-menu-items-for-commands
(list
["Open Last Closed"
ergoemacs-open-last-closed
:help "Remove duplicates, and obsoletes files from the recent list"
:active t]
["Cleanup list"
recentf-cleanup
:help "Remove duplicates, and obsoletes files from the recent list"
:active t]
["Edit list..."
recentf-edit-list
:help "Manually remove files from the recent list"
:active t]
["Save list now"
recentf-save-list
:help "Save the list of recently opened files now"
:active t]
["Options..."
(customize-group "recentf")
:help "Customize recently opened files menu and options"
:active t]))
(recentf-mode (if noninteractive -1 1))
;; (setq cua--rectangle-modifier-key ergoemacs-cua-rect-modifier)
;; (setq cua--rectangle-keymap (make-sparse-keymap))
;; (setq cua--rectangle-initialized nil)
;; (setq cua--keymap-alist
;; (progn
;; (cua--init-rectangles)
;; `((cua--ena-prefix-override-keymap . ,cua--prefix-override-keymap)
;; (cua--ena-prefix-repeat-keymap . ,cua--prefix-repeat-keymap)
;; (cua--ena-cua-keys-keymap . ,cua--cua-keys-keymap)
;; (cua--ena-global-mark-keymap . ,cua--global-mark-keymap)
;; (cua--rectangle . ,cua--rectangle-keymap)
;; (cua--ena-region-keymap . ,cua--region-keymap)
;; (cua-mode . ,cua-global-keymap))))
)
(ergoemacs-component save-options-on-exit ()
"Save emacs options on exit"
(add-hook 'kill-emacs-hook 'ergoemacs-exit-customize-save-customized))
;;; Fixed components
(ergoemacs-component standard-fixed ()
"Standard Fixed Shortcuts"
:variable-reg nil ;; No variable keys
(global-set-key [tool-bar kill-buffer] 'ergoemacs-close-current-buffer)
(global-set-key (kbd "C-n") 'ergoemacs-new-empty-buffer)
(global-set-key (kbd "C-x C-f") nil) ;; Remove Emacs Method
(global-set-key (kbd "C-o") ("C-o" :emacs))
(global-set-key (kbd "C-S-o") 'ergoemacs-open-in-desktop)
(global-set-key (kbd "C-S-t") 'ergoemacs-open-last-closed)
(global-set-key (kbd "C-w") 'ergoemacs-close-current-buffer)
(global-set-key (kbd "C-s") nil) ;; Search Forward
(global-set-key (kbd "C-f") ("C-s" :emacs))
(global-set-key (kbd "C-x C-s") nil) ;; Save File
(global-set-key (kbd "C-s") ("C-x C-s" :emacs))
(global-set-key (kbd "C-x C-w") nil) ;; Write File
(global-set-key (kbd "C-S-s") ("C-x C-w" :emacs))
(global-set-key (kbd "C-p") 'ergoemacs-print-buffer-confirm)
(global-set-key (kbd "C-x h") nil) ;; Mark whole buffer
(global-set-key (kbd "C-a") ("C-x h" :emacs))
(global-set-key (kbd "C-z") 'undo)
;; Take out undo-tree's redo bindings
(define-key undo-tree-map (kbd "C-?") nil)
(define-key undo-tree-map (kbd "M-_") nil)
(global-set-key (kbd "C-S-z") '(redo undo-tree-redo ergoemacs-redo))
(global-set-key (kbd "") 'ergoemacs-cut-line-or-region)
(global-set-key (kbd "C-c ") 'ergoemacs-copy-line-or-region)
(global-set-key (kbd "") 'ergoemacs-copy-line-or-region)
(global-set-key (kbd "C-S-v") 'ergoemacs-paste-cycle)
(global-set-key (kbd "") 'ergoemacs-paste)
(global-set-key (kbd "C-v") 'ergoemacs-paste)
;; Navigation
(global-set-key (kbd "C-S-n") 'make-frame-command)
;; Text editing
;; the Del key for forward delete. Needed if C-d is set to nil.
(global-set-key (kbd "") 'delete-char )
(global-set-key (kbd "") 'kill-word)
(global-set-key (kbd "") 'kill-word)
(global-set-key (kbd "") 'move-beginning-of-line)
(global-set-key (kbd "") 'move-end-of-line)
(global-set-key (kbd "") 'beginning-of-buffer)
(global-set-key (kbd "") 'end-of-buffer)
(global-set-key (kbd "") 'backward-word)
(global-set-key (kbd "") 'forward-word)
(global-set-key (kbd "") 'ergoemacs-backward-block)
(global-set-key (kbd "") 'ergoemacs-forward-block)
;; C-H is search and replace.
;; C-1 to C-9 should be switch tab... Same as in Google chrome.
;; C-T should be new tab.
;; Refresh should be ; erogemacs uses .
;; C-r also should be refresh
(global-set-key (kbd "") 'revert-buffer)
(global-set-key (kbd "C-r") 'revert-buffer)
;; Text Formatting
;; Upper/Lower case toggle.
;; Ergoemacs fixed keys...
(global-set-key (kbd "") 'ergoemacs-delete-frame) ;; Alt+f4 should work.
; Alt+→
;; Allow shift selection
(global-set-key (kbd "") 'mouse-save-then-kill)
(global-set-key (kbd "") 'ignore)
(global-set-key (kbd "C-+") 'text-scale-increase)
(global-set-key (kbd "C--") 'text-scale-decrease)
(global-set-key (kbd "C-.") 'keyboard-quit)
(global-set-key (kbd "C-/") 'info)
(global-set-key (kbd "C-0") 'ergoemacs-text-scale-normal-size)
(global-set-key (kbd "C-") 'ergoemacs-next-user-buffer)
(global-set-key (kbd "C-") 'kill-compilation) ; stop compilation/find/grep
(global-set-key (kbd "C-") 'ergoemacs-previous-user-buffer)
(global-set-key (kbd "C-=") 'text-scale-increase)
(global-set-key (kbd "C-?") 'info)
(global-set-key (kbd "C-S-") 'ergoemacs-next-emacs-buffer)
(global-set-key (kbd "C-S-") 'ergoemacs-previous-emacs-buffer)
(global-set-key (kbd "C-S-f") 'occur)
(global-set-key (kbd "C-S-o") 'ergoemacs-open-in-external-app)
(global-set-key (kbd "C-S-s") 'write-file)
(global-set-key (kbd "C-S-t") 'ergoemacs-open-last-closed)
(global-set-key (kbd "C-S-w") 'delete-frame)
(global-set-key (kbd "C-`") 'other-frame)
(global-set-key (kbd "C-a") 'mark-whole-buffer)
(global-set-key (kbd "C-f") 'isearch-forward)
(global-set-key (kbd "C-l") 'goto-line)
(global-set-key (kbd "C-n") 'ergoemacs-new-empty-buffer)
(global-set-key (kbd "C-o") 'find-file)
(global-set-key (kbd "C-p") 'ergoemacs-print-buffer-confirm)
(global-set-key (kbd "C-x k") nil)
(global-set-key (kbd "C-w") 'ergoemacs-close-current-buffer)
(global-set-key (kbd "C-x ") 'ergoemacs-cut-line-or-region)
(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "C-y") '(redo undo-tree-redo ergoemacs-redo) "↷ redo")
(global-set-key (kbd "M-S-") 'forward-page)
(global-set-key (kbd "M-S-") 'backward-page)
;; Mode specific changes
(define-key org-mode-map (kbd "") 'ergoemacs-org-insert-heading-respect-content)
(define-key org-mode-map (kbd "") 'ergoemacs-org-metadown)
(define-key org-mode-map (kbd "") 'ergoemacs-org-metaup)
(define-key org-mode-map (kbd "") 'ergoemacs-org-metaleft)
(define-key org-mode-map (kbd "") 'ergoemacs-org-metaright)
(define-key org-mode-map (kbd "M-v") 'ergoemacs-org-yank)
(define-key org-mode-map (kbd "C-v") 'ergoemacs-org-yank)
(define-key browse-kill-ring-mode-map (kbd "C-f") 'browse-kill-ring-search-forward)
(define-key browse-kill-ring-mode-map (kbd "") 'browse-kill-ring-delete)
(define-key log-edit-mode-map [remap save-buffer] 'log-edit-done)
(define-key eshell-mode-map (kbd "") 'eshell-bol)
(define-key comint-mode-map (kbd "") 'comint-bol)
(define-key helm-map [remap mark-whole-buffer] 'helm-mark-all)
(define-key helm-map (kbd "C-w") 'helm-keyboard-quit)
(define-key helm-map (kbd "C-z") nil)
;; Compatibility with Icicle (allows the use of
;; `icicle-read-string-completing' directly)
(when icicle-mode
(global-set-key [remap ergoemacs-apropos-user-options] 'apropos-user-options))
(when icicle-ido-like-mode
(global-set-key [remap ergoemacs-apropos-user-options] 'apropos-user-options))
(define-key isearch-mode-map (kbd "C-S-f") 'isearch-occur)
(define-key isearch-mode-map (kbd "C-M-f") 'isearch-occur)
(define-key isearch-mode-map (kbd "") 'ergoemacs-paste)
(define-key isearch-mode-map (kbd "C-S-v") 'ergoemacs-paste-cycle)
(define-key isearch-mode-map (kbd "C-c") 'isearch-yank-word-or-char)
(define-key isearch-mode-map (kbd "M-c") 'isearch-yank-word-or-char)
(define-key isearch-mode-map (kbd "M-v") 'ergoemacs-paste)
(define-key isearch-mode-map (kbd "C-v") 'ergoemacs-paste))
(ergoemacs-component tab-indents-region ()
"Tab indents selected region"
(when mark-active
(global-set-key (kbd "TAB") 'indent-region)))
(ergoemacs-component fixed-bold-italic ()
"Fixed keys for bold and italic"
(define-key org-mode-map (kbd "C-b") 'ergoemacs-org-bold)
;; C-i is TAB... This seems to cause issues?
;; (define-key org-mode-map (kbd "C-i") 'ergoemacs-org-italic)
(define-key org-mode-map (kbd "") 'org-cycle)
(define-key org-mode-map (kbd "") 'org-cycle))
(ergoemacs-component backspace-is-back ()
"Backspace is back, as in browsers..."
(define-key Info-mode-map (kbd "") 'Info-history-back)
(define-key Info-mode-map (kbd "") 'Info-history-forward)
(define-key Info-mode-map (kbd "") 'Info-history-forward)
(define-key help-mode-map (kbd "") 'help-go-back)
(define-key help-mode-map (kbd "") 'help-go-forward)
(define-key eww-mode-map (kbd "") 'eww-back-url)
(define-key eww-mode-map (kbd "") 'eww-forward-url))
(ergoemacs-component fixed-newline ()
"Newline and indent"
(global-set-key (kbd "M-RET") ("C-j" :emacs))
(define-key helm-map (kbd "M-RET") 'helm-execute-persistent-action)
(define-key helm-map (kbd "") 'helm-execute-persistent-action)
(define-key helm-map (kbd "M-S-RET") "C-u M-RET")
(define-key helm-map (kbd "") "C-u M-RET")
(define-key helm-read-file-map [remap eshell] 'helm-ff-run-switch-to-eshell)
(define-key helm-read-file-map [remap ergoemacs-eshell-here] 'helm-ff-run-switch-to-eshell)
(define-key helm-read-file-map (kbd "RET") 'ergoemacs-helm-ff-persistent-expand-dir)
(define-key helm-read-file-map (kbd "") 'ergoemacs-helm-ff-persistent-expand-dir)
(define-key helm-read-file-map (kbd "M-RET") 'ergoemacs-helm-ff-execute-dired-dir)
(define-key helm-read-file-map (kbd "") 'ergoemacs-helm-ff-execute-dired-dir)
(define-key helm-read-file-map (kbd "DEL") 'ergoemacs-helm-ff-backspace)
(define-key helm-find-files-map [remap eshell] 'helm-ff-run-switch-to-eshell)
(define-key helm-find-files-map [remap ergoemacs-eshell-here] 'helm-ff-run-switch-to-eshell)
(define-key helm-find-files-map (kbd "DEL") 'ergoemacs-helm-ff-backspace)
(define-key helm-find-files-map (kbd "RET") 'ergoemacs-helm-ff-persistent-expand-dir)
(define-key helm-find-files-map (kbd "") 'ergoemacs-helm-ff-persistent-expand-dir)
(define-key helm-find-files-map (kbd "M-RET") 'ergoemacs-helm-ff-execute-dired-dir)
(define-key helm-find-files-map (kbd "") 'ergoemacs-helm-ff-execute-dired-dir)
(define-key helm-find-files-map (kbd "RET") 'ergoemacs-helm-ff-persistent-expand-dir)
(define-key helm-find-files-map (kbd "") 'ergoemacs-helm-ff-persistent-expand-dir)
(define-key helm-find-files-map (kbd "M-RET") 'ergoemacs-helm-ff-execute-dired-dir)
(define-key helm-find-files-map (kbd "") 'ergoemacs-helm-ff-execute-dired-dir))
(ergoemacs-component fn-keys ()
"Function Keys"
;; Modernize isearch and add back search-map to ergoemacs-mode
(global-set-key (kbd "") 'ergoemacs-cut-all)
(global-set-key (kbd "") 'ergoemacs-copy-all)
(global-set-key (kbd "") 'ergoemacs-paste-cycle)
(global-set-key (kbd "") '(redo undo-tree-redo ergoemacs-redo))
(global-set-key (kbd "") 'highlight-symbol-prev)
(global-set-key (kbd "") 'highlight-symbol-next)
(global-set-key (kbd "") 'ergoemacs-cut-all)
(global-set-key (kbd "") 'ergoemacs-copy-all)
(global-set-key (kbd "") '(redo undo-tree-redo ergoemacs-redo))
(global-set-key (kbd "") 'ergoemacs-toggle-letter-case)
(global-set-key (kbd "") 'previous-line)
(global-set-key (kbd "") 'next-line)
(global-set-key (kbd "") 'ergoemacs-copy-line-or-region)
(global-set-key (kbd "") 'ergoemacs-unchorded-alt-modal)
(global-set-key (kbd "") 'search-map)
(global-set-key (kbd " ") 'highlight-symbol-at-point)
(global-set-key (kbd " ") 'highlight-symbol-query-replace)
(global-set-key (kbd "") 'ergoemacs-cut-line-or-region)
(global-set-key (kbd "") 'ergoemacs-paste)
;; Mode Specific Changes
(define-key compilation-mode-map (kbd "") 'previous-error)
(define-key compilation-mode-map (kbd "") 'next-error)
(define-key browse-kill-ring-mode-map (kbd "") 'browse-kill-ring-previous)
(define-key browse-kill-ring-mode-map (kbd "") 'browse-kill-ring-next)
;; Comint
(define-key comint-mode-map (kbd "") 'comint-previous-input)
(define-key comint-mode-map (kbd "") 'comint-next-input)
(define-key comint-mode-map (kbd "S-") 'comint-previous-matching-input)
(define-key comint-mode-map (kbd "") 'comint-previous-matching-input)
(define-key comint-mode-map (kbd "S-") 'comint-next-matching-input)
(define-key comint-mode-map (kbd "") 'comint-next-matching-input)
;; Log Edit
(define-key log-edit-mode-map (kbd "") 'log-edit-previous-comment)
(define-key log-edit-mode-map (kbd "") 'log-edit-next-comment)
(define-key log-edit-mode-map (kbd "S-") 'log-edit-previous-comment)
(define-key log-edit-mode-map (kbd "") 'log-edit-previous-comment)
(define-key log-edit-mode-map (kbd "S-") 'log-edit-next-comment)
(define-key log-edit-mode-map (kbd "") 'log-edit-next-comment)
(define-key eshell-mode-map (kbd "") 'eshell-previous-matching-input-from-input)
(define-key eshell-mode-map (kbd "") 'eshell-next-matching-input-from-input)
(define-key eshell-mode-map (kbd "S-") 'eshell-previous-matching-input-from-input)
(define-key eshell-mode-map (kbd "") 'eshell-previous-matching-input-from-input)
(define-key eshell-mode-map (kbd "") 'eshell-previous-matching-input-from-input)
(define-key eshell-mode-map (kbd "S-") 'eshell-next-matching-input-from-input)
(define-key eshell-mode-map (kbd "") 'eshell-next-matching-input-from-input)
(define-key isearch-mode-map (kbd "") 'isearch-toggle-regexp)
(define-key isearch-mode-map (kbd "") 'isearch-ring-retreat)
(define-key isearch-mode-map (kbd "") 'isearch-ring-advance)
(define-key isearch-mode-map (kbd "S-") 'isearch-ring-advance)
(define-key isearch-mode-map (kbd "S-") 'isearch-ring-retreat)
(when icicle-minibuffer-setup-hook
:command-loop-unsupported-p t
(define-key minibuffer-local-map (kbd "") 'previous-history-element)
(define-key minibuffer-local-map (kbd "M-") 'icicle-insert-history-element)
(define-key minibuffer-local-map (kbd "") 'next-history-element)
(define-key minibuffer-local-map (kbd "S-") 'next-history-element)
(define-key minibuffer-local-map (kbd "M-") 'icicle-insert-history-element)
(define-key minibuffer-local-map (kbd "S-") 'previous-history-element))
(when iswitchb-define-mode-map-hook
:modify-map t
:always t
(define-key iswitchb-mode-map [remap previous-history-element] 'iswitchb-prev-match)
(define-key iswitchb-mode-map [remap next-history-element] 'iswitchb-next-match)))
(ergoemacs-component f2-edit ()
"Have edit"
(define-key ergoemacs-translate--parent-map [f2] 'ergoemacs-command-loop--force-universal-argument))
(ergoemacs-component backspace-del-seq ()
"Backspace deletes last key entered in command sequence"
(define-key ergoemacs-translate--parent-map (kbd "DEL") 'ergoemacs-command-loop--force-undo-last))
(ergoemacs-component help ()
"Help changes for ergoemacs-mode"
(global-set-key (kbd "C-h '") 'ergoemacs-describe-current-theme)
(global-set-key (kbd "C-h 1") 'describe-function)
(global-set-key (kbd "C-h 2") 'describe-variable)
(global-set-key (kbd "C-h 3") 'describe-key)
(global-set-key (kbd "C-h 4") 'describe-char)
(global-set-key (kbd "C-h 5") 'man)
(global-set-key (kbd "C-h 7") 'ergoemacs-lookup-google)
(global-set-key (kbd "C-h 8") 'ergoemacs-lookup-wikipedia)
(global-set-key (kbd "C-h 9") 'ergoemacs-lookup-word-definition)
(global-set-key (kbd "C-h `") 'elisp-index-search)
(global-set-key (kbd "C-h o") 'ergoemacs-where-is-old-binding)
(global-set-key (kbd "C-h z") 'ergoemacs-clean)
(global-set-key (kbd "C-h C-z") 'ergoemacs-clean-library)
(global-set-key (kbd " '") 'ergoemacs-describe-current-theme)
(global-set-key (kbd " 1") 'describe-function)
(global-set-key (kbd " 2") 'describe-variable)
(global-set-key (kbd " 3") 'describe-key)
(global-set-key (kbd " 4") 'describe-char)
(global-set-key (kbd " 5") 'man)
(global-set-key (kbd " 7") 'ergoemacs-lookup-google)
(global-set-key (kbd " 8") 'ergoemacs-lookup-wikipedia)
(global-set-key (kbd " 9") 'ergoemacs-lookup-word-definition)
(global-set-key (kbd " `") 'elisp-index-search)
(global-set-key (kbd " o") 'ergoemacs-where-is-old-binding))
;;; Variable Components
(ergoemacs-component move-char ()
"Movement by Characters & Set Mark"
(global-set-key (kbd "C-b") nil)
(global-set-key (kbd "M-j") ("C-b" :emacs))
(global-set-key (kbd "C-f") nil)
(define-key global-map (kbd "M-l") ("C-f" :emacs))
(global-set-key (kbd "C-p") nil)
(define-key (current-global-map) (kbd "M-i") ("C-p" :emacs))
(global-set-key (kbd "C-n") nil)
(define-key ergoemacs-keymap (kbd "M-k") ("C-n" :emacs))
;; These are here so that C-M-i will translate to C- for modes
;; like inferior R mode. That allows the command to be the last
;; command.
;; Not sure it belongs here or not...
(global-set-key (kbd "M-C-j") ("" :emacs))
(global-set-key (kbd "M-C-l") ("" :emacs))
(global-set-key (kbd "M-C-i") ("" :emacs))
(global-set-key (kbd "M-C-k") ("" :emacs))
(global-set-key (kbd "C-SPC") nil) ;; Set Mark
(global-set-key (kbd "M-SPC") ("C-SPC" :emacs))
;; Mode specific changes
(define-key browse-kill-ring-mode-map (kbd "M-i") 'browse-kill-ring-previous)
(define-key browse-kill-ring-mode-map (kbd "M-k") 'browse-kill-ring-forward)
;; Delete previous/next char.
(global-set-key (kbd "M-d") 'delete-backward-char)
(global-set-key (kbd "C-d") nil)
(global-set-key (kbd "M-f") 'delete-char)
;; Mode specific changes
(define-key browse-kill-ring-mode-map (kbd "M-i") 'browse-kill-ring-backward)
(define-key browse-kill-ring-mode-map (kbd "M-k") 'browse-kill-ring-forward)
(define-key browse-kill-ring-mode-map (kbd "M-f") 'browse-kill-ring-delete)
(when iswitchb-define-mode-map-hook
(define-key iswitchb-mode-map [remap backward-char] 'iswitchb-prev-match)
(define-key iswitchb-mode-map [remap forward-char] 'iswitchb-next-match))
:version 5.7.5
(global-set-key (kbd "C-SPC") 'set-mark-command) ;; Set Mark
)
(ergoemacs-component move-word ()
"Moving around and deleting words"
(global-set-key (kbd "M-b") nil)
(global-set-key (kbd "M-u") 'backward-word)
(global-set-key (kbd "M-f") nil)
(global-set-key (kbd "M-o") 'forward-word)
;; Delete previous/next word.
;; C-backspace is standard; don't change
(global-set-key (kbd "M-e") 'backward-kill-word)
(global-set-key (kbd "M-d") nil)
(global-set-key (kbd "M-r") 'kill-word))
(ergoemacs-component move-sexp ()
"Instead of moving around by words, use sexps."
(global-set-key [remap forward-word] 'forward-sexp)
(global-set-key [remap backward-word] 'backward-sexp))
(ergoemacs-component move-paragraph ()
"Move by Paragraph"
(global-unset-key (kbd "M-{"))
(global-unset-key (kbd "M-}"))
(global-set-key (kbd "M-U") ("M-{" :emacs))
(global-set-key (kbd "M-O") ("M-}" :emacs)))
(ergoemacs-component move-line ()
"Move by Line"
(global-unset-key (kbd "C-a"))
(global-unset-key (kbd "C-e"))
(global-set-key (kbd "M-h") ("C-a" :emacs))
(global-set-key (kbd "M-H") ("C-e" :emacs))
;; Mode specific movement
(define-key eshell-mode-map [remap move-beginning-of-line] 'eshell-bol)
(define-key comint-mode-map [remap move-beginning-of-line] 'comint-bol))
(ergoemacs-component move-and-transpose-lines ()
"Move Current line/selection down or up with Alt+up or Alt+down"
(global-set-key [\M-up] 'ergoemacs-move-text-up)
(global-set-key [\M-down] 'ergoemacs-move-text-down))
(ergoemacs-component alt-backspace-is-undo ()
"Alt+Backspace is Undo"
(global-set-key (kbd "") 'undo))
(ergoemacs-component move-page ()
"Move by Page"
(global-unset-key (kbd "M-v"))
(global-unset-key (kbd "C-v"))
(global-unset-key (kbd "C-M-v"))
;; Not sure I like the scroll other window placment... C+M+ argh.
(global-set-key (kbd "C-M-I") 'scroll-other-window-down)
(global-set-key (kbd "C-M-K") ("C-M-v" :emacs))
;; These are OK
(global-set-key (kbd "M-I") ("M-v" :emacs))
(global-set-key (kbd "M-K") ("C-v" :emacs)))
(ergoemacs-component move-buffer ()
"Move Beginning/End of buffer"
(global-unset-key (kbd "M->"))
(global-unset-key (kbd "M-<"))
(global-set-key (kbd "M-n") 'ergoemacs-beginning-or-end-of-buffer)
(global-set-key (kbd "M-N") 'ergoemacs-end-or-beginning-of-buffer)
:version 5.7.5
(global-reset-key (kbd "M->"))
(global-reset-key (kbd "M-<"))
(global-unset-key (kbd "M-n"))
(global-unset-key (kbd "M-N")))
(ergoemacs-component move-bracket ()
"Move By Bracket"
(global-set-key (kbd "M-J") 'ergoemacs-backward-open-bracket)
(global-set-key (kbd "M-L") 'ergoemacs-forward-close-bracket)
(global-set-key (kbd "") 'ergoemacs-backward-open-bracket) ; Alt+←
(global-set-key (kbd "") 'ergoemacs-forward-close-bracket))
(ergoemacs-component copy ()
"Copy, Cut, Paste, Redo and Undo"
(global-set-key (kbd "C-w") nil) ;; Kill region = Cut
(global-set-key (kbd "M-x") 'ergoemacs-cut-line-or-region)
(global-set-key (kbd "M-w") nil) ;; Kill ring save = Copy
(global-set-key (kbd "M-c") 'ergoemacs-copy-line-or-region)
(global-set-key (kbd "C-y") nil) ;; Yank = paste
(global-set-key (kbd "M-v") 'ergoemacs-paste)
(global-set-key (kbd "M-y") nil) ;; Yank-pop = paste cycle
(global-set-key (kbd "M-V") 'ergoemacs-paste-cycle)
(global-set-key (kbd "M-C") 'ergoemacs-copy-all)
(global-set-key (kbd "M-X") 'ergoemacs-cut-all)
(global-set-key (kbd "M-Z") '("C-_" :emacs))
;; Undo
(global-set-key (kbd "C-_") nil)
(global-set-key (kbd "C-/") nil)
(global-set-key (kbd "C-x u") nil)
(global-set-key (kbd "M-z") '("C-_" :emacs))
;; Fixed Component; Note that is the actual function.
(global-set-key (kbd "C-c ") 'ergoemacs-copy-line-or-region)
(global-set-key (kbd "C-x ") 'ergoemacs-cut-line-or-region)
(global-set-key (kbd "C-z") 'undo)
(global-set-key (kbd "C-S-z") '(redo undo-tree-redo ergoemacs-redo))
(global-set-key (kbd "C-y") '(redo undo-tree-redo ergoemacs-redo))
;; Mode specific changes
(define-key isearch-mode-map (kbd "C-c") 'isearch-yank-word-or-char)
(define-key isearch-mode-map (kbd "M-c") 'isearch-yank-word-or-char)
(define-key isearch-mode-map (kbd "M-v") 'ergoemacs-paste)
(define-key isearch-mode-map (kbd "M-V") 'ergoemacs-paste-cycle)
(define-key isearch-mode-map (kbd "C-v") 'ergoemacs-paste)
(define-key isearch-mode-map (kbd "C-S-v") 'ergoemacs-paste-cycle)
(define-key org-mode-map [remap ergoemacs-paste] 'ergoemacs-org-yank)
(define-key org-mode-map [remap ergoemacs-paste] 'ergoemacs-org-yank)
(define-key browse-kill-ring-mode-map [remap undo] 'browse-kill-ring-undo-other-window)
(define-key browse-kill-ring-mode-map [remap undo-tree-undo] 'browse-kill-ring-undo-other-window)
(define-key browse-kill-ring-mode-map [remap undo-tree-undo] 'browse-kill-ring-undo-other-window)
(define-key calc-mode-map [remap undo-tree-undo] 'calc-undo))
(ergoemacs-component search ()
"Search and Replace"
(global-set-key (kbd "C-s") nil)
(global-set-key (kbd "M-y") '("C-s" :emacs))
(global-set-key (kbd "C-r") nil)
(global-set-key (kbd "M-Y") '("C-r" :emacs))
(global-set-key (kbd "M-%") nil)
(global-set-key (kbd "M-5") '("M-%" :emacs))
(global-set-key (kbd "C-M-%") nil)
(global-set-key (kbd "M-%") '("C-M-%" :emacs))
;; Mode specific changes
(define-key dired-mode-map (kbd "M-5") 'dired-do-query-replace-regexp)
(define-key dired-mode-map (kbd "M-%") 'dired-do-query-replace-regexp)
;; Reclaim dired+ overrides.
(define-key dired-mode-map (kbd "M-u") 'backward-word)
(define-key dired-mode-map (kbd "C-b") 'diredp-do-bookmark)
(define-key browse-kill-ring-mode-map [remap isearch-forward] 'browse-kill-ring-search-forward)
(define-key browse-kill-ring-mode-map [remap isearch-backward] 'browse-kill-ring-search-backward)
:version 5.7.5
(global-set-key (kbd "M-;") 'isearch-forward)
(global-set-key (kbd "M-:") 'isearch-backward))
(ergoemacs-component search-reg ()
"Regular Expression Search/Replace"
(global-set-key [remap isearch-forward] 'isearch-forward-regexp)
(global-set-key [remap isearch-backward] 'isearch-backward-regexp)
(global-set-key (kbd "M-%") nil)
(global-set-key (kbd "M-5") '("C-M-%" :emacs))
(global-set-key (kbd "C-M-%") nil)
(global-set-key (kbd "M-%") '("M-%" :emacs)))
(ergoemacs-component switch ()
"Window/Frame/Tab Switching"
(global-set-key (kbd "M-s") 'ergoemacs-move-cursor-next-pane)
(global-set-key (kbd "M-S") 'ergoemacs-move-cursor-previous-pane)
(global-set-key (kbd "M-~") 'ergoemacs-switch-to-previous-frame)
(global-set-key (kbd "M-`") 'ergoemacs-switch-to-next-frame)
(global-unset-key (kbd "C-x 1"))
(global-set-key (kbd "M-3") 'delete-other-windows)
(global-unset-key (kbd "C-x 0"))
(global-set-key (kbd "M-2") 'delete-window)
(global-unset-key (kbd "C-x 3"))
(global-set-key (kbd "M-4") '(split-window-below split-window-horizontally))
(global-unset-key (kbd "C-x 2"))
(global-set-key (kbd "M-$") '(split-window-right split-window-vertically))
:version 5.7.5
(global-set-key (kbd "M-0") 'delete-window))
(ergoemacs-component execute ()
"Execute Commands"
(global-unset-key (kbd "M-x"))
(global-set-key (kbd "M-a") '("M-x" :emacs))
(global-unset-key (kbd "M-!"))
(global-set-key (kbd "M-A") '("M-!" :emacs)))
(ergoemacs-component misc ()
"Misc Commands"
(global-unset-key (kbd "C-l"))
(global-set-key (kbd "M-p") '("C-l" :emacs))
(global-set-key (kbd "M-b") 'avy-goto-word-or-subword-1))
(ergoemacs-component kill-line ()
"Kill Line"
(global-unset-key (kbd "C-k"))
(global-set-key (kbd "M-g") '("C-k" :emacs))
(global-set-key (kbd "M-G") 'ergoemacs-kill-line-backward))
(ergoemacs-component text-transform ()
"Text Transformation"
(global-unset-key (kbd "M-;"))
(global-set-key (kbd "M-'") '("M-;" :emacs))
(global-set-key (kbd "M-w") 'ergoemacs-shrink-whitespaces)
(global-set-key (kbd "M-?") 'ergoemacs-toggle-camel-case)
(global-set-key (kbd "M-/") 'ergoemacs-toggle-letter-case)
;; ;; keyword completion, because Alt+Tab is used by OS
(global-set-key (kbd "M-t") 'ergoemacs-call-keyword-completion)
(global-set-key (kbd "M-T") 'flyspell-auto-correct-word)
;; ;; Hard-wrap/un-hard-wrap paragraph
(global-set-key (kbd "M-q") 'ergoemacs-compact-uncompact-block)
(define-key isearch-mode-map (kbd "M-?") 'isearch-toggle-regexp)
(define-key isearch-mode-map (kbd "M-/") 'isearch-toggle-case-fold)
(when iswitchb-define-mode-map-hook
(define-key iswitchb-mode-map [remap ergoemacs-toggle-camel-case] 'iswitchb-toggle-case)
(define-key iswitchb-mode-map [remap ergoemacs-toggle-letter-case] 'iswitchb-toggle-regexp)))
(ergoemacs-component select-items ()
"Select Items"
(global-set-key (kbd "M-S-SPC") 'mark-paragraph)
(global-set-key (kbd "M-8") '(er/expand-region ergoemacs-extend-selection))
(global-set-key (kbd "M-*") '(er/mark-inside-quotes ergoemacs-select-text-in-quote))
(global-set-key (kbd "M-6") 'ergoemacs-select-current-block)
(global-set-key (kbd "M-7") 'ergoemacs-select-current-line))
(ergoemacs-component quit ()
"Escape exits"
(global-set-key (kbd "") 'keyboard-quit)
(define-key isearch-mode-map (kbd "") 'isearch-abort)
(when org-read-date-minibuffer-setup-hook
(define-key minibuffer-local-map (kbd "") 'minibuffer-keyboard-quit))
:version 5.3.7
(global-set-key (kbd "M-n") 'keyboard-quit))
(ergoemacs-component apps ()
"General Apps Key Sequence"
:just-first-keys (list [apps ?h] [menu ?h])
:bind (" '" ergoemacs-org-edit-src
" 2" delete-window
" 3" delete-other-windows
" 4" split-window-vertically
" 5" query-replace
" " ergoemacs-cut-all
" " ergoemacs-copy-all
" " execute-extended-command
" RET" execute-extended-command
" TAB" indent-region ;; Already in CUA
" SPC" set-mark-command
" a" mark-whole-buffer
" d" ("C-x" :ctl-to-alt)
" f" ("C-c" :unchorded-ctl)
" h" help-map
" h '" ergoemacs-describe-current-theme
" h 1" describe-function
" h 2" describe-variable
" h 3" describe-key
" h 4" describe-char
" h 5" man
" h 7" ergoemacs-lookup-google
" h 8" ergoemacs-lookup-wikipedia
" h 9" ergoemacs-lookup-word-definition
" h `" elisp-index-search
" h o" ergoemacs-where-is-old-binding
" h z" ergoemacs-clean
" h C-z" ergoemacs-clean-library
" h Z" ergoemacs-clean-nw
" m" (kbd "C-c C-c")
" s" save-buffer
" C-s" write-file
" o" find-file
" g" ergoemacs-read-key--universal-argument
" w" ergoemacs-close-current-buffer
" x" ergoemacs-cut-line-or-region
" c" ergoemacs-copy-line-or-region
" v" ergoemacs-paste
" b" (redo undo-tree-redo ergoemacs-redo)
" t" switch-to-buffer
" z" undo
" r" goto-map))
(ergoemacs-component apps-toggle ()
"Toggle States and applications"
:just-first-keys (list [apps ?i] [menu ?i])
(global-set-key (kbd " i c") 'column-number-mode)
(global-set-key (kbd " i d") 'toggle-debug-on-error)
(global-set-key (kbd " i e") 'toggle-debug-on-error)
(global-set-key (kbd " i f") 'auto-fill-mode)
(global-set-key (kbd " i l") 'toggle-truncate-lines)
(global-set-key (kbd " i q") 'toggle-debug-on-quit)
(global-set-key (kbd " i r") 'read-only-mode)
(global-set-key (kbd " i C-r") 'revert-buffer))
(ergoemacs-component apps-apps ()
"Applications"
:just-first-keys (list [apps ?n] [menu ?n])
(global-set-key (kbd " n a") 'org-agenda)
(global-set-key (kbd " n A") 'org-capture)
(global-set-key (kbd " n C-a") 'org-capture)
(global-set-key (kbd " n c") 'calc)
(global-set-key (kbd " n d") 'dired-jump)
(global-set-key (kbd " n e") 'eshell)
(global-set-key (kbd " n p") 'powershell)
(global-set-key (kbd " n f") 'ergoemacs-open-in-desktop)
(global-set-key (kbd " n g") 'grep)
(global-set-key (kbd " n m") 'magit-status)
(global-set-key (kbd " n o") 'ergoemacs-open-in-external-app)
(global-set-key (kbd " n r") 'R)
(global-set-key (kbd " n s") 'shell)
(global-set-key (kbd " n t") 'org-capture)
(global-set-key (kbd " n C-t") 'org-agenda)
(global-set-key (kbd " n T") 'org-agenda))
(ergoemacs-component apps-punctuation ()
"Punctuation"
;; Smart punctuation
;; `http://xahlee.info/comp/computer_language_char_distribution.html'
;; |------+-----------+---------+-----------------------|
;; | Rank | Character | Percent | Defined |
;; |------+-----------+---------+-----------------------|
;; | 1 | , | 12.1% | No; Already unchorded |
;; | 2 | _ | 8.0% | Yes |
;; | 3 | " | 8.0% | Yes |
;; | 4 | ( | 7.7% | Yes |
;; | 5 | ) | 7.7% | By pair |
;; | 6 | . | 7.4% | No; Already unchorded |
;; | 7 | ; | 4.8% | No; Already unchorded |
;; | 8 | - | 4.4% | Yes |
;; | 9 | = | 4.3% | Yes |
;; | 10 | ' | 3.9% | Yes (by pair) |
;; | 11 | / | 3.8% | No; Already unchorded |
;; | 12 | * | 3.5% | Yes |
;; | 13 | : | 3.2% | Yes |
;; | 14 | { | 3.2% | By pair |
;; | 15 | } | 3.2% | By pair |
;; | 16 | > | 2.4% | Yes |
;; | 17 | $ | 2.2% | Yes |
;; | 18 | # | 1.7% | Yes |
;; | 19 | + | 1.2% | Yes |
;; | 20 | \ | 1.1% | No; Already unchorded |
;; | 21 | [ | 1.0% | Yes (by pair) |
;; | 22 | ] | 1.0% | Yes |
;; | 23 | < | 1.0% | Yes |
;; | 24 | & | 0.9% | Yes |
;; | 25 | @ | 0.7% | Yes |
;; | 26 | | | 0.5% | Yes |
;; | 27 | ! | 0.5% | Yes |
;; | 28 | % | 0.3% | Yes |
;; | 29 | ? | 0.2% | Yes |
;; | 30 | ` | 0.1% | Yes |
;; | 31 | ^ | 0.1% | Yes |
;; | 32 | ~ | 0.1% | Yes |
;; |------+-----------+---------+-----------------------|
;; No pinkies are used in this setup.
(global-set-key (kbd " k o") "#")
(global-set-key (kbd " k l") "$")
(global-set-key (kbd " k .") ":")
(global-set-key (kbd " k w") "^")
(global-set-key (kbd " k s") "*")
(global-set-key (kbd " k x") "~")
(global-set-key (kbd " k i") 'ergoemacs-smart-bracket)
(global-set-key (kbd " k k") 'ergoemacs-smart-paren)
(global-set-key (kbd " k ,") 'ergoemacs-smart-curly)
(global-set-key (kbd " k j") 'ergoemacs-smart-quote)
(global-set-key (kbd " k u") 'ergoemacs-smart-apostrophe)
(global-set-key (kbd " k m") "`")
(global-set-key (kbd " k y") "?")
(global-set-key (kbd " k h") "%")
(global-set-key (kbd " k n") "@")
(global-set-key (kbd " k r") ">")
(global-set-key (kbd " k f") "_")
(global-set-key (kbd " k v") "<")
(global-set-key (kbd " k e") "+")
(global-set-key (kbd " k d") "=")
(global-set-key (kbd " k c") "-")
(global-set-key (kbd " k t") "&")
(global-set-key (kbd " k g") "|")
(global-set-key (kbd " k b") "!"))
(ergoemacs-component apps-swap ()
"Apps/Menu swaps key sequence translations"
(define-key ergoemacs-translate--parent-map (if (eq system-type 'windows-nt) [apps] [menu])
'ergoemacs-command-loop--swap-translation))
(ergoemacs-component dired-to-wdired ()
"C-c C-c enters wdired, exits."
(define-key dired-mode-map (kbd "C-c C-c") 'wdired-change-to-wdired-mode))
(ergoemacs-component dired-tab ()
"TAB expands a directory."
(define-key dired-mode-map (kbd "TAB") 'dired-maybe-insert-subdir))
(ergoemacs-component guru ()
"Unbind some commonly used keys such as and to get in the habit of using ergoemacs keybindings."
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd ""))
(global-unset-key (kbd "