Skip to content

Commit

Permalink
lsp: Add command for restarting lsp server (#2181)
Browse files Browse the repository at this point in the history
  • Loading branch information
fox0430 authored Sep 9, 2024
1 parent f287b70 commit 9a262c5
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.. _#2181: https://github.com/fox0430/moe/pull/2181

Added
.....

- `#2181`_ lsp: Add command for restarting lsp server

2 changes: 2 additions & 0 deletions documents/howtouse.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
| <kbd>**z**</kbd> <kbd>**d**</kbd></br> | Delete fold lines |
| <kbd>**z**</kbd> <kbd>**R**</kbd></br> | Delete fold lines |
| <kbd>**Ctrl**</kbd> <kbd>**s**</kbd></br> | Selection Range (LSP) |
| <kbd>**Space**</kbd> <kbd>**o**</kbd></br> | Document Symbol (LSP) |

</details>

Expand Down Expand Up @@ -346,6 +347,7 @@
| `lspFold` | LSP Folding Range |
| `log` | Open a log viewer for editor log |
| `lspLog` | Open a log viewer for LSP log |
| `lspRestart` | Result the current LSP server |
| `help` | Open help |
| `putConfigFile` | Put a sample configuration file in ~/.config/moe |
| `run` | Quick run |
Expand Down
2 changes: 1 addition & 1 deletion src/moepkg/editorstatus.nim
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ proc cancelLspForegroundRequest*(status: var EditorStatus) {.inline.} =
if status.lspClients.contains(currentBufStatus.langId):
lspClient.cancelLspForegroundRequest(currentBufStatus.id)

proc initLspExperimentalParams(
proc initLspExperimentalParams*(
serverName: string,
settings: LspServerSettings): Option[JsonNode] =

Expand Down
30 changes: 30 additions & 0 deletions src/moepkg/exmode.nim
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,34 @@ proc lspFoldingRange(status: var EditorStatus) =
if r.isErr:
status.commandLine.writeLspFoldingRangeError(r.error)

proc lspRestartClient(status: var EditorStatus) =
status.changeMode(currentBufStatus.prevMode)

if not status.lspClients.contains(currentBufStatus.langId):
status.commandLine.writeLspError("Client not found")
return

let r = lspClient.restart
if r.isOk:
status.commandLine.writeStandard(fmt"lsp: restarted client: {lspClient.serverName}")
else:
status.commandLine.writeLspError("Client not found")

let langId = currentBufStatus.langId
for b in status.bufStatus:
if b.langId == langId:
let r = lspClient.initialize(
status.bufStatus[^1].id,
initInitializeParams(
lspClient.serverName,
$b.openDir,
status.settings.lsp.languages[langId].trace,
initLspExperimentalParams(
status.lspClients[langId].serverName,
status.settings.lsp.servers)))
if r.isErr:
status.commandLine.writeLspError(r.error)

proc saveExCommandHistory(
exCommandHistory: var seq[Runes],
command: seq[Runes],
Expand Down Expand Up @@ -1355,6 +1383,8 @@ proc exModeCommand*(status: var EditorStatus, command: seq[Runes]) =
status.lspExecuteCommand(command[1 .. ^1])
elif isLspFoldingCommand(command):
status.lspFoldingRange
elif isLspRestartCommand(command):
status.lspRestartClient
else:
status.commandLine.writeNotEditorCommandError(command)
status.changeMode(currentBufStatus.prevMode)
Expand Down
10 changes: 9 additions & 1 deletion src/moepkg/exmodeutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ const
command: "lspLog",
description: "Open the LSP log viewer",
argsType: ArgsType.none),
ExCommandInfo(
command: "lspRestart",
description: "Restart the current LSP server",
argsType: ArgsType.none),
ExCommandInfo(
command: "man",
description: "Show the given UNIX manual page, if available",
Expand Down Expand Up @@ -759,6 +763,9 @@ proc isLspExeCommand*(command: seq[Runes]): bool {.inline.} =
proc isLspFoldingCommand*(command: seq[Runes]): bool {.inline.} =
command.len == 1 and cmpIgnoreCase($command[0], "lspfold") == 0

proc isLspRestartCommand*(command: seq[Runes]): bool {.inline.} =
command.len == 1 and cmpIgnoreCase($command[0], "lsprestart") == 0

proc isValidExCommand*(commandSplit: seq[Runes]): bool =
## Return true if valid ex command and valid args.

Expand Down Expand Up @@ -836,7 +843,8 @@ proc isValidExCommand*(commandSplit: seq[Runes]): bool =
isHighlightCurrentLineSettingCommand(commandSplit) or
isBuildCommand(commandSplit) or
isLspExeCommand(commandSplit) or
isLspFoldingCommand(commandSplit)
isLspFoldingCommand(commandSplit) or
isLspRestartCommand(commandSplit)

proc getArgsType*(command: Runes): Result[ArgsType, string] =
## Return ArgsType if valid ex command.
Expand Down
2 changes: 2 additions & 0 deletions src/moepkg/helputils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,8 @@ lspFold - LSP Folding Range
log - Open a log viewer for editor log
lspLog- Open a log viewer for LSP log
lspRestart - Restart the current LSP server
help - Open this help
putConfigFile - Put a sample configuration file in ~/.config/moe
Expand Down
24 changes: 24 additions & 0 deletions src/moepkg/lsp/client.nim
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ type
lastId*: RequestId
# Last request ID
serverName*: string
# The LSP server name
command*: string
# The LSP server start command

type
R = Result
Expand All @@ -102,6 +105,8 @@ type

initLspClientResult* = R[LspClient, string]

LspRestartClientResult* = R[(), string]

LspErrorParseResult* = R[LspError, string]
LspSendRequestResult* = R[(), string]
LspSendNotifyResult* = R[(), string]
Expand Down Expand Up @@ -438,8 +443,27 @@ proc initLspClient*(command: string): initLspClientResult =

c.serverName = commandSplit[0]

c.command = command

return initLspClientResult.ok c

proc restart*(c: var LspClient): LspRestartClientResult =
## Restart the LSP server process.
## Logs will be taken over.

if c.serverProcess.running: c.exit

let beforeLog = c.log

var newClient = initLspClient(c.command)
if newClient.isErr:
return LspRestartClientResult.err newClient.error

c = newClient.get
c.log = beforeLog

return LspRestartClientResult.ok ()

proc initInitializeParams*(
serverName, workspaceRoot: string,
trace: TraceValue,
Expand Down
54 changes: 54 additions & 0 deletions tests/tlspclient.nim
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#[############################################################################]#

import std/[unittest, importutils, os, osproc, options, tables, json]

import pkg/results

import moepkg/independentutils
import moepkg/lsp/protocol/[enums, types]
import moepkg/lsp/utils
Expand Down Expand Up @@ -83,6 +85,58 @@ suite "lsp: initInitializeParams":

check r.capabilities.experimental.get == experimental

suite "lsp: restart":
privateAccess(LspClient)

const
ServerName = "nimlangserver"
Command = "nimlangserver"
Trace = TraceValue.verbose

var client: LspClient

setup:
if isNimlangserverAvailable():
client = initLspClient(Command).get

test "Basic 1":
if not isNimlangserverAvailable():
skip()
else:
const BufferId = 1
let params = initInitializeParams(ServerName, "/", Trace)
check client.initialize(BufferId, params).isOk

let
beforePid = client.serverProcessId
beforeLogLen = client.log.len

check client.running

check client.restart.isOk

check beforePid != client.serverProcessId
check client.log.len == beforeLogLen

test "Basic 2":
if not isNimlangserverAvailable():
skip()
else:
const BufferId = 1
let params = initInitializeParams(ServerName, "/", Trace)
check client.initialize(BufferId, params).isOk

let
beforePid = client.serverProcessId
beforeLogLen = client.log.len

client.serverProcess.kill

check client.restart.isOk

check beforePid != client.serverProcessId
check client.log.len == beforeLogLen

suite "lsp: setCapabilities":
var client: LspClient

Expand Down

0 comments on commit 9a262c5

Please sign in to comment.