From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Lele Gaifax Newsgroups: gmane.emacs.devel Subject: Support for PEP492 async quasi-keyword in python.el Date: Mon, 05 Oct 2015 19:14:18 +0200 Organization: Nautilus Entertainments Message-ID: <87h9m5w845.fsf@nautilus.nautilus> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1444065285 10015 80.91.229.3 (5 Oct 2015 17:14:45 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 5 Oct 2015 17:14:45 +0000 (UTC) To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Oct 05 19:14:39 2015 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 1Zj9LR-0003PA-7k for ged-emacs-devel@m.gmane.org; Mon, 05 Oct 2015 19:14:37 +0200 Original-Received: from localhost ([::1]:46744 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zj9LQ-0007TA-R0 for ged-emacs-devel@m.gmane.org; Mon, 05 Oct 2015 13:14:36 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:34776) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zj9LM-0007PR-9Z for emacs-devel@gnu.org; Mon, 05 Oct 2015 13:14:33 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zj9LI-0003y4-7S for emacs-devel@gnu.org; Mon, 05 Oct 2015 13:14:32 -0400 Original-Received: from plane.gmane.org ([80.91.229.3]:49842) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zj9LH-0003x2-TZ for emacs-devel@gnu.org; Mon, 05 Oct 2015 13:14:28 -0400 Original-Received: from list by plane.gmane.org with local (Exim 4.69) (envelope-from ) id 1Zj9LF-0003Eq-FW for emacs-devel@gnu.org; Mon, 05 Oct 2015 19:14:25 +0200 Original-Received: from 151.62.155.119 ([151.62.155.119]) by main.gmane.org with esmtp (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 05 Oct 2015 19:14:25 +0200 Original-Received: from lele by 151.62.155.119 with local (Gmexim 0.1 (Debian)) id 1AlnuQ-0007hv-00 for ; Mon, 05 Oct 2015 19:14:25 +0200 X-Injected-Via-Gmane: http://gmane.org/ Original-Lines: 157 Original-X-Complaints-To: usenet@ger.gmane.org X-Gmane-NNTP-Posting-Host: 151.62.155.119 User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5.50 (gnu/linux) Cancel-Lock: sha1:EAe/yI64z6j1hr5YCSUCJvUIzhU= X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 80.91.229.3 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:190950 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Hi all, I spent the afternoon teaching python.el to properly indent the new “async” constructs introduced in Python 3.5, and I'm attaching the result of my attempt. Of course it's far from being either correct or complete, but maybe some of you could give me some feedback on the following points: a) is there a better way to introduce the new "async" variants of "def|with|for" in the `block-start' regexp? b) how should the "await" quasi-keyword be handled? I mean, it's not a real keyword (that is, the assignment “await = 1” is valid code for example), but in an expression such as “return await foo()” it should probably be highlighted as such... c) the diff below breaks one existing test, namely `python-indent-region-5'; I will try to understand what's going on... Thank you in advance for any hint, ciao, lele. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=python-el+pep492.diff Content-Description: PEP492 async support for python.el diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 6ff12b5..9f5c087 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -384,7 +384,10 @@ python-mode-map (defconst python-rx-constituents `((block-start . ,(rx symbol-start (or "def" "class" "if" "elif" "else" "try" - "except" "finally" "for" "while" "with") + "except" "finally" "for" "while" "with" + ;; Python 3.5+ PEP492 + (and "async" (+ space) + (or "def" "for" "with"))) symbol-end)) (dedenter . ,(rx symbol-start (or "elif" "else" "except" "finally") @@ -395,7 +398,11 @@ python-mode-map symbol-end)) (decorator . ,(rx line-start (* space) ?@ (any letter ?_) (* (any word ?_)))) - (defun . ,(rx symbol-start (or "def" "class") symbol-end)) + (defun . ,(rx symbol-start + (or "def" "class" + ;; Python 3.5+ PEP492 + (and "async" (+ space) "def")) + symbol-end)) (if-name-main . ,(rx line-start "if" (+ space) "__name__" (+ space) "==" (+ space) (any ?' ?\") "__main__" (any ?' ?\") @@ -527,6 +534,8 @@ python-font-lock-keywords ;; fontified like that in order to keep font-lock consistent between ;; Python versions. "nonlocal" + ;; Python 3.5+ PEP492 + (and "async" (+ space) (or "def" "for" "with")) ;; Extra: "self") symbol-end) diff --git a/test/automated/python-tests.el b/test/automated/python-tests.el index 44b05e2..23d799a 100644 --- a/test/automated/python-tests.el +++ b/test/automated/python-tests.el @@ -604,6 +604,42 @@ python-tests-visible-string (should (eq (car (python-indent-context)) :after-line)) (should (= (python-indent-calculate-indentation) 0)))) +(ert-deftest python-indent-after-async-block-1 () + "Test PEP492 async def." + (python-tests-with-temp-buffer + " +async def foo(a, b, c=True): +" + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (goto-char (point-max)) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-after-async-block-2 () + "Test PEP492 async with." + (python-tests-with-temp-buffer + " +async with foo(a) as mgr: +" + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (goto-char (point-max)) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + +(ert-deftest python-indent-after-async-block-3 () + "Test PEP492 async for." + (python-tests-with-temp-buffer + " +async for a in sequencer(): +" + (should (eq (car (python-indent-context)) :no-indent)) + (should (= (python-indent-calculate-indentation) 0)) + (goto-char (point-max)) + (should (eq (car (python-indent-context)) :after-block-start)) + (should (= (python-indent-calculate-indentation) 4)))) + (ert-deftest python-indent-after-backslash-1 () "The most common case." (python-tests-with-temp-buffer @@ -1483,6 +1519,26 @@ python-tests-visible-string (beginning-of-line) (point)))))) +(ert-deftest python-nav-beginning-of-defun-3 () + (python-tests-with-temp-buffer + " +class C(object): + + async def m(self): + return await self.c() + + async def c(self): + pass +" + (python-tests-look-at "self.c()") + (should (= (save-excursion + (python-nav-beginning-of-defun) + (point)) + (save-excursion + (python-tests-look-at "async def m" -1) + (beginning-of-line) + (point)))))) + (ert-deftest python-nav-end-of-defun-1 () (python-tests-with-temp-buffer " --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit -- nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia. lele@metapensiero.it | -- Fortunato Depero, 1929. --=-=-=--