Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
# power-mode-zeranthium Changelog

## [Unreleased]
- bug fix: Specify Read/Write Action types on some EDT Thread tasks


## [3.4.1-stable.243] - 2025-02-17

Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ pluginRepositoryUrl = https://github.com/cschar/power-mode-zeranthium
#pluginVersion = 1.14.0
#pluginVersion = 3.4.0-eap.242
#pluginVersion = 3.4.1-stable.251
pluginVersion = 3.4.1-stable.243
#pluginVersion = 3.4.1-stable.243
pluginVersion = 3.4.2-stable.243

# Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# when running ./gradlew :verifyPlugin, will start at below VERSION_NUM and check all going forward
Expand Down
9 changes: 8 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@ test_ui_launch_ide:
./gradlew :testIdeUi

test_ui_run_tests:
TEST_TYPE=UI ./gradlew :test --tests com.cschar.pmode3.uitest.OpenSettingsJavaTest
TEST_TYPE=UI ./gradlew :test --tests com.cschar.pmode3.uitest.OpenSettingsJavaTest

gradle_check_cache:
dust ~/.gradle

gradle_clean_cache:
rm -rf ~/.gradle/caches/transforms/
# rm -rf ~/.gradle/caches
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package com.cschar.pmode3;

import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollingModel;
import com.intellij.openapi.editor.VisualPosition;
Expand All @@ -37,7 +38,7 @@
*/
public class ParticleContainerManager implements EditorFactoryListener, Disposable {
private static final Logger LOGGER = Logger.getInstance(ParticleContainerManager.class);
private PowerMode3 settings;

Check warning on line 41 in src/main/java/com/cschar/pmode3/ParticleContainerManager.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Field may be 'final'

Field `settings` may be 'final'
/** the main render thread */
private Thread thread;
public static Map<Editor, ParticleContainer> particleContainers = new HashMap<>();
Expand All @@ -61,7 +62,7 @@

try {
// 1000ms/60 = 16.6666666667 60 fps
Thread.sleep(17);

Check warning on line 65 in src/main/java/com/cschar/pmode3/ParticleContainerManager.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Busy wait

Call to `Thread.sleep()` in a loop, probably busy-waiting
} catch (InterruptedException ignored) {
LOGGER.debug("Thread interrupted ....");
//thread interrupted, shutdown
Expand Down Expand Up @@ -128,7 +129,7 @@

particleContainers.put(editor, pc);

// MyCaretListener cl = new MyCaretListener();

Check notice on line 132 in src/main/java/com/cschar/pmode3/ParticleContainerManager.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Commented out code

Commented out code (4 lines)
// MyCaretListener.enabled = true;
// editor.getCaretModel().addCaretListener(cl, this);
// editor.getCaretModel().addCaretListener(cl, pc);
Expand All @@ -154,7 +155,9 @@
@Override
public void run()
{
updateInUI(editor);
ApplicationManager.getApplication().runReadAction(() -> {
updateInUI(editor);
});
}
});
}
Expand Down Expand Up @@ -197,11 +200,11 @@
break;
}

char c = documentText.charAt(anchorOffset);

Check notice on line 203 in src/main/java/com/cschar/pmode3/ParticleContainerManager.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Method can be extracted

It's possible to extract method returning 'addPoint' from a long surrounding method


boolean addPoint = false;
if (settings.anchorType == PowerMode3.AnchorTypes.BRACE

Check warning on line 207 in src/main/java/com/cschar/pmode3/ParticleContainerManager.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Redundant 'if' statement

`if` statement can be simplified
&& (c == '{' || c == '}')) {
addPoint = true;
}
Expand Down Expand Up @@ -233,6 +236,6 @@
}


return points.toArray(new Anchor[points.size()]);

Check warning on line 239 in src/main/java/com/cschar/pmode3/ParticleContainerManager.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

'Collection.toArray()' call style

Call to `toArray()` with pre-sized array argument 'new Anchor\[points.size()\]'
}
}
223 changes: 108 additions & 115 deletions src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
private static final Logger LOGGER = Logger.getInstance(MyPasteHandler.class.getName());

// deprecated
// @Override

Check notice on line 30 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Commented out code

Commented out code (8 lines)
// public void execute(Editor editor, DataContext dataContext, Producer<Transferable> producer) {
//
// LOGGER.info("Psting...in project.." + editor.getProject().getName());
Expand All @@ -39,14 +39,14 @@
@Override
public void execute(Editor editor, DataContext dataContext, @Nullable Producer<? extends Transferable> producer) {

LOGGER.debug("Pasting...in project.." + editor.getProject().getName());

Check warning on line 42 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Nullability and data flow problems

Method invocation `getName` may produce `NullPointerException`
if (origEditorActionHandler != null && origEditorActionHandler instanceof EditorTextInsertHandler) {
((EditorTextInsertHandler) origEditorActionHandler).execute(editor, dataContext, producer);
}
}


private EditorActionHandler origEditorActionHandler;

Check warning on line 49 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Field may be 'final'

Field `origEditorActionHandler` may be 'final'

public MyPasteHandler(@NotNull EditorActionHandler origEditorActionHandler) {
LOGGER.debug("creating MyPasteHandler");
Expand All @@ -56,7 +56,7 @@
@Override
protected void doExecute(@NotNull Editor editor, @Nullable Caret caret, DataContext dataContext) {

LOGGER.debug("Pasting doExecute..in project.." + editor.getProject().getName());

Check warning on line 59 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Nullability and data flow problems

Method invocation `getName` may produce `NullPointerException`
PowerMode3 settings = PowerMode3.getInstance();

if(!settings.isEnabled() || !settings.getSpriteTypeEnabled(PowerMode3.ConfigType.COPYPASTEVOID)){
Expand All @@ -69,127 +69,120 @@
@Override
public void run() {

ScrollingModel scrollingModel = editor.getScrollingModel();

//disable so sprites render at correct spot and arent slowed down by visual scroll
scrollingModel.disableAnimation();
try {
int beforePasteOffset = scrollingModel.getVerticalScrollOffset();
}catch(UnsupportedOperationException e){
LOGGER.debug("paste unsupported, exiting early");
//if we are pasting into a search box via ctrl+f, etc.. (not a real editor),
// e.g. com.intellij.openapi.editor.textarea.TextComponentScrollingModel
// don't draw to GUI, just paste and exit
EditorCopyPasteHelper.getInstance().pasteFromClipboard(editor);
return;
}

TextRange[] pasted = EditorCopyPasteHelper.getInstance().pasteFromClipboard(editor);
if(pasted.length != 1) return; //ensure we have a single TextRange to work with
TextRange t = pasted[0];


//TODO: figure out how to calculate each pasted character x,y coord without incrementing caret
//Disable CaretListener for the following...
MyCaretListener.enabled = false;

// |hey| | |
// |ya| ----> | |
// |hello there hi| | |

//Begin moving caret along all of selected text to build an outline of
//the 'selected' blob. When outline built, add effect to it.
int afterPasteOffset = scrollingModel.getVerticalScrollOffset();
scrollingModel.enableAnimation();
//
// int charWidth = EditorUtil.getPlainSpaceWidth(editor);
int lineHeight = editor.getLineHeight();
int start = t.getStartOffset();
int offset = t.getLength(); //offset is # of characters typed

//paste outline points,
//to show where each line starts and ends with 2 points
// max size possible for line numbers is offset
// ex: paste offset 5, but contents is 5 characters w/ newlines
Point[][] poPoints = new Point[offset][2];

Caret curCaret = editor.getCaretModel().getCurrentCaret();
Point prevPoint = null;
Point point = null;
int curLine = 0;

for(int i = start; i <= start + offset; i++){
curCaret.moveToOffset(i);
VisualPosition visualPosition = curCaret.getVisualPosition();
point = editor.visualPositionToXY(visualPosition);
point.x = point.x - scrollingModel.getHorizontalScrollOffset();
point.y = point.y - afterPasteOffset;

if(prevPoint == null){ //only happens once
poPoints[0][0] = point;
}else{
if(prevPoint.y == point.y){ //on same line, dont add anything
//continue
}else {//we've moved to a new line,
// so add prevPoint as END of last line,
poPoints[curLine][1] = prevPoint;
curLine += 1;
//add new line boundary
poPoints[curLine][0] = point;
}
// All editor operations should be in write action since we're modifying content
WriteCommandAction.runWriteCommandAction(editor.getProject(), () -> {

ScrollingModel scrollingModel = editor.getScrollingModel();

//disable so sprites render at correct spot and arent slowed down by visual scroll
scrollingModel.disableAnimation();

int beforePasteOffset;
try {
beforePasteOffset = scrollingModel.getVerticalScrollOffset();

Check warning on line 82 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unused assignment

The value `scrollingModel.getVerticalScrollOffset()` assigned to `beforePasteOffset` is never used
} catch(UnsupportedOperationException e){
LOGGER.debug("paste unsupported, exiting early");
//if we are pasting into a search box via ctrl+f, etc.. (not a real editor),
// e.g. com.intellij.openapi.editor.textarea.TextComponentScrollingModel
// don't draw to GUI, just paste and exit
EditorCopyPasteHelper.getInstance().pasteFromClipboard(editor);
return;
}
prevPoint = point;

}

poPoints[curLine][1] = point;

TextRange[] pasted = EditorCopyPasteHelper.getInstance().pasteFromClipboard(editor);
if(pasted.length != 1) return; //ensure we have a single TextRange to work with

Check warning on line 93 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Nullability and data flow problems

Dereference of `pasted` may produce `NullPointerException`
TextRange t = pasted[0];

//TODO: figure out how to calculate each pasted character x,y coord without incrementing caret
//Disable CaretListener for the following...
MyCaretListener.enabled = false;

int afterPasteOffset = scrollingModel.getVerticalScrollOffset();
scrollingModel.enableAnimation();

int lineHeight = editor.getLineHeight();
int start = t.getStartOffset();
int offset = t.getLength(); //offset is # of characters typed

//paste outline points,
//to show where each line starts and ends with 2 points
// max size possible for line numbers is offset
// ex: paste offset 5, but contents is 5 characters w/ newlines
Point[][] poPoints = new Point[offset][2];

Caret curCaret = editor.getCaretModel().getCurrentCaret();
Point prevPoint = null;
Point point = null;
int curLine = 0;

for(int i = start; i <= start + offset; i++){
curCaret.moveToOffset(i);
VisualPosition visualPosition = curCaret.getVisualPosition();
point = editor.visualPositionToXY(visualPosition);
point.x = point.x - scrollingModel.getHorizontalScrollOffset();
point.y = point.y - afterPasteOffset;

if(prevPoint == null){ //only happens once
poPoints[0][0] = point;
}else{
if(prevPoint.y == point.y){ //on same line, dont add anything

Check warning on line 128 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Statement with empty body

`if` statement has empty body
//continue
}else {//we've moved to a new line,
// so add prevPoint as END of last line,
poPoints[curLine][1] = prevPoint;
curLine += 1;
//add new line boundary
poPoints[curLine][0] = point;
}
}
prevPoint = point;
}

//Now, with poPoints containing outline for every caret spot in blob
//flesh out the pasteShape
Path2D pasteShape = new Path2D.Double();
poPoints[curLine][1] = point;

//Now, with poPoints containing outline for every caret spot in blob
//flesh out the pasteShape
Path2D pasteShape = new Path2D.Double();

Check notice on line 145 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Method can be extracted

It's possible to extract method returning 'pasteShape' from a long surrounding method

for(int i = 0; i <= curLine; i++) {
if (i == 0) { //immediately go to right side
pasteShape.moveTo(poPoints[i][0].x, poPoints[i][0].y);
pasteShape.lineTo(poPoints[i][1].x, poPoints[i][1].y);
} else { //work way down to bottom
//move down
pasteShape.lineTo(poPoints[i-1][1].x, poPoints[i-1][1].y+lineHeight);
//move either left/right to meet next line point
pasteShape.lineTo(poPoints[i][1].x, poPoints[i][1].y);
}
}
//wrap around
pasteShape.lineTo(poPoints[curLine][1].x, poPoints[curLine][1].y + lineHeight);
pasteShape.lineTo(poPoints[curLine][0].x, poPoints[curLine][0].y + lineHeight);

for(int i = 0; i <= curLine; i++) {
if (i == 0) { //immediately go to right side
pasteShape.moveTo(poPoints[i][0].x, poPoints[i][0].y);
pasteShape.lineTo(poPoints[i][1].x, poPoints[i][1].y);
} else { //work way down to bottom
//move down
pasteShape.lineTo(poPoints[i-1][1].x, poPoints[i-1][1].y+lineHeight);
//move either left/right to meet next line point
pasteShape.lineTo(poPoints[i][1].x, poPoints[i][1].y);
//work way back up
for(int i = curLine; i > 0; i--) {
pasteShape.lineTo(poPoints[i][0].x, poPoints[i][0].y);
}
pasteShape.lineTo(poPoints[0][0].x, poPoints[0][0].y+lineHeight);
pasteShape.lineTo(poPoints[0][0].x, poPoints[0][0].y);

int winningIndex = SpriteDataAnimated.getWeightedAmountWinningIndex(ParticleSpritePasteShape.spriteDataAnimated);
if(winningIndex == -1 && !CopyPasteVoidConfig.FADE_ENABLED(settings)){

Check warning on line 170 in src/main/java/com/cschar/pmode3/actionHandlers/MyPasteHandler.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Statement with empty body

`if` statement has empty body
//do nothing
}else {
ParticleSpritePasteShape pFontShape = new ParticleSpritePasteShape(pasteShape, 100,
CopyPasteVoidConfig.FADE_COLOR(settings),
CopyPasteVoidConfig.FADE_AMOUNT(settings),
CopyPasteVoidConfig.FADE_ENABLED(settings),
winningIndex,
editor);
ParticleContainerManager.particleContainers.get(editor).addExternalParticle(pFontShape);
}
}
//wrap around
pasteShape.lineTo(poPoints[curLine][1].x, poPoints[curLine][1].y + lineHeight);
pasteShape.lineTo(poPoints[curLine][0].x, poPoints[curLine][0].y + lineHeight);

//work way back up
for(int i = curLine; i > 0; i--) {
pasteShape.lineTo(poPoints[i][0].x, poPoints[i][0].y);
}
pasteShape.lineTo(poPoints[0][0].x, poPoints[0][0].y+lineHeight);
pasteShape.lineTo(poPoints[0][0].x, poPoints[0][0].y);


int winningIndex = SpriteDataAnimated.getWeightedAmountWinningIndex(ParticleSpritePasteShape.spriteDataAnimated);
if(winningIndex == -1 && !CopyPasteVoidConfig.FADE_ENABLED(settings)){
//do nothing
}else {
ParticleSpritePasteShape pFontShape = new ParticleSpritePasteShape(pasteShape, 100,
CopyPasteVoidConfig.FADE_COLOR(settings),
CopyPasteVoidConfig.FADE_AMOUNT(settings),
CopyPasteVoidConfig.FADE_ENABLED(settings),
winningIndex,
editor);
ParticleContainerManager.particleContainers.get(editor).addExternalParticle(pFontShape);
}


MyCaretListener.enabled = true;
curCaret.moveToOffset(start+offset);
scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE);

MyCaretListener.enabled = true;
curCaret.moveToOffset(start+offset);
scrollingModel.scrollToCaret(ScrollType.MAKE_VISIBLE);
});
}
};

Expand Down
56 changes: 29 additions & 27 deletions src/main/java/com/cschar/pmode3/listeners/MyCaretListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.cschar.pmode3.config.LanternConfig;
import com.cschar.pmode3.config.LinkerConfig;
import com.cschar.pmode3.config.MultiLayerConfig;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollingModel;
Expand All @@ -29,47 +30,48 @@

if(enabled && pluginInitialized) {

Editor editor = event.getEditor();
VisualPosition visualPosition = event.getCaret().getVisualPosition();
Point point = editor.visualPositionToXY(visualPosition);
ScrollingModel scrollingModel = editor.getScrollingModel();
point.x = point.x - scrollingModel.getHorizontalScrollOffset();
point.y = point.y - scrollingModel.getVerticalScrollOffset();
ApplicationManager.getApplication().runReadAction(() -> {
Editor editor = event.getEditor();
VisualPosition visualPosition = event.getCaret().getVisualPosition();

Check warning on line 35 in src/main/java/com/cschar/pmode3/listeners/MyCaretListener.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Nullability and data flow problems

Method invocation `getVisualPosition` may produce `NullPointerException`
Point point = editor.visualPositionToXY(visualPosition);
ScrollingModel scrollingModel = editor.getScrollingModel();
point.x = point.x - scrollingModel.getHorizontalScrollOffset();
point.y = point.y - scrollingModel.getVerticalScrollOffset();


ParticleSpriteDroste.cursorX = point.x;
ParticleSpriteDroste.cursorY = point.y;

ParticleSpriteDroste.cursorX = point.x;
ParticleSpriteDroste.cursorY = point.y;
PowerMode3 settings = PowerMode3.getInstance();
if (settings.getSpriteTypeEnabled(PowerMode3.ConfigType.MULTI_LAYER) &&
MultiLayerConfig.MOVE_WITH_CARET(settings)) {

PowerMode3 settings = PowerMode3.getInstance();
if(settings.getSpriteTypeEnabled(PowerMode3.ConfigType.MULTI_LAYER) &&
MultiLayerConfig.MOVE_WITH_CARET(settings)){
ParticleSpriteMultiLayer.targetX = point.x;
ParticleSpriteMultiLayer.targetY = point.y;
ParticleSpriteMultiLayer.moveSpeed = MultiLayerConfig.CARET_MOVE_SPEED(settings);

ParticleSpriteMultiLayer.targetX = point.x;
ParticleSpriteMultiLayer.targetY = point.y;
ParticleSpriteMultiLayer.moveSpeed = MultiLayerConfig.CARET_MOVE_SPEED(settings);
}

}

if(settings.getSpriteTypeEnabled(PowerMode3.ConfigType.LINKER) &&
LinkerConfig.MOVE_WITH_CARET(settings)){
if (settings.getSpriteTypeEnabled(PowerMode3.ConfigType.LINKER) &&
LinkerConfig.MOVE_WITH_CARET(settings)) {

// ParticleSpriteLinkerAnchor.cursorX = point.x;

Check notice on line 58 in src/main/java/com/cschar/pmode3/listeners/MyCaretListener.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Commented out code

Commented out code (2 lines)
// ParticleSpriteLinkerAnchor.cursorY = point.y;
ParticleSpriteLinkerAnchor.targetX = point.x;
ParticleSpriteLinkerAnchor.targetY = point.y;
ParticleSpriteLinkerAnchor.moveSpeed = LinkerConfig.CARET_MOVE_SPEED(settings);
ParticleSpriteLinkerAnchor.targetX = point.x;
ParticleSpriteLinkerAnchor.targetY = point.y;
ParticleSpriteLinkerAnchor.moveSpeed = LinkerConfig.CARET_MOVE_SPEED(settings);

}
}

if(settings.getSpriteTypeEnabled(PowerMode3.ConfigType.LANTERN) &&
LanternConfig.MOVE_WITH_CARET(settings)){
if (settings.getSpriteTypeEnabled(PowerMode3.ConfigType.LANTERN) &&
LanternConfig.MOVE_WITH_CARET(settings)) {

ParticleSpriteLantern.targetX = point.x;
ParticleSpriteLantern.targetY = point.y;
ParticleSpriteLantern.targetX = point.x;
ParticleSpriteLantern.targetY = point.y;
// ParticleSpriteLantern.typeX = point.x;

Check notice on line 71 in src/main/java/com/cschar/pmode3/listeners/MyCaretListener.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Commented out code

Commented out code (2 lines)
// ParticleSpriteLantern.typeY = point.y;
}
}
});
}
}

Expand All @@ -82,4 +84,4 @@
public void caretRemoved(@NotNull CaretEvent event) {

}
};

Check warning on line 87 in src/main/java/com/cschar/pmode3/listeners/MyCaretListener.java

View workflow job for this annotation

GitHub Actions / Qodana Community for JVM

Unnecessary semicolon

Unnecessary semicolon `;`
Loading