From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: =?utf-8?Q?Etienne_Prud=E2=80=99homme?= Newsgroups: gmane.emacs.devel Subject: Re: Easy traversal of customize groups Date: Fri, 23 Jun 2017 18:56:25 -0400 Message-ID: <878tkiia92.fsf@x230.lts> References: <87mv8yipav.fsf@x230.lts> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1498258629 15865 195.159.176.226 (23 Jun 2017 22:57:09 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 23 Jun 2017 22:57:09 +0000 (UTC) User-Agent: Emacs/25.2 (gnu/linux) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Jun 24 00:57:05 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dOXVg-0003nO-Qm for ged-emacs-devel@m.gmane.org; Sat, 24 Jun 2017 00:57:05 +0200 Original-Received: from localhost ([::1]:37550 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dOXVk-00030n-6l for ged-emacs-devel@m.gmane.org; Fri, 23 Jun 2017 18:57:08 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:35916) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dOXV9-00030h-1V for emacs-devel@gnu.org; Fri, 23 Jun 2017 18:56:32 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dOXV5-0002FP-TE for emacs-devel@gnu.org; Fri, 23 Jun 2017 18:56:31 -0400 Original-Received: from mail-qt0-x22e.google.com ([2607:f8b0:400d:c0d::22e]:32770) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dOXV5-0002FD-Nc for emacs-devel@gnu.org; Fri, 23 Jun 2017 18:56:27 -0400 Original-Received: by mail-qt0-x22e.google.com with SMTP id u12so45018520qth.0 for ; Fri, 23 Jun 2017 15:56:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-transfer-encoding; bh=NJeRuoZVIoeRNOZoN0Q1SLTQbbzxtlp160Pcj+jmP+E=; b=HPBENaXBuRkpMS5CffG51U9kbbxSEXNG6Wkeg08AuJlWsS4AQrueZx+60OuwPueH9f gb3G+Bmf5F/HDo2J/jrBeHFO5MxBtulb4KaYZJert30vpO/f8UD9MwcomTALmpp0i7YV jL8MUySmzWFtkPoTVj8AgH0aRHjRYYbL2HPfGbDvH9rkK0DTXQ13XzPyxBH4t4hw4cTw YAzlQy+8qy5ibBvoCu7y6v1oBynFB6ExpE1qBLI2QXADviP/bAo3j5f45rlaxqs3c/lU D4loMi5AT07rxcvlOlJbegEGXSaLER/jgeZwZYLkPZu55HEkWWRM8wxEZqnoYzW4k59i VlRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:references:date:in-reply-to :message-id:user-agent:mime-version:content-transfer-encoding; bh=NJeRuoZVIoeRNOZoN0Q1SLTQbbzxtlp160Pcj+jmP+E=; b=T7y7JyZx3CItKTuNam7vVgPv5lJ/5XWtDg1kjqknSFnx5vOsYpzMSFIFJxYTMRuON9 EgTkKT6v0r/sbF4QI2BKLShEK3MSDcdFbVgOPleWmDDarYf7wEjDyJakWWMbOs1udXUC W1zdiRmYB2g1xcy1aYyQzisvdBAmB0Iuu8ISosZ7ztwbLZB+ifNinYOL9KVyQlgKdSWg xF9FNjhUkllFCyhBaKHKp7c/4xJovFrz1vEIoIcEysIozwaOI4opS852CIg0qGQtAg0B te/xbvJAKLoSqBkaZlTcqcjIukUPXN0hcod8VbJFxb4RZ2dxAiU01wYC+mTlGHWSl+7B 7qZQ== X-Gm-Message-State: AKS2vOyB2p/q5zAKafXPEtysnETOTN9PjUz5gIrlDsqRh/21vb7GOUlF gJZ0TY0cCRsHBg== X-Received: by 10.200.51.125 with SMTP id u58mr7468629qta.12.1498258586906; Fri, 23 Jun 2017 15:56:26 -0700 (PDT) Original-Received: from localhost (modemcable232.49-20-96.mc.videotron.ca. [96.20.49.232]) by smtp.gmail.com with ESMTPSA id t13sm4468314qtc.22.2017.06.23.15.56.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 23 Jun 2017 15:56:26 -0700 (PDT) In-Reply-To: (Stefan Monnier's message of "Fri, 23 Jun 2017 16:34:31 -0400") X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400d:c0d::22e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:215920 Archived-At: Stefan Monnier writes: > Another option is to perform one mapatoms traversal which builds a cache > of the "reverse links" and then use that. That=E2=80=99s also a solution. Were you talking about a tree structure? It think it might over complicate the current implementation since we would have to remove an entry from the cache when it is unloaded and we would have to update each possible paths when a new group is loaded. Here=E2=80=99s a snippet of what I=E2=80=99m using: > (require 'seq) >=20 > (defun custom-group-parent-group-p (group parent) > "Test that GROUP is a direct child of PARENT." > (eq 'custom-group (car (alist-get group (get parent 'custom-group))))) >=20 > (defun custom-group-parent-groups (group) > "Return a list of parent groups for GROUP. >=20 > E.g. =E2=80=9Cwdired=E2=80=9D would return =E2=80=9C(dired)=E2=80=9D. >=20 > Note: This function has much faster implementation of finding > parents than using `custom-group-parent-group-p'. Around 10x > faster than mapping with `custom-group-parent-group-p'." > (let ((parents)) > ;; First find the =E2=80=9Cgroup=E2=80=9D a-list candidates. > (mapatoms (lambda (symbol) > (when (alist-get group (get symbol 'custom-group)) > (setq parents (cons symbol parents)))) > obarray) > ;; Than filter =E2=80=9Cgroup=E2=80=9D a-list candidates to only show= `custom-group' > ;; symbol properties. > (seq-filter (lambda (value) > (eq (car (alist-get group (get value 'custom-group))) 'cust= om-gr> oup)) > parents))) >=20 > (defun custom-group-get-paths (group) > "Get an ordered list on the parent paths for GROUP. >=20 > The path is in the form of: > \((files dired wdired) > (environment dired wdired)) >=20 > Where =E2=80=9Cfiles=E2=80=9D is the topmost parent group of the =E2=80= =9Cwdired=E2=80=9D > group (without counting an orphan or the Emacs group)." > (let ((tree (custom-group--get-tree group)) > (paths) > (custom-group-get--paths)) > (setq custom-group-get--paths > (lambda (nodes path) > "Private. >=20 > Go through all possible NODES and add the PATH to the `paths' variable." > (message (prin1-to-string nodes)) > (let ((newpath (if (listp path) > path > (list path))) > (newnodes (cadr nodes))) > (unless (eq nil (car nodes)) > (push (car nodes) newpath)) > (if newnodes > (dolist (node newnodes) > (funcall custom-group-get--paths node newpath)) > (add-to-list 'paths newpath))))) > (funcall custom-group-get--paths tree nil) > paths)) >=20 > (defun custom-group--get-tree (group) > "Private. >=20 > Get a tree on the parent paths for GROUP. >=20 > The following tree: > =E2=95=94=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=97 > =E2=95=91 files =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=90 =E2=95=91 > =E2=95=91 =E2=94=9C=E2=94=80=E2=94=80=E2=94=80 dired =E2= =94=80=E2=94=80=E2=94=80 wdired =E2=95=91 > =E2=95=91 environment =E2=94=80=E2=94=80=E2=94=80=E2=94=98 = =E2=95=91 > =E2=95=9A=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=9D >=20 > Would give the expression: > =E2=95=94=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=97 > =E2=95=91 (wdired ((dired ((environment (nil)) (files (nil)))))) =E2=95=91 > =E2=95=9A=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=9D >=20 > Where nil either represent no more parent or the Emacs group." > (let ((parents (custom-group-parent-groups group)) > (tree)) > (unless (or (eq nil group) (eq 'emacs group)) > (cons group > (list > (dolist (parent parents tree) > (push (custom-group--get-tree parent) tree))))))) =20 As an example, if we get =E2=80=9Cmessage-forwarding=E2=80=9D:=20 > (require 'gnus) > (require 'message) > (custom-group-get-paths 'message-forwarding) It becomes quite a large tree: > (message-forwarding > ((message-interface > ((message > ((news > ((applications (nil)))) > (mail ((applications (nil)))) > (gnus-message > ((gnus > ((news ((applications (nil)))) > (mail ((applications (nil)))))))))))))) Where =E2=80=9Cnil=E2=80=9D is the Emacs group node. We could of course map their parents instead of making a tree structure, but it=E2=80=99s almost the same way my suggestion works. I=E2=80=99m proposing to change the =E2=80=9Ccustom-declare-group=E2=80=9D = function to add links to the parent groups wen defining a new group. -- Etienne