0

In wakatime-mode, there are a bunch of process calls that is done by the wakatime-call function. It calls a predefined shell command, so no real magic inside.

Now I’d like to make it a bit more error prone by adding a retry count. However, as this is done by a process sentinel, I have to create a lambda for this. A process sentinel takes two parameters, process and signal.

Question is, is it possible to somehow pass the value of a local (ie. function parameter) variable to a lambda for use, thus converting the lambda into a clojure? I’d prefer to go without moving to lexical binding.

Backquote is not an option (or is it?), as the variable I want to reference is not in the function’s argument list.

Here is the function:

(defun wakatime-call (savep &optional retrying)
  "Call WakaTime command."
  (let*
    ((command (wakatime-client-command savep t))
     (process-environment (if wakatime-python-path
                              (cons (format "PYTHONPATH=%s"
                                            wakatime-python-path)
                                    process-environment)
                            process-environment))
     (process (start-process
               "Shell"
               (generate-new-buffer " *WakaTime messages*")
               shell-file-name
               shell-command-switch
               command)))

    (set-process-sentinel process
                          `(lambda (process signal)
                             (when (memq (process-status process) '(exit signal))
                               (kill-buffer (process-buffer process))
                               (let ((exit-status (process-exit-status process)))
                                 (when (and (not (= 0 exit-status)) (not (= 102 exit-status)))
                                   (error "WakaTime Error (%s)" exit-status))
                                 (when (= 102 exit-status)
                                        ; If we are retrying already, error out
                                   (if retrying
                                       (error "WakaTime Error (%s)" exit-status)
                                        ; otherwise, ask for an API key and call ourselves
                                        ; recursively
                                     (wakatime-prompt-api-key)
                                     (wakatime-call savep t)))))))

    (set-process-query-on-exit-flag process nil)))

The goal is to access savep and retrying in the process sentinel’s lambda/closure.

GergelyPolonkai
  • 748
  • 5
  • 12
  • There are several duplicate or near-duplicate questions. See [1](http://emacs.stackexchange.com/q/20063/105) and [2](http://emacs.stackexchange.com/q/4265/105), for instance. You need to either (a) use lexical binding or (b) insert the *value* of the argument, not just its name (symbol), into the lambda form. – Drew Sep 30 '16 at 14:29
  • 1 seems not to be an option for me (or I just don’t understand this whole lambda/clojure thing correctly). I’m still looking into option 2. – GergelyPolonkai Oct 03 '16 at 10:33
  • n.b. "Clojure" is a programming language. You are referring to a "closure". Not the same thing (despite being pronounced the same way :) – phils Oct 03 '16 at 11:19
  • Please *show* the code (ideally a minimal example), rather than *describing* it. – phils Oct 03 '16 at 11:25
  • @phils: that’s a typo of mine, as I was just talking about Clojure with a friend minutes before. – GergelyPolonkai Oct 03 '16 at 11:30
  • You've already backquoted the lambda; now just evaluate the values within (e.g. `,savep` instead of `savep`) to use its *value* in the definition of the function. (This being the non-closure approach.) – phils Oct 03 '16 at 12:19
  • Oh… all the examples used this `,savep` formula for the lambda’s parameters, not for variables completely outside of it. Thank you for pointing it out! How should this question be closed? Should it remain a duplicate? – GergelyPolonkai Oct 04 '16 at 11:25

0 Answers0