Skip to content

Commit 22ad862

Browse files
SougandhSlaeubi
authored andcommitted
Add configurable elapsed time display with format customization
This commit introduces a Combo selection in Console settings to choose different formatting options for elapsed time shown on the console output or disable it entirely fixes : #2112
1 parent 80176d0 commit 22ad862

File tree

7 files changed

+208
-13
lines changed

7 files changed

+208
-13
lines changed

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/DebugUIPreferenceInitializer.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2004, 2020 IBM Corporation and others.
2+
* Copyright (c) 2004, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,6 +15,7 @@
1515
package org.eclipse.debug.internal.ui;
1616

1717
import org.eclipse.core.runtime.preferences.AbstractPreferenceInitializer;
18+
import org.eclipse.debug.internal.ui.preferences.DebugPreferencesMessages;
1819
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
1920
import org.eclipse.debug.internal.ui.views.memory.MemoryViewUtil;
2021
import org.eclipse.debug.ui.IDebugUIConstants;
@@ -84,6 +85,8 @@ public void initializeDefaultPreferences() {
8485
prefs.setDefault(IDebugPreferenceConstants.CONSOLE_TAB_WIDTH, 8);
8586
prefs.setDefault(IDebugPreferenceConstants.CONSOLE_INTERPRET_CONTROL_CHARACTERS, false);
8687
prefs.setDefault(IDebugPreferenceConstants.CONSOLE_INTERPRET_CR_AS_CONTROL_CHARACTER, true);
88+
prefs.setDefault(IDebugPreferenceConstants.CONSOLE_ELAPSED_FORMAT,
89+
DebugPreferencesMessages.ConsoleDefaultElapsedTimeFormat);
8790

8891
// console colors
8992
setThemeBasedPreferences(prefs, false);

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/ConsolePreferencePage.java

Lines changed: 101 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2020 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,22 +15,32 @@
1515

1616

1717
import java.text.MessageFormat;
18+
import java.time.Duration;
19+
import java.util.Arrays;
20+
import java.util.regex.Pattern;
1821

1922
import org.eclipse.debug.internal.ui.DebugUIPlugin;
2023
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
24+
import org.eclipse.debug.internal.ui.SWTFactory;
25+
import org.eclipse.debug.internal.ui.views.console.ProcessConsole;
2126
import org.eclipse.jface.preference.BooleanFieldEditor;
2227
import org.eclipse.jface.preference.ColorFieldEditor;
2328
import org.eclipse.jface.preference.FieldEditor;
2429
import org.eclipse.jface.preference.FieldEditorPreferencePage;
2530
import org.eclipse.jface.preference.IPreferenceStore;
2631
import org.eclipse.jface.preference.IntegerFieldEditor;
2732
import org.eclipse.jface.util.PropertyChangeEvent;
33+
import org.eclipse.jface.viewers.ArrayContentProvider;
34+
import org.eclipse.jface.viewers.ComboViewer;
35+
import org.eclipse.jface.viewers.IStructuredSelection;
2836
import org.eclipse.swt.SWT;
2937
import org.eclipse.swt.events.SelectionAdapter;
3038
import org.eclipse.swt.events.SelectionEvent;
3139
import org.eclipse.swt.layout.GridData;
3240
import org.eclipse.swt.widgets.Button;
41+
import org.eclipse.swt.widgets.Combo;
3342
import org.eclipse.swt.widgets.Composite;
43+
import org.eclipse.swt.widgets.Label;
3444
import org.eclipse.ui.IWorkbench;
3545
import org.eclipse.ui.IWorkbenchPreferencePage;
3646
import org.eclipse.ui.PlatformUI;
@@ -87,6 +97,14 @@ protected void clearErrorMessage() {
8797
private BooleanFieldEditor2 fInterpretControlCharactersEditor;
8898
private BooleanFieldEditor2 fInterpretCrAsControlCharacterEditor;
8999

100+
private ComboViewer fElapsedFormat;
101+
102+
private Label fElapsedFormatPreviewLabel;
103+
104+
@SuppressWarnings("nls")
105+
private static final String[] ELAPSED_FORMATS = new String[] { "H:MM:SS", "HH:MM:SS", "HH:MM:SS.mmm", "MM:SS.mmm",
106+
"HHh MMm SSs", DebugPreferencesMessages.ConsoleDisableElapsedTime.toString() };
107+
90108
/**
91109
* Create the console page.
92110
*/
@@ -159,6 +177,40 @@ public void widgetSelected(SelectionEvent e) {
159177
addField(new BooleanFieldEditor(IDebugPreferenceConstants.CONSOLE_OPEN_ON_OUT, DebugPreferencesMessages.ConsolePreferencePage_Show__Console_View_when_there_is_program_output_3, SWT.NONE, getFieldEditorParent()));
160178
addField(new BooleanFieldEditor(IDebugPreferenceConstants.CONSOLE_OPEN_ON_ERR, DebugPreferencesMessages.ConsolePreferencePage_Show__Console_View_when_there_is_program_error_3, SWT.NONE, getFieldEditorParent()));
161179

180+
Label comboLabel = new Label(getFieldEditorParent(), SWT.NONE);
181+
comboLabel.setText(DebugPreferencesMessages.ConsoleElapsedTimeLabel);
182+
fElapsedFormat = new ComboViewer(getFieldEditorParent(), SWT.DROP_DOWN | SWT.BORDER);
183+
Combo combo = fElapsedFormat.getCombo();
184+
combo.setToolTipText(DebugPreferencesMessages.ConsoleElapsedTimeToolTip);
185+
186+
combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
187+
188+
fElapsedFormat.setContentProvider(ArrayContentProvider.getInstance());
189+
fElapsedFormat.setInput(ELAPSED_FORMATS);
190+
combo.select(selectPreferredElapsedTime());
191+
192+
fElapsedFormat.addSelectionChangedListener(event -> {
193+
if (event.getSelection() instanceof IStructuredSelection selection) {
194+
String selectedFormat = selection.getFirstElement() != null ? selection.getFirstElement().toString()
195+
: null;
196+
if (selectedFormat != null) {
197+
fElapsedFormatPreviewLabel.setText("Preview : " + processElapsedTimeFormat(selectedFormat.trim())); //$NON-NLS-1$
198+
}
199+
}
200+
201+
});
202+
combo.addModifyListener(e -> {
203+
if (validateElapsedTimeFormat(combo.getText().trim())) {
204+
fElapsedFormatPreviewLabel.setText("Preview : " + processElapsedTimeFormat(combo.getText().trim())); //$NON-NLS-1$
205+
} else {
206+
fElapsedFormatPreviewLabel.setText("Invalid format"); //$NON-NLS-1$
207+
}
208+
});
209+
210+
SWTFactory.createLabel(getFieldEditorParent(), "", 1); //$NON-NLS-1$
211+
fElapsedFormatPreviewLabel = SWTFactory.createLabel(getFieldEditorParent(),
212+
"Preview : " + processElapsedTimeFormat(combo.getText().trim()), 1); //$NON-NLS-1$
213+
162214
ColorFieldEditor sysout= new ColorFieldEditor(IDebugPreferenceConstants.CONSOLE_SYS_OUT_COLOR, DebugPreferencesMessages.ConsolePreferencePage_Standard_Out__2, getFieldEditorParent());
163215
ColorFieldEditor syserr= new ColorFieldEditor(IDebugPreferenceConstants.CONSOLE_SYS_ERR_COLOR, DebugPreferencesMessages.ConsolePreferencePage_Standard_Error__3, getFieldEditorParent());
164216
ColorFieldEditor sysin= new ColorFieldEditor(IDebugPreferenceConstants.CONSOLE_SYS_IN_COLOR, DebugPreferencesMessages.ConsolePreferencePage_Standard_In__4, getFieldEditorParent());
@@ -197,6 +249,11 @@ public boolean performOk() {
197249
int low = store.getInt(IDebugPreferenceConstants.CONSOLE_LOW_WATER_MARK);
198250
int high = low + 8000;
199251
store.setValue(IDebugPreferenceConstants.CONSOLE_HIGH_WATER_MARK, high);
252+
String elapsedTimeInput = fElapsedFormat.getCombo().getText().trim();
253+
if (validateElapsedTimeFormat(elapsedTimeInput)) {
254+
store.setValue(IDebugPreferenceConstants.CONSOLE_ELAPSED_FORMAT,
255+
elapsedTimeInput);
256+
}
200257
return ok;
201258
}
202259

@@ -266,6 +323,7 @@ protected void performDefaults() {
266323
updateWidthEditor();
267324
updateBufferSizeEditor();
268325
updateInterpretCrAsControlCharacterEditor();
326+
updateElapsedTimePreferences();
269327
}
270328

271329
protected boolean canClearErrorMessage() {
@@ -301,4 +359,46 @@ public void propertyChange(PropertyChangeEvent event) {
301359
super.propertyChange(event);
302360
}
303361
}
362+
363+
protected void updateElapsedTimePreferences() {
364+
fElapsedFormat.setInput(ELAPSED_FORMATS);
365+
fElapsedFormat.getCombo().select(0);
366+
}
367+
368+
private int selectPreferredElapsedTime() {
369+
IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
370+
String prefElapsed = store.getString(IDebugPreferenceConstants.CONSOLE_ELAPSED_FORMAT);
371+
int selectionIndex = Arrays.asList(ELAPSED_FORMATS).indexOf(prefElapsed);
372+
if (selectionIndex > -1) {
373+
return selectionIndex;
374+
}
375+
fElapsedFormat.getCombo().add(prefElapsed);
376+
return fElapsedFormat.getCombo().getItemCount() - 1;
377+
}
378+
379+
private boolean validateElapsedTimeFormat(String format) {
380+
if (format.equals(DebugPreferencesMessages.ConsoleDisableElapsedTime)) {
381+
return true;
382+
}
383+
if (format.equals("")) { //$NON-NLS-1$
384+
return false;
385+
}
386+
String matcherFormat = "^((H{1,2}:)?MM(:SS)?(\\.mmm)?|(HHh )?(MMm )?(SSs)?)$"; //$NON-NLS-1$
387+
Pattern pattern = Pattern.compile(matcherFormat);
388+
if (pattern.matcher(format).matches()) {
389+
return true;
390+
}
391+
return false;
392+
}
393+
394+
private String processElapsedTimeFormat(String format) {
395+
if (format.equals(DebugPreferencesMessages.ConsoleDisableElapsedTime)) {
396+
return "Not Available"; //$NON-NLS-1$
397+
}
398+
String dateTimeFormated = ProcessConsole.convertElapsedFormat(format);
399+
Duration elapsedTime = Duration.ofHours(1).plusMinutes(2).plusSeconds(3).plusMillis(456);
400+
String elapsedString = String.format(dateTimeFormated, elapsedTime.toHours(), elapsedTime.toMinutesPart(),
401+
elapsedTime.toSecondsPart(), elapsedTime.toMillisPart());
402+
return elapsedString;
403+
}
304404
}

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2020 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -219,4 +219,12 @@ public class DebugPreferencesMessages extends NLS {
219219
public static String RunDebugPropertiesPage_0;
220220

221221

222+
public static String ConsoleDefaultElapsedTimeFormat;
223+
224+
public static String ConsoleElapsedTimeLabel;
225+
226+
public static String ConsoleElapsedTimeToolTip;
227+
228+
public static Object ConsoleDisableElapsedTime;
229+
222230
}

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/DebugPreferencesMessages.properties

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
# Copyright (c) 2000, 2022 IBM Corporation and others.
2+
# Copyright (c) 2000, 2025 IBM Corporation and others.
33
#
44
# This program and the accompanying materials
55
# are made available under the terms of the Eclipse Public License 2.0
@@ -31,6 +31,10 @@ ConsolePreferencePage_11=Back&ground color:
3131
ConsolePreferencePage_Interpret_control_characters=Interpret ASCII &control characters
3232
ConsolePreferencePage_Interpret_cr_as_control_character=Interpret Carriage &Return (\\r) as control character
3333
ConsolePreferencePage_Enable_Word_Wrap_text=E&nable word wrap
34+
ConsoleElapsedTimeLabel=Elapsed Time Format (Choose 'None' to disable)
35+
ConsoleDefaultElapsedTimeFormat=%d:%02d:%02d
36+
ConsoleElapsedTimeToolTip=Supports formats like: 'H:MM:SS.mmm', 'MMm SSs', 'H:MM:SS' \nYou can also use positional parameters \n%1$ = (H)hours\n%2$ = (M)minutes\n%3$ = (S)seconds\n%4$ = (mmm)milliseconds
37+
ConsoleDisableElapsedTime=None
3438

3539
DebugPreferencePage_1=General Settings for Running and Debugging.
3640
DebugPreferencePage_2=Re&use editor when displaying source code

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/preferences/IDebugPreferenceConstants.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2019 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -335,6 +335,7 @@ public interface IDebugPreferenceConstants {
335335
* @since 3.8
336336
*/
337337
String DEBUG_VIEW_TOOLBAR_HIDDEN_PERSPECTIVES = "org.eclipse.debug.ui.Debug_view.debug_toolbar_hidden_perspectives"; //$NON-NLS-1$
338+
String CONSOLE_ELAPSED_FORMAT = "org.eclipse.console.elapsedTimeFormat"; //$NON-NLS-1$
338339
}
339340

340341

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/console/ConsoleMessages.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
###############################################################################
2-
# Copyright (c) 2000, 2020 IBM Corporation and others.
2+
# Copyright (c) 2000, 2025 IBM Corporation and others.
33
#
44
# This program and the accompanying materials
55
# are made available under the terms of the Eclipse Public License 2.0
@@ -25,8 +25,8 @@ ProcessConsole_0=<terminated> {0}
2525
ProcessConsole_1=[Console output redirected to file:{0}]\n
2626
ProcessConsole_2=[Invalid file specified for console output: {0}]\n
2727
ProcessConsole_3=[Invalid file specified for stdin file: {0}]\n
28-
ProcessConsole_commandLabel_withStart={0} ({1} elapsed: {2})
28+
ProcessConsole_commandLabel_withStart={0} ({1} {2})
2929
ProcessConsole_commandLabel_withEnd={0} (Terminated {1})
30-
ProcessConsole_commandLabel_withStartEnd={0} ({1} \u2013 {2} elapsed: {3})
30+
ProcessConsole_commandLabel_withStartEnd={0} ({1} \u2013 {2} {3})
3131
ShowStandardErrorAction_0=Show Console When Standard Error Changes
3232
ShowStandardOutAction_0=Show Console When Standard Out Changes

debug/org.eclipse.debug.ui/ui/org/eclipse/debug/internal/ui/views/console/ProcessConsole.java

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2020 IBM Corporation and others.
2+
* Copyright (c) 2000, 2025 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -73,6 +73,7 @@
7373
import org.eclipse.debug.internal.ui.DebugPluginImages;
7474
import org.eclipse.debug.internal.ui.DebugUIPlugin;
7575
import org.eclipse.debug.internal.ui.IDebugHelpContextIds;
76+
import org.eclipse.debug.internal.ui.preferences.DebugPreferencesMessages;
7677
import org.eclipse.debug.internal.ui.preferences.IDebugPreferenceConstants;
7778
import org.eclipse.debug.ui.DebugUITools;
7879
import org.eclipse.debug.ui.IDebugUIConstants;
@@ -347,8 +348,6 @@ protected String computeName() {
347348
}
348349

349350
DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
350-
Duration elapsedTime = Duration.between(launchTime != null ? launchTime.toInstant() : Instant.now(),
351-
terminateTime != null ? terminateTime.toInstant() : Instant.now());
352351
String elapsedFormat = "%d:%02d:%02d.%03d"; //$NON-NLS-1$
353352
if (terminateTime == null) {
354353
// refresh every second:
@@ -357,8 +356,20 @@ protected String computeName() {
357356
// pointless to update milliseconds:
358357
elapsedFormat = "%d:%02d:%02d"; //$NON-NLS-1$
359358
}
360-
String elapsedString = String.format(elapsedFormat, elapsedTime.toHours(),
361-
elapsedTime.toMinutesPart(), elapsedTime.toSecondsPart(), elapsedTime.toMillisPart());
359+
360+
IPreferenceStore store = DebugUIPlugin.getDefault().getPreferenceStore();
361+
362+
String elapsedTimeFormat = store.getString(IDebugPreferenceConstants.CONSOLE_ELAPSED_FORMAT);
363+
String elapsedString = "";//$NON-NLS-1$
364+
if (!elapsedTimeFormat.equals(DebugPreferencesMessages.ConsoleDisableElapsedTime)) {
365+
Duration elapsedTime = Duration.between(
366+
launchTime != null ? launchTime.toInstant() : Instant.now(),
367+
terminateTime != null ? terminateTime.toInstant() : Instant.now());
368+
elapsedFormat = "elapsed " + convertElapsedFormat(elapsedTimeFormat); //$NON-NLS-1$
369+
elapsedString = String.format(elapsedFormat, elapsedTime.toHours(), elapsedTime.toMinutesPart(),
370+
elapsedTime.toSecondsPart(), elapsedTime.toMillisPart());
371+
}
372+
362373
if (launchTime != null && terminateTime != null) {
363374
String launchTimeStr = dateTimeFormat.format(launchTime);
364375
// Check if process started and terminated at same day. If so only print the
@@ -1114,4 +1125,72 @@ public boolean exists() {
11141125
public String getHelpContextId() {
11151126
return IDebugHelpContextIds.PROCESS_CONSOLE;
11161127
}
1128+
1129+
@SuppressWarnings("nls")
1130+
public static String convertElapsedFormat(String humanReadable) {
1131+
humanReadable = humanReadable.trim();
1132+
1133+
StringBuilder format = new StringBuilder();
1134+
1135+
for (int i = 0; i < humanReadable.length(); i++) {
1136+
char c = humanReadable.charAt(i);
1137+
String part = switch (c) {
1138+
case 'H' -> {
1139+
if (i + 1 < humanReadable.length() && humanReadable.charAt(i + 1) == 'H') {
1140+
i++;
1141+
if (i + 1 < humanReadable.length() && humanReadable.charAt(i + 1) == 'h') {
1142+
i++;
1143+
yield "%02dh";
1144+
}
1145+
yield "%02d";
1146+
} else {
1147+
if (i + 1 < humanReadable.length() && humanReadable.charAt(i + 1) == 'h') {
1148+
i++;
1149+
yield "%dh";
1150+
}
1151+
yield "%d";
1152+
}
1153+
}
1154+
1155+
case 'M' -> {
1156+
if (i + 1 < humanReadable.length() && humanReadable.charAt(i + 1) == 'M') {
1157+
i++;
1158+
if (i + 1 < humanReadable.length() && humanReadable.charAt(i + 1) == 'm') {
1159+
i++;
1160+
yield "%02dm";
1161+
}
1162+
yield "%02d";
1163+
}
1164+
yield "";
1165+
}
1166+
1167+
case 'S' -> {
1168+
if (i + 1 < humanReadable.length() && humanReadable.charAt(i + 1) == 'S') {
1169+
i++;
1170+
if (i + 1 < humanReadable.length() && humanReadable.charAt(i + 1) == 's') {
1171+
i++;
1172+
yield "%02ds";
1173+
}
1174+
yield "%02d";
1175+
}
1176+
yield "";
1177+
}
1178+
1179+
case 'm' -> {
1180+
if (i + 2 < humanReadable.length() && humanReadable.charAt(i + 1) == 'm'
1181+
&& humanReadable.charAt(i + 2) == 'm') {
1182+
i += 2;
1183+
yield "%03d";
1184+
}
1185+
yield "";
1186+
}
1187+
1188+
default -> String.valueOf(c);
1189+
};
1190+
1191+
format.append(part);
1192+
}
1193+
1194+
return format.toString();
1195+
}
11171196
}

0 commit comments

Comments
 (0)