summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDante Catalfamo2021-05-02 00:26:05 -0400
committerDante Catalfamo2021-05-02 00:26:05 -0400
commit8d76b78741cb77fec62cb10970bce0259e1ebcc9 (patch)
tree7500195952d9081daa0c18a9e1a1bc18fc8df2ab
parent6d7669c07b72e651438c4b9075fadab9a889c138 (diff)
downloadblog-8d76b78741cb77fec62cb10970bce0259e1ebcc9.tar.gz
blog-8d76b78741cb77fec62cb10970bce0259e1ebcc9.tar.bz2
blog-8d76b78741cb77fec62cb10970bce0259e1ebcc9.zip
emacs-buffers-to-stdout: new blog post
-rw-r--r--content/posts/emacs-buffers-to-stdout/cover.pngbin0 -> 85386 bytes
-rw-r--r--content/posts/emacs-buffers-to-stdout/index.org89
2 files changed, 89 insertions, 0 deletions
diff --git a/content/posts/emacs-buffers-to-stdout/cover.png b/content/posts/emacs-buffers-to-stdout/cover.png
new file mode 100644
index 0000000..da413a5
--- /dev/null
+++ b/content/posts/emacs-buffers-to-stdout/cover.png
Binary files differ
diff --git a/content/posts/emacs-buffers-to-stdout/index.org b/content/posts/emacs-buffers-to-stdout/index.org
new file mode 100644
index 0000000..cce6ee2
--- /dev/null
+++ b/content/posts/emacs-buffers-to-stdout/index.org
@@ -0,0 +1,89 @@
+#+TITLE: How to get all Emacs daemon buffers from a shell script
+#+DATE: 2021-05-01T22:38:32-04:00
+#+DRAFT: true
+#+DESCRIPTION: A small script that will print all Emacs daemon buffers to stdout
+#+TAGS[]: emacs
+#+KEYWORDS[]: emacs
+#+SLUG:
+#+SUMMARY:
+
+#+ATTR_HTML: :title Emacs daemon buffers
+#+ATTR_HTML: :alt Emacs darmon buffers
+[[file:cover.png]]
+
+A while back I posted a response to someone's question on [[https://www.reddit.com/r/emacs/comments/ljtify/is_it_there_a_way_to_export_the_list_of_opened/gnhatdu/?context=3][reddit]] about
+how to get a list of all Emacs daemon buffers from a shell script. It
+was a pretty interesting problem so I thought I'd explain my answer
+here.
+
+The question was "Is it there a way to export the list of opened
+buffers to STDOUT?".
+
+In the comments I left a rather byzantine looking snippet of code that
+I'd managed to produce.
+
+#+begin_src
+emacs --batch --eval "(require 'server)" --eval "(mapc #'print (read (server-eval-at \"server\" '(format \"%s\" (mapcar (lambda (buffer) (format \"\\\"%s\\\"\n\" buffer)) (buffer-list))))))" | sed '/^$/d; s/^"//g; s/"$//g'
+#+end_src
+
+I've simplified the lisp slightly since I answered that question.
+Here's the updated version.
+
+#+begin_src
+emacs --batch --eval "(require 'server)" --eval "(mapc #'princ (read (server-eval-at \"server\" '(prin1-to-string (mapcar (lambda (buffer) (format \"%s\\n\" buffer)) (buffer-list))))))" 2>/dev/null
+#+end_src
+
+Here it is written in a way that's easier to read.
+
+#+begin_src
+emacs --batch \
+ --eval "(require 'server)" \
+ --eval "(mapc #'princ
+ (read (server-eval-at \"server\"
+ '(prin1-to-string (mapcar (lambda (buffer)
+ (format \"%s\\n\" buffer))
+ (buffer-list))))))" \
+ 2>/dev/null
+#+end_src
+
+
+Let's break it down.
+
+- =emacs= Emacs itself!
+ - =--batch= Runs Emacs in [[https://www.gnu.org/software/emacs/manual/html_node/elisp/Batch-Mode.html][=batch=]] mode, which executes commands
+ non-interactively and stops it from opening a window. This is
+ usually used for running Emacs lisp as a script.
+ - =--eval= Evaluates the following piece of elisp in the batch Emacs
+ - =(require 'server)= Loads the built-in =server= package. This is
+ used to connect to the running Emacs daemon
+ - =--eval= Since the previous elisp snippet was a complete
+ s-expression I evaluate the next expression as a new argument. I
+ could have also wrapped them both in a =progn=, but this felt cleaner.
+ - =mapc FUNCTION SEQUENCE= Apply =FUNCTION= to every object in the
+ list =SEQUENCE=.
+ - =princ= Outputs the printed form of an object to
+ =standard-out=. It's used here because it doesn't surround the
+ string in quotes like =print= does.
+ - =read STREAM= Read =STREAM=, in this case a string, and turn it
+ into a lisp object
+ - =server-eval-at \"server\" FORM= Evaluates =FORM= on the Emacs
+ daemon and returns the result. The quotes are escaped
+ because it's already inside a quote because it's a command
+ line argument.
+ - =prin1-to-string OBJECT= Return a string containing the
+ printed representation of =OBJECT=. I use this instead of
+ =princ= because that outputs the result to the minibuffer of
+ the Emacs daemon instead of returning it.
+ - =mapcar FUNCTION SEQUENCE= Applies FUNCTION to each
+ element of SEQUENCE and returns a list of the result.
+ - =(lambda (buffer) (format \"%s\\n\" buffer)= An
+ anonymous function that takes a buffer and returns the
+ string version of its name followed by a newline. The
+ quotes and newline are escaped because it's already
+ inside a quote because it's a command line argument.
+ - =buffer-list= Returns a list of all buffers in Emacs
+ - =2>/dev/null= Send the Emacs startup text, which is outputted to
+ =stderr=, to =/dev/null=. We don't want to see it.
+
+The result is a single line command that outputs the name of every
+buffer in the Emacs daemon, one per line, to =stdout=.