How do EMACS Lisp programmers read text files for purposes without editing?

What EMACS Lisp programmers do when they want to write something roughly equivalent ...

for line in open("foo.txt", "r", encoding="utf-8").readlines(): ...(split on ws and call a fn, or whatever)... 

..

When I look in the EMACS Lisp help, I see the functions of opening files in text editing buffers - not quite what I intended. I believe that I could write functions to visit the lines of a file, but if I did, I would not want the user to see this, and, moreover, it does not seem very efficient in terms of text processing.

+6
source share
2 answers

I think a more direct translation of the Python source code is as follows:

 (with-temp-buffer (insert-file-contents "foo.txt") (while (search-forward-regexp "\\(.*\\)\n?" nil t) ; do something with this line in (match-string 1) )) 

I think that with-temp-buffer / insert-file-contents usually preferable to with-current-buffer / find-file-noselect , because the first ensures that you are working with a fresh copy of the entire contents of the file. With the latter construction, if you already have a buffer visiting the target file, then this buffer is returned by find-file-noselect , so if this buffer is narrowed, you will see only part of the file when it is processed.

Keep in mind that it may not be more convenient to process a file in turn. For example, this is an expression that returns a list of all sequences of consecutive digits in a file:

 (with-temp-buffer (insert-file-contents "foo.txt") (loop while (search-forward-regexp "[0-9]+" nil t) collect (match-string 0))) 

(require 'cl) enter the loop macro first.

+9
source
  • Yes, what you want to do: visit the file in the buffer and operate on the text in this buffer.

  • You must not display buffer, ie, the user should not see him.

  • And as for efficiency: manipulating text in a buffer is usually the most efficient way to manage text.


You can visit the file in the buffer in several ways. You can use an existing file buffer for this, depending on the use case. That is, if the file is already β€œopen” in Emacs, then you can use its buffer.

Or you can discard any existing file buffer for an already β€œopen” file and read the file again into a new buffer. To do this, as @Sean mentions, you can use insert-file-contents with the generated buffer. You can create a buffer using with-temp-buffer or generate-new-buffer , depending, again, on what you need / need to do with it.

If you want to reuse a buffer that is already visiting the file, you can check if it has been changed in memory, if it has been narrowed, etc., and do whatever is appropriate for your use case. You can check if there is already a buffer by visiting the file (using any path / file name) using the find-buffer-visiting function.

To view a file using any existing buffer that visits it, you can use find-file-noselect . This function returns the buffer that the file visits, so you can pass this buffer as the first argument to with-current-buffer . Here is a simple example.

 (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. ) 

(Binding enable-local-variables with nil is a minor optimization for the normal case where you don't need to worry about local buffer variables.)

+4
source

Source: https://habr.com/ru/post/988191/


All Articles