如何在 emacs 中查找别名
How to find aliases in emacs
我想检查一个函数是否存在默认\现有别名(在本例中:x-clipboard-yank
,但问题很笼统)。
是否有显示活动别名的 emacs 函数我可以用来计算它?
预期的行为类似于 shell alias
命令。
您可以查看 (symbol-function 'THE-FUNCTION)
的值。如果该值是一个符号,那么 THE-FUNCTION
是一个别名。
但是,如果值不是符号,THE-FUNCTION
可能仍然使用 defalias
(或 fset
)定义。在那种情况下,THE-FUNCTION
不是另一个函数的符号的别名,而是函数定义的别名(例如,某个符号的当前函数定义,而不是符号本身)或变量定义(例如,键映射变量的值).
无论如何您可能都不关心这种情况 - 您可能甚至不认为它是别名。因此,测试 symbol-function
值是否为非 nil
符号可能就足够了。 (值 nil
表示给定符号既没有函数别名也没有任何其他函数定义。)
例如:
(defun aliased-p (fn)
"Return non-nil if function FN is aliased to a function symbol."
(let ((val (symbol-function fn)))
(and val ; `nil' means not aliased
(symbolp val))))
回应您评论中的问题:这是函数的命令版本:
(defun aliased-p (fn &optional msgp)
"Prompt for a function name and say whether it is an alias.
Return non-nil if the function is aliased."
(interactive "aFunction: \np")
(let* ((val (symbol-function fn))
(ret (and val (symbolp val))))
(when msgp (message "`%s' %s an alias" fn (if ret "IS" "is NOT")))
ret))
要清楚非符号大小写 - 如果代码这样做:
(defalias 'foo (symbol-function 'bar))
然后 foo
是 bar
的当前函数定义的别名。如果 bar
的定义随后被更改,那将不会影响 foo
的定义。 foo
的定义是 bar
在 defalias
时的定义的快照。
但是如果代码这样做:
(defalias 'foo 'bar)
那么 foo
就是符号 bar
的别名。 foo
的函数定义是符号bar
:(symbol-function 'foo)
= bar
。因此,如果 bar
的函数定义发生变化,那么 foo
的定义也会随之改变。
从 Drew 提到的另一个方向,您需要扫描整个符号列表以查看是否有 'pointed to' 给定的函数符号,因为别名是单向关系。
因此此函数将为您提供引用给定函数的别名列表,使用 mapatoms
遍历所有符号:
(defun get-aliases (fn-symbol)
"Return a list of aliases for the given function."
(let ((aliases nil))
(mapatoms (lambda (sym)
(if (eq fn-symbol (symbol-function sym))
(setq aliases (cons sym aliases)))))
(nreverse aliases)))
例如
(get-aliases 'cl-caddr) => (caddr cl-third)
因为 caddr
和 cl-third
'point to' cl-caddr。
我想检查一个函数是否存在默认\现有别名(在本例中:x-clipboard-yank
,但问题很笼统)。
是否有显示活动别名的 emacs 函数我可以用来计算它?
预期的行为类似于 shell alias
命令。
您可以查看 (symbol-function 'THE-FUNCTION)
的值。如果该值是一个符号,那么 THE-FUNCTION
是一个别名。
但是,如果值不是符号,THE-FUNCTION
可能仍然使用 defalias
(或 fset
)定义。在那种情况下,THE-FUNCTION
不是另一个函数的符号的别名,而是函数定义的别名(例如,某个符号的当前函数定义,而不是符号本身)或变量定义(例如,键映射变量的值).
无论如何您可能都不关心这种情况 - 您可能甚至不认为它是别名。因此,测试 symbol-function
值是否为非 nil
符号可能就足够了。 (值 nil
表示给定符号既没有函数别名也没有任何其他函数定义。)
例如:
(defun aliased-p (fn)
"Return non-nil if function FN is aliased to a function symbol."
(let ((val (symbol-function fn)))
(and val ; `nil' means not aliased
(symbolp val))))
回应您评论中的问题:这是函数的命令版本:
(defun aliased-p (fn &optional msgp)
"Prompt for a function name and say whether it is an alias.
Return non-nil if the function is aliased."
(interactive "aFunction: \np")
(let* ((val (symbol-function fn))
(ret (and val (symbolp val))))
(when msgp (message "`%s' %s an alias" fn (if ret "IS" "is NOT")))
ret))
要清楚非符号大小写 - 如果代码这样做:
(defalias 'foo (symbol-function 'bar))
然后 foo
是 bar
的当前函数定义的别名。如果 bar
的定义随后被更改,那将不会影响 foo
的定义。 foo
的定义是 bar
在 defalias
时的定义的快照。
但是如果代码这样做:
(defalias 'foo 'bar)
那么 foo
就是符号 bar
的别名。 foo
的函数定义是符号bar
:(symbol-function 'foo)
= bar
。因此,如果 bar
的函数定义发生变化,那么 foo
的定义也会随之改变。
从 Drew 提到的另一个方向,您需要扫描整个符号列表以查看是否有 'pointed to' 给定的函数符号,因为别名是单向关系。
因此此函数将为您提供引用给定函数的别名列表,使用 mapatoms
遍历所有符号:
(defun get-aliases (fn-symbol)
"Return a list of aliases for the given function."
(let ((aliases nil))
(mapatoms (lambda (sym)
(if (eq fn-symbol (symbol-function sym))
(setq aliases (cons sym aliases)))))
(nreverse aliases)))
例如
(get-aliases 'cl-caddr) => (caddr cl-third)
因为 caddr
和 cl-third
'point to' cl-caddr。