@@ -4,9 +4,10 @@ use octocrab::models::{Author, Repository};
44use octocrab:: params:: State ;
55use octocrab:: Octocrab ;
66use ropey:: Rope ;
7- use tower_lsp:: jsonrpc:: Result ;
7+ use tower_lsp:: jsonrpc:: { self , Result } ;
88use tower_lsp:: lsp_types:: {
9- CompletionItem , CompletionTextEdit , MessageType , Range , TextDocumentItem , TextEdit ,
9+ CompletionItem , CompletionTextEdit , Hover , HoverContents , MarkupContent , MarkupKind ,
10+ MessageType , Range , TextDocumentItem , TextEdit ,
1011} ;
1112use tower_lsp:: { lsp_types:: Position , Client } ;
1213
@@ -31,6 +32,20 @@ pub struct Backend {
3132impl Backend {
3233 const PER_PAGE : u8 = 100 ;
3334
35+ pub fn new ( client : Client , octocrab : Octocrab , owner : String , repo : String ) -> Backend {
36+ Backend {
37+ client,
38+ octocrab,
39+ owner,
40+ repo,
41+ document_map : DashMap :: new ( ) ,
42+ repository_map : DashMap :: new ( ) ,
43+ issue_map : DashMap :: new ( ) ,
44+ member_map : DashMap :: new ( ) ,
45+ wiki_map : DashMap :: new ( ) ,
46+ }
47+ }
48+
3449 pub ( crate ) async fn initialize ( & self ) {
3550 self . initialize_issues ( ) . await ;
3651 self . initialize_members ( ) . await ;
@@ -39,6 +54,63 @@ impl Backend {
3954 self . initialize_wiki ( ) . await ;
4055 }
4156
57+ pub async fn on_hover ( & self , link : String ) -> Result < Option < Hover > > {
58+ let mut text = String :: new ( ) ;
59+ //FIX: probably will cause issues for someone, maybe?
60+ if link. contains ( "github.com" ) {
61+ let link = link. replace ( "https://github.com/" , "" ) ;
62+ let parts = link. split ( '/' ) ;
63+ let identifier = parts
64+ . last ( )
65+ . ok_or ( "No issue part in URL" )
66+ . map_err ( |_| jsonrpc:: Error :: method_not_found ( ) ) ?;
67+ if link. contains ( "issues" ) {
68+ let issue = self
69+ . issue_map
70+ . iter ( )
71+ . filter ( |issue| issue. get_label ( ) . starts_with ( & format ! ( "#{} " , identifier) ) )
72+ . last ( )
73+ . ok_or ( "No issue" )
74+ . map_err ( |_| jsonrpc:: Error :: method_not_found ( ) ) ?;
75+ text = issue. get_detail ( ) . to_string ( ) ;
76+ } else if link. contains ( "wiki" ) {
77+ text = format ! ( "# Wiki article {}" , identifier) ;
78+ } else if link. contains ( '/' ) {
79+ let repository = self
80+ . repository_map
81+ . iter ( )
82+ . filter ( |repo| repo. get_label ( ) == link)
83+ . last ( )
84+ . ok_or ( "No repo" )
85+ . map_err ( |_| jsonrpc:: Error :: method_not_found ( ) ) ?;
86+ text = repository. get_detail ( ) . to_string ( ) ;
87+ } else {
88+ let users = octocrab:: instance ( )
89+ . search ( )
90+ . users ( identifier)
91+ . per_page ( 1 )
92+ . page ( 0u32 )
93+ . send ( )
94+ . await
95+ . map_err ( |_| {
96+ tower_lsp:: jsonrpc:: Error :: new (
97+ tower_lsp:: jsonrpc:: ErrorCode :: MethodNotFound ,
98+ )
99+ } ) ?;
100+ let user = & users. items [ 0 ] ;
101+ text = format ! ( "# User {}" , user. login. to_owned( ) ) ;
102+ }
103+ }
104+ let hover = Hover {
105+ contents : HoverContents :: Markup ( MarkupContent {
106+ kind : MarkupKind :: Markdown ,
107+ value : text,
108+ } ) ,
109+ range : None ,
110+ } ;
111+ Ok ( Some ( hover) )
112+ }
113+
42114 pub ( crate ) async fn search_issue_and_pr (
43115 & self ,
44116 position : Position ,
@@ -340,18 +412,4 @@ impl Backend {
340412 self . member_map . insert ( member. login . to_owned ( ) , member) ;
341413 } ) ;
342414 }
343-
344- pub fn new ( client : Client , octocrab : Octocrab , owner : String , repo : String ) -> Backend {
345- Backend {
346- client,
347- octocrab,
348- owner,
349- repo,
350- document_map : DashMap :: new ( ) ,
351- repository_map : DashMap :: new ( ) ,
352- issue_map : DashMap :: new ( ) ,
353- member_map : DashMap :: new ( ) ,
354- wiki_map : DashMap :: new ( ) ,
355- }
356- }
357415}
0 commit comments