kiwanami / emacs-deferred Goto Github PK
View Code? Open in Web Editor NEWSimple asynchronous functions for emacs lisp
License: GNU General Public License v3.0
Simple asynchronous functions for emacs lisp
License: GNU General Public License v3.0
Hello: The package looks very impressive. It took me a little while to figure out how to loop downloading. The solution below works. Could you comment on whether this is the "right" way to do things? In particular, I was a little surprised that the inner lexical-let
seems to be required. Then again, I am not an expert on lexical-let
. Any advice would be appreciated. If this, or something close to it, is correct, then it might be useful to add some similar example to the docs, to show that nested chains of deferred:$
work.
(defun download-freenums ()
(lexical-let ((freenums '("1310.6934"
"1310.7131"
"1310.8383"
"1310.8598"))
(pos 0)
(wait-time 50))
(deferred:$
(deferred:next
(lambda (x) (message (concat "Deferred start; first download: "
(nth pos freenums)))))
(deferred:nextc it
(deferred:lambda (x)
(message "Entering loop, let's see what happens if we nest these...")
;; This line was somewhat unexpected
(lexical-let ((mypos pos))
(deferred:$
(deferred:next
(lambda (x)
(message "Inside inner chain...")))
(deferred:url-retrieve (concat "http://uk.arxiv.org/e-print/"
(nth mypos freenums)))
(deferred:nextc it
(lambda (buf)
(with-current-buffer buf
(write-file (concat (nth mypos freenums) ".txt")))
(kill-buffer buf)))))
(if (> (length freenums) (incf pos)) ; return nil to stop this loop
(progn (message
(concat "(" (int-to-string pos) "-" (nth pos freenums)
") Looping..."))
(deferred:nextc (deferred:wait wait-time) self)))))
(deferred:nextc it
(lambda (x) (message "Deferred end."))))))
Hi, I am trying to make a number of concurrent http post requests from inside emacs. The deferred:parallel function seems perfect for this task however I cannot get it to work.
I have an example function with three requests being made bellow. I would like them to all complete asynchronously in parallel and then return the result as a list in the deferred:nextc function so I can operate on them.
(defun my-deferred-func ()
(let ((lk ))
(deferred:$
(deferred:parallel
(request (format "http://localhost:%s" tern-known-port)
:type "POST"
:parser 'json-read
:success (function* (lambda (&key data &allow-other-keys)
(push (cdr (car data)) lk)))
:data
(format "{\"query\":{\"end\":%s,\"file\":\"%s\",\"type\":\"type\",\"preferFunction\":true}}"
196
(buffer-file-name)
)
:sync nil)
(request (format "http://localhost:%s" tern-known-port)
:type "POST"
:parser 'json-read
:success (function* (lambda (&key data &allow-other-keys)
(push (cdr (car data)) lk)))
:data
(format "{\"query\":{\"end\":%s,\"file\":\"%s\",\"type\":\"type\",\"preferFunction\":true}}"
196
(buffer-file-name)
)
:sync nil)
(request (format "http://localhost:%s" tern-known-port)
:type "POST"
:parser 'json-read
:success (function* (lambda (&key data &allow-other-keys)
(push (cdr (car data)) lk)))
:data
(format "{\"query\":{\"end\":%s,\"file\":\"%s\",\"type\":\"type\",\"preferFunction\":true}}"
196
(buffer-file-name)
)
:sync nil)
)
(deferred:nextc it (lambda (args) args))
)))
The above requests make a simple post request to the ternjs server.
Any guidance on using deferred:parallel? I have also seen the deferred:url-post but having trouble wrapping my head around that function too.
This is an excellent library.
When I'm trying to create a POST command with raw format in the data field. It won't let me do this because following code in the deferred:url-post
:
(url-request-data (deferred:url-param-serialize params))
e.g. I need to fill in the data field with a JSON object.
So I'm currently using deferred:url-retrieve
to complete my mission.
It would be very nice if the API is more generic. :D
The test codes test-deferred.el and test-concurrent.el fail.
They should be fixed as soon as possible.
Hello like for ctables, I get this during the installation
Install emacs-deferred-el for emacs23
install/deferred: Handling install for emacsen flavor emacs23
In deferred:earlier-main:
deferred.el:655:40:Warning: value returned from (length (symbol-value G20439))
is unused
deferred.el:655:40:Warning: value returned from (symbol-value G20441) is
unused
deferred.el:655:40:Warning: value returned from (length (symbol-value G20439))
is unused
deferred.el:655:40:Warning: value returned from (symbol-value G20441) is
unused
Wrote /usr/share/emacs23/site-lisp/deferred/deferred.elc
Wrote /usr/share/emacs23/site-lisp/deferred/concurrent.elc
Install emacs-deferred-el for emacs24
install/deferred: Handling install for emacsen flavor emacs24
In deferred:earlier-main:
deferred.el:655:40:Warning: value returned from (length (symbol-value G20439))
is unused
deferred.el:655:40:Warning: value returned from (symbol-value G20441) is
unused
cheers
Frederic
Currently, the documentation doesn't clearly indicate what "cancelling" involves. It probably wouldn't hurt to be explicit what does and what doesn't occur with cancelling. For example, a modified version of an example from the documentation reveals that cancelling does not imply that things halt or are terminated in any way (the WAIT continues and the subsequent NEXTC does its thing as well):
(deferred:$
(deferred:earlier
(deferred:process "sh" "-c" "sleep 3 | echo 'hello!'")
(deferred:$
(deferred:wait 4000) ; timeout msec
(deferred:nextc it (message "canceled!"))))
(deferred:nextc it
(lambda (x) (insert x))))
#16 に関する議論ですが、 twitter でやるより日本語でも良いから issue にでやったほうが便利じゃないかと思ったのでこっちに作ってみましたがどうでしょう? twitter のほうが良いですか?
放っておくとマージが辛くなりそうなので、決めたほうが良いと思うこと (後の方に書いてますが、 sphinxcontrib-emacs の現状にかなり左右されると思います):
sphinxcontrib-emacs の現状なんですが、
ttps://github.com/flycheck/sphinxcontrib-emacs/issues/12 (←2chっぽい)
で議論した感じだと、「ReST マークアップに *Help*
を組み合わせる案、良いと思ったんだけど色々問題出てきてやっぱやめようか迷ってる。ReSTの処理系を色々弄って実験してる最中だし忙しいし、リリースまだまだ遠いかも。」みたいな感じらしいです。
ad147a3 や 1814a40 で提案した docstring のテンプレートは ReST にかなり依存した書き方になっているんで、 sphinxcontrib-emacs が 「ReST やっぱり辞める。ごめんね。」ってなった場合に、大規模な docstring のスタイル変更が必要になります。doc/requirements.txt で書いてあるように github 経由で必要な sphix module をインストールしているんですが、最悪リビジョンを指定して使い続けることもできるんで、このまま移行してしまうという方法も一応考えられます。 docstring が充実するという意味では、 Emacs hacker な人たち的にはプラスだと思いますが、二度手間になる可能性があるのを考えるとあまり推してしまってはまずいかな、とも思います。
私の提案としては、こんな感じです(楽さを重視):
Is it OK to use deferred:sync!
in normal code, i.e. outside testing and debugging? Will that function continue to be supported in the future?
I've got a situation where I've written some code using deferred. It's part of the emacs-ycmd
project, for communicating with a completion server. However, the completion frameworks I want to integrate with (company
, auto-complete
, etc.) operate in a very synchronous way. It seems that the simplest way to integrate my asynchronous, deferred-based code with their frameworks is to use something like deferred:sync!
.
So, is it safe for me to use deferred:sync!
? It seems to do exactly what I need.
If it's not OK to use deferred:sync!
, is there an alternative? The only other option I can see is to have a synchronous and asyncronous version of my HTTP request code, and that seems silly.
What do you think about defining a set of anamorphic versions of the functions, like this:
(defmacro deferred::nextc (d &rest body) ;; the prefix could be different.
`(deferred:nextc ,d (lambda (result)
,@body)))
Here it is how the readme example will look like(using dash's ->
).
(-> (deferred::next (message "deferred start"))
(deferred::nextc
(message "chain 1")
1)
(deferred::nextc (message "chain 2 : %s" result))
(deferred::nextc (read-minibuffer "Input a number: "))
(deferred::nextc (message "Got the number : %i" result))
(deferred::error (message "Wrong input : %s" error)))
This issue is coming up in a downstream usage, via company-jedi, aka jedi (python auto complete in emacs).
Used emacs + TRAMP to work on a ros project
deferred error : (user-error "Not a Tramp file name: \"/Workspace [bazel]: /home/edgar/code/ros
Rosbag: Saving bag file LOCALLY to /home/edgar/data/ext_dsshare/emacs/site-lisp/\"")
This happening even when I'm not over tramp, now directly working on the machine.
(let ((default-directory "/"))
(deferred:nextc (deferred:process "pwd") 'message)
(let ((default-directory "~/"))
(dotimes (_ 3)
(sleep-for 0.1)))) ; prints $HOME ("/" is expected).
default-directory
はサブプロセスの $PWD を決めるのに使われますが、 deferred の process 系関数だと、それを決める方法が無いようです。
I'm writing an emacs mode that relies on a parser that returns a non-zero status code if there are certain types of parsing errors. I'd like to extract the stderr output in these cases, however the best I've been able to figure out how to do is to extract the text that also specifies that there has been an error within the deferred library.
Looking in the source code, it looks like the message is immediately run through a format function. Is there a way to get the stderr output without having to parse this string?
I followed the example in the documentation related to lexical binding:
(let ((a (point)))
(deferred:$
(deferred:wait 1000)
(deferred:nextc it
(lambda (x)
(goto-char a)
(insert "here!")))))
In Emacs 26.1 I did a evaluation on region with above code and I got an error like:
deferred error : (void-variable a)
I have a feeling that deferred's implementation could become a lot cleaner for 26. :) Great library, btw, I use it for interacting with REST APIs.
I'd add monadic notation macro in next version v0.6.0.
Here is a sample code:
(let (aa bb)
(deferred:do
(aa <- (deferred:process-shell "ls /var | wc -l"))
(bb <- (deferred:liftd length (deferred:process-shell "ls /lib")))
(lambda (x)
(message "var: %s / lib: %s" aa bb))))
The definition is the same as edbi:seq
at edbi.el.
https://github.com/kiwanami/emacs-edbi/blob/master/edbi.el#L119-L144
The documentation warns that sometimes a "finally" block may not be executed due to asynchrony. If I have some clean-up code that needs to be run no matter how a deferred chain terminates, what's the best, most robust way to do that? I worry about implementing cleanup code that silently gets ignored sometimes.
Hi,
I'm working on making a CPU-intensive function called from the modeline loop asynchronous, and am using a simple boolean var as a lock to skip body of a deferred:nextc it
function when the lock is active. Unfortunately deferred:wait-idle
unconditionally blocks execution of the deferred task chain. Would it be possible useful to add a third argument to its function definition? Something like a bool, that if nil
will not block while waiting for the idle timer to expire (eg: skip the timer if nil
). The form would become deferred:wait-idle (msec) (optional-boolean-lock)
.
I'm using a simple:
(deferred:$
(deferred:wait-idle idle-wait-value)
(deferred:next it (lambda (elapsed) set-lock-and-do-slow-CPU-intensive-stuff))
(deferred:next it (lambda (result) format-result-as-a-string-and-set-a-var-and-unset-lock)))
The buffer-local var set in the 3rd task is evaluated in the modeline loop. The 3rd task also unsets the lock. The specific issue I'm experiencing is that the unconditional wait-idle introduces a minimum latency of 2x the idle-wait-value. In my case it might be possible to merge 2nd and 3rd tasks, but I believe other people would find it useful to be able to conditionally skip the wait-idle task, thus eliminating the guarantied latency of 1x idle-wait-value
.
Thank you for maintaining emacs-deferred!
Nicholas
It's been 2.5 years since the last release, and a lot of stuff has happened. It would be nice if there were an actual number authors could use for dependencies, rather than having to depend on the melpa release.
The latest stable release is v0.5.1, but the marmalade Emacs package repository only offers v0.3.1. Can the latter be updated or removed? In my opinion, removing deferred
from marmalade entirely is a fine option, since MELPA Stable already offers v0.5.1.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.