More lsp stuff / telemetry-prep (#1694)
* more text document stuff Signed-off-by: Jess Frazelle <github@jessfraz.com> * backend for rename and create etc Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates for functions Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanup Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * js future Signed-off-by: Jess Frazelle <github@jessfraz.com> * utils Signed-off-by: Jess Frazelle <github@jessfraz.com> * cleanup send and sync shit Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * save the client Signed-off-by: Jess Frazelle <github@jessfraz.com> * store the users privacy settings Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * updates Signed-off-by: Jess Frazelle <github@jessfraz.com> * bump version Signed-off-by: Jess Frazelle <github@jessfraz.com> --------- Signed-off-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
@ -21,14 +21,6 @@ function getIndentationCSS(level: number) {
|
||||
return `calc(1rem * ${level + 1})`
|
||||
}
|
||||
|
||||
// an OS-agnostic way to get the basename of the path.
|
||||
export function basename(path: string): string {
|
||||
// Regular expression to match the last portion of the path, taking into account both POSIX and Windows delimiters
|
||||
const re = /[^\\/]+$/
|
||||
const match = path.match(re)
|
||||
return match ? match[0] : ''
|
||||
}
|
||||
|
||||
function RenameForm({
|
||||
fileOrDir,
|
||||
setIsRenaming,
|
||||
@ -156,7 +148,7 @@ const FileTreeItem = ({
|
||||
level?: number
|
||||
}) => {
|
||||
const { send, context } = useFileContext()
|
||||
const { lspClients } = useLspContext()
|
||||
const { onFileOpen, onFileClose } = useLspContext()
|
||||
const navigate = useNavigate()
|
||||
const [isRenaming, setIsRenaming] = useState(false)
|
||||
const [isConfirmingDelete, setIsConfirmingDelete] = useState(false)
|
||||
@ -185,26 +177,8 @@ const FileTreeItem = ({
|
||||
)
|
||||
} else {
|
||||
// Let the lsp servers know we closed a file.
|
||||
const currentFilePath = basename(currentFile?.path || 'main.kcl')
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.textDocumentDidClose({
|
||||
textDocument: {
|
||||
uri: `file:///${currentFilePath}`,
|
||||
},
|
||||
})
|
||||
})
|
||||
const newFilePath = basename(fileOrDir.path)
|
||||
// Then let the clients know we opened a file.
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.textDocumentDidOpen({
|
||||
textDocument: {
|
||||
uri: `file:///${newFilePath}`,
|
||||
languageId: 'kcl',
|
||||
version: 1,
|
||||
text: '',
|
||||
},
|
||||
})
|
||||
})
|
||||
onFileClose(currentFile?.path || null, project?.path || null)
|
||||
onFileOpen(fileOrDir.path, project?.path || null)
|
||||
|
||||
// Open kcl files
|
||||
navigate(`${paths.FILE}/${encodeURIComponent(fileOrDir.path)}`)
|
||||
|
@ -12,24 +12,46 @@ import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
|
||||
import { Extension } from '@codemirror/state'
|
||||
import { LanguageSupport } from '@codemirror/language'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { basename } from './FileTree'
|
||||
import { paths } from 'lib/paths'
|
||||
import { FileEntry } from '@tauri-apps/api/fs'
|
||||
import { ProjectWithEntryPointMetadata } from 'lib/types'
|
||||
|
||||
const DEFAULT_FILE_NAME: string = 'main.kcl'
|
||||
|
||||
function getWorkspaceFolders(): LSP.WorkspaceFolder[] {
|
||||
return []
|
||||
}
|
||||
|
||||
// an OS-agnostic way to get the basename of the path.
|
||||
export function projectBasename(filePath: string, projectPath: string): string {
|
||||
const newPath = filePath.replace(projectPath, '')
|
||||
// Trim any leading slashes.
|
||||
let trimmedStr = newPath.replace(/^\/+/, '').replace(/^\\+/, '')
|
||||
return trimmedStr
|
||||
}
|
||||
|
||||
type LspContext = {
|
||||
lspClients: LanguageServerClient[]
|
||||
copilotLSP: Extension | null
|
||||
kclLSP: LanguageSupport | null
|
||||
onProjectClose: (file: FileEntry | null, redirect: boolean) => void
|
||||
onProjectClose: (
|
||||
file: FileEntry | null,
|
||||
projectPath: string | null,
|
||||
redirect: boolean
|
||||
) => void
|
||||
onProjectOpen: (
|
||||
project: ProjectWithEntryPointMetadata | null,
|
||||
file: FileEntry | null
|
||||
) => void
|
||||
onFileOpen: (filePath: string | null, projectPath: string | null) => void
|
||||
onFileClose: (filePath: string | null, projectPath: string | null) => void
|
||||
onFileCreate: (file: FileEntry, projectPath: string | null) => void
|
||||
onFileRename: (
|
||||
oldFile: FileEntry,
|
||||
newFile: FileEntry,
|
||||
projectPath: string | null
|
||||
) => void
|
||||
onFileDelete: (file: FileEntry, projectPath: string | null) => void
|
||||
}
|
||||
|
||||
export const LspStateContext = createContext({} as LspContext)
|
||||
@ -58,7 +80,8 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const client = new Client(fromServer, intoServer)
|
||||
if (!TEST) {
|
||||
Server.initialize(intoServer, fromServer).then((lspServer) => {
|
||||
lspServer.start('kcl')
|
||||
const token = auth?.context?.token
|
||||
lspServer.start('kcl', token)
|
||||
setIsKclLspServerReady(true)
|
||||
})
|
||||
}
|
||||
@ -77,7 +100,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
if (isKclLspServerReady && !TEST) {
|
||||
// Set up the lsp plugin.
|
||||
const lsp = kclLanguage({
|
||||
documentUri: `file:///main.kcl`,
|
||||
documentUri: `file:///${DEFAULT_FILE_NAME}`,
|
||||
workspaceFolders: getWorkspaceFolders(),
|
||||
client: kclLspClient,
|
||||
})
|
||||
@ -113,7 +136,7 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
if (isCopilotLspServerReady && !TEST) {
|
||||
// Set up the lsp plugin.
|
||||
const lsp = copilotPlugin({
|
||||
documentUri: `file:///main.kcl`,
|
||||
documentUri: `file:///${DEFAULT_FILE_NAME}`,
|
||||
workspaceFolders: getWorkspaceFolders(),
|
||||
client: copilotLspClient,
|
||||
allowHTMLContent: true,
|
||||
@ -126,8 +149,15 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
const lspClients = [kclLspClient, copilotLspClient]
|
||||
|
||||
const onProjectClose = (file: FileEntry | null, redirect: boolean) => {
|
||||
const currentFilePath = basename(file?.name || 'main.kcl')
|
||||
const onProjectClose = (
|
||||
file: FileEntry | null,
|
||||
projectPath: string | null,
|
||||
redirect: boolean
|
||||
) => {
|
||||
const currentFilePath = projectBasename(
|
||||
file?.path || DEFAULT_FILE_NAME,
|
||||
projectPath || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.textDocumentDidClose({
|
||||
textDocument: {
|
||||
@ -155,7 +185,10 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
})
|
||||
if (file) {
|
||||
// Send that the file was opened.
|
||||
const filename = basename(file?.name || 'main.kcl')
|
||||
const filename = projectBasename(
|
||||
file?.path || DEFAULT_FILE_NAME,
|
||||
project?.path || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.textDocumentDidOpen({
|
||||
textDocument: {
|
||||
@ -169,6 +202,82 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const onFileOpen = (filePath: string | null, projectPath: string | null) => {
|
||||
const currentFilePath = projectBasename(
|
||||
filePath || DEFAULT_FILE_NAME,
|
||||
projectPath || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.textDocumentDidOpen({
|
||||
textDocument: {
|
||||
uri: `file:///${currentFilePath}`,
|
||||
languageId: 'kcl',
|
||||
version: 1,
|
||||
text: '',
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onFileClose = (filePath: string | null, projectPath: string | null) => {
|
||||
const currentFilePath = projectBasename(
|
||||
filePath || DEFAULT_FILE_NAME,
|
||||
projectPath || ''
|
||||
)
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.textDocumentDidClose({
|
||||
textDocument: {
|
||||
uri: `file:///${currentFilePath}`,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onFileCreate = (file: FileEntry, projectPath: string | null) => {
|
||||
const currentFilePath = projectBasename(file.path, projectPath || '')
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.workspaceDidCreateFiles({
|
||||
files: [
|
||||
{
|
||||
uri: `file:///${currentFilePath}`,
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onFileRename = (
|
||||
oldFile: FileEntry,
|
||||
newFile: FileEntry,
|
||||
projectPath: string | null
|
||||
) => {
|
||||
const oldFilePath = projectBasename(oldFile.path, projectPath || '')
|
||||
const newFilePath = projectBasename(newFile.path, projectPath || '')
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.workspaceDidRenameFiles({
|
||||
files: [
|
||||
{
|
||||
oldUri: `file:///${oldFilePath}`,
|
||||
newUri: `file:///${newFilePath}`,
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const onFileDelete = (file: FileEntry, projectPath: string | null) => {
|
||||
const currentFilePath = projectBasename(file.path, projectPath || '')
|
||||
lspClients.forEach((lspClient) => {
|
||||
lspClient.workspaceDidDeleteFiles({
|
||||
files: [
|
||||
{
|
||||
uri: `file:///${currentFilePath}`,
|
||||
},
|
||||
],
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<LspStateContext.Provider
|
||||
value={{
|
||||
@ -177,6 +286,11 @@ export const LspProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
kclLSP,
|
||||
onProjectClose,
|
||||
onProjectOpen,
|
||||
onFileOpen,
|
||||
onFileClose,
|
||||
onFileCreate,
|
||||
onFileRename,
|
||||
onFileDelete,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
@ -28,7 +28,7 @@ const ProjectSidebarMenu = ({
|
||||
<div className="rounded-sm !no-underline h-9 mr-auto max-h-min min-w-max border-0 py-1 px-2 flex items-center gap-2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-energy-50 dark:hover:bg-chalkboard-90">
|
||||
<Link
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, false)
|
||||
onProjectClose(file || null, project?.path || null, false)
|
||||
}}
|
||||
to={paths.HOME}
|
||||
className="group"
|
||||
@ -39,7 +39,7 @@ const ProjectSidebarMenu = ({
|
||||
<>
|
||||
<Link
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, false)
|
||||
onProjectClose(file || null, project?.path || null, false)
|
||||
}}
|
||||
to={paths.HOME}
|
||||
className="!no-underline"
|
||||
@ -163,7 +163,7 @@ function ProjectMenuPopover({
|
||||
<ActionButton
|
||||
Element="button"
|
||||
onClick={() => {
|
||||
onProjectClose(file || null, true)
|
||||
onProjectClose(file || null, project?.path || null, true)
|
||||
}}
|
||||
icon={{
|
||||
icon: faHome,
|
||||
|
Reference in New Issue
Block a user