From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 31 Oct 2015 08:47:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: 21798@debbugs.gnu.org X-Debbugs-Original-To: bug-gnu-emacs@gnu.org Received: via spool by submit@debbugs.gnu.org id=B.144628119612104 (code B ref -1); Sat, 31 Oct 2015 08:47:01 +0000 Received: (at submit) by debbugs.gnu.org; 31 Oct 2015 08:46:36 +0000 Received: from localhost ([127.0.0.1]:46706 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZsRo2-000399-Ql for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:35 -0400 Received: from eggs.gnu.org ([208.118.235.92]:40872) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZsRnh-00038c-S8 for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZsRnf-0005Kh-FD for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:13 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, HTML_MESSAGE,T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:52297) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZsRnf-0005Kd-CF for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50877) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZsRnd-0003yb-Fr for bug-gnu-emacs@gnu.org; Sat, 31 Oct 2015 04:46:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZsRna-0005KP-4F for bug-gnu-emacs@gnu.org; Sat, 31 Oct 2015 04:46:09 -0400 Received: from mail-wi0-x22a.google.com ([2a00:1450:400c:c05::22a]:38003) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZsRnZ-0005KL-QV for bug-gnu-emacs@gnu.org; Sat, 31 Oct 2015 04:46:06 -0400 Received: by wicll6 with SMTP id ll6so23480654wic.1 for ; Sat, 31 Oct 2015 01:46:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:message-id:mime-version:content-type; bh=zyQlVlgyJEk8cBTCuJtVl8M4ogSm8+fSb8t2CHeuhYw=; b=mPm0ljRCA9RM6ac6fNTJSjwkY/nGsrKuDXtgd9vTk3CUjZBslI+Cf37xj/Mvh4jbN1 rzwkeSGMe0mpsZjZ+ruUoEIUONy+mcveZAA54IdFC0hDMDPMFBFYHxAD6wj87QJybkG6 1vc7n6Ejl/NC8XyBKZysIElTfmZqc756sA7MvqNJVM03cRSwVWGt/fb9Wbj01RcVOsqy XiDFfhOw5CaIs/x68/sXkBCopqcbk6Jc9HOmlCVxyWI4lhtOFCw/J1y7sUfbnpNV+mkL BRHHUZpm7XoIEJ5BIsSqnmC5KPDjyKdrvQWr7gK9jDz4xUPjPN/BXEVIvfpP2m10x4w+ ujww== X-Received: by 10.194.61.13 with SMTP id l13mr15307014wjr.76.1446281165048; Sat, 31 Oct 2015 01:46:05 -0700 (PDT) Received: from [192.168.101.25] ([77.40.215.202]) by smtp.gmail.com with ESMTPSA id c67sm6831605wmh.11.2015.10.31.01.46.03 for (version=TLSv1/SSLv3 cipher=OTHER); Sat, 31 Oct 2015 01:46:04 -0700 (PDT) Date: Sat, 31 Oct 2015 09:46:02 +0100 From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Message-Id: <1446281162.2607.0@smtp.gmail.com> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-b4IqqtSK8ay5FwlaWkkt" X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -4.0 (----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-b4IqqtSK8ay5FwlaWkkt Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Sometimes when working with a JSON structure, one needs to find the path to a particular element. That can be tiresome to do manually, especially if the structure is deep. The proposed patch extends json.el with the ability to retrieve the path to a particular JSON element. See the following video for an example of how it can be used by an interactive command, to show the path to the JSON element at point: http://folk.uio.no/simenheg/json-mode.webm The patch follows! -- Simen From f6ddd3b797d6b0d92a1ffa0f5db59543ac7cdc11 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D Date: Sun, 25 Oct 2015 14:44:59 +0100 Subject: [PATCH] Add support for retrieving paths to JSON elements Add support for retrieving the path to a JSON element. This can for instance be useful to retrieve paths in deeply nested JSON structures. * lisp/json.el (json-path-to-position): New function for retrieving the path to a JSON object at a given position. (json--path-to-position, json--path): New variables, used internally by `json-path-to-position'. (json-read-object, json-read-array): Respect `json--path-to-position'. * test/automated/json-tests.el (test-json-path-to-position-with-objects) (test-json-path-to-position-with-arrays): New tests for `json-path-to-position'. --- lisp/json.el | 67 ++++++++++++++++++++++++++++++++++++++++++-- test/automated/json-tests.el | 14 +++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/lisp/json.el b/lisp/json.el index b23d12a..2c82eee 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -196,6 +196,49 @@ 'json-end-of-file +;;; Paths + +(defvar json--path-to-position nil + "When set to a position, `json-read' will return the path to +the JSON element at the specified position, instead of returning +the parsed JSON object.") + +(defvar json--path '() + "Used internally by `json-path-to-position' to keep track of +the path during recursive calls to `json-read'.") + +(defun json-path-to-position (position &optional string) + "Return the path to the JSON element at POSITION. + +When STRING is provided, return the path to the position in the +string, else to the position in the current buffer. + +The return value is a property list with the following +properties: + +:path -- A list of strings and numbers forming the path to + the JSON element at the given position. Strings + denote object names, while numbers denote array + indexes. + +:match-start -- Position where the matched JSON element begins. + +:match-end -- Position where the matched JSON element ends. + +This can for instance be useful to determine the path to a JSON +element in a deeply nested structure." + (save-excursion + (unless string + (goto-char (point-min))) + (let* ((json--path '()) + (json--path-to-position position) + (path (catch :json-path + (if string + (json-read-from-string string) + (json-read))))) + (when (plist-get path :path) + path)))) + ;;; Keywords (defvar json-keywords '("true" "false" "null") @@ -399,11 +442,21 @@ json-read-object (while (not (char-equal (json-peek) ?})) (json-skip-whitespace) (setq key (json-read-string)) + (when json--path-to-position + (push key json--path)) (json-skip-whitespace) (if (char-equal (json-peek) ?:) (json-advance) (signal 'json-object-format (list ":" (json-peek)))) - (setq value (json-read)) + (json-skip-whitespace) + (let ((start (point))) + (setq value (json-read)) + (when json--path-to-position + (when (< start json--path-to-position (+ (point) 1)) + (throw :json-path (list :path (nreverse json--path) + :match-start start + :match-end (point)))) + (pop json--path))) (setq elements (json-add-to-object elements key value)) (json-skip-whitespace) (unless (char-equal (json-peek) ?}) @@ -509,7 +562,17 @@ json-read-array ;; read values until "]" (let (elements) (while (not (char-equal (json-peek) ?\])) - (push (json-read) elements) + (json-skip-whitespace) + (when json--path-to-position + (push (length elements) json--path)) + (let ((start (point))) + (push (json-read) elements) + (when json--path-to-position + (when (< start json--path-to-position (+ (point) 1)) + (throw :json-path (list :path (nreverse json--path) + :match-start start + :match-end (point)))) + (pop json--path))) (json-skip-whitespace) (unless (char-equal (json-peek) ?\]) (if (char-equal (json-peek) ?,) diff --git a/test/automated/json-tests.el b/test/automated/json-tests.el index d1b7a2f..e0672dd 100644 --- a/test/automated/json-tests.el +++ b/test/automated/json-tests.el @@ -49,5 +49,19 @@ (should (equal (json-read-from-string=20 "\"\\nasd\\u0444\\u044b\\u0432fgh\\t\"") "\nasd=D1=84=D1=8B=D0=B2fgh\t"))) +(ert-deftest test-json-path-to-position-with-objects () + (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}") + (matched-path (json-path-to-position 32 json-string))) + (should (equal (plist-get matched-path :path) '("foo" "bar" "baz"))) + (should (equal (plist-get matched-path :match-start) 25)) + (should (equal (plist-get matched-path :match-end) 32)))) + +(ert-deftest test-json-path-to-position-with-arrays () + (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}") + (matched-path (json-path-to-position 20 json-string))) + (should (equal (plist-get matched-path :path) '("foo" 1 0))) + (should (equal (plist-get matched-path :match-start) 18)) + (should (equal (plist-get matched-path :match-end) 23)))) + (provide 'json-tests) ;;; json-tests.el ends here -- 2.6.1 = --=-b4IqqtSK8ay5FwlaWkkt Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Sometimes when working with a JSON structure, one needs to find the
pat= h to a particular element. That can be tiresome to do manually,
e= specially if the structure is deep.

The proposed p= atch extends json.el with the ability to retrieve the
path to a p= articular JSON element.

See the following video fo= r an example of how it can be used by an
interactive command, to = show the path to the JSON element at point:


The patch follows!
=
-- Simen


From f6ddd3= b797d6b0d92a1ffa0f5db59543ac7cdc11 Mon Sep 17 00:00:00 2001
From:= =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D <simenheg@gmail.com>
Date: Sun, 25 Oct 2015 14:44:59 +0100
Subject: [PATCH] A= dd support for retrieving paths to JSON elements

A= dd support for retrieving the path to a JSON element. This can for
instance be useful to retrieve paths in deeply nested JSON
stru= ctures.

* lisp/json.el (json-path-to-position): Ne= w function for retrieving the
path to a JSON object at a given po= sition.
(json--path-to-position, json--path): New variables, used= internally by
`json-path-to-position'.
(json-read-obje= ct, json-read-array): Respect `json--path-to-position'.

* test/automated/json-tests.el (test-json-path-to-position-with-objec= ts)
(test-json-path-to-position-with-arrays): New tests for
=
`json-path-to-position'.
---
 lisp/json.el = | 67 ++++++++++++++++++++++++++++++++++++++++++--
&= nbsp;test/automated/json-tests.el | 14 +++++++++
 2 files ch= anged, 79 insertions(+), 2 deletions(-)

diff --git= a/lisp/json.el b/lisp/json.el
index b23d12a..2c82eee 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -196,6 += 196,49 @@ 'json-end-of-file

 =0C
+;;; Paths
+
+(defvar json--path-to-positi= on nil
+ "When set to a position, `json-read' will return the pa= th to
+the JSON element at the specified position, instead of ret= urning
+the parsed JSON object.")
+
+(defvar = json--path '()
+ "Used internally by `json-path-to-position' to = keep track of
+the path during recursive calls to `json-read'.")<= /div>
+
+(defun json-path-to-position (position &optional= string)
+ "Return the path to the JSON element at POSITION.
+
+When STRING is provided, return the path to the positio= n in the
+string, else to the position in the current buffer.
+
+The return value is a property list with the following<= /div>
+properties:
+
+:path -- A list of str= ings and numbers forming the path to
+ the JSON el= ement at the given position. Strings
+ denote obj= ect names, while numbers denote array
+ indexes.
+
+:match-start -- Position where the matched JSON eleme= nt begins.
+
+:match-end -- Position where the matche= d JSON element ends.
+
+This can for instance be useful= to determine the path to a JSON
+element in a deeply nested stru= cture."
+ (save-excursion
+ (unless string
+ (goto-char (point-min)))
+ (let* ((json--path '())
+ (json--path-to-position position)
+ = (path (catch :json-path
+ (if string
+ (json-read-from-string string)
+ = (json-read)))))
+ (when (plist-get path :path)<= /div>
+ path))))
+
 ;;; Keywords
<= div>
 (defvar json-keywords '("true" "false" "null")
@@ -399,11 +442,21 @@ json-read-object
     = ;(while (not (char-equal (json-peek) ?}))
      &n= bsp;(json-skip-whitespace)
       (setq key (= json-read-string))
+ (when json--path-to-position
= + (push key json--path))
       (json-= skip-whitespace)
       (if (char-equal (json= -peek) ?:)
           (json-advance= )
         (signal 'json-object-format (= list ":" (json-peek))))
- (setq value (json-read))
+ (json-skip-whitespace)
+ (let ((start (point)))
+ (setq value (json-read))
+ (when json--path= -to-position
+ (when (< start json--path-to-position = (+ (point) 1))
+ (throw :json-path (list :path (nrever= se json--path)
+ :match-start = start
+ :match-end (point))))<= /div>
+ (pop json--path)))
      &nbs= p;(setq elements (json-add-to-object elements key value))
  =      (json-skip-whitespace)
      &= nbsp;(unless (char-equal (json-peek) ?})
@@ -509,7 +562,17 @@ jso= n-read-array
   ;; read values until "]"
&nbs= p;  (let (elements)
     (while (not (char-eq= ual (json-peek) ?\]))
- (push (json-read) elements)
+ (json-skip-whitespace)
+ (when json--path-to-positi= on
+ (push (length elements) json--path))
+ = (let ((start (point)))
+ (push (json-read) elements)
+ (when json--path-to-position
+ (when (<= ; start json--path-to-position (+ (point) 1))
+ (throw= :json-path (list :path (nreverse json--path)
+ = :match-start start
+ = :match-end (point))))
+ (pop json--path)))
       (json-skip-whitespace)
  &n= bsp;    (unless (char-equal (json-peek) ?\])
  &nb= sp;      (if (char-equal (json-peek) ?,)
diff --gi= t a/test/automated/json-tests.el b/test/automated/json-tests.el
i= ndex d1b7a2f..e0672dd 100644
--- a/test/automated/json-tests.el
+++ b/test/automated/json-tests.el
@@ -49,5 +49,19 @@
   (should (equal (json-read-from-string "\"\\nasd\\u0444= \\u044b\\u0432fgh\\t\"")
           = ;       "\nasd=D1=84=D1=8B=D0=B2fgh\t")))

+(ert-deftest test-json-path-to-position-with-objects ()
+= (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}")
+ (matched-path (json-path-to-position 32 json-string)))
+ (should (equal (plist-get matched-path :path) '("foo" "bar" "baz"))= )
+ (should (equal (plist-get matched-path :match-start) 25))<= /div>
+ (should (equal (plist-get matched-path :match-end) 32))))
+
+(ert-deftest test-json-path-to-position-with-arrays ()=
+ (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}")
<= div>+ (matched-path (json-path-to-position 20 json-string)))
<= div>+ (should (equal (plist-get matched-path :path) '("foo" 1 0)))
=
+ (should (equal (plist-get matched-path :match-start) 18))
+ (should (equal (plist-get matched-path :match-end) 23))))
+
 (provide 'json-tests)
 ;;; json-tests.el = ends here
--
2.6.1

= --=-b4IqqtSK8ay5FwlaWkkt-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 31 Oct 2015 14:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Simen =?UTF-8?Q?Heggest=C3=B8yl?= , 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.144630144122463 (code B ref 21798); Sat, 31 Oct 2015 14:24:02 +0000 Received: (at 21798) by debbugs.gnu.org; 31 Oct 2015 14:24:01 +0000 Received: from localhost ([127.0.0.1]:47264 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZsX4a-0005qE-Gj for submit@debbugs.gnu.org; Sat, 31 Oct 2015 10:24:00 -0400 Received: from mail-wm0-f45.google.com ([74.125.82.45]:36622) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZsX4F-0005pl-Ae for 21798@debbugs.gnu.org; Sat, 31 Oct 2015 10:23:58 -0400 Received: by wmec75 with SMTP id c75so30657974wme.1 for <21798@debbugs.gnu.org>; Sat, 31 Oct 2015 07:23:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=AzojM6k8aImsMcU2/3oe1kKd6bVgZUdE8JBw66IIAHk=; b=VpW4FLw5IijNJVRhrikY966ag5cM8zqGfh7w2hUpCmcx42sHj9NkhVHJ+3NjKyO+XG f9JyAk+AskgcDgSpVt7T1Q6m7GPqNN9HxjfoILDRcqbX6ucOqutsqhqcIFZQroOxEj2P 4hf4rELFYDvvPEslLpq5udkD3itQtU0HGRUUaNPKT9S3hIjGRVWS9Jlj+oVfO5zuPV9F P5hzXrVKzgjwQos9aMCi3dnh8q3bIXzlX0Qg5Z5MXwMrp+5bEG26aM0zUdIiMaTsU6Kp fgmssU5yvRE/QFLrocRwS2SaMRlwP6UUFMNTL5DC6Xp+ej8wEFUDAmn+y2JAtHjOkh+s 4M2A== X-Received: by 10.28.173.67 with SMTP id w64mr3891376wme.71.1446301418550; Sat, 31 Oct 2015 07:23:38 -0700 (PDT) Received: from [10.9.0.103] (nat.webazilla.com. [78.140.128.228]) by smtp.googlemail.com with ESMTPSA id r12sm8128165wmd.17.2015.10.31.07.23.37 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 31 Oct 2015 07:23:37 -0700 (PDT) References: <1446281162.2607.0@smtp.gmail.com> From: Dmitry Gutov Message-ID: <5634CEE7.3070200@yandex.ru> Date: Sat, 31 Oct 2015 16:23:35 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Thunderbird/42.0 MIME-Version: 1.0 In-Reply-To: <1446281162.2607.0@smtp.gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) On 10/31/2015 10:46 AM, Simen Heggestøyl wrote: > The proposed patch extends json.el with the ability to retrieve the > path to a particular JSON element. > > See the following video for an example of how it can be used by an > interactive command, to show the path to the JSON element at point: > > http://folk.uio.no/simenheg/json-mode.webm Hi Simen, The video looks great, but the inline patch lacks indentation, and doesn't apply (dunno if the former is the cause of the latter). Please resend it as an attachment. Without trying it, my main concern would be any performance regression to json-read (it's not particularly fast already). Have you done any benchmarking? Splitting the new changes into new functions might be more optimal. From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 01 Nov 2015 19:53:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Dmitry Gutov Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.144640757817179 (code B ref 21798); Sun, 01 Nov 2015 19:53:02 +0000 Received: (at 21798) by debbugs.gnu.org; 1 Nov 2015 19:52:58 +0000 Received: from localhost ([127.0.0.1]:48113 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZsygT-0004T0-7k for submit@debbugs.gnu.org; Sun, 01 Nov 2015 14:52:58 -0500 Received: from mail-lb0-f178.google.com ([209.85.217.178]:34951) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zsyg8-0004SX-OG for 21798@debbugs.gnu.org; Sun, 01 Nov 2015 14:52:56 -0500 Received: by lbbes7 with SMTP id es7so75700275lbb.2 for <21798@debbugs.gnu.org>; Sun, 01 Nov 2015 11:52:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:cc:message-id:in-reply-to:references :mime-version:content-type; bh=20hO5K/pMiRd5/n8PsiPKdrvcMRV3fMrznR4uWvZXAs=; b=v6MriaF9jnQhIumvkI8qxHb5avyTz/tTZPpHcJlYF2fZc4o9GbuTi6V51YE0mom4Tb NUZcZDf6vPirAQJYzh79/W43U3tskZnhKbajFnmeSlvTLDkG5ItciFaPNyKpYkBQ0bo0 OjMQCuFm/GMP9GQN042b8JnVa4f6SihIM5mRReDkQBYQL4EJTjt3D0SGEM+depL/nuYC Aa56ukecCisJ8sSxPsaWPCQO31iPNEsg5B5qGAkRtM9Mh6vPqVHE5GOzvwgKnCHO/rkL ulTNMxnpXUntcCqtsbCCD0vxf0gsZMLJC3JY6xvRWJ8FvL7kE2NbfdRO/KbwyFOwroY5 9S4A== X-Received: by 10.112.198.106 with SMTP id jb10mr8232761lbc.111.1446407555641; Sun, 01 Nov 2015 11:52:35 -0800 (PST) Received: from [192.168.100.7] (cm-84.210.143.4.getinternet.no. [84.210.143.4]) by smtp.gmail.com with ESMTPSA id jj4sm3287759lbc.14.2015.11.01.11.52.34 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 01 Nov 2015 11:52:34 -0800 (PST) Date: Sun, 01 Nov 2015 20:52:33 +0100 From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Message-Id: <1446407553.4906.0@smtp.gmail.com> In-Reply-To: <5634CEE7.3070200@yandex.ru> References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-8EBW3L51X0hu3V/8ITCT" X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --=-8EBW3L51X0hu3V/8ITCT Content-Type: multipart/alternative; boundary="=-XrCv70Zw4YgnAf4t75V5" --=-XrCv70Zw4YgnAf4t75V5 Content-Type: text/plain; charset=utf-8; format=flowed Hi Dmitry, thanks for the feedback! On Sat, Oct 31, 2015 at 3:23 PM, Dmitry Gutov wrote: > The video looks great, but the inline patch lacks indentation, and > doesn't apply (dunno if the former is the cause of the latter). > Please resend it as an attachment. Ah, yes, it appear that the whitespace got lost in the email for some reason. I'll try attaching it to this email. To test it, I've been using the following interactive function: (defun json-mode-show-path () "Show the path to the JSON value under point." (interactive) (let ((path (json-path-to-position (point)))) (if path (let ((formatted-path (json-mode--format-path (plist-get path :path)))) (pulse-momentary-highlight-region (plist-get path :match-start) (plist-get path :match-end)) (message formatted-path) (kill-new formatted-path)) (message "Not a JSON value")))) (defun json-mode--format-path (path) "Return PATH formatted as a JSON data selector. PATH should be a list of keys, which can be either strings or integers." (mapconcat (lambda (key) (format "[%S]" key)) path "")) It's also included it in json-mode.el: http://folk.uio.no/simenheg/json-mode.el. > Without trying it, my main concern would be any performance > regression to json-read (it's not particularly fast already). Have > you done any benchmarking? I agree that would be bad. I'll try to produce some benchmarks when I've got some free time on my hands! -- Simen --=-XrCv70Zw4YgnAf4t75V5 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Dmitry, thanks for the feedback!

On Sat, Oct 31, 2015 at 3:23 PM= , Dmitry Gutov <dgutov@yandex.ru> wrote:
The video looks = great, but the inline patch lacks indentation, and doesn't apply (dunno if = the former is the cause of the latter). Please resend it as an attachment.<= /div>

Ah, yes, it appear that the whit= espace got lost in the email for some
reason. I'll try attaching = it to this email.

To test it, I've been using the = following interactive function:

  (defun json= -mode-show-path ()
    "Show the path to the JSON value= under point."
    (interactive)
   = ; (let ((path (json-path-to-position (point))))
    &nb= sp; (if path
          (let ((formatted-= path
                &nbs= p;(json-mode--format-path (plist-get path :path))))
   =         (pulse-momentary-highlight-region
&n= bsp;            (plist-get path :match-start)=
             (plist-get path = :match-end))
            (message f= ormatted-path)
            (kill-ne= w formatted-path))
        (message "Not a JS= ON value"))))
  
  (defun json-mode--for= mat-path (path)
    "Return PATH formatted as a JSON da= ta selector.
  PATH should be a list of keys, which can be e= ither strings or
  integers."
    (mapco= ncat (lambda (key) (format "[%S]" key)) path ""))

= It's also included it in json-mode.el:

Without trying it, my main concern would be any perfo= rmance regression to json-read (it's not particularly fast already). Have y= ou done any benchmarking?

I agree that would be = bad. I'll try to produce some benchmarks when
I've got some free = time on my hands!

-- Simen
= --=-XrCv70Zw4YgnAf4t75V5-- --=-8EBW3L51X0hu3V/8ITCT Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-support-for-retrieving-paths-to-JSON-elements.patch Content-Transfer-Encoding: quoted-printable >From f6ddd3b797d6b0d92a1ffa0f5db59543ac7cdc11 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D Date: Sun, 25 Oct 2015 14:44:59 +0100 Subject: [PATCH] Add support for retrieving paths to JSON elements Add support for retrieving the path to a JSON element. This can for instance be useful to retrieve paths in deeply nested JSON structures. * lisp/json.el (json-path-to-position): New function for retrieving the path to a JSON object at a given position. (json--path-to-position, json--path): New variables, used internally by `json-path-to-position'. (json-read-object, json-read-array): Respect `json--path-to-position'. * test/automated/json-tests.el (test-json-path-to-position-with-objects) (test-json-path-to-position-with-arrays): New tests for `json-path-to-position'. --- lisp/json.el | 67 ++++++++++++++++++++++++++++++++++++++++= ++-- test/automated/json-tests.el | 14 +++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/lisp/json.el b/lisp/json.el index b23d12a..2c82eee 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -196,6 +196,49 @@ 'json-end-of-file =20 =0C =20 +;;; Paths + +(defvar json--path-to-position nil + "When set to a position, `json-read' will return the path to +the JSON element at the specified position, instead of returning +the parsed JSON object.") + +(defvar json--path '() + "Used internally by `json-path-to-position' to keep track of +the path during recursive calls to `json-read'.") + +(defun json-path-to-position (position &optional string) + "Return the path to the JSON element at POSITION. + +When STRING is provided, return the path to the position in the +string, else to the position in the current buffer. + +The return value is a property list with the following +properties: + +:path -- A list of strings and numbers forming the path to + the JSON element at the given position. Strings + denote object names, while numbers denote array + indexes. + +:match-start -- Position where the matched JSON element begins. + +:match-end -- Position where the matched JSON element ends. + +This can for instance be useful to determine the path to a JSON +element in a deeply nested structure." + (save-excursion + (unless string + (goto-char (point-min))) + (let* ((json--path '()) + (json--path-to-position position) + (path (catch :json-path + (if string + (json-read-from-string string) + (json-read))))) + (when (plist-get path :path) + path)))) + ;;; Keywords =20 (defvar json-keywords '("true" "false" "null") @@ -399,11 +442,21 @@ json-read-object (while (not (char-equal (json-peek) ?})) (json-skip-whitespace) (setq key (json-read-string)) + (when json--path-to-position + (push key json--path)) (json-skip-whitespace) (if (char-equal (json-peek) ?:) (json-advance) (signal 'json-object-format (list ":" (json-peek)))) - (setq value (json-read)) + (json-skip-whitespace) + (let ((start (point))) + (setq value (json-read)) + (when json--path-to-position + (when (< start json--path-to-position (+ (point) 1)) + (throw :json-path (list :path (nreverse json--path) + :match-start start + :match-end (point)))) + (pop json--path))) (setq elements (json-add-to-object elements key value)) (json-skip-whitespace) (unless (char-equal (json-peek) ?}) @@ -509,7 +562,17 @@ json-read-array ;; read values until "]" (let (elements) (while (not (char-equal (json-peek) ?\])) - (push (json-read) elements) + (json-skip-whitespace) + (when json--path-to-position + (push (length elements) json--path)) + (let ((start (point))) + (push (json-read) elements) + (when json--path-to-position + (when (< start json--path-to-position (+ (point) 1)) + (throw :json-path (list :path (nreverse json--path) + :match-start start + :match-end (point)))) + (pop json--path))) (json-skip-whitespace) (unless (char-equal (json-peek) ?\]) (if (char-equal (json-peek) ?,) diff --git a/test/automated/json-tests.el b/test/automated/json-tests.el index d1b7a2f..e0672dd 100644 --- a/test/automated/json-tests.el +++ b/test/automated/json-tests.el @@ -49,5 +49,19 @@ (should (equal (json-read-from-string "\"\\nasd\\u0444\\u044b\\u0432fgh\= \t\"") "\nasd=D1=84=D1=8B=D0=B2fgh\t"))) =20 +(ert-deftest test-json-path-to-position-with-objects () + (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}") + (matched-path (json-path-to-position 32 json-string))) + (should (equal (plist-get matched-path :path) '("foo" "bar" "baz"))) + (should (equal (plist-get matched-path :match-start) 25)) + (should (equal (plist-get matched-path :match-end) 32)))) + +(ert-deftest test-json-path-to-position-with-arrays () + (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}") + (matched-path (json-path-to-position 20 json-string))) + (should (equal (plist-get matched-path :path) '("foo" 1 0))) + (should (equal (plist-get matched-path :match-start) 18)) + (should (equal (plist-get matched-path :match-end) 23)))) + (provide 'json-tests) ;;; json-tests.el ends here --=20 2.6.1 = --=-8EBW3L51X0hu3V/8ITCT-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 01 Nov 2015 23:28:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Dmitry Gutov Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.14464204724884 (code B ref 21798); Sun, 01 Nov 2015 23:28:02 +0000 Received: (at 21798) by debbugs.gnu.org; 1 Nov 2015 23:27:52 +0000 Received: from localhost ([127.0.0.1]:48210 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zt22S-0001Gh-24 for submit@debbugs.gnu.org; Sun, 01 Nov 2015 18:27:52 -0500 Received: from mail-lb0-f170.google.com ([209.85.217.170]:33937) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zt22P-0001GY-Dc for 21798@debbugs.gnu.org; Sun, 01 Nov 2015 18:27:50 -0500 Received: by lbbwb3 with SMTP id wb3so77298883lbb.1 for <21798@debbugs.gnu.org>; Sun, 01 Nov 2015 15:27:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:cc:message-id:in-reply-to:references :mime-version:content-type; bh=kkzuhQCHtxC2sIw1jK8KlkLzEhXU1esQDWNaVWEsIm8=; b=rI3bHbMbkE6ogJaUf+h3b7dmWj84oAqCthXPsf8eaD4t93G8B1y7OXQBK+xarllzYw l+OHHNS0eenJflJTdlHS14ah9M3tLBC1+6UdpBuh54CTYXq8j4EofHonB6OqIdTBxxI5 /H+tTRsjgAL7cftEwzCro12io7f6yAw/iO7LPHL2XI/J1Nezh/0JWrnOSrGXeL2I9qbH IKDXlERzOcKVdWaAtVQejA9Adp6+vbk8qHW5huUImqo7fnUQtgvE348ZIVo84A6ZYoZZ oWuxlnfmyHWMLrn1fA6s3nv4dOinF7r1tVkfxJBKcwidm7+7t9CQDJ+VuXVPY5x/GvSA C/7w== X-Received: by 10.112.234.163 with SMTP id uf3mr8654915lbc.15.1446420468493; Sun, 01 Nov 2015 15:27:48 -0800 (PST) Received: from [192.168.100.7] (cm-84.210.143.4.getinternet.no. [84.210.143.4]) by smtp.gmail.com with ESMTPSA id yp7sm3401335lbb.47.2015.11.01.15.27.46 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 01 Nov 2015 15:27:47 -0800 (PST) Date: Mon, 02 Nov 2015 00:27:46 +0100 From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Message-Id: <1446420466.13180.0@smtp.gmail.com> In-Reply-To: <1446407553.4906.0@smtp.gmail.com> References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-uGcAHqT79X22IzxXbJYF" X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --=-uGcAHqT79X22IzxXbJYF Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Hello again, Dmitry. I managed to produce a benchmark with the following JSON file (560K, ~10,000 lines): http://folk.uio.no/simenheg/huge.json. I read it into `huge-json', and ran the following before the patch: (benchmark-run 100 (json-read-from-string huge-json)) =E2=87=92 (19.421527195 938 7.448190372000017) And after the patch: (benchmark-run 100 (json-read-from-string huge-json)) =E2=87=92 (19.321667537 997 7.218977015999971) -- Simen On Sun, Nov 1, 2015 at 8:52 PM, Simen Heggest=C3=B8yl =20 wrote: > Hi Dmitry, thanks for the feedback! >=20 > On Sat, Oct 31, 2015 at 3:23 PM, Dmitry Gutov =20 > wrote: >> The video looks great, but the inline patch lacks indentation, and=20 >> doesn't apply (dunno if the former is the cause of the latter).=20 >> Please resend it as an attachment. >=20 > Ah, yes, it appear that the whitespace got lost in the email for some > reason. I'll try attaching it to this email. >=20 > To test it, I've been using the following interactive function: >=20 > (defun json-mode-show-path () > "Show the path to the JSON value under point." > (interactive) > (let ((path (json-path-to-position (point)))) > (if path > (let ((formatted-path > (json-mode--format-path (plist-get path :path)))) > (pulse-momentary-highlight-region > (plist-get path :match-start) > (plist-get path :match-end)) > (message formatted-path) > (kill-new formatted-path)) > (message "Not a JSON value")))) >=20 > (defun json-mode--format-path (path) > "Return PATH formatted as a JSON data selector. > PATH should be a list of keys, which can be either strings or > integers." > (mapconcat (lambda (key) (format "[%S]" key)) path "")) >=20 > It's also included it in json-mode.el: > http://folk.uio.no/simenheg/json-mode.el. >=20 >> Without trying it, my main concern would be any performance=20 >> regression to json-read (it's not particularly fast already). Have=20 >> you done any benchmarking? >=20 > I agree that would be bad. I'll try to produce some benchmarks when > I've got some free time on my hands! >=20 > -- Simen = --=-uGcAHqT79X22IzxXbJYF Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
Hello again, Dmitry.

I managed to produce a b= enchmark with the following JSON file (560K,

I read it into `huge-json', and ran = the following before the patch:

(benchmark-run 100= (json-read-from-string huge-json))
     =E2=87=92= (19.421527195 938 7.448190372000017)

And after th= e patch:

(benchmark-run 100 (json-read-from-string= huge-json))
     =E2=87=92 (19.321667537 997 7.21= 8977015999971)

-- Simen

On Sun, Nov 1, 20= 15 at 8:52 PM, Simen Heggest=C3=B8yl <simenheg@gmail.com> wrote:
Hi Dmitry, thanks for the feedback!

On Sat, Oct 31, 2015 at 3:23 PM= , Dmitry Gutov <dgutov@yandex.ru> wrote:
The video looks = great, but the inline patch lacks indentation, and doesn't apply (dunno if = the former is the cause of the latter). Please resend it as an attachment.<= /div>

Ah, yes, it appear that the whit= espace got lost in the email for some
reason. I'll try attaching = it to this email.

To test it, I've been using the = following interactive function:

  (defun json= -mode-show-path ()
    "Show the path to the JSON value= under point."
    (interactive)
   = ; (let ((path (json-path-to-position (point))))
    &nb= sp; (if path
          (let ((formatted-= path
                &nbs= p;(json-mode--format-path (plist-get path :path))))
   =         (pulse-momentary-highlight-region
&n= bsp;            (plist-get path :match-start)=
             (plist-get path = :match-end))
            (message f= ormatted-path)
            (kill-ne= w formatted-path))
        (message "Not a JS= ON value"))))
  
  (defun json-mode--for= mat-path (path)
    "Return PATH formatted as a JSON da= ta selector.
  PATH should be a list of keys, which can be e= ither strings or
  integers."
    (mapco= ncat (lambda (key) (format "[%S]" key)) path ""))

= It's also included it in json-mode.el:

Without trying it, my main concern would be any perfo= rmance regression to json-read (it's not particularly fast already). Have y= ou done any benchmarking?

I agree that would be = bad. I'll try to produce some benchmarks when
I've got some free = time on my hands!

-- Simen
= --=-uGcAHqT79X22IzxXbJYF-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 03 Nov 2015 02:02:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.144651606313248 (code B ref 21798); Tue, 03 Nov 2015 02:02:01 +0000 Received: (at 21798) by debbugs.gnu.org; 3 Nov 2015 02:01:03 +0000 Received: from localhost ([127.0.0.1]:50208 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtQuE-0003Rb-QS for submit@debbugs.gnu.org; Mon, 02 Nov 2015 21:01:03 -0500 Received: from mail-wm0-f43.google.com ([74.125.82.43]:33960) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZtQuB-0003R3-Tu for 21798@debbugs.gnu.org; Mon, 02 Nov 2015 21:01:00 -0500 Received: by wmff134 with SMTP id f134so73218754wmf.1 for <21798@debbugs.gnu.org>; Mon, 02 Nov 2015 18:00:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=qsHQ5O/4z5czDL2Ca7VSc4TQuVoLxWpvIGt/hWNPqgk=; b=U2CICnoX7352FzxrTBiw9vUnDE1Ic+RPqFPGW2pAB3xd+QyYuS0dBM7gQ7/TCGkTYq eoSkKD2gJ5eBLaU1u8lPw3vHvB6eh5lSuQ7rnm6P+UWoaCXvJz6q7KU/AM0sV6p1yD5i SCSM/DFDTf/Rw+Tw/wold9gWpv+BMH5O7yY97GY51EKRN4h2cjGgy4aH1TK2qzNgAVkF as/PJUz9olQ4KwJzu3s6J/qeMiQuiTrAZUGf5o2AUGFBDtrjTYs7jXJZpw3Y2xGK4GpM ZSlKF9lqB/XNFUzRToquNCbPokVamFMEoasg+EMqtiJTf/eTblwWPoe0yDom1mK18SJA vYmw== X-Received: by 10.28.215.205 with SMTP id o196mr17399795wmg.95.1446516058937; Mon, 02 Nov 2015 18:00:58 -0800 (PST) Received: from [192.168.1.2] ([185.105.175.24]) by smtp.googlemail.com with ESMTPSA id j4sm21028275wmg.18.2015.11.02.18.00.57 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 02 Nov 2015 18:00:57 -0800 (PST) References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> From: Dmitry Gutov Message-ID: <56381558.7050607@yandex.ru> Date: Tue, 3 Nov 2015 04:00:56 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Thunderbird/42.0 MIME-Version: 1.0 In-Reply-To: <1446420466.13180.0@smtp.gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) Hello Simen, On 11/02/2015 01:27 AM, Simen Heggestøyl wrote: > I managed to produce a benchmark with the following JSON file (560K, > ~10,000 lines): http://folk.uio.no/simenheg/huge.json. > > I read it into `huge-json', and ran the following before the patch: ... Thanks. In my testing, too, the difference seems to be statistically insignificant. That's good. I have to say, I'm still not very comfortable with mixing it sort of alien logic inside json-read-object and json-read-array (would anyone else like to chime in with their opinion?). I do believe we want this functionality, though. One option to tighten the implementation is to extract common pieces from json-read-object and json-read-array, and implement two new functions using them, but the while-loops used there will make avoiding just copying code somewhat difficult. Here's an idea: both json-read-object-1 and json-read-array-2 will advise json-read to add the new logic around calls to it (there will have to be some guard in the advice, so that recursive calls are run unmodified). And json-path-to-position will locally modify json-readtable to use json-read-object-1 and json-read-array-2. That's just a suggestion, though. From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 06 Nov 2015 16:32:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Dmitry Gutov Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.14468275143676 (code B ref 21798); Fri, 06 Nov 2015 16:32:02 +0000 Received: (at 21798) by debbugs.gnu.org; 6 Nov 2015 16:31:54 +0000 Received: from localhost ([127.0.0.1]:56022 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zujvd-0000xD-O0 for submit@debbugs.gnu.org; Fri, 06 Nov 2015 11:31:54 -0500 Received: from mail-wi0-f173.google.com ([209.85.212.173]:36562) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZujvH-0000wR-6j for 21798@debbugs.gnu.org; Fri, 06 Nov 2015 11:31:52 -0500 Received: by wimw2 with SMTP id w2so33722612wim.1 for <21798@debbugs.gnu.org>; Fri, 06 Nov 2015 08:31:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:cc:message-id:in-reply-to:references :mime-version:content-type; bh=tTVgq13mGrTqX0MaRghSCJ84+BGhWakK92h0EY4yxL0=; b=u1Nl5Ky/ZkUULyDnkaUS0ccTfBgI5OKlxQlXC/mqS6s/caLfmOiH946U2/Jyf+jSg8 Ehg5XGH5VtPrWZZHRVhhragopAQN6FR7az2gBAP7bBCZP6R3RmaA2Pqm/rmnlTBri+fJ /boZOwsJVKpwXsz9otcoWxmLDRviFPO/FTSYujpBlcMAyilCBDoJDR7S6ifATZlAUJ6B G35nDRmnHC47wbfYv0xJgkLFfd3sUgdFGA5dgabVp7MLhRt8s3xza9+PZrypXpGjTB0v yC9e54FMPiMJ3hHzT74SE8lRRTyp7M9BolNxs53KE9uqHh4RtRbf6pQJrXN6gKrjj+n/ YlHw== X-Received: by 10.195.18.67 with SMTP id gk3mr15206433wjd.35.1446827490515; Fri, 06 Nov 2015 08:31:30 -0800 (PST) Received: from [192.168.101.25] ([77.40.215.202]) by smtp.gmail.com with ESMTPSA id 186sm3796700wmp.10.2015.11.06.08.31.29 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 06 Nov 2015 08:31:29 -0800 (PST) Date: Fri, 06 Nov 2015 17:31:28 +0100 From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Message-Id: <1446827488.11140.2@smtp.gmail.com> In-Reply-To: <56381558.7050607@yandex.ru> References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-CsgJEp8htxb4vhJxa7sF" X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --=-CsgJEp8htxb4vhJxa7sF Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Hello Dmitry, thanks for the feedback. On Tue, Nov 3, 2015 at 3:00 AM, Dmitry Gutov wrote: > I have to say, I'm still not very comfortable with mixing it sort of=20 > alien logic inside json-read-object and json-read-array (would anyone=20 > else like to chime in with their opinion?). I understand your uneasiness, I feel the same way after you pointed it out. > Here's an idea: both json-read-object-1 and json-read-array-2 will=20 > advise json-read to add the new logic around calls to it (there will=20 > have to be some guard in the advice, so that recursive calls are run=20 > unmodified). I'm reluctant to use advises for it, not based on my own experience, but based on advice from the Elisp manual: > [...] advice should be reserved for the cases where you cannot modify > a function=E2=80=99s behavior in any other way. [...] In particular,=20 > Emacs=E2=80=99s > own source files should not put advice on functions in Emacs. (There > are currently a few exceptions to this convention, but we aim to > correct them.) Here we do have a chance to modify the functions' behavior. How about a sort of compromise between our approaches: provide 'json-read-object' and 'json-read-array' with pre- and post-read callback functions, that are only called when they're set. That would make it possible to leverage the power of 'json-read-object' and 'json-read-array' by binding the callback functions, without mixing alien logic into them. That would also make it a lot cleaner when adding other extensions to them in the future, compared to my original suggestion. If that sounds good to you, I'll cook up a new patch! -- Simen = --=-CsgJEp8htxb4vhJxa7sF Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Dmitry, thanks for the feedback.

On Tue, Nov 3, 2015 at 3:00 A= M, Dmitry Gutov <dgutov@yandex.ru> wrote:
I have to say, = I'm still not very comfortable with mixing it sort of alien logic inside js= on-read-object and json-read-array (would anyone else like to chime in with= their opinion?).

I understand your uneasi= ness, I feel the same way after you pointed it
out.

Her= e's an idea: both json-read-object-1 and json-read-array-2 will advise json= -read to add the new logic around calls to it (there will have to be some g= uard in the advice, so that recursive calls are run unmodified).

I'm reluctant to use advises for it, not based on my= own experience, but
based on advice from the Elisp manual:
=

[...] advice should be reserv= ed for the cases where you cannot modify
a function=E2=80=99s beh= avior in any other way. [...] In particular, Emacs=E2=80=99s
own = source files should not put advice on functions in Emacs. (There
= are currently a few exceptions to this convention, but we aim to
= correct them.)

Here we do have a chan= ce to modify the functions' behavior.

How about a = sort of compromise between our approaches: provide
'json-read-obj= ect' and 'json-read-array' with pre- and post-read
callback funct= ions, that are only called when they're set. That would
make it p= ossible to leverage the power of 'json-read-object' and
'json-rea= d-array' by binding the callback functions, without mixing
alien = logic into them.

That would also make it a lot cle= aner when adding other extensions to
them in the future, compared= to my original suggestion.

If that sounds good to= you, I'll cook up a new patch!

-- Simen
= --=-CsgJEp8htxb4vhJxa7sF-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 06 Nov 2015 17:16:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.14468301537986 (code B ref 21798); Fri, 06 Nov 2015 17:16:02 +0000 Received: (at 21798) by debbugs.gnu.org; 6 Nov 2015 17:15:53 +0000 Received: from localhost ([127.0.0.1]:56060 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZukcC-00024j-F1 for submit@debbugs.gnu.org; Fri, 06 Nov 2015 12:15:52 -0500 Received: from mail-wm0-f54.google.com ([74.125.82.54]:38751) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZukcA-00024b-RB for 21798@debbugs.gnu.org; Fri, 06 Nov 2015 12:15:51 -0500 Received: by wmec201 with SMTP id c201so23251447wme.1 for <21798@debbugs.gnu.org>; Fri, 06 Nov 2015 09:15:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=ukSBR79eVTaOGfSso/NWAey1QciwUBd6sxWo9M7MGrk=; b=izdfsCNS6yKo/49J8leD4YKo2VROAu+JuA9mzY/LKO0PkQ5mvjkWiAb08TNlCaUA7n xJg3pAdXHxQRMZJiNVRbX7yfHaRK2Lh3YFtU+bb2YNkUN0kvWgVuIIrxt8jUl6ds+K1j RzxpibU2HdA8ChqMQHEq6Ftx66n7ROOmi+JsEt+aFFscI/fxfE+hheqPOl4ogfnRq6sv q5izC0t5mJPg8e79QP3orOWOZl/SAmqImiZGG/QedTPngCzmLPo5J7nQUxOH8+hsp2xX a8Q9KIVtl4E6kcOU60ai0N7RXTk+jSPNPOvMj1wJyponBgbIArWQu6XCPuH6+UpVkax0 8v6w== X-Received: by 10.28.146.146 with SMTP id u140mr11089375wmd.85.1446830150113; Fri, 06 Nov 2015 09:15:50 -0800 (PST) Received: from [10.9.0.103] (nat.webazilla.com. [78.140.128.228]) by smtp.googlemail.com with ESMTPSA id e79sm3950943wmd.16.2015.11.06.09.15.48 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Nov 2015 09:15:48 -0800 (PST) References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> From: Dmitry Gutov Message-ID: <563CE043.9060404@yandex.ru> Date: Fri, 6 Nov 2015 19:15:47 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Thunderbird/42.0 MIME-Version: 1.0 In-Reply-To: <1446827488.11140.2@smtp.gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) On 11/06/2015 06:31 PM, Simen Heggestøyl wrote: > I'm reluctant to use advises for it, not based on my own experience, but > based on advice from the Elisp manual: > >> [...] advice should be reserved for the cases where you cannot modify >> a function’s behavior in any other way. [...] In particular, Emacs’s >> own source files should not put advice on functions in Emacs. (There >> are currently a few exceptions to this convention, but we aim to >> correct them.) > > Here we do have a chance to modify the functions' behavior. I happen to think that an advice with a short lifetime is okay, but yes, these are the guidelines. > How about a sort of compromise between our approaches: provide > 'json-read-object' and 'json-read-array' with pre- and post-read > callback functions, that are only called when they're set. That would > make it possible to leverage the power of 'json-read-object' and > 'json-read-array' by binding the callback functions, without mixing > alien logic into them. That sounds fine to me in terms of design, but it might add some performance overhead. So some testing is needed. > That would also make it a lot cleaner when adding other extensions to > them in the future, compared to my original suggestion. > > If that sounds good to you, I'll cook up a new patch! Please go ahead. From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Richard Stallman Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 07 Nov 2015 13:24:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Dmitry Gutov Cc: 21798@debbugs.gnu.org, simenheg@gmail.com Reply-To: rms@gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.14469026185140 (code B ref 21798); Sat, 07 Nov 2015 13:24:02 +0000 Received: (at 21798) by debbugs.gnu.org; 7 Nov 2015 13:23:38 +0000 Received: from localhost ([127.0.0.1]:56567 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv3T0-0001Kq-3p for submit@debbugs.gnu.org; Sat, 07 Nov 2015 08:23:38 -0500 Received: from eggs.gnu.org ([208.118.235.92]:41047) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv3Sy-0001Ki-2s for 21798@debbugs.gnu.org; Sat, 07 Nov 2015 08:23:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zv3Sx-0000n3-54 for 21798@debbugs.gnu.org; Sat, 07 Nov 2015 08:23:35 -0500 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,T_RP_MATCHES_RCVD autolearn=disabled version=3.3.2 Received: from fencepost.gnu.org ([2001:4830:134:3::e]:41603) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zv3Ss-0000k6-Dv; Sat, 07 Nov 2015 08:23:30 -0500 Received: from rms by fencepost.gnu.org with local (Exim 4.82) (envelope-from ) id 1Zv3Sr-00082I-Lo; Sat, 07 Nov 2015 08:23:29 -0500 Content-Type: text/plain; charset=Utf-8 From: Richard Stallman In-reply-to: <563CE043.9060404@yandex.ru> (message from Dmitry Gutov on Fri, 6 Nov 2015 19:15:47 +0200) References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> Message-Id: Date: Sat, 07 Nov 2015 08:23:29 -0500 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::e X-Spam-Score: -5.0 (-----) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -5.0 (-----) [[[ To any NSA and FBI agents reading my email: please consider ]]] [[[ whether defending the US Constitution against all enemies, ]]] [[[ foreign or domestic, requires you to follow Snowden's example. ]]] > I happen to think that an advice with a short lifetime is okay, but yes, > these are the guidelines. The reason that Emacs sources should not use advice is that advice is bad for debugging. If you look at function foo's source code, it won't tell you that advice is causing the function to do something not in that source. This problem occurs no matter how long the advice is on function foo. The right thing to do, instead of using advice on foo, is to change foo to call a hook, and put things in that hook. This is better because the source code of foo will include code to run the hook. When you see that, you'll know you should check what is in the hook. -- Dr Richard Stallman President, Free Software Foundation (gnu.org, fsf.org) Internet Hall-of-Famer (internethalloffame.org) Skype: No way! See stallman.org/skype.html. From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 07 Nov 2015 13:44:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: rms@gnu.org Cc: 21798@debbugs.gnu.org, simenheg@gmail.com Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.14469037996945 (code B ref 21798); Sat, 07 Nov 2015 13:44:01 +0000 Received: (at 21798) by debbugs.gnu.org; 7 Nov 2015 13:43:19 +0000 Received: from localhost ([127.0.0.1]:56579 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv3m2-0001nv-GD for submit@debbugs.gnu.org; Sat, 07 Nov 2015 08:43:18 -0500 Received: from mail-wi0-f179.google.com ([209.85.212.179]:34761) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv3m0-0001nm-0t for 21798@debbugs.gnu.org; Sat, 07 Nov 2015 08:43:16 -0500 Received: by wikq8 with SMTP id q8so45272396wik.1 for <21798@debbugs.gnu.org>; Sat, 07 Nov 2015 05:43:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=mQB/LYBwwSUfSXBXaDKnz8Vc0jQ3IIahUxGucLkfoaE=; b=eYxNnRmIaol+MUu0loPKzjmUiYKFQAVWC/ZqmLzyxypo9R6tmfGdV5UiVXhQz10nX8 PcpTdL8JPMlLG0eoNCzmSHEtrt2dr/JlumqwDtL65CTs+FWSMwoNfu9lPCYM5yVh5dZ9 pMXTnWYe/Gudj26oZAaNvLOybGUIFmnz7mlsz33nj8ba3WBoi2rQQ2DMTqO/9PK8hBaM zHzm+6E5d4yxWHFaWQLd7xJdjVpCts9nWbBjJdp6iCetcI05Os6qwR4WRSlgIAUSd6ze wK1jrerMH/mp9fgToq2+jnI6T9FSTMLGKdr/1QneAWxLCQqWT9H3Pvb4gDCW31SATUYm 5K2A== X-Received: by 10.194.184.44 with SMTP id er12mr20358746wjc.58.1446903795308; Sat, 07 Nov 2015 05:43:15 -0800 (PST) Received: from [10.9.0.103] (nat.webazilla.com. [78.140.128.228]) by smtp.googlemail.com with ESMTPSA id e79sm4047437wmd.16.2015.11.07.05.43.13 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 07 Nov 2015 05:43:14 -0800 (PST) References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> From: Dmitry Gutov Message-ID: <563DFFF0.2000608@yandex.ru> Date: Sat, 7 Nov 2015 15:43:12 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Thunderbird/42.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On 11/07/2015 03:23 PM, Richard Stallman wrote: > The reason that Emacs sources should not use advice is that advice is > bad for debugging. If you look at function foo's source code, it > won't tell you that advice is causing the function to do something not > in that source. Yes still, if we support advice in the user code, we should be able to debug the result. One doesn't usually just reads the source code when debugging Emacs; edebug is very helpful in that, and it seems to support advice. > This problem occurs no matter how long the advice is on function foo. I don't think it's black-and-white: if an advice is only active during execution of just one or two commands, we don't have to worry about it most of the time. Neither when debugging, nor when running the code. > The right thing to do, instead of using advice on foo, is to change > foo to call a hook, and put things in that hook. I agree it will be a simpler solution, if we can choose a meaningful place and name for the hook, and if there's no performance hit. From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 07 Nov 2015 18:51:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Dmitry Gutov Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.144692222310000 (code B ref 21798); Sat, 07 Nov 2015 18:51:01 +0000 Received: (at 21798) by debbugs.gnu.org; 7 Nov 2015 18:50:23 +0000 Received: from localhost ([127.0.0.1]:57104 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv8ZB-0002bC-Op for submit@debbugs.gnu.org; Sat, 07 Nov 2015 13:50:23 -0500 Received: from mail-lb0-f178.google.com ([209.85.217.178]:34333) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv8Z8-0002b2-TK for 21798@debbugs.gnu.org; Sat, 07 Nov 2015 13:50:20 -0500 Received: by lbbwb3 with SMTP id wb3so76727315lbb.1 for <21798@debbugs.gnu.org>; Sat, 07 Nov 2015 10:50:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:cc:message-id:in-reply-to:references :mime-version:content-type; bh=UYSR6gOn8Y1/5GvzTc0jYVKsnX1YPJ6aVlXa/XtCq64=; b=yYwMpCJb46QOYX3pgA5YZtQuPD3iwcMIL4GzC85QfVk7O2ubG38ZYluhPBUCTznNT8 82wzCKuANBdy4t51LrDbksllNQslRlEZE0osNcN3tNYgjGMuo/LdcDN2yt7QzXRnn/ks 0N/1IFK81r8pb9tI7ERogvdcCBYVDj2c+qEYUs/X+yzFddp5ue+NufYbs0o+EaCPBhuz H2zRU67W1uZeFRi2t6dADGsKq8vp15ALp46Y01j8WlHbQ7XypCBSwoZDoq5qWxYJpPLw 9wBxodlSW2TREme6780EFiojwbrtfCElzOfiClWvDPfAQy8mi/J9CSfGmErD2Yps2+x5 O5PA== X-Received: by 10.112.64.72 with SMTP id m8mr9856923lbs.41.1446922218041; Sat, 07 Nov 2015 10:50:18 -0800 (PST) Received: from [192.168.100.7] (cm-84.210.143.4.getinternet.no. [84.210.143.4]) by smtp.gmail.com with ESMTPSA id q197sm1014622lfd.36.2015.11.07.10.50.16 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 07 Nov 2015 10:50:17 -0800 (PST) Date: Sat, 07 Nov 2015 19:50:15 +0100 From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Message-Id: <1446922215.4732.0@smtp.gmail.com> In-Reply-To: <563CE043.9060404@yandex.ru> References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-mXzLxhu9TJt1K29PGzeR" X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --=-mXzLxhu9TJt1K29PGzeR Content-Type: multipart/alternative; boundary="=-DqbhF2blkE3mXuhW8IMG" --=-DqbhF2blkE3mXuhW8IMG Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable On Fri, Nov 6, 2015 at 6:15 PM, Dmitry Gutov wrote: > That sounds fine to me in terms of design, but it might add some=20 > performance overhead. So some testing is needed. Good! A revised patch is attached. Benchmarks follow below, with the same setup as last time. Before the patch: (benchmark-run 100 (json-read-from-string huge-json)) =E2=87=92 (16.84457266 1007 4.886441912999999) After the patch: (benchmark-run 100 (json-read-from-string huge-json)) =E2=87=92 (16.905379125000003 1007 4.722544520000007) -- Simen = --=-DqbhF2blkE3mXuhW8IMG Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Fri, Nov 6, 2015 at 6:15 PM, Dmitry Gutov <dgutov@yandex.ru> wrote= :
That sounds fine to me in terms of design, but it might add s= ome performance overhead. So some testing is needed.

=
Good! A revised patch is attached.

Bench= marks follow below, with the same setup as last time.

<= div>Before the patch:

(benchmark-run 100 (json-rea= d-from-string huge-json))
     =E2=87=92 (16.84457= 266 1007 4.886441912999999)

After the patch:
=

(benchmark-run 100 (json-read-from-string huge-json))
     =E2=87=92 (16.905379125000003 1007 4.722544520= 000007)

-- Simen
= --=-DqbhF2blkE3mXuhW8IMG-- --=-mXzLxhu9TJt1K29PGzeR Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-support-for-retrieving-paths-to-JSON-elements.patch Content-Transfer-Encoding: quoted-printable >From b6c10884b48770143468d93c6a816564834c77be Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D Date: Sun, 25 Oct 2015 14:44:59 +0100 Subject: [PATCH] Add support for retrieving paths to JSON elements Add support for retrieving the path to a JSON element. This can for instance be useful to retrieve paths in deeply nested JSON structures. * lisp/json.el (json-pre-read-function, json-post-read-function): New variables to hold pre- and post read callback functions for `json-read-array' and `json-read-object'. (json--path): New variable used internally by `json-path-to-position'. (json--record-path, json--check-position): New functions used internally by `json-path-to-position'. (json-path-to-position): New function for retrieving the path to a JSON element at a given position. (json-read-object, json-read-array): Call `json-pre-read-function' and `json-post-read-function' when set. * test/automated/json-tests.el (test-json-path-to-position-with-objects) (test-json-path-to-position-with-arrays): New tests for `json-path-to-position'. --- lisp/json.el | 75 ++++++++++++++++++++++++++++++++++++++++= ++++ test/automated/json-tests.el | 14 +++++++++ 2 files changed, 89 insertions(+) diff --git a/lisp/json.el b/lisp/json.el index b23d12a..4cc4f97 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -111,6 +111,16 @@ json-encoding-lisp-style-closings "If non-nil, ] and } closings will be formatted lisp-style, without indentation.") =20 +(defvar json-pre-read-function nil + "Function called (if non-nil) by `json-read-array' and +`json-read-object' right before reading a JSON array or object, +respectively.") + +(defvar json-post-read-function nil + "Function called (if non-nil) by `json-read-array' and +`json-read-object' right after reading a JSON array or object, +respectively.") + =0C =20 ;;; Utilities @@ -196,6 +206,61 @@ 'json-end-of-file =20 =0C =20 +;;; Paths + +(defvar json--path '() + "Used internally by `json-path-to-position' to keep track of +the path during recursive calls to `json-read'.") + +(defun json--record-path (key) + "Record the KEY to the current JSON path. Used internally by +`json-path-to-position'." + (push (cons (point) key) json--path)) + +(defun json--check-position (position) + "Check if the last parsed JSON structure passed POSITION. Used +internally by `json-path-to-position'." + (let ((start (caar json--path))) + (when (< start position (+ (point) 1)) + (throw :json-path (list :path (nreverse (mapcar #'cdr json--path)) + :match-start start + :match-end (point))))) + (pop json--path)) + +(defun json-path-to-position (position &optional string) + "Return the path to the JSON element at POSITION. + +When STRING is provided, return the path to the position in the +string, else to the position in the current buffer. + +The return value is a property list with the following +properties: + +:path -- A list of strings and numbers forming the path to + the JSON element at the given position. Strings + denote object names, while numbers denote array + indexes. + +:match-start -- Position where the matched JSON element begins. + +:match-end -- Position where the matched JSON element ends. + +This can for instance be useful to determine the path to a JSON +element in a deeply nested structure." + (save-excursion + (unless string + (goto-char (point-min))) + (let* ((json--path '()) + (json-pre-read-function #'json--record-path) + (json-post-read-function + (apply-partially #'json--check-position position)) + (path (catch :json-path + (if string + (json-read-from-string string) + (json-read))))) + (when (plist-get path :path) + path)))) + ;;; Keywords =20 (defvar json-keywords '("true" "false" "null") @@ -403,7 +468,12 @@ json-read-object (if (char-equal (json-peek) ?:) (json-advance) (signal 'json-object-format (list ":" (json-peek)))) + (json-skip-whitespace) + (when json-pre-read-function + (funcall json-pre-read-function key)) (setq value (json-read)) + (when json-post-read-function + (funcall json-post-read-function)) (setq elements (json-add-to-object elements key value)) (json-skip-whitespace) (unless (char-equal (json-peek) ?}) @@ -509,7 +579,12 @@ json-read-array ;; read values until "]" (let (elements) (while (not (char-equal (json-peek) ?\])) + (json-skip-whitespace) + (when json-pre-read-function + (funcall json-pre-read-function (length elements))) (push (json-read) elements) + (when json-post-read-function + (funcall json-post-read-function)) (json-skip-whitespace) (unless (char-equal (json-peek) ?\]) (if (char-equal (json-peek) ?,) diff --git a/test/automated/json-tests.el b/test/automated/json-tests.el index d1b7a2f..e0672dd 100644 --- a/test/automated/json-tests.el +++ b/test/automated/json-tests.el @@ -49,5 +49,19 @@ (should (equal (json-read-from-string "\"\\nasd\\u0444\\u044b\\u0432fgh\= \t\"") "\nasd=D1=84=D1=8B=D0=B2fgh\t"))) =20 +(ert-deftest test-json-path-to-position-with-objects () + (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}") + (matched-path (json-path-to-position 32 json-string))) + (should (equal (plist-get matched-path :path) '("foo" "bar" "baz"))) + (should (equal (plist-get matched-path :match-start) 25)) + (should (equal (plist-get matched-path :match-end) 32)))) + +(ert-deftest test-json-path-to-position-with-arrays () + (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}") + (matched-path (json-path-to-position 20 json-string))) + (should (equal (plist-get matched-path :path) '("foo" 1 0))) + (should (equal (plist-get matched-path :match-start) 18)) + (should (equal (plist-get matched-path :match-end) 23)))) + (provide 'json-tests) ;;; json-tests.el ends here --=20 2.6.2 = --=-mXzLxhu9TJt1K29PGzeR-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 07 Nov 2015 19:19:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Cc: 21798@debbugs.gnu.org, Richard Stallman Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.144692391512694 (code B ref 21798); Sat, 07 Nov 2015 19:19:02 +0000 Received: (at 21798) by debbugs.gnu.org; 7 Nov 2015 19:18:35 +0000 Received: from localhost ([127.0.0.1]:57112 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv90U-0003If-T6 for submit@debbugs.gnu.org; Sat, 07 Nov 2015 14:18:35 -0500 Received: from mail-wi0-f182.google.com ([209.85.212.182]:34524) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1Zv90A-0003IE-PD for 21798@debbugs.gnu.org; Sat, 07 Nov 2015 14:18:33 -0500 Received: by wikq8 with SMTP id q8so47957168wik.1 for <21798@debbugs.gnu.org>; Sat, 07 Nov 2015 11:18:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=GF1pNXl5+WoAGwoJM1zgWEm1kZ1GwAXkknGDW1IBlE0=; b=cfdu9z/6wk6VBI0o17wJ6g5zxamZ+Huk/0giMLCh7j8TVRvON7NVXikg2VUTMDzVXq mSlwn2AWDbYbtTfvIr8/vrOkjI9nElB4Pl0wsQ3/3qhO5Q9zhk1h0+Hs6vEHJN7ayYsU HHfk/MSMtAoDCcPAZLAXR7L9P6wkntVBHI2KliEC7aXgQfKGSBk+W3CmrNaCmc2Hp/w8 8o/j25d8ok7jRNMbCBl3lC5fAzH60kNaLOKPdas3OKyjfy6lmSxIGOQcSV8Q1sAoaDJa TEfas3j/mQzBbTECi3SWPoGBl//tCRzero5FlMSuZb9pd3AAA2ra7FfW3Rq8HptUqwUT g9BQ== X-Received: by 10.194.186.196 with SMTP id fm4mr25456186wjc.152.1446923893997; Sat, 07 Nov 2015 11:18:13 -0800 (PST) Received: from [10.9.0.103] (nat.webazilla.com. [78.140.128.228]) by smtp.googlemail.com with ESMTPSA id it4sm6480123wjb.0.2015.11.07.11.18.12 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 07 Nov 2015 11:18:13 -0800 (PST) References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> <1446922215.4732.0@smtp.gmail.com> From: Dmitry Gutov Message-ID: <563E4E73.50702@yandex.ru> Date: Sat, 7 Nov 2015 21:18:11 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Thunderbird/42.0 MIME-Version: 1.0 In-Reply-To: <1446922215.4732.0@smtp.gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On 11/07/2015 08:50 PM, Simen Heggestøyl wrote: > Before the patch: > > (benchmark-run 100 (json-read-from-string huge-json)) > ⇒ (16.84457266 1007 4.886441912999999) > > After the patch: > > (benchmark-run 100 (json-read-from-string huge-json)) > ⇒ (16.905379125000003 1007 4.722544520000007) Looks good enough, thanks. > +(defvar json-pre-read-function nil > + "Function called (if non-nil) by `json-read-array' and > +`json-read-object' right before reading a JSON array or object, > +respectively.") > + > +(defvar json-post-read-function nil > + "Function called (if non-nil) by `json-read-array' and > +`json-read-object' right after reading a JSON array or object, > +respectively.") Shouldn't they be called by `json-read' itself? From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 08 Nov 2015 12:33:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Dmitry Gutov Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.14469859401161 (code B ref 21798); Sun, 08 Nov 2015 12:33:02 +0000 Received: (at 21798) by debbugs.gnu.org; 8 Nov 2015 12:32:20 +0000 Received: from localhost ([127.0.0.1]:57330 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvP8t-0000Ie-IB for submit@debbugs.gnu.org; Sun, 08 Nov 2015 07:32:20 -0500 Received: from mail-lb0-f179.google.com ([209.85.217.179]:35720) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvP8q-0000IR-UD for 21798@debbugs.gnu.org; Sun, 08 Nov 2015 07:32:17 -0500 Received: by lbces9 with SMTP id es9so13186830lbc.2 for <21798@debbugs.gnu.org>; Sun, 08 Nov 2015 04:32:15 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:cc:message-id:in-reply-to:references :mime-version:content-type; bh=0tBFrArtW7A/gn1LgT1bqMbKyMKGF3070mh6yYB2YtA=; b=pBmODAjq+h4R9oPUSc3ne4RPRH7Sg49ttbzQqbybtswYdZWZnMONtzHVnb6dyhRNu8 SulWXKmLVTi8iPZfPDe3c/9801Oir/X4oQeiXB7qcr7+32z5rPlrJ8Gd63OYKmKl5NcC 4IIGio3SAiw9sNLVbAteYwLFYOrigAeF7DU4CxNeWDmNtH2dlouqMOeDabgxlGp+HHgu 7bQenL7xpGkFo+d5Gnnw1ccRitrCXgapn0S/i6aLxhdNzvwHboL4FfnWEeJvqLPR25l3 CwAR2H+xa5xQiVa4lMbonFHkyKP45vLQjZ7z5glY9H65fuzfucDcgapg9xfWUybkx7Xh 09yQ== X-Received: by 10.112.188.168 with SMTP id gb8mr11379070lbc.6.1446985935832; Sun, 08 Nov 2015 04:32:15 -0800 (PST) Received: from [192.168.100.7] (cm-84.210.143.4.getinternet.no. [84.210.143.4]) by smtp.gmail.com with ESMTPSA id re5sm1533891lbb.36.2015.11.08.04.32.14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 04:32:15 -0800 (PST) Date: Sun, 08 Nov 2015 13:32:13 +0100 From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Message-Id: <1446985933.1975.0@smtp.gmail.com> In-Reply-To: <563E4E73.50702@yandex.ru> References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> <1446922215.4732.0@smtp.gmail.com> <563E4E73.50702@yandex.ru> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-081SO8yKnWfC+wfhXb4b" X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --=-081SO8yKnWfC+wfhXb4b Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Thanks again for your feedback, Dmitry. On Sat, Nov 7, 2015 at 8:18 PM, Dmitry Gutov wrote: > Shouldn't they be called by `json-read' itself? Yes, maybe they should. The only drawback I see is that 'json-read' then needs to accept an optional parameter, which is the JSON key of the current element. A revised patch implementing your suggestion is attached. Benchmarks follow below, with the usual setup! Before the patch: (benchmark-run 100 (json-read-from-string huge-json)) =E2=87=92 (18.782874379000003 1007 5.674178575000008) After the patch: (benchmark-run 100 (json-read-from-string huge-json)) =E2=87=92 (18.233328517999997 1007 4.907621599000008) -- Simen = --=-081SO8yKnWfC+wfhXb4b Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
Thanks again for your feedback, Dmitry.

On Sat, No= v 7, 2015 at 8:18 PM, Dmitry Gutov <dgutov@yandex.ru> wrote:
Shouldn't they be called by `json-read' itself?

<= div>
Yes, maybe they should. The only drawback I see is that 'json-read= ' then
needs to accept an optional parameter, which is the JSON k= ey of the
current element.

A revised pat= ch implementing your suggestion is attached.

Bench= marks follow below, with the usual setup!

Before t= he patch:

(benchmark-run 100 (json-read-from-strin= g huge-json))
     =E2=87=92 (18.782874379000003 1= 007 5.674178575000008)

After the patch:
=
(benchmark-run 100 (json-read-from-string huge-json))
<= div>     =E2=87=92 (18.233328517999997 1007 4.90762159900000= 8)

-- Simen

= --=-081SO8yKnWfC+wfhXb4b-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 08 Nov 2015 12:35:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Dmitry Gutov Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.14469860601406 (code B ref 21798); Sun, 08 Nov 2015 12:35:01 +0000 Received: (at 21798) by debbugs.gnu.org; 8 Nov 2015 12:34:20 +0000 Received: from localhost ([127.0.0.1]:57334 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvPAp-0000Ma-Cs for submit@debbugs.gnu.org; Sun, 08 Nov 2015 07:34:20 -0500 Received: from mail-lf0-f50.google.com ([209.85.215.50]:33448) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvPAm-0000MS-Uc for 21798@debbugs.gnu.org; Sun, 08 Nov 2015 07:34:17 -0500 Received: by lffz63 with SMTP id z63so20926336lff.0 for <21798@debbugs.gnu.org>; Sun, 08 Nov 2015 04:34:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:cc:message-id:in-reply-to:references :mime-version:content-type; bh=eUIymT/NCWjmVodBhW1FkC2DtZcyHPcY2ykuoi19occ=; b=kMgoOfSS/MEVdjhrGUutjQuC2aiotsPEAS88rPEG+v21JoBNBV4R9TiYuWCtul0aU8 DdNFvUObMhM0OPpjC+LK0WIcvfW8zIFYE5k/f3u4qYl8dzv+qAWSGSeqpmuehiLOgRiq FaSQh6oWOoGa0OrZmoQBP48Y7/Xj+KWVNOyMb1OFvJ9W3QpIRGKwYDJXkZjQ8+WYC/zN p7J/lGkUyNTm/3k1f4mrV0oiFoPOkObseD47i7y/0By+d4CGd5Wp8jDEPo5SH3DyY2zX nAGrIryh7PqpQRwMHOfquDmPMQD5S9u1Qnvje9/6Z0IZVycRQnP7raWUDvUZd3YzlM26 FsXQ== X-Received: by 10.25.207.149 with SMTP id f143mr7488310lfg.73.1446986056107; Sun, 08 Nov 2015 04:34:16 -0800 (PST) Received: from [192.168.100.7] (cm-84.210.143.4.getinternet.no. [84.210.143.4]) by smtp.gmail.com with ESMTPSA id c7sm1571055lfe.22.2015.11.08.04.34.14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 04:34:15 -0800 (PST) Date: Sun, 08 Nov 2015 13:34:14 +0100 From: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Message-Id: <1446986054.1975.1@smtp.gmail.com> In-Reply-To: <1446985933.1975.0@smtp.gmail.com> References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> <1446922215.4732.0@smtp.gmail.com> <563E4E73.50702@yandex.ru> <1446985933.1975.0@smtp.gmail.com> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-FskjqSS2DlfAsNoIPXuh" X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --=-FskjqSS2DlfAsNoIPXuh Content-Type: multipart/alternative; boundary="=-6Y8hTKAbrOKGUHNjnFHa" --=-6Y8hTKAbrOKGUHNjnFHa Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable On Sun, Nov 8, 2015 at 1:32 PM, Simen Heggest=C3=B8yl =20 wrote: > A revised patch implementing your suggestion is attached. Sorry, I forgot to attach the patch. Here it is! -- Simen = --=-6Y8hTKAbrOKGUHNjnFHa Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable On Sun, Nov 8, 2015 at 1:32 PM, Simen Heggest=C3=B8yl <simenheg@gmail.co= m> wrote:
A revised patch impleme= nting your suggestion is attached.

So= rry, I forgot to attach the patch.

Here it is!

-- Simen
= --=-6Y8hTKAbrOKGUHNjnFHa-- --=-FskjqSS2DlfAsNoIPXuh Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-Add-support-for-retrieving-paths-to-JSON-elements.patch Content-Transfer-Encoding: quoted-printable >From 2e220a1bfce42081ed84c343ecd809263215a54e Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D Date: Sun, 25 Oct 2015 14:44:59 +0100 Subject: [PATCH] Add support for retrieving paths to JSON elements Add support for retrieving the path to a JSON element. This can for instance be useful to retrieve paths in deeply nested JSON structures. * lisp/json.el (json-pre-read-function, json-post-read-function): New variables to hold pre- and post read callback functions for `json-read'. (json--path): New variable used internally by `json-path-to-position'. (json--record-path, json--check-position): New functions used internally by `json-path-to-position'. (json-path-to-position): New function for retrieving the path to a JSON element at a given position. (json-read-object, json-read-array): Pass the current JSON key to subsequent calls to `json-read'. (json-read): Call `json-pre-read-function' and `json-post-read-function' before and after reading a JSON element, respectively. * test/automated/json-tests.el (test-json-path-to-position-with-objects) (test-json-path-to-position-with-arrays) (test-json-path-to-position-no-match): New tests for `json-path-to-position'. --- lisp/json.el | 88 ++++++++++++++++++++++++++++++++++++++++= +--- test/automated/json-tests.el | 19 ++++++++++ 2 files changed, 101 insertions(+), 6 deletions(-) diff --git a/lisp/json.el b/lisp/json.el index b23d12a..2982f08 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -111,6 +111,16 @@ json-encoding-lisp-style-closings "If non-nil, ] and } closings will be formatted lisp-style, without indentation.") =20 +(defvar json-pre-read-function nil + "Function called (if non-nil) by `json-read' right before +reading a JSON element. The function is called with one +argument, which is the current JSON key when reading an array or +object, else it is nil.") + +(defvar json-post-read-function nil + "Function called (if non-nil) by `json-read' right after +reading a JSON element.") + =0C =20 ;;; Utilities @@ -196,6 +206,63 @@ 'json-end-of-file =20 =0C =20 +;;; Paths + +(defvar json--path '() + "Used internally by `json-path-to-position' to keep track of +the path during recursive calls to `json-read'. Each entry is a +cons of a buffer position, and a JSON key (if any, else nil).") + +(defun json--record-path (key) + "Record the KEY to the current JSON path. +Used internally by `json-path-to-position'." + (push (cons (point) key) json--path)) + +(defun json--check-position (position) + "Check if the last parsed JSON structure passed POSITION. +Used internally by `json-path-to-position'." + (let ((start (caar json--path))) + (when (< start position (+ (point) 1)) + (let ((path (nreverse (delq nil (mapcar #'cdr json--path))))) + (throw :json-path (list :path path + :match-start start + :match-end (point)))))) + (pop json--path)) + +(defun json-path-to-position (position &optional string) + "Return the path to the JSON element at POSITION. + +When STRING is provided, return the path to the position in the +string, else to the position in the current buffer. + +The return value is a property list with the following +properties: + +:path -- A list of strings and numbers forming the path to + the JSON element at the given position. Strings + denote object names, while numbers denote array + indexes. + +:match-start -- Position where the matched JSON element begins. + +:match-end -- Position where the matched JSON element ends. + +This can for instance be useful to determine the path to a JSON +element in a deeply nested structure." + (save-excursion + (unless string + (goto-char (point-min))) + (let* ((json--path '()) + (json-pre-read-function #'json--record-path) + (json-post-read-function + (apply-partially #'json--check-position position)) + (path (catch :json-path + (if string + (json-read-from-string string) + (json-read))))) + (when (plist-get path :path) + path)))) + ;;; Keywords =20 (defvar json-keywords '("true" "false" "null") @@ -403,7 +470,8 @@ json-read-object (if (char-equal (json-peek) ?:) (json-advance) (signal 'json-object-format (list ":" (json-peek)))) - (setq value (json-read)) + (json-skip-whitespace) + (setq value (json-read key)) (setq elements (json-add-to-object elements key value)) (json-skip-whitespace) (unless (char-equal (json-peek) ?}) @@ -507,14 +575,17 @@ json-read-array (json-advance) (json-skip-whitespace) ;; read values until "]" - (let (elements) + (let ((index 0) + elements) (while (not (char-equal (json-peek) ?\])) - (push (json-read) elements) + (json-skip-whitespace) + (push (json-read index) elements) (json-skip-whitespace) (unless (char-equal (json-peek) ?\]) (if (char-equal (json-peek) ?,) (json-advance) - (signal 'json-error (list 'bleah))))) + (signal 'json-error (list 'bleah)))) + (setq index (+ index 1))) ;; Skip over the "]" (json-advance) (apply json-array-type (nreverse elements)))) @@ -558,7 +629,7 @@ json-readtable table) "Readtable for JSON reader.") =20 -(defun json-read () +(defun json-read (&optional current-key) "Parse and return the JSON object following point. Advances point just past JSON object." (json-skip-whitespace) @@ -566,7 +637,12 @@ json-read (if (not (eq char :json-eof)) (let ((record (cdr (assq char json-readtable)))) (if (functionp (car record)) - (apply (car record) (cdr record)) + (prog2 + (when json-pre-read-function + (funcall json-pre-read-function current-key)) + (apply (car record) (cdr record)) + (when json-post-read-function + (funcall json-post-read-function))) (signal 'json-readtable-error record))) (signal 'json-end-of-file nil)))) =20 diff --git a/test/automated/json-tests.el b/test/automated/json-tests.el index d1b7a2f..fa1f548 100644 --- a/test/automated/json-tests.el +++ b/test/automated/json-tests.el @@ -49,5 +49,24 @@ (should (equal (json-read-from-string "\"\\nasd\\u0444\\u044b\\u0432fgh\= \t\"") "\nasd=D1=84=D1=8B=D0=B2fgh\t"))) =20 +(ert-deftest test-json-path-to-position-with-objects () + (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}") + (matched-path (json-path-to-position 32 json-string))) + (should (equal (plist-get matched-path :path) '("foo" "bar" "baz"))) + (should (equal (plist-get matched-path :match-start) 25)) + (should (equal (plist-get matched-path :match-end) 32)))) + +(ert-deftest test-json-path-to-position-with-arrays () + (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}") + (matched-path (json-path-to-position 20 json-string))) + (should (equal (plist-get matched-path :path) '("foo" 1 0))) + (should (equal (plist-get matched-path :match-start) 18)) + (should (equal (plist-get matched-path :match-end) 23)))) + +(ert-deftest test-json-path-to-position-no-match () + (let* ((json-string "{\"foo\": {\"bar\": \"baz\"}}") + (matched-path (json-path-to-position 5 json-string))) + (should (null matched-path)))) + (provide 'json-tests) ;;; json-tests.el ends here --=20 2.6.2 = --=-FskjqSS2DlfAsNoIPXuh-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 08 Nov 2015 16:17:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Cc: 21798@debbugs.gnu.org Received: via spool by 21798-submit@debbugs.gnu.org id=B21798.144699941622914 (code B ref 21798); Sun, 08 Nov 2015 16:17:01 +0000 Received: (at 21798) by debbugs.gnu.org; 8 Nov 2015 16:16:56 +0000 Received: from localhost ([127.0.0.1]:57777 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvSeF-0005xW-He for submit@debbugs.gnu.org; Sun, 08 Nov 2015 11:16:55 -0500 Received: from mail-wm0-f50.google.com ([74.125.82.50]:35508) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvSdv-0005x7-PD for 21798@debbugs.gnu.org; Sun, 08 Nov 2015 11:16:54 -0500 Received: by wmdw130 with SMTP id w130so12405085wmd.0 for <21798@debbugs.gnu.org>; Sun, 08 Nov 2015 08:16:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=jAMGoiaEx/QE5+wbF1uN9W6Cv8ozVQ0Fvtk3WViQ0Ng=; b=Wao6E3AhVJnxrzUPWgGrrWSWgo5JW54W0JoajVDgwTInxVucUIuaC2RFU1YDsgt/Zo Y70uGOBJjretYe3trzrlT4K5Rg5jm7zbRka2TeDgDyhO1zeueRU7ITnewezE9gNbj27V Ef9Xixb/i/7348qGLyu+zlcvdIeGWUkqW/ta/CKlxo8KLY2HUwgmTUlT8B4CNusHTHFN XSAIBLyjXsuJfZ1alK01S3c0sF1CqeplnnFO++JJSI+OJ5sZ1BLX91AthdSsTvVUHvFU eF244HFkMPEw4cn5hRGklnMyuHzeBWhIrnrCgHMrMYe1O5kdwhdC5GdNPd8kSuY1uQ2x Qoow== X-Received: by 10.28.143.79 with SMTP id r76mr22567001wmd.102.1446999395217; Sun, 08 Nov 2015 08:16:35 -0800 (PST) Received: from [192.168.1.2] ([185.105.175.24]) by smtp.googlemail.com with ESMTPSA id ly4sm10674033wjb.4.2015.11.08.08.16.33 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 08:16:34 -0800 (PST) References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> <1446922215.4732.0@smtp.gmail.com> <563E4E73.50702@yandex.ru> <1446985933.1975.0@smtp.gmail.com> From: Dmitry Gutov Message-ID: <563F7560.1000409@yandex.ru> Date: Sun, 8 Nov 2015 18:16:32 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Thunderbird/42.0 MIME-Version: 1.0 In-Reply-To: <1446985933.1975.0@smtp.gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: 0.0 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: 0.0 (/) Hi again, Simen. On 11/08/2015 02:32 PM, Simen Heggestøyl wrote: > Yes, maybe they should. The only drawback I see is that 'json-read' then > needs to accept an optional parameter, which is the JSON key of the > current element. > > A revised patch implementing your suggestion is attached. Thank you, but since `json-read' needs an optional argument in this case (which is not trivial to describe), I'd rather we go back to the previous patch. How about renaming json-pre-read-function to json-pre-element-read-function, maybe? And same for the other one. If you're fine with that, please install the result. (Or without the rename, it's up to you). > Benchmarks follow below, with the usual setup! > > Before the patch: > > (benchmark-run 100 (json-read-from-string huge-json)) > ⇒ (18.782874379000003 1007 5.674178575000008) > > After the patch: > > (benchmark-run 100 (json-read-from-string huge-json)) > ⇒ (18.233328517999997 1007 4.907621599000008) Nice! The extra code made it faster. :) Apparently, the difference is within the margin of error. From unknown Mon Jun 23 13:10:59 2025 MIME-Version: 1.0 X-Mailer: MIME-tools 5.503 (Entity 5.503) X-Loop: help-debbugs@gnu.org From: help-debbugs@gnu.org (GNU bug Tracking System) To: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Subject: bug#21798: closed (Re: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements) Message-ID: References: <1447017159.19568.0@smtp.gmail.com> <1446281162.2607.0@smtp.gmail.com> X-Gnu-PR-Message: they-closed 21798 X-Gnu-PR-Package: emacs X-Gnu-PR-Keywords: patch Reply-To: 21798@debbugs.gnu.org Date: Sun, 08 Nov 2015 21:13:03 +0000 Content-Type: multipart/mixed; boundary="----------=_1447017183-23166-1" This is a multi-part message in MIME format... ------------=_1447017183-23166-1 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Your bug report #21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements which was filed against the emacs package, has been closed. The explanation is attached below, along with your original report. If you require more details, please reply to 21798@debbugs.gnu.org. --=20 21798: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=3D21798 GNU Bug Tracking System Contact help-debbugs@gnu.org with problems ------------=_1447017183-23166-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at 21798-done) by debbugs.gnu.org; 8 Nov 2015 21:12:46 +0000 Received: from localhost ([127.0.0.1]:57877 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvXGX-00061A-GZ for submit@debbugs.gnu.org; Sun, 08 Nov 2015 16:12:45 -0500 Received: from mail-lf0-f48.google.com ([209.85.215.48]:36548) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvXGV-000612-BR for 21798-done@debbugs.gnu.org; Sun, 08 Nov 2015 16:12:44 -0500 Received: by lfs39 with SMTP id 39so60871239lfs.3 for <21798-done@debbugs.gnu.org>; Sun, 08 Nov 2015 13:12:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:cc:message-id:in-reply-to:references :mime-version:content-type; bh=UopOfnqaHzxTh6BAoa3Gy9WMBLE2aWCpNOyHbgXXFdY=; b=ilGgEZt/eFmDBjt+M27Wg6bHumY2bV4jl3EpPkiWik2zji5Nvzftgyiw/H4uZF0Crf K16QrNkVhcKyQvx26q6YgY0m78knHmqrvDAzMRkLu4CXD1qxw3AbXcYJH9vganmNeyjX YBMzZh6LG6eJkp/a1o92iH74drhuzYRR3JQtIUPanUPfPtF0JLd+KYe6wNHoi69C1iCX +EIBg8BRUTwT5pcrFOWD3f2rIpoBERyk1VFAK66kwb7hegDVOZWDxHxMbJDSMAu2MGCx W8Yrqbnt2HIkA0nu+GFdwa2HGsRcSGF64jRb0G77gQEXF+IJHelU4F7RygUlOhzyRlen Zyhw== X-Received: by 10.25.164.66 with SMTP id n63mr4902282lfe.24.1447017162453; Sun, 08 Nov 2015 13:12:42 -0800 (PST) Received: from [192.168.100.7] (cm-84.210.143.4.getinternet.no. [84.210.143.4]) by smtp.gmail.com with ESMTPSA id v1sm1847479lfd.25.2015.11.08.13.12.41 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 13:12:41 -0800 (PST) Date: Sun, 08 Nov 2015 22:12:39 +0100 From: Simen =?iso-8859-1?q?Heggest=F8yl?= Subject: Re: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements To: Dmitry Gutov Message-Id: <1447017159.19568.0@smtp.gmail.com> In-Reply-To: <563F7560.1000409@yandex.ru> References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> <1446922215.4732.0@smtp.gmail.com> <563E4E73.50702@yandex.ru> <1446985933.1975.0@smtp.gmail.com> <563F7560.1000409@yandex.ru> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-jNI1lirybN5kUJ62U79c" X-Spam-Score: -0.7 (/) X-Debbugs-Envelope-To: 21798-done Cc: 21798-done@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) --=-jNI1lirybN5kUJ62U79c Content-Type: text/plain; charset=utf-8; format=flowed On Sun, Nov 8, 2015 at 5:16 PM, Dmitry Gutov wrote: > Thank you, but since `json-read' needs an optional argument in this > case (which is not trivial to describe), I'd rather we go back to the > previous patch. > > How about renaming json-pre-read-function to > json-pre-element-read-function, maybe? And same for the other one. > > If you're fine with that, please install the result. (Or without the > rename, it's up to you). I installed the previous patch with the renaming you suggested. Thanks for your reviews! By the way, if you find the time, could you give bug #21616 a quick look as well? It teaches the JSON encoder how to sort objects by their keys. I think it would be nice to get it in before the feature freeze, since it's the last piece of the puzzle to enable the new json-mode to achieve feature parity with the old one. -- Simen --=-jNI1lirybN5kUJ62U79c Content-Type: text/html; charset=utf-8 On Sun, Nov 8, 2015 at 5:16 PM, Dmitry Gutov <dgutov@yandex.ru> wrote:
Thank you, but since `json-read' needs an optional argument in this case (which is not trivial to describe), I'd rather we go back to the previous patch. How about renaming json-pre-read-function to json-pre-element-read-function, maybe? And same for the other one. If you're fine with that, please install the result. (Or without the rename, it's up to you).

I installed the previous patch with the renaming you suggested.

Thanks for your reviews!

By the way, if you find the time, could you give bug #21616 a quick
look as well? It teaches the JSON encoder how to sort objects by their
keys. I think it would be nice to get it in before the feature freeze,
since it's the last piece of the puzzle to enable the new json-mode to
achieve feature parity with the old one.

-- Simen
--=-jNI1lirybN5kUJ62U79c-- ------------=_1447017183-23166-1 Content-Type: message/rfc822 Content-Disposition: inline Content-Transfer-Encoding: 7bit Received: (at submit) by debbugs.gnu.org; 31 Oct 2015 08:46:36 +0000 Received: from localhost ([127.0.0.1]:46706 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZsRo2-000399-Ql for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:35 -0400 Received: from eggs.gnu.org ([208.118.235.92]:40872) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZsRnh-00038c-S8 for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZsRnf-0005Kh-FD for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:13 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50,FREEMAIL_FROM, HTML_MESSAGE,T_DKIM_INVALID autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:52297) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZsRnf-0005Kd-CF for submit@debbugs.gnu.org; Sat, 31 Oct 2015 04:46:11 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50877) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZsRnd-0003yb-Fr for bug-gnu-emacs@gnu.org; Sat, 31 Oct 2015 04:46:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZsRna-0005KP-4F for bug-gnu-emacs@gnu.org; Sat, 31 Oct 2015 04:46:09 -0400 Received: from mail-wi0-x22a.google.com ([2a00:1450:400c:c05::22a]:38003) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZsRnZ-0005KL-QV for bug-gnu-emacs@gnu.org; Sat, 31 Oct 2015 04:46:06 -0400 Received: by wicll6 with SMTP id ll6so23480654wic.1 for ; Sat, 31 Oct 2015 01:46:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:subject:to:message-id:mime-version:content-type; bh=zyQlVlgyJEk8cBTCuJtVl8M4ogSm8+fSb8t2CHeuhYw=; b=mPm0ljRCA9RM6ac6fNTJSjwkY/nGsrKuDXtgd9vTk3CUjZBslI+Cf37xj/Mvh4jbN1 rzwkeSGMe0mpsZjZ+ruUoEIUONy+mcveZAA54IdFC0hDMDPMFBFYHxAD6wj87QJybkG6 1vc7n6Ejl/NC8XyBKZysIElTfmZqc756sA7MvqNJVM03cRSwVWGt/fb9Wbj01RcVOsqy XiDFfhOw5CaIs/x68/sXkBCopqcbk6Jc9HOmlCVxyWI4lhtOFCw/J1y7sUfbnpNV+mkL BRHHUZpm7XoIEJ5BIsSqnmC5KPDjyKdrvQWr7gK9jDz4xUPjPN/BXEVIvfpP2m10x4w+ ujww== X-Received: by 10.194.61.13 with SMTP id l13mr15307014wjr.76.1446281165048; Sat, 31 Oct 2015 01:46:05 -0700 (PDT) Received: from [192.168.101.25] ([77.40.215.202]) by smtp.gmail.com with ESMTPSA id c67sm6831605wmh.11.2015.10.31.01.46.03 for (version=TLSv1/SSLv3 cipher=OTHER); Sat, 31 Oct 2015 01:46:04 -0700 (PDT) Date: Sat, 31 Oct 2015 09:46:02 +0100 From: Simen =?iso-8859-1?q?Heggest=F8yl?= Subject: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements To: bug-gnu-emacs@gnu.org Message-Id: <1446281162.2607.0@smtp.gmail.com> X-Mailer: geary/0.10.0 MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-b4IqqtSK8ay5FwlaWkkt" X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 X-Spam-Score: -4.0 (----) X-Debbugs-Envelope-To: submit X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -4.0 (----) --=-b4IqqtSK8ay5FwlaWkkt Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: quoted-printable Sometimes when working with a JSON structure, one needs to find the path to a particular element. That can be tiresome to do manually, especially if the structure is deep. The proposed patch extends json.el with the ability to retrieve the path to a particular JSON element. See the following video for an example of how it can be used by an interactive command, to show the path to the JSON element at point: http://folk.uio.no/simenheg/json-mode.webm The patch follows! -- Simen From f6ddd3b797d6b0d92a1ffa0f5db59543ac7cdc11 Mon Sep 17 00:00:00 2001 From: =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D Date: Sun, 25 Oct 2015 14:44:59 +0100 Subject: [PATCH] Add support for retrieving paths to JSON elements Add support for retrieving the path to a JSON element. This can for instance be useful to retrieve paths in deeply nested JSON structures. * lisp/json.el (json-path-to-position): New function for retrieving the path to a JSON object at a given position. (json--path-to-position, json--path): New variables, used internally by `json-path-to-position'. (json-read-object, json-read-array): Respect `json--path-to-position'. * test/automated/json-tests.el (test-json-path-to-position-with-objects) (test-json-path-to-position-with-arrays): New tests for `json-path-to-position'. --- lisp/json.el | 67 ++++++++++++++++++++++++++++++++++++++++++-- test/automated/json-tests.el | 14 +++++++++ 2 files changed, 79 insertions(+), 2 deletions(-) diff --git a/lisp/json.el b/lisp/json.el index b23d12a..2c82eee 100644 --- a/lisp/json.el +++ b/lisp/json.el @@ -196,6 +196,49 @@ 'json-end-of-file +;;; Paths + +(defvar json--path-to-position nil + "When set to a position, `json-read' will return the path to +the JSON element at the specified position, instead of returning +the parsed JSON object.") + +(defvar json--path '() + "Used internally by `json-path-to-position' to keep track of +the path during recursive calls to `json-read'.") + +(defun json-path-to-position (position &optional string) + "Return the path to the JSON element at POSITION. + +When STRING is provided, return the path to the position in the +string, else to the position in the current buffer. + +The return value is a property list with the following +properties: + +:path -- A list of strings and numbers forming the path to + the JSON element at the given position. Strings + denote object names, while numbers denote array + indexes. + +:match-start -- Position where the matched JSON element begins. + +:match-end -- Position where the matched JSON element ends. + +This can for instance be useful to determine the path to a JSON +element in a deeply nested structure." + (save-excursion + (unless string + (goto-char (point-min))) + (let* ((json--path '()) + (json--path-to-position position) + (path (catch :json-path + (if string + (json-read-from-string string) + (json-read))))) + (when (plist-get path :path) + path)))) + ;;; Keywords (defvar json-keywords '("true" "false" "null") @@ -399,11 +442,21 @@ json-read-object (while (not (char-equal (json-peek) ?})) (json-skip-whitespace) (setq key (json-read-string)) + (when json--path-to-position + (push key json--path)) (json-skip-whitespace) (if (char-equal (json-peek) ?:) (json-advance) (signal 'json-object-format (list ":" (json-peek)))) - (setq value (json-read)) + (json-skip-whitespace) + (let ((start (point))) + (setq value (json-read)) + (when json--path-to-position + (when (< start json--path-to-position (+ (point) 1)) + (throw :json-path (list :path (nreverse json--path) + :match-start start + :match-end (point)))) + (pop json--path))) (setq elements (json-add-to-object elements key value)) (json-skip-whitespace) (unless (char-equal (json-peek) ?}) @@ -509,7 +562,17 @@ json-read-array ;; read values until "]" (let (elements) (while (not (char-equal (json-peek) ?\])) - (push (json-read) elements) + (json-skip-whitespace) + (when json--path-to-position + (push (length elements) json--path)) + (let ((start (point))) + (push (json-read) elements) + (when json--path-to-position + (when (< start json--path-to-position (+ (point) 1)) + (throw :json-path (list :path (nreverse json--path) + :match-start start + :match-end (point)))) + (pop json--path))) (json-skip-whitespace) (unless (char-equal (json-peek) ?\]) (if (char-equal (json-peek) ?,) diff --git a/test/automated/json-tests.el b/test/automated/json-tests.el index d1b7a2f..e0672dd 100644 --- a/test/automated/json-tests.el +++ b/test/automated/json-tests.el @@ -49,5 +49,19 @@ (should (equal (json-read-from-string=20 "\"\\nasd\\u0444\\u044b\\u0432fgh\\t\"") "\nasd=D1=84=D1=8B=D0=B2fgh\t"))) +(ert-deftest test-json-path-to-position-with-objects () + (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}") + (matched-path (json-path-to-position 32 json-string))) + (should (equal (plist-get matched-path :path) '("foo" "bar" "baz"))) + (should (equal (plist-get matched-path :match-start) 25)) + (should (equal (plist-get matched-path :match-end) 32)))) + +(ert-deftest test-json-path-to-position-with-arrays () + (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}") + (matched-path (json-path-to-position 20 json-string))) + (should (equal (plist-get matched-path :path) '("foo" 1 0))) + (should (equal (plist-get matched-path :match-start) 18)) + (should (equal (plist-get matched-path :match-end) 23)))) + (provide 'json-tests) ;;; json-tests.el ends here -- 2.6.1 = --=-b4IqqtSK8ay5FwlaWkkt Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Sometimes when working with a JSON structure, one needs to find the
pat= h to a particular element. That can be tiresome to do manually,
e= specially if the structure is deep.

The proposed p= atch extends json.el with the ability to retrieve the
path to a p= articular JSON element.

See the following video fo= r an example of how it can be used by an
interactive command, to = show the path to the JSON element at point:


The patch follows!
=
-- Simen


From f6ddd3= b797d6b0d92a1ffa0f5db59543ac7cdc11 Mon Sep 17 00:00:00 2001
From:= =3D?UTF-8?q?Simen=3D20Heggest=3DC3=3DB8yl?=3D <simenheg@gmail.com>
Date: Sun, 25 Oct 2015 14:44:59 +0100
Subject: [PATCH] A= dd support for retrieving paths to JSON elements

A= dd support for retrieving the path to a JSON element. This can for
instance be useful to retrieve paths in deeply nested JSON
stru= ctures.

* lisp/json.el (json-path-to-position): Ne= w function for retrieving the
path to a JSON object at a given po= sition.
(json--path-to-position, json--path): New variables, used= internally by
`json-path-to-position'.
(json-read-obje= ct, json-read-array): Respect `json--path-to-position'.

* test/automated/json-tests.el (test-json-path-to-position-with-objec= ts)
(test-json-path-to-position-with-arrays): New tests for
=
`json-path-to-position'.
---
 lisp/json.el = | 67 ++++++++++++++++++++++++++++++++++++++++++--
&= nbsp;test/automated/json-tests.el | 14 +++++++++
 2 files ch= anged, 79 insertions(+), 2 deletions(-)

diff --git= a/lisp/json.el b/lisp/json.el
index b23d12a..2c82eee 100644
--- a/lisp/json.el
+++ b/lisp/json.el
@@ -196,6 += 196,49 @@ 'json-end-of-file

 =0C
+;;; Paths
+
+(defvar json--path-to-positi= on nil
+ "When set to a position, `json-read' will return the pa= th to
+the JSON element at the specified position, instead of ret= urning
+the parsed JSON object.")
+
+(defvar = json--path '()
+ "Used internally by `json-path-to-position' to = keep track of
+the path during recursive calls to `json-read'.")<= /div>
+
+(defun json-path-to-position (position &optional= string)
+ "Return the path to the JSON element at POSITION.
+
+When STRING is provided, return the path to the positio= n in the
+string, else to the position in the current buffer.
+
+The return value is a property list with the following<= /div>
+properties:
+
+:path -- A list of str= ings and numbers forming the path to
+ the JSON el= ement at the given position. Strings
+ denote obj= ect names, while numbers denote array
+ indexes.
+
+:match-start -- Position where the matched JSON eleme= nt begins.
+
+:match-end -- Position where the matche= d JSON element ends.
+
+This can for instance be useful= to determine the path to a JSON
+element in a deeply nested stru= cture."
+ (save-excursion
+ (unless string
+ (goto-char (point-min)))
+ (let* ((json--path '())
+ (json--path-to-position position)
+ = (path (catch :json-path
+ (if string
+ (json-read-from-string string)
+ = (json-read)))))
+ (when (plist-get path :path)<= /div>
+ path))))
+
 ;;; Keywords
<= div>
 (defvar json-keywords '("true" "false" "null")
@@ -399,11 +442,21 @@ json-read-object
     = ;(while (not (char-equal (json-peek) ?}))
      &n= bsp;(json-skip-whitespace)
       (setq key (= json-read-string))
+ (when json--path-to-position
= + (push key json--path))
       (json-= skip-whitespace)
       (if (char-equal (json= -peek) ?:)
           (json-advance= )
         (signal 'json-object-format (= list ":" (json-peek))))
- (setq value (json-read))
+ (json-skip-whitespace)
+ (let ((start (point)))
+ (setq value (json-read))
+ (when json--path= -to-position
+ (when (< start json--path-to-position = (+ (point) 1))
+ (throw :json-path (list :path (nrever= se json--path)
+ :match-start = start
+ :match-end (point))))<= /div>
+ (pop json--path)))
      &nbs= p;(setq elements (json-add-to-object elements key value))
  =      (json-skip-whitespace)
      &= nbsp;(unless (char-equal (json-peek) ?})
@@ -509,7 +562,17 @@ jso= n-read-array
   ;; read values until "]"
&nbs= p;  (let (elements)
     (while (not (char-eq= ual (json-peek) ?\]))
- (push (json-read) elements)
+ (json-skip-whitespace)
+ (when json--path-to-positi= on
+ (push (length elements) json--path))
+ = (let ((start (point)))
+ (push (json-read) elements)
+ (when json--path-to-position
+ (when (<= ; start json--path-to-position (+ (point) 1))
+ (throw= :json-path (list :path (nreverse json--path)
+ = :match-start start
+ = :match-end (point))))
+ (pop json--path)))
       (json-skip-whitespace)
  &n= bsp;    (unless (char-equal (json-peek) ?\])
  &nb= sp;      (if (char-equal (json-peek) ?,)
diff --gi= t a/test/automated/json-tests.el b/test/automated/json-tests.el
i= ndex d1b7a2f..e0672dd 100644
--- a/test/automated/json-tests.el
+++ b/test/automated/json-tests.el
@@ -49,5 +49,19 @@
   (should (equal (json-read-from-string "\"\\nasd\\u0444= \\u044b\\u0432fgh\\t\"")
           = ;       "\nasd=D1=84=D1=8B=D0=B2fgh\t")))

+(ert-deftest test-json-path-to-position-with-objects ()
+= (let* ((json-string "{\"foo\": {\"bar\": {\"baz\": \"value\"}}}")
+ (matched-path (json-path-to-position 32 json-string)))
+ (should (equal (plist-get matched-path :path) '("foo" "bar" "baz"))= )
+ (should (equal (plist-get matched-path :match-start) 25))<= /div>
+ (should (equal (plist-get matched-path :match-end) 32))))
+
+(ert-deftest test-json-path-to-position-with-arrays ()=
+ (let* ((json-string "{\"foo\": [\"bar\", [\"baz\"]]}")
<= div>+ (matched-path (json-path-to-position 20 json-string)))
<= div>+ (should (equal (plist-get matched-path :path) '("foo" 1 0)))
=
+ (should (equal (plist-get matched-path :match-start) 18))
+ (should (equal (plist-get matched-path :match-end) 23))))
+
 (provide 'json-tests)
 ;;; json-tests.el = ends here
--
2.6.1

= --=-b4IqqtSK8ay5FwlaWkkt-- ------------=_1447017183-23166-1-- From unknown Mon Jun 23 13:10:59 2025 X-Loop: help-debbugs@gnu.org Subject: bug#21798: 25.0.50; [PATCH] Add support for retrieving paths to JSON elements Resent-From: Dmitry Gutov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 09 Nov 2015 00:21:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 21798 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch To: Simen =?UTF-8?Q?Heggest=C3=B8yl?= Cc: 21798-done@debbugs.gnu.org Received: via spool by 21798-done@debbugs.gnu.org id=D21798.14470284377710 (code D ref 21798); Mon, 09 Nov 2015 00:21:01 +0000 Received: (at 21798-done) by debbugs.gnu.org; 9 Nov 2015 00:20:37 +0000 Received: from localhost ([127.0.0.1]:57967 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvaCJ-00020G-Kt for submit@debbugs.gnu.org; Sun, 08 Nov 2015 19:20:36 -0500 Received: from mail-wi0-f178.google.com ([209.85.212.178]:37321) by debbugs.gnu.org with esmtp (Exim 4.80) (envelope-from ) id 1ZvaCF-000206-AV for 21798-done@debbugs.gnu.org; Sun, 08 Nov 2015 19:20:31 -0500 Received: by wiva10 with SMTP id a10so24328754wiv.0 for <21798-done@debbugs.gnu.org>; Sun, 08 Nov 2015 16:20:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:subject:to:references:cc:from:message-id:date:user-agent :mime-version:in-reply-to:content-type:content-transfer-encoding; bh=sAJ8hY+evQn7aRKIGnBq8a4OTpfgnSfkdbb++q/kXog=; b=mYtntJO276bl5vBHrog0QdXQGrMWMjhVYaoFIErov3F9UAQEslN47jptqbI/qANVDZ oGYIvfj2rxRau4imUKeTyJCa6FiG6sORn9gDpmcnBQw6o+y6xQMOzonBkqhcQn2CbfLn hrveSSL4XirvB5zrtybCOIsybuZcGDWqmBwEWa1PW7yxqnSjunhDCzlYNWrOnDusDRQC l94p58+Iqp0SadiOR9A3PEv6qAMC4FClJVw45uepy+8I8g24MBbnpP3bx4zcq3TqUtW7 VNmICFqxcqjcrBj1hZ/XuRw4NPYoRHbUuECqE6z/iVb12QN+WyU51lEFdMJk8d+7Gtzb s41g== X-Received: by 10.194.10.68 with SMTP id g4mr6475848wjb.151.1447028430831; Sun, 08 Nov 2015 16:20:30 -0800 (PST) Received: from [192.168.1.2] ([185.105.175.24]) by smtp.googlemail.com with ESMTPSA id c1sm12358379wjf.19.2015.11.08.16.20.29 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 08 Nov 2015 16:20:29 -0800 (PST) References: <1446281162.2607.0@smtp.gmail.com> <5634CEE7.3070200@yandex.ru> <1446407553.4906.0@smtp.gmail.com> <1446420466.13180.0@smtp.gmail.com> <56381558.7050607@yandex.ru> <1446827488.11140.2@smtp.gmail.com> <563CE043.9060404@yandex.ru> <1446922215.4732.0@smtp.gmail.com> <563E4E73.50702@yandex.ru> <1446985933.1975.0@smtp.gmail.com> <563F7560.1000409@yandex.ru> <1447017159.19568.0@smtp.gmail.com> From: Dmitry Gutov Message-ID: <563FE6CC.7040200@yandex.ru> Date: Mon, 9 Nov 2015 02:20:28 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:42.0) Gecko/20100101 Thunderbird/42.0 MIME-Version: 1.0 In-Reply-To: <1447017159.19568.0@smtp.gmail.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit X-Spam-Score: -0.7 (/) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: debbugs-submit-bounces@debbugs.gnu.org Sender: "Debbugs-submit" X-Spam-Score: -0.7 (/) On 11/08/2015 11:12 PM, Simen Heggestøyl wrote: > I installed the previous patch with the renaming you suggested. > > Thanks for your reviews! Thank you for the code. > By the way, if you find the time, could you give bug #21616 a quick > look as well? It teaches the JSON encoder how to sort objects by their > keys. I think it would be nice to get it in before the feature freeze, > since it's the last piece of the puzzle to enable the new json-mode to > achieve feature parity with the old one. I agree, and done.