Fix bin/publish: use correct .env path for rspade_system Fix bin/publish script: prevent grep exit code 1 from terminating script 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
313 lines
13 KiB
JavaScript
Executable File
313 lines
13 KiB
JavaScript
Executable File
"use strict";
|
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
}
|
|
Object.defineProperty(o, k2, desc);
|
|
}) : (function(o, m, k, k2) {
|
|
if (k2 === undefined) k2 = k;
|
|
o[k2] = m[k];
|
|
}));
|
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
}) : function(o, v) {
|
|
o["default"] = v;
|
|
});
|
|
var __importStar = (this && this.__importStar) || (function () {
|
|
var ownKeys = function(o) {
|
|
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
var ar = [];
|
|
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
return ar;
|
|
};
|
|
return ownKeys(o);
|
|
};
|
|
return function (mod) {
|
|
if (mod && mod.__esModule) return mod;
|
|
var result = {};
|
|
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
__setModuleDefault(result, mod);
|
|
return result;
|
|
};
|
|
})();
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.JqhtmlFormattingEditProvider = void 0;
|
|
const vscode = __importStar(require("vscode"));
|
|
class JqhtmlFormattingEditProvider {
|
|
constructor() {
|
|
this.indentSize = 2;
|
|
// IMPORTANT: DO NOT USE REGEX FOR PARSING IN THIS FORMATTER
|
|
// This formatter uses string manipulation and indexOf for reliability
|
|
// Regex should only be used in the syntax highlighter, not here
|
|
// Based on the RS3 formatter (reformat_html.php) logic
|
|
// Patterns that increase indent on the NEXT line
|
|
this.indentIncrease = [': %>', ': ?>', '{ %>', '{ ?>'];
|
|
// Patterns that decrease indent
|
|
this.indentDecrease = [
|
|
'<% end; %>',
|
|
'<% endif; %>',
|
|
'<% endfor; %>',
|
|
'<% endforeach; %>',
|
|
'<% endfunction; %>',
|
|
'<% } %>',
|
|
'<% }); %>',
|
|
'<% } else',
|
|
'<% else'
|
|
];
|
|
// Known self-closing HTML tags
|
|
this.selfClosingTags = [
|
|
'area', 'base', 'br', 'embed', 'hr', 'iframe',
|
|
'img', 'input', 'link', 'meta', 'param', 'source', 'track'
|
|
];
|
|
}
|
|
provideDocumentFormattingEdits(document, options) {
|
|
this.indentSize = options.tabSize || 2;
|
|
const formatted = this.formatDocument(document);
|
|
const fullRange = new vscode.Range(document.positionAt(0), document.positionAt(document.getText().length));
|
|
return [vscode.TextEdit.replace(fullRange, formatted)];
|
|
}
|
|
formatDocument(document) {
|
|
const text = document.getText();
|
|
const safeCode = [];
|
|
let working = text;
|
|
let reading = text;
|
|
// Step 1: Escape HTML comments
|
|
working = '';
|
|
while (reading.indexOf('<!--') !== -1) {
|
|
const pos = reading.indexOf('<!--');
|
|
working += reading.substring(0, pos);
|
|
reading = reading.substring(pos);
|
|
const closePos = reading.indexOf('-->');
|
|
if (closePos === -1) {
|
|
// Parse error, return original
|
|
return text;
|
|
}
|
|
safeCode.push(reading.substring(0, closePos + 3));
|
|
reading = reading.substring(closePos + 3);
|
|
working += '@@__SAFE__(' + (safeCode.length - 1) + ')';
|
|
}
|
|
working += reading;
|
|
reading = working;
|
|
// Step 2: Escape multiline <% %> blocks
|
|
working = '';
|
|
while (reading.indexOf('<%') !== -1) {
|
|
const pos = reading.indexOf('<%');
|
|
working += reading.substring(0, pos);
|
|
reading = reading.substring(pos);
|
|
const closePos = reading.indexOf('%>');
|
|
if (closePos === -1) {
|
|
// Parse error, return original
|
|
return text;
|
|
}
|
|
const nlPos = reading.indexOf('\n');
|
|
if (nlPos === -1 || nlPos > closePos) {
|
|
// Not multiline, keep it
|
|
working += reading.substring(0, closePos + 2);
|
|
reading = reading.substring(closePos + 2);
|
|
continue;
|
|
}
|
|
// It's multiline, escape it
|
|
safeCode.push(reading.substring(0, closePos + 2));
|
|
reading = reading.substring(closePos + 2);
|
|
working += '@@__SAFE__(' + (safeCode.length - 1) + ')';
|
|
}
|
|
working += reading;
|
|
// Step 3: Split into lines with indent levels
|
|
const lines = [];
|
|
const splitLines = working.split('\n');
|
|
for (const line of splitLines) {
|
|
lines.push([0, line.trim()]);
|
|
}
|
|
// Step 4: Handle JS/control flow indents (if:, endif;, etc)
|
|
let jsIndent = 0;
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const trimmedLine = lines[i][1];
|
|
let plus = 0;
|
|
let minus = 0;
|
|
// Check for indent increase patterns
|
|
for (const pattern of this.indentIncrease) {
|
|
if (trimmedLine.indexOf(pattern) !== -1) {
|
|
plus++;
|
|
}
|
|
}
|
|
// Check for indent decrease patterns
|
|
for (const pattern of this.indentDecrease) {
|
|
if (trimmedLine.indexOf(pattern) !== -1) {
|
|
minus++;
|
|
}
|
|
}
|
|
// Apply indent changes
|
|
if (plus > minus) {
|
|
lines[i][0] = jsIndent;
|
|
jsIndent += plus;
|
|
jsIndent -= minus;
|
|
}
|
|
else {
|
|
jsIndent += plus;
|
|
jsIndent -= minus;
|
|
lines[i][0] = jsIndent;
|
|
}
|
|
// Special handling for else statements
|
|
if (trimmedLine.startsWith('<% else') ||
|
|
trimmedLine.startsWith('<% } else')) {
|
|
lines[i][0]--;
|
|
}
|
|
}
|
|
// Step 5: Escape remaining single-line code blocks
|
|
for (let i = 0; i < lines.length; i++) {
|
|
reading = lines[i][1];
|
|
working = '';
|
|
// Escape <% %> blocks
|
|
while (reading.indexOf('<%') !== -1) {
|
|
const pos = reading.indexOf('<%');
|
|
working += reading.substring(0, pos);
|
|
reading = reading.substring(pos);
|
|
const closePos = reading.indexOf('%>');
|
|
if (closePos === -1) {
|
|
working += reading;
|
|
reading = '';
|
|
continue;
|
|
}
|
|
safeCode.push(reading.substring(0, closePos + 2));
|
|
reading = reading.substring(closePos + 2);
|
|
working += '@@__SAFE__(' + (safeCode.length - 1) + ')';
|
|
}
|
|
working += reading;
|
|
lines[i][1] = working;
|
|
}
|
|
// Step 6: Handle HTML tag indents
|
|
let htmlIndent = 0;
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const line = lines[i][1];
|
|
let thisIndent = 0;
|
|
// Count opening tags
|
|
thisIndent += this.countOccurrences(line, '<');
|
|
// Subtract self-closing tags
|
|
thisIndent -= this.countOccurrences(line, '/>');
|
|
// Subtract closing tags (count double)
|
|
thisIndent -= this.countOccurrences(line, '</') * 2;
|
|
// Handle known self-closing tags
|
|
for (const tag of this.selfClosingTags) {
|
|
const searchStr = '<' + tag;
|
|
if (line.indexOf(searchStr) !== -1) {
|
|
// Split by this tag and check each occurrence
|
|
const parts = line.split(searchStr);
|
|
for (let j = 1; j < parts.length; j++) {
|
|
// Check if it's not self-closed with />
|
|
if (parts[j].indexOf('/>') === -1 && parts[j].indexOf('>') !== -1) {
|
|
thisIndent--;
|
|
}
|
|
else if (parts[j].indexOf('/>') !== -1 &&
|
|
parts[j].indexOf('>') !== -1 &&
|
|
parts[j].indexOf('/>') > parts[j].indexOf('>')) {
|
|
// Has both > and />, but > comes first
|
|
thisIndent--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Special case for DOCTYPE
|
|
if (line.indexOf('<!DOCTYPE') !== -1) {
|
|
thisIndent--;
|
|
}
|
|
// Apply indent changes
|
|
if (thisIndent < 0) {
|
|
// Negative change - apply before this line
|
|
htmlIndent += thisIndent;
|
|
lines[i][0] += htmlIndent;
|
|
}
|
|
else {
|
|
// Positive/zero change - apply after this line
|
|
lines[i][0] += htmlIndent;
|
|
htmlIndent += thisIndent;
|
|
}
|
|
// Multiline self-closing tag (line has /> but no <)
|
|
if (line.indexOf('/>') !== -1 && line.indexOf('<') === -1) {
|
|
lines[i][0]++;
|
|
}
|
|
}
|
|
// Step 7: Build result with proper indentation
|
|
let result = '';
|
|
for (const [indent, line] of lines) {
|
|
const finalIndent = Math.max(0, indent);
|
|
if (line.length > 0) {
|
|
result += ' '.repeat(finalIndent * this.indentSize) + line + '\n';
|
|
}
|
|
else {
|
|
result += '\n';
|
|
}
|
|
}
|
|
// Step 8: Restore safe blocks
|
|
for (let attempt = 0; attempt < 10; attempt++) {
|
|
let hasChanges = false;
|
|
for (let i = 0; i < safeCode.length; i++) {
|
|
const placeholder = '@@__SAFE__(' + i + ')';
|
|
if (result.indexOf(placeholder) !== -1) {
|
|
result = result.replace(placeholder, safeCode[i]);
|
|
hasChanges = true;
|
|
}
|
|
}
|
|
if (!hasChanges || result.indexOf('@@__SAFE__') === -1) {
|
|
break;
|
|
}
|
|
}
|
|
// Step 9: Add blank lines around Define tag contents
|
|
result = this.addDefineTagSpacing(result);
|
|
return result.trim();
|
|
}
|
|
addDefineTagSpacing(text) {
|
|
const lines = text.split('\n');
|
|
const resultLines = [];
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const currentLine = lines[i];
|
|
const trimmedCurrent = currentLine.trim();
|
|
// Check if this is an opening Define tag
|
|
if (trimmedCurrent.startsWith('<Define:') && trimmedCurrent.endsWith('>') && !trimmedCurrent.includes('</')) {
|
|
resultLines.push(currentLine);
|
|
// Check if next line exists and is not already blank
|
|
if (i + 1 < lines.length) {
|
|
const nextLine = lines[i + 1];
|
|
const trimmedNext = nextLine.trim();
|
|
// Only add blank line if:
|
|
// 1. Next line is not already blank
|
|
// 2. Next line is not the closing Define tag
|
|
if (trimmedNext.length > 0 && !trimmedNext.startsWith('</Define:')) {
|
|
resultLines.push('');
|
|
}
|
|
}
|
|
}
|
|
// Check if this is a closing Define tag
|
|
else if (trimmedCurrent.startsWith('</Define:') && trimmedCurrent.endsWith('>')) {
|
|
// Check if previous line exists and is not already blank
|
|
if (i > 0) {
|
|
const prevLine = lines[i - 1];
|
|
const trimmedPrev = prevLine.trim();
|
|
// Only add blank line if:
|
|
// 1. Previous line is not already blank
|
|
// 2. Previous line is not the opening Define tag
|
|
if (trimmedPrev.length > 0 && !trimmedPrev.startsWith('<Define:') && resultLines[resultLines.length - 1].trim().length > 0) {
|
|
resultLines.push('');
|
|
}
|
|
}
|
|
resultLines.push(currentLine);
|
|
}
|
|
else {
|
|
resultLines.push(currentLine);
|
|
}
|
|
}
|
|
return resultLines.join('\n');
|
|
}
|
|
countOccurrences(str, search) {
|
|
let count = 0;
|
|
let pos = 0;
|
|
while ((pos = str.indexOf(search, pos)) !== -1) {
|
|
count++;
|
|
pos += search.length;
|
|
}
|
|
return count;
|
|
}
|
|
}
|
|
exports.JqhtmlFormattingEditProvider = JqhtmlFormattingEditProvider;
|
|
//# sourceMappingURL=formatter.js.map
|