├── settings.gradle ├── src ├── main │ ├── resources │ │ ├── images │ │ │ └── px2rwd.gif │ │ ├── intentionDescriptions │ │ │ ├── PX2VHIntention │ │ │ │ ├── description.html │ │ │ │ ├── before.css.template │ │ │ │ └── after.css.template │ │ │ ├── PX2VWIntention │ │ │ │ ├── description.html │ │ │ │ ├── before.css.template │ │ │ │ └── after.css.template │ │ │ ├── PX2REMIntention │ │ │ │ ├── description.html │ │ │ │ ├── after.css.template │ │ │ │ └── before.css.template │ │ │ └── RollbackIntention │ │ │ │ ├── after.css.template │ │ │ │ ├── description.html │ │ │ │ └── before.css.template │ │ └── META-INF │ │ │ └── plugin.xml │ └── java │ │ └── com │ │ └── sunqian │ │ ├── constvalue │ │ ├── ShortCutType.java │ │ ├── MagicValue.java │ │ └── ConstValue.java │ │ ├── utils │ │ ├── ExceptionUtils.java │ │ ├── CollectionUtils.java │ │ ├── StringUtils.java │ │ ├── LogicUtils.java │ │ ├── NumberUtils.java │ │ └── FormatTools.java │ │ ├── completion │ │ ├── PX2RWDCompletion.java │ │ └── PX2RWDProvider.java │ │ ├── intention │ │ ├── IntentionUtils.java │ │ ├── PX2VHIntention.java │ │ ├── PX2VWIntention.java │ │ ├── PX2REMIntention.java │ │ └── RollbackIntention.java │ │ ├── action │ │ ├── ConvertRollback.java │ │ ├── PX2RWDWithFile.java │ │ └── PX2RWDWithLine.java │ │ ├── model │ │ └── ActionPerformer.java │ │ └── settings │ │ ├── ProjectSettingConfig.java │ │ ├── ProjectSettingsPage.java │ │ └── ProjectSettingsPage.form └── test │ └── java │ └── com │ └── sunqian │ └── px2rwd │ └── test │ └── P2RTestApplication.java ├── gradle └── wrapper │ └── gradle-wrapper.properties ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── LICENSE ├── .gitignore ├── gradlew.bat ├── README_CN.md ├── README.md └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'px2rem' 2 | 3 | -------------------------------------------------------------------------------- /src/main/resources/images/px2rwd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sunqian1991/px2rwd-intellij-plugin/HEAD/src/main/resources/images/px2rwd.gif -------------------------------------------------------------------------------- /src/test/java/com/sunqian/px2rwd/test/P2RTestApplication.java: -------------------------------------------------------------------------------- 1 | package com.sunqian.px2rwd.test; 2 | 3 | public class P2RTestApplication { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/sunqian/constvalue/ShortCutType.java: -------------------------------------------------------------------------------- 1 | package com.sunqian.constvalue; 2 | 3 | public enum ShortCutType { 4 | REM,VW,VH,PX,CM 5 | } 6 | -------------------------------------------------------------------------------- /src/main/resources/intentionDescriptions/PX2VHIntention/description.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |This intention converts px to vh. 4 |
5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/intentionDescriptions/PX2VWIntention/description.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |This intention converts px to vw. 4 |
5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/intentionDescriptions/PX2REMIntention/description.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |This intention converts px to rem. 4 |
5 | 6 | -------------------------------------------------------------------------------- /src/main/resources/intentionDescriptions/RollbackIntention/after.css.template: -------------------------------------------------------------------------------- 1 | .class-name{ 2 | padding:4 | convert rem/vw/vh to px 5 |
6 | 7 | -------------------------------------------------------------------------------- /src/main/resources/intentionDescriptions/RollbackIntention/before.css.template: -------------------------------------------------------------------------------- 1 | .class-name{ 2 | padding:
22 | * 0 处理整行
23 | * 1 处理选中的文字
24 | *
25 | * @author sunqian
26 | * @date 2019/6/10
27 | */
28 | @SuppressWarnings("ALL")
29 | public class PX2RWDWithLine extends AnAction {
30 |
31 | @Override
32 | public void actionPerformed(AnActionEvent anActionEvent) {
33 | Optional.ofNullable(ActionPerformer.getActionPerformer(anActionEvent.getRequiredData(CommonDataKeys.PROJECT), anActionEvent.getRequiredData(CommonDataKeys.EDITOR))).ifPresent(ap ->
34 | LogicUtils.getLogic().conOrEnd(anActionEvent.getData(LangDataKeys.PSI_FILE), file -> Objects.nonNull(file) && (!ap.getConstValue().getOnlyCssFiles() || StringUtils.containsAny(file.getLanguage().getID(), STYLE_SHEET_LANGUAGE_ID, LESS_LANGUAGE_ID, SASS_LANGUAGE_ID, HTML_LANGUAGE_ID, SCSS_LANGUAGE_ID, STYLUS_LANGUAGE_ID)), file ->
35 | Optional.of(FormatTools.getFormatTools(ap.getConstValue())).ifPresent(formatTools ->
36 | LogicUtils.getLogic().generateObject(new HashMap
there are three ways to convert: short-cut key, code intention, code completion. you can find the settings related to these converting ways in settings page with the path 'File - Settings - Px to Rem'
10 |1. short-cut key
12 |select a converting type from three options of rem, vw, vh in setting page and give a necessary value set below the radio group, then use the default short-cut key of Alt + d to convert a line or a selected text. you can also use the short-cut key of Ctrl + Alt + d to convert in a whole file.
14 |you can only choose one converting type of short-cut key from rem,vw,vg to convert.
15 |btw, you can change the short-cut key in your ide by setting the keymap option.
16 |2. code intention
18 |you can find three code intention types in settings page and you can select if a code intention type works by check the checkbox.
20 |by check a code intention in a line of a css file, which will display by typing Alt + Enter, you can convert the line where the caret displays.
21 |the unselected code intention types in settings page will not show in the list of code intention in a css file
22 |3. code completion
24 |you can also find three code completion types in the settings page and you can select if a code completion type works by check the checkbox.
26 |by typing 'px' in a css file, you can find some code completion types you set in settings page. choose a type then it will give a result of converting.
27 |the unselected code completion types in settings page will not show in the list of code completion in a css file
28 |Instructions:
30 |1. find menu at 'File - Settings - Px to Rem', and give some settings.
31 |2. select a text or move cursor at a line which contains a 'px' value.
32 |3. use default shortcut key Alt + d to convert px to rem/vw/vh with a line; btw, you can change the shortcut at 'File - Settings - keymap - Plug-ins - px2rem'.
33 |4. use default shortcut key Ctrl + Alt + d to convert px to rem/vw/vh in a whole file.
34 |5. use a code intention to convert px to rem/vw/vh in a css file
35 |6. use a code completion to convert px to rem/vw/vh in a css file
36 |7. use the short-cut key Ctrl + Shift + Alt + d to rollback the converting within one line
37 |this plugin only support css, less file type and you should not use it in other file types, because this will bring some unexpected errors.
39 |you can find more details in github
41 |if this plugin is not bad, you can give me a star in github and I will be very grateful for your support.
43 |这是一个转换css文件中的px单位为rem/vw/vh等单位的插件,主要适用于idea和webstorm.
45 |目前提供了三种方式来转换:快捷键、代码意图提示(Alt + Enter)、代码自动完成提示
47 |1. 快捷键
49 |默认的快捷键是Alt + d,在插件配置页面中可以看到快捷键部分有3种转换类型的选项,分别是rem,vw,vh,选择其中的一个来使用快捷键转换,需要注意的是,需要在选项下方的值配置中设置对应的基值。
51 |只能选择一种转换类型来使用快捷键转换单位。同时也可以重新设置快捷键。需要注意的是,跟之前的版本相比,默认的快捷键修改了,修改的原因主要是原来的'Shift' + 'd'会与大小写冲突。
52 |2. code intention
54 |选择使用代码意图提示的类型后即可使用已选择的类型来在css文件中通过Alt + Enter来调用code intention来快捷转换单位。未勾选的选项不会出现在文件的code intention列表中。
56 |3. code completion
58 |选择使用代码自动提示的类型后即可使用已选择的类型来在css文件中快捷转换单位,当输入'px'后,code completion列表中会出现在配置页面中选择的类型名称,选择其中一个类型后即可实现自动完成转换功能。
60 |如果觉得这个插件还不错,希望可以在github上给我点个赞,非常感激。
62 |插件仅支持css和less两种文件类型,在其他的样式文件类型如sass中也可以使用某一些功能,但可能会引起某些未知的错误,请谨慎使用!
64 |使用说明:
66 |1. File-Settings-Px to Rem进行必要的参数配置
67 |2. 选择一个需要转换的样式或者将光标移动到一个包含需要转换样式的行中,使用快捷键Alt + d来转换,也可以使用Ctrl + Alt + d来转换整个文件中的可转换样式
68 |3. 通过code intentionAlt + Enter来转换某一行中涉及到的样式
69 |4. 通过在输入'px'字符后显示的自动完成提示列表中选择相应的选项来转换相应的样式
70 |5. 通过快捷键Ctrl + Shift + Alt + d来回退一行内的转换
71 |更多请前往github查看
73 | ]]> 74 | 75 | 76 |
202 | * 这里行号取的是当前光标所在的行
203 | *
204 | * @param actionPerformer 获取的动作参数
205 | */
206 | public void formatLineCode(ActionPerformer actionPerformer, ShortCutType shortCutType) {
207 | actionPerformer.getCaretModel().runForEachCaret(caret -> formatLineCode(actionPerformer, actionPerformer.getDocument().getLineNumber(caret.getOffset()), shortCutType));
208 | }
209 |
210 | /**
211 | * 转换一行代码中的样式单位
212 | *
213 | * @param actionPerformer 获取的动作参数
214 | * @param lineNum 行号
215 | */
216 | public void formatLineCode(ActionPerformer actionPerformer, int lineNum, ShortCutType shortCutType) {
217 | // 行起始offset
218 | Optional.of(actionPerformer.getDocument().getLineStartOffset(lineNum)).ifPresent(lineStartOffset -> {
219 | // 行结束offset
220 | Optional.of(actionPerformer.getDocument().getLineEndOffset(lineNum)).ifPresent(lineEndOffset ->
221 | Optional.of(actionPerformer.getDocument().getText(new TextRange(lineStartOffset, lineEndOffset)))
222 | .filter(lineContent -> lineContent.toLowerCase().contains(PX_STYLE_TAG))
223 | .map(lineContent -> {
224 | WriteCommandAction.runWriteCommandAction(actionPerformer.getProject(), () ->
225 | actionPerformer.getDocument().replaceString(
226 | lineStartOffset,
227 | lineEndOffset,
228 | getFormatLine(lineContent, shortCutType, PX_STYLE_TAG, (value, type) -> getFormatText(value, shortCutType)))
229 | );
230 | return lineContent;
231 | })
232 | );
233 | });
234 | }
235 |
236 | /**
237 | * 格式化光标处往前最近的一个可格化的长度
238 | *
239 | * @param actionPerformer 获取的动作参数
240 | */
241 | public void formatNearCode(ActionPerformer actionPerformer, ShortCutType shortCutType, ShortCutType unit) {
242 | Document document = actionPerformer.getDocument();
243 | CaretModel caretModel = actionPerformer.getCaretModel();
244 | int lineNum = document.getLineNumber(caretModel.getOffset());
245 | int lineStartOffset = document.getLineStartOffset(lineNum);
246 | String lineContent = document.getText(new TextRange(lineStartOffset, caretModel.getOffset()));
247 | String content = lineContent.substring(getNearCode(lineContent) + 1, lineContent.length() - STYLE_TAG_TYPE.get(unit).length()).trim();
248 | formatText(
249 | content,
250 | new int[]{
251 | caretModel.getOffset() - content.length() - STYLE_TAG_TYPE.get(unit).length(),
252 | caretModel.getOffset(),
253 | },
254 | actionPerformer,
255 | shortCutType);
256 | }
257 |
258 | public void formatNearCode(ActionPerformer actionPerformer, ShortCutType shortCutType) {
259 | formatNearCode(actionPerformer, shortCutType, ShortCutType.PX);
260 | }
261 |
262 | /**
263 | * 取一个长度单位的起始index
264 | *
265 | * @param content 待处理文本
266 | * @return 返回文本中包含的一个长度单位的起始index
267 | */
268 | private int getNearCode(String content) {
269 | return NumberUtils.max(StringUtils.lastIndexOf(content, COLON_STRING), StringUtils.lastIndexOf(content, BLANK_STRING));
270 | }
271 |
272 | /**
273 | * 转换选择的代码
274 | *
275 | * @param actionPerformer 获取的动作参数
276 | */
277 | public void formatSelectCode(ActionPerformer actionPerformer, ShortCutType shortCutType) {
278 | // 光标选择的文字
279 | String selectTexts = actionPerformer.getSelectionModel().getSelectedText(true);
280 | if (Objects.isNull(selectTexts)) {
281 | return;
282 | }
283 | String[] testArray = selectTexts.split("\n");
284 | int[] starts = actionPerformer.getSelectionModel().getBlockSelectionStarts();
285 | int[] ends = actionPerformer.getSelectionModel().getBlockSelectionEnds();
286 | if (testArray.length != starts.length || testArray.length != ends.length) {
287 | return;
288 | }
289 | for (int i = 0; i < testArray.length; i++) {
290 | String selectText = testArray[i];
291 | if (selectText.contains(PX_STYLE_TAG)) {
292 | formatText(
293 | selectText.substring(0, selectText.indexOf(PX_STYLE_TAG)),
294 | new int[]{
295 | starts[i],
296 | ends[i]
297 | },
298 | actionPerformer,
299 | shortCutType);
300 | starts = actionPerformer.getSelectionModel().getBlockSelectionStarts();
301 | ends = actionPerformer.getSelectionModel().getBlockSelectionEnds();
302 | }
303 | }
304 | }
305 |
306 | /**
307 | * 格式化指定的style文本
308 | *
309 | * @param style style文本
310 | * @param position 起止index
311 | * @param actionPerformer 动作参数
312 | */
313 | private void formatText(String style, int[] position, ActionPerformer actionPerformer, ShortCutType shortCutType) {
314 | Optional.of(style).filter(FormatTools::isNumeric).ifPresent(text ->
315 | WriteCommandAction.runWriteCommandAction(actionPerformer.getProject(), () ->
316 | actionPerformer.getDocument().replaceString(
317 | position[0],
318 | position[1],
319 | getFormatText(style + PX_STYLE_TAG, shortCutType))
320 | )
321 | );
322 | }
323 |
324 | }
325 |
--------------------------------------------------------------------------------
/src/main/java/com/sunqian/settings/ProjectSettingsPage.java:
--------------------------------------------------------------------------------
1 | package com.sunqian.settings;
2 |
3 | import com.intellij.uiDesigner.core.GridConstraints;
4 | import com.intellij.uiDesigner.core.GridLayoutManager;
5 | import com.intellij.uiDesigner.core.Spacer;
6 | import com.jgoodies.forms.layout.CellConstraints;
7 | import com.jgoodies.forms.layout.FormLayout;
8 | import com.sunqian.constvalue.ConstValue;
9 | import com.sunqian.constvalue.ShortCutType;
10 | import com.sunqian.utils.LogicUtils;
11 | import lombok.Data;
12 | import lombok.NoArgsConstructor;
13 |
14 | import javax.swing.*;
15 | import java.awt.*;
16 | import java.util.HashMap;
17 | import java.util.function.Consumer;
18 |
19 | @Data
20 | @NoArgsConstructor
21 | public class ProjectSettingsPage {
22 | private JCheckBox showCalculationProcessInCheckBox;
23 | private JTextField remBaseValue;
24 | private JTextField vwValue;
25 | private JTextField vhValue;
26 | private JRadioButton remRadioButton;
27 | private JRadioButton vwRadioButton;
28 | private JRadioButton vhRadioButton;
29 | private JPanel panel;
30 | private JCheckBox remIntention;
31 | private JCheckBox vwIntention;
32 | private JCheckBox vhIntention;
33 | private JCheckBox remCompletion;
34 | private JCheckBox vwCompletion;
35 | private JCheckBox vhCompletion;
36 | private JCheckBox onlyCssFiles;
37 | private JRadioButton cmRadioButton;
38 | private JTextField dpiBaseValue;
39 | private ButtonGroup buttonGroup;
40 |
41 | private ConstValue constValue;
42 |
43 | ProjectSettingsPage(ConstValue constValue) {
44 | this.constValue = constValue;
45 | }
46 |
47 | private void setShowParams() {
48 | remBaseValue.setText(constValue.getRemBaseValue() + "");
49 | vwValue.setText(constValue.getWidthValue().toString());
50 | vhValue.setText(constValue.getHeightValue().toString());
51 | LogicUtils.getLogic().generateObject(new HashMap