@@ -34,6 +34,7 @@ import { createColors, createFrames } from "../../ui/spinner.ts"
3434import { useDialog } from "@tui/ui/dialog"
3535import { DialogProvider as DialogProviderConnect } from "../dialog-provider"
3636import { DialogAlert } from "../../ui/dialog-alert"
37+ import { DialogSelect } from "../../ui/dialog-select"
3738import { useToast } from "../../ui/toast"
3839import { useKV } from "../../context/kv"
3940import { createFadeIn } from "../../util/signal"
@@ -411,6 +412,19 @@ export function Prompt(props: PromptProps) {
411412 ) )
412413 } ,
413414 } ,
415+ {
416+ title : "List LSP servers" ,
417+ value : "lsp.list" ,
418+ category : "System" ,
419+ description : "Use /lsps kill <name> to stop one" ,
420+ slash : {
421+ name : "lsps" ,
422+ } ,
423+ onSelect : async ( dialog ) => {
424+ dialog . clear ( )
425+ await runLsps ( "/lsps" )
426+ } ,
427+ } ,
414428 ]
415429 } )
416430
@@ -571,6 +585,89 @@ export function Prompt(props: PromptProps) {
571585 )
572586 }
573587
588+ async function showLsps ( ) {
589+ const result = await sdk . client . lsp . status ( ) . catch ( ( ) => undefined )
590+ if ( ! result || result . error ) {
591+ toast . show ( { message : "Failed to list LSP servers" , variant : "error" } )
592+ return
593+ }
594+
595+ const data = result . data ?? [ ]
596+ if ( data . length === 0 ) {
597+ toast . show ( { message : "No LSP servers running" , variant : "warning" } )
598+ return
599+ }
600+
601+ dialog . replace ( ( ) => (
602+ < DialogSelect
603+ title = "LSP Servers"
604+ options = { data . map ( ( item ) => ( {
605+ title : item . name ,
606+ value : item . name ,
607+ description : `/lsps kill ${ item . name } ` ,
608+ footer : item . root || "." ,
609+ } ) ) }
610+ onSelect = { async ( option ) => {
611+ await runLsps ( `/lsps kill ${ option . value } ` )
612+ await showLsps ( )
613+ } }
614+ />
615+ ) )
616+ }
617+
618+ async function runLsps ( input : string ) {
619+ const rest = input . replace ( / ^ \/ l s p s / , "" ) . trim ( )
620+
621+ if ( ! rest ) {
622+ await showLsps ( )
623+ return true
624+ }
625+
626+ if ( rest === "kill" ) {
627+ toast . show ( { message : "Usage: /lsps kill <name>" , variant : "warning" } )
628+ return true
629+ }
630+
631+ if ( rest === "killall" ) {
632+ const result = await sdk . client . lsp . killAll ( ) . catch ( ( ) => undefined )
633+ if ( ! result || result . error ) {
634+ toast . show ( { message : "Failed to kill LSP servers" , variant : "error" } )
635+ return true
636+ }
637+ if ( ! result . data ) {
638+ toast . show ( { message : "No LSP servers running" , variant : "warning" } )
639+ return true
640+ }
641+ toast . show ( { message : "Killed all LSP servers" , variant : "success" } )
642+ return true
643+ }
644+
645+ if ( ! rest . startsWith ( "kill " ) ) {
646+ toast . show ( { message : "Unknown /lsps command" , variant : "warning" } )
647+ return true
648+ }
649+
650+ const name = rest . slice ( "kill" . length ) . trim ( )
651+ if ( ! name ) {
652+ toast . show ( { message : "Usage: /lsps kill <name>" , variant : "warning" } )
653+ return true
654+ }
655+
656+ const result = await sdk . client . lsp . kill ( { name } ) . catch ( ( ) => undefined )
657+ if ( ! result || result . error ) {
658+ toast . show ( { message : `Failed to kill LSP server ${ name } ` , variant : "error" } )
659+ return true
660+ }
661+
662+ if ( ! result . data ) {
663+ toast . show ( { message : `No running LSP server named ${ name } ` , variant : "warning" } )
664+ return true
665+ }
666+
667+ toast . show ( { message : `Killed LSP server ${ name } ` , variant : "success" } )
668+ return true
669+ }
670+
574671 command . register ( ( ) => [
575672 {
576673 title : "Stash prompt" ,
@@ -644,6 +741,19 @@ export function Prompt(props: PromptProps) {
644741 void exit ( )
645742 return true
646743 }
744+
745+ if ( store . mode === "normal" && trimmed . match ( / ^ \/ l s p s (?: \s | $ ) / ) ) {
746+ await runLsps ( trimmed )
747+ input . extmarks . clear ( )
748+ setStore ( "prompt" , {
749+ input : "" ,
750+ parts : [ ] ,
751+ } )
752+ setStore ( "extmarkToPartIndex" , new Map ( ) )
753+ input . clear ( )
754+ return
755+ }
756+
647757 const selectedModel = local . model . current ( )
648758 if ( ! selectedModel ) {
649759 void promptModelWarning ( )
0 commit comments