Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion src/main/main.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { app, BrowserWindow } from 'electron'
import { app, BrowserWindow, ipcMain } from 'electron'
import path, { join } from 'path'
import log from 'electron-log/main'

Expand Down Expand Up @@ -120,3 +120,18 @@ app.on('window-all-closed', () => {
app.on('before-quit', async () => {
await lsp.shutdown()
})

ipcMain.on('lsp.restart', async event => {
console.log('Received request to restart LSP server.')

try {
await lsp.shutdown()
console.log('Previous LSP server shut down. Restarting...')
await lsp.init()
console.log('LSP server restarted successfully.')
event.sender.send('lsp.restart.success')
} catch (error) {
console.error('Failed to restart LSP server:', error)
event.sender.send('lsp.restart.error', error?.message)
}
})
22 changes: 22 additions & 0 deletions src/renderer/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import { initVimMode } from 'monaco-vim'
import { installPHPLanguage, installOutputLanguage, installThemes } from '../editor'
import { useSettingsStore } from '../stores/settings'
import { useLspStore } from '../stores/lsp'

const settingsStore = useSettingsStore()
const lspStore = useLspStore()

// Props
const props = defineProps({
Expand Down Expand Up @@ -113,6 +115,8 @@
})

onBeforeUnmount(async () => {
lspStore.setDisconnected()

if (editor) {
if (vimMode.value) {
vimMode.value.dispose()
Expand Down Expand Up @@ -152,8 +156,18 @@
}
}

const reconnectLsp = async () => {
if (languageClient && languageClient.isRunning()) {
await languageClient.stop()
await languageClient.dispose()
}

await createWebSocketClient(`ws://127.0.0.1:${import.meta.env.VITE_LSP_WEBSOCKET_PORT}`)
}

const createWebSocketClient = (url: string) => {
return new Promise<void>((resolve, reject) => {
lspStore.setConnecting()
const webSocket = new WebSocket(url)

webSocket.onopen = async () => {
Expand All @@ -172,7 +186,9 @@

try {
await languageClient.start()
lspStore.setConnected()
} catch (e) {
lspStore.setDisconnected()
// reject(error)
}

Expand All @@ -184,8 +200,13 @@
// }

webSocket.onerror = error => {
lspStore.setDisconnected()
reject(error)
}

webSocket.onclose = () => {
lspStore.setDisconnected()
}
})
}

Expand Down Expand Up @@ -217,6 +238,7 @@
defineExpose({
updateValue,
focusEditor,
reconnectLsp,
})
</script>

Expand Down
22 changes: 22 additions & 0 deletions src/renderer/stores/lsp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'

export type LspStatus = 'connected' | 'connecting' | 'disconnected'

export const useLspStore = defineStore('lsp', () => {
const status = ref<LspStatus>('disconnected')

function setConnected() {
status.value = 'connected'
}

function setConnecting() {
status.value = 'connecting'
}

function setDisconnected() {
status.value = 'disconnected'
}

return { status, setConnected, setConnecting, setDisconnected }
})
46 changes: 44 additions & 2 deletions src/renderer/views/CodeView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { useExecuteStore } from '../stores/execute'
import { useTabsStore } from '../stores/tabs'
import { useVaporStore } from '../stores/vapor.ts'
import { useVaporStore } from '../stores/vapor'
import { useLspStore } from '../stores/lsp'
import Container from '../components/Container.vue'
import events from '../events'
import { useSettingsStore } from '../stores/settings'
Expand All @@ -20,7 +21,8 @@
const executeStore = useExecuteStore()
const vaporStore = useVaporStore()
const tabsStore = useTabsStore()
const codeEditor = ref(null)
const lspStore = useLspStore()
const codeEditor = ref<InstanceType<typeof Editor> | null>(null)
const resultEditor = ref<InstanceType<typeof Editor> | null>(null)
const loadersStore = useLodaersStore()

Expand Down Expand Up @@ -51,6 +53,23 @@
return output ? output.output : ''
})

const lspStatusTooltip = computed(() => {
switch (lspStore.status) {
case 'connected':
return 'LSP Connected'
case 'connecting':
return 'LSP Connecting...'
case 'disconnected':
return 'LSP Disconnected (Click to reconnect)'
}
})

const handleLspReconnect = () => {
if (lspStore.status === 'disconnected') {
window.ipcRenderer.send('lsp.restart')
}
}

const vaporRequestEnvironmentTab = () => {
if (!tabsStore.current?.id || !tabsStore.current?.path) {
console.warn('No current tab or path set, cannot request environments.')
Expand Down Expand Up @@ -166,6 +185,13 @@
}

onMounted(async () => {
window.ipcRenderer.on('lsp.restart.success', () => {
console.log('LSP restart success, reconnecting editors...')
if (codeEditor.value) {
codeEditor.value.reconnectLsp()
}
})

if (settingsStore.settings.php === '') {
await router.push({ name: 'settings' })
alert('PHP path is not set!')
Expand Down Expand Up @@ -316,6 +342,22 @@
backgroundColor: settingsStore.colors.background,
}"
>
<div
class="flex items-center ml-2"
:class="{ 'cursor-pointer': lspStore.status === 'disconnected' }"
v-tippy="lspStatusTooltip"
@click="handleLspReconnect"
>
<template v-if="lspStore.status === 'connected'">
<div class="flex items-center justify-center bg-green-500 rounded-full size-3"></div>
</template>
<template v-else-if="lspStore.status === 'connecting'">
<div class="flex items-center justify-center bg-yellow-500 rounded-full size-3"></div>
</template>
<template v-else-if="lspStore.status === 'disconnected'">
<div class="flex items-center justify-center bg-red-500 rounded-full size-3"></div>
</template>
</div>
<div class="px-2 flex gap-1 w-1/2 items-center">
<div class="whitespace-nowrap">PHP {{ tab.info.php_version }}</div>
</div>
Expand Down
Loading