reddit / emacs

How to open and edit a file from within a function

olivuser · 2022-09-15 14:06
Hej fellows, I tried to find a solution to this question on my own for quite a while now. I'm rather certain that I am also phrasing my problem the wrong way, because it is impossible that it is that hard to find. I want to write a function that opens my org agenda file(s) in buffer(s), operates on said buffer(s) and then saves them. More concretely, I want to have `org-sort-entities` sort my [`todos.org`](https://todos.org) file every time I used org-capture (using `org-capture-after-finalize-hook`). I am grateful for both pointers and complete solutions. As I said, for some reason I can't wrap my head around the way emacs opens files when it doesn't happen upon my initiative. Have a good day, fellows :) **SOLVED:** I was able to solve the problem! Thanks a bunch, u/MitchellMarquez42 and u/EternalMigrainity! Now I will say that the pointer provided by u/MitchellMarquez42 helped me find a solution that is clearer to me on first sight than the other one. Nonetheless, thank you both - not least because I not know that `with-current-buffer` and `with-temp-file` can use `find-file` as input. I had seen both elements - `with-*-*` and `find-file` \- but would not have come up with the idea to combine the two. This will make it that much easier to work with files in the future :-\* **EDIT:** For some reason, it did not work properly when invoked that way from a hook. I would add a new todo entry via org-capture and the org-agenda-file would not be sorted. DOES NOT WORK (defun org-sort-agenda-files-after-capture (file-list) (mapcar #'(lambda (file) (with-current-buffer (find-file file) (mark-whole-buffer) (org-sort-entries nil ?p) (save-buffer) (kill-buffer))) file-list)) (use-package org-capture :hook (org-capture-after-finalize . (org-sort-agenda-files-after-capture org-agenda-files))) Then I decided to try again removing the argument from the function, hardcoding `org-agenda-files` into the `org-sort-agenda-files-after-capture` function instead of the `file-list` parameter. It turns out that it worked. I don't know why. If you happen to know, I'd love to be enlightened :-) DOES WORK (defun org-sort-agenda-files-after-capture () (mapcar #'(lambda (file) (with-current-buffer (find-file file) (mark-whole-buffer) (org-sort-entries nil ?p) (save-buffer) (kill-buffer))) org-agenda-files)) (use-package org-capture :hook (org-capture-after-finalize . org-sort-agenda-files-after-capture)) ​
[deleted] · 2022-09-15 15:09
[removed]
[deleted] · 2022-09-15 15:23
[deleted]
EternalMigrainity · 2022-09-15 15:24
pointer lol xd https://pastebin.com/Rc9vV0Fu
EternalMigrainity · 2022-09-15 15:25
If this is not what you want then try clarifying a bit I don't know shit about org
EternalMigrainity · 2022-09-15 15:35
My code sorts entries invisibly, if you want to see everything happen in front of you then you could just have your org buffers appear via find-file and then use org-sort-entries and finally save the buffer, also, you should consider creating a KBD Macro for sorting with org-sort-entries that you can call from your code, it'll make things much easier.
EternalMigrainity · 2022-09-15 15:43
use dolist instead of dotimes sorry lmaOLOOOOO
MitchellMarquez42 · 2022-09-15 15:57
Emacs opens files with the command `find-file`. This opens the file in a new buffer, and returns the name of that buffer. You can use `with-current-buffer` to execute editing commands in said buffer, and `save-buffer` to save the buffer. So something like: ``` (with-current-buffer (find-file "/path/to/todos.org") (org-sort-entities) ;; I don't know how Agenda works but should be pretty straightforward (save-buffer) ;; optional kill-buffer if you want ) ``` The other commenter links a more complete example that opens multiple files. This is just a basic outline of how I'd approach the problem.