public async provideHover(document: TextDocument, position: Position, token: CancellationToken): Promise<Hover> {
        if (!VariableUtility.isVariableReference(document, position)) {
            return;
        }

        let wordRange = document.getWordRangeAtPosition(position);
        let selectedVariableName = document.getText(wordRange);

        if (await FileVariableProvider.Instance.has(document, selectedVariableName)) {
            const { name, value, error, warning } = await FileVariableProvider.Instance.get(document, selectedVariableName);
            if (!warning && !error) {
                const contents: MarkedString[] = [value as string, new MarkdownString(`*File Variable* \`${name}\``)];
                return new Hover(contents, wordRange);
            }

            return;
        }

        if (await EnvironmentVariableProvider.Instance.has(document, selectedVariableName)) {
            const { name, value, error, warning } = await EnvironmentVariableProvider.Instance.get(document, selectedVariableName);
            if (!warning && !error) {
                const contents: MarkedString[] = [value as string, new MarkdownString(`*Environment Variable* \`${name}\``)];
                return new Hover(contents, wordRange);
            }

            return;
        }

        return;
    }
Example #2
0
	constructor(
		public position: Position,
		public document: TextDocument,
		entry: CompletionEntry,
		enableDotCompletions: boolean,
		enableCallCompletions: boolean
	) {
		super(entry.name);
		this.sortText = entry.sortText;
		this.kind = MyCompletionItem.convertKind(entry.kind);
		this.position = position;
		this.commitCharacters = MyCompletionItem.getCommitCharacters(enableDotCompletions, enableCallCompletions, entry.kind);
		if (entry.replacementSpan) {
			let span: protocol.TextSpan = entry.replacementSpan;
			// The indexing for the range returned by the server uses 1-based indexing.
			// We convert to 0-based indexing.
			this.textEdit = TextEdit.replace(new Range(span.start.line - 1, span.start.offset - 1, span.end.line - 1, span.end.offset - 1), entry.name);
		} else {
			// Try getting longer, prefix based range for completions that span words
			const wordRange = document.getWordRangeAtPosition(position);
			const text = document.getText(new Range(position.line, Math.max(0, position.character - entry.name.length), position.line, position.character)).toLowerCase();
			const entryName = entry.name.toLowerCase();
			for (let i = entryName.length; i >= 0; --i) {
				if (text.endsWith(entryName.substr(0, i)) && (!wordRange || wordRange.start.character > position.character - i)) {
					this.range = new Range(position.line, Math.max(0, position.character - i), position.line, position.character);
					break;
				}
			}
		}
	}
Example #3
0
export function getWindowsLineEndingCount(document: TextDocument, offset: Number) {
    const eolPattern = new RegExp('\r\n', 'g');
    const readBlock = 1024;
    let count = 0;
    let offsetDiff = offset.valueOf();

    // In order to prevent the one-time loading of large files from taking up too much memory
    for (let pos = 0; pos < offset; pos += readBlock) {
        let startAt = document.positionAt(pos);
        let endAt = null;

        if (offsetDiff >= readBlock) {
            endAt = document.positionAt(pos + readBlock);
            offsetDiff = offsetDiff - readBlock;
        } else {
            endAt = document.positionAt(pos + offsetDiff);
        }

        let text = document.getText(new Range(startAt, endAt));
        let cr = text.match(eolPattern);

        count += cr ? cr.length : 0;
    }
    return count;
}
  provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken) : CompletionItem[] {
    const start = new Position(position.line, 0);
    const range = new Range(start, position);
    const currentWord = document.getText(range).trim();
    const text = document.getText();
    const value = isValue(cssSchema, currentWord);
    const config = workspace.getConfiguration('languageStylus');

    let symbols = [],
        atRules = [],
        properties = [],
        values = [];

    if (value) {
      values = getValues(cssSchema, currentWord);
      symbols = compact(getAllSymbols(text, currentWord)).filter(item =>
        item.kind === CompletionItemKind.Variable
      );
    } else {
      atRules = getAtRules(cssSchema, currentWord);
      properties = getProperties(cssSchema, currentWord, config.get('useSeparator', true));
      symbols = compact(getAllSymbols(text, currentWord));
    }

    const completions = [].concat(
      symbols,
      atRules,
      properties,
      values,
      config.get('useBuiltinFunctions', true) ? builtIn : []
    );

    return completions;
  }
Example #5
0
export function applyLineChanges(original: TextDocument, modified: TextDocument, diffs: LineChange[]): string {
	const result: string[] = [];
	let currentLine = 0;

	for (let diff of diffs) {
		const isInsertion = diff.originalEndLineNumber === 0;
		const isDeletion = diff.modifiedEndLineNumber === 0;

		result.push(original.getText(new Range(currentLine, 0, isInsertion ? diff.originalStartLineNumber : diff.originalStartLineNumber - 1, 0)));

		if (!isDeletion) {
			let fromLine = diff.modifiedStartLineNumber - 1;
			let fromCharacter = 0;

			// if this is an insertion at the very end of the document,
			// then we must start the next range after the last character of the
			// previous line, in order to take the correct eol
			if (isInsertion && diff.originalStartLineNumber === original.lineCount) {
				fromLine -= 1;
				fromCharacter = modified.lineAt(fromLine).range.end.character;
			}

			result.push(modified.getText(new Range(fromLine, fromCharacter, diff.modifiedEndLineNumber, 0)));
		}

		currentLine = isInsertion ? diff.originalStartLineNumber : diff.originalEndLineNumber;
	}

	result.push(original.getText(new Range(currentLine, 0, original.lineCount, 0)));

	return result.join('');
}
Example #6
0
function getDiagnostic(document: TextDocument, report: NpmListReport, moduleName: string, ranges: SourceRanges): Diagnostic {
	let diagnostic = null;

	// npm list only reports errors against 'dependencies' and not against 'devDependencies'
	if (report.dependencies && report.dependencies[moduleName]) {
		if (report.dependencies[moduleName]['missing'] === true) {
			if (ranges.dependencies[moduleName]) {
				const source = ranges.dependencies[moduleName].name;
				const range = new Range(document.positionAt(source.offset), document.positionAt(source.offset + source.length));
				diagnostic = new Diagnostic(range, `Module '${moduleName}' is not installed`, DiagnosticSeverity.Warning);
			} else {
				console.log(`[npm-script] Could not locate "missing" dependency '${moduleName}' in package.json`);
			}
		}
		else if (report.dependencies[moduleName]['invalid'] === true) {
			if (ranges.dependencies[moduleName]) {
				const source = ranges.dependencies[moduleName].version;
				const installedVersion = report.dependencies[moduleName]['version'];
				const range = new Range(document.positionAt(source.offset), document.positionAt(source.offset + source.length));
				const message = installedVersion ?
					`Module '${moduleName}' the installed version '${installedVersion}' is invalid` :
					`Module '${moduleName}' the installed version is invalid or has errors`;
				diagnostic = new Diagnostic(range, message, DiagnosticSeverity.Warning);
			} else {
				console.log(`[npm-script] Could not locate "invalid" dependency '${moduleName}' in package.json`);
			}
		}
		else if (report.dependencies[moduleName]['extraneous'] === true) {
			const source = findAttributeRange(ranges);
			const range = new Range(document.positionAt(source.offset), document.positionAt(source.offset + source.length));
			diagnostic = new Diagnostic(range, `Module '${moduleName}' is extraneous`, DiagnosticSeverity.Warning);
		}
	}
	return diagnostic;
}
        return new Promise<Command[]>((resolve, reject) => {
            let commands: Command[] = [
                {
                    command: 'python.sortImports',
                    title: 'Sort Imports'
                }
            ];

            if (vscode.window.activeTextEditor.document === document && !vscode.window.activeTextEditor.selection.isEmpty) {
                let wordRange = document.getWordRangeAtPosition(range.start);
                // If no word has been selected by the user, then don't display rename
                // If something has been selected, then ensure we have selected a word (i.e. end and start matches the word range) 
                if (wordRange && !wordRange.isEmpty && wordRange.isEqual(vscode.window.activeTextEditor.selection)) {
                    let word = document.getText(wordRange).trim();
                    if (word.length > 0) {
                        commands.push({ command: 'editor.action.rename', title: 'Rename Symbol' });
                    }
                }
            }

            if (!range.isEmpty) {
                let word = document.getText(range).trim();
                if (word.trim().length > 0) {
                    commands.push({ command: 'python.refactorExtractVariable', title: 'Extract Variable', arguments: [range] });
                    commands.push({ command: 'python.refactorExtractMethod', title: 'Extract Method', arguments: [range] });
                }
            }
            resolve(commands);
        });
    public static getTodos(doc: TextDocument): model.TodoItem[] {
        let docContent = doc.getText();
        let regex = new rg.RegexFactory(doc.languageId).get();
        /* For no reason, vscode returns duplicates matches sometimes.
        To avoid that, check if a new item exists in the set */
        let set = new collections.Set<model.TodoItem>();
        let results: model.TodoItem[] = [];
        if (docContent != "") {
            let match, indices = [];
            while (match = regex.exec(docContent)) {
                indices.push(match.index);

                let matched_text = (match[1]) ? match[1] : match[0];
                let filter_result = this.filter(this.cleanString(matched_text));
                matched_text = filter_result[0];
                if(!matched_text) { // there is no todo
                    continue;
                }
                let skipped = filter_result[1];
                let id = match.index + skipped;
                let range = new Range(doc.positionAt(id), doc.positionAt(id + matched_text.length));
                let new_item = new model.TodoItem(range, matched_text, doc.fileName);
                
                if (!set.contains(new_item)) {
                    results.push(new_item);
                    set.add(new_item);
                }
            }
        }

        return results;
    }
export function buildDiagnostic(componentFailure): Diagnostic {
    let lineNumber: number = 0;
    let columnNumber: number = 0;

    if(componentFailure.lineNumber){
        lineNumber = componentFailure.lineNumber - 1;
    }
    if(componentFailure.columnNumber){
        columnNumber = componentFailure.columnNumber - 1;
    }

    let start = new Position(lineNumber, columnNumber);
    let end = new Position(lineNumber+1, 0);
    let range = new Range(start, end);

    if(componentFailure.document){
        let document: TextDocument = componentFailure.document;
        let wordRange = document.getWordRangeAtPosition(start); 
        if(wordRange){
            range = wordRange;
        }
    }

    let newDiagnostic = new Diagnostic(range, componentFailure.problem);

    return newDiagnostic;
}
Example #10
0
 public toDecorationRange(start: number, document: TextDocument): Range {
     const pos = document.positionAt(start);
     const line = pos.line;
     const documentLine = document.lineAt(line);
     const lineRange = documentLine.range;
     return new Range(lineRange.end.line, lineRange.end.character, lineRange.end.line, lineRange.end.character);
 }