Subject: Re: bug#58136: [PATCH] ui: Improve sort order when searching package names.

From: Ludovic Courtès <[email-masked]>
Date: Mon, 17 Oct 2022 09:46:28 +0200

Hi!

Lars-Dominik Braun <[email-masked]> skribis:

> diff --git a/guix/packages.scm b/guix/packages.scm
> index 94e464cd01..9934501cdb 100644
> --- a/guix/packages.scm
> +++ b/guix/packages.scm
> @@ -86,6 +86,7 @@ (define-module (guix packages)
>              this-package
>              package-name
>              package-upstream-name
> +            package-upstream-name*
>              package-version
>              package-full-name
>              package-source
> @@ -657,6 +658,38 @@ (define (package-upstream-name package)
>    (or (assq-ref (package-properties package) 'upstream-name)
>        (package-name package)))
>  
> +(define (package-upstream-name* package)
> +  "Return the upstream name of PACKAGE, which could be different from the name
> +it has in Guix."

s/which could.*Guix/accounting for commonly-used package name prefixes
in addition to the @code{upstream-name} property/

Preferably make this addition in a separate commit.

> +++ b/guix/ui.scm
> @@ -1623,10 +1623,23 @@ (define (relevance obj regexps metrics)
>    (define (score regexp str)
>      (fold-matches regexp str 0
>                    (lambda (m score)
> -                    (+ score
> -                       (if (string=? (match:substring m) str)
> -                           5             ;exact match
> -                           1)))))
> +                    (let* ((start (- (match:start m) 1))
> +                           (end (match:end m))
> +                           (left (if (>= start 0) (string-ref str start) #f))
> +                           (right (if (< end (string-length str)) (string-ref str end) #f))
> +                           (delimiter-classes '(Cc Cf Pd Pe Pf Pi Po Ps Sk Zs Zl Zp))
> +                           (delim-left (or (member (and=> left char-general-category) delimiter-classes) (eq? left #f)))
> +                           (delim-right (or (member (and=> right char-general-category) delimiter-classes) (eq? right #f))))
> +                      (max score
> +                        (cond
> +                          ;; regexp is a full match for str.
> +                          ((and (eq? left #f) (eq? right #f)) 4)
> +                          ;; regexp matches a single word in str.
> +                          ((and delim-left delim-right) 3)
> +                          ;; regexp matches the beginning or end of a word in str.
> +                          ((or delim-left delim-right) 2)
> +                          ;; Everything else.
> +                          (#t 1)))))))

The intent is to have all regexps behave as if the user passed \<STR\>,
is that right?  Would be nice to have a comment clarifying that above
and perhaps making it a separate change?

Stylistic notes:

  (if cond consequent #f)  =>  (and cond consequent)
  (eq? x #f)               =>  (not x)
  (cond … (#t x))          =>  (cond … (else x))

> @@ -1635,10 +1648,11 @@ (define (regexp->score regexp)
>                  ((field . weight)
>                   (match (field obj)
>                     (#f  relevance)
> +                   ('() relevance)
>                     ((? string? str)
> -                    (+ relevance (* (score-regexp str) weight)))
> +                    (max relevance (* (score-regexp str) weight)))
>                     ((lst ...)
> -                    (+ relevance (* weight (apply + (map score-regexp lst)))))))))
> +                    (max relevance (* weight (apply max (map score-regexp lst)))))))))

Intuitively I would expect scores to add up, otherwise we’re kinda
losing information; so I would not make this change.  WDYT?

There’s a test for ‘package-relevance’ in tests/ui.scm.  Please make
sure it still passes and ideally add relevant tests such as the CSV
example you gave.

Thanks!

Ludo’.