Subject: Re: bug#41706: 26.1; sort-subr predicate cannot be set successfully

From: Marvin Gülker <[email-masked]>
Date: Thu, 4 Jun 2020 21:05:26 +0200

Am 04. Juni 2020 um 14:11 Uhr +0200 schrieb Michael Heerdegen:
>I think you use it wrong: the keys are not strings but cons cells.  So
>the predicate function should be something like
>`compare-buffer-substrings'.

You are correct. Your comment put me on the right track (but see below). 
This version works and sorts the lines according to the locale's rules:

    (defun my-sort-lines-collate (reverse beg end)
     (interactive "P\nr")
     (save-excursion
       (save-restriction
         (narrow-to-region beg end)
         (goto-char (point-min))
         (let ;; To make `end-of-line' and etc. to ignore fields.
             ((inhibit-field-text-motion t))
           (sort-subr
            reverse 'forward-line 'end-of-line nil nil
            (lambda (a b) (string-collate-lessp (buffer-substring (car a) (cdr a)) (buffer-substring (car b) (cdr b)))))))))

I have broken it slightly different for readability. The change I did was 
to use `buffer-substring' in the predicate lambda. It was not clear to me 
that the arguments given to the predicate function are actually buffer 
positions and not the buffer substrings themselves as I expected. This 
is not explained in the manual (section § 32.15) on `sort-subr').

>To understand how ‘sort-subr’ works, consider the whole accessible
>portion of the buffer as being divided into disjoint pieces called
>“sort records”.  The records may or may not be contiguous, but they
>must not overlap.  A portion of each sort record (perhaps all of
>it) is designated as the sort key. [...]
>The argument PREDICATE is the function to use to compare keys.  If
>keys are numbers, it defaults to ‘<’; otherwise it defaults to
>string<’.

No further mention of how to use PREDICATE is made, and the manual 
continues with reproducing the source code of `sort-lines'. I took that 
section to mean that the PREDICATE is in the default case `<' and 
with strings `string<'. From the manual's text it became not clear to me 
under which condition the keys are not strings, and I assumed they will 
normally always be strings as buffer substrings are always strings.

Now I see that the documentation for the `sort-subr' function is a 
little more specific, but still it doesn't really make clear which kind 
of "key" is received as arguments in the PREDICATE under which 
conditions. The call above appearently yields cons cell keys whose CAR 
and CDR correspond to buffer positions, but the documentation makes me 
suspect that calling `sort-subr' differently will yield other kinds of 
keys.

I would suggest to amend the manual to be more precise about the 
arguments that PREDICATE receives, and perhaps add an example.

Thank you for your explanation.

-- 
Blog: https://mg.guelker.eu