Skip to content

Commit

Permalink
Allow users to set terminal cursor style with termux.properties
Browse files Browse the repository at this point in the history
This `terminal-cursor-style` key can be used to set the terminal cursor style. The user can set a string value to `block` for `■`, `underline` for `_` or `bar` for `|` cursor style. The default value is still `block`. So adding an entry like `terminal-cursor-style=bar` to `termux.properties` file will allow users to change to the `bar` cursor style. After updating the value, termux must be restarted. You can also run `termux-reload-settings` command so that termux loads the updated value, but only new sessions will use the updated value, existing sessions will not be affected unless you Reset them from terminal's long hold options menu `More` -> `Reset` or restart termux activity after double back press to exit.

You can temporarily switch to different cursor styles with (or add to `.bashrc` but resetting will restore default `bar` style):

- block: `echo -e "\033[2 q"`
- underline: `echo -e "\033[4 q"`
- bar: ` echo -e "\033[6 q"`

Closes #2075
  • Loading branch information
agnostic-apollo committed Jun 10, 2021
1 parent 0b4bbaf commit f545ebf
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,13 @@ public void onTerminalCursorStateChange(boolean enabled) {



@Override
public Integer getTerminalCursorStyle() {
return mActivity.getProperties().getTerminalCursorStyle();
}



/** Initialize and get mBellSoundPool */
private synchronized SoundPool getBellSoundPool() {
if (mBellSoundPool == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,6 @@ public final class TerminalEmulator {
public static final int MOUSE_WHEELUP_BUTTON = 64;
public static final int MOUSE_WHEELDOWN_BUTTON = 65;

public static final int CURSOR_STYLE_BLOCK = 0;
public static final int CURSOR_STYLE_UNDERLINE = 1;
public static final int CURSOR_STYLE_BAR = 2;

/** Used for invalid data - http:https://en.wikipedia.org/wiki/Replacement_character#Replacement_character */
public static final int UNICODE_REPLACEMENT_CHAR = 0xFFFD;

Expand Down Expand Up @@ -126,14 +122,14 @@ public final class TerminalEmulator {
/** Not really DECSET bit... - http:https://www.vt100.net/docs/vt510-rm/DECSACE */
private static final int DECSET_BIT_RECTANGULAR_CHANGEATTRIBUTE = 1 << 12;


private String mTitle;
private final Stack<String> mTitleStack = new Stack<>();


/** The cursor position. Between (0,0) and (mRows-1, mColumns-1). */
private int mCursorRow, mCursorCol;

private int mCursorStyle = CURSOR_STYLE_BLOCK;

/** The number of character rows and columns in the terminal screen. */
public int mRows, mColumns;

Expand All @@ -142,6 +138,19 @@ public final class TerminalEmulator {
public static final int TERMINAL_TRANSCRIPT_ROWS_MAX = 50000;
public static final int DEFAULT_TERMINAL_TRANSCRIPT_ROWS = 2000;


/* The supported terminal cursor styles. */

public static final int TERMINAL_CURSOR_STYLE_BLOCK = 0;
public static final int TERMINAL_CURSOR_STYLE_UNDERLINE = 1;
public static final int TERMINAL_CURSOR_STYLE_BAR = 2;
public static final int DEFAULT_TERMINAL_CURSOR_STYLE = TERMINAL_CURSOR_STYLE_BLOCK;
public static final Integer[] TERMINAL_CURSOR_STYLES_LIST = new Integer[]{TERMINAL_CURSOR_STYLE_BLOCK, TERMINAL_CURSOR_STYLE_UNDERLINE, TERMINAL_CURSOR_STYLE_BAR};

/** The terminal cursor styles. */
private int mCursorStyle = DEFAULT_TERMINAL_CURSOR_STYLE;


/** The normal screen buffer. Stores the characters that appear on the screen of the emulated terminal. */
private final TerminalBuffer mMainBuffer;
/**
Expand Down Expand Up @@ -312,6 +321,7 @@ public TerminalEmulator(TerminalOutput session, int columns, int rows, Integer t

public void updateTerminalSessionClient(TerminalSessionClient client) {
mClient = client;
setCursorStyle();
}

public TerminalBuffer getScreen() {
Expand Down Expand Up @@ -396,11 +406,24 @@ public int getCursorCol() {
return mCursorCol;
}

/** {@link #CURSOR_STYLE_BAR}, {@link #CURSOR_STYLE_BLOCK} or {@link #CURSOR_STYLE_UNDERLINE} */
/** Get the terminal cursor style. It will be one of {@link #TERMINAL_CURSOR_STYLES_LIST} */
public int getCursorStyle() {
return mCursorStyle;
}

/** Set the terminal cursor style. */
public void setCursorStyle() {
Integer cursorStyle = null;

if (mClient != null)
cursorStyle = mClient.getTerminalCursorStyle();

if (cursorStyle == null || !Arrays.asList(TERMINAL_CURSOR_STYLES_LIST).contains(cursorStyle))
mCursorStyle = DEFAULT_TERMINAL_CURSOR_STYLE;
else
mCursorStyle = cursorStyle;
}

public boolean isReverseVideo() {
return isDecsetInternalBitSet(DECSET_BIT_REVERSE_VIDEO);
}
Expand Down Expand Up @@ -818,15 +841,15 @@ public void processCodePoint(int b) {
case 0: // Blinking block.
case 1: // Blinking block.
case 2: // Steady block.
mCursorStyle = CURSOR_STYLE_BLOCK;
mCursorStyle = TERMINAL_CURSOR_STYLE_BLOCK;
break;
case 3: // Blinking underline.
case 4: // Steady underline.
mCursorStyle = CURSOR_STYLE_UNDERLINE;
mCursorStyle = TERMINAL_CURSOR_STYLE_UNDERLINE;
break;
case 5: // Blinking bar (xterm addition).
case 6: // Steady bar (xterm addition).
mCursorStyle = CURSOR_STYLE_BAR;
mCursorStyle = TERMINAL_CURSOR_STYLE_BAR;
break;
}
break;
Expand Down Expand Up @@ -2342,7 +2365,7 @@ public void clearScrollCounter() {

/** Reset terminal state so user can interact with it regardless of present state. */
public void reset() {
mCursorStyle = CURSOR_STYLE_BLOCK;
setCursorStyle();
mArgIndex = 0;
mContinueSequence = false;
mEscapeState = ESC_NONE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public interface TerminalSessionClient {
void onTerminalCursorStateChange(boolean state);



Integer getTerminalCursorStyle();



void logError(String tag, String message);

void logWarn(String tag, String message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,23 @@ public void testDeviceStatusReport() throws Exception {
/** Test the cursor shape changes using DECSCUSR. */
public void testSetCursorStyle() throws Exception {
withTerminalSized(5, 5);
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
enterString("\033[3 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
enterString("\033[5 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
enterString("\033[0 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
enterString("\033[6 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
enterString("\033[4 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
enterString("\033[1 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
enterString("\033[4 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
enterString("\033[2 q");
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
}

public void testPaste() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,8 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int
if (cursor != 0) {
mTextPaint.setColor(cursor);
float cursorHeight = mFontLineSpacingAndAscent - mFontAscent;
if (cursorStyle == TerminalEmulator.CURSOR_STYLE_UNDERLINE) cursorHeight /= 4.;
else if (cursorStyle == TerminalEmulator.CURSOR_STYLE_BAR) right -= ((right - left) * 3) / 4.;
if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE) cursorHeight /= 4.;
else if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR) right -= ((right - left) * 3) / 4.;
canvas.drawRect(left, y - cursorHeight, right, y, mTextPaint);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.Set;

/*
* Version: v0.11.0
* Version: v0.12.0
*
* Changelog
*
Expand Down Expand Up @@ -53,6 +53,8 @@
* - 0.11.0 (2021-06-10)
* - Add `*KEY_TERMINAL_TRANSCRIPT_ROWS*`.
*
* - 0.12.0 (2021-06-10)
* - Add `*KEY_TERMINAL_CURSOR_STYLE*`.
*/

/**
Expand Down Expand Up @@ -135,6 +137,28 @@ public final class TermuxPropertyConstants {



/** Defines the key for the terminal cursor style */
public static final String KEY_TERMINAL_CURSOR_STYLE = "terminal-cursor-style"; // Default: "terminal-cursor-style"

public static final String VALUE_TERMINAL_CURSOR_STYLE_BLOCK = "block";
public static final String VALUE_TERMINAL_CURSOR_STYLE_UNDERLINE = "underline";
public static final String VALUE_TERMINAL_CURSOR_STYLE_BAR = "bar";

public static final int IVALUE_TERMINAL_CURSOR_STYLE_BLOCK = TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK;
public static final int IVALUE_TERMINAL_CURSOR_STYLE_UNDERLINE = TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE;
public static final int IVALUE_TERMINAL_CURSOR_STYLE_BAR = TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR;
public static final int DEFAULT_IVALUE_TERMINAL_CURSOR_STYLE = TerminalEmulator.DEFAULT_TERMINAL_CURSOR_STYLE;

/** Defines the bidirectional map for terminal cursor styles and their internal values */
public static final ImmutableBiMap<String, Integer> MAP_TERMINAL_CURSOR_STYLE =
new ImmutableBiMap.Builder<String, Integer>()
.put(VALUE_TERMINAL_CURSOR_STYLE_BLOCK, IVALUE_TERMINAL_CURSOR_STYLE_BLOCK)
.put(VALUE_TERMINAL_CURSOR_STYLE_UNDERLINE, IVALUE_TERMINAL_CURSOR_STYLE_UNDERLINE)
.put(VALUE_TERMINAL_CURSOR_STYLE_BAR, IVALUE_TERMINAL_CURSOR_STYLE_BAR)
.build();



/** Defines the key for the terminal transcript rows */
public static final String KEY_TERMINAL_TRANSCRIPT_ROWS = "terminal-transcript-rows"; // Default: "terminal-transcript-rows"
public static final int IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN = TerminalEmulator.TERMINAL_TRANSCRIPT_ROWS_MIN;
Expand Down Expand Up @@ -271,6 +295,7 @@ public final class TermuxPropertyConstants {
/* int */
KEY_BELL_BEHAVIOUR,
KEY_TERMINAL_CURSOR_BLINK_RATE,
KEY_TERMINAL_CURSOR_STYLE,
KEY_TERMINAL_TRANSCRIPT_ROWS,

/* float */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ public static Object getInternalTermuxPropertyValueFromValue(Context context, St
return (int) getBellBehaviourInternalPropertyValueFromValue(value);
case TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE:
return (int) getTerminalCursorBlinkRateInternalPropertyValueFromValue(value);
case TermuxPropertyConstants.KEY_TERMINAL_CURSOR_STYLE:
return (int) getTerminalCursorStyleInternalPropertyValueFromValue(value);
case TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS:
return (int) getTerminalTranscriptRowsInternalPropertyValueFromValue(value);

Expand Down Expand Up @@ -277,7 +279,7 @@ public static boolean getUseBlackUIInternalPropertyValueFromValue(Context contex
/**
* Returns the internal value after mapping it based on
* {@code TermuxPropertyConstants#MAP_BELL_BEHAVIOUR} if the value is not {@code null}
* and is valid, otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_BELL_BEHAVIOUR}.
* and is valid, otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_BELL_BEHAVIOUR}.
*
* @param value The {@link String} value to convert.
* @return Returns the internal value for value.
Expand All @@ -288,14 +290,14 @@ public static int getBellBehaviourInternalPropertyValueFromValue(String value) {

/**
* Returns the int for the value if its not null and is between
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN} and
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX},
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE}.
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN} and
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX},
* otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE}.
*
* @param value The {@link String} value to convert.
* @return Returns the internal value for value.
*/
public static float getTerminalCursorBlinkRateInternalPropertyValueFromValue(String value) {
public static int getTerminalCursorBlinkRateInternalPropertyValueFromValue(String value) {
return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE,
DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE),
TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE,
Expand All @@ -304,16 +306,28 @@ public static float getTerminalCursorBlinkRateInternalPropertyValueFromValue(Str
true, true, LOG_TAG);
}

/**
* Returns the internal value after mapping it based on
* {@link TermuxPropertyConstants#MAP_TERMINAL_CURSOR_STYLE} if the value is not {@code null}
* and is valid, otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_STYLE}.
*
* @param value The {@link String} value to convert.
* @return Returns the internal value for value.
*/
public static int getTerminalCursorStyleInternalPropertyValueFromValue(String value) {
return (int) SharedProperties.getDefaultIfNotInMap(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_STYLE, TermuxPropertyConstants.MAP_TERMINAL_CURSOR_STYLE, SharedProperties.toLowerCase(value), TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_STYLE, true, LOG_TAG);
}

/**
* Returns the int for the value if its not null and is between
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN} and
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MAX},
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS}.
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN} and
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MAX},
* otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS}.
*
* @param value The {@link String} value to convert.
* @return Returns the internal value for value.
*/
public static float getTerminalTranscriptRowsInternalPropertyValueFromValue(String value) {
public static int getTerminalTranscriptRowsInternalPropertyValueFromValue(String value) {
return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS,
DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS),
TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS,
Expand All @@ -324,9 +338,9 @@ public static float getTerminalTranscriptRowsInternalPropertyValueFromValue(Stri

/**
* Returns the int for the value if its not null and is between
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX},
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR}.
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX},
* otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR}.
*
* @param value The {@link String} value to convert.
* @return Returns the internal value for value.
Expand Down Expand Up @@ -478,6 +492,10 @@ public int getTerminalCursorBlinkRate() {
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE, true);
}

public int getTerminalCursorStyle() {
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_STYLE, true);
}

public int getTerminalTranscriptRows() {
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ public void onTerminalCursorStateChange(boolean state) {



@Override
public Integer getTerminalCursorStyle() {
return null;
}



@Override
public void logError(String tag, String message) {
Logger.logError(tag, message);
Expand Down

0 comments on commit f545ebf

Please sign in to comment.