Merge: Model index
authorJean Privat <jean@pryen.org>
Wed, 24 Aug 2016 18:02:48 +0000 (14:02 -0400)
committerJean Privat <jean@pryen.org>
Wed, 24 Aug 2016 18:02:48 +0000 (14:02 -0400)
commit0d45be1fdc51fd104e03aa08a6081af507a835ba
tree2e1e370858af85e68e02ceaebd528bd47c6a349c
parent7e3a73ceb584bbac76b73da33ac6120b89629a9b
parent14263ff2c7fc1507aba2227f8e644c52cfd5f426
Merge: Model index

## Search things from the Model

ModelIndex allows you to index mentities then retrieve them by their `name`
or `full_name`.
It offers a set of `find_*` methods that can be used to match queries
against entities name.

Because each use is different, ModelIndex only provide base raw search services.
All of them return IndexMatches that can be ordered and filtered by the client.

## Indexing mentities

Before searching something from the ModelIndex, you have to index it.
Use the `ModelIndex::index` method to do that:

~~~nit
var index = new ModelIndex

for mentity in model.private_view.mentities do
index.index(mentity)
end
~~~

## Search mentities

You can then run queries on the ModelIndex:

~~~nit
for res in index.find("Array").limit(10) do
   print res
end
~~~

## Examples

Here some examples of how you can use the ModelIndex.

### Smart type prediction

Use ModelIndex to implement a smart prediction system based on the typed prefix:

~~~nit
var index = new ModelIndex

for mentity in model.private_view.mentities do
# We don't really care about definitions
if mentity isa MClassDef or mentity isa MPropDef then continue
index.index(mentity)
end

var typed_prefix = "Arr"
for res in index.find_by_name_prefix(typed_prefix).
uniq. # keep only the best ranked mentity
limit(5). # limit to ten results
sort(new VisibilityComparator, new NameComparator) do # order by visibility then name
   print res
end
~~~

Will output something like:

~~~raw
Array (1)
ArraySet (2)
ArrayMap (3)
ArrayCmp (4)
ArrayMapKeys (5)
~~~

### Method autocompletion

Find methods from a class full_name:

~~~nit
var class_full_name = "core::Array"
for res in index.find_by_full_name_prefix("{class_full_name}::").
uniq. # keep only the best ranked mentity
sort(new VisibilityComparator). # put private in the bottom of the list
limit(5). # limit to ten results
sort(new FullNameComparator) do # order by lexicographic order
   print res
end
~~~

Will output something like:

~~~raw
* (2)
+ (1)
filled_with (5)
from (3)
with_items (4)
~~~

### Name typo detection and suggestion

Detect unknown names and suggest corrections:

~~~nit
var name = "Zrray"

if index.find_by_name_prefix(name).is_empty then
printn "`{name}` not found, did you mean: "
printn index.find_by_name_similarity(name).sort(new ScoreComparator).limit(2).join(" or ")
print "?"
end
~~~

Will output something like:

~~~raw
`Zrray` not found, did you mean: Array (1) or array (1)?
~~~

The next version of Nitweb will use ModelIndex for the search field. Demo here: http://nitweb.moz-code.org/

Pull-Request: #2280
Reviewed-by: Jean Privat <jean@pryen.org>