Repository: lapce/lapce
File: lapce-proxy/src/dispatch.rs (Rust)

Code before:
                .ok_or_else(|| anyhow!("can't to str"))?
                .as_str();
            let repo = v
                .name("repo")
                .ok_or_else(|| anyhow!("can't to str"))?
                .as_str();
            (host, org, repo)
        } else {
            return Err(anyhow!("can't parse remote url"));
        };

    Ok(format!(
        "https://{}/{}/{}/blob/{}/{}",
        host,
        org,
        repo,
        head.peel_to_commit()?.id(),
        file.strip_prefix(workspace_path)?.to_str().unwrap()
    ))
}

fn start_global_search_job(
    proxy_rpc: ProxyRpcHandler,
    global_search_rx: Receiver<()>,
) {
    loop {
        for _ in global_search_rx.iter() {
            let input = {
                let mut lock = GLOBAL_SEARCH_INPUT.lock();
                lock.take()
            };

            if input.is_none() {
                break;
            }

            let (id, workspace, pattern, case_sensitive) = input.unwrap();
            let result = if let Some(workspace) = workspace.as_ref() {
                let mut matches = IndexMap::new();
                let pattern = regex::escape(&pattern);
                if let Ok(matcher) = RegexMatcherBuilder::new()
                    .case_insensitive(!case_sensitive)
                    .build_literals(&[&pattern])
                {
                    let mut searcher = SearcherBuilder::new().build();
                    for path in ignore::Walk::new(workspace).flatten() {
                        if let Some(file_type) = path.file_type() {
                            if file_type.is_file() {
                                let path = path.into_path();
                                let mut line_matches = Vec::new();
                                let _ = searcher.search_path(

Review comment (suggestion):
Can someone explain why this loop is necessary here? It doesn't work if you remove it. Yet people keep telling me that it should work without it. The documentation says that the channel will yield `None` if the sender is empty AND disconnected. But our sender here lives as long as `Dispatcher` is so I don't see why it should die.

Code after:
        head: name,
        branches,
        diffs: file_diffs,
    })
}

fn file_get_head(workspace_path: &Path, path: &Path) -> Result<(String, String)> {
    let repo = Repository::open(
        workspace_path
            .to_str()
            .ok_or_else(|| anyhow!("can't to str"))?,
    )?;
    let head = repo.head()?;
    let tree = head.peel_to_tree()?;
    let tree_entry = tree.get_path(path.strip_prefix(workspace_path)?)?;
    let blob = repo.find_blob(tree_entry.id())?;
    let id = blob.id().to_string();
    let content = std::str::from_utf8(blob.content())
        .with_context(|| "content bytes to string")?
        .to_string();
    Ok((id, content))
}

fn git_get_remote_file_url(workspace_path: &Path, file: &Path) -> Result<String> {
    let repo = Repository::open(
        workspace_path
            .to_str()
            .ok_or_else(|| anyhow!("can't to str"))?,
    )?;

    let head = repo.head()?;

    let target_remote = repo.find_remote("origin")?;

    let target_remote_file_url =
        target_remote.url().ok_or_else(|| anyhow!("can't to str"))?;

    // This Regex isn't perfect, but it's good enough for now
    // git@github.com:rust-lang/rust.git
    // https://github.com/rust-lang/rust.git

    let git_repo_remote_regex = Regex::new(
        r"^(?:git@|https://)(?P<host>[^:/]+)[:/](?P<org>[^/]+)/(?P<repo>.+)$",
    )
    .unwrap();

    let (host, org, repo) =
        if let Some(v) = git_repo_remote_regex.captures(target_remote_file_url) {
            let host = v
                .name("host")
                .ok_or_else(|| anyhow!("can't to str"))?