小编Jis*_*Yoo的帖子

Emacs:defun 或 defmacro 主体中的代码不能引用周围的词法变量?

2013 年 5 月更新:从 GNU Emacs 24.3.1 开始,(let .. (defun..)) 字节编译很好,没有警告,并且字节编译代码与未编译代码的工作方式相同。只是不要忘记将文件变量添加lexical-binding: t到要字节编译的文件中。现在不需要这个问题末尾的解决方法。


词法绑定 - Emacs Lisp 手册中有这样一段:

请注意,像 symbol-value、boundp 和 set 这样的函数仅检索或修改变量的动态绑定(即其符号值单元格的内容)。此外,defun 或 defmacro 主体中的代码不能引用周围的词法变量。

我不确定我是否理解了第二句话的意思。在以下应在词法绑定模式下运行的代码中, defun 主体中的代码成功引用了 name 的词法绑定值n

(let ((n 0))
  (defun my-counter ()
    (incf n)))

(my-counter) ;; 1
(my-counter) ;; 2
Run Code Online (Sandbox Code Playgroud)

这句话只是说 (let .. (defun ..)) 是一种不好的做法吗?


解决方法

;; -*- lexical-binding: t -*-

;; a way to define the counter function without byte-compile error or warning

(defvar my--counter-func
  (let ((n …
Run Code Online (Sandbox Code Playgroud)

lisp emacs elisp lexical-scope emacs24

5
推荐指数
1
解决办法
1214
查看次数

如何在Emacs中挂钩"缓冲区已经缩减了很多"

Emacs说,

缓冲区foo.txt已经缩减了很多; 在该缓冲区中禁用自动保存,直到下一次实际保存

当它检测到大量文本消失时自动保存时间,并禁用自动保存,除非auto-save-include-big-deletions是非零.

我怎么能挂钩这个Emacs事件检测到缓冲区已经缩小了很多?我想要挂钩,因为我想在缓冲区大量收缩的时候设置一个缓冲区本地标志,以便当我这样做时save-some-buffers,它的一个建议会检测到该标志并对我说"嘿,这个缓冲区已经缩小了很多.不要忘记看到差异以确保你没有错误地删除一些大块".除了备份之外,这还不错.简单地比较保存前缓冲区的大小和保存的文件将无法检测到添加大量的情况,然后错误地删除批次然后保存.

emacs

5
推荐指数
1
解决办法
171
查看次数

用于为Lisp生成分步框图的工具

是否有一个工具需要一个简短的Lisp代码片段,然后生成一系列框图来表示代码的每一步的状态?

我在考虑这样的事情:在线Python导师.

这样的事情可以很好地回答新手Lisp问题.很多新手问题是基于以下一个或多个问题的混淆:

  • 分享通过的含义

  • 共享结构

  • 破坏性的功能

通过调用这样的工具,可以轻松,直观地演示所有这些内容.我不必画一个框图来帮助一个新手,我可以通过将新手的代码或我的示例代码提供给该工具来生成图表.我不必希望新手会知道像引用,相同对象,不同对象,对象身份,新鲜缺点等词语,因为图表会讲述整个故事,甚至可以帮助解释这些词语的含义.

lisp visualization

5
推荐指数
0
解决办法
167
查看次数

在Emacs Lisp中,如何找到符号的定义位置

当我这样做C-h f或者C-h v,帮助告诉我在哪个文件中定义符号或从哪里自动加载.如何以编程方式查找相同的信息?

emacs elisp

5
推荐指数
1
解决办法
630
查看次数

如何调试字体锁定关键字错误

如何调试我写的字体锁定关键字?例如

(progn
  (font-lock-add-keywords
   nil
   '(
     ;; ("hi1" . 'success)
     ("hi2" . (intern (concat "warn" "ing")))
     ))
  (font-lock-fontify-buffer))
Run Code Online (Sandbox Code Playgroud)

将在Messages缓冲区中生成以下消息:

Error during redisplay: (jit-lock-function 1) signaled (wrong-type-argument stringp 22)
Run Code Online (Sandbox Code Playgroud)

为了在错误的类型参数错误时看到调用堆栈,我调用toggle-debug-on-error并且在字体锁定错误时Emacs仍然没有进入调试器.

debugging emacs elisp syntax-highlighting font-lock

5
推荐指数
1
解决办法
679
查看次数

如何以编程方式触发或使用edebug进行检测?

C-u C-M-x使用edebug检测评估defun表单.我能以编程方式执行此操作吗?我想这样做是因为我想写一个以下形式的elisp文件:

;;; define a function with edebug instrumented.
...


;;; do something that invokes the function with particular arguments.
...
Run Code Online (Sandbox Code Playgroud)

然后我可以运行emacs -q --load那个elisp文件,逐步执行代码,了解有关错误的进一步调查,在我原来的emacs会话中编辑elisp文件,emacs -q --load再次运行它,然后重复.

debugging emacs elisp

5
推荐指数
1
解决办法
99
查看次数

在过去处理Emacs Lisp动态范围陷阱

在过去,Emacs不支持词法范围.我想知道当时人们如何处理动态范围的特定陷阱.

假设Alice编写的命令my-insert-stuff依赖于fp-repeat定义的函数fp.el(我们假设它是一个为Bob编写的函数式编程提供大量函数的库),并且假设fp-repeat是多次重复调用函数.

init.elAlice的部分内容:

(require 'fp)

(defun my-insert-stuff ()
  (interactive)
  ;; inserts "1111111111\n2222222222\n3333333333" to current buffer
  (dolist (i (list "1" "2" "3"))
    (fp-repeat 10
               (lambda ()
                 (insert i)))
    (insert "\n")))
Run Code Online (Sandbox Code Playgroud)

fp.elBob的部分内容:

(defun fp-repeat (n func)
  "Calls FUNC repeatedly, N times."
  (dotimes (i n)
    (funcall func)))
Run Code Online (Sandbox Code Playgroud)

爱丽丝很快发现她的命令不像她预期的那样有效.那是因为Alice的使用i和Bob的使用i相撞.在过去,爱丽丝或/和鲍勃可以做些什么来阻止这种碰撞的发生?

也许Bob可以将文档字符串更改为

"Calls FUNC repeatedly, N times.
Warning: Never use i, n, func in FUNC body as nonlocal variables."
Run Code Online (Sandbox Code Playgroud)

emacs elisp dynamic-scope

4
推荐指数
2
解决办法
188
查看次数

Emacs 中普通缓冲区和空间前缀缓冲区的区别?

通过空格前缀缓冲区,我的意思是名称以空格开头的缓冲区。不确定此类缓冲区的官方术语是什么。

我认为空间前缀缓冲区的唯一区别是对它们禁用了撤消,但似乎还有其他差异导致包htmlize对空间前缀缓冲区的反应不同。

(require 'htmlize)

;; function to write stuff on current buffer and call htmlize-region
(defun my-test-htmlize ()
  (insert "1234567")
  (emacs-lisp-mode)
  ;; (put-text-property 1 2 'font-lock-face "bold")
  (put-text-property 3 4 'font-lock-face 'bold)
  (with-current-buffer (htmlize-region (point-min)
                                       (point-max))
    (buffer-string)))

;; function that makes a (failed) attempt to make current buffer behave like a normal buffer
(defun my-make-buffer-normal ()
  (buffer-enable-undo))

;; like with-temp-buffer, except it uses a buffer that is not a space prefix buffer.
(defmacro my-with-temp-buffer-with-no-space-prefix (&rest body)
  (declare (indent …
Run Code Online (Sandbox Code Playgroud)

emacs elisp

4
推荐指数
1
解决办法
369
查看次数

如何在Emacs Lisp中模拟特定的按键

上下文:我想制作一个次要模式,按下f两次快速结果,无论当时(应该做什么.这并不总是意味着插入(.例如,在启用了paredit模式或autopair模式的缓冲区中,按下(通常会导致插入().在paredit模式缓冲区中,有时会导致包装所选文本:例如,如果我选择a b并按下(,则应该导致替换选择(a b).

为了检测f被按两次,我只需要在http://www.emacswiki.org/emacs/electric-dot-and-dash.el中的短代码中采用逻辑.

所以唯一缺少的部分是一个Lisp代码片段,它告诉Emacs" (现在触发按下!"

我想到的第一件事就是片段应该这样做

  1. 找到绑定到该键的命令 (
  2. 然后在该命令上以交互方式调用call.

但是,如果自动配对包(autopair或paredit或其他类似的包)绑定(到一个命令,该命令具有查找用于调用命令的键的逻辑,或者如果包只依赖于自我插入-hook或post-command-hook而不是绑定(.


更新

我已经查找了Key Chord文档,结果证明我正在尝试解决这个问题的答案有一个更简单的解决方案:

(require 'key-chord)
(key-chord-mode 1)

(defvar my-easy-open-paren-mode-map
  (let ((map (make-sparse-keymap)))
    (key-chord-define map ",." (kbd "("))
    map))
(define-minor-mode my-easy-open-paren-mode
  "In this mode, pressing . and , together is another way of pressing the open paren.")

(defvar my-easy-semicolon-mode-map
  (let ((map (make-sparse-keymap)))
    (key-chord-define map …
Run Code Online (Sandbox Code Playgroud)

emacs elisp key-bindings

4
推荐指数
1
解决办法
1892
查看次数

Lisp中树结构的定义

来自 Common Lisp HyperSpec 词汇表:

ñ。1. 由 conses 和 atom 组成的二进制递归数据结构:conses 本身也是树(有时称为“子树”或“分支”),而原子是终端节点(有时称为叶子)。通常,叶子代表数据,而分支在这些数据之间建立某种关系。2. 一般来说,任何具有“分支”和叶子概念的递归数据结构。

树形结构ñ。(一棵树的)构成这棵树的一组 conses。请注意,虽然每个这样的 cons 的 car[1b] 组件是树结构的一部分,但作为树中每个 cons 的汽车的对象本身并不是其树结构的一部分,除非它们也是 conses。

树结构定义中的最后一句提出了一个问题,那就是,cdrs 也可以这样说吗?

在“树”的定义中使用二进制一词似乎表明就树而言,汽车与 cdr 之间没有区别,但是“树结构”的定义似乎对汽车特殊对待,所以我很困惑。

lisp tree common-lisp

4
推荐指数
1
解决办法
1896
查看次数