UNPKG

dockerfile-language-service

Version:

A language service for Dockerfiles to enable the creation of feature-rich Dockerfile editors.

174 lines (173 loc) 8.53 kB
(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "vscode-languageserver-textdocument", "vscode-languageserver-types", "dockerfile-ast"], factory); } })(function (require, exports) { /* -------------------------------------------------------------------------------------------- * Copyright (c) Remy Suen. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. * ------------------------------------------------------------------------------------------ */ 'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.DockerFormatter = void 0; var vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument"); var vscode_languageserver_types_1 = require("vscode-languageserver-types"); var dockerfile_ast_1 = require("dockerfile-ast"); var DockerFormatter = /** @class */ (function () { function DockerFormatter() { } DockerFormatter.prototype.getIndentation = function (formattingOptions) { var indentation = "\t"; if (formattingOptions && formattingOptions.insertSpaces) { indentation = ""; for (var i = 0; i < formattingOptions.tabSize; i++) { indentation = indentation + " "; } } return indentation; }; /** * Creates a TextEdit for formatting the given document. * * @param document the document being formatted * @param start the start offset of the document's content to be replaced * @param end the end offset of the document's content to be replaced * @param indent true if this block should be replaced with an indentation, false otherwise * @param indentation the string to use for an indentation */ DockerFormatter.prototype.createFormattingEdit = function (document, start, end, indent, indentation) { if (indent) { return vscode_languageserver_types_1.TextEdit.replace({ start: document.positionAt(start), end: document.positionAt(end) }, indentation); } else { return vscode_languageserver_types_1.TextEdit.del({ start: document.positionAt(start), end: document.positionAt(end) }); } }; DockerFormatter.prototype.formatOnType = function (content, position, ch, options) { var dockerfile = dockerfile_ast_1.DockerfileParser.parse(content); // check that the inserted character is the escape character if (dockerfile.getEscapeCharacter() === ch) { for (var _i = 0, _a = dockerfile.getComments(); _i < _a.length; _i++) { var comment = _a[_i]; // ignore if we're in a comment if (comment.getRange().start.line === position.line) { return []; } } var directive = dockerfile.getDirective(); // ignore if we're in the parser directive if (directive && position.line === 0) { return []; } var document = vscode_languageserver_textdocument_1.TextDocument.create("", "", 0, content); validityCheck: for (var i = document.offsetAt(position); i < content.length; i++) { switch (content.charAt(i)) { case ' ': case '\t': break; case '\r': case '\n': break validityCheck; default: // not escaping a newline, no need to format the next line return []; } } var lines = [position.line + 1]; var indentedLines = []; indentedLines[lines[0]] = true; return this.formatLines(document, document.getText(), lines, indentedLines, options); } return []; }; DockerFormatter.prototype.formatRange = function (content, range, options) { var lines = []; for (var i = range.start.line; i <= range.end.line; i++) { lines.push(i); } return this.format(content, lines, options); }; /** * Formats the specified lines of the given document based on the * provided formatting options. * * @param document the text document to format * @param lines the lines to format * @param options the formatting options to use to perform the format * @return the text edits to apply to format the lines of the document */ DockerFormatter.prototype.format = function (content, lines, options) { var document = vscode_languageserver_textdocument_1.TextDocument.create("", "", 0, content); var dockerfile = dockerfile_ast_1.DockerfileParser.parse(content); var indentedLines = []; for (var i = 0; i < document.lineCount; i++) { indentedLines[i] = false; } for (var _i = 0, _a = dockerfile.getInstructions(); _i < _a.length; _i++) { var instruction = _a[_i]; var range = instruction.getRange(); indentedLines[range.start.line] = false; for (var i = range.start.line + 1; i <= range.end.line; i++) { indentedLines[i] = true; } } return this.formatLines(document, content, lines, indentedLines, options); }; DockerFormatter.prototype.formatLines = function (document, content, lines, indentedLines, options) { var indentation = this.getIndentation(options); var edits = []; lineCheck: for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) { var line = lines_1[_i]; var startOffset = document.offsetAt(vscode_languageserver_types_1.Position.create(line, 0)); for (var i = startOffset; i < content.length; i++) { switch (content.charAt(i)) { case ' ': case '\t': break; case '\r': case '\n': if (i !== startOffset) { // only whitespace on this line, trim it var edit = vscode_languageserver_types_1.TextEdit.del({ start: document.positionAt(startOffset), end: document.positionAt(i) }); edits.push(edit); } // process the next line continue lineCheck; default: // non-whitespace encountered if (i !== startOffset || indentedLines[line]) { var edit = this.createFormattingEdit(document, startOffset, i, indentedLines[line], indentation); edits.push(edit); } // process the next line continue lineCheck; } } if (startOffset < content.length) { // only whitespace on the last line, trim it var edit = vscode_languageserver_types_1.TextEdit.del({ start: document.positionAt(startOffset), end: document.positionAt(content.length) }); edits.push(edit); } } return edits; }; return DockerFormatter; }()); exports.DockerFormatter = DockerFormatter; });