Skip to content

Commit

Permalink
feat: support shortcut (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk authored Oct 29, 2021
1 parent bd31e6b commit 7ad7a1e
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 51 deletions.
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@ Converts between `px` and `rem` units in VSCode, And support WXSS.
# Features

- Support intellisense
- `px` -> `rem`
- `rem` -> `px`
- `px` -> `rpx` (微信小程序)
- `rpx` -> `px` (微信小程序)
- `px` -> `rem` (Shortcut key: `Alt + z`)
- `rem` -> `px` (Shortcut key: `Alt + z`)
- `px` -> `rpx` (微信小程序, 快捷键:`Alt + r`)
- `rpx` -> `px` (微信小程序, 快捷键:`Alt + r`)
- Support mouse hover to display the conversion process
- Support mark
- Support selected area

> You can use VSCODE's Keyboard shortcuts to redefine the shortcut keys.
# How To Use

+ Auto snippet
+ Move the cursor to `14px`, press `Alt + z` to convert `rem`
+ CLI: Press `F1`, enter `cssrem`

# Support Language
Expand Down
12 changes: 8 additions & 4 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@
# 特性

- 支持智能感知
- `px` -> `rem`
- `rem` -> `px`
- `px` -> `rpx` (微信小程序)
- `rpx` -> `px` (微信小程序)
- `px` -> `rem` (快捷键:`Alt + z`)
- `rem` -> `px` (快捷键:`Alt + z`)
- `px` -> `rpx` (微信小程序, 快捷键:`Alt + r`)
- `rpx` -> `px` (微信小程序, 快捷键:`Alt + r`)
- 支持鼠标悬停显示转化过程
- 支持直接打上标记
- 支持选中区域

> 可以利用VSCODE的Keyboard shortcuts重新定义快捷键。
# 如何使用

+ 在文件内自动转换,例如录入 `12px` 智能提醒对应转化后 `rem`
+ 光标至 `14px` 上,按下 `Alt + z` 对应转化 `rem`
+ 通过 `F1` 面板查找:`cssrem`

# 支持语言
Expand Down
42 changes: 30 additions & 12 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.4.3",
"version": "2.5.0",
"publisher": "cipchk",
"icon": "icon.png",
"license": "MIT",
Expand Down Expand Up @@ -66,13 +66,31 @@
"command": "extension.cssrem.rem-to-px",
"title": "CSSRem: Rem To Px"
},
{
"command": "extension.cssrem.rem-switch-px",
"title": "CSSRem: Rem <=> Px"
},
{
"command": "extension.cssrem.px-to-rpx",
"title": "CSSRem: Px To Rpx (小程序WXSS)"
},
{
"command": "extension.cssrem.rpx-to-px",
"title": "CSSRem: Rpx To Px (小程序WXSS)"
},
{
"command": "extension.cssrem.rpx-switch-px",
"title": "CSSRem: Rpx <=> Px (小程序WXSS)"
}
],
"keybindings": [
{
"command": "extension.cssrem.rem-switch-px",
"key": "Alt+z"
},
{
"command": "extension.cssrem.rpx-switch-px",
"key": "Alt+z+r"
}
],
"configuration": {
Expand Down Expand Up @@ -157,20 +175,20 @@
}
},
"devDependencies": {
"@types/node": "^10.12.2",
"typescript": "^3.1.6",
"vscode": "^1.1.21",
"mocha": "^2.3.3",
"@types/mocha": "^2.2.32",
"vsce": "^1.81.1",
"@types/node": "^16.11.6",
"typescript": "^4.4.4",
"vscode": "^1.1.37",
"mocha": "^9.1.3",
"@types/mocha": "^9.0.0",
"vsce": "^1.100.2",
"gulp": "^4.0.2",
"gulp-filter": "^5.1.0",
"gulp-sourcemaps": "^2.6.5",
"gulp-typescript": "^5.0.1",
"gulp-filter": "^7.0.0",
"gulp-sourcemaps": "^3.0.0",
"gulp-typescript": "6.0.0-alpha.1",
"run-sequence": "^2.2.1",
"del": "^4.1.1",
"del": "^6.0.0",
"event-stream": "^4.0.1",
"vscode-nls-dev": "^3.2.6"
"vscode-nls-dev": "^3.3.2"
},
"dependencies": {
"vscode-nls": "^5.0.0",
Expand Down
3 changes: 2 additions & 1 deletion src/completion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ export default class implements CompletionItemProvider {
}

return resolve(
res.map(i => {
res.map((i, idx) => {
const item = new CompletionItem(i.label, CompletionItemKind.Snippet);
if (i.documentation) {
item.documentation = new MarkdownString(i.documentation);
}
item.preselect = idx === 0;
item.insertText = i.value + (cog.addMark ? ` /* ${i.label} */` : ``);
return item;
}),
Expand Down
36 changes: 12 additions & 24 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,11 @@
import { commands, ExtensionContext, languages, Position, Range, Selection, TextEditor, workspace } from 'vscode';
import { commands, ExtensionContext, languages, workspace } from 'vscode';
import CssRemProvider from './completion';
import { cog, isIngore, loadConfig } from './config';
import { cog, loadConfig } from './config';
import CssRemHoverProvider from './hover';
import { Type } from './interface';
import { CssRemProcess } from './process';

let process: CssRemProcess;

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

let selection: Selection | Range = textEditor.selection;
if (selection.isEmpty) {
const start = new Position(0, 0);
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, process.convertAll(text, ingoresViaCommand, type));
});
}

export function activate(context: ExtensionContext) {
loadConfig();
workspace.onDidChangeConfiguration(() => loadConfig());
Expand All @@ -46,19 +28,25 @@ export function activate(context: ExtensionContext) {
const ingoresViaCommand = ((cog.ingoresViaCommand || []) as string[]).filter(w => !!w).map(v => (v.endsWith('px') ? v : `${v}px`));
context.subscriptions.push(
commands.registerTextEditorCommand('extension.cssrem', textEditor => {
modifyDocument(textEditor, ingoresViaCommand, 'pxToRem');
process.modifyDocument(textEditor, ingoresViaCommand, 'pxToRem');
}),
commands.registerTextEditorCommand('extension.cssrem.rem-to-px', textEditor => {
modifyDocument(textEditor, ingoresViaCommand, 'remToPx');
process.modifyDocument(textEditor, ingoresViaCommand, 'remToPx');
}),
commands.registerTextEditorCommand('extension.cssrem.rem-switch-px', textEditor => {
process.modifyDocument(textEditor, ingoresViaCommand, 'pxSwitchRem');
}),
);
if (cog.wxss) {
context.subscriptions.push(
commands.registerTextEditorCommand('extension.cssrem.px-to-rpx', textEditor => {
modifyDocument(textEditor, ingoresViaCommand, 'pxToRpx');
process.modifyDocument(textEditor, ingoresViaCommand, 'pxToRpx');
}),
commands.registerTextEditorCommand('extension.cssrem.rpx-to-px', textEditor => {
modifyDocument(textEditor, ingoresViaCommand, 'rpxToPx');
process.modifyDocument(textEditor, ingoresViaCommand, 'rpxToPx');
}),
commands.registerTextEditorCommand('extension.cssrem.rpx-switch-px', textEditor => {
process.modifyDocument(textEditor, ingoresViaCommand, 'rpxSwitchPx');
}),
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ export interface Config {

export interface Rule {
type: Type;
single: RegExp;
all: RegExp;
single?: RegExp;
fn: (text: string) => ConvertResult;
hover?: RegExp;
hoverFn?: (text: string) => HoverResult;
}

export type Type = 'pxToRem' | 'remToPx' | 'pxToRpx' | 'rpxToPx';
export type Type = 'pxToRem' | 'remToPx' | 'pxSwitchRem' | 'pxToRpx' | 'rpxToPx' | 'rpxSwitchPx';

export type RuleOPType = 'single' | 'all';

Expand Down
38 changes: 37 additions & 1 deletion src/process.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ConvertResult, Rule, RuleOPType, Type } from './interface';
import { RULES } from './rules';
import { Position, Range, Selection, TextEditor } from 'vscode';
import { isIngore } from './config';

export class CssRemProcess {
convert(text: string): ConvertResult[] | null {
Expand Down Expand Up @@ -34,10 +36,44 @@ export class CssRemProcess {
const result: { rule: Rule; text: string }[] = [];
for (const rule of RULES) {
const match = text.match(rule[type]);
if (match) {
if (match && match[1]) {
result.push({ rule, text: match[1] });
}
}
return result;
}

private getWordRange(textEditor: TextEditor, type: Type): Range | null {
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);
return rule && rule.all.test(word) ? range : null;
}

modifyDocument(textEditor: TextEditor, ingoresViaCommand: 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')) {
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);
selection = new Range(start, end);
}

const text = doc.getText(selection);
textEditor.edit(builder => {
builder.replace(selection, this.convertAll(text, ingoresViaCommand, type));
});
}
}
24 changes: 21 additions & 3 deletions src/rules.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as nls from 'vscode-nls';
import { cog } from './config';
import { Rule } from './interface';
import { Rule, Type } from './interface';

const localize = nls.config({ messageFormat: nls.MessageFormat.both })();

Expand Down Expand Up @@ -100,13 +100,22 @@ export function resetRules(): void {
};
},
},
{
type: 'pxSwitchRem',
all: /([-]?[\d.]+)(rem|px)/g,
fn: text => {
const type: Type = text.endsWith('px') ? 'pxToRem' : 'remToPx';
const rule = RULES.find(r => r.type === type);
return rule.fn(text);
},
},
);
if (cog.wxss) {
RULES.push(
{
type: 'pxToRpx',
single: /([-]?[\d.]+)p(x)?$/,
all: /([-]?[\d.]+)px/g,
single: /([-]?[\d.]+)p(x)?$/,
fn: text => {
const px = parseFloat(text);
const resultValue = +(px * (cog.wxssScreenWidth / cog.wxssDeviceWidth)).toFixed(cog.fixedDigits);
Expand Down Expand Up @@ -134,8 +143,8 @@ export function resetRules(): void {
},
{
type: 'rpxToPx',
single: /([-]?[\d.]+)r(p|px)?$/,
all: /([-]?[\d.]+)rpx/g,
single: /([-]?[\d.]+)r(p|px)?$/,
fn: text => {
const px = parseFloat(text);
const resultValue = +(px / (cog.wxssScreenWidth / cog.wxssDeviceWidth)).toFixed(cog.fixedDigits);
Expand Down Expand Up @@ -175,6 +184,15 @@ export function resetRules(): void {
};
},
},
{
type: 'rpxSwitchPx',
all: /([-]?[\d.]+)(rpx|px)/g,
fn: text => {
const type: Type = text.endsWith('px') ? 'pxToRpx' : 'rpxToPx';
const rule = RULES.find(r => r.type === type);
return rule.fn(text);
},
},
);
}
}

0 comments on commit 7ad7a1e

Please sign in to comment.