EMACS Lisp程序员做什么,当他们想要写一些大致相当于......
的东西时for line in open("foo.txt", "r", encoding="utf-8").readlines():
...(split on ws and call a fn, or whatever)...
...
当我查看EMACS lisp帮助时,我看到了将文件打开到文本编辑缓冲区的功能 - 这不是我想要的。我想我可以编写函数来访问文件的行,但如果我这样做,我就不希望用户看到它,而且,从文本处理看起来效率不高观点出发
答案 0 :(得分:9)
我认为原始Python代码的更直接的翻译如下:
(with-temp-buffer
(insert-file-contents "foo.txt")
(while (search-forward-regexp "\\(.*\\)\n?" nil t)
; do something with this line in (match-string 1)
))
我认为with-temp-buffer
/ insert-file-contents
通常比with-current-buffer
/ find-file-noselect
更受欢迎,因为前者保证您使用整个新副本文件内容。使用后一种结构,如果你碰巧已经有一个访问目标文件的缓冲区,那么find-file-noselect
就会返回该缓冲区,所以如果缩小了该缓冲区,你只会看到该文件的那一部分当你处理它时。
请注意,逐行处理文件可能更方便不。例如,这是一个表达式,它返回文件中所有连续数字序列的列表:
(with-temp-buffer
(insert-file-contents "foo.txt")
(loop while (search-forward-regexp "[0-9]+" nil t)
collect (match-string 0)))
(require 'cl)
首先引入loop
宏。
答案 1 :(得分:4)
是的,是您想要做的事情:在缓冲区中访问该文件,然后对该缓冲区中的文本进行操作。
您不必须显示缓冲区,即用户无需查看。
至于效率:在缓冲区中操作文本通常是操作文本的最有效方式。
您可以通过多种方式访问缓冲区中的文件。您可能希望使用现有的文件缓冲区,具体取决于用例。也就是说,如果文件已经打开"在Emacs中你可能想要使用它的缓冲区。
或者您可能想要忽略已经打开的任何现有文件缓冲区"文件,并将文件重新读入新缓冲区。为此,正如@Sean所提到的,您可以将insert-file-contents
与您创建的缓冲区一起使用。您可以使用with-temp-buffer
或generate-new-buffer
创建缓冲区,具体取决于您希望/需要使用的内容。
如果您确实要重用已经访问该文件的缓冲区,您可以测试它是否已在内存中修改,是否缩小等,并执行适合您的用例的任何操作。您可以使用函数find-buffer-visiting
检查是否已有缓冲区访问该文件(使用任何路径/文件名)。
要访问该文件,利用访问它的任何现有缓冲区,您可以使用find-file-noselect
。该函数返回访问文件的缓冲区,因此您可以将该缓冲区作为第一个参数传递给with-current-buffer
。这是一个简单的例子。
(with-current-buffer (let ((enable-local-variables ())) (find-file-noselect file))
;; Do some stuff with the text in the buffer.
;; Optionally save the buffer back to the file.
)
(enable-local-variables
与nil
的绑定是次要优化,适用于您不需要打扰缓冲区局部变量的常见情况。)