Compare commits

...

8 Commits

39 changed files with 706 additions and 307 deletions

19
.gitignore vendored
View File

@ -1,16 +1,9 @@
/.idea/$CACHE_FILE$
/.idea/compiler.xml
/.idea/dictionaries
/.idea/gradle.xml
/.idea/inspectionProfiles
/.idea/jarRepositories.xml
/.idea/libraries
/.idea/misc.xml
/.idea/modules
/.idea/modules.xml
/.idea/uiDesigner.xml
/.idea/*.iml
/.idea/.name
/.idea/*
!/.idea/runConfigurations
!/.idea/compiler.xml
!/.idea/encodings.xml
!/.idea/gradle.xml
!/.idea/vcs.xml
/.gradle/
/build/

View File

@ -1,6 +1,12 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="AUTODETECT_INDENTS" value="false" />
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="2" />
<option name="TAB_SIZE" value="2" />
</value>
</option>
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="RIGHT_MARGIN" value="999" />
<option name="FORMATTER_TAGS_ENABLED" value="true" />
@ -21,8 +27,7 @@
</option>
</JavaCodeStyleSettings>
<XML>
<option name="XML_ATTRIBUTE_WRAP" value="0" />
<option name="XML_TEXT_WRAP" value="0" />
<option name="XML_SPACE_INSIDE_EMPTY_TAG" value="true" />
</XML>
<codeStyleSettings language="JAVA">
<option name="RIGHT_MARGIN" value="999" />
@ -31,28 +36,7 @@
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
<option name="SPACE_AFTER_TYPE_CAST" value="false" />
<option name="SPACE_BEFORE_WHILE_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_FOR_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_TRY_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CATCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SWITCH_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_PARENTHESES" value="false" />
<option name="SPACE_BEFORE_CLASS_LBRACE" value="false" />
<option name="SPACE_BEFORE_METHOD_LBRACE" value="false" />
<option name="SPACE_BEFORE_IF_LBRACE" value="false" />
<option name="SPACE_BEFORE_ELSE_LBRACE" value="false" />
<option name="SPACE_BEFORE_WHILE_LBRACE" value="false" />
<option name="SPACE_BEFORE_FOR_LBRACE" value="false" />
<option name="SPACE_BEFORE_DO_LBRACE" value="false" />
<option name="SPACE_BEFORE_SWITCH_LBRACE" value="false" />
<option name="SPACE_BEFORE_TRY_LBRACE" value="false" />
<option name="SPACE_BEFORE_CATCH_LBRACE" value="false" />
<option name="SPACE_BEFORE_FINALLY_LBRACE" value="false" />
<option name="SPACE_BEFORE_SYNCHRONIZED_LBRACE" value="false" />
<option name="SPACE_BEFORE_ELSE_KEYWORD" value="false" />
<option name="SPACE_BEFORE_WHILE_KEYWORD" value="false" />
<option name="SPACE_BEFORE_CATCH_KEYWORD" value="false" />
<option name="SPACE_BEFORE_FINALLY_KEYWORD" value="false" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
@ -75,5 +59,21 @@
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="BLOCK_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
<option name="ELSE_ON_NEW_LINE" value="true" />
<option name="METHOD_ANNOTATION_WRAP" value="0" />
<option name="CLASS_ANNOTATION_WRAP" value="0" />
<option name="FIELD_ANNOTATION_WRAP" value="0" />
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
<option name="KEEP_INDENTS_ON_EMPTY_LINES" value="true" />
</indentOptions>
</codeStyleSettings>
</code_scheme>
</component>

6
.idea/compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

19
.idea/gradle.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="delegatedBuild" value="true" />
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -1,10 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="FixSVGs" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.chylex.intellij.coloredicons.FixSVGs" />
<module name="ColoredIcons.helpers" />
<shortenClasspath name="MANIFEST" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Fix SVGs" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="fixSVGs" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>

View File

@ -1,10 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="GrabIconsFromInstalledIDEs" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="com.chylex.intellij.coloredicons.GrabIconsFromInstalledIDEs" />
<module name="ColoredIcons.helpers" />
<shortenClasspath name="MANIFEST" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Grab Icons from Gradle" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="grabIconsFromGradle" />
</list>
</option>
<option name="vmOptions" value="-DdownloadExtraIDEs=true" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>

View File

@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Grab Icons from Installed IDEs" type="GradleRunConfiguration" factoryName="Gradle">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="grabIconsFromInstalledIDEs" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>

View File

@ -1,38 +1,78 @@
plugins {
java
idea
id("org.jetbrains.intellij") version "1.2.0"
java
idea
id("org.jetbrains.intellij") version "1.7.0"
}
group = "com.chylex.intellij.coloredicons"
version = "1.3"
version = "1.4"
repositories {
mavenCentral()
mavenCentral()
maven("https://www.jetbrains.com/intellij-repository/snapshots/")
}
intellij {
version.set("2021.2.2")
type.set("IU")
version.set("LATEST-EAP-SNAPSHOT")
updateSinceUntilBuild.set(false)
}
tasks.buildSearchableOptions {
enabled = false
}
configurations {
create("ides")
}
java {
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
toolchain.languageVersion.set(JavaLanguageVersion.of(11))
}
sourceSets {
main {
java.setSrcDirs(setOf(file("src")))
resources.setSrcDirs(setOf(file("resources")))
}
create("helpers") {
java.setSrcDirs(setOf(file("helpers")))
resources.setSrcDirs(sourceSets.main.get().resources.srcDirs)
}
main {
java.setSrcDirs(setOf(file("src")))
resources.setSrcDirs(setOf(file("resources")))
}
create("helpers") {
java.setSrcDirs(setOf(file("helpers")))
resources.setSrcDirs(sourceSets.main.get().resources.srcDirs)
}
}
dependencies {
"helpersImplementation"("commons-io:commons-io:2.11.0")
"helpersImplementation"("org.apache.commons:commons-compress:1.21")
"helpersImplementation"("commons-io:commons-io:2.11.0")
"ides"("com.jetbrains.intellij.idea:ideaIU:LATEST-EAP-SNAPSHOT")
if (System.getProperty("downloadExtraIDEs", "") == "true") {
"ides"("com.jetbrains.intellij.clion:clion:LATEST-EAP-SNAPSHOT")
"ides"("com.jetbrains.intellij.goland:goland:LATEST-EAP-SNAPSHOT")
"ides"("com.jetbrains.intellij.phpstorm:phpstorm:LATEST-EAP-SNAPSHOT")
"ides"("com.jetbrains.intellij.pycharm:pycharmPY:LATEST-EAP-SNAPSHOT")
"ides"("com.jetbrains.intellij.rider:riderRD:2022.3-SNAPSHOT")
}
}
fun createHelperTask(name: String, main: String, configure: ((JavaExec) -> Unit)? = null) {
tasks.create(name, JavaExec::class.java) {
group = "helpers"
mainClass.set("com.chylex.intellij.coloredicons.$main")
classpath = sourceSets.getByName("helpers").runtimeClasspath
configure?.invoke(this)
}
}
fun getClassPathFolders(configuration: Configuration): List<String> {
return configuration.files.map(File::getParentFile).distinct().map(File::getAbsolutePath)
}
createHelperTask("fixSVGs", main = "FixSVGs")
createHelperTask("grabIconsFromInstalledIDEs", main = "GrabIcons\$FromInstalledIDEs")
createHelperTask("grabIconsFromGradle", main = "GrabIcons\$FromArgumentPaths") {
val ideLibraries = getClassPathFolders(project.configurations.getByName("ides"))
val downloadedPlugins = File(buildDir, "idea-sandbox/system/plugins").absolutePath
it.args = ideLibraries + downloadedPlugins
}

View File

@ -8,10 +8,14 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
import static java.util.Map.entry;
final class FixSVGs{
public static void main(final String[] args) throws IOException{
final class FixSVGs {
private static final File ICONS_FOLDER = new File("./resources/icons");
public static void main(final String[] args) throws IOException {
final Charset charset = StandardCharsets.UTF_8;
final String encoding = charset.name();
@ -25,45 +29,103 @@ final class FixSVGs{
int changedFiles = 0;
for(final File file : FileUtils.listFiles(new File("./resources/icons"), new String[]{ "svg" }, true)){
for (final File file : FileUtils.listFiles(ICONS_FOLDER, new String[]{ "svg" }, true)) {
boolean hasChanged = false;
final List<String> lines = FileUtils.readLines(file, charset);
if (lines.get(0).startsWith("<?xml")){
if (lines.get(0).startsWith("<?xml")) {
lines.remove(0);
hasChanged = true;
}
if (lines.get(0).startsWith("<!DOCTYPE")){
if (lines.get(0).startsWith("<!DOCTYPE")) {
lines.remove(0);
hasChanged = true;
}
final String svg = lines.get(0);
if (!svgValidTags.contains(svg)){
if (!svgValidTags.contains(svg)) {
final String correctedTag = svgRemapping.keySet().stream().filter(svg::contains).findAny().map(svgRemapping::get).orElse(null);
if (correctedTag == null){
if (correctedTag == null) {
System.out.println("Error processing <svg> tag in file: " + file);
System.out.println(" " + svg);
continue;
}
else{
else {
lines.set(0, correctedTag);
hasChanged = true;
}
}
if (hasChanged){
if (hasChanged) {
++changedFiles;
System.out.println("Updated file: " + file);
}
printWarnings(lines, file);
FileUtils.writeLines(file, encoding, lines, "\n");
}
System.out.println("Total updated files: " + changedFiles);
}
private static final Pattern invalidColorDefinition = Pattern.compile("\\bfill:[^#]");
private static final Pattern hexColorDefinition = Pattern.compile("\\bfill:#([0-9a-f]{6});");
private static final Set<String> allowedLightColors = Set.of(
"b76db7",
"6e6e6e",
"59a869",
"eda200",
"389fd6",
"db5860"
);
private static final Set<String> allowedDarkColors = Set.of(
"afb1b3",
"b066b0",
"499c54",
"f0a732",
"3592c4",
"c75450"
);
private static final Set<String> skipColorCheck = Set.of(
"general/addJdk",
"modules/addExcludedRoot",
"toolbarDecorator/addClass",
"toolbarDecorator/addJira"
);
private static void printWarnings(final List<String> lines, final File file) {
final boolean isDark = file.getName().endsWith("_dark.svg");
final String relativeFilePath = ICONS_FOLDER.toPath().relativize(file.toPath()).toString().replace('\\', '/');
final String suffixlessFilePath = isDark ? relativeFilePath.replace("_dark.svg", "") : relativeFilePath.replace(".svg", "");
if (skipColorCheck.contains(suffixlessFilePath)) {
return;
}
final Set<String> validThemeColors = isDark ? allowedDarkColors : allowedLightColors;
for (final String line : lines) {
if (invalidColorDefinition.matcher(line).find()) {
System.out.println("Warning: Invalid color definition in file: " + relativeFilePath);
System.out.println("Line: " + line.trim());
}
hexColorDefinition.matcher(line).results().forEachOrdered(result -> {
final String color = result.group(1);
if (!validThemeColors.contains(color)) {
System.out.println("Warning: Invalid theme color in file: " + relativeFilePath);
System.out.println("Line: " + line.trim());
}
});
}
}
}

View File

@ -0,0 +1,316 @@
package com.chylex.intellij.coloredicons;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
abstract class GrabIcons {
private static final List<String> EXPECTED_VIEW_BOXES_LOWERCASE = List.of(
"viewbox=\"0 0 12 12\"",
"viewbox=\"0 0 16 16\"",
"viewbox=\"0 0 13 13\""
);
private static final List<String> EXPECTED_COLORS_LOWERCASE = List.of(
"#afb1b3",
"#6e6e6e"
);
private static final boolean FLATTEN_ARCHIVE_PATHS = true;
private static final boolean FLATTEN_SVG_PATHS = false;
private static final class ArchiveExtractionStats {
int foundSVGs = 0;
int uniqueSVGs = 0;
void sumWith(final ArchiveExtractionStats other) {
foundSVGs += other.foundSVGs;
uniqueSVGs += other.uniqueSVGs;
}
}
protected final void run() throws IOException {
final Stream<Path> libAndPluginFolders = findLibAndPluginFolders();
if (libAndPluginFolders == null) {
return;
}
final Path[] foundArchives = libAndPluginFolders
.flatMap(GrabIcons::getJarAndZipFiles)
.sorted()
.toArray(Path[]::new);
System.out.println("Total JAR and ZIP files found: " + foundArchives.length);
if (foundArchives.length == 0) {
return;
}
final Path extractionRootPath = new File("./extracted").toPath();
if (Files.exists(extractionRootPath)) {
FileUtils.cleanDirectory(extractionRootPath.toFile());
}
else {
Files.createDirectory(extractionRootPath);
}
extractSVGsFromArchives(foundArchives, extractionRootPath);
System.out.println("Done!");
}
protected abstract Stream<Path> findLibAndPluginFolders();
private static Stream<Path> getJarAndZipFiles(final Path parentFolder) {
System.out.println("Collecting JAR and ZIP files from: " + parentFolder);
try {
return Files.find(parentFolder, Integer.MAX_VALUE, GrabIcons::isJarOrZipFile);
} catch (final IOException e) {
e.printStackTrace();
return Stream.empty();
}
}
private static boolean isJarOrZipFile(final Path path, final BasicFileAttributes attr) {
if (!Files.isRegularFile(path)) {
return false;
}
final String name = getFileNameLowerCase(path);
return name.endsWith(".jar") || name.endsWith(".zip");
}
private static String getFileNameLowerCase(final Path path) {
return path.getFileName().toString().toLowerCase(Locale.ROOT);
}
private static void extractSVGsFromArchives(final Path[] foundArchives, final Path extractionRootPath) throws IOException {
final Path commonParent = findCommonParent(foundArchives);
for (final Path archiveFile : foundArchives) {
final Path extractionArchiveBasePath = FLATTEN_ARCHIVE_PATHS ? extractionRootPath : extractionRootPath.resolve(archiveFile.getFileName());
try (final ZipInputStream inputStream = new ZipInputStream(new FileInputStream(archiveFile.toFile()))) {
final Path relativeArchivePath = commonParent == null ? archiveFile : commonParent.relativize(archiveFile);
try {
extractSVGsFromArchiveStream(extractionArchiveBasePath, relativeArchivePath.toString().replace('\\', '/'), inputStream);
} catch (final Exception e) {
System.out.println("Failed to extract SVGs from archive: " + archiveFile);
}
}
}
}
private static Path findCommonParent(final Path[] paths) {
return Arrays.stream(paths)
.map(Optional::of)
.reduce(GrabIcons::findCommonParent)
.orElseGet(Optional::empty)
.orElse(null);
}
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
private static Optional<Path> findCommonParent(final Optional<Path> a, final Optional<Path> b) {
if (a.isEmpty() || b.isEmpty()) {
return Optional.empty();
}
final Path other = b.get().normalize();
return Stream.iterate(a.get().normalize(), Objects::nonNull, Path::getParent)
.filter(parent -> Stream.iterate(other, Objects::nonNull, Path::getParent).anyMatch(Predicate.isEqual(parent)))
.findFirst();
}
@SuppressWarnings({ "NestedAssignment", "AutoBoxing" })
private static void extractSVGsFromArchiveStream(final Path extractionBasePath, final String archiveName, final ZipInputStream inputStream) throws IOException {
final ArchiveExtractionStats stats = new ArchiveExtractionStats();
ZipEntry entry;
while ((entry = inputStream.getNextEntry()) != null) {
stats.sumWith(extractSVGsFromArchiveEntry(extractionBasePath, archiveName, inputStream, entry));
}
if (stats.foundSVGs > 0) {
final String foundStr = String.format("%4d", stats.foundSVGs);
final String uniqueStr = String.format("%4d", stats.uniqueSVGs);
System.out.println("Found " + uniqueStr + " new, " + foundStr + " total SVG(s) in: " + archiveName);
}
}
private static ArchiveExtractionStats extractSVGsFromArchiveEntry(final Path basePath, final String archiveName, final ZipInputStream parentInputStream, final ZipEntry entry) throws IOException {
final ArchiveExtractionStats stats = new ArchiveExtractionStats();
if (entry.isDirectory()) {
return stats;
}
final String entryName = entry.getName();
final String entryNameLowerCase = entryName.toLowerCase(Locale.ROOT);
if (entryNameLowerCase.endsWith(".jar") || entryNameLowerCase.endsWith(".zip")) {
final String nestedArchiveName = archiveName + '/' + entryName;
try {
extractSVGsFromArchiveStream(FLATTEN_ARCHIVE_PATHS ? basePath : getRelativePathForExtraction(basePath, entry), nestedArchiveName, new ZipInputStream(parentInputStream));
} catch (final Exception e) {
System.out.println("Failed to extract SVGs from nested archive: " + nestedArchiveName);
}
}
else if (entryNameLowerCase.endsWith(".svg")) {
extractSVG(parentInputStream, entry, getRelativePathForExtraction(basePath, entry), stats);
}
return stats;
}
private static Path getRelativePathForExtraction(final Path basePath, final ZipEntry entry) {
return basePath.resolve(FLATTEN_SVG_PATHS ? entry.getName().replace("/", "__") : entry.getName());
}
private static void extractSVG(final ZipInputStream inputStream, final ZipEntry entry, final Path basePath, final ArchiveExtractionStats stats) throws IOException {
final byte[] svgBytes = inputStream.readAllBytes();
final String svgText = new String(svgBytes, StandardCharsets.UTF_8);
if (!isValidSVG(svgText)) {
return;
}
++stats.foundSVGs;
Path svgPath = basePath;
final Path svgParentFolder = svgPath.getParent();
final String originalFileName = svgPath.getFileName().toString();
int duplicateCounter = 0;
while (Files.exists(svgPath)) {
if (Files.size(svgPath) == entry.getSize() && IOUtils.contentEquals(new ByteArrayInputStream(svgBytes), Files.newInputStream(svgPath, StandardOpenOption.READ))) {
return;
}
svgPath = svgParentFolder.resolve(FilenameUtils.removeExtension(originalFileName) + '_' + (++duplicateCounter) + '.' + FilenameUtils.getExtension(originalFileName));
}
Files.createDirectories(svgParentFolder);
Files.write(svgPath, svgBytes);
Files.setLastModifiedTime(svgPath, entry.getLastModifiedTime());
++stats.uniqueSVGs;
}
private static boolean isValidSVG(final String svg) {
boolean hasExpectedViewBox = false;
boolean hasExpectedColor = false;
for (final String line : svg.lines().map(line -> line.toLowerCase(Locale.ROOT)).toArray(String[]::new)) {
if (EXPECTED_VIEW_BOXES_LOWERCASE.stream().anyMatch(line::contains)) {
hasExpectedViewBox = true;
}
if (EXPECTED_COLORS_LOWERCASE.stream().anyMatch(line::contains)) {
hasExpectedColor = true;
}
if (hasExpectedViewBox && hasExpectedColor) {
return true;
}
}
return false;
}
public static final class FromArgumentPaths extends GrabIcons {
public static void main(final String[] args) throws IOException {
new FromArgumentPaths(args).run();
}
private final Path[] paths;
public FromArgumentPaths(final String[] paths) {
this.paths = Arrays.stream(paths).map(Path::of).toArray(Path[]::new);
}
@Override
protected Stream<Path> findLibAndPluginFolders() {
return Arrays.stream(paths);
}
}
public static final class FromInstalledIDEs extends GrabIcons {
public static void main(final String[] args) throws IOException {
new FromInstalledIDEs().run();
}
@SuppressWarnings("CallToSystemGetenv")
@Override
protected Stream<Path> findLibAndPluginFolders() {
final String localAppData = System.getenv("LOCALAPPDATA");
if (localAppData == null) {
System.out.println("Missing %LOCALAPPDATA%, only Windows Vista or newer are supported.");
return null;
}
final Path toolboxAppsFolder = Paths.get(localAppData, "JetBrains", "Toolbox", "apps");
if (!Files.exists(toolboxAppsFolder)) {
System.out.println("Missing JetBrains Toolbox installation folder at: " + toolboxAppsFolder);
return null;
}
return list(toolboxAppsFolder)
.filter(Files::isDirectory)
.flatMap(FromInstalledIDEs::getAppChannelFolders)
.flatMap(FromInstalledIDEs::getLibAndPluginsFolders);
}
private static Stream<Path> getAppChannelFolders(final Path appFolder) {
return list(appFolder).filter(Files::isDirectory).filter(child -> getFileNameLowerCase(child).startsWith("ch-"));
}
private static Stream<Path> getLibAndPluginsFolders(final Path channelFolder) {
return list(channelFolder).filter(Files::isDirectory).flatMap(child -> {
final String name = getFileNameLowerCase(child);
if (name.contains(".remove-")) {
return Stream.empty();
}
else if (name.endsWith(".plugins")) {
return Stream.of(child);
}
else {
return Stream.of(child.resolve("lib"), child.resolve("plugins"));
}
}).filter(Files::isDirectory); // catches non-existent paths too
}
private static Stream<Path> list(final Path parent) {
try {
return Files.list(parent);
} catch (final IOException e) {
e.printStackTrace();
return Stream.empty();
}
}
}
}

View File

@ -1,194 +0,0 @@
package com.chylex.intellij.coloredicons;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.Comparator.comparing;
final class GrabIconsFromInstalledIDEs{
private static final List<String> EXPECTED_VIEW_BOXES_LOWERCASE = List.of(
"viewbox=\"0 0 12 12\"",
"viewbox=\"0 0 16 16\"",
"viewbox=\"0 0 13 13\""
);
private static final List<String> EXPECTED_COLORS_LOWERCASE = List.of(
"#afb1b3",
"#6e6e6e"
);
private static boolean FLATTEN = true;
public static void main(final String[] args) throws IOException{
@SuppressWarnings("CallToSystemGetenv")
final String localAppData = System.getenv("LOCALAPPDATA");
if (localAppData == null){
System.out.println("Missing %LOCALAPPDATA%, only Windows Vista or newer are supported.");
return;
}
final Path toolboxAppsFolder = Paths.get(localAppData, "JetBrains", "Toolbox", "apps");
if (!Files.exists(toolboxAppsFolder)){
System.out.println("Missing JetBrains Toolbox installation folder at: " + toolboxAppsFolder);
return;
}
final List<Path> foundJarFiles = list(toolboxAppsFolder)
.filter(Files::isDirectory)
.flatMap(GrabIconsFromInstalledIDEs::getAppChannelFolders)
.flatMap(GrabIconsFromInstalledIDEs::getLibAndPluginsFolders)
.flatMap(GrabIconsFromInstalledIDEs::getJarFiles)
.sorted(comparing(GrabIconsFromInstalledIDEs::getName))
.collect(Collectors.toList());
System.out.println("Total JAR files found: " + foundJarFiles.size());
final Path extractionRootPath = new File("./extracted").toPath();
if (Files.exists(extractionRootPath)){
FileUtils.cleanDirectory(extractionRootPath.toFile());
}
else{
Files.createDirectory(extractionRootPath);
}
int totalExtractedFiles = 0;
for(final Path jarFile : foundJarFiles){
final Path jarFileName = jarFile.getFileName();
final Path extractionJarPath = extractionRootPath.resolve(jarFileName);
int extractedFiles = 0;
try(final ZipFile zip = new ZipFile(jarFile.toFile())){
for(final Enumeration<ZipArchiveEntry> entries = zip.getEntries(); entries.hasMoreElements();){
final ZipArchiveEntry entry = entries.nextElement();
if (!entry.isDirectory()){
final String entryName = entry.getName();
if (entryName.toLowerCase(Locale.ROOT).endsWith(".svg") && extractFile(zip, entry, extractionJarPath.resolve(FLATTEN ? entryName.replace("/", "__") : entryName))){
++extractedFiles;
}
}
}
}
if (extractedFiles > 0){
totalExtractedFiles += extractedFiles;
System.out.println("Extracted SVGs from " + jarFileName + ": " + extractedFiles);
}
}
System.out.println("Total extracted SVGs: " + totalExtractedFiles);
}
private static Stream<Path> list(final Path parent){
try{
return Files.list(parent);
}catch(final IOException e){
e.printStackTrace();
return Stream.empty();
}
}
private static String getName(final Path path){
return path.getFileName().toString().toLowerCase(Locale.ROOT);
}
private static Stream<Path> getAppChannelFolders(final Path appFolder){
return list(appFolder).filter(Files::isDirectory).filter(child -> getName(child).startsWith("ch-"));
}
private static Stream<Path> getLibAndPluginsFolders(final Path channelFolder){
return list(channelFolder).filter(Files::isDirectory).flatMap(child -> {
final String name = getName(child);
if (name.contains(".remove-")){
return Stream.empty();
}
else if (name.endsWith(".plugins")){
return Stream.of(child);
}
else{
return Stream.of(child.resolve("lib"), child.resolve("plugins"));
}
}).filter(Files::isDirectory); // catches non-existent paths too
}
private static Stream<Path> getJarFiles(final Path parentFolder){
System.out.println("Collecting JAR files from: " + parentFolder);
try{
return Files.find(parentFolder, Integer.MAX_VALUE, (path, attr) -> Files.isRegularFile(path) && getName(path).endsWith(".jar"));
}catch(final IOException e){
e.printStackTrace();
return Stream.empty();
}
}
private static boolean extractFile(final ZipFile zip, final ZipArchiveEntry entry, final Path target) throws IOException{
if (!isValidSVG(zip.getInputStream(entry))){
return false;
}
Path svgPath = target;
final Path svgParentFolder = svgPath.getParent();
final String originalFileName = svgPath.getFileName().toString();
int duplicateCounter = 0;
while(Files.exists(svgPath)){
if (Files.size(svgPath) == entry.getSize() && IOUtils.contentEquals(zip.getInputStream(entry), Files.newInputStream(svgPath, StandardOpenOption.READ))){
return false;
}
svgPath = svgParentFolder.resolve(FilenameUtils.removeExtension(originalFileName) + '_' + (++duplicateCounter) + '.' + FilenameUtils.getExtension(originalFileName));
}
Files.createDirectories(svgParentFolder);
Files.copy(zip.getInputStream(entry), svgPath);
Files.setLastModifiedTime(svgPath, entry.getLastModifiedTime());
return true;
}
private static boolean isValidSVG(final InputStream fileStream) throws IOException{
boolean hasExpectedViewBox = false;
boolean hasExpectedColor = false;
for(final Iterator<String> lineIterator = IOUtils.lineIterator(fileStream, StandardCharsets.UTF_8); lineIterator.hasNext();){
final String line = lineIterator.next().toLowerCase(Locale.ROOT);
if (EXPECTED_VIEW_BOXES_LOWERCASE.stream().anyMatch(line::contains)){
hasExpectedViewBox = true;
}
if (EXPECTED_COLORS_LOWERCASE.stream().anyMatch(line::contains)){
hasExpectedColor = true;
}
if (hasExpectedViewBox && hasExpectedColor){
return true;
}
}
return false;
}
}

View File

@ -1,15 +1,18 @@
<idea-plugin>
<id>com.chylex.intellij.coloredicons</id>
<name>Colored Icons</name>
<version>1.3</version>
<vendor email="contact@chylex.com" url="https://chylex.com">chylex</vendor>
<description>
Adds color to many of the gray IntelliJ platform icons.
Uses resources from https://github.com/JetBrains/intellij-community and some of the official IntelliJ platform plugins.
Adds color to many of the gray IntelliJ platform icons.
Uses resources from https://github.com/JetBrains/intellij-community and some of the official IntelliJ platform plugins.
</description>
<change-notes><![CDATA[
<b>Version 1.4</b>
<ul>
<li>Added tool window icons for Bookmarks, Notifications, Dependencies, Scala, and more</li>
</ul>
<b>Version 1.3</b>
<ul>
<li>Added new icons related to VCS, unit tests, source code presentation and navigation, and more</li>
@ -32,13 +35,13 @@
<li>First release with 176 updated icons</li>
</ul>
]]></change-notes>
<idea-version since-build="183.0"/>
<idea-version since-build="183.0" />
<depends>com.intellij.modules.platform</depends>
<application-components>
<component>
<implementation-class>com.chylex.intellij.coloredicons.IconPatcher</implementation-class>
</component>
</application-components>
<application-components>
<component>
<implementation-class>com.chylex.intellij.coloredicons.IconPatcher</implementation-class>
</component>
</application-components>
</idea-plugin>

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<rect x="3" y="3" width="10" height="2" style="fill:#6e6e6e;"/>
<rect x="3" y="7" width="7" height="2" style="fill:#6e6e6e;"/>
<rect x="3" y="11" width="4" height="2" style="fill:#6e6e6e;"/>
<path d="M13,8l-2,0l0,3l-3,0l0,2l3,0l0,3l2,0l0,-3l3,0l0,-2l-3,0l0,-3Z" style="fill:#59a869;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 411 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<rect x="3" y="3" width="10" height="2" style="fill:#afb1b3;"/>
<rect x="3" y="7" width="7" height="2" style="fill:#afb1b3;"/>
<rect x="3" y="11" width="4" height="2" style="fill:#afb1b3;"/>
<path d="M13,8l-2,0l0,3l-3,0l0,2l3,0l0,3l2,0l0,-3l3,0l0,-2l-3,0l0,-3Z" style="fill:#499c54;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 411 B

View File

@ -1,6 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g>
<rect x="0" y="0" width="16" height="16" style="fill:none;"/>
<g>
<rect x="2" y="3" width="11" height="2" style="fill:#6e6e6e;"/>
<rect x="2" y="7" width="6" height="2" style="fill:#6e6e6e;"/>

Before

Width:  |  Height:  |  Size: 659 B

After

Width:  |  Height:  |  Size: 589 B

View File

@ -1,13 +1,12 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g>
<rect x="0" y="0" width="16" height="16" style="fill:none;"/>
<g>
<path d="M2,3l11,0l0,2l-11,0l0,-2Z" style="fill:#afb1b3;"/>
<path d="M2,7l6,0l0,2l-6,0l0,-2Z" style="fill:#afb1b3;"/>
<path d="M2,11l6,0l0,2l-6,0l0,-2Z" style="fill:#afb1b3;"/>
<path d="M12,8l1,0l0,6l-1,0l0,-6Z" style="fill:#f0a732;"/>
<path d="M10,7l5,0l0,1l-5,0l0,-1Z" style="fill:#f0a732;"/>
<path d="M10,14l5,0l0,1l-5,0l0,-1Z" style="fill:#f0a732;"/>
<rect x="2" y="3" width="11" height="2" style="fill:#afb1b3;fill-rule:nonzero;"/>
<rect x="2" y="7" width="6" height="2" style="fill:#afb1b3;fill-rule:nonzero;"/>
<rect x="2" y="11" width="6" height="2" style="fill:#afb1b3;fill-rule:nonzero;"/>
<rect x="12" y="8" width="1" height="6" style="fill:#f0a732;fill-rule:nonzero;"/>
<rect x="10" y="7" width="5" height="1" style="fill:#f0a732;fill-rule:nonzero;"/>
<rect x="10" y="14" width="5" height="1" style="fill:#f0a732;fill-rule:nonzero;"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 697 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<g>
<path d="M6.5,0.375l6.125,3.403l-6.125,3.403l-6.125,-3.403l6.125,-3.403Zm4.9,5.444l1.225,0.681l-6.125,3.403l-6.125,-3.403l1.225,-0.681l4.9,2.723l4.9,-2.723Zm0,2.723l1.225,0.68l-6.125,3.403l-6.125,-3.403l1.225,-0.68l4.9,2.722l4.9,-2.722Z" style="fill:#b76db7;fill-rule:nonzero;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 396 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M6.5,0.375l6.125,3.403l-6.125,3.403l-6.125,-3.403l6.125,-3.403Zm4.9,5.444l1.225,0.681l-6.125,3.403l-6.125,-3.403l1.225,-0.681l4.9,2.723l4.9,-2.723Zm0,2.723l1.225,0.68l-6.125,3.403l-6.125,-3.403l1.225,-0.68l4.9,2.722l4.9,-2.722Z" style="fill:#b066b0;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 375 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12,1l-11,0l0,11l11,0l0,-11Zm-5,9l-5,0l0,1l5,0l0,-1Zm-3.279,-2l1.1,0l0,-1.993l1.922,-3.007l-1.25,0l-1.214,2.007l-1.193,-2.007l-1.286,0l1.921,3.029l0,1.971Zm5.9,0l-1.1,0l0,-3.986l-1.521,0l-0,-1.014l4.143,0l0,1.014l-1.522,0l0,3.986Z" style="fill:#389fd6;"/>
</svg>

After

Width:  |  Height:  |  Size: 400 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path fill-rule="evenodd" clip-rule="evenodd" d="M12,1l-11,0l0,11l11,0l0,-11Zm-5,9l-5,0l0,1l5,0l0,-1Zm-3.279,-2l1.1,0l0,-1.993l1.922,-3.007l-1.25,0l-1.214,2.007l-1.193,-2.007l-1.286,0l1.921,3.029l0,1.971Zm5.9,0l-1.1,0l0,-3.986l-1.521,0l-0,-1.014l4.143,0l0,1.014l-1.522,0l0,3.986Z" style="fill:#3592c4;"/>
</svg>

After

Width:  |  Height:  |  Size: 400 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M2.443,6.769l3.857,2.16l-0,2.142l-3.856,-2.159l-0.001,-2.143Zm7.714,0l-0.001,2.143l-3.856,2.159l-0,-2.142l3.857,-2.16Zm-3.857,-5.469l6,3.171l-0,4.372l-1.029,0l-0,-3.799l-4.971,2.77l-6,-3.343l6,-3.171Z" style="fill:#389fd6;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 348 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M2.443,6.769l3.857,2.16l-0,2.142l-3.856,-2.159l-0.001,-2.143Zm7.714,0l-0.001,2.143l-3.856,2.159l-0,-2.142l3.857,-2.16Zm-3.857,-5.469l6,3.171l-0,4.372l-1.029,0l-0,-3.799l-4.971,2.77l-6,-3.343l6,-3.171Z" style="fill:#3592c4;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 348 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<g>
<path d="M6,10l-4,0l0,-5l9,0l0,1l1,0l0,-4l-11,0l0,9l5,0l0,-1Z" style="fill:#6e6e6e;fill-rule:nonzero;"/>
<g transform="matrix(0.965926,0.258819,-0.258819,0.965926,2.7558,-2.1844)">
<path d="M9.674,6.374l2.598,1.5l0,3l-2.598,1.5l-2.598,-1.5l0,-3l2.598,-1.5Z" style="fill:#59a869;fill-rule:nonzero;"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 449 B

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<g>
<path d="M6,10l-4,0l0,-5l9,0l0,1l1,0l0,-4l-11,0l0,9l5,0l0,-1Z" style="fill:#afb1b3;fill-rule:nonzero;"/>
<g transform="matrix(0.965926,0.258819,-0.258819,0.965926,2.7558,-2.1844)">
<path d="M9.674,6.374l2.598,1.5l0,3l-2.598,1.5l-2.598,-1.5l0,-3l2.598,-1.5Z" style="fill:#499c54;fill-rule:nonzero;"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 449 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<g transform="matrix(0.965926,0.258819,-0.258819,0.965926,1.91002,-1.46002)">
<path d="M6.5,1.524l4.33,2.5l0,5l-4.33,2.5l-4.33,-2.5l0,-5l4.33,-2.5Z" style="fill:#db5860;fill-rule:nonzero;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 303 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<g transform="matrix(0.965926,0.258819,-0.258819,0.965926,1.91002,-1.46002)">
<path d="M6.5,1.524l4.33,2.5l0,5l-4.33,2.5l-4.33,-2.5l0,-5l4.33,-2.5Z" style="fill:#c75450;fill-rule:nonzero;"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 303 B

View File

@ -1,7 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<g>
<rect x="0" y="0" width="13" height="13" style="fill:#ffe6ff;fill-opacity:0;"/>
<path d="M13,9.51c-0.005,1.916 -1.584,3.49 -3.5,3.49c-1.92,-0 -3.5,-1.58 -3.5,-3.5c0,-1.92 1.58,-3.5 3.5,-3.5c0.003,-0 0.007,-0 0.01,0c1.916,0.005 3.49,1.584 3.49,3.5c0,0.003 0,0.007 0,0.01Zm-1,0c0,-0.003 0,-0.007 0,-0.01c0,-1.369 -1.124,-2.496 -2.493,-2.5l-0.007,0l0,5c1.369,0 2.496,-1.124 2.5,-2.493l0,0.003Z" style="fill:#6e6e6e;fill-rule:nonzero;"/>
<path d="M13,9.51c-0.005,1.916 -1.584,3.49 -3.5,3.49c-1.92,0 -3.5,-1.58 -3.5,-3.5c0,-1.92 1.58,-3.5 3.5,-3.5l0.01,0c1.916,0.005 3.49,1.584 3.49,3.5l0,0.01Zm-1,0l0,-0.01c0,-1.369 -1.124,-2.496 -2.493,-2.5l-0.007,0l0,5c1.369,0 2.496,-1.124 2.5,-2.493l0,0.003Z" style="fill:#6e6e6e;fill-rule:nonzero;"/>
<path d="M5.226,10.84l-0.226,0.16c-2.41,-1.7 -5,-3.46 -5,-10c1.59,-0.64 3.286,-0.979 5,-1c1.714,0.021 3.41,0.36 5,1c0.019,1.346 -0.124,2.689 -0.426,4l-0.054,0c-0.337,0.001 -0.672,0.04 -1,0.116c0.301,-1.114 0.462,-2.262 0.48,-3.416c-1.291,-0.43 -2.639,-0.666 -4,-0.7l0,8.77l0.026,-0.019c0.021,0.37 0.088,0.736 0.2,1.089Z" style="fill:#59a869;fill-rule:nonzero;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 788 B

View File

@ -1,7 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<g>
<rect x="0" y="0" width="13" height="13" style="fill:#ffe6ff;fill-opacity:0;"/>
<path d="M13,9.51c-0.005,1.916 -1.584,3.49 -3.5,3.49c-1.92,-0 -3.5,-1.58 -3.5,-3.5c0,-1.92 1.58,-3.5 3.5,-3.5c0.003,-0 0.007,-0 0.01,0c1.916,0.005 3.49,1.584 3.49,3.5c0,0.003 0,0.007 0,0.01Zm-1,0c0,-0.003 0,-0.007 0,-0.01c0,-1.369 -1.124,-2.496 -2.493,-2.5l-0.007,0l0,5c1.369,0 2.496,-1.124 2.5,-2.493l0,0.003Z" style="fill:#afb1b3;fill-rule:nonzero;"/>
<path d="M13,9.51c-0.005,1.916 -1.584,3.49 -3.5,3.49c-1.92,0 -3.5,-1.58 -3.5,-3.5c0,-1.92 1.58,-3.5 3.5,-3.5l0.01,0c1.916,0.005 3.49,1.584 3.49,3.5l0,0.01Zm-1,0l0,-0.01c0,-1.369 -1.124,-2.496 -2.493,-2.5l-0.007,0l0,5c1.369,0 2.496,-1.124 2.5,-2.493l0,0.003Z" style="fill:#afb1b3;fill-rule:nonzero;"/>
<path d="M5.226,10.84l-0.226,0.16c-2.41,-1.7 -5,-3.46 -5,-10c1.59,-0.64 3.286,-0.979 5,-1c1.714,0.021 3.41,0.36 5,1c0.019,1.346 -0.124,2.689 -0.426,4l-0.054,0c-0.337,0.001 -0.672,0.04 -1,0.116c0.301,-1.114 0.462,-2.262 0.48,-3.416c-1.291,-0.43 -2.639,-0.666 -4,-0.7l0,8.77l0.026,-0.019c0.021,0.37 0.088,0.736 0.2,1.089Z" style="fill:#499c54;fill-rule:nonzero;"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 929 B

After

Width:  |  Height:  |  Size: 788 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M2.502,4.485c0.286,-2 1.998,-3.485 4.019,-3.485c2.002,-0 3.705,1.46 4.011,3.438l0.551,3.562l-9.083,0l0.502,-3.515Z" style="fill:#eda200;fill-rule:nonzero;"/>
<path d="M1,10c0,-1.657 1.343,-3 3,-3l5,0c1.657,0 3,1.343 3,3l-11,0Z" style="fill:#eda200;fill-rule:nonzero;"/>
<path d="M8.333,11c0,1.105 -0.82,2 -1.833,2c-1.012,0 -1.833,-0.895 -1.833,-2l3.666,0Z" style="fill:#eda200;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 511 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M1,10c0,-1.657 1.343,-3 3,-3l5,0c1.657,0 3,1.343 3,3l-11,0Z" style="fill:#eda200;fill-rule:nonzero;"/>
<path d="M8.333,11c0,1.105 -0.82,2 -1.833,2c-1.012,0 -1.833,-0.895 -1.833,-2l3.666,0Z" style="fill:#eda200;fill-rule:nonzero;"/>
<path d="M10.772,5.99c-0.09,0.006 -0.18,0.01 -0.272,0.01c-1.933,0 -3.5,-1.567 -3.5,-3.5c0,-0.507 0.108,-0.989 0.302,-1.425c-0.253,-0.049 -0.515,-0.075 -0.781,-0.075c-2.021,0 -3.733,1.485 -4.019,3.485l-0.502,3.515l9.083,0l-0.311,-2.01Z" style="fill:#eda200;fill-rule:nonzero;"/>
<circle cx="10.5" cy="2.5" r="2.5" style="fill:#389fd6;"/>
</svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M1,10c0,-1.657 1.343,-3 3,-3l5,0c1.657,0 3,1.343 3,3l-11,0Z" style="fill:#eda200;fill-rule:nonzero;"/>
<path d="M8.333,11c0,1.105 -0.82,2 -1.833,2c-1.012,0 -1.833,-0.895 -1.833,-2l3.666,0Z" style="fill:#eda200;fill-rule:nonzero;"/>
<path d="M10.772,5.99c-0.09,0.006 -0.18,0.01 -0.272,0.01c-1.933,0 -3.5,-1.567 -3.5,-3.5c0,-0.507 0.108,-0.989 0.302,-1.425c-0.253,-0.049 -0.515,-0.075 -0.781,-0.075c-2.021,0 -3.733,1.485 -4.019,3.485l-0.502,3.515l9.083,0l-0.311,-2.01Z" style="fill:#eda200;fill-rule:nonzero;"/>
<circle cx="10.5" cy="2.5" r="2.5" style="fill:#db5860;"/>
</svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M1,10c0,-1.657 1.343,-3 3,-3l5,0c1.657,0 3,1.343 3,3l-11,0Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<path d="M8.333,11c0,1.105 -0.82,2 -1.833,2c-1.012,0 -1.833,-0.895 -1.833,-2l3.666,0Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<path d="M10.772,5.99c-0.09,0.006 -0.18,0.01 -0.272,0.01c-1.933,0 -3.5,-1.567 -3.5,-3.5c0,-0.507 0.108,-0.989 0.302,-1.425c-0.253,-0.049 -0.515,-0.075 -0.781,-0.075c-2.021,0 -3.733,1.485 -4.019,3.485l-0.502,3.515l9.083,0l-0.311,-2.01Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<circle cx="10.5" cy="2.5" r="2.5" style="fill:#c75450;"/>
</svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M1,10c0,-1.657 1.343,-3 3,-3l5,0c1.657,0 3,1.343 3,3l-11,0Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<path d="M8.333,11c0,1.105 -0.82,2 -1.833,2c-1.012,0 -1.833,-0.895 -1.833,-2l3.666,0Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<path d="M10.772,5.99c-0.09,0.006 -0.18,0.01 -0.272,0.01c-1.933,0 -3.5,-1.567 -3.5,-3.5c0,-0.507 0.108,-0.989 0.302,-1.425c-0.253,-0.049 -0.515,-0.075 -0.781,-0.075c-2.021,0 -3.733,1.485 -4.019,3.485l-0.502,3.515l9.083,0l-0.311,-2.01Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<circle cx="10.5" cy="2.5" r="2.5" style="fill:#3592c4;"/>
</svg>

After

Width:  |  Height:  |  Size: 685 B

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M2.502,4.485c0.286,-2 1.998,-3.485 4.019,-3.485c2.002,0 3.705,1.46 4.011,3.438l0.551,3.562l-9.083,0l0.502,-3.515Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<path d="M1,10c0,-1.657 1.343,-3 3,-3l5,0c1.657,0 3,1.343 3,3l-11,0Z" style="fill:#f0a732;fill-rule:nonzero;"/>
<path d="M8.333,11c0,1.105 -0.82,2 -1.833,2c-1.012,0 -1.833,-0.895 -1.833,-2l3.666,0Z" style="fill:#f0a732;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 510 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M2,12l4.5,-4l4.5,4l0,-11l-9,0l0,11Z" style="fill:#eda200;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 183 B

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 13 13">
<path d="M2,12l4.5,-4l4.5,4l0,-11l-9,0l0,11Z" style="fill:#f0a732;fill-rule:nonzero;"/>
</svg>

After

Width:  |  Height:  |  Size: 183 B

View File

@ -6,11 +6,12 @@ import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
public class IconPatcher extends IconPathPatcher{
public class IconPatcher extends IconPathPatcher {
private final ClassLoader classLoader = getClass().getClassLoader();
private final Map<String, String> iconPaths = new HashMap<>();
public IconPatcher(){
public IconPatcher() {
addPathWithDark("actions/addList");
addPathWithDark("actions/AddMulticaret");
addPathWithDark("actions/back");
addPathWithDark("actions/buildAutoReloadChanges");
@ -78,6 +79,7 @@ public class IconPatcher extends IconPathPatcher{
addPathWithDark("hierarchy/subtypes");
addPathWithDark("hierarchy/supertypes");
addPathWithDark("icons/artifactSmall");
addPathWithDark("icons/cherryPick");
addPathWithDark("icons/CMakeToolWindow");
addPathWithDark("icons/ConcurrencyDiagramToolwindow");
@ -99,6 +101,7 @@ public class IconPatcher extends IconPathPatcher{
addPathWithDark("icons/toolwindowEndpoints");
addPathWithDark("icons/toolWindowGradle");
addPathWithDark("icons/toolWindowSQLGenerator");
addPathWithDark("icons/youTrack");
addPathWithDark("icons/buildTools/gulp_toolwindow");
addPathWithDark("icons/buildTools/grunt/grunt_toolwindow");
addPathWithDark("icons/buildTools/npm/npm_13");
@ -110,6 +113,8 @@ public class IconPatcher extends IconPathPatcher{
addPathWithDark("images/updateFolders");
addPathWithDark("images/webServerToolWindow");
addPathWithDark("img/featureTrainerToolWindow");
addPathWithDark("modules/addExcludedRoot");
addPathWithDark("objectBrowser/sortByType");
@ -118,6 +123,8 @@ public class IconPatcher extends IconPathPatcher{
addPathWithDark("objectBrowser/visibilitySort");
addPathWithDark("org/jetbrains/plugins/github/pullRequestsToolWindow");
addPathWithDark("org/jetbrains/plugins/scala/images/sbtShellToolwin");
addPathWithDark("org/jetbrains/plugins/scala/images/sbtToolwin");
addPathWithDark("resources/icons/bvToolWindow");
addPathWithDark("resources/icons/hibConsoleToolWindow");
@ -146,8 +153,12 @@ public class IconPatcher extends IconPathPatcher{
addPathWithDark("toolbarDecorator/import");
addPathWithDark("toolwindows/documentation");
addPathWithDark("toolwindows/notifications");
addPathWithDark("toolwindows/notificationsNew");
addPathWithDark("toolwindows/notificationsNewImportant");
addPathWithDark("toolwindows/toolWindowAnalyzeDataflow");
addPathWithDark("toolwindows/toolWindowAnt");
addPathWithDark("toolwindows/toolWindowBookmarks");
addPathWithDark("toolwindows/toolWindowBuild");
addPathWithDark("toolwindows/toolWindowChanges");
addPathWithDark("toolwindows/toolWindowCommit");
@ -160,7 +171,7 @@ public class IconPatcher extends IconPathPatcher{
addPathWithDark("toolwindows/toolWindowMessages");
addPathWithDark("toolwindows/toolWindowModuleDependencies");
addPathWithDark("toolwindows/toolWindowProfiler");
addPathWithDark("toolwindows/toolWindowProject"); // TODO not working
addPathWithDark("toolwindows/toolWindowProject");
addPathWithDark("toolwindows/toolWindowRun");
addPathWithDark("toolwindows/toolWindowServices");
addPathWithDark("toolwindows/toolWindowStructure");
@ -178,20 +189,20 @@ public class IconPatcher extends IconPathPatcher{
IconLoader.installPathPatcher(this);
}
private void addPathWithDark(final String path){
private void addPathWithDark(final String path) {
iconPaths.put('/' + path + ".svg", "/icons/" + path + ".svg");
iconPaths.put('/' + path + "_dark.svg", "/icons/" + path + "_dark.svg");
}
@Nullable
@Override
public String patchPath(@NotNull final String path, final ClassLoader classLoaderIgnore){
public String patchPath(@NotNull final String path, final ClassLoader classLoaderIgnore) {
return iconPaths.get(path);
}
@Nullable
@Override
public ClassLoader getContextClassLoader(@NotNull final String path, final ClassLoader originalClassLoader){
public ClassLoader getContextClassLoader(@NotNull final String path, final ClassLoader originalClassLoader) {
return classLoader;
}
}