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." + (let ((namespaces (list "cl-" + "ecl-" + "emacs-" + "ghc-" + "go-" + "guile-" + "java-" + "julia-" + "lua-" + "minetest-" + "node-" + "ocaml-" + "perl-" + "python-" + "r-" + "ruby-" + "rust-" + "sbcl-" + "texlive-")) + (name (package-name package))) + (or (assq-ref (package-properties package) 'upstream-name) + (let loop ((prefixes namespaces)) + (match prefixes + ('() name) + ((prefix rest ...) + (if (string-prefix? prefix name) + (substring name (string-length prefix)) + (loop (cdr prefixes))))))))) + (define (hidden-package p) "Return a \"hidden\" version of P--i.e., one that 'fold-packages' and thus, user interfaces, ignores." diff --git a/guix/ui.scm b/guix/ui.scm index dad2b853ac..da16a50f9f 100644 --- a/guix/ui.scm +++ 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))))))) (define (regexp->score regexp) (let ((score-regexp (lambda (str) (score regexp str)))) @@ -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))))))))) 0 metrics))) (let loop ((regexps regexps) @@ -1655,7 +1669,8 @@ (define (regexp->score regexp) (define %package-metrics ;; Metrics used to compute the "relevance score" of a package against a set ;; of regexps. - `((,package-name . 4) + `((,package-name . 5) + (,package-upstream-name* . 1) ;; Match against uncommon outputs. (,(lambda (package)