From 2ea6722383c03ac44ade7679cb90748ddb8e070c Mon Sep 17 00:00:00 2001 From: Sorawee Porncharoenwase Date: Sun, 23 Feb 2020 02:36:53 -0500 Subject: [PATCH] Feat: prioritize search result --- src/packages.rkt | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/packages.rkt b/src/packages.rkt index e36a24c..c631aa3 100644 --- a/src/packages.rkt +++ b/src/packages.rkt @@ -290,20 +290,35 @@ ;; to do this at package save time, but this will do for now. (pkg->searchable-text pkg))))) +;; prioritize-search :: string? (listof symbol?) -> (listof symbol?) +;; Precondition: names are sorted ascendingly +;; Postcondition: names are reordered so that exact match is prioritized first +;; followed by those whose prefix matches the search text, +;; followed by those that contain the search text, +;; followed by other results +(define (prioritize-search text names) + (match-define-values (prefixing non-prefixing) + (partition (λ (name) (string-prefix? (symbol->string name) text)) names)) + (match-define-values (containing non-containing) + (partition (λ (name) (string-contains? (symbol->string name) text)) non-prefixing)) + (append prefixing containing non-containing)) + (define (package-search text tags) (define res (map (lambda (r) (regexp (regexp-quote r #f))) (string-split text))) (define packages (manager-rpc 'packages)) - (sort-package-names - (filter (lambda (package-name) - (define pkg (hash-ref packages package-name)) - (andmap (package-text-matches? pkg) res)) - (hash-keys - (for/fold ((ps packages)) ((tag-spec tags)) - (match-define (list tag-name include?) tag-spec) - (for/hash (((package-name pkg) (in-hash ps)) - #:when (and (not (tombstone? pkg)) - ((if include? values not) (@ref (@ pkg search-terms) tag-name)))) - (values package-name pkg))))))) + (prioritize-search + text + (sort-package-names + (filter (lambda (package-name) + (define pkg (hash-ref packages package-name)) + (andmap (package-text-matches? pkg) res)) + (hash-keys + (for/fold ((ps packages)) ((tag-spec tags)) + (match-define (list tag-name include?) tag-spec) + (for/hash (((package-name pkg) (in-hash ps)) + #:when (and (not (tombstone? pkg)) + ((if include? values not) (@ref (@ pkg search-terms) tag-name)))) + (values package-name pkg)))))))) (define (packages-jsexpr) (manager-rpc 'packages))