From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: John Wiegley Newsgroups: gmane.emacs.devel Subject: async.el: A simple asynchronous framework for Emacs Date: Mon, 18 Jun 2012 21:51:31 -0500 Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: dough.gmane.org 1340076039 23414 80.91.229.3 (19 Jun 2012 03:20:39 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Tue, 19 Jun 2012 03:20:39 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Tue Jun 19 05:20:39 2012 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Sgozb-0004mP-6a for ged-emacs-devel@m.gmane.org; Tue, 19 Jun 2012 05:20:35 +0200 Original-Received: from localhost ([::1]:41556 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Sgoza-0007El-Q1 for ged-emacs-devel@m.gmane.org; Mon, 18 Jun 2012 23:20:34 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:57012) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SgozY-0007Ee-C5 for emacs-devel@gnu.org; Mon, 18 Jun 2012 23:20:33 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SgozW-0006yA-CK for emacs-devel@gnu.org; Mon, 18 Jun 2012 23:20:31 -0400 Original-Received: from mail-yw0-f41.google.com ([209.85.213.41]:35835) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SgozW-0006xz-5e for emacs-devel@gnu.org; Mon, 18 Jun 2012 23:20:30 -0400 Original-Received: by yhr47 with SMTP id 47so5074500yhr.0 for ; Mon, 18 Jun 2012 20:20:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=to:subject:date:user-agent:mail-followup-to:from:message-id :mime-version:content-type; bh=EhclRY0cDPBTct6yxXtfNRN9pKePQ4V5OMAO/aaTFh0=; b=KZ3frAwBqViv4kKU0WLocFLHghzBQEDNhKFambqWJWGgolfK4Vp0PwMLTWfc7uXix3 s0D3GsM19WFgk/q+QKJ0kue+EZUNmIB2wsduIX9WLRl8jzw/iTrELeezvRLltrVx6fyu jZRQmOks5lo6ooX1dh45AC9zXz2ezNXV685v0/XPUKovPREN/yPO1bjeHQDjNB7buqLs 67LZIcE9OEphCpEp6EwmpnW+/3pyvR+3VplOznxhP7lHdgpPsnfviA3y2Day14QdEEeg CcuAmJUDCpH2p0lOhaHTfDwEZ5Ynzxwj+X5Ux9UVSF+yXir3m+lnnCh1qtztKzz6Mnki Wn2g== Original-Received: by 10.42.189.73 with SMTP id dd9mr6679075icb.49.1340076028316; Mon, 18 Jun 2012 20:20:28 -0700 (PDT) Original-Received: from vulcan.local (c-98-215-105-167.hsd1.il.comcast.net. [98.215.105.167]) by mx.google.com with ESMTPS id bp8sm19083657igb.12.2012.06.18.20.20.27 (version=TLSv1/SSLv3 cipher=OTHER); Mon, 18 Jun 2012 20:20:27 -0700 (PDT) User-Agent: Gnus/5.130006 (Ma Gnus v0.6) Emacs/24.1 (darwin) Mail-Followup-To: emacs-devel@gnu.org X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.213.41 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:151011 Archived-At: Hello, I think we've all wanted threading and asynchronicity in Emacs for some time now (Gnus, anyone?), and there have been many attempts to provide it. I propose a module for inclusion in Emacs, async.el, which offers a very ease to use model for asynchronicity, without the need for any threading (and its attendant complexities). It should work on every platform that supports asynchronous processes using `start-process'. The whole interface is two functions: `async-start' and `async-get' (of which the latter is optional). Here is the basic form of use: (async-start (lambda () ...) 'function-to-call-when-done) This will execute the lambda (which must *not* be byte-compiled -- in other words, don't use `function' or #') in a child Emacs asynchronously. When it's done, the return value is passed to `function-to-call-when-done' as an argument. (If you don't care about the return value, pass the `ignore' symbol as the second argument). If you pass no second argument, a future is returned. You can later call `async-get' on this future to obtain the value, blocking if necessary. That's it. All you need to do asynchronous computation within Emacs. Since it's likely that you'll want the child Emacs to heavy lifting based on the parent Emacs' configuration, you can use `async-inject-environment' to pass variable definitions across the process boundary: (async-start (lambda () (require 'some-module) (async-inject-environment "\\`some-module-") ...)) The variable definitions from the module "some-module" will be passed into the child. Using these facilities, here's all it takes to send e-mail asynchronously with smtpmail.el: (defun async-smtpmail-send-it () (async-start `(lambda () (require 'smtpmail) (with-temp-buffer (insert ,(buffer-substring-no-properties (point-min) (point-max))) ;; Pass in the variable environment for smtpmail ,(async-inject-environment "\\`\\(smtpmail\\|\\(user-\\)?mail\\)-") (smtpmail-send-it))) 'ignore)) I've also written dired-async.el, which performs copies, moves and deletes asynchronously. It works great with Tramp. The files are hosted on GitHub presently: https://github.com/jwiegley/emacs-async One thing I would love to do is to work with the authors of other modules -- such as one of my all-time favorites, Gnus -- to see how a facility like this can help improve user experience. Comments welcome, John p.s. This e-mail sent asynchronously with smtpmail.el :)