(cl--generic-derived-specializers): New function.
(cl--generic-derived-generalizer): New generalizer.
(cl-generic-generalizers): New specializer (derived-mode MODE).
(cl--generic-split-args): Apply the rewriter, if any.
(cl-generic-define-context-rewriter): New macro.
(major-mode): Use it to define a new context-rewriter, so we can write
`(major-mode MODE)' instead of `(major-mode (derived-mode MODE))'.
* lisp/frame.el (window-system): New context-rewriter so we can write
`(window-system VAL)' instead of (window-system (eql VAL)).
(cl--generic-split-args): Apply the rewriter, if any.
(frame-creation-function): Use the new syntax.
* lisp/term/x-win.el (window-system-initialization)
(handle-args-function, frame-creation-function)
(gui-backend-set-selection, gui-backend-selection-owner-p)
(gui-backend-selection-exists-p, gui-backend-get-selection):
* lisp/term/w32-win.el (window-system-initialization)
(handle-args-function, frame-creation-function)
(gui-backend-set-selection, gui-backend-get-selection)
(gui-backend-selection-owner-p, gui-backend-selection-exists-p):
* lisp/term/pc-win.el (gui-backend-get-selection)
(gui-backend-selection-exists-p, gui-backend-selection-owner-p)
(gui-backend-set-selection, window-system-initialization)
(frame-creation-function, handle-args-function):
* lisp/term/ns-win.el (window-system-initialization)
(handle-args-function, frame-creation-function)
(gui-backend-set-selection, gui-backend-selection-exists-p)
(gui-backend-get-selection):
* lisp/startup.el (handle-args-function):
* lisp/term/xterm.el (gui-backend-get-selection)
(gui-backend-set-selection): Use the new syntax.
This macro can only be used within the lexical scope of a cl-generic method."
(error "cl-generic-current-method-specializers used outside of a method"))
+(defmacro cl-generic-define-context-rewriter (name args &rest body)
+ "Define a special kind of context named NAME.
+Whenever a context specializer of the form (NAME . ACTUALS) appears,
+the specializer used will be the one returned by BODY."
+ (declare (debug (&define name lambda-list def-body)) (indent defun))
+ `(eval-and-compile
+ (put ',name 'cl-generic--context-rewriter
+ (lambda ,args ,@body))))
+
(eval-and-compile ;Needed while compiling the cl-defmethod calls below!
(defun cl--generic-fgrep (vars sexp) ;Copied from pcase.el.
"Check which of the symbols VARS appear in SEXP."
((let 'context mandatory)
(unless (consp arg)
(error "Invalid &context arg: %S" arg))
+ (let* ((name (car arg))
+ (rewriter
+ (and (symbolp name)
+ (get name 'cl-generic--context-rewriter))))
+ (if rewriter (setq arg (apply rewriter (cdr arg)))))
(push `((&context . ,(car arg)) . ,(cadr arg)) specializers)
nil)
(`(,name . ,type)
(cl--generic-prefill-dispatchers 0 integer)
+;;; Dispatch on major mode.
+
+;; Two parts:
+;; - first define a specializer (derived-mode <mode>) to match symbols
+;; representing major modes, while obeying the major mode hierarchy.
+;; - then define a context-rewriter so you can write
+;; "&context (major-mode c-mode)" rather than
+;; "&context (major-mode (derived-mode c-mode))".
+
+(defun cl--generic-derived-specializers (mode &rest _)
+ ;; FIXME: Handle (derived-mode <mode1> ... <modeN>)
+ (let ((specializers ()))
+ (while mode
+ (push `(derived-mode ,mode) specializers)
+ (setq mode (get mode 'derived-mode-parent)))
+ (nreverse specializers)))
+
+(cl-generic-define-generalizer cl--generic-derived-generalizer
+ 90 (lambda (name) `(and (symbolp ,name) (functionp ,name) ,name))
+ #'cl--generic-derived-specializers)
+
+(cl-defmethod cl-generic-generalizers ((_specializer (head derived-mode)))
+ "Support for the `(derived-mode MODE)' specializers."
+ (list cl--generic-derived-generalizer))
+
+(cl-generic-define-context-rewriter major-mode (mode &rest modes)
+ `(major-mode ,(if (consp mode)
+ ;;E.g. could be (eql ...)
+ (progn (cl-assert (null modes)) mode)
+ `(derived-mode ,mode . ,modes))))
+
;; Local variables:
;; generated-autoload-file: "cl-loaddefs.el"
;; End:
function to this method, which should take an alist of parameters
as its argument.")
-(cl-defmethod frame-creation-function (params
- &context (window-system (eql nil)))
+(cl-generic-define-context-rewriter window-system (value)
+ ;; If `value' is a `consp', it's probably an old-style specializer,
+ ;; so just use it, and anyway `eql' isn't very useful on cons cells.
+ `(window-system ,(if (consp value) value `(eql ,value))))
+
+(cl-defmethod frame-creation-function (params &context (window-system nil))
;; It's tempting to get rid of tty-create-frame-with-faces and turn it into
;; this method (i.e. move this method to faces.el), but faces.el is loaded
;; much earlier from loadup.el (before cl-generic and even before
method, which should parse the command line arguments. Those
pertaining to the window system should be processed and removed
from the returned command line.")
-(cl-defmethod handle-args-function (args &context (window-system (eql nil)))
+(cl-defmethod handle-args-function (args &context (window-system nil))
(tty-handle-args args))
(cl-defgeneric window-system-initialization (&optional _display)
;; Do the actual Nextstep Windows setup here; the above code just
;; defines functions and variables that we use now.
-(cl-defmethod window-system-initialization (&context (window-system (eql ns))
+(cl-defmethod window-system-initialization (&context (window-system ns)
&optional _display)
"Initialize Emacs for Nextstep (Cocoa / GNUstep) windowing."
(cl-assert (not ns-initialized))
;; Any display name is OK.
(add-to-list 'display-format-alist '(".*" . ns))
-(cl-defmethod handle-args-function (args &context (window-system (eql ns)))
+(cl-defmethod handle-args-function (args &context (window-system ns))
(x-handle-args args))
-(cl-defmethod frame-creation-function (params &context (window-system (eql ns)))
+(cl-defmethod frame-creation-function (params &context (window-system ns))
(x-create-frame-with-faces params))
(declare-function ns-own-selection-internal "nsselect.m" (selection value))
(declare-function ns-get-selection "nsselect.m" (selection-symbol target-type))
(cl-defmethod gui-backend-set-selection (selection value
- &context (window-system (eql ns)))
+ &context (window-system ns))
(if value (ns-own-selection-internal selection value)
(ns-disown-selection-internal selection)))
(cl-defmethod gui-backend-selection-owner-p (selection
- &context (window-system (eql ns)))
+ &context (window-system ns))
(ns-selection-owner-p selection))
(cl-defmethod gui-backend-selection-exists-p (selection
- &context (window-system (eql ns)))
+ &context (window-system ns))
(ns-selection-exists-p selection))
(cl-defmethod gui-backend-get-selection (selection-symbol target-type
- &context (window-system (eql ns)))
+ &context (window-system ns))
(ns-get-selection selection-symbol target-type))
(provide 'ns-win)
;; gui-get-selection is used in select.el
(cl-defmethod gui-backend-get-selection (_selection-symbol _target-type
- &context (window-system (eql pc)))
+ &context (window-system pc))
"Return the value of the current selection.
Consult the selection. Treat empty strings as if they were unset."
;; Don't die if x-get-selection signals an error.
(declare-function w16-selection-exists-p "w16select.c")
;; gui-selection-owner-p is used in simple.el.
(cl-defmethod gui-backend-selection-exists-p (selection
- &context (window-system (eql pc)))
+ &context (window-system pc))
(w16-selection-exists-p selection))
(cl-defmethod gui-backend-selection-owner-p (selection
- &context (window-system (eql pc)))
+ &context (window-system pc))
(w16-selection-owner-p selection))
(defun w16-selection-owner-p (_selection)
(declare-function w16-set-clipboard-data "w16select.c"
(string &optional ignored))
(cl-defmethod gui-backend-set-selection (selection value
- &context (window-system (eql pc)))
+ &context (window-system pc))
(if (not value)
(if (w16-selection-owner-p selection)
t)
(window-system)))
;; window-system-initialization is called by startup.el:command-line.
-(cl-defmethod window-system-initialization (&context (window-system (eql pc))
+(cl-defmethod window-system-initialization (&context (window-system pc)
&optional _display)
"Initialization function for the `pc' \"window system\"."
(or (eq (window-system) 'pc)
(run-hooks 'terminal-init-msdos-hook))
;; frame-creation-function is called by frame.el:make-frame.
-(cl-defmethod frame-creation-function (params &context (window-system (eql pc)))
+(cl-defmethod frame-creation-function (params &context (window-system pc))
(msdos-create-frame-with-faces params))
;; We don't need anything beyond tty-handle-args for handling
;; command-line argument; see startup.el.
-(cl-defmethod handle-args-function (args &context (window-system (eql pc)))
+(cl-defmethod handle-args-function (args &context (window-system pc))
(tty-handle-args args))
;; ---------------------------------------------------------------------------
(declare-function x-parse-geometry "frame.c" (string))
(defvar x-command-line-resources)
-(cl-defmethod window-system-initialization (&context (window-system (eql w32))
+(cl-defmethod window-system-initialization (&context (window-system w32)
&optional _display)
"Initialize Emacs for W32 GUI frames."
(cl-assert (not w32-initialized))
(setq w32-initialized t))
(add-to-list 'display-format-alist '("\\`w32\\'" . w32))
-(cl-defmethod handle-args-function (args &context (window-system (eql w32)))
+(cl-defmethod handle-args-function (args &context (window-system w32))
(x-handle-args args))
-(cl-defmethod frame-creation-function (params &context (window-system (eql w32)))
+(cl-defmethod frame-creation-function (params &context (window-system w32))
(x-create-frame-with-faces params))
;;;; Selections
(get 'x-selections (or selection 'PRIMARY))))
(cl-defmethod gui-backend-set-selection (type value
- &context (window-system (eql w32)))
+ &context (window-system w32))
(w32--set-selection type value))
(cl-defmethod gui-backend-get-selection (type data-type
- &context (window-system (eql w32)))
+ &context (window-system w32))
(w32--get-selection type data-type))
(cl-defmethod gui-backend-selection-owner-p (selection
- &context (window-system (eql w32)))
+ &context (window-system w32))
(w32--selection-owner-p selection))
(cl-defmethod gui-backend-selection-exists-p (selection
- &context (window-system (eql w32)))
+ &context (window-system w32))
(w32-selection-exists-p selection))
(when (eq system-type 'windows-nt)
;; We could move those cl-defmethods outside of the `when' and use
;; "&context (system-type (eql windows-nt))" instead!
(cl-defmethod gui-backend-set-selection (type value
- &context (window-system (eql nil)))
+ &context (window-system nil))
(w32--set-selection type value))
(cl-defmethod gui-backend-get-selection (type data-type
- &context (window-system (eql nil)))
+ &context (window-system nil))
(w32--get-selection type data-type))
(cl-defmethod gui-backend-selection-owner-p (selection
- &context (window-system (eql nil)))
+ &context (window-system nil))
(w32--selection-owner-p selection))
(cl-defmethod gui-selection-exists-p (selection
- &context (window-system (eql nil)))
+ &context (window-system nil))
(w32-selection-exists-p selection)))
;; The "Windows" keys on newer keyboards bring up the Start menu
(defvar x-display-name)
(defvar x-command-line-resources)
-(cl-defmethod window-system-initialization (&context (window-system (eql x))
+(cl-defmethod window-system-initialization (&context (window-system x)
&optional display)
"Initialize Emacs for X frames and open the first connection to an X server."
(cl-assert (not x-initialized))
(selection-symbol target-type &optional time-stamp terminal))
(add-to-list 'display-format-alist '("\\`[^:]*:[0-9]+\\(\\.[0-9]+\\)?\\'" . x))
-(cl-defmethod handle-args-function (args &context (window-system (eql x)))
+(cl-defmethod handle-args-function (args &context (window-system x))
(x-handle-args args))
-(cl-defmethod frame-creation-function (params &context (window-system (eql x)))
+(cl-defmethod frame-creation-function (params &context (window-system x))
(x-create-frame-with-faces params))
(cl-defmethod gui-backend-set-selection (selection value
- &context (window-system (eql x)))
+ &context (window-system x))
(if value (x-own-selection-internal selection value)
(x-disown-selection-internal selection)))
(cl-defmethod gui-backend-selection-owner-p (selection
- &context (window-system (eql x)))
+ &context (window-system x))
(x-selection-owner-p selection))
(cl-defmethod gui-backend-selection-exists-p (selection
- &context (window-system (eql x)))
+ &context (window-system x))
(x-selection-exists-p selection))
(cl-defmethod gui-backend-get-selection (selection-symbol target-type
- &context (window-system (eql x))
+ &context (window-system x)
&optional time-stamp terminal)
(x-get-selection-internal selection-symbol target-type time-stamp terminal))
(cl-defmethod gui-backend-get-selection
(type data-type
- &context (window-system (eql nil))
+ &context (window-system nil)
;; Only applies to terminals which have it enabled.
((terminal-parameter nil 'xterm--get-selection) (eql t)))
(unless (eq data-type 'STRING)
(cl-defmethod gui-backend-set-selection
(type data
- &context (window-system (eql nil))
+ &context (window-system nil)
;; Only applies to terminals which have it enabled.
((terminal-parameter nil 'xterm--set-selection) (eql t)))
"Copy DATA to the X selection using the OSC 52 escape sequence.