EMACS Lisp 程序员如何读取非编辑目的的文本文件?
How do EMACS Lisp programmers read text files for non-editing purposes?
当 EMACS Lisp 程序员想要编写大致相当于...的东西时,他们会做什么...
for line in open("foo.txt", "r", encoding="utf-8").readlines():
...(split on ws and call a fn, or whatever)...
..?
当我查看 EMACS lisp 帮助时,我看到了关于将文件打开到文本编辑缓冲区中的函数——这与我想要的不完全一样。我想我可以编写函数来访问文件的行,但如果我这样做了,我不希望用户看到它,此外,从文本处理的角度来看,它似乎效率不高。
是的,那是你想做的:访问缓冲区中的文件,并对缓冲区中的文本进行操作。
你不需要显示缓冲区,也就是说,用户不需要看到它。
关于效率:在缓冲区中操作文本通常是最操作文本的有效方式。
您可以通过多种方式访问缓冲区中的文件。您可能希望为此使用现有的文件缓冲区,具体取决于用例。也就是说,如果文件在 Emacs 中已经是 "open",那么您可能想要使用它的缓冲区。
或者您可能想要忽略任何现有的文件缓冲区,以获取一个已经 "open" 的文件,并将文件重新读入新的缓冲区。为此,正如@Sean 提到的,您可以将 insert-file-contents
与您创建的缓冲区一起使用。您可以使用 with-temp-buffer
或 generate-new-buffer
创建缓冲区,同样取决于您 want/need 使用它做什么。
如果你确实想重用一个已经在访问文件的缓冲区,你可以测试它是否在内存中被修改,它是否被缩小等等,并做任何适合你的用例的事情。您可以使用函数 find-buffer-visiting
.
检查是否已经有一个缓冲区访问文件(使用任何 path/file 名称)
要访问文件,利用正在访问它的任何现有缓冲区,您可以使用 find-file-noselect
。该函数 returns 访问文件的缓冲区,因此您可以将该缓冲区作为第一个参数传递给 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
的绑定是一个小优化,适用于您不需要为缓冲区局部变量操心的常见情况。)
我觉得比较直接的翻译原文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
返回,因此如果该缓冲区已缩小,您将只能看到文件的那一部分处理它。
请记住,而不是逐行处理文件可能更方便。例如,这是一个表达式 returns 文件中所有连续数字序列的列表:
(with-temp-buffer
(insert-file-contents "foo.txt")
(loop while (search-forward-regexp "[0-9]+" nil t)
collect (match-string 0)))
(require 'cl)
先引入loop
宏。
当 EMACS Lisp 程序员想要编写大致相当于...的东西时,他们会做什么...
for line in open("foo.txt", "r", encoding="utf-8").readlines():
...(split on ws and call a fn, or whatever)...
..?
当我查看 EMACS lisp 帮助时,我看到了关于将文件打开到文本编辑缓冲区中的函数——这与我想要的不完全一样。我想我可以编写函数来访问文件的行,但如果我这样做了,我不希望用户看到它,此外,从文本处理的角度来看,它似乎效率不高。
是的,那是你想做的:访问缓冲区中的文件,并对缓冲区中的文本进行操作。
你不需要显示缓冲区,也就是说,用户不需要看到它。
关于效率:在缓冲区中操作文本通常是最操作文本的有效方式。
您可以通过多种方式访问缓冲区中的文件。您可能希望为此使用现有的文件缓冲区,具体取决于用例。也就是说,如果文件在 Emacs 中已经是 "open",那么您可能想要使用它的缓冲区。
或者您可能想要忽略任何现有的文件缓冲区,以获取一个已经 "open" 的文件,并将文件重新读入新的缓冲区。为此,正如@Sean 提到的,您可以将 insert-file-contents
与您创建的缓冲区一起使用。您可以使用 with-temp-buffer
或 generate-new-buffer
创建缓冲区,同样取决于您 want/need 使用它做什么。
如果你确实想重用一个已经在访问文件的缓冲区,你可以测试它是否在内存中被修改,它是否被缩小等等,并做任何适合你的用例的事情。您可以使用函数 find-buffer-visiting
.
要访问文件,利用正在访问它的任何现有缓冲区,您可以使用 find-file-noselect
。该函数 returns 访问文件的缓冲区,因此您可以将该缓冲区作为第一个参数传递给 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
的绑定是一个小优化,适用于您不需要为缓冲区局部变量操心的常见情况。)
我觉得比较直接的翻译原文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
返回,因此如果该缓冲区已缩小,您将只能看到文件的那一部分处理它。
请记住,而不是逐行处理文件可能更方便。例如,这是一个表达式 returns 文件中所有连续数字序列的列表:
(with-temp-buffer
(insert-file-contents "foo.txt")
(loop while (search-forward-regexp "[0-9]+" nil t)
collect (match-string 0)))
(require 'cl)
先引入loop
宏。