isamert / empv.el

An Emacs media player, media library manager, radio player, YouTube frontend
GNU General Public License v3.0
103 stars 18 forks source link

Let binding empv-display-current-format should work ? #54

Closed tvraman closed 7 months ago

tvraman commented 7 months ago

See for example: the let binding has no effect. (let ((empv-display-current-format "#{time-pos}")) (empv-display-current nil)) ; was hoping this would just display the time position

isamert commented 7 months ago

Yeah, unfortunately that does not work because empv-display-current is an async function (it calls some external commands and runs the main functionality after it gets the response from those commands).

isamert commented 7 months ago

However, instead of let-binding empv-display-current-format, you can do the following:

(empv--let-properties '(time-pos)
  (message "time-pos is %s" .time-pos))
tvraman commented 7 months ago

Thanks for the clarification.

I somehow -- perhaps naively tried:

(empv--let-properties '(time-pos) .time-pos)

To see if that would return the position but you likely already know that that didn't work:-)

The code in empv-display-current went beyond my ability to figure out how to use that fancy macro empv--let-properties could you perhaps add a simple usage example?

I see the let-alist expansion -- played with it using macrostep-mode but I still failed to figure it out. --

tvraman commented 7 months ago

Will try that; in the meantime messages crossed, I almost tried what you suggest but it failed yesterday. --

isamert commented 7 months ago

Thanks for the feedback, I'll add some documentation to clarify things a bit. The thing that complicates things is that I decided to use macros instead of simple functions (in some cases, I had to) so it is hard to distinguish between a synchronous call and an asynchronous one. For example

(empv--let-properties '(time-pos)
 .time-pos)

will yield nothing useful, because the body of the macro (.time-pos part) will be evaluated asynchronously, after the whole expression finishes. What essentially it does is this:

(empv--send-command
 (list "get_property" "time-pos")
 (lambda (result)
   ;; do something with the result
   ))

So it simply talks with mpv instance by sending it get_property time-pos command and then listens the mpv process asynchronously and then calls the callback lambda when it responds to our command. It does this asynchronously to not to block Emacs.

I also added another command called empv--send-command-sync which is essentially the same thing as empv--send-command but blocks Emacs until it gets the response so you can talk with mpv instance in synchronous fashion:

(empv--send-command-sync (list "get_property" "time-pos")) ;; This directly returns the time-pos value.

I still recommend using something like:

(empv--let-properties '(time-pos)
 (message "time-pos is %s" .time-pos))

if your sole purpose is to display it. This way it will not block Emacs but if you have a complicated logic empv--send-command-sync might also be an option. I guess it's not that bad to use empv--send-command-sync because it'll probably finish instantaneously and you'll not feel the blocking but I wrote empv this way to make it smoother.

tvraman commented 7 months ago

Thanks for the explanation, it all makes sense once you explain it;-)

I already have things working with the async version now.

You can see the results at https://github.com/tvraman/emacspeak/blob/master/lisp/emacspeak-empv.el#start-of-content

Note that emacspeak-empv now has a few additional commands in it:

  1. Navigation by time
  2. Custom filters

    Not sure if this is useful to empv users in general; feel free to take anything from there if you deem it useful; if you think it useful but dont have the time, I can try sending you a contrib section.

--