Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
private async applyTextEdit(item: CompletionItem, option: CompleteOption): Promise {
let { nvim } = this
let { textEdit } = item
if (!textEdit) return false
let { line, bufnr, linenr } = option
let doc = workspace.getDocument(bufnr)
if (!doc) return false
let { range, newText } = textEdit
let isSnippet = item.insertTextFormat === InsertTextFormat.Snippet
// replace inserted word
let start = line.substr(0, range.start.character)
let end = line.substr(range.end.character)
if (isSnippet) {
await doc.applyEdits(nvim, [{
range: Range.create(linenr - 1, 0, linenr, 0),
newText: `${start}${end}\n`
}])
// can't select, since additionalTextEdits would break selection
let pos = Position.create(linenr - 1, range.start.character)
return await snippetManager.insertSnippet(newText, false, Range.create(pos, pos))
}
let newLines = `${start}${newText}${end}`.split('\n')
if (newLines.length == 1) {
await nvim.call('coc#util#setline', [linenr, newLines[0]])
await workspace.moveTo(Position.create(linenr - 1, (start + newText).length))
} else {
let buffer = nvim.createBuffer(bufnr)
await buffer.setLines(newLines, {
start: linenr - 1,
end: linenr,
strictIndexing: false
let res: number[] = []
if (this.env.isVim && !this.env.textprop) {
res = this.matchAddRanges(ranges, hlGroup, 10)
} else {
let lineRanges = []
for (let range of ranges) {
if (range.start.line == range.end.line) {
lineRanges.push(range)
} else {
// split range by lines
for (let i = range.start.line; i < range.end.line; i++) {
let line = this.getline(i)
if (i == range.start.line) {
lineRanges.push(Range.create(i, range.start.character, i, line.length))
} else if (i == range.end.line) {
lineRanges.push(Range.create(i, Math.min(line.match(/^\s*/)[0].length, range.end.character), i, range.end.character))
} else {
lineRanges.push(Range.create(i, Math.min(line.match(/^\s*/)[0].length, line.length), i, line.length))
}
}
}
}
for (let range of lineRanges) {
let { start, end } = range
if (comparePosition(start, end) == 0) continue
let line = this.getline(start.line)
// tslint:disable-next-line: no-floating-promises
this.buffer.addHighlight({
hlGroup,
srcId,
line: start.line,
colStart: byteIndex(line, start.character),
public async documentRangeFormatting(mode: string): Promise {
let document = await workspace.document
if (!document) return -1
let range: Range
if (mode) {
range = await workspace.getSelectedRange(mode, document.textDocument)
if (!range) return -1
} else {
let lnum = await this.nvim.getVvar('lnum') as number
let count = await this.nvim.getVvar('count') as number
let mode = await this.nvim.call('mode')
// we can't handle
if (count == 0 || mode == 'i' || mode == 'R') return -1
range = Range.create(lnum - 1, 0, lnum - 1 + count, 0)
}
let options = await workspace.getFormatOptions()
let textEdits = await languages.provideDocumentRangeFormattingEdits(document.textDocument, range, options)
if (!textEdits) return - 1
await document.applyEdits(this.nvim, textEdits)
return 0
}
this._placeholders = placeholders.map((p, idx) => {
const offset = snippet.offset(p)
const position = document.positionAt(offset)
const start: Position = {
line: line + position.line,
character: position.line == 0 ? character + position.character : position.character
}
const value = p.toString()
const lines = value.split('\n')
let res: CocSnippetPlaceholder = {
range: Range.create(start, {
line: start.line + lines.length - 1,
character: lines.length == 1 ? start.character + value.length : lines[lines.length - 1].length
}),
transform: p.transform != null,
line: start.line,
id: idx,
index: p.index,
value,
isFinalTabstop: p.isFinalTabstop,
snippet: this
}
Object.defineProperty(res, 'snippet', {
enumerable: false
})
if (p.choice) {
let { options } = p.choice
private fixRange(range: Range): Range {
let { start, end } = range
if (start.line != end.line) return range
let line = this.document.getline(start.line)
if (!line) return range
if (start.character < line.length) return range
return Range.create(start.line, line.length - 1, start.line, line.length)
}
public async getQuickfixActions(range?: Range): Promise {
let document = await workspace.document
if (!document) return []
range = range || Range.create(0, 0, document.lineCount, 0)
let diagnostics = diagnosticManager.getDiagnosticsInRange(document.textDocument, range)
let context: CodeActionContext = { diagnostics, only: [CodeActionKind.QuickFix] }
let codeActionsMap = await languages.getCodeActions(document.textDocument, range, context, true)
if (!codeActionsMap) return []
let codeActions: CodeAction[] = []
for (let clientId of codeActionsMap.keys()) {
let actions = codeActionsMap.get(clientId)
for (let action of actions) {
if (action.kind !== CodeActionKind.QuickFix) continue
(action as any).clientId = clientId
codeActions.push(action)
}
}
return codeActions
}
public async selectFunction(inner: boolean, visualmode: string): Promise {
let { nvim } = this
let bufnr = await nvim.eval('bufnr("%")') as number
let doc = workspace.getDocument(bufnr)
if (!doc) return
let range: Range
if (visualmode) {
range = await workspace.getSelectedRange(visualmode, doc)
} else {
let pos = await workspace.getCursorPosition()
range = Range.create(pos, pos)
}
let symbols = await this.getDocumentSymbols(doc)
if (!symbols || symbols.length === 0) {
workspace.showMessage('No symbols found', 'warning')
return
}
let properties = symbols.filter(s => s.kind == 'Property')
symbols = symbols.filter(s => [
'Method',
'Function',
].includes(s.kind))
let selectRange: Range
for (let sym of symbols.reverse()) {
if (sym.range && !equals(sym.range, range) && rangeInRange(range, sym.range)) {
selectRange = sym.range
break
get range(): Range {
const start = this.node.loc.start;
const startCharacter = this.node.visibility
? start.column - this.node.visibility.length
: start.column;
const end = this.node.loc.end;
return Range.create(
start.line - 1,
startCharacter,
end.line - 1,
end.column
);
}