1

For instance the expression (mapcar (lambda (frame) (cons frame (list (window-list frame)))) (frame-list)) produces the output:

((#<frame *scratch* 0x55e9a0b70408> (#<window 280 on *scratch*>)) (#<frame *scratch* 0x55e99b016538> (#<window 248 on *scratch*>)) (#<frame *scratch* 0x55e99db04910> (#<window 215 on *scratch*>)) (#<frame *scratch* 0x55e99abaa0d0> (#<window 30 on *scratch*>)) (#<frame *scratch* 0x55e99a2677f0> (#<window 27 on *scratch*>))) 

with each

which is a list of frames and the windows in them.

In EXWM the function exwm-workspace-switch (frame-or-index &optional force) switches to a frame or a particular workspace.

How can I convert the hex value such as 0x55e9a0b70408 to a form which could be used in the exwm-workspace-switch function?

7
  • 1
    Not clear. Maybe an X-Y problem. Say what you're really trying to do. If exvm-workspace-switch expects a frame as argument then pass it a frame, not the hex number shown but the frame itself. #<frame *scratch* 0x55e99a2677f0> is just a print representation of the frame, not the frame. There's no way to obtain the frame from such a sequence of characters. Commented Jun 30, 2024 at 15:15
  • What I mean is how can the hex value 0x55e99a2677f0 on its own without the #<frame *scratch* be "cast" to a frame if you know it is a frame? I've done something like that in Object Pascal and want to know if its possible in Emacs Lisp. Commented Jun 30, 2024 at 19:52
  • As I said, I think there's no way to do that, from Lisp. Perhaps someone will correct me, though. Commented Jun 30, 2024 at 21:25
  • 1
    Do you know the workspace index of the frame that you are trying to switch to? From my cursory reading of the code, it seems that you should somehow know that. It is an integer that can take values from 0 to one less than the number of workspaces (which you can get by calling exwm-workspace--count). Assuming you know that index, you pass it to exwm-worspace-switch. That's the only supported way: the doc says "Passing a workspace frame as the first option or making use of the rest options are for internal use only." Commented Jul 1, 2024 at 13:26
  • @NickD This the reason why - emacs.stackexchange.com/questions/81610/…. When I do exwm-workspace-switch I want to see the frame a window is on as well. Not knowing how to get the workspace label from the frame is my problem. I probably have to create a map from workspace label to frame (#<frame *scratch* 0x55e9a0b70408> (#<window 280 on *scratch*>)) at startup. Hopefully there may be something like that in the EXWM source. Commented Jul 1, 2024 at 15:32

1 Answer 1

1

You shouldn't need this except for debugging purposes. Lisp code should manipulate frame objects, never their printed representation. The printed representation of a frame is only intended for debugging. If some interface offers a choice of frame where the user can select one in a buffer, you can put the text containing the user-readable frame description in an overlay or text property that contains the frame. Alternatively, there are functions such as select-frame-by-name that find the frame object matching a user-readable frame name.

There is no direct way to reconstruct an opaque object such as a buffer, frame, etc. from its printed representation. For many opaque objects, the representation isn't unique. For frames, the representation is unique: the number at the end is a pointer inside Emacs, which is distinct from any other object (frame or not). But Emacs doesn't expose that number except in the printed representation.

The following function looks for a frame with a matching printed representation. You can pass it either the number (as a string "0x...") or the whole printed representation ("#<frame ...>").

(defun get-frame-from-print (needle) "Return a frame from its print syntax (`#<frame ...>') or from the number used there. Return nil if the string does not correspond to an existing frame." (save-match-data (if (string-match "#<\(dead \)?frame .*\( 0x[0-9a-f]+>\)" needle) (setq needle (match-string 2 needle))) (let ((suffix (concat " " needle ">"))) (seq-some (lambda (frame) (and (string-suffix-p suffix (prin1-to-string frame)) frame)) (frame-list))))) 

Note that this will stop working if the printed representation of frame changes in a future Emacs version (it works as of Emacs 24–29).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.