Skip to content

Commit

Permalink
feat: support ignore code (#71)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk authored Nov 12, 2024
1 parent cb67ea7 commit b3b45cc
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 40 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ Converts between `px` and `rem` units in VSCode, And support WXSS.
+ Move the cursor to `14px`, press `Alt + z` to convert `rem`
+ CLI: Press `F1`, enter `cssrem`

## Ignoring code

You can ignore:
- Entire files by setting ignores in `.cssrem` or `.vscode/settings.json`
- The next line by using `// cssrem-disable-next-line`

```less
// cssrem-disable-next-line
@media (min-width: 768px) {}
```
> The above code will ignore processing of `768px`
# Support Language

html vue css less scss sass stylus tpl(php smarty3) tsx jsx
Expand Down
12 changes: 12 additions & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,18 @@
+ 光标至 `14px` 上,按下 `Alt + z` 对应转化 `rem`
+ 通过 `F1` 面板查找:`cssrem`

## 忽略代码

你可以忽略:
- 通过 `.cssrem``.vscode/settings.json` 设置 `ignores` 忽略整个文件
- 通过使用 `// cssrem-disable-next-line` 表示忽略下一行的处理

```less
// cssrem-disable-next-line
@media (min-width: 768px) {}
```
> 以上代码将忽略 `768px` 的处理
# 支持语言

html vue css less scss sass stylus tpl(php smarty3) tsx jsx
Expand Down
12 changes: 12 additions & 0 deletions examples/.cssrem
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"$schema": "https://raw.githubusercontent.com/cipchk/vscode-cssrem/master/schema.json",
"rootFontSize": 24,
"fixedDigits": 3,
"vw": true,
"currentLine": "show",
"ignores": [
// "**/*.less",
// "*.tsx"
],
"ignoresViaCommand": []
}
13 changes: 11 additions & 2 deletions examples/demo.less
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
body {
font-size: 1rem;
padding: 10px 12px 1rem 1.2rem;
font-size: 48px;
padding: 10px 12px 24px 28.8px;
margin: 7.5px 1vw;
}

// cssrem-disable-next-line
@media (min-width: 768px) {
body {
font-size: 28.8px;
padding: 10px 12px 24px 28.8px;
margin: 7.5px 1vw;
}
}
2 changes: 2 additions & 0 deletions src/completion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { CompletionItem, CompletionItemKind, CompletionItemProvider, MarkdownString, Position, Range, TextDocument } from 'vscode';
import { cog, isIngore } from './config';
import { CssRemProcess } from './process';
import { isDisabledNextLine } from './ignore-comment';

export default class implements CompletionItemProvider {
constructor(private _: string, private process: CssRemProcess) {}
Expand All @@ -9,6 +10,7 @@ export default class implements CompletionItemProvider {
if (isIngore(document.uri)) return Promise.resolve([]);

return new Promise(resolve => {
if (isDisabledNextLine(document, position.line)) return null;
const lineText = document.getText(new Range(position.with(undefined, 0), position));
const res = this.process.convert(lineText);
if (res == null || res.length === 0) {
Expand Down
40 changes: 28 additions & 12 deletions src/hover.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
import { Hover, HoverProvider, MarkdownString, Position, ProviderResult, TextDocument } from 'vscode';
import { cog, isIngore } from './config';
import { RULES } from './rules';
import {
Hover,
HoverProvider,
MarkdownString,
Position,
ProviderResult,
TextDocument,
} from "vscode";
import { cog, isIngore } from "./config";
import { RULES } from "./rules";
import { isDisabledNextLine } from "./ignore-comment";

export default class implements HoverProvider {
private getText(line: string, pos: Position): string {
const point = pos.character;
let text = '';
let text = "";
line.replace(/[.0-9]+(px|rem|rpx|vw)/g, (a, _, idx) => {
const start = idx + 1;
const end = idx + a.length + 1;
if (!text && point >= start && point <= end) {
text = a;
}
return '';
return "";
});
return text;
}
Expand All @@ -24,15 +32,23 @@ export default class implements HoverProvider {
if (!text) {
return null;
}
let results = RULES.filter(w => w.hover && w.hover.test(text) && w.hoverFn != null)
.map(rule => rule.hoverFn!(text))
.filter(h => h != null && h.documentation);
if (cog.hover === 'onlyMark') {
results = results.filter(w => !line.includes(`/* ${w.type} */`));
if (isDisabledNextLine(doc, pos.line)) {
return null;
}
let results = RULES.filter(
(w) => w.hover && w.hover.test(text) && w.hoverFn != null
)
.map((rule) => rule.hoverFn!(text))
.filter((h) => h != null && h.documentation);
if (cog.hover === "onlyMark") {
results = results.filter((w) => !line.includes(`/* ${w.type} */`));
}
if (results.length === 0) return null;
if (results.length === 1) return new Hover(new MarkdownString(results[0].documentation));
if (results.length === 1)
return new Hover(new MarkdownString(results[0].documentation));

return new Hover(new MarkdownString(results.map(h => `- ${h.documentation}`).join('\n')));
return new Hover(
new MarkdownString(results.map((h) => `- ${h.documentation}`).join("\n"))
);
}
}
13 changes: 13 additions & 0 deletions src/ignore-comment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { TextDocument } from 'vscode';

export const DISABLE_NEXT_LINE_COMMAND = 'cssrem-disable-next-line';

export function isDisabledNextLineViaText(line: string): boolean {
return line.includes(DISABLE_NEXT_LINE_COMMAND);
}

export function isDisabledNextLine(doc: TextDocument, lineNumber: number): boolean {
if (lineNumber - 1 < 0) return false;
const line = doc.lineAt(lineNumber - 1).text.trim();
return isDisabledNextLineViaText(line);
}
2 changes: 2 additions & 0 deletions src/line-annotation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import { cog, isIngore } from './config';
import { HoverResult } from './interface';
import { RULES } from './rules';
import { isDisabledNextLine } from './ignore-comment';

const annotationDecoration = window.createTextEditorDecorationType({
after: {
Expand Down Expand Up @@ -93,6 +94,7 @@ export class LineAnnotation implements Disposable {
private genMessage(doc: TextDocument, lineNumber: number): string | null {
const text = doc.lineAt(lineNumber).text.trim();
if (text.length <= 0) return null;
if (isDisabledNextLine(doc, lineNumber)) return null;
const values = text.match(/([.0-9]+(px|rem|rpx|vw))/g);
if (values == null) return null;

Expand Down
79 changes: 53 additions & 26 deletions src/process.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,55 @@
import { ConvertResult, Rule, RuleOPType, Type } from './interface';
import { RULES } from './rules';
import { Position, Range, Selection, TextEditor } from 'vscode';
import { isIngore } from './config';
import { ConvertResult, Rule, RuleOPType, Type } from "./interface";
import { RULES } from "./rules";
import { Position, Range, Selection, TextEditor } from "vscode";
import { isIngore } from "./config";
import { isDisabledNextLineViaText } from "./ignore-comment";

export class CssRemProcess {
convert(text: string): ConvertResult[] | null {
const res = this.getRule('single', text);
const res = this.getRule("single", text);
if (res.length === 0) {
return null;
}

return res.map(i => i.rule.fn(i.text)!);
return res.map((i) => i.rule.fn(i.text)!);
}

convertAll(code: string, ignores: string[], type: Type): string {
private convertAll(code: string, ignores: string[], type: Type): string {
if (!code) {
return code;
}

const rule = RULES.find(w => w.type === type);
const rule = RULES.find((w) => w.type === type);
if (!rule) {
return code;
}

return code.replace(rule.all, (word: string) => {
if (ignores.includes(word)) {
return word;
}
const res = rule.fn(word);
if (res) {
return res.value;
}
return word;
});
const lines = code.split("\n");

const result = lines
.map((line, lineIndex) => {
return line.replace(rule.all, (word) => {
if (ignores.includes(word)) {
return word;
}
if (lineIndex > 0 && isDisabledNextLineViaText(lines[lineIndex - 1]))
return word;

const res = rule.fn(word);
if (res) {
return res.value;
}
return word;
});
})
.join("\n");
return result;
}

private getRule(type: RuleOPType, text: string): { rule: Rule; text: string }[] {
private getRule(
type: RuleOPType,
text: string
): { rule: Rule; text: string }[] {
const result: { rule: Rule; text: string }[] = [];
for (const rule of RULES) {
const match = text.match((rule as any)[type]);
Expand All @@ -47,36 +61,49 @@ export class CssRemProcess {
}

private getWordRange(textEditor: TextEditor, type: Type): Range | null {
const position = new Position(textEditor.selection.start.line, textEditor.selection.start.character);
const position = new Position(
textEditor.selection.start.line,
textEditor.selection.start.character
);
const range = textEditor.document.getWordRangeAtPosition(position);
if (!range) return null;
const word = textEditor.document.getText(range);
if (!word) return null;
const rule = RULES.find(w => w.type === type);
const rule = RULES.find((w) => w.type === type);
return rule && rule.all.test(word) ? range : null;
}

modifyDocument(textEditor: TextEditor, ignoresViaCommand: string[], type: Type): void {
modifyDocument(
textEditor: TextEditor,
ignoresViaCommand: string[],
type: Type
): void {
const doc = textEditor.document;
if (isIngore(doc.uri)) return;

let selection: Selection | Range = textEditor.selection;
// When the cursor is in the valid range in switch mode
if (selection.isEmpty && type.toLowerCase().includes('switch')) {
if (selection.isEmpty && type.toLowerCase().includes("switch")) {
const wordRange = this.getWordRange(textEditor, type);
if (wordRange) {
selection = wordRange;
}
}
if (selection.isEmpty) {
const start = new Position(0, 0);
const end = new Position(doc.lineCount - 1, doc.lineAt(doc.lineCount - 1).text.length);
const end = new Position(
doc.lineCount - 1,
doc.lineAt(doc.lineCount - 1).text.length
);
selection = new Range(start, end);
}

const text = doc.getText(selection);
textEditor.edit(builder => {
builder.replace(selection, this.convertAll(text, ignoresViaCommand, type));
textEditor.edit((builder) => {
builder.replace(
selection,
this.convertAll(text, ignoresViaCommand, type)
);
});
}
}

0 comments on commit b3b45cc

Please sign in to comment.