diff --git a/.claude/commands/pr.md b/.claude/commands/pr.md
index 64c7128..e9aab39 100644
--- a/.claude/commands/pr.md
+++ b/.claude/commands/pr.md
@@ -46,5 +46,5 @@ Create a branch (if needed), commit staged/unstaged changes, push, and open/upda
- Body: formatted using this repo's PR template (`.github/PULL_REQUEST_TEMPLATE.md`),
with an additional footer: `🤖 Generated with [Claude Code](https://claude.ai/claude-code)`
- Labels — add any that are relevant:
- - `bug`, `build`, `ci/cd`, `code-folding`, dependencies`, `enhancement`, `refactor`, `sytax-highlighting`
+ - `bug`, `build`, `ci/cd`, `dependencies`, `enhancement`, `refactor`
- Only add a `tests` label if the PR is *only* adding test coverage
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index f276c6f..c3af96a 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -37,10 +37,10 @@ jobs:
- name: Checkout repository
uses: actions/checkout@v6
- - name: Set up JDK 17
+ - name: Set up JDK 25
uses: actions/setup-java@v5
with:
- java-version: '17'
+ java-version: '25'
distribution: 'temurin'
# Initializes the CodeQL tools for scanning.
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index 0038613..2676546 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -16,14 +16,14 @@ jobs:
strategy:
matrix:
- java: [ '17', '21', '23' ]
+ java: [ '25', '26' ]
steps:
- uses: actions/checkout@v6
- name: Verify gradle wrapper
- uses: gradle/actions/wrapper-validation@v5
- if: matrix.java == '17'
+ uses: gradle/actions/wrapper-validation@v6
+ if: matrix.java == '25'
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v5
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AbstractCompletionProvider.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AbstractCompletionProvider.java
index 4166b7d..9c777ac 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AbstractCompletionProvider.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AbstractCompletionProvider.java
@@ -236,6 +236,13 @@ public boolean removeCompletion(Completion c) {
public static class CaseInsensitiveComparator implements Comparator,
Serializable {
+ /**
+ * Empty constructor.
+ */
+ public CaseInsensitiveComparator() {
+ // Empty constructor for Javadoc/linting
+ }
+
@Override
public int compare(Object o1, Object o2) {
String s1 = o1 instanceof String ? (String)o1 :
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletePopupWindow.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
index 14ad7f8..4fa0305 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletePopupWindow.java
@@ -283,7 +283,7 @@ protected void doAutocomplete() {
*/
private static KeyStroke getCopyKeyStroke() {
int key = KeyEvent.VK_C;
- int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();
+ int mask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMaskEx();
return KeyStroke.getKeyStroke(key, mask);
}
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletion.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletion.java
index 5653c82..b08bac4 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletion.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/AutoCompletion.java
@@ -10,6 +10,7 @@
import java.awt.*;
import java.awt.event.*;
+import java.awt.geom.Rectangle2D;
import java.beans.*;
import java.util.List;
import javax.swing.*;
@@ -380,8 +381,8 @@ static boolean getDebug() {
* @return The default auto-complete trigger key.
*/
public static KeyStroke getDefaultTriggerKey() {
- // Default to CTRL, even on Mac, since Ctrl+Space activates Spotlight
- int mask = InputEvent.CTRL_MASK;
+ // Default to CTRL, even on Mac, since Cmd+Space activates Spotlight
+ int mask = InputEvent.CTRL_DOWN_MASK;
return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, mask);
}
@@ -865,19 +866,17 @@ protected int refreshPopupWindow() {
popupWindow.setCompletions(completions);
if (!popupWindow.isVisible()) {
- Rectangle r;
+ Rectangle2D r;
try {
- r = textComponent.modelToView(textComponent
- .getCaretPosition());
+ r = textComponent.modelToView2D(textComponent.getCaretPosition());
} catch (BadLocationException ble) {
ble.printStackTrace();
return -1;
}
- Point p = new Point(r.x, r.y);
+ Point p = new Point((int)r.getX(), (int)r.getY());
SwingUtilities.convertPointToScreen(p, textComponent);
- r.x = p.x;
- r.y = p.y;
- popupWindow.setLocationRelativeTo(r);
+ Rectangle r2 = new Rectangle(p.x, p.y, (int)r.getWidth(), (int)r.getHeight());
+ popupWindow.setLocationRelativeTo(r2);
setPopupVisible(true);
}
@@ -1416,11 +1415,17 @@ public void removeUpdate(DocumentEvent e) {
}
/**
- * The Action that displays the popup window if auto-completion
- * is enabled.
+ * The Action that displays the popup window if auto-completionn is enabled.
*/
protected class AutoCompleteAction extends AbstractAction {
+ /**
+ * Empty constructor.
+ */
+ protected AutoCompleteAction() {
+ // Empty constructor for Javadoc constructor/linting
+ }
+
@Override
public void actionPerformed(ActionEvent e) {
if (isAutoCompleteEnabled()) {
@@ -1486,8 +1491,7 @@ public void actionPerformed(ActionEvent e) {
* Listens for events in the parent window of the text component with
* auto-completion enabled.
*/
- private final class ParentWindowListener extends ComponentAdapter implements
- WindowFocusListener {
+ private final class ParentWindowListener extends ComponentAdapter implements WindowFocusListener {
public void addTo(Window w) {
w.addComponentListener(this);
@@ -1558,8 +1562,7 @@ public void uninstall(AutoCompletePopupWindow popupWindow) {
/**
* Listens for events from the text component we're installed on.
*/
- private final class TextComponentListener extends FocusAdapter implements
- HierarchyListener {
+ private final class TextComponentListener extends FocusAdapter implements HierarchyListener {
void addTo(JTextComponent tc) {
tc.addFocusListener(this);
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionCellRenderer.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionCellRenderer.java
index a7b5fdb..f2041f9 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionCellRenderer.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionCellRenderer.java
@@ -229,7 +229,7 @@ private String createTypeColor() {
public void delegateToSubstanceRenderer() throws Exception {
Class> clazz = Class.forName(SUBSTANCE_RENDERER_CLASS_NAME);
DefaultListCellRenderer delegate =
- (DefaultListCellRenderer)clazz.newInstance();
+ (DefaultListCellRenderer)clazz.getDeclaredConstructor().newInstance();
setDelegateRenderer(delegate);
}
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionProviderBase.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionProviderBase.java
index 96b5476..c1a033b 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionProviderBase.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/CompletionProviderBase.java
@@ -88,6 +88,14 @@ public abstract class CompletionProviderBase implements CompletionProvider {
new SortByRelevanceComparator();
+ /**
+ * Empty constructor.
+ */
+ public CompletionProviderBase() {
+ // Constructor only for no-oart Javadoc comment/linting
+ }
+
+
@Override
public void clearParameterizedCompletionParams() {
paramListEnd = paramListStart = 0;
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/DefaultCompletionProvider.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/DefaultCompletionProvider.java
index df314e1..a91b420 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/DefaultCompletionProvider.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/DefaultCompletionProvider.java
@@ -124,7 +124,7 @@ public String getAlreadyEnteredText(JTextComponent comp) {
@Override
public List getCompletionsAt(JTextComponent tc, Point p) {
- int offset = tc.viewToModel(p);
+ int offset = tc.viewToModel2D(p);
if (offset<0 || offset>=tc.getDocument().getLength()) {
lastCompletionsAtText = null;
return lastParameterizedCompletionsAt = null;
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletion.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletion.java
index 4b05f7c..4720b2b 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletion.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletion.java
@@ -160,6 +160,8 @@ public Object getTypeObject() {
}
/**
+ * Returns whether this is the last parameter in the completion text.
+ *
* @return Whether this parameter is an "ending parameter;"
* that is, whether this parameter is at a logical "ending
* point" in the completion text. If the user types in a
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletionContext.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletionContext.java
index 0671a52..5a72008 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletionContext.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/ParameterizedCompletionContext.java
@@ -17,6 +17,7 @@
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
+import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
@@ -205,12 +206,11 @@ public void activate() {
parentWindow, this, ac, pc);
try {
int dot = tc.getCaretPosition();
- Rectangle r = tc.modelToView(dot);
- Point p = new Point(r.x, r.y);
+ Rectangle2D r = tc.modelToView2D(dot);
+ Point p = new Point((int)r.getX(), (int)r.getY());
SwingUtilities.convertPointToScreen(p, tc);
- r.x = p.x;
- r.y = p.y;
- tip.setLocationRelativeTo(r);
+ Rectangle r2 = new Rectangle(p.x, p.y, (int)r.getWidth(), (int)r.getHeight());
+ tip.setLocationRelativeTo(r2);
tip.setVisible(true);
} catch (BadLocationException ble) { // Should never happen
UIManager.getLookAndFeel().provideErrorFeedback(tc);
@@ -472,7 +472,7 @@ private void installKeyBindings() {
oldTabAction = am.get(IM_KEY_TAB);
am.put(IM_KEY_TAB, new NextParamAction());
- ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK);
+ ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK);
oldShiftTabKey = im.get(ks);
im.put(ks, IM_KEY_SHIFT_TAB);
oldShiftTabAction = am.get(IM_KEY_SHIFT_TAB);
@@ -674,12 +674,11 @@ private void prepareParamChoicesWindow() {
JTextComponent tc = ac.getTextComponent();
try {
- Rectangle r = tc.modelToView(offs);
- Point p = new Point(r.x, r.y);
+ Rectangle2D r = tc.modelToView2D(offs);
+ Point p = new Point((int)r.getX(), (int)r.getY());
SwingUtilities.convertPointToScreen(p, tc);
- r.x = p.x;
- r.y = p.y;
- paramChoicesWindow.setLocationRelativeTo(r);
+ Rectangle r2 = new Rectangle(p.x, p.y, (int)r.getWidth(), (int)r.getHeight());
+ paramChoicesWindow.setLocationRelativeTo(r2);
} catch (BadLocationException ble) { // Should never happen
UIManager.getLookAndFeel().provideErrorFeedback(tc);
ble.printStackTrace();
@@ -770,7 +769,7 @@ private void uninstallKeyBindings() {
im.put(ks, oldTabKey);
am.put(IM_KEY_TAB, oldTabAction);
- ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK);
+ ks = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK);
im.put(ks, oldShiftTabKey);
am.put(IM_KEY_SHIFT_TAB, oldShiftTabAction);
diff --git a/AutoComplete/src/main/java/org/fife/ui/autocomplete/SortByRelevanceComparator.java b/AutoComplete/src/main/java/org/fife/ui/autocomplete/SortByRelevanceComparator.java
index ec2a36f..70d7bf2 100644
--- a/AutoComplete/src/main/java/org/fife/ui/autocomplete/SortByRelevanceComparator.java
+++ b/AutoComplete/src/main/java/org/fife/ui/autocomplete/SortByRelevanceComparator.java
@@ -22,6 +22,14 @@
*/
public class SortByRelevanceComparator implements Comparator, Serializable {
+ /**
+ * Compares to {@code CompletionProvider}s by their relevance before sorting them
+ * lexicographically.
+ */
+ public SortByRelevanceComparator() {
+ // Do nothing (for Javadoc comment)
+ }
+
@Override
public int compare(Completion c1, Completion c2) {
diff --git a/build.gradle b/build.gradle
index 295386e..2d988dc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -14,12 +14,12 @@ plugins {
apply plugin: 'io.github.gradle-nexus.publish-plugin'
-// We require building with JDK 17 or later. Built artifact compatibility
+// We require building with JDK 25 or later. Built artifact compatibility
// is controlled by javaLanguageVersion
-assert JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)
+assert JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_25)
group = 'com.fifesoft'
-// NOTE: Local Java 17: /Library/Java/JavaVirtualMachines/jdk-17.0.13+11/Contents/Home
+// NOTE: Local Java 25: /Library/Java/JavaVirtualMachines/jdk-25.0.1+8/Contents/Home
allprojects {
@@ -31,7 +31,7 @@ allprojects {
}
wrapper {
- gradleVersion = '9.2.1'
+ gradleVersion = '9.6.1'
}
}
diff --git a/gradle.properties b/gradle.properties
index febffc4..4b1635a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,5 +1,5 @@
# Note that Maven- and signing-related properties are in /gradle.properties
-javaLanguageVersion=8
+javaLanguageVersion=11
version=3.3.4-SNAPSHOT
# Ugh, see https://github.com/gradle/gradle/issues/11308
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index f8e1ee3..b1b8ef5 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 23449a2..a9db115 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,9 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
networkTimeout=10000
+retries=0
+retryBackOffMs=500
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index adff685..249efbb 100755
--- a/gradlew
+++ b/gradlew
@@ -20,7 +20,7 @@
##############################################################################
#
-# Gradle start up script for POSIX generated by Gradle.
+# gradlew start up script for POSIX generated by Gradle.
#
# Important for running:
#
@@ -29,7 +29,7 @@
# bash, then to run this script, type that shell name before the whole
# command line, like:
#
-# ksh Gradle
+# ksh gradlew
#
# Busybox and similar reduced shells will NOT work, because this script
# requires all of these POSIX shell features:
@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/3d91ce3b8caaf77ad09f381f43615b715b53f72c/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
diff --git a/gradlew.bat b/gradlew.bat
index e509b2d..8508ef6 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -19,12 +19,12 @@
@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
-@rem Gradle startup script for Windows
+@rem gradlew startup script for Windows
@rem
@rem ##########################################################################
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
+@rem Set local scope for the variables, and ensure extensions are enabled
+setlocal EnableExtensions
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@@ -51,7 +51,7 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
-goto fail
+"%COMSPEC%" /c exit 1
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
@@ -65,29 +65,18 @@ echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
-goto fail
+"%COMSPEC%" /c exit 1
:execute
@rem Setup the command line
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
+@rem Execute gradlew
+@rem endlocal doesn't take effect until after the line is parsed and variables are expanded
+@rem which allows us to clear the local environment before executing the java command
+endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel
-:end
-@rem End local scope for the variables with windows NT shell
-if %ERRORLEVEL% equ 0 goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-set EXIT_CODE=%ERRORLEVEL%
-if %EXIT_CODE% equ 0 set EXIT_CODE=1
-if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
-exit /b %EXIT_CODE%
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+:exitWithErrorLevel
+@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts
+"%COMSPEC%" /c exit %ERRORLEVEL%