# HG changeset patch # User mpm@selenic.com # Date 2005-07-01 07:19:37 # Node ID 7140bc7816555daa4649ea25c998327c5fa64a95 # Parent 411e05b04ffaeb62f490a3b50fc9ddd414777022 Add multiple keyword search to hgweb -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Add multiple keyword search to hgweb People kept pestering me about this one. Now it's done. If you type a tag/id/rev in the search box, it takes you to that entry in the changelog. If you type some other random keywords, it does a case-insensitive search through the history and returns the most recent N items. It's not super-fast, but it's serviceable. manifest hash: e8fa980dee92cf78c04051d3028da9b07a45f3de -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCxO6JywK+sNU5EO8RArAwAKCq+9qO/OL0mQxa1J7C77Z6AcZoWgCfbiDC AZ5KllldwBtdRRREn7HH6go= =sIy0 -----END PGP SIGNATURE----- diff --git a/mercurial/hgweb.py b/mercurial/hgweb.py --- a/mercurial/hgweb.py +++ b/mercurial/hgweb.py @@ -286,6 +286,68 @@ class hgweb: manifest = hex(mf), rev = pos, changesets = count, entries = changelist) + def search(self, query): + + def changelist(): + cl = self.repo.changelog + count = 0 + qw = query.lower().split() + + def revgen(): + for i in range(cl.count() - 1, 0, -100): + l = [] + for j in range(max(0, i - 100), i): + n = cl.node(j) + changes = cl.read(n) + l.insert(0, (n, j, changes)) + for e in l: + yield e + + for n, i, changes in revgen(): + miss = 0 + for q in qw: + if not (q in changes[1].lower() or + q in changes[4].lower() or + q in " ".join(changes[3][:20]).lower()): + miss = 1 + break + if miss: continue + + count += 1 + hn = hex(n) + p1, p2 = cl.parents(n) + t = float(changes[2].split(' ')[0]) + + yield self.t( + 'searchentry', + parity = count & 1, + author = changes[1], + parent1 = self.parent("changelogparent", + hex(p1), cl.rev(p1)), + parent2 = self.parent("changelogparent", + hex(p2), cl.rev(p2)), + p1 = hex(p1), p2 = hex(p2), + p1rev = cl.rev(p1), p2rev = cl.rev(p2), + manifest = hex(changes[0]), + desc = changes[4], + date = t, + files = self.listfilediffs(changes[3], n), + rev = i, + node = hn) + + if count >= self.maxchanges: break + + cl = self.repo.changelog + mf = cl.read(cl.tip())[0] + + yield self.t('search', + header = self.header(), + footer = self.footer(), + query = query, + repo = self.reponame, + manifest = hex(mf), + entries = changelist) + def changeset(self, nodeid): n = bin(nodeid) cl = self.repo.changelog @@ -586,13 +648,16 @@ class hgweb: self.t = templater(m, self.filters) if not args.has_key('cmd') or args['cmd'][0] == 'changelog': - hi = self.repo.changelog.count() - 1 + c = self.repo.changelog.count() - 1 + hi = c if args.has_key('rev'): hi = args['rev'][0] try: hi = self.repo.changelog.rev(self.repo.lookup(hi)) - except KeyError: pass - + except KeyError: + write(self.search(hi)) + return + write(self.changelog(hi)) elif args['cmd'][0] == 'changeset': diff --git a/templates/map b/templates/map --- a/templates/map +++ b/templates/map @@ -1,11 +1,13 @@ header = header.tmpl footer = footer.tmpl +search = search.tmpl changelog = changelog.tmpl naventry = "#label# " filedifflink = "#file# " filenodelink = "#file# " fileellipses = "..." changelogentry = changelogentry.tmpl +searchentry = searchentry.tmpl changeset = changeset.tmpl manifest = manifest.tmpl manifestdirentry = "drwxr-xr-x #basename#/" diff --git a/templates/search.tmpl b/templates/search.tmpl new file mode 100644 --- /dev/null +++ b/templates/search.tmpl @@ -0,0 +1,28 @@ +#header# +#repo|escape#: searching for #query|escape# + + + +
+changelog +tags +manifest +
+ +

searching for #query|escape#

+ +
+search: + + +
+ +#entries# + +
+search: + + +
+ +#footer# diff --git a/templates/searchentry.tmpl b/templates/searchentry.tmpl new file mode 100644 --- /dev/null +++ b/templates/searchentry.tmpl @@ -0,0 +1,22 @@ +
+ + + + + + + +#parent1# +#parent2# + + + + + + + + + +
#date|age# ago: #desc|firstline|escape#
changeset #rev#: #node|short#
author: #author|obfuscate#
date: #date|date#
files#files#
+
+