From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Jean Louis Newsgroups: gmane.emacs.help Subject: Re: Format of lists and alists required for displaying lists of tabulated data Date: Sat, 24 Jun 2023 22:19:21 +0300 Message-ID: References: <648d6296.050a0220.f0b55.8bfc@mx.google.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="36283"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mutt/2.2.10+64 (b470a9a) (2023-06-05) Cc: Christopher Dimech , Bruno Barbier , uzibalqa via Users list for the GNU Emacs text editor To: uzibalqa Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Sat Jun 24 21:20:44 2023 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qD8oN-0009Gb-GA for geh-help-gnu-emacs@m.gmane-mx.org; Sat, 24 Jun 2023 21:20:43 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qD8nP-0005hD-Si; Sat, 24 Jun 2023 15:19:43 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qD8nO-0005gq-3g for help-gnu-emacs@gnu.org; Sat, 24 Jun 2023 15:19:42 -0400 Original-Received: from stw1.rcdrun.com ([217.170.207.13]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qD8nI-0004jZ-Eu for help-gnu-emacs@gnu.org; Sat, 24 Jun 2023 15:19:38 -0400 Original-Received: from localhost ([::ffff:41.75.178.229]) (AUTH: PLAIN admin, TLS: TLS1.3,256bits,ECDHE_RSA_AES_256_GCM_SHA384) by stw1.rcdrun.com with ESMTPSA id 0000000000103870.00000000649741C5.00000433; Sat, 24 Jun 2023 12:19:32 -0700 Mail-Followup-To: uzibalqa , Christopher Dimech , Bruno Barbier , uzibalqa via Users list for the GNU Emacs text editor Content-Disposition: inline In-Reply-To: Received-SPF: pass client-ip=217.170.207.13; envelope-from=bugs@gnu.support; helo=stw1.rcdrun.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.help:144033 Archived-At: * uzibalqa [2023-06-21 13:46]: > It works indeed. But instead of just a dyad (a key and value), I > want to handle an arbitrary number of values. I am always inside tabulated-list-mode as I use heavily my software: RCD Notes & Hyperscope for GNU Emacs, which may not be easy to install. So I have made functions making my life easy. Let me point out what I mean. Let us say I wish to find who introduced the person in the list: (defun cf-people-jump-to-introducer (&optional id) "Jump to introducer of person with ID" (interactive) (when-tabulated-id "people" (let ((introducer (rcd-db-get-entry "people" "people_introducedby" id cf-db))) (cond (introducer (cf-people-by-id-list (list introducer))) (t (rcd-warning-message "Cannot find introducer for person with ID %s" id)))))) I am pointing now to the function `cf-people-by-id-list'. The rest is only finding the ID of introducer, and then that function is opening that contact of introducer. Let us say I need people by their relation type: (defun cf-people-by-relation-type (&optional id) "List of people by relation type ID." (interactive) (when-tabulated-id "relationtypes" (let* ((id-list (rcd-sql-list "SELECT peoplerelations_people1 FROM peoplerelations WHERE peoplerelations_relationtypes = $1" cf-db id)) (relation-name (rcd-db-get-entry "relationtypes" "relationtypes_name" id cf-db)) (title (format "People with relation `%s'" relation-name))) (cf-people-by-id-list id-list title)))) Then that function `cf-by-people-id-list` does something more complex: (defun cf-people-by-id-list (list &optional title refresh-function return-function) (rcd-db-log-function 'cf-people-by-id-list) (let* ((limit (or (cf-user-number-of-latest-entries) cf-people-list-limit)) (refresh-function (or refresh-function (lambda () (cf-people-by-id-list list)))) (list (cond ((> (length list) limit) (seq-subseq list 0 limit)) (t list))) (sql-id-list (rcd-sql-id-list list))) (cond (list (let ((sql (format "SELECT DISTINCT ON (people_id) people_id, get_full_contacts_name(people_id), coalesce((SELECT get_contacts_name(peoplerelations_people2) FROM peoplerelations WHERE peoplerelations_people1 = people_id ORDER BY peoplerelations_default, peoplerelations_id LIMIT 1), '>>>UNKNOWN<<<') FROM people WHERE people_id IN (%s) ORDER BY people_id DESC" sql-id-list)) (title (or title "People")) (gc-cons-threshold 500000000)) (rcd-message "Fetching list of people") (prog2 (rcd-db-sql-report title sql cf-people-tabulated-format-with-people-list "people" nil refresh-function '(">>>UNKNOWN<<<") return-function) (rcd-message "Total of %s %s" (rcd-propertize-bold (number-to-string (length list))) (rcd-propertize-bold "people"))))) (t (rcd-warning-message (cond (title (format "NO REPORT FOR: %s" title)) (t "NO REPORT FOR PEOPLE LIST"))))))) So by using that function I am making 2 SQL calls, it could be faster if I am not using that function, right now there are no noticable differences. However, it is not really arbitrary data, a there is format `cf-people-tabulated-format-with-people-list' which is always used for table `people': cf-people-tabulated-format-with-people-list ➜ [("ID" 8 rcd-tabulated-number-as-string-predicate) ("Name" 40 t) ("List of people" 40 t)] To make it more arbitrary one would need to make dynamic format for tabulated-list-mode, it means your program should figure out how many columns are there and what are columns names, and maybe even their width. I think I do not have that possibility currently. What I have are database table combined views or "combos", so for each table I am sometimes automatically generating the combo view, which has it's ID and NAME, and then I can edit the entry with arbitrary number of lines. Not arbitrary number of columns, even though that is possible too. For example, I have the entry like: 33446 countries Country public table maddox 32 kB then I press "l" for the list, and I get: 1 AFGHANISTAN 2 ÅLAND ISLANDS 3 ALBANIA 4 ALGERIA 5 AMERICAN SAMOA 6 ANDORRA 7 ANGOLA 8 ANGUILLA 9 ANTARCTICA 10 ANTIGUA AND BARBUDA 11 ARGENTINA then on some of those entries I press `e' to edit: ID 5 Country "AMERICAN SAMOA" Code "AS" Dialing Prefix 1 Apostille nil Offshore nil Continent nil Company registration nil CRS t Tag #1 nil Tag #2 nil Tag #3 nil EU Member nil Flag image nil Schengen nil Flag emoji nil Potential Schengen nil so that is arbitrary number of rows, not columns, as in some other list: 1 Europe 2 Africa 3 North America 4 South America 5 Asia 6 Australia 7 Antarctica I would get different rows: ID 2 Name "Africa" Area km^2 30370000.0 Description nil However, in the same manner one can make a function to recognize number of columns. -- Jean Take action in Free Software Foundation campaigns: https://www.fsf.org/campaigns In support of Richard M. Stallman https://stallmansupport.org/