您的位置:首页 > 其它

VSCode扩展

2018-11-23 10:47 856 查看

原网站地址:http://www.qingpingshan.com/m/view.php?aid=364895

vscode扩展api及例子:https://www.cntofu.com/book/98/md/扩展API/vscode-api.md

首先来看怎么获取文本。在 Hello World 范例 这篇文章中,我们能简单了解到以下几种对象:

Window 对象 - 表示当前 VS Code 的整个窗口,用 vscode.window 得到这个 Window 对象。
TextEditor 对象 - VS Code 的整个窗口中可能打开了多个 tab,每一个 tab 就是一个 TextEditor 对象,但我们只需要那个当前激活的 tab,我们用 window.activeTextEditor 属性来取得当前工作中的 tab,即 TextEditor 对象。
TextDocument 对象 - 每个 TextEditor 中都有一个文档,这个文档就是 TextDocument 对象,我们用 editor.document 属性来取得 TextEditor 对象中的 TextDocument 对象。TextDocument 对象有一个 getText() 方法来取得其中的所有文本。
最终,我们通过

const originText = vscode.window.activeTextEditor.document.getText()
取得当前正在编辑的文档的所有文本。

既然拿到了原始文本,处理就很好办了 (此处忽略了通过 npm 安装 pangu 的过程):

const refinedText = pangu.spacing(originText)

TextEdit 对象 (注意,不是 TextEditor)。一个 TextEdit 对象就表示对文本的一次操作。

对文本的操作无外乎三种:增加,删除,替换,但其实归结起来,增加和删除,也算是替换操作。增加,用新的字符串,替换空字符串;删除,用空字符串替换原来的字符串。

对于要换替换的对象,既原来的字符串,我们要知道它在文档中所处的位置,这个位置包括起始位置和结束位置,每个位置都应该包括它所在的行号和所在行内的编号,这两个位置组成了一个区间。

VS Code 用 Position 对象来表征文档内一个字符所在的位置,它有两个属性:

line - 行号
character - 所在行内的编号
一个起始 Position 和一个结尾 Position,两个 Position 组成了 Range 对象,这个 Range 对象就代表了一串连续的字符。

这样,我们有了要替换的对象,又有新的字符串,我们就可以定义出一个 TextEdit 对象来表示这样一次替换操作。

const aTextReplace = new vscode.TextEdit(range, newText)
比如,我们要把第 2 行第 3 个字符,到第 5 行第 6 个字符,删除掉,即用空字符串替换它,代码如下:

const start = new vscode.Position(2, 3)
const end = new vscode.Position(5, 6)
const range = new vscode.Range(start, end)
const aTextDel = new vscode.TextEdit(range, ‘’)
上面前三行代码可以简化成

const range = new vscode.Range(2, 3, 5, 6)
第四行代码 TextEdit 对象可以用 TextEdit.delete(range) 静态方法生成:

const aTextDel = vscode.TextEdit.delete(range)
Range 和 TextEdit,我认为是操作文本的核心概念,理解它这两个对象,其它的也就没什么难的了。

但是,到目前为止,TextEdit 还只是定义了一个将被应用的操作,但还没有真正地被应用到文本上,那怎么来把这个操作真正执行呢。

这里又涉及到一个新的对象 - WorkspaceEdit 对象。WorkspaceEdit 可以理解成 TextEdit 的容器。TextEdit 只是对文本的一次操作,如果我们需要对这个文本同时进行多次操作,比如全局替换,我们就要定义多个 TextEdit 对象,并把这些对象放到一个数组里,再把这个数组放到 WorkspaceEdit 对象中。

更强大的在于,WorkspaceEdit 支持对多个文档同时进行多次操作,因此,每个 TextEdit 数组必然需要对应一个文档对象,WorkspaceEdit 使用 uri 来表征一个文档,uri 可以从 document.uri 属性获得。

我们前面得到了 document 对象,我们又定义了一些 TextEdit 对象,我们把它放到 WorkspaceEdit 对象中:

let textEdits = []
textEdits.push(aTextDel)
// push more TextEdit
// textEdits.push(…)

let workspaceEdit = new vscode.WorkspaceEdit()
workspaceEdit.set(document.uri, textEdits)
最后,我们终于可以真正地执行这些操作了,使用 vscode.workspace.applyEdit() 方法来使这些操作生效:

vscode.workspace.applyEdit(workspaceEdit)

来看看我们这个插件是如何实现的:

const editor = vscode.window.activeTextEditor
if (!editor) {
return // No open text editor
}

const document = editor.document
const lineCount = document.lineCount

let textEdits = []
for (let i=0; i<lineCount; i++) {
const textLine = document.lineAt(i)
const oriTrimText = textLine.text.trimRight()

if (oriTrimText.length === 0) {
textEdits.push(new vscode.TextEdit(textLine.range, ''))
} else {
const panguText = pangu.spacing(oriTrimText)
textEdits.push(new vscode.TextEdit(textLine.range, panguText))
}

}
let workspaceEdit = new vscode.WorkspaceEdit()
workspaceEdit.set(document.uri, textEdits)
vscode.workspace.applyEdit(workspaceEdit)

CodeActionProvider improvements
A CodeActionProvider can now return objects of the new CodeAction class. CodeAction adds additional metadata and functionality over Command, and better captures what Code Actions are and how they are used in VS Code’s UI.

A CodeAction primarily consists of a title, kind, and at least a Command or (new in VS Code 1.20) a WorkspaceEdit

import * as vscode from 'vscode'

/**
* Quick fix provider that converts :) to 😀
*/
export class Emojizer implements vscode.CodeActionProvider {
provideCodeActions(document: vscode.TextDocument, range: vscode.Range) {
const pos = range.start;
const line = document.lineAt(pos.line);

// Check if we are at a :)
if (line.text[pos.character] === ':' && line.text[pos.character + 1] === ')') {
const fix = new vscode.CodeAction('Convert to 😀', vscode.CodeActionKind.QuickFix);
fix.edit = new vscode.WorkspaceEdit();
fix.edit.replace(document.uri, new vscode.Range(pos, pos.translate(0, 2)), '😀');
return [fix];
}
return undefined;
}
}

CodeAction also adds metadata about Code Actions, including the Code Action’s kind (vscode.CodeActionKind.QuickFix in the example above) and the set of diagnostics that the Code Action addresses. We use this metadata to implement features such as the Refactor command and vscode.action.codeAction keybindings, and plan to build additional features using it in the future.

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: