diff --git a/ide/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/api/execution/NativeExecutionService.java b/ide/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/api/execution/NativeExecutionService.java index ff3780db8273..3c1a53df2aaf 100644 --- a/ide/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/api/execution/NativeExecutionService.java +++ b/ide/dlight.nativeexecution/src/org/netbeans/modules/nativeexecution/api/execution/NativeExecutionService.java @@ -54,11 +54,11 @@ import org.openide.windows.OutputWriter; /** - * This is a wrapper over an Executionservice that handles running + * This is a wrapper over an {@link ExecutionService} that handles running * NativeProcesses in a terminal output window. * * It also can be used for running in an output windows - in this case it just - * delegates execution to the ExecutionService + * delegates execution to the {@link ExecutionService} * * @see ExecutionService * @see NativeExecutionDescriptor @@ -126,49 +126,32 @@ private Future runTerm() { processBuilder.setUsePty(true); if (IOEmulation.isSupported(descriptor.inputOutput)) { - // TODO: this is a temporary solution. - // - // Currently only ansi emulation is supported (NB7.4). - // xterm/dtterm cannot be considered as fully supported yet.. - // So will set TERM environment to 'ansi' - String termType = processBuilder.getEnvironment().get("TERM"); //NOI18N - if (termType != null && termType.startsWith("xterm")) { //NOI18N - // $TERM is one of xterm-color, xterm-16color, xterm-88color, or xterm-256color. - // Allows user to use his favorite one. - processBuilder.getEnvironment().put("TERM", termType); // NOI18N - } else { - processBuilder.getEnvironment().put("TERM", "xterm" /*IOEmulation.getEmulation(descriptor.inputOutput)*/); // NOI18N - } + processBuilder.getEnvironment().put("TERM", IOEmulation.getEmulation(descriptor.inputOutput)); // NOI18N + // This is a hack - this should also come from the IOEmulation + processBuilder.getEnvironment().put("COLORTERM", "truecolor"); // NOI18N } else { processBuilder.getEnvironment().put("TERM", "dumb"); // NOI18N } processBuilder.setCharset(descriptor.charset); - Callable callable = new Callable() { - - @Override - public Integer call() throws Exception { - ProgressHandle progressHandle = null; + Callable callable = () -> { + ProgressHandle progressHandle = null; - try { - if (descriptor.showProgress) { - Cancellable c = null; - if (descriptor.controllable) { - c = new Cancellable() { - - @Override - public boolean cancel() { - FutureTask task = runTaskRef.get(); - if (task != null) { - return task.cancel(true); - } - return false; - } - }; - } + try { + if (descriptor.showProgress) { + Cancellable c = null; + if (descriptor.controllable) { + c = () -> { + FutureTask task = runTaskRef.get(); + if (task != null) { + return task.cancel(true); + } + return false; + }; + } - progressHandle = ProgressHandle.createHandle(displayName, c);//, new AbstractAction() { + progressHandle = ProgressHandle.createHandle(displayName, c);//, new AbstractAction() { // @Override // public void actionPerformed(ActionEvent e) { @@ -177,83 +160,76 @@ public boolean cancel() { // } // } // }); - progressHandle.start(); - } - - final NativeProcess process = processBuilder.call(); + progressHandle.start(); + } - /** - * As IO could be re-used we need to 'unlock' it because it - * could be 'locked' by previous run... (It is always set to - * read-only mode on run finish) - */ - IOTerm.setReadOnly(descriptor.inputOutput, !descriptor.inputVisible); - //IOTerm.term(descriptor.inputOutput).setReadOnly(!descriptor.inputVisible); - - PtySupport.connect(descriptor.inputOutput, process, new PreExecution()); - - /** - * We call invokeAndWait here to be sure that connect is - * done. This is because connection is asynchronous - * operation that occurs in EDT. return from connect() - * guarantees that event was posted to EDT. So our event is - * queued after that one. So as soon as our is processed we - * are sure that connection is done. - */ - /** - * comment above is true only in case of NetBeans implementation - * As only in NB implementation the task of connecting to the IOTerm - * is invoked asynchronous in EDT. - * In other case it can be done differently, - * that's why we will use IOTerm itself to provide service for - * running pre-execution task - */ - // SwingUtilities.invokeAndWait(new PreExecution()); + final NativeProcess process = processBuilder.call(); + + /** + * As IO could be re-used we need to 'unlock' it because it + * could be 'locked' by previous run... (It is always set to + * read-only mode on run finish) + */ + IOTerm.setReadOnly(descriptor.inputOutput, !descriptor.inputVisible); + //IOTerm.term(descriptor.inputOutput).setReadOnly(!descriptor.inputVisible); + + PtySupport.connect(descriptor.inputOutput, process, new PreExecution()); + + /** + * We call invokeAndWait here to be sure that connect is + * done. This is because connection is asynchronous + * operation that occurs in EDT. return from connect() + * guarantees that event was posted to EDT. So our event is + * queued after that one. So as soon as our is processed we + * are sure that connection is done. + */ + /** + * comment above is true only in case of NetBeans implementation + * As only in NB implementation the task of connecting to the IOTerm + * is invoked asynchronous in EDT. + * In other case it can be done differently, + * that's why we will use IOTerm itself to provide service for + * running pre-execution task + */ + // SwingUtilities.invokeAndWait(new PreExecution()); + + if (process.getState() == State.ERROR) { + out(true, ProcessUtils.readProcessErrorLine(process), "\r"); // NOI18N + return 1; + } - if (process.getState() == State.ERROR) { - out(true, ProcessUtils.readProcessErrorLine(process), "\r"); // NOI18N - return 1; - } + return process.waitFor(); + } finally { + if (progressHandle != null) { + progressHandle.finish(); + } - return process.waitFor(); + final CountDownLatch latch = new CountDownLatch(1); + IOTerm.disconnect(descriptor.inputOutput, latch::countDown); + try { + // The problem here is that continuation passed to the + // disconnect() method could be ignored (if, for some + // reasons terminal is already disconnected. + // In this case we may deadlock on wait. + // It is not possible to detect if continuation was not + // called because of some error or because terminal is + // still waiting for IO drain.. + // To avoid deadlocks assume that 5 seconds is enough + // for drain... and assume that if runnable was not + // called in 5 seconds then it makes no sense to wait + // any more. + // The worst situation that this approach could lead to + // is that postExecution is called before all IO was + // drained.... + latch.await(5, TimeUnit.SECONDS); } finally { - if (progressHandle != null) { - progressHandle.finish(); - } - - final CountDownLatch latch = new CountDownLatch(1); - IOTerm.disconnect(descriptor.inputOutput, new Runnable() { - - @Override - public void run() { - latch.countDown(); - } - }); try { - // The problem here is that continuation passed to the - // disconnect() method could be ignored (if, for some - // reasons terminal is already disconnected. - // In this case we may deadlock on wait. - // It is not possible to detect if continuation was not - // called because of some error or because terminal is - // still waiting for IO drain.. - // To avoid deadlocks assume that 5 seconds is enough - // for drain... and assume that if runnable was not - // called in 5 seconds then it makes no sense to wait - // any more. - // The worst situation that this approach could lead to - // is that postExecution is called before all IO was - // drained.... - latch.await(5, TimeUnit.SECONDS); - } finally { - try { - if (descriptor.postExecution != null) { - descriptor.postExecution.run(); - } - } finally { - IOTerm.setReadOnly(descriptor.inputOutput, true); - //IOTerm.term(descriptor.inputOutput).setReadOnly(true); + if (descriptor.postExecution != null) { + descriptor.postExecution.run(); } + } finally { + IOTerm.setReadOnly(descriptor.inputOutput, true); + //IOTerm.term(descriptor.inputOutput).setReadOnly(true); } } } @@ -329,22 +305,18 @@ private static boolean isUnitTestMode() { } private void out(final boolean toError, final CharSequence... cs) { - final Action action = new Action() { - - @Override - public Void run() { - if (descriptor.inputOutput != null) { - OutputWriter w = toError - ? descriptor.inputOutput.getErr() - : descriptor.inputOutput.getOut(); - if (w != null) { - for (CharSequence c : cs) { - w.append(c); - } + final Action action = () -> { + if (descriptor.inputOutput != null) { + OutputWriter w = toError + ? descriptor.inputOutput.getErr() + : descriptor.inputOutput.getOut(); + if (w != null) { + for (CharSequence c : cs) { + w.append(c); } } - return null; } + return null; }; if (isUnitTestMode()) { action.run(); @@ -354,26 +326,22 @@ public Void run() { } private void closeIO() { - Mutex.EVENT.writeAccess(new Action() { - - @Override - public Void run() { - final OutputWriter out = (descriptor.inputOutput == null) ? null : descriptor.inputOutput.getOut(); - final OutputWriter err = (descriptor.inputOutput == null) ? null : descriptor.inputOutput.getErr(); - if (err != null) { - try { - err.close(); - } catch (Throwable th) { - } + Mutex.EVENT.writeAccess((Action) () -> { + final OutputWriter out = (descriptor.inputOutput == null) ? null : descriptor.inputOutput.getOut(); + final OutputWriter err = (descriptor.inputOutput == null) ? null : descriptor.inputOutput.getErr(); + if (err != null) { + try { + err.close(); + } catch (Throwable th) { } - if (out != null) { - try { - out.close(); - } catch (Throwable th) { - } + } + if (out != null) { + try { + out.close(); + } catch (Throwable th) { } - return null; } + return null; }); } diff --git a/ide/lib.terminalemulator/nbproject/project.properties b/ide/lib.terminalemulator/nbproject/project.properties index e9b64b41c82d..1cb4c76b6b01 100644 --- a/ide/lib.terminalemulator/nbproject/project.properties +++ b/ide/lib.terminalemulator/nbproject/project.properties @@ -16,7 +16,7 @@ # under the License. is.autoload=true javac.compilerargs=-Xlint -Xlint:-serial -javac.release=17 +javac.release=21 javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml nbm.homepage=http://wiki.netbeans.org/TerminalEmulator diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/AbstractInterp.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/AbstractInterp.java index bd6c9c92fc5e..d37f0d04e5f9 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/AbstractInterp.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/AbstractInterp.java @@ -20,6 +20,8 @@ package org.netbeans.lib.terminalemulator; import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.List; public abstract class AbstractInterp implements Interp { @@ -30,22 +32,17 @@ protected interface Actor { protected static class State { // some generic actors - Actor act_error = new Actor() { - @Override - public String action(AbstractInterp ai, char c) { - return "generic error"; // NOI18N - } - }; + private static Actor ACT_ERROR = (AbstractInterp ai, char c) -> "generic error"; // NOI18N public String name() { return name; - } + } private final String name; - class Action { + static class Action { public State new_state = null; - public Actor actor = act_error; + public Actor actor = ACT_ERROR; }; private final Action action[] = new Action[128]; @@ -65,7 +62,7 @@ public State(String name) { public void setRegular(State new_state, Actor actor) { action_regular.actor = actor; action_regular.new_state = new_state; - } + } public void setAction(char c, State new_state, Actor actor) { if ((int) c > 127) @@ -78,12 +75,12 @@ Action getAction(char c) { if ((int) c > 127) return action_regular; return action[c]; - } + } }; // Why make these be public and not protected? // Someone might inherit from us in a package other than org.netbeans - // and while the inherited Interp will see these if they are protected, + // and while the inherited Interp will see these if they are protected, // the corresponding InterpType won't. /* @@ -98,10 +95,10 @@ Action getAction(char c) { protected AbstractInterp(Ops ops) { this.ops = ops; - } + } public void reset() { - } + } protected final void sendChars(KeyEvent e, String s) { e.consume(); @@ -117,9 +114,7 @@ protected final void sendChars(KeyEvent e, String s) { private final String number[] = new String[MAX_NUMBERS]; protected void resetNumber() { - for (int x = 0; x < MAX_NUMBERS; x++) { - number[x] = ""; - } + Arrays.setAll(number, i -> ""); numberx = 0; } protected void remember_digit(char c) { @@ -146,4 +141,20 @@ protected int numberAt(int position) { protected int nNumbers() { return numberx; } -} + protected List numbers() { + int lastIndexToConsider = numberx; + if (!number[numberx].isEmpty()) { + lastIndexToConsider++; + } + return Arrays + .stream(number, 0, numberx + 1) + .map(s -> { + try { + return Integer.valueOf(s); + } catch (NumberFormatException x) { + return 0; + } + }) + .toList(); + } +} diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveRegion.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveRegion.java index ba2536605146..fb292b4a1a9d 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveRegion.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveRegion.java @@ -31,11 +31,11 @@ public class ActiveRegion { public Coord end = new Coord(); // accessible to RegionManager - ActiveRegion parent; - boolean nested; + private final ActiveRegion parent; + private final boolean nested; private LinkedList children; private boolean has_end; - private int parentAttrs; // attrs at the time this region began + private Attr parentAttrs; // attrs at the time this region began ActiveRegion(ActiveRegion parent, Coord begin, boolean nested) { this.parent = parent; @@ -43,11 +43,11 @@ public class ActiveRegion { this.nested = nested; } - void setParentAttrs(int attrs) { + void setParentAttrs(Attr attrs) { this.parentAttrs = attrs; } - int getParentAttrs() { + Attr getParentAttrs() { return parentAttrs; } @@ -55,6 +55,10 @@ public ActiveRegion parent() { return this.parent; } + boolean isNested() { + return nested; + } + public Extent getExtent() { if (has_end) { return new Extent(begin, end); @@ -148,6 +152,8 @@ void cull(int origin) { * Mark this region as one that may be converted to a selection. *

* This is just a convenience state-keeping flag + * + * @param selectable */ public void setSelectable(boolean selectable) { this.selectable = selectable; @@ -155,6 +161,8 @@ public void setSelectable(boolean selectable) { /** * Return the value set using setSelectable(). + * + * @return */ public boolean isSelectable() { return selectable; @@ -166,6 +174,8 @@ public boolean isSelectable() { * over it. *

* This is just a convenience state-keeping flag + * + * @param feedback */ public void setFeedbackEnabled(boolean feedback) { this.feedback_enabled = feedback; @@ -173,6 +183,8 @@ public void setFeedbackEnabled(boolean feedback) { /** * Return the value set using setFeedback(). + * + * @return */ public boolean isFeedbackEnabled() { return feedback_enabled; @@ -182,6 +194,8 @@ public boolean isFeedbackEnabled() { /** * Mark this region as one that will provide feedback in it's containing * region. + * + * @param feedback_via_parent */ public void setFeedbackViaParent(boolean feedback_via_parent) { this.feedback_via_parent = feedback_via_parent; @@ -206,14 +220,18 @@ public boolean isLink() { /** * Associate additional data with this ActiveRegion. + * + * @param object */ public void setUserObject(Object object) { this.user_object = object; } /** - * Retrieve the additional data associated with this ActiveRegion through + * Retrieve the additional data associated with this ActiveRegion through * setUserObject. + * + * @return */ public Object getUserObject() { return user_object; @@ -222,15 +240,15 @@ public Object getUserObject() { // siblings // - // I've chosen to delegate finding of siblings to the parent instead of + // I've chosen to delegate finding of siblings to the parent instead of // using explicit sibling links. Here are the reasons: - // - explicit links take up memory. I believe in the long run that is + // - explicit links take up memory. I believe in the long run that is // more costly than dumb searches. // - AR's get created when stuff gets rendered. We want to render stuff // as fast as possible. So instead of doing work at creation time // which needs to be supra-human speed, we do the work at query time // which is usualy in reponse to human actions and need not be too fast. - // + // // Ultimately a Vector is probably a better substitute for LinkedList // In that case each child could remember it's index in it's parents // vector (less storage than two pointers, and vector has less overhead @@ -238,6 +256,7 @@ public Object getUserObject() { // because ActiveRegions are not editable. /** * Return the first child of this + * @return */ public ActiveRegion firstChild() { if (children == null) { @@ -248,6 +267,8 @@ public ActiveRegion firstChild() { /** * Return the last child of this + * + * @return */ public ActiveRegion lastChild() { if (children == null) { @@ -258,6 +279,8 @@ public ActiveRegion lastChild() { /** * Get the previous sibling of this region + * + * @return */ public ActiveRegion getPreviousSibling() { if (parent != null) { diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveTerm.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveTerm.java index 7875640ba553..aea480f5a1f3 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveTerm.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/ActiveTerm.java @@ -27,6 +27,7 @@ import java.awt.*; import java.awt.event.*; +import java.util.List; public class ActiveTerm extends StreamTerm { @@ -46,6 +47,7 @@ public class ActiveTerm extends StreamTerm { /** Remember what cursor is currently active */ private Cursor currentCursor; + @SuppressWarnings("this-escape") public ActiveTerm() { super(); @@ -87,11 +89,11 @@ public void mouseMoved(MouseEvent e) { ActiveRegion hl_region = findRegionToHilite(region); if (hl_region == null) hilite(null, null); - else + else hilite(hl_region.begin, hl_region.end); } } ); - } + } private void setCursorEfficiently(Cursor cursor) { if (cursor == currentCursor) @@ -113,7 +115,7 @@ else if (region.isFeedbackViaParent()) public void setActionListener(ActiveTermListener listener) { this.at_listener = listener; - } + } private void hilite_help(Coord begin, Coord end, boolean on) { if (begin == null && end == null) @@ -122,17 +124,19 @@ private void hilite_help(Coord begin, Coord end, boolean on) { } public void hilite(Coord begin, Coord end) { - if (end != null && end.row == 1 && end.col == 0) - end = getCursorCoord(); + Coord last_end_work = end; + if (last_end_work != null && last_end_work.row == 1 && last_end_work.col == 0) { + last_end_work = getCursorCoord(); + } hilite_help(last_begin, last_end, false); last_begin = (begin == null)? null: (Coord) begin.clone(); - last_end = (end == null)? null: (Coord) end.clone(); - hilite_help(begin, end, true); + last_end = (last_end_work == null) ? null : (Coord) last_end_work.clone(); + hilite_help(begin, last_end_work, true); } public void hilite(ActiveRegion region) { hilite(region.begin, region.end); - } + } public ActiveRegion beginRegion(boolean hyperlink) { ActiveRegion region; @@ -140,11 +144,11 @@ public ActiveRegion beginRegion(boolean hyperlink) { region = rm.beginRegion(getCursorCoord()); } catch (RegionException x) { return new ActiveRegion(null, new Coord(), false); - } + } region.setParentAttrs(attrSave()); if (hyperlink) { - setAttribute(34); // fg -> blue - setAttribute(4); // underline + setAttribute(List.of(34)); // fg -> blue + setAttribute(List.of(4)); // underline } return region; } @@ -167,7 +171,7 @@ public void endRegion() { } // OLD setAttribute(0); // reset attrRestore(endedRegion.getParentAttrs()); - } + } public ActiveRegion findRegion(Coord coord) { return rm.findRegion(coord); @@ -179,9 +183,9 @@ public void cancelRegion() { rm.cancelRegion(); } catch (RegionException x) { ; - } + } } - + @Override public void clear() { nullLasts(); @@ -209,9 +213,9 @@ protected void hyperlink(String url, String text) { ops().op_char(c); endRegion(); } - + private void nullLasts() { last_begin = null; - last_end = null; + last_end = null; } } diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Attr.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Attr.java index d4c26ea5ff68..8ba5c40d8a01 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Attr.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Attr.java @@ -24,26 +24,13 @@ package org.netbeans.lib.terminalemulator; -@SuppressWarnings("AccessingNonPublicFieldOfAnotherObject") -enum Attr { - BGCOLOR(9), // encodes 0 or palette index+1 (was: 5) - FGCOLOR(9), // encodes 0 or palette index+1 (was: 5) - HIDDEN(1), - REVERSE(1), - BLINK(1), - UNDERSCORE(1), - BRIGHT(1), - DIM(1), - ACTIVE(1), - - // Since an attr value of 0 means render using default attributes - // We need a value that signifies that no attribute has been set. - // Can't use the highest (sign) bit since Java has no unsigned and - // we get complaints from the compiler. - UNSET(30, 1); - - public static final int ALT; +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +@SuppressWarnings("AccessingNonPublicFieldOfAnotherObject") +class Attr { // // Bases of various color ranges. // These are indexes into Term.palette @@ -70,536 +57,598 @@ enum Attr { public static final int PAL_SIZE = 259; - private final int width; // ... of field - private final int fmask; // ... corresponding to width + private final Color fgColor; - private int offset; // ... of field from the "left" - private int wmask; // ... over the word. 1 where bits are set. + private final Color bgColor; - static { - // System.out.printf("Attr.static()\n"); - for (Attr a : values()) - a.init(); - ALT = Attr.BGCOLOR.wmask | Attr.FGCOLOR.wmask | Attr.REVERSE.wmask | Attr.ACTIVE.wmask; - } + private final int attributes; - /* - * Explicitly set the offset. - */ - private Attr(int offset, int width) { - // System.out.printf("Attr(%d, %d) -> %d\n", offset, width, ordinal()); - this.offset = offset; - this.width = width; - this.fmask = (1< %d\n", width, ordinal()); - this.offset = -1; - this.width = width; - this.fmask = (1<> offset) & fmask; + public boolean isBlink() { + return AttrEncoding.BLINK.isSet(this.attributes); } - /* - * Use for setting a wide field. - * Works for 1-bit field but set(int) is more efficient. - */ - public final int set(int attr, int value) { - // value &= fmask; // throw all but lowest relevant bits away - // attr &= ~ wmask; // 0 out existing bits - // attr |= value << offset;// set new value + public boolean isUnderscore() { + return AttrEncoding.UNDERSCORE.isSet(this.attributes); + } - return (attr & ~wmask) | ((value & fmask) << offset); + public boolean isBright() { + return AttrEncoding.BRIGHT.isSet(this.attributes); } - /* - * Use for setting a 1 bit field - */ - public final int set(int attr) { - assert width == 1; - return attr | (1 << offset); + public boolean isDim() { + return AttrEncoding.DIM.isSet(this.attributes); } - /* - * Use for clearing any width field. - */ - public final int clear(int attr) { - return attr & ~wmask; + public boolean isActive() { + return AttrEncoding.ACTIVE.isSet(this.attributes); } - public final boolean isSet(int attr) { - return (attr & wmask) != 0; + public boolean isBGcolor() { + return bgColor != null || AttrEncoding.BGCOLOR.isSet(this.attributes); + } + + public boolean isFGcolor() { + return fgColor != null || AttrEncoding.FGCOLOR.isSet(this.attributes); } /** * Use this to get at the FG palette index embedded in an attr. */ - public static int foregroundColor(int attr) { - final int cx = FGCOLOR.get(attr); - if (cx == 0) - return PAL_FG; - else - return cx-1; - } + public Color getFGcolor(Color[] palette) { + if (fgColor != null) { + return fgColor; + } + final int cx = AttrEncoding.FGCOLOR.get(this.attributes); + if (cx == 0) { + return palette[PAL_FG]; + } else { + return palette[cx - 1]; + } + } /** * Use this to get at the BG palette index embedded in an attr. */ - public static int backgroundColor(int attr) { - final int cx = BGCOLOR.get(attr); - if (cx == 0) - return PAL_BG; - else - return cx-1; + public Color getBGColor(Color[] palette) { + if (bgColor != null) { + return bgColor; + } + final int cx = AttrEncoding.BGCOLOR.get(this.attributes); + if (cx == 0) { + return palette[PAL_BG]; + } else { + return palette[cx - 1]; + } } - /* - * Read-modify-write utility for setting bitfields in 'attr'. - */ - @SuppressWarnings("AssignmentToMethodParameter") - public static int setAttribute(int attr, int value) { - switch (value) { - case 0: - // Reset all attributes - attr = 0; - break; - case 5: // slow blink - case 6: // fast blink - // Attr.BLINK - // FALLTHRU - case 1: - attr = DIM.clear(attr); - attr = BRIGHT.set(attr); - break; - case 2: - // Faint - not implemented - attr = BRIGHT.clear(attr); - attr = DIM.set(attr); - break; - case 3: - // Italic - not supported - break; - case 4: - attr = UNDERSCORE.set(attr); - break; - case 7: - attr = REVERSE.set(attr); - break; - case 8: - attr = HIDDEN.set(attr); - break; - - case 9: - // Term specific - attr = ACTIVE.set(attr); - break; - - // turn individual attributes off (dtterm specific?) - case 25: - // blinking off - // FALLTHRU - case 22: - attr = DIM.clear(attr); - attr = BRIGHT.clear(attr); - break; - case 24: - attr = UNDERSCORE.clear(attr); - break; - case 27: - attr = REVERSE.clear(attr); - break; - case 28: - attr = HIDDEN.clear(attr); - break; - - // default color - case 39: - attr = FGCOLOR.clear(attr); - break; - case 49: - attr = BGCOLOR.clear(attr); - break; - - - // ANSI fg - case 30: - case 31: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - - // ANSI bg - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - - // custom fg - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: - - // custom bg (was: 60-67) - case 58: - case 59: - case 60: - case 61: - case 62: - case 63: - case 64: - case 65: - - // bright fg - case 90: - case 91: - case 92: - case 93: - case 94: - case 95: - case 96: - case 97: - - // bright bg - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - case 106: - case 107: - try { - Info i = map[value]; - if (i != null) - attr = i.field.set(attr, i.pindex+1); - } catch (ArrayStoreException x) { - // silently ignore unrecognized attribute - break; - } - break; - - default: - // silently ignore unrecognized attribute - break; - } - return attr; + public Attr setAttribute(List parameterList) { + int attributesUpdated = this.attributes; + Color fgColorUpdated = this.fgColor; + Color bgColorUpdated = this.bgColor; + + // Loop over the parameter list as multiple operations can be combined + // into a single call + List workList = new ArrayList<>(parameterList); + if (workList.isEmpty()) { + workList.add(0); // No parameter implies reset + } + while (!workList.isEmpty()) { + Integer value = workList.removeFirst(); + switch (value) { + case 0 -> { + // Reset all attributes + attributesUpdated = 0; + fgColorUpdated = null; + bgColorUpdated = null; + } + case 1, 5, 6 -> { // bold/bright // slow blink // fast blink (blink is not supported) + attributesUpdated = AttrEncoding.DIM.clear(attributesUpdated); + attributesUpdated = AttrEncoding.BRIGHT.set(attributesUpdated); + } + case 2 -> { + // Faint - not implemented + attributesUpdated = AttrEncoding.BRIGHT.clear(attributesUpdated); + attributesUpdated = AttrEncoding.DIM.set(attributesUpdated); + } + case 3 -> { + // Italic - not supported + } + case 4 -> { + attributesUpdated = AttrEncoding.UNDERSCORE.set(attributesUpdated); + } + case 7 -> { + attributesUpdated = AttrEncoding.REVERSE.set(attributesUpdated); + } + case 8 -> { + attributesUpdated = AttrEncoding.HIDDEN.set(attributesUpdated); + } + case 9 -> { + // Term specific + attributesUpdated = AttrEncoding.ACTIVE.set(attributesUpdated); + } + case 22, 25 -> { // reset bold/dim // reset blink (not supported) + attributesUpdated = AttrEncoding.DIM.clear(attributesUpdated); + attributesUpdated = AttrEncoding.BRIGHT.clear(attributesUpdated); + } + case 24 -> { + attributesUpdated = AttrEncoding.UNDERSCORE.clear(attributesUpdated); + } + case 27 -> { + attributesUpdated = AttrEncoding.REVERSE.clear(attributesUpdated); + } + case 28 -> { + attributesUpdated = AttrEncoding.HIDDEN.clear(attributesUpdated); + } + case 39 -> { // default color + attributesUpdated = AttrEncoding.FGCOLOR.clear(attributesUpdated); + fgColorUpdated = null; + } + case 49 -> { // default color + attributesUpdated = AttrEncoding.BGCOLOR.clear(attributesUpdated); + bgColorUpdated = null; + } + case 30, 31, 32, 33, 34, 35, 36, 37, // ANSI fg + 40, 41, 42, 43, 44, 45, 46, 47, // ANSI bg + 50, 51, 52, 53, 54, 55, 56, 57, // custom fg + 58, 59, 60, 61, 62, 63, 64, 65, // custom bg (was: 60-67) + 90, 91, 92, 93, 94, 95, 96, 97, // bright fg + 100, 101, 102, 103, 104, 105, 106, 107 -> { // bright bg + try { + Info i = map[value]; + if (i != null) { + attributesUpdated = i.field.set(attributesUpdated, i.pindex + 1); + // If color is switched to a predefined value, clear + // clear the corresponding truecolor value + if (i.field == AttrEncoding.FGCOLOR) { + fgColorUpdated = null; + } else if (i.field == AttrEncoding.BGCOLOR) { + bgColorUpdated = null; + } + } + } catch (ArrayStoreException x) { + // silently ignore unrecognized attribute + break; + } + } + case 38, 48 -> { // Extended set color foreground / background + if (workList.size() > 1) { + boolean background = value == 48; + value = workList.removeFirst(); + if (value == 5) { // Color format indexed into 256 color palette + value = workList.removeFirst(); + attributesUpdated = + (background ? AttrEncoding.BGCOLOR : AttrEncoding.FGCOLOR) + .set(attributesUpdated, value + 1); + } else if (value == 2) { // Color format RGB values + int r = workList.removeFirst(); + int g = workList.removeFirst(); + int b = workList.removeFirst(); + if (background) { + bgColorUpdated = new Color(r, g, b); + } else { + fgColorUpdated = new Color(r, g, b); + } + } + } + } + default -> { + // silently ignore unrecognized attribute + } + } + } + return new Attr(attributesUpdated, fgColorUpdated, bgColorUpdated); } - /* - * Read-modify-write utility for unsetting bitfields in 'attr'. - * Note: this doesn't cover the unsetting operations which - * setAttributes does. - */ - @SuppressWarnings("AssignmentToMethodParameter") - public static int unsetAttribute(int attr, int value) { - switch (value) { - case 0: - // Reset all attributes - attr = 0; - break; - case 5: - // Attr.BLINK - // FALLTHRU - case 1: - attr = BRIGHT.clear(attr); - break; - case 2: - attr = DIM.clear(attr); - break; - case 4: - attr = UNDERSCORE.clear(attr); - break; - case 7: - attr = REVERSE.clear(attr); - break; - case 8: - attr = HIDDEN.clear(attr); - break; - case 9: - attr = ACTIVE.clear(attr); - break; - - // ANSI fg - case 30: - case 31: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - - // ANSI bg - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - - // custom colors dtterm fg - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: - - // custom colors dtterm bg - case 58: - case 59: - case 60: - case 61: - case 62: - case 63: - case 64: - case 65: - - // bright fg - case 90: - case 91: - case 92: - case 93: - case 94: - case 95: - case 96: - case 97: - - // bright bg - case 100: - case 101: - case 102: - case 103: - case 104: - case 105: - case 106: - case 107: - try { - Info i = map[value]; - if (i != null) - attr = i.field.clear(attr); - } catch (ArrayStoreException x) { - // silently ignore unrecognized attribute - break; - } - break; - default: - // silently ignore unrecognized attribute - break; - } - return attr; + public Attr unsetAttribute(int value) { + int attrUpdated = attributes; + Color fgColorUpdated = this.fgColor; + Color bgColorUpdated = this.bgColor; + switch (value) { + case 0 -> { + // Reset all attributes + attrUpdated = 0; + fgColorUpdated = null; + bgColorUpdated = null; + } + case 1, 5, 6 -> { // bold/bright // slow blink // fast blink (blink is not supported) + attrUpdated = AttrEncoding.BRIGHT.clear(attrUpdated); + } + case 2 -> { + attrUpdated = AttrEncoding.DIM.clear(attrUpdated); + } + case 4 -> { + attrUpdated = AttrEncoding.UNDERSCORE.clear(attrUpdated); + } + case 7 -> { + attrUpdated = AttrEncoding.REVERSE.clear(attrUpdated); + } + case 8 -> { + attrUpdated = AttrEncoding.HIDDEN.clear(attrUpdated); + } + case 9 -> { + attrUpdated = AttrEncoding.ACTIVE.clear(attrUpdated); + } + case 30, 31, 32, 33, 34, 35, 36, 37, // ANSI fg + 40, 41, 42, 43, 44, 45, 46, 47, // ANSI bg + 50, 51, 52, 53, 54, 55, 56, 57, // custom fg + 58, 59, 60, 61, 62, 63, 64, 65, // custom bg (was: 60-67) + 90, 91, 92, 93, 94, 95, 96, 97, // bright fg + 100, 101, 102, 103, 104, 105, 106, 107 -> { // bright bg + try { + Info i = map[value]; + if (i != null) { + attrUpdated = i.field.clear(attrUpdated); + if (i.field == AttrEncoding.BGCOLOR) { + fgColorUpdated = null; + } else if (i.field == AttrEncoding.BGCOLOR) { + bgColorUpdated = null; + } + } + } catch (ArrayStoreException x) { + // silently ignore unrecognized attribute + break; + } + } + default -> { + // silently ignore unrecognized attribute + } + } + return new Attr(attrUpdated, fgColorUpdated, bgColorUpdated); + } + + public Attr altVariant() { + return new Attr(this.attributes & ~ AttrEncoding.ALT, null, null); + } + + public Attr bgColorVariant() { + return new Attr(AttrEncoding.BGCOLOR.get(this.attributes), null, this.bgColor); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 53 * hash + Objects.hashCode(this.fgColor); + hash = 53 * hash + Objects.hashCode(this.bgColor); + hash = 53 * hash + this.attributes; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Attr other = (Attr) obj; + if (this.attributes != other.attributes) { + return false; + } + if (!Objects.equals(this.fgColor, other.fgColor)) { + return false; + } + return Objects.equals(this.bgColor, other.bgColor); + } + + + + @Override + public String toString() { + return "Attr {" + + "isActive=" + isActive() + ", " + + "isBGcolor=" + isBGcolor()+ ", " + + "isBlink=" + isBlink() + ", " + + "isDim=" + isDim() + ", " + + "isEmpty=" + isEmpty() + ", " + + "isFGcolor=" + isFGcolor() + ", " + + "isHidden=" + isHidden() + ", " + + "isReverse=" + isReverse() + ", " + + "isUnderscore=" + isUnderscore() + ", " + + "fgColor=" + fgColor + ", " + + "bgColor=" + bgColor + + "}"; + } + + private enum AttrEncoding { + BGCOLOR(9), // encodes 0 or palette index+1 (was: 5), offset 0 + FGCOLOR(9), // encodes 0 or palette index+1 (was: 5), offset 9 + HIDDEN(1), // offset 10 + REVERSE(1), // offset 11 + BLINK(1), // offset 12 + UNDERSCORE(1), // offset 13 + BRIGHT(1), // offset 14 + DIM(1), // offset 15 + ACTIVE(1), // offset 16 + + // Since an attr value of 0 means render using default attributes + // We need a value that signifies that no attribute has been set. + // Can't use the highest (sign) bit since Java has no unsigned and + // we get complaints from the compiler. + UNSET(30, 1); + + public static final int ALT; + + private final int width; // ... of field + private final int fmask; // ... corresponding to width + + private int offset; // ... of field from the "left" + private int wmask; // ... over the word. 1 where bits are set. + + static { + // System.out.printf("Attr.static()\n"); + for (AttrEncoding a : values()) + a.init(); + ALT = AttrEncoding.BGCOLOR.wmask | AttrEncoding.FGCOLOR.wmask | AttrEncoding.REVERSE.wmask | AttrEncoding.ACTIVE.wmask; + } + + /* + * Explicitly set the offset. + */ + private AttrEncoding(int offset, int width) { + // System.out.printf("Attr(%d, %d) -> %d\n", offset, width, ordinal()); + this.offset = offset; + this.width = width; + this.fmask = (1< %d\n", width, ordinal()); + this.offset = -1; + this.width = width; + this.fmask = (1<> offset) & fmask; + } + + /* + * Use for setting a wide field. + * Works for 1-bit field but set(int) is more efficient. + */ + public final int set(int attr, int value) { + // value &= fmask; // throw all but lowest relevant bits away + // attr &= ~ wmask; // 0 out existing bits + // attr |= value << offset;// set new value + + return (attr & ~wmask) | ((value & fmask) << offset); + } + + /* + * Use for setting a 1 bit field + */ + public final int set(int attr) { + assert width == 1; + return attr | (1 << offset); + } + + /* + * Use for clearing any width field. + */ + public final int clear(int attr) { + return attr & ~wmask; + } + + + public final boolean isSet(int attr) { + return (attr & wmask) != 0; + } + } public static final int rendition_to_pindex(int rendition) { - try { - Info i = map[rendition]; - if (i == null) - return -1; - else - return i.pindex; - } catch (ArrayIndexOutOfBoundsException x) { - return -1; - } + try { + Info i = map[rendition]; + if (i == null) { + return -1; + } else { + return i.pindex; + } + } catch (ArrayIndexOutOfBoundsException x) { + return -1; + } } private static final class Info { - public final int rendition; // map[r].rendition == r - public final Attr field; // ... to set - public final int pindex; // palette index - - Info(int rendition, Attr field, int pindex) { - this.rendition = rendition; - this.field = field; - this.pindex = pindex; - } + + public final int rendition; // map[r].rendition == r + public final AttrEncoding field; // ... to set + public final int pindex; // palette index + + Info(int rendition, AttrEncoding field, int pindex) { + this.rendition = rendition; + this.field = field; + this.pindex = pindex; + } } // Map a rendition to info needed for settig it's value private static final Info map[]; static { - map = new Info[] { - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, // 9 - - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, // 19 - - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, // 29 - - // ANSI fg - new Info(30, FGCOLOR, PAL_ANSI+0), - new Info(31, FGCOLOR, PAL_ANSI+1), - new Info(32, FGCOLOR, PAL_ANSI+2), - new Info(33, FGCOLOR, PAL_ANSI+3), - new Info(34, FGCOLOR, PAL_ANSI+4), - new Info(35, FGCOLOR, PAL_ANSI+5), - new Info(36, FGCOLOR, PAL_ANSI+6), - new Info(37, FGCOLOR, PAL_ANSI+7), - null, // 38 - new Info(39, FGCOLOR, PAL_FG), - - // ANSI bg - new Info(40, BGCOLOR, PAL_ANSI+0), - new Info(41, BGCOLOR, PAL_ANSI+1), - new Info(42, BGCOLOR, PAL_ANSI+2), - new Info(43, BGCOLOR, PAL_ANSI+3), - new Info(44, BGCOLOR, PAL_ANSI+4), - new Info(45, BGCOLOR, PAL_ANSI+5), - new Info(46, BGCOLOR, PAL_ANSI+6), - new Info(47, BGCOLOR, PAL_ANSI+7), - null, // 48 - new Info(49, BGCOLOR, PAL_BG), - - // dtterm/custom fg - new Info(50, FGCOLOR, PAL_BRIGHT+0), - new Info(51, FGCOLOR, PAL_BRIGHT+1), - new Info(52, FGCOLOR, PAL_BRIGHT+2), - new Info(53, FGCOLOR, PAL_BRIGHT+3), - new Info(54, FGCOLOR, PAL_BRIGHT+4), - new Info(55, FGCOLOR, PAL_BRIGHT+5), - new Info(56, FGCOLOR, PAL_BRIGHT+6), - new Info(57, FGCOLOR, PAL_BRIGHT+7), - - // dtterm/custom bg - new Info(58, BGCOLOR, PAL_BRIGHT+0), - new Info(59, BGCOLOR, PAL_BRIGHT+1), - new Info(60, BGCOLOR, PAL_BRIGHT+2), - new Info(61, BGCOLOR, PAL_BRIGHT+3), - new Info(62, BGCOLOR, PAL_BRIGHT+4), - new Info(63, BGCOLOR, PAL_BRIGHT+5), - new Info(64, BGCOLOR, PAL_BRIGHT+6), - new Info(65, BGCOLOR, PAL_BRIGHT+7), - - null, // 66 - null, - null, - null, // 69 - - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, // 79 - - null, - null, - null, - null, - null, - null, - null, - null, - null, - null, // 89 - - // BRIGHT fg - new Info(90, FGCOLOR, PAL_BRIGHT+0), - new Info(91, FGCOLOR, PAL_BRIGHT+1), - new Info(92, FGCOLOR, PAL_BRIGHT+2), - new Info(93, FGCOLOR, PAL_BRIGHT+3), - new Info(94, FGCOLOR, PAL_BRIGHT+4), - new Info(95, FGCOLOR, PAL_BRIGHT+5), - new Info(96, FGCOLOR, PAL_BRIGHT+6), - new Info(97, FGCOLOR, PAL_BRIGHT+7), - null, // 98 - null, // 99 - - // BRIGHT bg - new Info(100, BGCOLOR, PAL_BRIGHT+0), - new Info(101, BGCOLOR, PAL_BRIGHT+1), - new Info(102, BGCOLOR, PAL_BRIGHT+2), - new Info(103, BGCOLOR, PAL_BRIGHT+3), - new Info(104, BGCOLOR, PAL_BRIGHT+4), - new Info(105, BGCOLOR, PAL_BRIGHT+5), - new Info(106, BGCOLOR, PAL_BRIGHT+6), - new Info(107, BGCOLOR, PAL_BRIGHT+7), - }; - - for (int mx = 0; mx < map.length; mx++) { - assert map[mx] == null || - map[mx].rendition == mx; - } + map = new Info[]{ + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, // 9 + + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, // 19 + + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, // 29 + + // ANSI fg + new Info(30, AttrEncoding.FGCOLOR, PAL_ANSI + 0), + new Info(31, AttrEncoding.FGCOLOR, PAL_ANSI + 1), + new Info(32, AttrEncoding.FGCOLOR, PAL_ANSI + 2), + new Info(33, AttrEncoding.FGCOLOR, PAL_ANSI + 3), + new Info(34, AttrEncoding.FGCOLOR, PAL_ANSI + 4), + new Info(35, AttrEncoding.FGCOLOR, PAL_ANSI + 5), + new Info(36, AttrEncoding.FGCOLOR, PAL_ANSI + 6), + new Info(37, AttrEncoding.FGCOLOR, PAL_ANSI + 7), + null, // 38 + new Info(39, AttrEncoding.FGCOLOR, PAL_FG), + // ANSI bg + new Info(40, AttrEncoding.BGCOLOR, PAL_ANSI + 0), + new Info(41, AttrEncoding.BGCOLOR, PAL_ANSI + 1), + new Info(42, AttrEncoding.BGCOLOR, PAL_ANSI + 2), + new Info(43, AttrEncoding.BGCOLOR, PAL_ANSI + 3), + new Info(44, AttrEncoding.BGCOLOR, PAL_ANSI + 4), + new Info(45, AttrEncoding.BGCOLOR, PAL_ANSI + 5), + new Info(46, AttrEncoding.BGCOLOR, PAL_ANSI + 6), + new Info(47, AttrEncoding.BGCOLOR, PAL_ANSI + 7), + null, // 48 + new Info(49, AttrEncoding.BGCOLOR, PAL_BG), + // dtterm/custom fg + new Info(50, AttrEncoding.FGCOLOR, PAL_BRIGHT + 0), + new Info(51, AttrEncoding.FGCOLOR, PAL_BRIGHT + 1), + new Info(52, AttrEncoding.FGCOLOR, PAL_BRIGHT + 2), + new Info(53, AttrEncoding.FGCOLOR, PAL_BRIGHT + 3), + new Info(54, AttrEncoding.FGCOLOR, PAL_BRIGHT + 4), + new Info(55, AttrEncoding.FGCOLOR, PAL_BRIGHT + 5), + new Info(56, AttrEncoding.FGCOLOR, PAL_BRIGHT + 6), + new Info(57, AttrEncoding.FGCOLOR, PAL_BRIGHT + 7), + // dtterm/custom bg + new Info(58, AttrEncoding.BGCOLOR, PAL_BRIGHT + 0), + new Info(59, AttrEncoding.BGCOLOR, PAL_BRIGHT + 1), + new Info(60, AttrEncoding.BGCOLOR, PAL_BRIGHT + 2), + new Info(61, AttrEncoding.BGCOLOR, PAL_BRIGHT + 3), + new Info(62, AttrEncoding.BGCOLOR, PAL_BRIGHT + 4), + new Info(63, AttrEncoding.BGCOLOR, PAL_BRIGHT + 5), + new Info(64, AttrEncoding.BGCOLOR, PAL_BRIGHT + 6), + new Info(65, AttrEncoding.BGCOLOR, PAL_BRIGHT + 7), + null, // 66 + null, + null, + null, // 69 + + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, // 79 + + null, + null, + null, + null, + null, + null, + null, + null, + null, + null, // 89 + + // BRIGHT fg + new Info(90, AttrEncoding.FGCOLOR, PAL_BRIGHT + 0), + new Info(91, AttrEncoding.FGCOLOR, PAL_BRIGHT + 1), + new Info(92, AttrEncoding.FGCOLOR, PAL_BRIGHT + 2), + new Info(93, AttrEncoding.FGCOLOR, PAL_BRIGHT + 3), + new Info(94, AttrEncoding.FGCOLOR, PAL_BRIGHT + 4), + new Info(95, AttrEncoding.FGCOLOR, PAL_BRIGHT + 5), + new Info(96, AttrEncoding.FGCOLOR, PAL_BRIGHT + 6), + new Info(97, AttrEncoding.FGCOLOR, PAL_BRIGHT + 7), + null, // 98 + null, // 99 + + // BRIGHT bg + new Info(100, AttrEncoding.BGCOLOR, PAL_BRIGHT + 0), + new Info(101, AttrEncoding.BGCOLOR, PAL_BRIGHT + 1), + new Info(102, AttrEncoding.BGCOLOR, PAL_BRIGHT + 2), + new Info(103, AttrEncoding.BGCOLOR, PAL_BRIGHT + 3), + new Info(104, AttrEncoding.BGCOLOR, PAL_BRIGHT + 4), + new Info(105, AttrEncoding.BGCOLOR, PAL_BRIGHT + 5), + new Info(106, AttrEncoding.BGCOLOR, PAL_BRIGHT + 6), + new Info(107, AttrEncoding.BGCOLOR, PAL_BRIGHT + 7),}; + + for (int mx = 0; mx < map.length; mx++) { + assert map[mx] == null + || map[mx].rendition == mx; + } } -} \ No newline at end of file +} diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/AttrSave.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/AttrSave.java deleted file mode 100644 index a3f9c2a0d476..000000000000 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/AttrSave.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* - * "Attr.java" - * Attr.java 1.7 01/07/23 - */ - -package org.netbeans.lib.terminalemulator; - -class AttrSave { - private static final int BGCOLOR_OFF = 0; - private static final int BGCOLOR_WIDTH = 5; - private static final int BGCOLOR_MASK = 0xf; - @SuppressWarnings("PointlessBitwiseExpression") - public static final int BGCOLOR = BGCOLOR_MASK << BGCOLOR_OFF; - - private static final int FGCOLOR_OFF = BGCOLOR_OFF + BGCOLOR_WIDTH; - private static final int FGCOLOR_WIDTH = 5; - private static final int FGCOLOR_MASK = 0xf; - public static final int FGCOLOR = FGCOLOR_MASK << FGCOLOR_OFF; - - private static final int HIDDEN_OFF = FGCOLOR_OFF + FGCOLOR_WIDTH; - private static final int HIDDEN_WIDTH = 1; - public static final int HIDDEN = 0x1 << HIDDEN_OFF; - - private static final int REVERSE_OFF = HIDDEN_OFF + HIDDEN_WIDTH; - private static final int REVERSE_WIDTH = 1; - public static final int REVERSE = 0x1 << REVERSE_OFF; - - private static final int BLINK_OFF = REVERSE_OFF + REVERSE_WIDTH; - private static final int BLINK_WIDTH = 1; - public static final int BLINK = 0x1 << BLINK_OFF; - - private static final int UNDERSCORE_OFF = BLINK_OFF + BLINK_WIDTH; - private static final int UNDERSCORE_WIDTH = 1; - public static final int UNDERSCORE = 0x1 << UNDERSCORE_OFF; - - private static final int BRIGHT_OFF = UNDERSCORE_OFF + UNDERSCORE_WIDTH; - private static final int BRIGHT_WIDTH = 1; - public static final int BRIGHT = 0x1 << BRIGHT_OFF; - - private static final int DIM_OFF = BRIGHT_OFF + BRIGHT_WIDTH; - private static final int DIM_WIDTH = 1; - public static final int DIM = 0x1 << DIM_OFF; - - private static final int ACTIVE_OFF = DIM_OFF + DIM_WIDTH; - private static final int ACTIVE_WIDTH = 1; - public static final int ACTIVE = 0x1 << ACTIVE_OFF; - - // Since an attr value of 0 means render using default attributes - // We need a value that signifies that no attribute has been set. - // Can't use the highest (sign) bit since Java has no unsigned and - // we get complaints from the compiler. - public static final int UNSET = 0x40000000; - - - - /** - * attr = Attr.setBackgroundColor(attr, 7); - */ - - @SuppressWarnings({"PointlessBitwiseExpression", "AssignmentToMethodParameter"}) - public static int setBackgroundColor(int attr, int code) { - code &= BGCOLOR_MASK; // throw all but lowest relevant bits away - attr &= ~ BGCOLOR; // 0 out existing bits - attr |= code << BGCOLOR_OFF; - return attr; - } - - - /** - * attr = Attr.setForegroundColor(attr, 7); - */ - - @SuppressWarnings("AssignmentToMethodParameter") - public static int setForegroundColor(int attr, int code) { - code &= FGCOLOR_MASK; // throw all but lowest relevant bits away - attr &= ~ FGCOLOR; // 0 out existing bits - attr |= code << FGCOLOR_OFF; - return attr; - } - - /** - * Use this to get at the FG color value embedded in an attr. - */ - public static int foregroundColor(int attr) { - return (attr >> FGCOLOR_OFF) & FGCOLOR_MASK; - } - - /** - * Use this to get at the BG color value embedded in an attr. - */ - @SuppressWarnings("PointlessBitwiseExpression") - public static int backgroundColor(int attr) { - return (attr >> BGCOLOR_OFF) & BGCOLOR_MASK; - } - - /* - * Read-modify-write utility for setting bitfields in 'attr'. - */ - @SuppressWarnings("AssignmentToMethodParameter") - public static int setAttribute(int attr, int value) { - switch (value) { - case 0: - // Reset all attributes - attr = 0; - break; - case 5: // slow blink - case 6: // fast blink - // Attr.BLINK - // FALLTHRU - case 1: - attr &= ~ AttrSave.DIM; - attr |= AttrSave.BRIGHT; - break; - case 2: - attr &= ~ AttrSave.BRIGHT; - attr |= AttrSave.DIM; - break; - case 3: - // Italic - not supported - break; - case 4: - attr |= AttrSave.UNDERSCORE; - break; - case 7: - attr |= AttrSave.REVERSE; - break; - case 8: - attr |= AttrSave.HIDDEN; - break; - - case 9: - // Term specific - attr |= AttrSave.ACTIVE; - break; - - // turn individual attributes off (dtterm specific?) - case 25: - // blinking off - // FALLTHRU - case 22: - attr &= ~ AttrSave.DIM; - attr &= ~ AttrSave.BRIGHT; - break; - case 24: - attr &= ~ AttrSave.UNDERSCORE; - break; - case 27: - attr &= ~ AttrSave.REVERSE; - break; - case 28: - attr &= ~ AttrSave.HIDDEN; - break; - - case 30: - case 31: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - attr = AttrSave.setForegroundColor(attr, value-30+1); - break; - - case 39: - // revert to default (dtterm specific) - attr = AttrSave.setForegroundColor(attr, 0); - break; - - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - attr = AttrSave.setBackgroundColor(attr, value-40+1); - break; - - case 49: - // revert to default (dtterm specific) - attr = AttrSave.setBackgroundColor(attr, 0); - break; - - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: - // custom colors - attr = AttrSave.setForegroundColor(attr, value-50+9); - break; - - case 60: - case 61: - case 62: - case 63: - case 64: - case 65: - case 66: - case 67: - // custom colors - attr = AttrSave.setBackgroundColor(attr, value-60+9); - break; - - default: - // silently ignore unrecognized attribute - break; - } - return attr; - } - - /* - * Read-modify-write utility for unsetting bitfields in 'attr'. - * Note: this doesn't cover the unsetting operations which - * setAttributes does. - */ - @SuppressWarnings("AssignmentToMethodParameter") - public static int unsetAttribute(int attr, int value) { - switch (value) { - case 0: - // Reset all attributes - attr = 0; - break; - case 5: - // Attr.BLINK - // FALLTHRU - case 1: - attr &= ~ AttrSave.BRIGHT; - break; - case 2: - attr &= ~ AttrSave.DIM; - break; - case 4: - attr &= ~ AttrSave.UNDERSCORE; - break; - case 7: - attr &= ~ AttrSave.REVERSE; - break; - case 8: - attr &= ~ AttrSave.HIDDEN; - break; - case 9: - attr &= ~ AttrSave.ACTIVE; - break; - - case 30: - case 31: - case 32: - case 33: - case 34: - case 35: - case 36: - case 37: - attr = AttrSave.setForegroundColor(attr, 0); - break; - - case 40: - case 41: - case 42: - case 43: - case 44: - case 45: - case 46: - case 47: - attr = AttrSave.setBackgroundColor(attr, 0); - break; - - case 50: - case 51: - case 52: - case 53: - case 54: - case 55: - case 56: - case 57: - // custom colors - attr = AttrSave.setForegroundColor(attr, 0); - break; - - case 60: - case 61: - case 62: - case 63: - case 64: - case 65: - case 66: - case 67: - // custom colors - attr = AttrSave.setBackgroundColor(attr, 0); - break; - - default: - // silently ignore unrecognized attribute - break; - } - return attr; - } -} diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpANSI.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpANSI.java index 2eb00767fd71..05ddd24a7f4a 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpANSI.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpANSI.java @@ -27,6 +27,7 @@ package org.netbeans.lib.terminalemulator; import java.awt.event.KeyEvent; +import java.util.List; public class InterpANSI extends InterpProtoANSI { @@ -67,7 +68,18 @@ public void reset() { */ @Override protected boolean dispatchAttr(AbstractInterp ai, int n) { - switch (n) { + return this.dispatchAttr(ai, List.of(n)); + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean dispatchAttr(AbstractInterp ai, List n) { + if(n.isEmpty()) { + return false; + } + switch (n.getFirst()) { case 10: case 11: case 12: @@ -78,7 +90,7 @@ protected boolean dispatchAttr(AbstractInterp ai, int n) { case 17: case 18: case 19: - ai.ops.op_setG(0, n - 10); + ai.ops.op_setG(0, n.getFirst() - 10); return true; case 0: @@ -111,7 +123,6 @@ protected boolean dispatchAttr(AbstractInterp ai, int n) { case 35: case 36: case 37: - // case 38: case 39: case 40: @@ -122,8 +133,11 @@ protected boolean dispatchAttr(AbstractInterp ai, int n) { case 45: case 46: case 47: - // case 48: case 49: + + // 256 Color palette and true color mode + case 38: + case 48: ai.ops.op_attr(n); return true; default: diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpDtTerm.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpDtTerm.java index 988781ddc877..da15ccbbf005 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpDtTerm.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpDtTerm.java @@ -29,6 +29,8 @@ package org.netbeans.lib.terminalemulator; +import java.util.List; + class InterpDtTerm extends InterpProtoANSIX { @@ -124,8 +126,11 @@ public void reset() { * {@inheritDoc} */ @Override - protected boolean dispatchAttr(AbstractInterp ai, int n) { - switch (n) { + protected boolean dispatchAttr(AbstractInterp ai, List n) { + if(n.isEmpty()) { + return false; + } + switch (n.getFirst()) { case 0: case 1: case 2: @@ -179,6 +184,10 @@ protected boolean dispatchAttr(AbstractInterp ai, int n) { case 105: case 106: case 107: + + // 256 Color palette and true color mode + case 38: + case 48: ai.ops.op_attr(n); return true; default: diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpKit.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpKit.java index 203a890eab2c..9fce75604df7 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpKit.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpKit.java @@ -35,6 +35,7 @@ static Interp forName(String name, Ops ops) { switch (name) { case "xterm": // NOI18N case "xterm-16color": // NOI18N + case "xterm-256color": // NOI18N return new InterpXTerm(ops); case "dumb": // NOI18N return new InterpDumb(ops); diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpProtoANSI.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpProtoANSI.java index 37579e72a517..75730410c2f9 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpProtoANSI.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpProtoANSI.java @@ -18,18 +18,20 @@ */ package org.netbeans.lib.terminalemulator; +import java.util.List; + /** * Stuff common to InterpANSI, InterpDtTerm and InterpXTerm. * @author ivan */ class InterpProtoANSI extends InterpDumb { - protected static class Ascii { + private static class Ascii { public static final char ESC = 27; public static final char CTRL_N = 14; // ASCII SO/ShiftOut public static final char CTRL_O = 15; // ASCII SI/ShiftIn } - + protected static class InterpTypeProtoANSI extends InterpTypeDumb { protected final Actor act_reset_number = new ACT_RESET_NUMBER(); protected final Actor act_remember_digit = new ACT_REMEMBER_DIGIT(); @@ -160,7 +162,7 @@ public String action(AbstractInterp ai, char c) { return null; } } - + private static final class ACT_AE implements Actor { @Override public String action(AbstractInterp ai, char c) { @@ -229,19 +231,19 @@ public String action(AbstractInterp ai, char c) { private static final class ACT_SETG implements Actor { @Override public String action(AbstractInterp ai, char c) { - int gx = 0; InterpProtoANSI i = (InterpProtoANSI) ai; - switch (i.rememberedChar) { - case '(': gx = 0; break; - case ')': gx = 1; break; - case '*': gx = 2; break; - case '+': gx = 3; break; - } - int fx = 0; - switch (c) { - case 'B': fx = 0; break; - case '0': fx = 1; break; - } + int gx = switch (i.rememberedChar) { + case '(' -> 0; + case ')' -> 1; + case '*' -> 2; + case '+' -> 3; + default -> 0; + }; + int fx = switch (c) { + case 'B' -> 0; + case '0' -> 1; + default -> 0; + }; ai.ops.op_setG(gx, fx); return null; } @@ -308,7 +310,7 @@ public String action(AbstractInterp ai, char c) { ai.ops.op_ho(); } else { ai.ops.op_cm(ai.numberAt(0), ai.numberAt(1));// row, col - } + } return null; } } @@ -321,15 +323,12 @@ public String action(AbstractInterp ai, char c) { } else { final int code = ai.numberAt(0); switch (code) { - case 0: - case 1: - case 2: - ai.ops.op_ed(code); - break; - default: + case 0, 1, 2 -> ai.ops.op_ed(code); + default -> { return "ACT J: count of > 2 not supported"; // NOI18N + } } - } + } return null; } } @@ -342,15 +341,12 @@ public String action(AbstractInterp ai, char c) { } else { final int code = ai.numberAt(0); switch (code) { - case 0: - case 1: - case 2: - ai.ops.op_el(code); - break; - default: + case 0, 1, 2 -> ai.ops.op_el(code); + default -> { return "ACT K: count of > 2 not supported"; // NOI18N + } } - } + } return null; } } @@ -362,7 +358,7 @@ public String action(AbstractInterp ai, char c) { ai.ops.op_al(1); } else { ai.ops.op_al(ai.numberAt(0)); - } + } return null; } } @@ -374,7 +370,7 @@ public String action(AbstractInterp ai, char c) { ai.ops.op_dl(1); } else { ai.ops.op_dl(ai.numberAt(0)); - } + } return null; } } @@ -419,18 +415,14 @@ public String action(AbstractInterp ai, char c) { if (ai.noNumber()) { // Print screen } else { + // Ignored are: + // 1 -> Print line + // 4 -> Stop Print Log + // 5 -> Start Print Log switch (ai.numberAt(0)) { - case 1: // Print Line - case 4: // Stop Print Log - case 5: // Start Print Log - break; - case 10: - ai.ops.op_time(true); - break; - case 11: - ai.ops.op_time(false); - break; - } + case 10 -> ai.ops.op_time(true); + case 11 -> ai.ops.op_time(false); + } } return null; } @@ -453,13 +445,11 @@ private static final class ACT_ATTR implements Actor { public String action(AbstractInterp ai, char c) { // set graphics modes (bold, reverse video etc) if (ai.noNumber()) { - ai.ops.op_attr(0); // reset everything + ai.ops.op_attr(List.of(0)); // reset everything } else { - for (int n = 0; n <= ai.nNumbers(); n++) { - final int attr = ai.numberAt(n); - if (!((InterpProtoANSI) ai).dispatchAttr(ai, attr)) - return "ACT_ATTR: unrecognized attribute " + attr; // NOI18N - } + List numbers = ai.numbers(); + if (!((InterpProtoANSI) ai).dispatchAttr(ai, numbers)) + return "ACT_ATTR: unrecognized attribute " + numbers; // NOI18N } return null; } @@ -501,18 +491,18 @@ public InterpProtoANSI(Ops ops) { super(ops, type_singleton); this.type = type_singleton; setup(); - } + } protected InterpProtoANSI(Ops ops, InterpTypeProtoANSI type) { super(ops, type); this.type = type; setup(); - } + } @Override public String name() { return "proto-ansi"; // NOI18N - } + } @Override public void reset() { @@ -529,6 +519,16 @@ protected boolean dispatchAttr(AbstractInterp ai, int n) { return false; } + /** + * Process an attrib code in an Interp-specific manner. + * @param ai + * @param n The attribute code. + * @return Whether the attribute code is valid for the Interp. + */ + protected boolean dispatchAttr(AbstractInterp ai, List n) { + return false; + } + private void setup() { state = type.st_base; } diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpXTerm.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpXTerm.java index ef4423943b8a..f47ae31dfe85 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpXTerm.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/InterpXTerm.java @@ -19,6 +19,8 @@ package org.netbeans.lib.terminalemulator; +import java.util.List; + class InterpXTerm extends InterpProtoANSIX { @@ -100,24 +102,19 @@ public String action(AbstractInterp ai, char c) { String p2 = i.text.substring(semix+1); int code = Integer.parseInt(p1); switch (code) { - case 0: - ai.ops.op_icon_name(p2); - ai.ops.op_win_title(p2); - break; - case 1: + case 0 -> { ai.ops.op_icon_name(p2); - break; - case 2: ai.ops.op_win_title(p2); - break; - case 3: + } + case 1 -> ai.ops.op_icon_name(p2); + case 2 -> ai.ops.op_win_title(p2); + case 3 -> { /* LATER cwd is a dttermism. For xterm we're supposed to set X properties ai.ops.op_cwd(p2); - */ - break; - - case 10: { + */ + } + case 10 -> { // This is specific to nbterm! int semix2 = p2.indexOf(';'); if (semix2 == -1) @@ -151,7 +148,7 @@ protected InterpXTerm(Ops ops, InterpTypeXTerm type) { @Override public String name() { - return "xterm-16color"; // NOI18N + return "xterm-256color"; // NOI18N } @Override @@ -163,8 +160,11 @@ public void reset() { * {@inheritDoc} */ @Override - protected boolean dispatchAttr(AbstractInterp ai, int n) { - switch (n) { + protected boolean dispatchAttr(AbstractInterp ai, List n) { + if(n.isEmpty()) { + return false; + } + switch ((int) n.getFirst()) { case 0: case 1: case 4: @@ -219,6 +219,10 @@ protected boolean dispatchAttr(AbstractInterp ai, int n) { case 105: case 106: case 107: + + // 256 Color palette and true color mode + case 38: + case 48: ai.ops.op_attr(n); return true; default: diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Line.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Line.java index 609e9f09b367..d7d2e80b8e5e 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Line.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Line.java @@ -24,24 +24,20 @@ package org.netbeans.lib.terminalemulator; -final class Line { - public int glyph_glyph; - public int glyph_rendition; // Background color for the whole line - // This is independent of per-character - // rendition. +import java.util.Arrays; +import java.util.List; +final class Line { private char buf[]; // actual characters - private int attr[]; // attributes (allocated on demand) - + private Attr attr[]; // attributes (allocated on demand) // SHOULD use shorts? private int capacity; // == buf.length == attr.length private int length; // how much of buf and attr is filled - - + public Line() { reset(); } - + public void reset() { length = 0; capacity = 32; @@ -53,15 +49,15 @@ public void reset() { about_to_wrap = false; } - public void reset(Term term, int end, int eraseAttr) { + public void reset(Term term, int end, Attr eraseAttr) { reset(); clearToEndFrom(term, 0, end, eraseAttr); } - + public int capacity() { return capacity; } - + /** * Number of characters in the line. * charArray()[length()] is where the cursor or newline would be. @@ -70,11 +66,11 @@ public int capacity() { public int length() { return length; } - + public boolean hasAttributes() { return attr != null; } - + private int glyphId; public void setGlyphId(int glyphId) { this.glyphId = glyphId; @@ -82,7 +78,7 @@ public void setGlyphId(int glyphId) { public int getGlyphId() { return glyphId; } - + private int backgroundColor;// Background color for the whole line // This is independent of per-character // rendition. @@ -92,7 +88,7 @@ public void setBackgroundColor(int bgColor) { public int getBackgroundColor() { return backgroundColor; } - + public void setWrapped(boolean wrapped) { this.wrapped = wrapped; } @@ -101,9 +97,9 @@ public boolean isWrapped() { } // SHOULD collapse wrapped with about_to_wrap into a bitfield private boolean wrapped; - - - + + + public boolean setAboutToWrap(boolean about_to_wrap) { boolean old_about_to_wrap = about_to_wrap; this.about_to_wrap = about_to_wrap; @@ -114,54 +110,55 @@ public boolean isAboutToWrap() { } // Perhaps SHOULD have a state: normal, about-to-wrap, wrapped. private boolean about_to_wrap; - - + + /** * Return true if we've already seen attributes for this line * or 'a' is the first one, in which case we allocate the 'attr' array. */ - private boolean haveAttributes(int a) { - if (attr == null && a != 0) { - attr = new int[capacity]; + private boolean haveAttributes(boolean allocate) { + if (attr == null && allocate) { + attr = new Attr[capacity]; + Arrays.setAll(attr, i -> new Attr()); } return attr != null; } - - + + public void accumulateInto(int bcol, int ecol, StringBuffer buf) { buf.append(this.buf, bcol, ecol-bcol+1); } - + public char charAt(int col) { return buf[col]; } - + private void charAtPut(int col, char c) { buf[col] = c; } - + @Override public String toString() { assert false; return new String(buf); } - + public char[] getChars(char[] array) { System.arraycopy(buf, 0, array, 0, length); return array; } - - public int [] attrArray() { + + public Attr[] attrArray() { return attr; } - - + + public byte width(MyFontMetrics metrics, int at) { if (at >= capacity) return 1; return (byte) metrics.wcwidth(charAt(at)); } - + /* * Convert a cell column to a buffer column. */ @@ -181,7 +178,7 @@ public int cellToBuf(MyFontMetrics metrics, int target_col) { return target_col; } } - + /* * Convert a buffer column to a cell column. */ @@ -196,9 +193,9 @@ public int bufToCell(MyFontMetrics metrics, int target_col) { return target_col; } } - - - + + + public StringBuffer stringBuffer() { // only used for word finding // Grrr, why don't we have: new StringBuffer(buf, 0, length); @@ -209,80 +206,86 @@ public StringBuffer stringBuffer() { StringBuffer sb = new StringBuffer(length); return sb.append(buf, 0, length); } - + /* * Ensure that we have at least 'min_capacity'. */ private void ensureCapacity(Term term, int min_capacity) { - + term.noteColumn(this, min_capacity); - + if (min_capacity <= capacity) return; // nothing to do - + // doubling int new_capacity = (length+1) * 2; if (new_capacity < 0) new_capacity = Integer.MAX_VALUE; else if (min_capacity > new_capacity) new_capacity = min_capacity; - - + + char new_buf[] = new char[new_capacity]; System.arraycopy(buf, 0, new_buf, 0, length); buf = new_buf; - + if (attr != null) { - int new_attr[] = new int[new_capacity]; + Attr new_attr[] = new Attr[new_capacity]; System.arraycopy(attr, 0, new_attr, 0, length); + for(int i = length; i < new_capacity; i++) { + assert new_attr[i] == null; + new_attr[i] = new Attr(); + } attr = new_attr; } - + capacity = new_capacity; } - private void fillGap(int col, int eraseAttr) { + private void fillGap(int col, Attr eraseAttr) { // fill any newly opened gap (between length and col) with SP for (int cx = length; cx < col; cx++) charAtPut(cx, ' '); - if (haveAttributes(eraseAttr)) { - for (int cx = length; cx < col; cx++) + if (haveAttributes(!eraseAttr.isEmpty())) { + for (int cx = length; cx < col; cx++) { attr[col] = eraseAttr; + } } } - + /** * Insert character and attribute at 'column' and shift everything * past 'column' right. */ - public void insertCharAt(Term term, char c, int column, int a) { + public void insertCharAt(Term term, char c, int column, Attr a) { int new_length = length + 1; - + if (column >= length) { new_length = column+1; ensureCapacity(term, new_length); - fillGap(column, 0); // SHOULD be eraseAttr? + fillGap(column, new Attr()); // SHOULD be eraseAttr? } else { ensureCapacity(term, new_length); System.arraycopy(buf, column, buf, column + 1, length - column); - if (haveAttributes(a)) + if (haveAttributes(! a.isEmpty())) { System.arraycopy(attr, column, attr, column + 1, length - column); + } } - + term.checkForMultiCell(c); - + charAtPut(column, c); - if (haveAttributes(a)) + if (haveAttributes(!a.isEmpty())) { attr[column] = a; - + } length = new_length; } - + /* * Generic addition and modification. * Line will grow to accomodate column. */ - public void setCharAt(Term term, char c, int column, int a, int eraseAttr) { + public void setCharAt(Term term, char c, int column, Attr a, Attr eraseAttr) { if (column >= length) { ensureCapacity(term, column+1); fillGap(column, eraseAttr); @@ -293,11 +296,11 @@ public void setCharAt(Term term, char c, int column, int a, int eraseAttr) { throw new IllegalArgumentException(String.format("column=%d; buf_length=%d; buf_capacity=%d", column, length, capacity)); //NOI18N } charAtPut(column, c); - if (haveAttributes(a)) { + if (haveAttributes(!a.isEmpty())) { attr[column] = a; } } - + public void deleteCharAt(int column) { if (column < 0 || column >= length) return; @@ -305,41 +308,44 @@ public void deleteCharAt(int column) { charAtPut(length-1, (char) 0); if (attr != null) { System.arraycopy(attr, column+1, attr, column, length-column-1); - attr[length-1] = 0; + attr[length-1] = new Attr(); } // SHOULD move this up length--; } - - public void clearToEndFrom(Term term, int from, int end, int eraseAttr) { + + public void clearToEndFrom(Term term, int from, int end, Attr eraseAttr) { ensureCapacity(term, end+1); fillGap(end, eraseAttr); // Grrr, why is there a System.arrayCopy() but no System.arrayClear()? - for (int cx = from; cx <= end; cx++) + for (int cx = from; cx <= end; cx++) { charAtPut(cx, ' '); - if (haveAttributes(eraseAttr)) { - for (int cx = from; cx <= end; cx++) + } + if (haveAttributes(!eraseAttr.isEmpty())) { + for (int cx = from; cx <= end; cx++) { attr[cx] = eraseAttr; + } } length = end+1; } - public void clearTo(Term term, int col, int eraseAttr) { + public void clearTo(Term term, int col, Attr eraseAttr) { ensureCapacity(term, col+1); fillGap(col, eraseAttr); for (int cx = 0; cx <= col; cx++) charAtPut(cx, ' '); - if (haveAttributes(eraseAttr)) { - for (int cx = 0; cx <= col; cx++) + if (haveAttributes(!eraseAttr.isEmpty())) { + for (int cx = 0; cx <= col; cx++) { attr[cx] = eraseAttr; + } } if (length < col+1) length = col+1; } - public void clearFromTo(Term term, int from, int to, int eraseAttr) { + public void clearFromTo(Term term, int from, int to, Attr eraseAttr) { if (from > to) return; ensureCapacity(term, to+1); @@ -347,14 +353,15 @@ public void clearFromTo(Term term, int from, int to, int eraseAttr) { for (int cx = from; cx <= to; cx++) charAtPut(cx, ' '); - if (haveAttributes(eraseAttr)) { - for (int cx = from; cx <= to; cx++) + if (haveAttributes(!eraseAttr.isEmpty())) { + for (int cx = from; cx <= to; cx++) { attr[cx] = eraseAttr; + } } if (length < to+1) length = to+1; } - + /* * Used for selections * If the ecol is past the actual line length a "\n" is appended. @@ -365,10 +372,10 @@ public String text(int bcol, int ecol) { System.out.println("Line.text(bcol " + bcol + " ecol " + ecol + ")"); // NOI18N System.out.println("\tlength " + length); // NOI18N */ - - + + String newline = ""; // NOI18N - + // This only happens for 'empty' lines below the cursor. // Actually it also happens for 'empty' lines in the middle. // See issue 31951 for example. @@ -377,15 +384,15 @@ public String text(int bcol, int ecol) { // This is in fact what xterm does. // DtTerm doesn't allow selection of the 'empty' lines below the // cursor, but that is issue 21577 and is not easy to solve. - + if (length == 0) return "\n"; // NOI18N - + if (ecol >= length) { // The -1 snuffs out the newline. ecol = length-1; newline = "\n"; // NOI18N - + if (bcol >= length) bcol = length-1; } @@ -395,21 +402,29 @@ public String text(int bcol, int ecol) { } return new String(buf, bcol, count) + newline; } - + public void setCharacterAttribute(int bcol, int ecol, int value, boolean on) { // HACK: value is the ANSI code, haveAttributes takes out own // compact encoding, but it only checks for 0 so it's OK. - if (!haveAttributes(value)) + if (!haveAttributes(value != 0)) { return; - + } + try { if (on) { for (int c = bcol; c <= ecol; c++) - attr[c] = Attr.setAttribute(attr[c], value); + if(attr[c] != null) { + attr[c] = new Attr(); + } else { + attr[c].setAttribute(List.of(value)); + } } else { - for (int c = bcol; c <= ecol; c++) - attr[c] = Attr.unsetAttribute(attr[c], value); + for (int c = bcol; c <= ecol; c++) { + if(attr[c] != null) { + attr[c].unsetAttribute(value); + } + } } } catch (ArrayIndexOutOfBoundsException x) { System.out.printf("bcol %d ecol %d capacity %d length %d buf %d attr %d", // NOI18N diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Ops.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Ops.java index cd35426ce1fb..ac09e719b71d 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Ops.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Ops.java @@ -25,6 +25,8 @@ package org.netbeans.lib.terminalemulator; +import java.util.List; + /** * The mnemonics for the ops are _roughly_ based on termcap entries. */ @@ -64,6 +66,11 @@ interface Ops { public void op_el(int code); // Erase in Line public void op_attr(int mode); // set ANSI attributes + default public void op_attr(List attributes) { + if(attributes.size() != 1) { + throw new IllegalArgumentException("op_attr(List) not overriden and not exactly one argument provided"); + } + } public void op_set_mode(int mode); public void op_reset_mode(int mode); diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/RegionManager.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/RegionManager.java index 431cfafa81bf..7340f0081221 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/RegionManager.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/RegionManager.java @@ -89,9 +89,9 @@ public ActiveRegion endRegion(Coord end) throws RegionException { ActiveRegion endedRegion = region; - if (region.nested) { + if (region.isNested()) { region = parent; - parent = region.parent; + parent = region.parent(); } else { region = null; } diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Screen.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Screen.java index 37d6f1d0de90..382f0d62148b 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Screen.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Screen.java @@ -56,6 +56,7 @@ public Screen(Term term, int dx, int dy) { if (DEBUG) { // Just turning our double buffering isn't enough, need to // turn it off everywhere. + @SuppressWarnings("LeakingThisInConstructor") RepaintManager repaintManager = RepaintManager.currentManager(this); repaintManager.setDoubleBufferingEnabled(false); @@ -127,10 +128,10 @@ private void setGrabTab(boolean grabTab) { if (original_fwd_keys == null) { original_fwd_keys = new java.util.HashSet<>(); original_fwd_keys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, - InputEvent.CTRL_MASK)); + InputEvent.CTRL_DOWN_MASK)); original_bwd_keys = new java.util.HashSet<>(); original_bwd_keys.add(AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, - InputEvent.CTRL_MASK | InputEvent.SHIFT_MASK)); + InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK)); } if (grabTab) { @@ -187,7 +188,7 @@ public AccessibleContext getAccessibleContext() { return accessible_context; } - protected class AccessibleScreenText implements AccessibleText { + private class AccessibleScreenText implements AccessibleText { AccessibleScreenText() { } @@ -198,7 +199,7 @@ public int getCaretPosition() { } // cache for getCharacterAttribute - private int last_attr; + private Attr last_attr; private MutableAttributeSet last_as; @Override @@ -208,10 +209,10 @@ public AttributeSet getCharacterAttribute(int index) { return null; } BCoord b = c.toBCoord(term.firsta()); - int attr; + Attr attr; try { Line l = term.buf().lineAt(b.row); - int[] attrs = l.attrArray(); + Attr[] attrs = l.attrArray(); attr = attrs[b.col]; } catch (Exception x) { return null; @@ -223,14 +224,14 @@ public AttributeSet getCharacterAttribute(int index) { MutableAttributeSet as = new SimpleAttributeSet(); - if (Attr.UNDERSCORE.isSet(attr)) { + if (attr.isUnderscore()) { as.addAttribute(StyleConstants.Underline, Boolean.TRUE); } - if (Attr.BRIGHT.isSet(attr)) { + if (attr.isBright()) { as.addAttribute(StyleConstants.Bold, Boolean.TRUE); } - boolean reverse = Attr.REVERSE.isSet(attr); + boolean reverse = attr.isReverse(); Color color; color = term.foregroundColor(reverse, attr); @@ -290,16 +291,19 @@ private String getHelper(int part, BCoord b) { Line l = term.buf().lineAt(b.row); switch (part) { - case CHARACTER: + case CHARACTER -> { // return new String(l.charArray(), b.col, 1); return String.valueOf(l.charAt(b.col)); - case WORD: + } + case WORD -> { BExtent bword = term.buf().find_word(term.getWordDelineator(), b); Extent word = bword.toExtent(term.firsta()); return term.textWithin(word.begin, word.end); - case SENTENCE: + } + case SENTENCE -> { // return new String(l.charArray()); return l.toString(); + } } return null; } @@ -344,7 +348,7 @@ public int getIndexAtPoint(Point p) { } } - protected class AccessibleScreen extends AccessibleJComponent { + private class AccessibleScreen extends AccessibleJComponent { @Override public String getAccessibleDescription() { diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Sel.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Sel.java index cbe620fea24d..f58b5b8f721d 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Sel.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Sel.java @@ -93,8 +93,8 @@ class Sel implements ClipboardOwner { // Used by 'track()'. private Extent initial_word; - private Term term; - private State state; + private final Term term; + private final State state; // properties: private Color color = new Color(204, 204, 255); // swing color @@ -219,38 +219,38 @@ public void select_line(Extent range) { } private boolean extend_work(Coord p, int tracking) { - /* - * return true if a screen refresh is needed - */ - if (tracking == Sel.SEL_NONE) { - return false; - - } else if (tracking == Sel.SEL_CHAR) { - sel_extent = p; - - } else if (tracking == Sel.SEL_WORD) { - BExtent Bnew_range = term.buf().find_word(term.getWordDelineator(), p.toBCoord(term.firsta())); - Extent new_range = Bnew_range.toExtent(term.firsta()); - if (p.compareTo(initial_word.begin) < 0) { - sel_origin = new Coord(new_range.begin); - sel_extent = initial_word.end; - } else if (p.compareTo(initial_word.end) > 0) { - sel_origin = initial_word.begin; - sel_extent = new Coord(new_range.end); - } else { - sel_origin = initial_word.begin; - sel_extent = initial_word.end; - } - - } else if (tracking == Sel.SEL_LINE) { - if (p.compareTo(sel_origin) > 0) { - sel_origin = Coord.make(sel_origin.row, 0); - sel_extent = Coord.make(p.row, term.buf().totalCols()); - } else { - sel_origin = Coord.make(sel_origin.row, term.buf().totalCols()); - sel_extent = Coord.make(p.row, 0); - } - } + /* + * return true if a screen refresh is needed + */ + switch (tracking) { + case Sel.SEL_NONE -> { + return false; + } + case Sel.SEL_CHAR -> sel_extent = p; + case Sel.SEL_WORD -> { + BExtent Bnew_range = term.buf().find_word(term.getWordDelineator(), p.toBCoord(term.firsta())); + Extent new_range = Bnew_range.toExtent(term.firsta()); + if (p.compareTo(initial_word.begin) < 0) { + sel_origin = new Coord(new_range.begin); + sel_extent = initial_word.end; + } else if (p.compareTo(initial_word.end) > 0) { + sel_origin = initial_word.begin; + sel_extent = new Coord(new_range.end); + } else { + sel_origin = initial_word.begin; + sel_extent = initial_word.end; + } + } + case Sel.SEL_LINE -> { + if (p.compareTo(sel_origin) > 0) { + sel_origin = Coord.make(sel_origin.row, 0); + sel_extent = Coord.make(p.row, term.buf().totalCols()); + } else { + sel_origin = Coord.make(sel_origin.row, term.buf().totalCols()); + sel_extent = Coord.make(p.row, 0); + } + } + } return true; } @@ -310,6 +310,7 @@ public void done(/* OLD boolean force_copy */) { term.fireSelectionExtentChanged(); } + @Override public void lostOwnership(Clipboard cb, Transferable c) { /* * Part of the ClipboardOwner interface. @@ -331,12 +332,11 @@ public String getSelection() { if (x.begin != null && x.end != null) { final StringBuffer text = new StringBuffer(); - term.visitLines(x.begin, x.end, true, new LineVisitor() { - public boolean visit(Line l, int row, int bcol, int ecol) { - text.append(l.text(bcol, ecol)); - return true; - } - } ); + term.visitLines(x.begin, x.end, true, + (Line l, int row, int bcol, int ecol) -> { + text.append(l.text(bcol, ecol)); + return true; + }); return text.toString(); } @@ -422,22 +422,21 @@ private void paint(Graphics g, int row, int bcol, int ecol) { } void paint(final Graphics g) { - /* + /* * Paint the selection. - */ + */ - Extent x = getExtent(); - if (x == null) - return; - x.order(); - - // DEBUG System.out.println("Sel.paint extent: " + x); // NOI18N + Extent x = getExtent(); + if (x == null) { + return; + } + x.order(); - term.visitLines(x.begin, x.end, true, new LineVisitor() { - public boolean visit(Line l, int row, int bcol, int ecol) { - paint(g, row, bcol, ecol); - return true; - } - } ); + // DEBUG System.out.println("Sel.paint extent: " + x); // NOI18N + term.visitLines(x.begin, x.end, true, + (Line l, int row, int bcol, int ecol) -> { + paint(g, row, bcol, ecol); + return true; + }); } } diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/State.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/State.java index efdbd3fdb8a7..8450aa1b9748 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/State.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/State.java @@ -45,7 +45,7 @@ public void adjust(int amount) { } // Current attribute as defined by class Attr - public int attr; + public Attr attr = new Attr(); // If 'true' characters replace what's under cursor (default) // If 'false' act as an insert operation. diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Term.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Term.java index 0da9fb844b0e..08215f3eb228 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Term.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/Term.java @@ -30,6 +30,7 @@ import java.awt.geom.Point2D; import java.io.IOException; import java.util.*; +import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import javax.accessibility.Accessible; import javax.accessibility.AccessibleContext; @@ -228,6 +229,7 @@ public static class ExternalCommandsConstants { } private State st = new State(); + @SuppressWarnings("this-escape") private Sel sel = new Sel(this, st); private transient Ops ops = new OpsImpl(); private int top_margin = 0; // 0 means default (see topMargin()) @@ -264,13 +266,15 @@ public static class ExternalCommandsConstants { // will be quite far from the initial press location. private Point left_down_point; // getSystemSelection() wasn't available on Java prior to 1.4 + @SuppressWarnings("this-escape") private Clipboard systemClipboard = getToolkit().getSystemClipboard(); + @SuppressWarnings("this-escape") private Clipboard systemSelection = getToolkit().getSystemSelection(); private static final Color TRANSPARENT = new Color(0, 0, 0, 0); - // + // // The palette maps color indexes into actual Color's. - // + // // Attr's FGCOLOR and BGCOLOR store either 0 to imply "default" or // the palette index + 1. So use methods Attr.foregroundColor() and // backgroudnColor() to convert Attr values to the indexes into the palette. @@ -471,7 +475,7 @@ public void pushStream(TermStream stream) { /* * Debugging utilities */ - private static final Integer DEFAULT_DEBUG = Integer.getInteger("org.netbeans.lib.terminalemulator.Term.debug"); + private static final int DEFAULT_DEBUG = Integer.getInteger("org.netbeans.lib.terminalemulator.Term.debug", 0); @SuppressWarnings("PointlessBitwiseExpression") public static final int DEBUG_OPS = 1 << 0; public static final int DEBUG_KEYS = 1 << 1; @@ -486,7 +490,7 @@ public void setDebugFlags(int flags) { debug = flags; } - private int debug = DEFAULT_DEBUG != null ? DEFAULT_DEBUG : 0; + private int debug = DEFAULT_DEBUG; private boolean debugOps() { return (debug & DEBUG_OPS) == DEBUG_OPS; @@ -664,25 +668,25 @@ private void fireSizeChanged(Dimension cells, Dimension pixels) { l.sizeChanged(cells, pixels); } } - + private void fireTitleChanged(String title) { for (TermListener l : listeners) { l.titleChanged(title); } } - + private void fireCwdChanged(String cwd) { for (TermListener l : listeners) { l.cwdChanged(cwd); } } - + private void fireExternalCommand(String command) { for (TermListener l : listeners) { l.externalToolCalled(command); } } - + private final java.util.List listeners = new CopyOnWriteArrayList<>(); /** @@ -747,7 +751,7 @@ public void clearHistoryNoRefresh() { st.firsty = 0; st.cursor.row = 0; st.cursor.col = 0; - setAttribute(0); + setAttribute(List.of(0)); st.saveCursor(); // This clobbers the saved cursor value st.restoreCursor(); // release reference to saved cursor object @@ -787,15 +791,12 @@ public String textWithin(Coord begin, Coord end) { final StringBuffer aBuf = new StringBuffer(); - visitLines(begin, end, false, new LineVisitor() { - - @Override - public boolean visit(Line l, int row, int bcol, int ecol) { - // buf.append(l.charArray(), bcol, ecol-bcol+1); - l.accumulateInto(bcol, ecol, aBuf); - return true; - } - }); + visitLines(begin, end, false, + (Line l, int row, int bcol, int ecol) -> { + // buf.append(l.charArray(), bcol, ecol-bcol+1); + l.accumulateInto(bcol, ecol, aBuf); + return true; + }); return aBuf.toString(); } @@ -806,10 +807,10 @@ public String getRowText(int row) { } return line.stringBuffer().toString(); } - + private Keymap keymap; private Set allowedActions; - + /** * Set keymap and allowed actions * @param keymap - use this to check if a keystroke is used outside the terminal @@ -888,7 +889,7 @@ private boolean maybeConsume(KeyEvent e) { System.out.println("\tKS = " + ks); // NOI18N System.out.println("\tcontained = " + keystroke_set.contains(ks)); // NOI18N } - + if (keystroke_set == null || !keystroke_set.contains(ks)) { e.consume(); @@ -1088,7 +1089,7 @@ public boolean visit(Line l, int brow, int bcol, int ecol) { * @param begin * @param offset * @param length - * @return + * @return */ @SuppressWarnings({"AssignmentToMethodParameter", "ValueOfIncrementOrDecrementUsed"}) public Extent extentInLogicalLine(Coord begin, int offset, int length) { @@ -1302,14 +1303,24 @@ private void possiblyHScroll() { * @param value attribute value */ public void setAttribute(int value) { - st.attr = Attr.setAttribute(st.attr, value); + setAttribute(List.of(value)); + } + + /** + * Set the display attribute for characters printed from now on. + *

+ * Unrecognized values silently ignored. + * @param value attribute value + */ + public void setAttribute(List value) { + st.attr = st.attr.setAttribute(value); } /** * Return the complete state of attributes. * @return Complete state of attributes. */ - int attrSave() { + Attr attrSave() { return st.attr; } @@ -1317,7 +1328,7 @@ int attrSave() { * Restore the complete set of attributes. * @param attr Attributes to be restored. */ - void attrRestore(int attr) { + void attrRestore(Attr attr) { st.attr = attr; } @@ -1334,14 +1345,11 @@ void attrRestore(int attr) { public void setCharacterAttribute(Coord begin, Coord end, final int value, final boolean on) { - visitLines(begin, end, false, new LineVisitor() { - - @Override - public boolean visit(Line l, int brow, int bcol, int ecol) { - l.setCharacterAttribute(bcol, ecol, value, on); - return true; - } - }); + visitLines(begin, end, false, + (Line l, int brow, int bcol, int ecol) -> { + l.setCharacterAttribute(bcol, ecol, value, on); + return true; + }); repaint(false); } @@ -1536,8 +1544,6 @@ private boolean extend() { return false; } - BCoord x = sel.sel_extent.toBCoord(firsta); - BCoord v = toViewCoord(x); int r; int c; @@ -1673,7 +1679,7 @@ private void initializePalette() { palette[Attr.PAL_ANSI+6] = new Color(0x00CDCD); palette[Attr.PAL_ANSI+7] = new Color(0xE5E5E5); - palette[Attr.PAL_BRIGHT+0] = new Color(0x0D0D0D); + palette[Attr.PAL_BRIGHT+0] = new Color(0x5d5050); palette[Attr.PAL_BRIGHT+1] = new Color(0xFF0000); palette[Attr.PAL_BRIGHT+2] = new Color(0x00FF00); palette[Attr.PAL_BRIGHT+3] = new Color(0xFFFF00); @@ -1684,13 +1690,16 @@ private void initializePalette() { // Fill RGB cube for (int r = 0; r <= 5; r++) { - for (int g = 0; g <= 5; g++) { - for (int b = 0; b <= 5; b++) { - int number = 36 * r + 6 * g + b; - palette[Attr.PAL_RGB+number] = new Color(r*51, b*51, b*51); - } - } - } + for (int g = 0; g <= 5; g++) { + for (int b = 0; b <= 5; b++) { + int number = 36 * r + 6 * g + b; + int rval = r == 0 ? 0 : (r * 40 + 55); + int gval = g == 0 ? 0 : (g * 40 + 55); + int bval = b == 0 ? 0 : (b * 40 + 55); + palette[Attr.PAL_RGB + number] = new Color(rval, gval, bval); + } + } + } // Fill greyscale portion. for (int g = 0; g < 24; g++) { @@ -1714,6 +1723,7 @@ private void initializePalette() { /** * Constructor */ + @SuppressWarnings("this-escape") public Term() { st.rows = 25; st.firstx = 0; @@ -1754,39 +1764,34 @@ public Term() { vscroll_bar.setEnabled(true); vscroll_bar.setFocusable(false); - vscroll_bar.addAdjustmentListener(new AdjustmentListener() { + vscroll_bar.addAdjustmentListener((AdjustmentEvent e) -> { + // JScrollBar sb = (JScrollBar) e.getAdjustable(); + switch (e.getAdjustmentType()) { + case AdjustmentEvent.TRACK -> { - @Override - public void adjustmentValueChanged(AdjustmentEvent e) { - // JScrollBar sb = (JScrollBar) e.getAdjustable(); - switch (e.getAdjustmentType()) { - case AdjustmentEvent.TRACK: - - int pos = e.getValue(); - - // adjustmentValueChanged() will get called when we - // call setValues() on the scrollbar. - // This test sort-of filters that out - if (pos == st.firstx) { - break; - } + int pos = e.getValue(); - // deal with the user moving the thumb - st.firstx = pos; - /* DEBUG - if (st.firstx + st.rows > buf.nlines) { - Thread.dumpStack(); - printStats("bad scroll value"); // NOI18N - } - */ - repaint(false); + // adjustmentValueChanged() will get called when we + // call setValues() on the scrollbar. + // This test sort-of filters that out + if (pos == st.firstx) { break; + } - default: - /* DEBUG - System.out.println("adjustmentValueChanged: " + e); // NOI18N - */ - break; + // deal with the user moving the thumb + st.firstx = pos; + /* DEBUG + if (st.firstx + st.rows > buf.nlines) { + Thread.dumpStack(); + printStats("bad scroll value"); // NOI18N + } + */ + repaint(false); + } + default -> { + /* DEBUG + System.out.println("adjustmentValueChanged: " + e); // NOI18N + */ } } }); @@ -1801,33 +1806,28 @@ public void adjustmentValueChanged(AdjustmentEvent e) { hscroll_wrapper = new ScrollWrapper(hscroll_bar); add(BorderLayout.SOUTH, hscroll_wrapper); - hscroll_bar.addAdjustmentListener(new AdjustmentListener() { + hscroll_bar.addAdjustmentListener((AdjustmentEvent e) -> { + // JScrollBar sb = (JScrollBar) e.getAdjustable(); + switch (e.getAdjustmentType()) { + case AdjustmentEvent.TRACK -> { - @Override - public void adjustmentValueChanged(AdjustmentEvent e) { - // JScrollBar sb = (JScrollBar) e.getAdjustable(); - switch (e.getAdjustmentType()) { - case AdjustmentEvent.TRACK: - - int pos = e.getValue(); - - // adjustmentValueChanged() will get called when we - // call setValues() on the scrollbar. - // This test sort-of filters that out - if (pos == st.firsty) { - break; - } + int pos = e.getValue(); - // deal with the user moving the thumb - st.firsty = pos; - repaint(false); + // adjustmentValueChanged() will get called when we + // call setValues() on the scrollbar. + // This test sort-of filters that out + if (pos == st.firsty) { break; + } - default: - /* DEBUG - System.out.println("adjustmentValueChanged: " + e); // NOI18N - */ - break; + // deal with the user moving the thumb + st.firsty = pos; + repaint(false); + } + default -> { + /* DEBUG + System.out.println("adjustmentValueChanged: " + e); // NOI18N + */ } } }); @@ -1873,13 +1873,13 @@ private void charTyped(char c, KeyEvent e) { // Consume ctrl+tab, ctrl+shift+tab event, see #237990 if (keymap != null && (c == KeyEvent.VK_TAB) - && ((e.getModifiers() == KeyEvent.CTRL_MASK) - || (e.getModifiers() == (KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK)))) { + && ((e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK) + || (e.getModifiersEx() == (KeyEvent.CTRL_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK)))) { e.consume(); } if (passOn && maybeConsume(e)) { - if ((e.getModifiers() & KeyEvent.ALT_MASK) == KeyEvent.ALT_MASK) { + if ((e.getModifiersEx() & KeyEvent.ALT_DOWN_MASK) == KeyEvent.ALT_DOWN_MASK) { if (getAltSendsEscape()) { on_char(ESC); on_char(c); @@ -1936,51 +1936,45 @@ public void keyPressed(KeyEvent e) { } switch (e.getKeyCode()) { - case KeyEvent.VK_ESCAPE: + case KeyEvent.VK_ESCAPE -> { if (onMac()) { // On a Mac AWT doesn't provide us with a keyTyped() // for VK_ESCAPE so we simulate it. charTyped(ESC, e); } - break; - case KeyEvent.VK_COPY: - copyToClipboard(); - break; - case KeyEvent.VK_PASTE: - pasteFromClipboard(); - break; - case KeyEvent.VK_ENTER: - saw_return = true; - break; - case KeyEvent.VK_PAGE_UP: - if (e.getModifiers() == Event.CTRL_MASK) { + } + case KeyEvent.VK_COPY -> copyToClipboard(); + case KeyEvent.VK_PASTE -> pasteFromClipboard(); + case KeyEvent.VK_ENTER -> saw_return = true; + case KeyEvent.VK_PAGE_UP -> { + if (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK) { pageLeft(1); } else { pageUp(1); } - break; - case KeyEvent.VK_PAGE_DOWN: - if (e.getModifiers() == Event.CTRL_MASK) { + } + case KeyEvent.VK_PAGE_DOWN -> { + if (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK) { pageRight(1); } else { pageDown(1); } - break; + } - case KeyEvent.VK_UP: - if (e.getModifiers() == Event.CTRL_MASK) { + case KeyEvent.VK_UP -> { + if (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK) { lineUp(1); } - break; - case KeyEvent.VK_DOWN: - if (e.getModifiers() == Event.CTRL_MASK) { + } + case KeyEvent.VK_DOWN -> { + if (e.getModifiersEx() == KeyEvent.CTRL_DOWN_MASK) { lineDown(1); } - break; - case KeyEvent.VK_LEFT: - break; - case KeyEvent.VK_RIGHT: - break; + } + case KeyEvent.VK_LEFT -> { + } + case KeyEvent.VK_RIGHT -> { + } } passOn = maybeConsume(e); } @@ -2081,7 +2075,7 @@ public void mouseClicked(MouseEvent e) { System.out.println("Selection: '" + sel.sel_get() + "'"); // NOI18N */ pasteFromSelection(); - + // See IZ 193527 if (click_to_type) { requestFocus(); @@ -2114,27 +2108,19 @@ public void mousePressed(MouseEvent e) { } switch (e.getClickCount()) { - case 1: - left_down_point = (Point) e.getPoint().clone(); - break; - case 2: - { + case 1 -> left_down_point = (Point) e.getPoint().clone(); + case 2 -> { BCoord bcoord = toBufCoords(toViewCoord(e.getPoint())); BExtent word = buf.find_word(word_delineator, bcoord); sel.select_word(word.toExtent(firsta)); repaint(false); - break; } - case 3: - { + case 3 -> { BCoord bcoord = toBufCoords(toViewCoord(e.getPoint())); BExtent line = buf.find_line(bcoord); sel.select_line(line.toExtent(firsta)); repaint(false); - break; } - default: - break; } fireSelectionExtentChanged(); @@ -2354,7 +2340,7 @@ private void pasteHelp(Clipboard cb) { try { String string; string = (String) contents.getTransferData(DataFlavor.stringFlavor); - + // bug #237034 if (string == null) { return; @@ -2634,7 +2620,7 @@ Point toPixel(BCoord v) { * coordinate system. * It returns the pixel of the upper left corner of the target cell. * @param target - * @return + * @return */ public Point toPixel(Coord target) { BCoord btarget = target.toBCoord(firsta); @@ -2677,7 +2663,7 @@ BCoord toBufCoords(BCoord v) { *

* In the returned Point, x represents the column, y the row. * @param p - * @return + * @return */ public Point mapToViewRowCol(Point p) { BCoord c = toViewCoord(p); @@ -2690,7 +2676,7 @@ public Point mapToViewRowCol(Point p) { *

* In the returned Point, x represents the column, y the row. * @param p - * @return + * @return */ public Point mapToBufRowCol(Point p) { BCoord c = toBufCoords(toViewCoord(p)); @@ -2710,8 +2696,7 @@ private Color rendition_to_color(int rendition) { private int totcols; private void do_run(Graphics g, int yoff, int xoff, int baseline, - int brow, /* OLD char buf[], */ Line l, - int attr, int rbegin, int rend) { + Line l, Attr attr, int rbegin, int rend) { /* DEBUG System.out.println("do_run(" + rbegin + ", " + rend + ")"); // NOI18N @@ -2747,8 +2732,8 @@ private void do_run(Graphics g, int yoff, int xoff, int baseline, xlength = rlength * metrics.width; } - boolean reverse = Attr.REVERSE.isSet(attr); - boolean active = Attr.ACTIVE.isSet(attr); + boolean reverse = attr.isReverse(); + boolean active = attr.isActive(); // choose background color Color bg; @@ -2756,7 +2741,7 @@ private void do_run(Graphics g, int yoff, int xoff, int baseline, if (active) { bg = active_color; } else { - if (Attr.BGCOLOR.isSet(attr) || Attr.REVERSE.isSet(attr)) { + if (attr.isBGcolor() || attr.isReverse()) { bg = backgroundColor(reverse, attr); } else if (l.getBackgroundColor() != 0) { bg = rendition_to_color(l.getBackgroundColor()); @@ -2777,7 +2762,7 @@ private void do_run(Graphics g, int yoff, int xoff, int baseline, g.setColor(fg); // draw any underscores - if (Attr.UNDERSCORE.isSet(attr)) { + if (attr.isUnderscore()) { int h = metrics.height - metrics.leading - 1; g.drawLine(x, yoff + h, x + xlength, yoff + h); } @@ -2786,7 +2771,7 @@ private void do_run(Graphics g, int yoff, int xoff, int baseline, myDrawChars(g, /* OLD buf, */ l, rbegin, rlength, x, baseline); // Draw fake bold characters by redrawing one pixel to the right - if (Attr.BRIGHT.isSet(attr)) { + if (attr.isBright()) { myDrawChars(g, /* OLD buf, */ l, rbegin, rlength, x + 1, baseline); } } @@ -2982,7 +2967,7 @@ private void paint_line_new(Graphics g, Line l, int brow, return; } - int attrs[] = l.attrArray(); + Attr[] attrs = l.attrArray(); // find the extent of the selection on this line int sbegin = -1; @@ -3019,10 +3004,10 @@ private void paint_line_new(Graphics g, Line l, int brow, // A run, as in run-length-encoding, is a set of characters with // the same attributes. - int attr = attrs[rbegin]; + Attr attr = attrs[rbegin]; rend = rbegin + 1; while (rend <= lastcol) { - if (attrs[rend] != attr) { + if (! attrs[rend].equals(attr)) { break; } rend++; @@ -3034,19 +3019,17 @@ private void paint_line_new(Graphics g, Line l, int brow, // parts that fall under the selection are rendered with an // alternative attribute set. - int alt_attr = attr & ~ Attr.ALT; + Attr alt_attr = attr.altVariant(); if (sbegin == -1 || send < rbegin || sbegin > rend) { // run is not in selection - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, attr, rbegin, rend); + do_run(g, yoff, xoff, baseline, l, attr, rbegin, rend); } else if (sbegin <= rbegin && send >= rend) { // run entirely in selection /* DEBUG System.out.println("run entirely in selection"); // NOI18N */ - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, alt_attr, rbegin, rend); + do_run(g, yoff, xoff, baseline, l, alt_attr, rbegin, rend); } else if (sbegin > rbegin && send < rend) { // selection fully within run @@ -3054,12 +3037,9 @@ private void paint_line_new(Graphics g, Line l, int brow, /* DEBUG System.out.println("run selection fully within run"); // NOI18N */ - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, attr, rbegin, sbegin - 1); - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, alt_attr, sbegin, send); - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, attr, send + 1, rend); + do_run(g, yoff, xoff, baseline, l, attr, rbegin, sbegin - 1); + do_run(g, yoff, xoff, baseline, l, alt_attr, sbegin, send); + do_run(g, yoff, xoff, baseline, l, attr, send + 1, rend); } else if (sbegin <= rbegin) { // selection covers left portion of run @@ -3067,10 +3047,8 @@ private void paint_line_new(Graphics g, Line l, int brow, System.out.println("selection covers left portion of run"); // NOI18N */ // split into two parts - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, alt_attr, rbegin, send); - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, attr, send + 1, rend); + do_run(g, yoff, xoff, baseline, l, alt_attr, rbegin, send); + do_run(g, yoff, xoff, baseline, l, attr, send + 1, rend); } else if (send >= rend) { // selection covers right portion of run @@ -3078,10 +3056,8 @@ private void paint_line_new(Graphics g, Line l, int brow, /* DEBUG System.out.println("selection covers right portion of run"); // NOI18N */ - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, attr, rbegin, sbegin - 1); - do_run(g, yoff, xoff, - baseline, brow, /* OLD buf, */ l, alt_attr, sbegin, rend); + do_run(g, yoff, xoff, baseline, l, attr, rbegin, sbegin - 1); + do_run(g, yoff, xoff, baseline, l, alt_attr, sbegin, rend); } else { /* DEBUG @@ -3467,7 +3443,7 @@ public void op_char(char inChar) { } l.setCharAt(Term.this, c, insertion_col, - st.attr, Attr.BGCOLOR.get(st.attr)); // overstrike + st.attr, st.attr.bgColorVariant()); // overstrike st.cursor.col += cwidth; if (st.cursor.col >= buf.visibleCols() && !horizontally_scrollable) { @@ -3497,6 +3473,11 @@ public void op_ae() { @Override public void op_attr(int attr) { + this.op_attr(List.of(attr)); + } + + @Override + public void op_attr(List attr) { if (debugOps()) { System.out.println("op_attr(" + attr + ")"); // NOI18N } @@ -3586,7 +3567,7 @@ public void op_tab() { } cht(); } - + private boolean cht() { // SHOULD do something better with tabs near the end of the line // On the other hand, that's how ANSI terminals are supposed @@ -3637,7 +3618,7 @@ public void op_cbt(int n) { } @Override - @SuppressWarnings({"ValueOfIncrementOrDecrementUsed", "ValueOfIncrementOrDecrementUsed"}) + @SuppressWarnings({"ValueOfIncrementOrDecrementUsed", "ValueOfIncrementOrDecrementUsed", "AssignmentToMethodParameter"}) public void op_cht(int n) { if (debugOps()) { System.out.printf("op_cht(%d)\n", n); // NOI18N @@ -3681,18 +3662,11 @@ public void op_al(int count) { } switch (sel.intersection(st.cursor.row - 1)) { - case Sel.INT_NONE: - case Sel.INT_ABOVE: - case Sel.INT_ON: - // nothing to do - break; - case Sel.INT_STRADDLES: - sel.cancel(true); // DtTerm behaviour - break; - case Sel.INT_BELOW: - sel.adjust(firsta, +1, firsta + buf.nlines()); - break; + case Sel.INT_NONE, Sel.INT_ABOVE, Sel.INT_ON -> {} // nothing to do + case Sel.INT_STRADDLES -> sel.cancel(true); // DtTerm behaviour + case Sel.INT_BELOW -> sel.adjust(firsta, +1, firsta + buf.nlines()); } + } @Override @@ -3759,35 +3733,29 @@ public void op_el(int code) { } Line l = cursor_line(); switch (code) { - case 0: // from cursor to end + case 0 -> { // from cursor to end l.clearToEndFrom(Term.this, l.cellToBuf(metrics, st.cursor.col), buf.visibleCols()-1, - Attr.BGCOLOR.get(st.attr)); - break; - case 1: // from beginning to cursor (inclusive) + st.attr.bgColorVariant()); + } + case 1 -> { // from beginning to cursor (inclusive) l.clearTo(Term.this, l.cellToBuf(metrics, st.cursor.col), - Attr.BGCOLOR.get(st.attr)); - break; - case 2: // whole line + st.attr.bgColorVariant()); + } + case 2 -> { // whole line l.clearToEndFrom(Term.this, 0, buf.visibleCols()-1, - Attr.BGCOLOR.get(st.attr)); - break; + st.attr.bgColorVariant()); + } } switch (sel.intersection(st.cursor.row)) { - case Sel.INT_NONE: - case Sel.INT_ABOVE: - case Sel.INT_BELOW: - // nothing to do - break; - case Sel.INT_ON: - case Sel.INT_STRADDLES: - sel.cancel(true); // DtTerm behaviour - break; + case Sel.INT_NONE, Sel.INT_ABOVE, Sel.INT_BELOW -> {} // nothing to do + case Sel.INT_ON, Sel.INT_STRADDLES -> sel.cancel(true); // DtTerm behaviour } + } @Override @@ -3802,16 +3770,10 @@ public void op_cd() { } switch (sel.intersection(st.cursor.row)) { - case Sel.INT_NONE: - case Sel.INT_ABOVE: - // nothing to do - break; - case Sel.INT_BELOW: - case Sel.INT_ON: - case Sel.INT_STRADDLES: - sel.cancel(true); // DtTerm behaviour - break; + case Sel.INT_NONE, Sel.INT_ABOVE -> {} // nothing to do + case Sel.INT_BELOW, Sel.INT_ON, Sel.INT_STRADDLES -> sel.cancel(true); // DtTerm behaviour } + } @Override @@ -3834,50 +3796,44 @@ public void op_ed(int code) { } Line l; switch (code) { - case 0: // from cursor to end + case 0 -> { // from cursor to end l = cursor_line(); // l.setAboutToWrap(false); l.clearToEndFrom(Term.this, l.cellToBuf(metrics, st.cursor.col), buf.visibleCols()-1, - Attr.BGCOLOR.get(st.attr)); + st.attr.bgColorVariant()); for (int lx = st.cursor.row+1; lx < beginx() + st.rows; lx++) { l = buf.lineAt(lx); // l.setAboutToWrap(false); - l.reset(Term.this, buf.visibleCols()-1, Attr.BGCOLOR.get(st.attr)); + l.reset(Term.this, buf.visibleCols()-1, st.attr.bgColorVariant()); } - break; - case 1: // from beginning to cursor (inclusive) + } + case 1 -> { // from beginning to cursor (inclusive) for (int lx = beginx(); lx < st.cursor.row; lx++) { l = buf.lineAt(lx); // l.setAboutToWrap(false); - l.reset(Term.this, buf.visibleCols()-1, Attr.BGCOLOR.get(st.attr)); + l.reset(Term.this, buf.visibleCols()-1, st.attr.bgColorVariant()); } l = cursor_line(); // l.setAboutToWrap(false); l.clearTo(Term.this, l.cellToBuf(metrics, st.cursor.col), - Attr.BGCOLOR.get(st.attr)); - break; - case 2: // whole screen + st.attr.bgColorVariant()); + } + case 2 -> { // whole screen for (int lx = beginx(); lx < beginx() + st.rows; lx++) { l = buf.lineAt(lx); // l.setAboutToWrap(false); - l.reset(Term.this, buf.visibleCols()-1, Attr.BGCOLOR.get(st.attr)); + l.reset(Term.this, buf.visibleCols()-1, st.attr.bgColorVariant()); } - break; + } } switch (sel.intersection(st.cursor.row)) { - case Sel.INT_NONE: - case Sel.INT_ABOVE: - case Sel.INT_BELOW: - // nothing to do - break; - case Sel.INT_ON: - case Sel.INT_STRADDLES: - sel.cancel(true); // DtTerm behaviour - break; + case Sel.INT_NONE, Sel.INT_ABOVE, Sel.INT_BELOW -> {} // nothing to do + case Sel.INT_ON, Sel.INT_STRADDLES -> sel.cancel(true); // DtTerm behaviour } + } @Override @@ -3923,17 +3879,9 @@ public void op_dl(int count) { } switch (sel.intersection(st.cursor.row)) { - case Sel.INT_NONE: - case Sel.INT_ABOVE: - // nothing to do - break; - case Sel.INT_ON: - case Sel.INT_STRADDLES: - sel.cancel(true); // DtTerm behaviour - break; - case Sel.INT_BELOW: - sel.adjust(firsta, -1, firsta + buf.nlines()); - break; + case Sel.INT_NONE, Sel.INT_ABOVE -> {} // nothing to do + case Sel.INT_ON, Sel.INT_STRADDLES -> sel.cancel(true); // DtTerm behaviour + case Sel.INT_BELOW -> sel.adjust(firsta, -1, firsta + buf.nlines()); } } @@ -4211,7 +4159,7 @@ public void op_cwd(String currentWorkingDirectory) { System.out.println("op_cwd(" + currentWorkingDirectory + ")"); // NOI18N } } - + @Override public void op_ext(String command) { fireExternalCommand(command); @@ -4285,7 +4233,7 @@ public void op_time(boolean repaint) { " repaint " + n_repaint + // NOI18N " paint " + n_paint; // NOI18N - setAttribute(41); // Red Bg + setAttribute(List.of(41)); // Red Bg // can't use appendText from within ops. @@ -4298,7 +4246,7 @@ public void op_time(boolean repaint) { op_char(output2.charAt(sx)); } - setAttribute(0); + setAttribute(List.of(0)); last_time = time; n_putchar = 0; @@ -4338,7 +4286,7 @@ public void op_soft_reset() { st.setG(3, 0); resetMargins(); - setAttribute(0); + setAttribute(List.of(0)); interp.softReset(); @@ -4357,42 +4305,37 @@ public void op_full_reset() { @Override public void op_set_mode(int mode) { switch (mode) { - case 4: // insert mode + case 4 -> // insert mode st.overstrike = false; - break; - case 2: // keyboard lock - case 12: // local echo off - case 20: // newline + case 2 /* keyboard unlock */, 12 /* local echo on */, 20 /* newline */ -> { // Currently unsupported - break; + } } } @Override public void op_reset_mode(int mode) { switch (mode) { - case 4: // replace mode + case 4 -> { // replace mode st.overstrike = true; - break; - case 2: // keyboard unlock - case 12: // local echo on - case 20: // newline + } + case 2 /* keyboard unlock */, 12 /* local echo on */, 20 /* newline */ -> { // Currently unsupported - break; + } } } @Override public void op_status_report(int code) { switch (code) { - case 5: + case 5 -> { reply((char) 27 + "[0n"); // NOI18N - break; - case 6: + } + case 6 -> { reply((char) 27 + "[" + // NOI18N (st.cursor.row - st.firstx) + ";" + // NOI18N st.cursor.col + "R"); // NOI18N - break; + } } } @@ -4476,18 +4419,11 @@ public void op_ech(int n) { int to = l.cellToBuf(metrics, st.cursor.col+n-1); if (debugOps()) System.out.printf("op_ech() from %d to %d\n", from, to); // NOI18N - l.clearFromTo(Term.this, from, to, Attr.BGCOLOR.get(st.attr)); + l.clearFromTo(Term.this, from, to, st.attr.bgColorVariant()); + // Ignore Sel.INT_NONE, Sel.INT_ABOVE, Sel.INT_BELOW switch (sel.intersection(st.cursor.row)) { - case Sel.INT_NONE: - case Sel.INT_ABOVE: - case Sel.INT_BELOW: - // nothing to do - break; - case Sel.INT_ON: - case Sel.INT_STRADDLES: - sel.cancel(true); // DtTerm behaviour - break; + case Sel.INT_ON, Sel.INT_STRADDLES -> sel.cancel(true); // DtTerm behaviour } } @@ -4524,83 +4460,42 @@ private char mapChar(char inChar) { final char outChar = interp.mapACS(inChar); if (outChar == '\0') return inChar; - switch (outChar) { - default: - return inChar; - + return switch (outChar) { // xterm and gnome term don't really honor these: - case '+': // ACS_RARROW - return '\u2192'; // RIGHTWARDS ARROW - case ',': // ACS_LARROW - return '\u2190'; // LEFTWARDS ARROW - case '-': // ACS_UARROW - return '\u2191'; // UPWARDS ARROW - case '.': // ACS_DARROW - return '\u2193'; // DOWNWARDS ARROW - case '0': // ACS_BLOCK - return '\u2588'; // FULL BLOCK - - - case '`': // ACS_DIAMOND - return '\u2666'; // BLACK DIAMOND SUIT - case 'a': // ACS_CKBOARD - return '\u2592'; // MEDIUM SHADE - // return '\u2593'; // DARK SHADE - case 'b': // ? - return '\u240b'; // SYMBOL FOR VERTICAL TABULATION - case 'c': // ? - return '\u240c'; // SYMBOL FOR FORM FEED - case 'd': // ? - return '\u240d'; // SYMBOL FOR CARRIAGE RETURN - case 'e': // ? - return '\u240a'; // SYMBOL FOR LINE FEED - case 'f': // ACS_DEGREE - return '\u00b0'; // DEGREE SIGN - case 'g': // ACS_PLMINUS - return '\u00b1'; // PLUS-MINUS SIGN - case 'h': // ACS_PLMINUS - return '\u2424'; // SYMBOL FOR NEW LINE - case 'i': // ACS_LANTERN - return '\u240b'; // SYMBOL FOR VERTICAL TABULATION - case 'j': // ACS_LRCORNER - return '\u2518'; // BOX DRAWINGS LIGHT UP AND LEFT - case 'k': // ACS_LRCORNER - return '\u2510'; // BOX DRAWINGS LIGHT DOWN AND LEFT - case 'l': // ACS_LRCORNER - return '\u250c'; // BOX DRAWINGS LIGHT DOWN AND RIGHT - case 'm': // ACS_LLCORNER - return '\u2514'; // BOX DRAWINGS LIGHT UP AND RIGHT - case 'n': // ACS_PLUS - return '\u253c'; // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - case 'v': // ACS_RTEE - return '\u2534'; // BOX DRAWINGS LIGHT UP AND HORIZONTAL - case 'w': // ACS_TTEE - return '\u252c'; // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - case 'o': // ACS_S1 - case 'p': // ACS_S3 - case 'q': // ACS_HLINE - case 'r': // ACS_S7 - case 's': // ACS_S9 - return '\u2500'; // BOX DRAWINGS LIGHT HORIZONTAL - case 't': // ACS_LTEE - return '\u251c'; // BOX DRAWINGS LIGHT VERTICAL AND RIGHT - case 'u': // ACS_RTEE - return '\u2524'; // BOX DRAWINGS LIGHT VERTICAL AND LEFT - case 'x': // ACS_VLINE - return '\u2502'; // BOX DRAWINGS LIGHT VERTICAL - case 'y': // ACS_LEQUAL - return '\u2264'; // LESS-THAN OR EQUAL TO - case 'z': // ACS_GEQUAL - return '\u2265'; // GREATER-THAN OR EQUAL TO - case '{': // ACS_PI - return '\u03c0'; // GREEK SMALL LETTER PI - case '|': // ACS_NEQUAL - return '\u2260'; // NOT EQUAL TO - case '}': // ACS_STERLING - return '\u00a3'; // POUND SIGN - case '~': // ACS_BULLET - return '\u00b7'; // MIDDLE DOT - } + case '+' -> '\u2192'; // ACS_RARROW -> RIGHTWARDS ARROW + case ',' -> '\u2190'; // ACS_LARROW -> LEFTWARDS ARROW + case '-' -> '\u2191'; // ACS_UARROW -> UPWARDS ARROW + case '.' -> '\u2193'; // ACS_DARROW -> DOWNWARDS ARROW + case '0' -> '\u2588'; // ACS_BLOCK -> FULL BLOCK + case '`' -> '\u2666'; // ACS_DIAMOND -> BLACK DIAMOND SUIT + case 'a' -> '\u2592'; // ACS_CKBOARD -> MEDIUM SHADE (Alt: \u2592 DARK SHADE) + case 'b' -> '\u240b'; // ? -> SYMBOL FOR VERTICAL TABULATION + case 'c' -> '\u240c'; // ? -> SYMBOL FOR FORM FEED + case 'd' -> '\u240d'; // ? -> SYMBOL FOR CARRIAGE RETURN + case 'e' -> '\u240a'; // ? -> SYMBOL FOR LINE FEED + case 'f' -> '\u00b0'; // ACS_DEGREE -> DEGREE SIGN + case 'g' -> '\u00b1'; // ACS_PLMINUS -> PLUS-MINUS SIGN + case 'h' -> '\u2424'; // ACS_PLMINUS -> SYMBOL FOR NEW LINE + case 'i' -> '\u240b'; // ACS_LANTERN -> SYMBOL FOR VERTICAL TABULATION + case 'j' -> '\u2518'; // ACS_LRCORNER -> BOX DRAWINGS LIGHT UP AND LEFT + case 'k' -> '\u2510'; // ACS_LRCORNER -> BOX DRAWINGS LIGHT DOWN AND LEFT + case 'l' -> '\u250c'; // ACS_LRCORNER -> BOX DRAWINGS LIGHT DOWN AND RIGHT + case 'm' -> '\u2514'; // ACS_LLCORNER -> BOX DRAWINGS LIGHT UP AND RIGHT + case 'n' -> '\u253c'; // ACS_PLUS -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + case 'v' -> '\u2534'; // ACS_RTEE -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + case 'w' -> '\u252c'; // ACS_TTEE -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + case 'o', 'p', 'q', 'r', 's'-> '\u2500'; // ACS_S1, ACS_S3, ACS_HLINE, ACS_S7, ACS_S9 -> BOX DRAWINGS LIGHT HORIZONTAL + case 't' -> '\u251c'; // ACS_LTEE -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + case 'u' -> '\u2524'; // ACS_RTEE -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + case 'x' -> '\u2502'; // ACS_VLINE -> BOX DRAWINGS LIGHT VERTICAL + case 'y' -> '\u2264'; // ACS_LEQUAL -> LESS-THAN OR EQUAL TO + case 'z' -> '\u2265'; // ACS_GEQUAL -> GREATER-THAN OR EQUAL TO + case '{' -> '\u03c0'; // ACS_PI -> GREEK SMALL LETTER PI + case '|' -> '\u2260'; // ACS_NEQUAL -> NOT EQUAL TO + case '}' -> '\u00a3'; // ACS_STERLING -> POUND SIGN + case '~' -> '\u00b7'; // ACS_BULLET -> MIDDLE DOT + default -> inChar; + }; } } } @@ -5095,7 +4990,7 @@ public boolean isAnchored() { /** * Returns the actual drawing area so events can be interposed upon, * like context menus. - * @return + * @return * @deprecated Replaced by{@link #getScreen()}. */ @Deprecated @@ -5106,7 +5001,7 @@ public JComponent getCanvas() { /** * Returns the actual drawing area so events can be interposed upon, * like context menus. - * @return + * @return */ public JComponent getScreen() { return screen; @@ -5115,7 +5010,7 @@ public JComponent getScreen() { /** * Return the terminal operations implementation. * WARNING! This is temporary - * @return + * @return */ public Ops ops() { return ops; @@ -5494,7 +5389,7 @@ public int getTabSize() { return tab_size; } private int tab_size = 8; - + /** * Set select-by-word delimiters. *

@@ -5658,7 +5553,7 @@ public boolean isHorizontallyScrollable() { public final void setRenderingHints(Map hints) { renderingHints = hints; } - + /** * Clear everything and assign new text. *

@@ -5822,7 +5717,7 @@ public void columnLeft(int n) { /** * Return the cell width of the given character. * @param c - * @return + * @return */ public int charWidth(char c) { return metrics.wcwidth(c); @@ -5866,7 +5761,7 @@ public final void setFont(Font new_font) { new_font.getStyle(), new_font.getSize()); } - + super.setFont(font); // This should invalidate us, which // ultimately will cause a repaint @@ -6021,7 +5916,7 @@ public void setAccessibleName(String name) { * This function really should be private but I need it to be public for * unit-testing purposes. * @param c - * @return + * @return */ public int CoordToPosition(Coord c) { BCoord b = c.toBCoord(firsta); @@ -6045,7 +5940,7 @@ public int CoordToPosition(Coord c) { * This function really should be private but I need it to be public for * unit-testing purposes. * @param position - * @return + * @return */ public Coord PositionToCoord(int position) { int nchars = charsInPrehistory; @@ -6110,34 +6005,22 @@ Rectangle getCharacterBounds(Coord c) { return rect; } - private Color csetBG(int attr) { - final int px = Attr.backgroundColor(attr); - final Color c = palette[px]; - return c; - } - - private Color csetFG(int attr) { - final int px = Attr.foregroundColor(attr); - final Color c = palette[px]; - return c; - } - - Color backgroundColor(boolean reverse, int attr) { + Color backgroundColor(boolean reverse, Attr attr) { final Color c; if (reverse) { - c = csetFG(attr); + c = attr.getFGcolor(palette); } else { - c = csetBG(attr); + c = attr.getBGColor(palette); } return c; } - Color foregroundColor(boolean reverse, int attr) { + Color foregroundColor(boolean reverse, Attr attr) { final Color c; if (reverse) { - c = csetBG(attr); + c = attr.getBGColor(palette); } else { - c = csetFG(attr); + c = attr.getFGcolor(palette); } return c; } diff --git a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/support/FindBar.java b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/support/FindBar.java index 009b72c7cb1a..e5f1bcb6c7a5 100644 --- a/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/support/FindBar.java +++ b/ide/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/support/FindBar.java @@ -191,7 +191,7 @@ public void changedUpdate(DocumentEvent e) { adjustButton(closeButton); InputMap inputMap = getInputMap(WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_MASK), getName(prevAction)); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_DOWN_MASK), getName(prevAction)); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0), getName(nextAction)); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), getName(closeAction));