From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= Subject: [PATCH 5/6] org-table-sort-lines: Fix case-sensitive sorting Date: Sun, 11 Mar 2018 16:43:51 +0100 Message-ID: <20180311154352.16920-5-seb@wirrsal.net> References: <20180311154352.16920-1-seb@wirrsal.net> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:51502) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ev39j-0000YM-FF for emacs-orgmode@gnu.org; Sun, 11 Mar 2018 11:45:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ev39i-0008Nd-9C for emacs-orgmode@gnu.org; Sun, 11 Mar 2018 11:45:03 -0400 Received: from wirrsal.net ([188.68.36.149]:42798 helo=mail.wirrsal.net) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ev39h-0008N8-Vh for emacs-orgmode@gnu.org; Sun, 11 Mar 2018 11:45:02 -0400 In-Reply-To: <20180311154352.16920-1-seb@wirrsal.net> List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: "Emacs-orgmode" To: emacs-orgmode@gnu.org Cc: =?UTF-8?q?Sebastian=20Reu=C3=9Fe?= * org-table.el (org-table-sort-lines): Fix case sensitive sorting, improve docstring. * test-org-table.el (test-org-table/sort-lines): Enforce C locale when testing alphabetic sorting. =E2=80=98sort-subr=E2=80=99 ignores =E2=80=98sort-fold-case=E2=80=99 when= a predicate is provided. To correctly handle case-sensitivity, we now bake it into the predicate. Since we are now sorting according to the user=E2=80=99s locale, WITH-CAS= E will not make a difference in most instances, since most locales always sort case-insensitively (cf. how GNU sort ignores the =E2=80=98-f=E2= =80=99 switch). We now mention this in the function docstring. In order to meaningfully test case-sensitive sorting, we now enforce the C locale in the respective unit test. --- lisp/org-table.el | 9 ++++---- testing/lisp/test-org-table.el | 49 +++++++++++++++++++++++-------------= ------ 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/lisp/org-table.el b/lisp/org-table.el index 316533172..5ebca54fd 100644 --- a/lisp/org-table.el +++ b/lisp/org-table.el @@ -1714,7 +1714,8 @@ (defun org-table-sort-lines in the field, or as a HH:MM value). Sorting in reverse order is also possible. =20 -With prefix argument WITH-CASE, alphabetic sorting will be case-sensitiv= e. +With prefix argument WITH-CASE, alphabetic sorting will be case-sensitiv= e +if the locale allows for it. =20 If SORTING-TYPE is specified when this function is called from a Lisp program, no prompting will take place. SORTING-TYPE must be a character= , @@ -1766,8 +1767,7 @@ (defun org-table-sort-lines ;; Determine arguments for `sort-subr'. Also record original ;; position. `org-table-save-field' cannot help here since ;; sorting is too much destructive. - (let* ((sort-fold-case (not with-case)) - (coordinates + (let* ((coordinates (cons (count-lines (point-min) (line-beginning-position)) (current-column))) (extract-key-from-field @@ -1794,7 +1794,8 @@ (defun org-table-sort-lines (predicate (cl-case sorting-type ((?n ?N ?t ?T) #'<) - ((?a ?A) #'org-string-collate-lessp) + ((?a ?A) (if with-case #'org-string-collate-lessp + (lambda (s1 s2) (org-string-collate-lessp s1 s2 nil t)))) ((?f ?F) (or compare-func (and interactive? diff --git a/testing/lisp/test-org-table.el b/testing/lisp/test-org-table= .el index d90caa8e9..873e79abb 100644 --- a/testing/lisp/test-org-table.el +++ b/testing/lisp/test-org-table.el @@ -1689,28 +1689,33 @@ (org-test-with-temp-text "| 1 | 2 |\n| 5 | 3 |\n| 2 | 4 |\n" (org-table-sort-lines nil ?N) (buffer-string)))) - ;; Sort alphabetically. - (should - (equal "| a | x |\n| B | 4 |\n| c | 3 |\n" - (org-test-with-temp-text "| a | x |\n| c | 3 |\n| B | 4 |\n" - (org-table-sort-lines nil ?a) - (buffer-string)))) - (should - (equal "| c | 3 |\n| B | 4 |\n| a | x |\n" - (org-test-with-temp-text "| a | x |\n| c | 3 |\n| B | 4 |\n" - (org-table-sort-lines nil ?A) - (buffer-string)))) - ;; Sort alphabetically with case. - (should - (equal "| C |\n| a |\n| b |\n" - (org-test-with-temp-text "| a |\n| C |\n| b |\n" - (org-table-sort-lines t ?a) - (buffer-string)))) - (should - (equal "| C |\n| b |\n| a |\n" - (org-test-with-temp-text "| a |\n| C |\n| b |\n" - (org-table-sort-lines nil ?A) - (buffer-string)))) + ;; Sort alphabetically. Enforce the C locale for consistent results. + (let ((original-string-collate-lessp (symbol-function 'string-collate-= lessp))) + (cl-letf (((symbol-function 'string-collate-lessp) + (lambda (s1 s2 &optional locale ignore-case) + (funcall original-string-collate-lessp + s1 s2 "C" ignore-case)))) + (should + (equal "| a | x |\n| B | 4 |\n| c | 3 |\n" + (org-test-with-temp-text "| a | x |\n| c | 3 |\n| B | 4 |\= n" + (org-table-sort-lines nil ?a) + (buffer-string)))) + (should + (equal "| c | 3 |\n| B | 4 |\n| a | x |\n" + (org-test-with-temp-text "| a | x |\n| c | 3 |\n| B | 4 |\= n" + (org-table-sort-lines nil ?A) + (buffer-string)))) + ;; Sort alphabetically with case. + (should + (equal "| C |\n| a |\n| b |\n" + (org-test-with-temp-text "| a |\n| C |\n| b |\n" + (org-table-sort-lines t ?a) + (buffer-string)))) + (should + (equal "| C |\n| b |\n| a |\n" + (org-test-with-temp-text "| a |\n| C |\n| b |\n" + (org-table-sort-lines nil ?A) + (buffer-string)))))) ;; Sort by time (timestamps) (should (equal --=20 2.16.2