2023年6月12日18:18:26

master
zhangmeng 2023-06-12 18:18:33 +08:00
parent afa4cbbf46
commit 81978c4f33
4 changed files with 182 additions and 5 deletions

View File

@ -3,11 +3,9 @@ package com.zhangmeng.tools.controller;
import cn.hutool.core.io.resource.ClassPathResource;
import cn.hutool.core.io.resource.Resource;
import com.zhangmeng.tools.components.RecursiveFileList;
import com.zhangmeng.tools.languages.ProcessGO;
import com.zhangmeng.tools.languages.ProcessHtml;
import com.zhangmeng.tools.languages.ProcessJava;
import com.zhangmeng.tools.languages.ProcessSql;
import com.zhangmeng.tools.languages.*;
import com.zhangmeng.tools.utils.AlertUtils;
import com.zhangmeng.tools.utils.FxmlUtils;
import javafx.application.Platform;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
@ -78,7 +76,9 @@ public class FileEditController {
GO,
JS,
CSS,
SQL
SQL,
XML,
YML
}
@FXML
@ -282,6 +282,32 @@ public class FileEditController {
codeArea.replaceText(0, 0, file_content);
Tab tab = new Tab(file.getName());
ContextMenu contextMenu = new ContextMenu();
MenuItem close = new MenuItem("close");
MenuItem close_other_tabs = new MenuItem("close other tabs");
MenuItem close_all = new MenuItem("close all");
close_all.setOnAction(event -> {
tabPane.getTabs().clear();
});
close_other_tabs.setOnAction(event -> {
ObservableList<Tab> tabs = tabPane.getTabs();
ObservableList<Tab> list = FXCollections.observableArrayList(tabs);
//关闭其他
for (Tab tabPaneTab : list) {
if (tabPaneTab != tabPane.getSelectionModel().getSelectedItem()){
tabs.remove(tabPaneTab);
}
}
});
close.setOnAction(event -> {
//关闭当前窗口
Tab selectedItem = tabPane.getSelectionModel().getSelectedItem();
tabPane.getTabs().remove(selectedItem);
});
contextMenu.getItems().add(close);
contextMenu.getItems().add(close_other_tabs);
contextMenu.getItems().add(close_all);
tab.setContextMenu(contextMenu);
tab.setOnCloseRequest(new EventHandler<Event>() {
@Override
public void handle(Event event) {
@ -375,6 +401,12 @@ public class FileEditController {
if (extension.equals("sql")) {
type = Type.SQL;
}
if (extension.equals("xml")) {
type = Type.XML;
}
if (extension.equals("yml")) {
type = Type.YML;
}
if (type == null) {
type = Type.JAVA;
}
@ -395,6 +427,12 @@ public class FileEditController {
if (type.equals(Type.SQL)) {
matcher = ProcessSql.PATTERN.matcher(text);
}
if (type.equals(Type.XML)) {
matcher = ProcessXML.PATTERN.matcher(text);
}
if (type.equals(Type.YML)) {
matcher = ProcessYML.PATTERN.matcher(text);
}
int lastKwEnd = 0;
StyleSpansBuilder<Collection<String>> spansBuilder = new StyleSpansBuilder<>();
while (matcher.find()) {
@ -458,6 +496,31 @@ public class FileEditController {
matcher.group("HTMLKEYWORDS2") != null ? "html-keyword2" : //html 属性
null; /* never happens */
}
if (type.equals(Type.XML)) {
if (matcher.group("ELEMENT") != null) {
if (matcher.group("ELEMENT").startsWith("</")) {
styleClass = "xml-close-tag";
} else {
styleClass = "xml-open-tag";
}
} else if (matcher.group("COMMENT") != null) {
styleClass = "xml-comment";
}
}
if (type.equals(Type.YML)) {
styleClass =
matcher.group("KEYWORD") != null ? "keyword" :
matcher.group("NUMBER") != null ? "number" :
matcher.group("STRING") != null ? "string" :
matcher.group("COMMENT") != null ? "comment" :
matcher.group("ANCHOR_ALIAS") != null ? "anchor-alias" :
matcher.group("TAG") != null ? "tag" :
matcher.group("DOCUMENT_MARKER") != null ? "document-marker" :
matcher.group("DIRECTIVE") != null ? "directive" :
matcher.group("VARIABLE") != null ? "variable" :
null; /* never happens */
}
assert styleClass != null;
spansBuilder.add(Collections.emptyList(), matcher.start() - lastKwEnd);
spansBuilder.add(Collections.singleton(styleClass), matcher.end() - matcher.start());

View File

@ -0,0 +1,17 @@
package com.zhangmeng.tools.languages;
import java.util.regex.Pattern;
/**
* @author :
* @version : 1.0
* @date : 2023-06-12 17:17
*/
public class ProcessXML {
public static final String XML_PATTERN = "(?<ELEMENT>(</?\\h*)(\\w+)([^<>]*)(\\h*/?>))"
+ "|(?<COMMENT><!--[^<>]+-->)";
public static final Pattern PATTERN = Pattern.compile(XML_PATTERN);
}

View File

@ -0,0 +1,39 @@
package com.zhangmeng.tools.languages;
import java.util.regex.Pattern;
/**
* @author :
* @version : 1.0
* @date : 2023-06-12 17:17
*/
public class ProcessYML {
public static final String[] KEYWORDS = new String[] {
"true", "false", "yes", "no", "null",""
};
public static final String KEYWORD_PATTERN = "\\b(" + String.join("|", KEYWORDS) + ")\\b";
public static final String NUMBER_PATTERN = "\\b\\d+\\b";
public static final String STRING_PATTERN = "\"([^\"\\\\]|\\\\.)*\"";
public static final String COMMENT_PATTERN = "\\s*#.*";
public static final String ANCHOR_ALIAS_PATTERN = "^(&|\\*)[a-zA-Z0-9_-]+$";
public static final String TAG_PATTERN = "!\\S+";
public static final String DOCUMENT_MARKER_PATTERN = "^(---|\\.\\.\\.)$";
public static final String DIRECTIVE_PATTERN = "^%.+$";
public static final String VARIABLE_PATTERN = "\\$\\{.+?\\}";
public static final Pattern PATTERN = Pattern.compile(
"(?<KEYWORD>" + KEYWORD_PATTERN + ")"
+ "|(?<NUMBER>" + NUMBER_PATTERN + ")"
+ "|(?<STRING>" + STRING_PATTERN + ")"
+ "|(?<COMMENT>" + COMMENT_PATTERN + ")"
// + "|(?<ANCHOR_ALIAS>" + ANCHOR_ALIAS_PATTERN + ")"
+ "|(?<TAG>" + TAG_PATTERN + ")"
// + "|(?<DOCUMENT_MARKER>" + DOCUMENT_MARKER_PATTERN + ")"
+ "|(?<DIRECTIVE>" + DIRECTIVE_PATTERN + ")"
+ "|(?<VARIABLE>" + VARIABLE_PATTERN + ")"
);
}

View File

@ -199,3 +199,61 @@
-fx-fill: #1097eb;
}
.xml-open-tag {
-fx-fill: #0000FF;
-fx-font-weight: bold;
}
.xml-close-tag {
-fx-fill: #0000FF;
-fx-font-weight: bold;
}
.xml-comment {
-fx-fill: #008000;
-fx-font-style: italic;
}
.comment {
-fx-fill: gray;
}
.string {
-fx-fill: green;
}
.keyword {
-fx-fill: blue;
}
.number {
-fx-fill: red;
}
.operator {
-fx-fill: black;
}
.punctuation {
-fx-fill: black;
}
.anchor-alias {
-fx-fill: purple;
}
.tag {
-fx-fill: orange;
}
.document-marker {
-fx-fill: brown;
}
.directive {
-fx-fill: teal;
}
.variable {
-fx-fill: darkgreen;
}