frederik-uni / zed-cargotom

6 stars 0 forks source link

Suggestions should have better ranking #3

Open kurtbuilds opened 1 month ago

kurtbuilds commented 1 month ago

As one example, when autocompleting for axu, it shows a bunch of other packages before axum.

image

Additionally, when I've written out axum, the result axum is not at the top of the list, which I would expect (confirmation that the package I've selected actually exists (also what happens for other crates).

Expected behavior: For axu, the top result is axum.

Presumably the ranking should be based on lifetime (or last 90 days?) downloads on crates.io, but there might be a better metric.

frederik-uni commented 1 month ago

im kinda annoyed about this too. The lifetime solution isn't really possible, because the source for the crates is the crate index which does not contain the creation date. I would sort the entries by length & version count. while I developed this I noticed that sort_text is ignored.

frederik-uni commented 1 month ago

nvm sorting seems to work now. Right now it is sorting the results by crate name length. My plan is to sort them by name length, count(versions), exists in .cargo/registry & manual bias in config file for libs like serde, serde_json,...

I don't have that time right now so it could take a while until its implemented tho:

a function like this would sort the items, but I don't have time testing the weights:

fn rank_item(item: &Item, bias_list: &[String], name_weight: f64, local_weight: f64, version_weight: f64, bias_weight: f64, version_punishment: f64, log_value: f64) -> f64 {
    let name_len = item.name.len();
    let is_local = item.local;
    let versions_len = item.versions.len();

    let base_version_score = if versions_len == 1 {
        let v = &item.versions[0];
        if (v.major == 0 && v.minor == 0 && v.patch == 0) || 
           (v.major == 0 && v.minor == 1 && v.patch == 0) || 
           (v.major == 0 && v.minor == 0 && v.patch == 1) {
            -version_punishment
        } else {
            0.0
        }
    } else {
        versions_len as f64 - 1.0
    };

    let bias_bonus = if bias_list.contains(&item.name) {
        bias_weight
    } else {
        0.0
    };

    let name_score = 1.0 / name_len as f64;
    let local_score = if is_local { 1.0 } else { 0.0 };

    // let version_score = base_version_score.log(2.0);
    let version_score = base_version_score.log(log_value);
    name_weight * name_score +
    local_weight * local_score +
    version_weight * version_score +
    bias_bonus
}