Skip to content

Commit f545ebf

Browse files
Allow users to set terminal cursor style with termux.properties
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
1 parent 0b4bbaf commit f545ebf

File tree

8 files changed

+120
-35
lines changed

8 files changed

+120
-35
lines changed

app/src/main/java/com/termux/app/terminal/TermuxTerminalSessionClient.java

+7
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,13 @@ public void onTerminalCursorStateChange(boolean enabled) {
207207

208208

209209

210+
@Override
211+
public Integer getTerminalCursorStyle() {
212+
return mActivity.getProperties().getTerminalCursorStyle();
213+
}
214+
215+
216+
210217
/** Initialize and get mBellSoundPool */
211218
private synchronized SoundPool getBellSoundPool() {
212219
if (mBellSoundPool == null) {

terminal-emulator/src/main/java/com/termux/terminal/TerminalEmulator.java

+34-11
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,6 @@ public final class TerminalEmulator {
3838
public static final int MOUSE_WHEELUP_BUTTON = 64;
3939
public static final int MOUSE_WHEELDOWN_BUTTON = 65;
4040

41-
public static final int CURSOR_STYLE_BLOCK = 0;
42-
public static final int CURSOR_STYLE_UNDERLINE = 1;
43-
public static final int CURSOR_STYLE_BAR = 2;
44-
4541
/** Used for invalid data - http://en.wikipedia.org/wiki/Replacement_character#Replacement_character */
4642
public static final int UNICODE_REPLACEMENT_CHAR = 0xFFFD;
4743

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

125+
129126
private String mTitle;
130127
private final Stack<String> mTitleStack = new Stack<>();
131128

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

135-
private int mCursorStyle = CURSOR_STYLE_BLOCK;
136-
137133
/** The number of character rows and columns in the terminal screen. */
138134
public int mRows, mColumns;
139135

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

141+
142+
/* The supported terminal cursor styles. */
143+
144+
public static final int TERMINAL_CURSOR_STYLE_BLOCK = 0;
145+
public static final int TERMINAL_CURSOR_STYLE_UNDERLINE = 1;
146+
public static final int TERMINAL_CURSOR_STYLE_BAR = 2;
147+
public static final int DEFAULT_TERMINAL_CURSOR_STYLE = TERMINAL_CURSOR_STYLE_BLOCK;
148+
public static final Integer[] TERMINAL_CURSOR_STYLES_LIST = new Integer[]{TERMINAL_CURSOR_STYLE_BLOCK, TERMINAL_CURSOR_STYLE_UNDERLINE, TERMINAL_CURSOR_STYLE_BAR};
149+
150+
/** The terminal cursor styles. */
151+
private int mCursorStyle = DEFAULT_TERMINAL_CURSOR_STYLE;
152+
153+
145154
/** The normal screen buffer. Stores the characters that appear on the screen of the emulated terminal. */
146155
private final TerminalBuffer mMainBuffer;
147156
/**
@@ -312,6 +321,7 @@ public TerminalEmulator(TerminalOutput session, int columns, int rows, Integer t
312321

313322
public void updateTerminalSessionClient(TerminalSessionClient client) {
314323
mClient = client;
324+
setCursorStyle();
315325
}
316326

317327
public TerminalBuffer getScreen() {
@@ -396,11 +406,24 @@ public int getCursorCol() {
396406
return mCursorCol;
397407
}
398408

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

414+
/** Set the terminal cursor style. */
415+
public void setCursorStyle() {
416+
Integer cursorStyle = null;
417+
418+
if (mClient != null)
419+
cursorStyle = mClient.getTerminalCursorStyle();
420+
421+
if (cursorStyle == null || !Arrays.asList(TERMINAL_CURSOR_STYLES_LIST).contains(cursorStyle))
422+
mCursorStyle = DEFAULT_TERMINAL_CURSOR_STYLE;
423+
else
424+
mCursorStyle = cursorStyle;
425+
}
426+
404427
public boolean isReverseVideo() {
405428
return isDecsetInternalBitSet(DECSET_BIT_REVERSE_VIDEO);
406429
}
@@ -818,15 +841,15 @@ public void processCodePoint(int b) {
818841
case 0: // Blinking block.
819842
case 1: // Blinking block.
820843
case 2: // Steady block.
821-
mCursorStyle = CURSOR_STYLE_BLOCK;
844+
mCursorStyle = TERMINAL_CURSOR_STYLE_BLOCK;
822845
break;
823846
case 3: // Blinking underline.
824847
case 4: // Steady underline.
825-
mCursorStyle = CURSOR_STYLE_UNDERLINE;
848+
mCursorStyle = TERMINAL_CURSOR_STYLE_UNDERLINE;
826849
break;
827850
case 5: // Blinking bar (xterm addition).
828851
case 6: // Steady bar (xterm addition).
829-
mCursorStyle = CURSOR_STYLE_BAR;
852+
mCursorStyle = TERMINAL_CURSOR_STYLE_BAR;
830853
break;
831854
}
832855
break;
@@ -2342,7 +2365,7 @@ public void clearScrollCounter() {
23422365

23432366
/** Reset terminal state so user can interact with it regardless of present state. */
23442367
public void reset() {
2345-
mCursorStyle = CURSOR_STYLE_BLOCK;
2368+
setCursorStyle();
23462369
mArgIndex = 0;
23472370
mContinueSequence = false;
23482371
mEscapeState = ESC_NONE;

terminal-emulator/src/main/java/com/termux/terminal/TerminalSessionClient.java

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public interface TerminalSessionClient {
2222
void onTerminalCursorStateChange(boolean state);
2323

2424

25+
26+
Integer getTerminalCursorStyle();
27+
28+
29+
2530
void logError(String tag, String message);
2631

2732
void logWarn(String tag, String message);

terminal-emulator/src/test/java/com/termux/terminal/TerminalTest.java

+9-9
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,23 @@ public void testDeviceStatusReport() throws Exception {
103103
/** Test the cursor shape changes using DECSCUSR. */
104104
public void testSetCursorStyle() throws Exception {
105105
withTerminalSized(5, 5);
106-
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
106+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
107107
enterString("\033[3 q");
108-
assertEquals(TerminalEmulator.CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
108+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
109109
enterString("\033[5 q");
110-
assertEquals(TerminalEmulator.CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
110+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
111111
enterString("\033[0 q");
112-
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
112+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
113113
enterString("\033[6 q");
114-
assertEquals(TerminalEmulator.CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
114+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR, mTerminal.getCursorStyle());
115115
enterString("\033[4 q");
116-
assertEquals(TerminalEmulator.CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
116+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
117117
enterString("\033[1 q");
118-
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
118+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
119119
enterString("\033[4 q");
120-
assertEquals(TerminalEmulator.CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
120+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE, mTerminal.getCursorStyle());
121121
enterString("\033[2 q");
122-
assertEquals(TerminalEmulator.CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
122+
assertEquals(TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK, mTerminal.getCursorStyle());
123123
}
124124

125125
public void testPaste() {

terminal-view/src/main/java/com/termux/view/TerminalRenderer.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,8 @@ private void drawTextRun(Canvas canvas, char[] text, int[] palette, float y, int
200200
if (cursor != 0) {
201201
mTextPaint.setColor(cursor);
202202
float cursorHeight = mFontLineSpacingAndAscent - mFontAscent;
203-
if (cursorStyle == TerminalEmulator.CURSOR_STYLE_UNDERLINE) cursorHeight /= 4.;
204-
else if (cursorStyle == TerminalEmulator.CURSOR_STYLE_BAR) right -= ((right - left) * 3) / 4.;
203+
if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE) cursorHeight /= 4.;
204+
else if (cursorStyle == TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR) right -= ((right - left) * 3) / 4.;
205205
canvas.drawRect(left, y - cursorHeight, right, y, mTextPaint);
206206
}
207207

termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java

+26-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import java.util.Set;
1313

1414
/*
15-
* Version: v0.11.0
15+
* Version: v0.12.0
1616
*
1717
* Changelog
1818
*
@@ -53,6 +53,8 @@
5353
* - 0.11.0 (2021-06-10)
5454
* - Add `*KEY_TERMINAL_TRANSCRIPT_ROWS*`.
5555
*
56+
* - 0.12.0 (2021-06-10)
57+
* - Add `*KEY_TERMINAL_CURSOR_STYLE*`.
5658
*/
5759

5860
/**
@@ -135,6 +137,28 @@ public final class TermuxPropertyConstants {
135137

136138

137139

140+
/** Defines the key for the terminal cursor style */
141+
public static final String KEY_TERMINAL_CURSOR_STYLE = "terminal-cursor-style"; // Default: "terminal-cursor-style"
142+
143+
public static final String VALUE_TERMINAL_CURSOR_STYLE_BLOCK = "block";
144+
public static final String VALUE_TERMINAL_CURSOR_STYLE_UNDERLINE = "underline";
145+
public static final String VALUE_TERMINAL_CURSOR_STYLE_BAR = "bar";
146+
147+
public static final int IVALUE_TERMINAL_CURSOR_STYLE_BLOCK = TerminalEmulator.TERMINAL_CURSOR_STYLE_BLOCK;
148+
public static final int IVALUE_TERMINAL_CURSOR_STYLE_UNDERLINE = TerminalEmulator.TERMINAL_CURSOR_STYLE_UNDERLINE;
149+
public static final int IVALUE_TERMINAL_CURSOR_STYLE_BAR = TerminalEmulator.TERMINAL_CURSOR_STYLE_BAR;
150+
public static final int DEFAULT_IVALUE_TERMINAL_CURSOR_STYLE = TerminalEmulator.DEFAULT_TERMINAL_CURSOR_STYLE;
151+
152+
/** Defines the bidirectional map for terminal cursor styles and their internal values */
153+
public static final ImmutableBiMap<String, Integer> MAP_TERMINAL_CURSOR_STYLE =
154+
new ImmutableBiMap.Builder<String, Integer>()
155+
.put(VALUE_TERMINAL_CURSOR_STYLE_BLOCK, IVALUE_TERMINAL_CURSOR_STYLE_BLOCK)
156+
.put(VALUE_TERMINAL_CURSOR_STYLE_UNDERLINE, IVALUE_TERMINAL_CURSOR_STYLE_UNDERLINE)
157+
.put(VALUE_TERMINAL_CURSOR_STYLE_BAR, IVALUE_TERMINAL_CURSOR_STYLE_BAR)
158+
.build();
159+
160+
161+
138162
/** Defines the key for the terminal transcript rows */
139163
public static final String KEY_TERMINAL_TRANSCRIPT_ROWS = "terminal-transcript-rows"; // Default: "terminal-transcript-rows"
140164
public static final int IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN = TerminalEmulator.TERMINAL_TRANSCRIPT_ROWS_MIN;
@@ -271,6 +295,7 @@ public final class TermuxPropertyConstants {
271295
/* int */
272296
KEY_BELL_BEHAVIOUR,
273297
KEY_TERMINAL_CURSOR_BLINK_RATE,
298+
KEY_TERMINAL_CURSOR_STYLE,
274299
KEY_TERMINAL_TRANSCRIPT_ROWS,
275300

276301
/* float */

termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java

+30-12
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ public static Object getInternalTermuxPropertyValueFromValue(Context context, St
217217
return (int) getBellBehaviourInternalPropertyValueFromValue(value);
218218
case TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE:
219219
return (int) getTerminalCursorBlinkRateInternalPropertyValueFromValue(value);
220+
case TermuxPropertyConstants.KEY_TERMINAL_CURSOR_STYLE:
221+
return (int) getTerminalCursorStyleInternalPropertyValueFromValue(value);
220222
case TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS:
221223
return (int) getTerminalTranscriptRowsInternalPropertyValueFromValue(value);
222224

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

289291
/**
290292
* Returns the int for the value if its not null and is between
291-
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN} and
292-
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX},
293-
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE}.
293+
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN} and
294+
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX},
295+
* otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE}.
294296
*
295297
* @param value The {@link String} value to convert.
296298
* @return Returns the internal value for value.
297299
*/
298-
public static float getTerminalCursorBlinkRateInternalPropertyValueFromValue(String value) {
300+
public static int getTerminalCursorBlinkRateInternalPropertyValueFromValue(String value) {
299301
return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE,
300302
DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE),
301303
TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE,
@@ -304,16 +306,28 @@ public static float getTerminalCursorBlinkRateInternalPropertyValueFromValue(Str
304306
true, true, LOG_TAG);
305307
}
306308

309+
/**
310+
* Returns the internal value after mapping it based on
311+
* {@link TermuxPropertyConstants#MAP_TERMINAL_CURSOR_STYLE} if the value is not {@code null}
312+
* and is valid, otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_STYLE}.
313+
*
314+
* @param value The {@link String} value to convert.
315+
* @return Returns the internal value for value.
316+
*/
317+
public static int getTerminalCursorStyleInternalPropertyValueFromValue(String value) {
318+
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);
319+
}
320+
307321
/**
308322
* Returns the int for the value if its not null and is between
309-
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN} and
310-
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MAX},
311-
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS}.
323+
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MIN} and
324+
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TRANSCRIPT_ROWS_MAX},
325+
* otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS}.
312326
*
313327
* @param value The {@link String} value to convert.
314328
* @return Returns the internal value for value.
315329
*/
316-
public static float getTerminalTranscriptRowsInternalPropertyValueFromValue(String value) {
330+
public static int getTerminalTranscriptRowsInternalPropertyValueFromValue(String value) {
317331
return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS,
318332
DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS),
319333
TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TRANSCRIPT_ROWS,
@@ -324,9 +338,9 @@ public static float getTerminalTranscriptRowsInternalPropertyValueFromValue(Stri
324338

325339
/**
326340
* Returns the int for the value if its not null and is between
327-
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and
328-
* {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX},
329-
* otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR}.
341+
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and
342+
* {@link TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX},
343+
* otherwise returns {@link TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR}.
330344
*
331345
* @param value The {@link String} value to convert.
332346
* @return Returns the internal value for value.
@@ -478,6 +492,10 @@ public int getTerminalCursorBlinkRate() {
478492
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE, true);
479493
}
480494

495+
public int getTerminalCursorStyle() {
496+
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_STYLE, true);
497+
}
498+
481499
public int getTerminalTranscriptRows() {
482500
return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TRANSCRIPT_ROWS, true);
483501
}

termux-shared/src/main/java/com/termux/shared/terminal/TermuxTerminalSessionClientBase.java

+7
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ public void onTerminalCursorStateChange(boolean state) {
3939

4040

4141

42+
@Override
43+
public Integer getTerminalCursorStyle() {
44+
return null;
45+
}
46+
47+
48+
4249
@Override
4350
public void logError(String tag, String message) {
4451
Logger.logError(tag, message);

0 commit comments

Comments
 (0)