11use std:: { collections:: HashSet , time:: Duration } ;
22
3- use futures_util:: { stream:: FuturesOrdered , StreamExt } ;
43use helix_core:: syntax:: config:: LanguageServerFeature ;
54use helix_event:: { cancelable_future, register_hook} ;
65use helix_view:: {
@@ -12,7 +11,6 @@ use tokio::time::Instant;
1211
1312use crate :: job;
1413
15- // TODO(matoous): use to update code lenses positions on document changes
1614#[ derive( Default ) ]
1715#[ allow( dead_code) ]
1816pub ( super ) struct DocumentCodeLensesHandler {
@@ -44,6 +42,10 @@ impl helix_event::AsyncHook for DocumentCodeLensesHandler {
4442 }
4543}
4644
45+ /// Requests code lenses for a specific document.
46+ ///
47+ /// NOTE: currently supports only a single language server, the first one supporting
48+ /// code lenses is used.
4749pub fn request_document_code_lenses ( editor : & mut Editor , doc_id : DocumentId ) {
4850 if !editor. config ( ) . lsp . display_code_lenses {
4951 return ;
@@ -53,77 +55,69 @@ pub fn request_document_code_lenses(editor: &mut Editor, doc_id: DocumentId) {
5355 return ;
5456 } ;
5557
56- let cancel = doc. color_swatch_controller . restart ( ) ;
58+ let cancel = doc. code_lenses_controller . restart ( ) ;
5759
58- let mut seen_language_servers = HashSet :: new ( ) ;
59- let mut futures: FuturesOrdered < _ > = doc
60+ let language_server = doc
6061 . language_servers_with_feature ( LanguageServerFeature :: CodeLens )
61- . filter ( |ls| seen_language_servers. insert ( ls. id ( ) ) )
62- . map ( |language_server| {
63- let text = doc. text ( ) . clone ( ) ;
64- let offset_encoding = language_server. offset_encoding ( ) ;
65- let future = language_server. code_lens ( doc. identifier ( ) ) . unwrap ( ) ;
66-
67- async move {
68- let lenses: Vec < _ > = future
69- . await ?
70- . unwrap_or_default ( )
71- . into_iter ( )
72- . filter_map ( |lens| {
73- let _pos = helix_lsp:: util:: lsp_pos_to_pos (
74- & text,
75- lens. range . start ,
76- offset_encoding,
77- ) ?;
78- Some ( lens)
79- } )
80- . collect ( ) ;
81- anyhow:: Ok ( lenses)
82- }
83- } )
84- . collect ( ) ;
62+ . next ( ) ;
63+ let language_server = match language_server {
64+ Some ( language_server) => language_server,
65+ None => {
66+ editor. set_error ( format ! (
67+ "No configured language server supports {}" ,
68+ LanguageServerFeature :: CodeLens
69+ ) ) ;
70+ return ;
71+ }
72+ } ;
8573
86- if futures . is_empty ( ) {
87- return ;
88- }
74+ let text = doc . text ( ) . clone ( ) ;
75+ let offset_encoding = language_server . offset_encoding ( ) ;
76+ let future = language_server . code_lens ( doc . identifier ( ) ) . unwrap ( ) ;
8977
9078 tokio:: spawn ( async move {
91- let mut code_lenses = Vec :: new ( ) ;
92- loop {
93- match cancelable_future ( futures. next ( ) , & cancel) . await {
94- Some ( Some ( Ok ( items) ) ) => code_lenses. extend ( items) ,
95- Some ( Some ( Err ( err) ) ) => log:: error!( "document color request failed: {err}" ) ,
96- Some ( None ) => break ,
97- // The request was cancelled.
98- None => return ,
79+ let lenses: Vec < _ > = match cancelable_future ( future, & cancel) . await {
80+ Some ( Ok ( Some ( items) ) ) => items
81+ . into_iter ( )
82+ . filter_map ( |lens| {
83+ let _pos =
84+ helix_lsp:: util:: lsp_pos_to_pos ( & text, lens. range . start , offset_encoding) ?;
85+ Some ( lens)
86+ } )
87+ . collect ( ) ,
88+ Some ( Ok ( None ) ) => Vec :: new ( ) ,
89+ Some ( Err ( err) ) => {
90+ log:: error!( "document color request failed: {err}" ) ;
91+ return ;
9992 }
100- }
93+ None => return ,
94+ } ;
95+
10196 job:: dispatch ( move |editor, _| {
10297 let Some ( doc) = editor. documents . get_mut ( & doc_id) else {
10398 return ;
10499 } ;
105100
106- if code_lenses . is_empty ( ) {
101+ if lenses . is_empty ( ) {
107102 doc. code_lenses . clear ( ) ;
108103 return ;
109104 }
110105
111- doc. code_lenses = code_lenses ;
106+ doc. set_code_lenses ( lenses ) ;
112107 } )
113108 . await ;
114109 } ) ;
115110}
116111
117112pub ( super ) fn register_hooks ( _handlers : & Handlers ) {
118113 register_hook ! ( move |event: & mut DocumentDidOpen <' _>| {
119- // when a document is initially opened, request colors for it
114+ // when a document is initially opened, request code lenses for it
120115 request_document_code_lenses( event. editor, event. doc) ;
121-
122116 Ok ( ( ) )
123117 } ) ;
124118
125119 register_hook ! ( move |_event: & mut DocumentDidChange <' _>| {
126- // TODO: update code lenses positions, same as with e.g. document colors
120+ // TODO(matoous): use to update code lenses positions on document changes
127121 Ok ( ( ) )
128122 } ) ;
129123
@@ -138,7 +132,7 @@ pub(super) fn register_hooks(_handlers: &Handlers) {
138132 } ) ;
139133
140134 register_hook ! ( move |event: & mut LanguageServerExited <' _>| {
141- // Clear and re-request all color swatches when a server exits.
135+ // Clear and re-request all code lenses when a server exits.
142136 for doc in event. editor. documents_mut( ) {
143137 if doc. supports_language_server( event. server_id) {
144138 doc. code_lenses. clear( ) ;
0 commit comments