2025-02-11

普通のGitHubのリポジトリのコードではパーマリンクをコマンドから取得できるのだが、GHESだと何かがうまくいかない。エラーメッセージは以下。

Failed to copy permalink: failed to parse Git remote URL

おそらくremoteのドメイン名がハードコードされているとかだろう。

該当のエラーメッセージを出力しているのはここみたい。

https://github.com/zed-industries/zed/blob/2e7bb11b7d5de6a79bef2491fa5ce8ecfd2bca15/crates/project/src/buffer_store.rs#L1673-L1675

そしてそこで呼ばれているのがこれ

https://github.com/zed-industries/zed/blob/2e7bb11b7d5de6a79bef2491fa5ce8ecfd2bca15/crates/git/src/hosting_provider.rs#L168-L184

pub fn parse_git_remote_url(
    provider_registry: Arc<GitHostingProviderRegistry>,
    url: &str,
) -> Option<(
    Arc<dyn GitHostingProvider + Send + Sync + 'static>,
    ParsedGitRemote,
)> {
    provider_registry
        .list_hosting_providers()
        .into_iter()
        .find_map(|provider| {
            provider
                .parse_remote_url(url)
                .map(|parsed_remote| (provider, parsed_remote))
        })
}

正しくURLをパースできるhosting providerが存在しないのでエラーになっていそう。Hosting providerは以下で設定されている。

https://github.com/zed-industries/zed/blob/2e7bb11b7d5de6a79bef2491fa5ce8ecfd2bca15/crates/git_hosting_providers/src/git_hosting_providers.rs#L11-L38

/// Initializes the Git hosting providers.
pub fn init(cx: &App) {
    let provider_registry = GitHostingProviderRegistry::global(cx);
    provider_registry.register_hosting_provider(Arc::new(Bitbucket));
    provider_registry.register_hosting_provider(Arc::new(Codeberg));
    provider_registry.register_hosting_provider(Arc::new(Gitee));
    provider_registry.register_hosting_provider(Arc::new(Github));
    provider_registry.register_hosting_provider(Arc::new(Gitlab::new()));
    provider_registry.register_hosting_provider(Arc::new(Sourcehut));
}

/// Registers additional Git hosting providers.
///
/// These require information from the Git repository to construct, so their
/// registration is deferred until we have a Git repository initialized.
pub fn register_additional_providers(
    provider_registry: Arc<GitHostingProviderRegistry>,
    repository: Arc<dyn GitRepository>,
) {
    let Some(origin_url) = repository.remote_url("origin") else {
        return;
    };

    if let Ok(gitlab_self_hosted) = Gitlab::from_remote_url(&origin_url) {
        provider_registry.register_hosting_provider(Arc::new(gitlab_self_hosted));
    }
}

ここでgithub.com以外の処理を諦めている。

https://github.com/zed-industries/zed/blob/2e7bb11b7d5de6a79bef2491fa5ce8ecfd2bca15/crates/git_hosting_providers/src/providers/github.rs#L111-L128

現在のプロジェクトがどのGitHostingProviderを使っているかを誰も管理していない(?)ぽくて、外部からそれに依存した操作をする際は、GitHostingProviderRegistryに登録されたもの全てを試してうまくいった結果を使う、としているのがよくなさそう。以下のように作りを変えると良いだろう。

あるいは拡張機能としてねじ込むのが正解か?GitHubとGitHub Enterprise Serverの違いがどんなものか次第でもあるので、そちらの調査もしたい。

LSPサーバがある前提で、そのクライアントをZedに追加する。PythonのLSPクライアントの実装があるので、それを参考にbuf LSPを使えるようにする。

https://github.com/rgbkrk/python-lsp-zed-extension/blob/main/src/python_lsp.rs

何も理解してないけどローカルでクライアントをビルドして定義ジャンプを実行するところまではできた。次は何が起きているかを調べていい感じにする。 zedにマージするまでがゴール。

Zed extensionを理解して、gitのアレをextensionとして実現できないか判断したい。