the-kenny / weechat.el

Chat via weechat's relay protocol in Emacs
177 stars 41 forks source link

Send notifications via libnotify(notify-osd) on systems that support it. #64

Open maxking opened 7 years ago

maxking commented 7 years ago

Most of the functionality works except for the part where one can choose the notification-handler.

I have defined a custom variable to point to the handler, but it looks like if you set the value of the variable later, it's previous value has already been added to the weechat-notification-handler-functions list.

I am very new to writing elisp, I think I need some help here.

maxking commented 7 years ago

@the-kenny I have tried debugging this issue and am still not very sure what exactly will fix things.

So I understand that in elisp symbols can be either functions or just have values. So,

(funcall weechat-notifications-default-handler :query)

works because the value of weechat-notifications-default-handler is a function. But,

(funcall 'weechat-notifications-default-handler :query)

with a quote, funcall tries to call it as a function and so I get the following taceback:

Debugger entered--Lisp error: (void-function weechat-notifications-default-handler)
  weechat-notifications-default-handler(:query)
  funcall(weechat-notifications-default-handler :query)
  eval((funcall (quote weechat-notifications-default-handler) :query) nil)
  elisp--eval-last-sexp(nil)
  eval-last-sexp(nil)
  funcall-interactively(eval-last-sexp nil)
  call-interactively(eval-last-sexp nil nil)
  command-execute(eval-last-sexp)

I get the same error when running my code in this MR. So, how can I change weechat-notify function to call the items in the list weechat-notification-handler-functions treating them like a symbol with value?

    (dolist (fn weechat-notification-handler-functions)
      (with-demoted-errors
        (funcall fn type sender text date buffer-ptr))))

Looks like there is something happening inside this part of code that I am not able to fix.

the-kenny commented 7 years ago

Sorry for not coming back to you earlier, short vacation :-)

I think (funcall 'weechat-notifications-default-handler :query) doesn't work in your example because elisp is actually a LISP-2. That means functions and variables don't share the same namespace. You can have a function under the symbol foo and a variable behind the same symbol:

(defun  foo () 42)
(defvar foo    23)
foo   ; => 23
(foo) ; => 42

This is as non-intuitive as it looks, and a common source of errors.

I'm not sure about the "correct" fix for this situation, but I can think of an easy one:

Add a new function weechat-notifications-notify or similar, with an implementation comparable to the following:

(defun weechat-notifications-notify (all necessary args)
  (funcall weechat-notifications-default-handler all necessary args))

This indirection should work around the LISP-2 issue and also handle the original "indirection" issue.