Skip to content

Commit

Permalink
feat: add currentLine, close #43 (#44)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk authored Nov 25, 2021
1 parent 16f823b commit a1748e1
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ Secondly, you can also configure the global. Open your user and workspace settin
| `cssrem.ingoresViaCommand` | Ignores `px` to `rem` when trigger command (Unit: `string[]`), can be set `[ "1px", "0.5px" ]` | `[]` |
| `cssrem.addMark` | Whether to enabled mark | `false` |
| `cssrem.hover` | Whether to enable display conversion data on hover, `disabled`: Disabled, `always` Anything, `onlyMark`: Only valid when `cssrem.addMark` is `true` | `onlyMark` |
| `cssrem.currentLine` | Whether to display mark in after line, `disabled`: Disabled, `show` Show | `show` |
| `cssrem.ingores` | Ignore file list, like this: `[ 'demo.less', 'src' ]` | `string[]` |
| `cssrem.languages` | Support language list, default: `[ 'html', 'vue', 'css', 'postcss', 'less', 'scss', 'sass', 'stylus', 'javascriptreact', 'typescriptreact' ]` | `string[]` |
| `cssrem.wxss` | **WXSS小程序样式** Whether to enable WXSS support | `false` |
Expand Down
1 change: 1 addition & 0 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ html vue css less scss sass stylus tpl(php smarty3) tsx jsx
| `cssrem.ingoresViaCommand` | 当使用命令行批量转换时,允许忽略部分 `px` 值不转换成 `rem`(单位:`string[]`),例如:`[ "1px", "0.5px" ]` | `[]` |
| `cssrem.addMark` | 是否启用加上标记 | `false` |
| `cssrem.hover` | 是否启用悬停时显示转换数据, `disabled`: Disabled, `always` Anything, `onlyMark`: Only valid when `cssrem.addMark` is `true` | `onlyMark` |
| `cssrem.currentLine` | 是否当前行尾显示标记,`disabled`: Disabled, `show` Show | `show` |
| `cssrem.ingores` | 忽略文件清单,例如:`[ 'demo.less', 'src' ]` | `string[]` |
| `cssrem.languages` | 支持语言清单,默认:`[ 'html', 'vue', 'css', 'postcss', 'less', 'scss', 'sass', 'stylus', 'javascriptreact', 'typescriptreact' ]` | `string[]` |
| `cssrem.wxss` | **WXSS小程序样式** 是否启用WXSS支持 | `false` |
Expand Down
1 change: 1 addition & 0 deletions examples/demo.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
body {
font-size: 1rem;
padding: 10px 12px 1rem 1.2rem;
}
3 changes: 3 additions & 0 deletions i18n/zh-cn/package.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"cssrem.hover.disabled": "禁用",
"cssrem.hover.always": "任何,不管是否由插件转换而来的都显示",
"cssrem.hover.onlyMark": "只对已经 `cssrem.addMark` 为 `true` 生效",
"cssrem.currentLine": "是否当前行尾显示标记, default: show",
"cssrem.currentLine.disabled": "禁用",
"cssrem.currentLine.show": "显示",
"cssrem.ingores": "忽略文件清单,例如:`[ 'demo.less', 'src' ]`",
"cssrem.languages": "支持语言清单,默认:`[ 'html', 'vue', 'css', 'postcss', 'less', 'scss', 'sass', 'stylus', 'javascriptreact', 'typescriptreact' ]`",
"cssrem.wxss": "是否启用WXSS支持",
Expand Down
37 changes: 35 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "cssrem",
"displayName": "px to rem & rpx (cssrem)",
"description": "Converts between px and rem & rpx units in VSCode",
"version": "2.5.1",
"version": "2.6.0",
"publisher": "cipchk",
"icon": "icon.png",
"license": "MIT",
Expand Down Expand Up @@ -156,6 +156,19 @@
},
"description": "%cssrem.languages%"
},
"cssrem.currentLine": {
"type": "string",
"enum": [
"disabled",
"show"
],
"default": "show",
"markdownEnumDescriptions": [
"%cssrem.currentLine.disabled%",
"%cssrem.currentLine.show%"
],
"description": "%cssrem.currentLine%"
},
"cssrem.wxss": {
"type": "boolean",
"default": false,
Expand All @@ -172,7 +185,27 @@
"description": "%cssrem.wxssDeviceWidth%"
}
}
}
},
"colors": [
{
"id": "extension.cssrem.trailingLineBackgroundColor",
"description": "Specifies the background color of the blame annotation for the current line",
"defaults": {
"dark": "#00000000",
"light": "#00000000",
"highContrast": "#00000000"
}
},
{
"id": "extension.cssrem.trailingLineForegroundColor",
"description": "Specifies the foreground color of the blame annotation for the current line",
"defaults": {
"dark": "#99999970",
"light": "#99999970",
"highContrast": "#99999999"
}
}
]
},
"devDependencies": {
"@types/node": "^16.11.6",
Expand Down
3 changes: 3 additions & 0 deletions package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"cssrem.hover.disabled": "Disabled",
"cssrem.hover.always": "Anything, whether converted by the plug-in or not, will be displayed",
"cssrem.hover.onlyMark": "Only valid when `cssrem.addMark` is `true`",
"cssrem.currentLine": "Whether to display mark in after line, default: show",
"cssrem.currentLine.disabled": "Disabled",
"cssrem.currentLine.show": "Show",
"cssrem.ingores": "Ignore file list, like this: `[ 'demo.less', 'src' ]`",
"cssrem.languages": "Support language list, default: `[ 'html', 'vue', 'css', 'postcss', 'less', 'scss', 'sass', 'stylus', 'javascriptreact', 'typescriptreact' ]`",
"cssrem.wxss": "Whether to enable WXSS support",
Expand Down
3 changes: 3 additions & 0 deletions package.nls.zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"cssrem.hover.disabled": "禁用",
"cssrem.hover.always": "任何,不管是否由插件转换而来的都显示",
"cssrem.hover.onlyMark": "只对已经 `cssrem.addMark` 为 `true` 生效",
"cssrem.currentLine": "是否当前行尾显示标记, default: show",
"cssrem.currentLine.disabled": "禁用",
"cssrem.currentLine.show": "显示",
"cssrem.ingores": "忽略文件清单,例如:`[ 'demo.less', 'src' ]`",
"cssrem.languages": "支持语言清单,默认:`[ 'html', 'vue', 'css', 'postcss', 'less', 'scss', 'sass', 'stylus', 'javascriptreact', 'typescriptreact' ]`",
"cssrem.wxss": "是否启用WXSS支持",
Expand Down
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { commands, ExtensionContext, languages, workspace } from 'vscode';
import CssRemProvider from './completion';
import { cog, loadConfig } from './config';
import CssRemHoverProvider from './hover';
import { LineAnnotation } from './line-annotation';
import { CssRemProcess } from './process';

let process: CssRemProcess;
Expand Down Expand Up @@ -50,6 +51,7 @@ export function activate(context: ExtensionContext) {
}),
);
}
if (cog.currentLine !== 'disabled') context.subscriptions.push(new LineAnnotation());
}

// this method is called when your extension is deactivated
Expand Down
2 changes: 1 addition & 1 deletion src/hover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default class implements HoverProvider {
private getText(line: string, pos: Position): string {
const point = pos.character;
let text = '';
line.replace(/[.0-9]+(px|rem|rpx)/g, (a, b, idx) => {
line.replace(/[.0-9]+(px|rem|rpx)/g, (a, _, idx) => {
const start = idx + 1;
const end = idx + a.length + 1;
if (!text && point >= start && point <= end) {
Expand Down
3 changes: 3 additions & 0 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface Config {
* Whether to enable display conversion data on hover, Default: onlyMark
*/
hover: 'disabled' | 'always' | 'onlyMark';
currentLine: 'disabled' | 'show';
/**
* 忽略清单
*/
Expand Down Expand Up @@ -67,4 +68,6 @@ export interface ConvertResult {
export interface HoverResult {
type: string;
documentation: string;
from: string;
to: string;
}
133 changes: 133 additions & 0 deletions src/line-annotation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import {
DecorationOptions,
DecorationRangeBehavior,
Disposable,
Range,
Selection,
TextDocument,
TextEditor,
TextEditorSelectionChangeEvent,
ThemeColor,
window,
} from 'vscode';
import { cog, isIngore } from './config';
import { RULES } from './rules';

const annotationDecoration = window.createTextEditorDecorationType({
after: {
margin: '0 0 0 1.5em',
textDecoration: 'none',
},
rangeBehavior: DecorationRangeBehavior.ClosedOpen,
});

interface LineSelection {
anchor: number;
active: number;
}

export class LineAnnotation implements Disposable {
protected _disposable?: Disposable;
private _editor?: TextEditor;
private _enabled = false;

constructor() {
this._disposable = Disposable.from(
window.onDidChangeActiveTextEditor(this.onActiveTextEditor, this),
window.onDidChangeTextEditorSelection(this.onTextEditorSelectionChanged, this),
);
}

private onActiveTextEditor(e: TextEditor) {
this._enabled = cog.languages.includes(e.document.languageId) && !isIngore(e.document.uri);
}

private onTextEditorSelectionChanged(e: TextEditorSelectionChangeEvent) {
if (!this._enabled) return;

if (!this.isTextEditor(e.textEditor)) return;

const selections = this.toLineSelections(e.selections);
if (selections.length === 0 || !selections.every(s => s.active === s.anchor)) {
this.clear(e.textEditor);
return;
}

this.refresh(e.textEditor, selections[0]);
}

private async refresh(editor: TextEditor | undefined, selection: LineSelection) {
if (editor.document == null || (editor == null && this._editor == null)) return;

if (this._editor !== editor) {
this.clear(this._editor);
this._editor = editor;
}

const l = selection.active;
const message = this.genMessage(editor.document, l);
if (message == null) {
this.clear(this._editor);
return;
}

const decoration: DecorationOptions = {
renderOptions: {
after: {
backgroundColor: new ThemeColor('extension.cssrem.trailingLineBackgroundColor'),
color: new ThemeColor('extension.cssrem.trailingLineForegroundColor'),
contentText: message,
fontWeight: 'normal',
fontStyle: 'normal',
textDecoration: 'none',
},
},
range: editor.document.validateRange(new Range(l, Number.MAX_SAFE_INTEGER, l, Number.MAX_SAFE_INTEGER)),
};

editor.setDecorations(annotationDecoration, [decoration]);
}

private genMessage(doc: TextDocument, lineNumber: number): string | null {
const text = doc.lineAt(lineNumber).text.trim();
if (text.length <= 0) return null;
const values = text.match(/([.0-9]+(px|rem|rpx))/g);
if (values == null) return null;

const results = values
.map(str => ({ text: str, rule: RULES.find(w => w.hover && w.hover.test(str)) }))
.filter(item => item.rule != null)
.map(item => item.rule.hoverFn(item.text));

if (results.length <= 0) return null;
if (results.length === 1) return results[0].to;
return results.map(res => `${res.to}->${res.from}`).join(', ');
}

private clear(editor: TextEditor | undefined) {
if (this._editor !== editor && this._editor != null) {
this.clearAnnotations(this._editor);
}
this.clearAnnotations(editor);
}

private clearAnnotations(editor: TextEditor | undefined) {
if (editor === undefined || (editor as any)._disposed === true) return;

editor.setDecorations(annotationDecoration, []);
}

private isTextEditor(editor: TextEditor): boolean {
const scheme = editor.document.uri.scheme;
return scheme !== 'output' && scheme !== 'debug';
}

dispose() {
this.clearAnnotations(this._editor);
this._disposable.dispose();
}

toLineSelections(selections: readonly Selection[] | undefined): LineSelection[] {
return selections?.map(s => ({ active: s.active.line, anchor: s.anchor.line }));
}
}
15 changes: 12 additions & 3 deletions src/rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@ export function resetRules(): void {
},
hover: /([-]?[\d.]+)px/,
hoverFn: pxText => {
const val = +(parseFloat(pxText) / cog.rootFontSize).toFixed(cog.fixedDigits);
const px = parseFloat(pxText);
const val = +(px / cog.rootFontSize).toFixed(cog.fixedDigits);
return {
type: 'remToPx',
from: `${px}px`,
to: `${val}rem`,
documentation: localize(
`pxToRem.documentation.hover`,
'Converted from `{0}rem` according to the benchmark font-size is `{1}px`',
Expand Down Expand Up @@ -88,9 +91,12 @@ export function resetRules(): void {
},
hover: /([-]?[\d.]+)rem/,
hoverFn: remText => {
const val = +(parseFloat(remText) * cog.rootFontSize).toFixed(cog.fixedDigits);
const rem = parseFloat(remText);
const val = +(rem * cog.rootFontSize).toFixed(cog.fixedDigits);
return {
type: 'pxToRem',
from: `${rem}rem`,
to: `${val}px`,
documentation: localize(
`remToPx.documentation.hover`,
'Converted from `{0}px` according to the benchmark font-size is `{1}px`, please refer to [Configuration Document](https://github.com/cipchk/vscode-cssrem#configuration) modify',
Expand Down Expand Up @@ -171,9 +177,12 @@ export function resetRules(): void {
},
hover: /([-]?[\d.]+)rpx/,
hoverFn: rpxText => {
const val = +(parseFloat(rpxText) / (cog.wxssScreenWidth / cog.wxssDeviceWidth)).toFixed(cog.fixedDigits);
const rpx = parseFloat(rpxText);
const val = +(rpx / (cog.wxssScreenWidth / cog.wxssDeviceWidth)).toFixed(cog.fixedDigits);
return {
type: 'rpxToPx',
from: `${rpx}rpx`,
to: `${val}px`,
documentation: localize(
`rpxToPx.documentation.hover`,
'**WXSS miniprogram style** Converted from `{0}px` (The current device width is `{1}px` and screen width is `{2}px`)',
Expand Down

0 comments on commit a1748e1

Please sign in to comment.