├── .gitignore
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── LICENSE
├── README.md
├── images
├── dark_flex
│ ├── content_center.svg
│ ├── content_center_column.svg
│ ├── content_flex-end.svg
│ ├── content_flex-end_column.svg
│ ├── content_flex-start.svg
│ ├── content_flex-start_column.svg
│ ├── content_space-around.svg
│ ├── content_space-around_column.svg
│ ├── content_space-between.svg
│ ├── content_space-between_column.svg
│ ├── content_space-evenly.svg
│ ├── content_space-evenly_column.svg
│ ├── content_stretch.svg
│ ├── content_stretch_column.svg
│ ├── icon_flex_direction_column.svg
│ ├── icon_flex_direction_column_reverse.svg
│ ├── icon_flex_direction_row.svg
│ ├── icon_flex_direction_row_reverse.svg
│ ├── items_baseline.svg
│ ├── items_center.svg
│ ├── items_center_column.svg
│ ├── items_flex-end.svg
│ ├── items_flex-end_column.svg
│ ├── items_flex-start.svg
│ ├── items_flex-start_column.svg
│ ├── items_stretch.svg
│ ├── items_stretch_column.svg
│ ├── justify-items-center.svg
│ ├── justify-items-end.svg
│ ├── justify-items-start.svg
│ ├── justify-items-stretch.svg
│ ├── wrap_nowrap.svg
│ ├── wrap_nowrap_column.svg
│ ├── wrap_wrap.svg
│ └── wrap_wrap_column.svg
├── flex_dark.svg
├── flex_light.svg
├── light_flex
│ ├── content_center.svg
│ ├── content_center_column.svg
│ ├── content_flex-end.svg
│ ├── content_flex-end_column.svg
│ ├── content_flex-start.svg
│ ├── content_flex-start_column.svg
│ ├── content_space-around.svg
│ ├── content_space-around_column.svg
│ ├── content_space-between.svg
│ ├── content_space-between_column.svg
│ ├── content_space-evenly.svg
│ ├── content_space-evenly_column.svg
│ ├── content_stretch.svg
│ ├── content_stretch_column.svg
│ ├── icon_flex_direction_column.svg
│ ├── icon_flex_direction_column_reverse.svg
│ ├── icon_flex_direction_row.svg
│ ├── icon_flex_direction_row_reverse.svg
│ ├── items_baseline.svg
│ ├── items_center.svg
│ ├── items_center_column.svg
│ ├── items_flex-end.svg
│ ├── items_flex-end_column.svg
│ ├── items_flex-start.svg
│ ├── items_flex-start_column.svg
│ ├── items_stretch.svg
│ ├── items_stretch_column.svg
│ ├── justify-items-center.svg
│ ├── justify-items-end.svg
│ ├── justify-items-start.svg
│ ├── justify-items-stretch.svg
│ ├── wrap_nowrap.svg
│ ├── wrap_nowrap_column.svg
│ ├── wrap_wrap.svg
│ └── wrap_wrap_column.svg
├── logo.png
└── readme
│ └── demo.gif
├── package-lock.json
├── package.json
├── src
├── extension.ts
└── flexboxPatterns.ts
├── test
└── text.scss
└── tsconfig.json
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | node_modules
3 | .vscode-test/
4 | *.vsix
5 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | // A launch configuration that compiles the extension and then opens it inside a new window
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | {
6 | "version": "0.2.0",
7 | "configurations": [{
8 | "name": "Run Extension",
9 | "type": "extensionHost",
10 | "request": "launch",
11 | "runtimeExecutable": "${execPath}",
12 | "args": [
13 | "--extensionDevelopmentPath=${workspaceFolder}"
14 | ],
15 | "outFiles": [
16 | "${workspaceFolder}/out/**/*.js"
17 | ],
18 | "preLaunchTask": "npm: watch"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "out": false
4 | },
5 | "search.exclude": {
6 | "out": true
7 | },
8 | "typescript.tsc.autoDetect": "off"
9 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | // See https://go.microsoft.com/fwlink/?LinkId=733558
2 | // for the documentation about the tasks.json format
3 | {
4 | "version": "2.0.0",
5 | "tasks": [
6 | {
7 | "type": "npm",
8 | "script": "watch",
9 | "problemMatcher": "$tsc-watch",
10 | "isBackground": true,
11 | "presentation": {
12 | "reveal": "never"
13 | },
14 | "group": {
15 | "kind": "build",
16 | "isDefault": true
17 | }
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 QiuQiu_XT
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CSS FlexCode(Grid)
2 | > 欢迎反馈交流,[点个Star~](https://github.com/xutao-o/css-flex-code)
3 | > Welcome to provide feedback and communicate, [please give it a star~](https://github.com/xutao-o/css-flex-code)
4 |
5 | [VS Code市场安装地址](https://marketplace.visualstudio.com/items?itemName=qiuqiu-xt.css-flex)
6 | [VS Code market installation address](https://marketplace.visualstudio.com/items?itemName=qiuqiu-xt.css-flex)
7 |
8 | 快捷生成CSS Flex布局与Grid布局代码的VS Code插件(类似于Google开发者控制台里的Flex布局工具)
9 | A VS Code extension that quickly generates CSS Flex and Grid layout code.
10 |
11 | - 支持多类css文件与框架(Support for multiple CSS files and frameworks)
12 | - 保持代码缩进格式(Maintain code indentation format)
13 | - 兼容深色与浅色主题(Compatible with both dark and light themes)
14 | - 自动替换同属性代码(Automatically replaces duplicate code with the same properties)
15 |
16 | ## 💻示例(Demo)
17 | 
18 |
19 | ### ⚠️注意事项(Warning )
20 | 不建议在压缩后的CSS代码或HTML的行内样式中使用插件
21 | This plugin is not recommended for use with compressed CSS code or inline styles in HTML.
22 |
23 | ### 😉致谢(Thank)
24 | - 由[小秋AI](https://www.xqai.net/)提供辅助支持,赞美AI!( [XiaoQiu AI](https://www.xqai.net/) provides auxiliary support. Praising AI!)
--------------------------------------------------------------------------------
/images/dark_flex/content_center.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_center_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_flex-end.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_flex-end_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_flex-start.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_flex-start_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_space-around.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_space-around_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_space-between.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_space-between_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_space-evenly.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_space-evenly_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_stretch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/content_stretch_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/icon_flex_direction_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/icon_flex_direction_column_reverse.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/icon_flex_direction_row.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/icon_flex_direction_row_reverse.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_baseline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_center.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_center_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_flex-end.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_flex-end_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_flex-start.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_flex-start_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_stretch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/items_stretch_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/justify-items-center.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/justify-items-end.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/justify-items-start.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/justify-items-stretch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/wrap_nowrap.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/wrap_nowrap_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/wrap_wrap.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/dark_flex/wrap_wrap_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/flex_dark.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/flex_light.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_center.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_center_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_flex-end.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_flex-end_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_flex-start.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_flex-start_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_space-around.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_space-around_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_space-between.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_space-between_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_space-evenly.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_space-evenly_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_stretch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/content_stretch_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/icon_flex_direction_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/icon_flex_direction_column_reverse.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/icon_flex_direction_row.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/icon_flex_direction_row_reverse.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_baseline.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_center.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_center_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_flex-end.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_flex-end_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_flex-start.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_flex-start_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_stretch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/items_stretch_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/justify-items-center.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/justify-items-end.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/justify-items-start.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/justify-items-stretch.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/wrap_nowrap.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/wrap_nowrap_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/wrap_wrap.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/light_flex/wrap_wrap_column.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xutao-o/css-flex-code/d9226bd77d4dddc020a89fc2590cd7f597cab2dc/images/logo.png
--------------------------------------------------------------------------------
/images/readme/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xutao-o/css-flex-code/d9226bd77d4dddc020a89fc2590cd7f597cab2dc/images/readme/demo.gif
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css_flex_code",
3 | "version": "0.0.1",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "css_flex_code",
9 | "version": "0.0.1",
10 | "devDependencies": {
11 | "@types/node": "^16.18.34",
12 | "@types/vscode": "^1.73.0",
13 | "typescript": "^5.2.2"
14 | },
15 | "engines": {
16 | "vscode": "^1.75.0"
17 | }
18 | },
19 | "node_modules/@types/node": {
20 | "version": "16.18.34",
21 | "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz",
22 | "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==",
23 | "dev": true
24 | },
25 | "node_modules/@types/vscode": {
26 | "version": "1.73.1",
27 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.73.1.tgz",
28 | "integrity": "sha512-eArfOrAoZVV+Ao9zQOCaFNaeXj4kTCD+bGS2gyNgIFZH9xVMuLMlRrEkhb22NyxycFWKV1UyTh03vhaVHmqVMg==",
29 | "dev": true
30 | },
31 | "node_modules/typescript": {
32 | "version": "5.2.2",
33 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
34 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
35 | "dev": true,
36 | "bin": {
37 | "tsc": "bin/tsc",
38 | "tsserver": "bin/tsserver"
39 | },
40 | "engines": {
41 | "node": ">=14.17"
42 | }
43 | }
44 | },
45 | "dependencies": {
46 | "@types/node": {
47 | "version": "16.18.34",
48 | "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.34.tgz",
49 | "integrity": "sha512-VmVm7gXwhkUimRfBwVI1CHhwp86jDWR04B5FGebMMyxV90SlCmFujwUHrxTD4oO+SOYU86SoxvhgeRQJY7iXFg==",
50 | "dev": true
51 | },
52 | "@types/vscode": {
53 | "version": "1.73.1",
54 | "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.73.1.tgz",
55 | "integrity": "sha512-eArfOrAoZVV+Ao9zQOCaFNaeXj4kTCD+bGS2gyNgIFZH9xVMuLMlRrEkhb22NyxycFWKV1UyTh03vhaVHmqVMg==",
56 | "dev": true
57 | },
58 | "typescript": {
59 | "version": "5.2.2",
60 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
61 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
62 | "dev": true
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "css-flex",
3 | "displayName": "CSS FlexCode(Grid)",
4 | "description": "一键生成Flex布局/Grid布局的CSS代码插件(类似于Google开发者控制台里的Flex布局工具) | A plugin to generate CSS Flex layout code (Similar to the Flexbox inspector tool in Google Developer Console)",
5 | "version": "1.1.1",
6 | "publisher": "qiuqiu-xt",
7 | "repository": "https://github.com/xutao-o/css-flex-code",
8 | "icon": "images/logo.png",
9 | "engines": {
10 | "vscode": "^1.75.0"
11 | },
12 | "categories": [
13 | "Snippets"
14 | ],
15 | "activationEvents": [
16 | "onLanguage:css",
17 | "onLanguage:less",
18 | "onLanguage:sass",
19 | "onLanguage:scss",
20 | "onLanguage:vue",
21 | "onLanguage:html",
22 | "onLanguage:jsx",
23 | "onLanguage:tsx",
24 | "onLanguage:svelte",
25 | "onLanguage:astro",
26 | "onLanguage:styl",
27 | "onLanguage:htm"
28 | ],
29 | "main": "./out/extension.js",
30 | "contributes": {
31 | "languages": [
32 | ]
33 | },
34 | "scripts": {
35 | "vscode:prepublish": "npm run compile",
36 | "compile": "tsc -p ./",
37 | "watch": "tsc -watch -p ./"
38 | },
39 | "devDependencies": {
40 | "@types/node": "^16.18.34",
41 | "@types/vscode": "^1.73.0",
42 | "typescript": "^5.2.2"
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | import * as vscode from 'vscode';
2 | import { join } from 'path';
3 | import * as flexboxPatterns from './flexboxPatterns';
4 |
5 | const supportedFiles = ['css', 'less', 'sass', 'scss', 'vue', 'html'];
6 | let decorationType: vscode.TextEditorDecorationType;
7 |
8 | export function activate(context: vscode.ExtensionContext) {
9 | decorationType = vscode.window.createTextEditorDecorationType({
10 | after: {
11 | margin: '0 0 0 0.25rem',
12 | width: '0.9rem',
13 | },
14 | dark: {
15 | after: {
16 | contentIconPath: context.asAbsolutePath(
17 | '/images/flex_light.svg'
18 | )
19 | },
20 | },
21 | light: {
22 | after: {
23 | contentIconPath: context.asAbsolutePath(
24 | '/images/flex_dark.svg'
25 | ),
26 | },
27 | },
28 | });
29 |
30 | const activeEditor = vscode.window.activeTextEditor;
31 |
32 | if (activeEditor) {
33 | decorate(activeEditor);
34 | }
35 |
36 |
37 | // 事件
38 | const disposableCommand = vscode.commands.registerCommand(
39 | 'flexcode.generating',
40 | (uri) => {
41 | const editor = vscode.window.activeTextEditor;
42 | if (!editor) {
43 | return;
44 | }
45 | const line = editor.document.lineAt(uri.posLine);
46 | // 根据缩进设置处理缩进格式
47 | let indentation = '';
48 | const tabSize = editor.options.tabSize || 4;
49 | const insertSpaces = editor.options.insertSpaces;
50 | const indentationLength = line.firstNonWhitespaceCharacterIndex;
51 | if (insertSpaces) {
52 | indentation = ' '.repeat(indentationLength);
53 | } else {
54 | const tabsCount = Math.floor(indentationLength / Number(tabSize));
55 | const spacesCount = indentationLength % Number(tabSize);
56 | indentation = '\t'.repeat(tabsCount) + ' '.repeat(spacesCount);
57 | }
58 | let upText = false
59 | // 遍历每个字符
60 | for (let i = uri.posLine - 1; i >= 0; i--) {
61 | const line = editor.document.lineAt(i);
62 | if(line.text.includes("{")){
63 | break
64 | }
65 | if(line.text.includes(uri.attr + ":")){
66 | upText = true
67 | editor.edit(editBuilder => {
68 | editBuilder.replace(line.range , indentation + `${uri.attr}: ${uri.code};`);
69 | });
70 | break
71 | }
72 | }
73 | for (let i = uri.posLine + 1; i < editor.document.lineCount; i++) {
74 | const line = editor.document.lineAt(i);
75 | if(line.text.includes("{") || line.text.includes("}")){
76 | break
77 | }
78 | if(line.text.includes(uri.attr + ":")){
79 | upText = true
80 | editor.edit(editBuilder => {
81 | editBuilder.replace(line.range , indentation + `${uri.attr}: ${uri.code};`);
82 | });
83 | break
84 | }
85 | }
86 | if(!upText){
87 | // 插入布局样式
88 | editor.edit(editBuilder => {
89 | const insertPosition = new vscode.Position(line.lineNumber, line.range.end.character);
90 | editBuilder.insert(insertPosition, '\n'+ indentation + `${uri.attr}: ${uri.code};`);
91 | });
92 | }
93 | }
94 | );
95 |
96 | const disposableVisibleTextEditors = vscode.window.onDidChangeVisibleTextEditors((event) => {
97 | let editor = vscode.window.activeTextEditor;
98 |
99 | if (editor && supportedFiles.includes(editor.document.languageId)) {
100 | decorate(editor);
101 | }
102 | });
103 |
104 | const disposableChangeDocument = vscode.workspace.onDidChangeTextDocument(
105 | (event) => {
106 | const openEditor = vscode.window.visibleTextEditors.filter(
107 | (editor) => editor.document.uri === event.document.uri
108 | )[0];
109 |
110 | if (
111 | openEditor &&
112 | supportedFiles.includes(openEditor.document.languageId)
113 | ) {
114 | decorate(openEditor);
115 | }
116 | }
117 | );
118 |
119 | // 悬浮信息
120 | const hoverProvider: vscode.HoverProvider = {
121 | provideHover(doc, pos, token): vscode.ProviderResult {
122 | const range = getPropertyRangeAtPosition(doc, pos);
123 | if (range === undefined) {
124 | return;
125 | }
126 | const markdownString = buildMarkdownString(context, pos.line);
127 | return new vscode.Hover(markdownString, range);
128 | },
129 | };
130 |
131 | const disposableHoverProvider = vscode.languages.registerHoverProvider(
132 | supportedFiles,
133 | hoverProvider
134 | );
135 |
136 | context.subscriptions.push(
137 | disposableCommand,
138 | disposableHoverProvider,
139 | disposableChangeDocument,
140 | disposableVisibleTextEditors,
141 | );
142 | }
143 |
144 |
145 | // 追加图标
146 | function decorate(editor: vscode.TextEditor) {
147 | const sourceCode = editor.document.getText();
148 |
149 | let decorationsArray: vscode.DecorationOptions[] = [];
150 |
151 | const sourceCodeArr = sourceCode.split('\n');
152 |
153 |
154 | function matchAll(pattern: RegExp, text: string): Array {
155 | const out: RegExpMatchArray[] = [];
156 | let match: RegExpMatchArray | null;
157 |
158 | pattern.lastIndex = 0;
159 |
160 | while ((match = pattern.exec(text))) {
161 | out.push(match);
162 | }
163 |
164 | return out;
165 | }
166 |
167 | for (let line = 0; line < sourceCodeArr.length; line++) {
168 | const sourceCode = sourceCodeArr[line];
169 |
170 | let matches = [] as any;
171 | for (const pattern of flexboxPatterns.allFlexboxPatterns) {
172 | matches = matchAll(pattern, sourceCode);
173 | if (matches.length > 0) {
174 | break;
175 | }
176 | }
177 | if (matches.length > 0) {
178 | matches.forEach((match:any) => {
179 | if (match.index !== undefined) {
180 | const flexIndex = sourceCode.indexOf(';', match.index) + 1;
181 | let range = new vscode.Range(
182 | new vscode.Position(line, match.index),
183 | new vscode.Position(line, flexIndex)
184 | );
185 | let decoration = { range };
186 | decorationsArray.push(decoration);
187 | }
188 | });
189 | }
190 | }
191 | editor.setDecorations(decorationType, decorationsArray);
192 | }
193 |
194 |
195 | // 主题
196 | function isDarkTheme() {
197 | const activeTheme = vscode.window.activeColorTheme;
198 | return activeTheme.kind === vscode.ColorThemeKind.Dark;
199 | }
200 |
201 |
202 |
203 | // 悬浮信息
204 | const getCommandUri = (attr:string, code:string, posLine: number) => {
205 | return vscode.Uri.parse(`command:flexcode.generating?${encodeURIComponent(JSON.stringify([{ attr, code, posLine }]))}`)
206 | }
207 | function buildMarkdownString(
208 | context: vscode.ExtensionContext,
209 | posLine: number
210 | ): vscode.MarkdownString[] {
211 | let markdownString: vscode.MarkdownString[] = [];
212 | const flexboxCommand = new vscode.MarkdownString();
213 | let imgUrl = isDarkTheme() ? 'light_flex' : 'dark_flex'
214 | const editor = vscode.window.activeTextEditor as any;
215 | let direction = "row"
216 |
217 | let LineText = editor.document.lineAt(posLine).text
218 | let flexBol = LineText.includes('flex')
219 | // 遍历字符
220 | for (let i = posLine - 1; i >= 0; i--) {
221 | const line = editor.document.lineAt(i);
222 | if(line.text.includes("{")){
223 | break
224 | }
225 | if(line.text.includes("flex-direction:")){
226 | const result = line.text.match(/flex-direction:\s*(.*?);/);
227 | if (result && result.length > 1) {
228 | direction = result[1].trim();
229 | }
230 | break
231 | }
232 | }
233 | for (let i = posLine + 1; i < editor.document.lineCount; i++) {
234 | const line = editor.document.lineAt(i);
235 | if(line.text.includes("{") || line.text.includes("}")){
236 | break
237 | }
238 | if(line.text.includes("flex-direction:")){
239 | const result = line.text.match(/flex-direction:\s*(.*?);/);
240 | if (result && result.length > 1) {
241 | direction = result[1].trim();
242 | }
243 | break
244 | }
245 | }
246 |
247 | if(!['row','column','row-reverse','column-reverse'].includes(direction)){
248 | direction = 'row'
249 | }
250 | let svgType = direction.includes('column') ? '_column' : ''
251 |
252 | const getSvg = (key: string) => {
253 | const alignmentMap = {
254 | 'flex-start': {
255 | 'row': 'content_flex-start_column.svg',
256 | 'column': 'content_flex-start.svg',
257 | 'row-reverse': 'content_flex-end_column.svg',
258 | 'column-reverse': 'content_flex-end.svg'
259 | },
260 | 'flex-end': {
261 | 'row': 'content_flex-end_column.svg',
262 | 'column': 'content_flex-end.svg',
263 | 'row-reverse': 'content_flex-start_column.svg',
264 | 'column-reverse': 'content_flex-start.svg'
265 | }
266 | } as any;
267 |
268 | if (alignmentMap[key]) {
269 | return alignmentMap[key][direction];
270 | }
271 | };
272 |
273 | const flex_html = `flex-direction
274 |
288 | flex-wrap
289 |
297 | align-content
298 |
318 | justify-content
319 |
339 | align-items
340 | `
357 |
358 | const grid_html = `align-content
359 |
376 | justify-content
377 |
397 | align-items
398 | justify-items
415 | `
429 |
430 | let HoverHtml = flexBol ? flex_html : grid_html
431 | flexboxCommand.appendMarkdown(HoverHtml)
432 | flexboxCommand.isTrusted = true
433 | flexboxCommand.supportHtml = true
434 | markdownString.push(flexboxCommand)
435 | return markdownString
436 | }
437 |
438 | function getPropertyRangeAtPosition(
439 | doc: vscode.TextDocument,
440 | pos: vscode.Position
441 | ) {
442 | let propertyRange: vscode.Range | undefined;
443 |
444 | for (const pattern of flexboxPatterns.allFlexboxPatterns) {
445 | const range = doc.getWordRangeAtPosition(pos, pattern);
446 |
447 | if (range) {
448 | propertyRange = range;
449 |
450 | break;
451 | }
452 | }
453 |
454 | return propertyRange;
455 | }
456 |
457 | export function deactivate() { }
458 |
--------------------------------------------------------------------------------
/src/flexboxPatterns.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Matches `display: flex` property
3 | */
4 | export const displayFlexPattern = /display:\s*flex;/g;
5 |
6 | /**
7 | * Matches `display: inline-flex` property
8 | */
9 | export const displayInlineFlexPattern = /display:\s*inline-flex;/g;
10 |
11 | /**
12 | * Matches `display: grid` property
13 | */
14 | export const displayGridPattern = /display:\s*grid;/g;
15 |
16 | /**
17 | * Matches `display: inline-grid` property
18 | */
19 | export const displayInlineGridPattern = /display:\s*inline-grid;/g;
20 |
21 | export const allFlexboxPatterns = [
22 | displayFlexPattern,
23 | displayInlineFlexPattern,
24 | displayGridPattern,
25 | displayInlineGridPattern
26 | ];
--------------------------------------------------------------------------------
/test/text.scss:
--------------------------------------------------------------------------------
1 | .test{
2 | display: flex;
3 | display: grid;
4 | flex-direction: column-reverse;
5 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es2020",
5 | "lib": ["es2020"],
6 | "outDir": "./out",
7 | "sourceMap": true,
8 | "strict": true,
9 | "rootDir": "src"
10 | },
11 | "exclude": ["node_modules", ".vscode-test"]
12 | }
--------------------------------------------------------------------------------