Typescript 如何通过语言服务器扩展在工作区中创建和编辑新文件

Typescript 如何通过语言服务器扩展在工作区中创建和编辑新文件,typescript,visual-studio-code,vscode-extensions,language-server-protocol,Typescript,Visual Studio Code,Vscode Extensions,Language Server Protocol,如何获取语言服务器扩展以触发新文件的创建、编辑并在附加的客户端工作区中显示它 我在node.js中使用vscode languageserver编写了一个LSP扩展,它通过onExecuteCommand在服务器上执行命令。我希望这个服务器端命令触发客户端创建一个新的文本文件,用一些文本填充它,这样它就会出现在客户端的工作区打开文件列表中 现在,我相信我需要做的是创建一个WorkspaceChange对象,运行createFile(),应用一些更改(.insert),然后告诉客户端通过conne

如何获取语言服务器扩展以触发新文件的创建、编辑并在附加的客户端工作区中显示它

我在node.js中使用vscode languageserver编写了一个LSP扩展,它通过onExecuteCommand在服务器上执行命令。我希望这个服务器端命令触发客户端创建一个新的文本文件,用一些文本填充它,这样它就会出现在客户端的工作区打开文件列表中

现在,我相信我需要做的是创建一个WorkspaceChange对象,运行createFile(),应用一些更改(.insert),然后告诉客户端通过connection.workspace.applyEdit()应用编辑,但这不起作用-没有创建任何文件,也没有在调试器中抛出错误

以下是我的服务器onExecuteCommand中的代码:

//add some text
const textToAdd: string = "test string";

//create new WorkspaceChange obj
let workspaceChange = new WorkspaceChange();

//uri of the file we want to create
let newuri = 'file:///c:/temp/create.txt';

//make a TextEditChange obj. Fails if you do not supply version
let change = workspaceChange.getTextEditChange({ uri: newuri, version: 10 });

// give it some text 
change.insert(Position.create(0, 1), textToAdd);

// add a createFile documentChange to the workspaceChange
workspaceChange.createFile(newuri);

// pass these edits to the client to apply:
let reply = connection.workspace.applyEdit(workspaceChange.edit);
console.log(reply); //always <Pending>
//添加一些文本
const textToAdd:string=“测试字符串”;
//创建新工作空间更改对象
让workspaceChange=新建workspaceChange();
//要创建的文件的uri
让纽乌里来吧file:///c:/temp/create.txt';
//做一个TextEditChange对象。如果不提供版本,则失败
let change=workspaceChange.getTextEditChange({uri:newuri,版本:10});
//给它一些文字
change.insert(Position.create(0,1),textToAdd);
//将createFile documentChange添加到工作空间更改
workspaceChange.createFile(newuri);
//将这些编辑传递给客户端以应用:
让reply=connection.workspace.applyEdit(workspaceChange.edit);
控制台日志(应答)//总是
如果我提供了一个不存在的文件名,那么该过程将失败-在工作区中不会创建或打开任何文件

但是,如果我提供了一个现有文件名,则会应用编辑,并按预期在工作区中打开该文件


我以为这是因为我在createFile()之前提供了一个编辑,但是如果我在createFile()之前运行getTextEditChange(),则该过程会失败,并出现错误“工作区编辑未配置用于文档更改”

谢谢您的提示,是的,我在一段时间后完成了此操作

它在这里实施:

第476行之后的内容值得注意,其中:

  • 构造一个CreateFile变量,保存要创建的文件的路径(uri),并形成一个CreateFile数组(第476-482行)
  • 创建一个WorkspaceEdit变量,为documentChanges属性(485)指定上述CreateFile数组
  • 我们通过workspace.applyEdit(488)将其传递给客户端进行应用。这实际上创建了文件
  • 要添加到新文档中的文本首先形成一个TextEdit对象数组,由范围(范围:)和内容(新文本:)(491-498)组成
  • 构建了一个TextDocumentEdit数组,其中包含我们的TextEdit(500-503)
  • 我们将workspaceEdit变量属性更新为引用此TextDocumentEdits数组(506)
  • 最后,请我们的连接客户端应用编辑(510)
  • 我复制了下面的相关代码部分以供参考,但查看了github链接以获得完整的实现,包括设置客户端连接等,设置功能等

    //uri of new file
    let currentPath :string = (thisdoc.uri).substr(0,thisdoc.uri.lastIndexOf('/'));
    
    let newuri = currentPath+'/syntaxcheck.txt';
    
    //construct a CreateFile variable
    let createFile: CreateFile = { kind: 'create', uri: newuri };
    //and make into array
    let createFiles: CreateFile[] = [];
    createFiles.push(createFile);
    
    //make a new workspaceEdit variable, specifying a createFile document change
    var workspaceEdit: WorkspaceEdit = { documentChanges: createFiles };
    
    //pass to client to apply this edit
    await connection.workspace.applyEdit(workspaceEdit);
    
    
    //To insert the text (and pop up the window), create array of TextEdit
    let textEdit: TextEdit[] = [];
    //let document = documents.get(newuri);
    let documentRange: Range = Range.create(0, 0, Number.MAX_VALUE, Number.MAX_VALUE);
    //populate with the text, and where to insert (surely this is what workspaceChange.insert is for?)
    let textEdits: TextEdit = { range: documentRange, newText: syntaxmessage };
    
    textEdit.push(textEdits);
    
    //make a new array of textDocumentEdits, containing our TextEdit (range and text)
    let textDocumentEdit = TextDocumentEdit.create({ uri: newuri, version: 1 }, textEdit);
    let textDocumentEdits: TextDocumentEdit[] = [];
    textDocumentEdits.push(textDocumentEdit);
    
    //set  our workspaceEdit variable to this new TextDocumentEdit
    workspaceEdit = { documentChanges: textDocumentEdits };
    
    //and finally apply this to our workspace.
    // we can probably do this some more elegant way 
    connection.workspace.applyEdit(workspaceEdit);
    
    
    

    一年后检查你是否能弄明白这一点,@profocum?@JohnWiseman谢谢你的一脚,是的,我过了一段时间才弄明白。见下文