дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
Stop flipped the session back to Run as soon as the direct child exited, but a shell, Maven or the debug adapter can exit while the application it started still holds its port, so the next Run failed with "port already in use". The console also went quiet on a debug Stop because the DAP session was disconnected before java-debug drained the program's output, and closing a window killed running programs with SIGKILL at once. Run and Debug sessions now stay in a stopping state from the Stop press until the whole process group (or the debuggee's pid tree) is gone. As in IntelliJ IDEA, the first Stop only interrupts and waits, and a second Stop kills; the Stop button turns into Kill process meanwhile. A rerun or restart waits for the old process without a time limit, and the termination time limit setting now only bounds a configuration's stop command. Debug launches record the program pid from the adapter's process/processid event, signal its pid tree and keep the adapter attached until the program exits; closing a project also stops debug sessions under its root. Closing a window with running programs shows a Terminating panel with Kill process and closes once they are gone. Co-authored-by: misswell <[email protected]>
811 рядки
14 KiB
CSS
811 рядки
14 KiB
CSS
.root {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-height: 0;
|
|
min-width: 0;
|
|
}
|
|
|
|
.tabs {
|
|
min-width: 0;
|
|
border: 0;
|
|
background: none;
|
|
}
|
|
|
|
.panel {
|
|
flex: 1;
|
|
display: flex;
|
|
min-height: 0;
|
|
}
|
|
|
|
.session {
|
|
flex: 1;
|
|
display: flex;
|
|
min-height: 0;
|
|
min-width: 0;
|
|
}
|
|
|
|
.toolbar {
|
|
flex: none;
|
|
width: 32px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 2px;
|
|
padding: 4px 0;
|
|
border-right: 1px solid var(--border);
|
|
}
|
|
.toolbarSep {
|
|
width: 16px;
|
|
height: 1px;
|
|
margin: 3px 0;
|
|
background: var(--border-strong);
|
|
}
|
|
|
|
.sessionBody {
|
|
flex: 1;
|
|
display: flex;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
}
|
|
|
|
.testSplit {
|
|
flex: 1;
|
|
}
|
|
|
|
.consoleColumn {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
height: 100%;
|
|
}
|
|
|
|
.notice {
|
|
flex: none;
|
|
padding: 4px 12px;
|
|
font-size: var(--fs-small);
|
|
color: var(--fg-subtle);
|
|
border-bottom: 1px solid var(--border);
|
|
}
|
|
.noticeLink {
|
|
color: var(--link);
|
|
font-size: inherit;
|
|
cursor: pointer;
|
|
}
|
|
.noticeLink:hover {
|
|
color: var(--link-hover);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* Console */
|
|
|
|
.consoleWrap {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
}
|
|
|
|
.console {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow: auto;
|
|
position: relative;
|
|
padding: 4px 0;
|
|
font-family: var(--font-mono);
|
|
font-weight: var(--fw-code);
|
|
font-size: var(--fs-code);
|
|
color: var(--fg);
|
|
background: var(--bg-app);
|
|
-webkit-user-select: text;
|
|
user-select: text;
|
|
cursor: default;
|
|
outline: none;
|
|
contain: strict;
|
|
}
|
|
.consoleInner {
|
|
position: relative;
|
|
width: 100%;
|
|
min-width: max-content;
|
|
cursor: text;
|
|
}
|
|
.wrap .consoleInner {
|
|
min-width: 0;
|
|
}
|
|
|
|
.match {
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.line {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
min-width: 100%;
|
|
padding: 0 12px;
|
|
line-height: 20px;
|
|
white-space: pre;
|
|
tab-size: 4;
|
|
}
|
|
.wrap .line {
|
|
width: 100%;
|
|
white-space: pre-wrap;
|
|
overflow-wrap: anywhere;
|
|
}
|
|
|
|
.stdout {
|
|
color: var(--fg);
|
|
}
|
|
.stderr {
|
|
color: color-mix(in srgb, var(--danger) 88%, var(--fg));
|
|
}
|
|
.system {
|
|
color: var(--fg-subtle);
|
|
font-style: italic;
|
|
}
|
|
|
|
.link {
|
|
color: var(--link);
|
|
text-decoration: underline;
|
|
text-decoration-color: color-mix(in srgb, var(--link) 45%, transparent);
|
|
text-underline-offset: 2px;
|
|
cursor: pointer;
|
|
}
|
|
.link:hover {
|
|
color: var(--link-hover);
|
|
text-decoration-color: currentColor;
|
|
}
|
|
|
|
/* Test runner */
|
|
|
|
.testPane {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
min-width: 0;
|
|
border-right: 1px solid var(--border);
|
|
}
|
|
.testHeader {
|
|
flex: none;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
height: 28px;
|
|
padding: 0 4px 0 10px;
|
|
border-bottom: 1px solid var(--border);
|
|
font-size: var(--fs-ui);
|
|
color: var(--fg-secondary);
|
|
}
|
|
.testCounts {
|
|
display: flex;
|
|
gap: 10px;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
}
|
|
.testTree {
|
|
flex: 1;
|
|
min-height: 0;
|
|
}
|
|
.testRow {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
min-width: 0;
|
|
flex: 1;
|
|
}
|
|
.testName {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
.testDuration {
|
|
flex: none;
|
|
padding-right: 8px;
|
|
color: var(--fg-subtle);
|
|
font-family: var(--font-mono);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.testEmpty {
|
|
padding: 12px;
|
|
color: var(--fg-subtle);
|
|
font-size: var(--fs-ui);
|
|
}
|
|
|
|
.passed {
|
|
color: var(--success);
|
|
}
|
|
.failed {
|
|
color: var(--danger);
|
|
}
|
|
.skipped {
|
|
color: var(--fg-subtle);
|
|
}
|
|
|
|
.spacer {
|
|
flex: 1;
|
|
}
|
|
|
|
.kbd {
|
|
font-family: var(--font-keys);
|
|
color: var(--fg-secondary);
|
|
}
|
|
|
|
/* Title bar widget */
|
|
|
|
.widget {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
.widgetChooser {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
max-width: 260px;
|
|
height: 30px;
|
|
border-radius: 6px;
|
|
}
|
|
.widgetButton {
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 6px;
|
|
}
|
|
.widgetConfigIcon {
|
|
position: relative;
|
|
display: inline-flex;
|
|
flex: none;
|
|
}
|
|
/* Static, on the icon's top-right corner like IDEA. */
|
|
.widgetStatusDot {
|
|
position: absolute;
|
|
top: -2px;
|
|
right: -2px;
|
|
width: 7px;
|
|
height: 7px;
|
|
border-radius: 50%;
|
|
background: var(--success);
|
|
}
|
|
.widgetFilled {
|
|
/* Solid buttons need more room between them than the ghost ones. */
|
|
margin-inline: 2px;
|
|
color: var(--fg-on-accent, white);
|
|
}
|
|
.widgetFilledRun,
|
|
.widgetFilledRun:hover:not(:disabled) {
|
|
background: var(--success);
|
|
}
|
|
.widgetFilledStop,
|
|
.widgetFilledStop:hover:not(:disabled) {
|
|
background: var(--danger);
|
|
}
|
|
.widgetStopping {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0;
|
|
border: none;
|
|
line-height: 0;
|
|
background: var(--warning);
|
|
color: var(--fg-on-accent);
|
|
}
|
|
.widgetFilled:hover:not(:disabled) {
|
|
filter: brightness(0.94);
|
|
}
|
|
.widgetName {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
.widgetIcon {
|
|
color: var(--fg-subtle);
|
|
flex: none;
|
|
}
|
|
.widgetChevron {
|
|
color: var(--fg-subtle);
|
|
flex: none;
|
|
}
|
|
.widgetButtons {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
}
|
|
.widgetRun:not(:disabled) {
|
|
color: var(--success);
|
|
}
|
|
/* Configuration chooser */
|
|
|
|
.chooser {
|
|
width: 340px;
|
|
padding: 0 0 4px;
|
|
}
|
|
.chooserSearch {
|
|
padding: 6px 8px;
|
|
border-bottom: 1px solid var(--border-popup);
|
|
}
|
|
.chooserList {
|
|
height: 100%;
|
|
}
|
|
.chooserRow {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
width: 100%;
|
|
min-width: 0;
|
|
}
|
|
.chooserIcon {
|
|
flex: none;
|
|
color: var(--fg-subtle);
|
|
}
|
|
/* A running configuration: a dot on its icon. */
|
|
.chooserRunning {
|
|
position: relative;
|
|
display: inline-flex;
|
|
}
|
|
.chooserRunning::after {
|
|
content: "";
|
|
position: absolute;
|
|
right: -2px;
|
|
bottom: -1px;
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: var(--success);
|
|
box-shadow: 0 0 0 1px var(--bg-popup);
|
|
}
|
|
.chooserName {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
text-align: left;
|
|
}
|
|
.chooserSelected {
|
|
color: var(--fg-strong);
|
|
font-weight: 500;
|
|
}
|
|
.chooserMuted {
|
|
flex: none;
|
|
color: var(--fg-faint);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.chooserShortcut {
|
|
margin-left: auto;
|
|
font-family: var(--font-keys);
|
|
color: var(--fg-subtle);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.chooserEdit {
|
|
color: var(--fg-secondary);
|
|
}
|
|
/* IDEA draws temporary configurations with a translucent icon. */
|
|
.chooserTemporary {
|
|
opacity: 0.55;
|
|
}
|
|
.chooserCaption {
|
|
padding: 6px 10px 0;
|
|
color: var(--fg-secondary);
|
|
font-weight: 500;
|
|
}
|
|
.chooserMnemonic {
|
|
flex: none;
|
|
width: 8px;
|
|
color: var(--fg-subtle);
|
|
font-family: var(--font-keys);
|
|
font-size: var(--fs-small);
|
|
}
|
|
/* IDEA's popup ad text. */
|
|
.chooserHint {
|
|
padding: 4px 10px 0;
|
|
border-top: 1px solid var(--border-popup);
|
|
color: var(--fg-faint);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.chooserActions {
|
|
display: flex;
|
|
margin-right: -4px;
|
|
}
|
|
.badge {
|
|
flex: none;
|
|
padding: 0 5px;
|
|
border-radius: var(--radius-small);
|
|
background: var(--bg-control);
|
|
color: var(--fg-muted);
|
|
font-size: var(--fs-tiny);
|
|
line-height: 16px;
|
|
}
|
|
|
|
/* Edit Configurations dialog */
|
|
|
|
.editDialog {
|
|
max-width: calc(100vw - 48px);
|
|
}
|
|
.editBody {
|
|
display: flex;
|
|
height: 100%;
|
|
min-height: min(520px, calc(100vh - 200px));
|
|
}
|
|
.editSidebar {
|
|
flex: none;
|
|
width: 250px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-right: 1px solid var(--border-popup);
|
|
}
|
|
.editToolbar {
|
|
flex: none;
|
|
display: flex;
|
|
gap: 2px;
|
|
padding: 4px 6px;
|
|
border-bottom: 1px solid var(--border-popup);
|
|
}
|
|
.editList {
|
|
flex: 1;
|
|
overflow: auto;
|
|
padding: 4px 0;
|
|
}
|
|
.editGroup {
|
|
padding: 6px 12px 2px;
|
|
color: var(--fg-subtle);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.editItem {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
width: 100%;
|
|
height: var(--h-row);
|
|
padding: 0 12px 0 20px;
|
|
color: var(--fg);
|
|
font-size: var(--fs-ui);
|
|
}
|
|
.editItem:hover {
|
|
background: var(--bg-hover);
|
|
}
|
|
.editItemSelected,
|
|
.editItemSelected:hover {
|
|
background: var(--bg-selected-strong);
|
|
color: var(--fg-strong);
|
|
}
|
|
.editForm {
|
|
flex: 1;
|
|
min-width: 0;
|
|
overflow: auto;
|
|
padding: 12px 16px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
.editForm > .notice {
|
|
border: 1px solid var(--border-popup);
|
|
border-radius: var(--radius-small);
|
|
margin-bottom: 4px;
|
|
}
|
|
.field {
|
|
display: grid;
|
|
grid-template-columns: 120px 1fr;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
.fieldTop {
|
|
align-items: start;
|
|
}
|
|
.fieldTop .fieldLabel {
|
|
padding-top: 4px;
|
|
}
|
|
.fieldLabel {
|
|
color: var(--fg-secondary);
|
|
font-size: var(--fs-ui);
|
|
}
|
|
.fieldControl {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
min-width: 0;
|
|
}
|
|
.fieldError {
|
|
color: var(--danger);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.editGroupName {
|
|
color: var(--fg-strong);
|
|
}
|
|
.editEmpty {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 6px;
|
|
padding: 24px 12px;
|
|
color: var(--fg-subtle);
|
|
text-align: center;
|
|
}
|
|
.editFooterLink {
|
|
flex: none;
|
|
align-self: flex-start;
|
|
margin: 8px 12px;
|
|
}
|
|
/* Below "Edit configuration templates…". */
|
|
.editImportLink {
|
|
margin-top: 0;
|
|
}
|
|
.footerRun {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
.formHeader {
|
|
display: grid;
|
|
grid-template-columns: 1fr auto;
|
|
align-items: center;
|
|
gap: 16px;
|
|
padding-bottom: 10px;
|
|
border-bottom: 1px solid var(--border-popup);
|
|
}
|
|
.formSection {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
.formSectionTitle {
|
|
flex: 1;
|
|
font-weight: 600;
|
|
color: var(--fg-strong);
|
|
}
|
|
.formSection .noticeLink {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 2px;
|
|
}
|
|
.inputWithButton {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
}
|
|
.inputWithButton > :first-child {
|
|
flex: 1;
|
|
}
|
|
.textarea {
|
|
min-height: 72px;
|
|
padding: 6px 8px;
|
|
resize: vertical;
|
|
border: 0;
|
|
border-radius: var(--radius-control, 4px);
|
|
background: var(--bg-field, var(--bg-button));
|
|
box-shadow: inset 0 0 0 1px var(--border-button);
|
|
color: var(--fg-strong);
|
|
font-family: var(--font-mono);
|
|
font-size: var(--fs-ui);
|
|
outline: none;
|
|
}
|
|
.textarea:focus {
|
|
box-shadow: inset 0 0 0 1px var(--focus-ring);
|
|
}
|
|
.textareaInvalid {
|
|
box-shadow: inset 0 0 0 1px var(--danger);
|
|
}
|
|
.taskList {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: stretch;
|
|
gap: 4px;
|
|
}
|
|
.taskList > button:last-of-type {
|
|
align-self: flex-start;
|
|
}
|
|
.taskRow {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
min-height: var(--h-row);
|
|
}
|
|
.taskRow > :first-child {
|
|
min-width: 0;
|
|
}
|
|
.taskRow > .taskLabel,
|
|
.taskRow > input {
|
|
flex: 1;
|
|
}
|
|
.taskLabel {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
.chips {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
}
|
|
.chip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 4px;
|
|
padding: 2px 4px 2px 10px;
|
|
border-radius: 999px;
|
|
background: var(--bg-elev);
|
|
color: var(--fg);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.typeNested {
|
|
padding-left: 16px;
|
|
}
|
|
.emptyHints {
|
|
text-align: left;
|
|
color: var(--fg-subtle);
|
|
}
|
|
.emptyHints ul {
|
|
margin: 4px 0 0;
|
|
padding: 0;
|
|
list-style: none;
|
|
}
|
|
.emptyHints li::before {
|
|
content: "— ";
|
|
}
|
|
.envDialog {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
padding: 12px 16px;
|
|
}
|
|
.envPanel {
|
|
display: flex;
|
|
flex-direction: column;
|
|
border: 1px solid var(--border-popup);
|
|
border-radius: var(--radius-small);
|
|
}
|
|
.envDisabled {
|
|
opacity: 0.55;
|
|
}
|
|
.envGrid {
|
|
height: 140px;
|
|
overflow: auto;
|
|
}
|
|
.envHeader,
|
|
.envGridRow {
|
|
display: grid;
|
|
grid-template-columns: 2fr 3fr;
|
|
gap: 4px;
|
|
align-items: center;
|
|
padding: 0 8px;
|
|
min-height: var(--h-row);
|
|
}
|
|
.envHeader {
|
|
position: sticky;
|
|
top: 0;
|
|
background: var(--bg-popup, var(--bg));
|
|
color: var(--fg-subtle);
|
|
font-size: var(--fs-small);
|
|
border-bottom: 1px solid var(--border-popup);
|
|
}
|
|
.envSystemRow {
|
|
color: var(--fg-subtle);
|
|
}
|
|
.envOverridden {
|
|
text-decoration: line-through;
|
|
}
|
|
.envCell {
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
font-family: var(--font-mono);
|
|
font-size: var(--fs-small);
|
|
}
|
|
.editPreview {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
margin-top: 8px;
|
|
padding: 8px 10px;
|
|
border-radius: var(--radius-small);
|
|
background: var(--bg-elev);
|
|
}
|
|
.editPreview code {
|
|
font-family: var(--font-mono);
|
|
font-size: var(--fs-small);
|
|
color: var(--fg);
|
|
overflow-wrap: anywhere;
|
|
}
|
|
.footerError {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
color: var(--danger);
|
|
font-size: var(--fs-ui);
|
|
}
|
|
|
|
/* Editor gutter ▶ run icons */
|
|
.runGutter {
|
|
width: 14px;
|
|
}
|
|
.runGutter :global(.cm-gutterElement) {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.runMarker {
|
|
width: 14px;
|
|
height: 14px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: var(--radius-small);
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* Run dialogs (rerun confirmation, $Prompt$). */
|
|
.dialogBody {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
padding: 12px 16px;
|
|
}
|
|
|
|
/* Folded console lines ("<N internal lines>"). */
|
|
.fold {
|
|
color: var(--fg-fold-placeholder);
|
|
background: var(--bg-fold-placeholder);
|
|
border: none;
|
|
border-radius: 3px;
|
|
padding: 0 6px;
|
|
font: inherit;
|
|
cursor: pointer;
|
|
}
|
|
.fold:hover {
|
|
color: var(--fg);
|
|
}
|
|
.foldToggle {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
margin-left: 6px;
|
|
padding: 0 2px;
|
|
border: none;
|
|
border-radius: 3px;
|
|
background: none;
|
|
color: var(--fg-faint);
|
|
vertical-align: middle;
|
|
cursor: pointer;
|
|
}
|
|
.foldToggle:hover {
|
|
color: var(--fg);
|
|
background: var(--bg-fold-placeholder);
|
|
}
|
|
|
|
/* Typed console input: echoed in the same colour once sent. */
|
|
.userInput {
|
|
color: var(--ansi-green);
|
|
}
|
|
.inputCaret {
|
|
display: inline-block;
|
|
width: 1px;
|
|
height: 1.1em;
|
|
margin-left: 1px;
|
|
vertical-align: text-bottom;
|
|
background: transparent;
|
|
}
|
|
|
|
.console:focus .inputCaret {
|
|
background: var(--fg);
|
|
animation: caretBlink 1s steps(1) infinite;
|
|
}
|
|
@keyframes caretBlink {
|
|
50% {
|
|
background: transparent;
|
|
}
|
|
}
|
|
|
|
/* "Emulate terminal in output console": the terminal widget fills the console. */
|
|
.terminalConsole {
|
|
flex: 1;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
padding: 4px 0 0 8px;
|
|
background: var(--bg-island);
|
|
}
|