@happy-nut/monacori 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -22
- package/dist/app-main.js +67 -11
- package/dist/commands.js +54 -215
- package/dist/diff.js +22 -9
- package/dist/i18n.js +12 -0
- package/dist/render.d.ts +1 -1
- package/dist/render.js +12 -3
- package/dist/util.js +13 -3
- package/dist/viewer.client.js +423 -50
- package/dist/viewer.css +95 -25
- package/package.json +1 -1
package/dist/viewer.css
CHANGED
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
--token-number: #6897bb;
|
|
20
20
|
--token-literal: #cc7832;
|
|
21
21
|
--token-tag: #e8bf6a;
|
|
22
|
+
--token-function: #ffc66d;
|
|
23
|
+
--token-type: #4ec9b0;
|
|
24
|
+
--token-decorator: #bbb529;
|
|
22
25
|
--d2h-bg-color: var(--panel);
|
|
23
26
|
--d2h-border-color: var(--border);
|
|
24
27
|
--d2h-dim-color: var(--muted);
|
|
@@ -34,6 +37,33 @@
|
|
|
34
37
|
--d2h-info-bg-color: var(--line);
|
|
35
38
|
--d2h-info-color: var(--muted);
|
|
36
39
|
}
|
|
40
|
+
/* Light theme. Everything (chrome, diff2html, syntax tokens) reads these var()s, so overriding the
|
|
41
|
+
palette flips the whole UI — no per-rule light styles needed. Toggled in Settings → General, which
|
|
42
|
+
sets data-theme="light" on <html>. Palette follows GitHub Light for familiarity. */
|
|
43
|
+
:root[data-theme="light"] {
|
|
44
|
+
color-scheme: light;
|
|
45
|
+
--bg: #ffffff;
|
|
46
|
+
--panel: #f6f8fa;
|
|
47
|
+
--text: #1f2328;
|
|
48
|
+
--muted: #6e7781;
|
|
49
|
+
--border: #d0d7de;
|
|
50
|
+
--line: #eef1f4;
|
|
51
|
+
--add: #e6ffec;
|
|
52
|
+
--del: #ffebe9;
|
|
53
|
+
--add-strong: #abf2bc;
|
|
54
|
+
--del-strong: #ffc1bc;
|
|
55
|
+
--active: #0969da;
|
|
56
|
+
--sidebar: #f0f2f5;
|
|
57
|
+
--token-comment: #6e7781;
|
|
58
|
+
--token-keyword: #cf222e;
|
|
59
|
+
--token-string: #0a3069;
|
|
60
|
+
--token-number: #0550ae;
|
|
61
|
+
--token-literal: #cf222e;
|
|
62
|
+
--token-tag: #116329;
|
|
63
|
+
--token-function: #8250df;
|
|
64
|
+
--token-type: #953800;
|
|
65
|
+
--token-decorator: #6639ba;
|
|
66
|
+
}
|
|
37
67
|
* { box-sizing: border-box; }
|
|
38
68
|
html, body { margin: 0; min-height: 100%; }
|
|
39
69
|
/* Reserve the scrollbar gutter so collapsing/expanding a file does not shift the layout. */
|
|
@@ -41,13 +71,17 @@ html { scrollbar-gutter: stable; }
|
|
|
41
71
|
body {
|
|
42
72
|
display: grid;
|
|
43
73
|
grid-template-columns: var(--sidebar-width, 280px) minmax(0, 1fr);
|
|
74
|
+
/* Row 1 = content, row 2 = the integrated terminal. The terminal is a real grid row (not a fixed
|
|
75
|
+
overlay), so content shrinks above it and the caret can never scroll behind it. When the terminal
|
|
76
|
+
is .hidden (display:none) the auto row collapses to 0 and content fills the viewport. */
|
|
77
|
+
grid-template-rows: minmax(0, 1fr) auto;
|
|
78
|
+
height: 100vh;
|
|
44
79
|
background: var(--bg);
|
|
45
80
|
color: var(--text);
|
|
46
81
|
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
47
82
|
}
|
|
48
83
|
.sidebar {
|
|
49
|
-
|
|
50
|
-
top: 0;
|
|
84
|
+
grid-row: 1 / -1; /* full height, left of both the content and terminal rows */
|
|
51
85
|
height: 100vh;
|
|
52
86
|
display: flex;
|
|
53
87
|
flex-direction: column;
|
|
@@ -142,6 +176,11 @@ body {
|
|
|
142
176
|
font-size: 11px;
|
|
143
177
|
color: var(--muted);
|
|
144
178
|
}
|
|
179
|
+
/* Background-work (indexing) progress, pinned as a thin bar flush at the very bottom of the sidebar,
|
|
180
|
+
right under the version footer. Hidden when idle; the bar fills left-to-right as work completes. */
|
|
181
|
+
.footer-progress { flex: none; height: 2px; background: color-mix(in srgb, var(--muted) 16%, transparent); overflow: hidden; }
|
|
182
|
+
.footer-progress.hidden { display: none; }
|
|
183
|
+
.footer-progress-bar { height: 100%; width: 0; background: var(--active); transition: width 0.18s ease; }
|
|
145
184
|
.sidebar-footer .app-version { margin-right: auto; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
146
185
|
.app-update-flag { color: var(--active); font-weight: 600; cursor: pointer; white-space: nowrap; }
|
|
147
186
|
.settings-btn {
|
|
@@ -223,6 +262,10 @@ body {
|
|
|
223
262
|
font: 12px/1.55 ui-sans-serif, system-ui, sans-serif;
|
|
224
263
|
}
|
|
225
264
|
.settings-select:focus { outline: none; border-color: var(--active); }
|
|
265
|
+
/* The settings dropdowns are buttons (custom dropdown), not native <select> — style them to read like one. */
|
|
266
|
+
.settings-select.mc-select { text-align: left; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; min-width: 130px; }
|
|
267
|
+
.settings-select.mc-select::after { content: '▾'; margin-left: auto; opacity: 0.55; }
|
|
268
|
+
.settings-select.mc-select:hover { border-color: var(--active); }
|
|
226
269
|
.settings-actions { display: flex; align-items: center; gap: 12px; margin-top: 18px; }
|
|
227
270
|
.settings-saved { font-size: 12px; color: var(--active); }
|
|
228
271
|
.app-info-keys-h { font-weight: 600; color: var(--text); margin-bottom: 8px; }
|
|
@@ -311,7 +354,7 @@ body {
|
|
|
311
354
|
.d2h-icon { fill: var(--muted); }
|
|
312
355
|
.d2h-tag { border-color: var(--border); }
|
|
313
356
|
.d2h-files-diff { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
|
|
314
|
-
.d2h-file-side-diff { min-width: 0; width: 100%; overflow-x: auto; }
|
|
357
|
+
.d2h-file-side-diff { position: relative; min-width: 0; width: 100%; overflow-x: auto; } /* relative: the line-number cells are position:absolute, so they must scroll WITH this column inside .diff2html-container instead of staying pinned to the viewport */
|
|
315
358
|
.d2h-file-side-diff:first-child { border-right: 1px solid var(--border); }
|
|
316
359
|
.d2h-code-wrapper { width: 100%; }
|
|
317
360
|
.d2h-diff-table {
|
|
@@ -526,18 +569,19 @@ summary.tree-focus { background: var(--bg); }
|
|
|
526
569
|
.status-deleted { background: var(--del); color: #cf222e; }
|
|
527
570
|
.status-renamed { background: #fff8c5; color: #9a6700; }
|
|
528
571
|
.status-source { background: var(--line); color: var(--muted); }
|
|
529
|
-
.content { min-width: 0; padding: 0; display: flex; flex-direction: column; min-height:
|
|
572
|
+
.content { min-width: 0; padding: 0; display: flex; flex-direction: column; min-height: 0; overflow: hidden; grid-column: 2; grid-row: 1; }
|
|
530
573
|
/* Pin the diff's horizontal scrollbar to the viewport bottom instead of letting it float
|
|
531
574
|
mid-screen when a file's diff is short: fill the content column vertically so the last
|
|
532
575
|
file's diff body extends all the way down. */
|
|
533
576
|
#diff-view:not(.hidden) { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
|
|
534
|
-
#diff-view .diff2html-container { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
|
|
577
|
+
#diff-view .diff2html-container { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; overflow: auto; }
|
|
535
578
|
/* Source view mirrors the diff view: fill the content column so the source-body (its last child, after
|
|
536
579
|
the tabs + toolbar) reaches the bottom even for short files, instead of floating at the top. */
|
|
537
580
|
#source-viewer:not(.hidden) { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; }
|
|
538
581
|
.diff2html-container .d2h-wrapper { flex: 1 1 auto; display: flex; flex-direction: column; }
|
|
539
|
-
|
|
540
|
-
|
|
582
|
+
/* (removed last-file flex-fill) It forced the wrapper to the container height + overflow:hidden, which
|
|
583
|
+
froze the diff's vertical scroll — and froze the absolute line numbers at "1". The diff column now
|
|
584
|
+
scrolls naturally inside .diff2html-container. */
|
|
541
585
|
/* Slimmer scrollbars — the default overlay bars read as chunky on the dark UI. */
|
|
542
586
|
::-webkit-scrollbar { width: 9px; height: 9px; }
|
|
543
587
|
::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--muted) 32%, transparent); border-radius: 5px; }
|
|
@@ -579,9 +623,10 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
579
623
|
color: var(--muted);
|
|
580
624
|
font-size: 12px;
|
|
581
625
|
}
|
|
626
|
+
.review-status:empty { display: none; }
|
|
582
627
|
.toolbar p { margin: 4px 0 0; color: var(--muted); font-size: 12px; }
|
|
583
628
|
.empty { padding: 24px; color: var(--muted); }
|
|
584
|
-
.source-viewer { min-height:
|
|
629
|
+
.source-viewer { min-height: 0; } /* grid sizes this; a 100vh min would overflow the content row */
|
|
585
630
|
.source-toolbar { margin-bottom: 0; }
|
|
586
631
|
.source-file-meta {
|
|
587
632
|
display: flex;
|
|
@@ -664,14 +709,14 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
664
709
|
#boot-overlay {
|
|
665
710
|
position: fixed; inset: 0; z-index: 200;
|
|
666
711
|
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
|
|
667
|
-
background:
|
|
712
|
+
background: var(--bg); color: var(--muted);
|
|
668
713
|
font: 13px -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
669
714
|
transition: opacity 0.22s ease;
|
|
670
715
|
}
|
|
671
716
|
#boot-overlay.hide { opacity: 0; pointer-events: none; }
|
|
672
717
|
.boot-spinner {
|
|
673
718
|
width: 34px; height: 34px;
|
|
674
|
-
border: 3px solid
|
|
719
|
+
border: 3px solid color-mix(in srgb, var(--muted) 28%, transparent); border-top-color: var(--active); border-radius: 50%;
|
|
675
720
|
animation: boot-spin 0.8s linear infinite;
|
|
676
721
|
}
|
|
677
722
|
@keyframes boot-spin { to { transform: rotate(360deg); } }
|
|
@@ -680,7 +725,7 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
680
725
|
display: flex;
|
|
681
726
|
align-items: center;
|
|
682
727
|
justify-content: center;
|
|
683
|
-
min-height:
|
|
728
|
+
min-height: 0; /* fills the content row via flex; a 100vh-based min would overflow the grid cell */
|
|
684
729
|
font-size: 13px;
|
|
685
730
|
}
|
|
686
731
|
.source-table {
|
|
@@ -718,7 +763,7 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
718
763
|
width: 2px;
|
|
719
764
|
height: 1.25em;
|
|
720
765
|
margin: -1px -1px;
|
|
721
|
-
background: #fff
|
|
766
|
+
background: var(--text); /* themed: bright on dark, dark on light — a hardcoded #fff was invisible in light mode */
|
|
722
767
|
vertical-align: text-bottom;
|
|
723
768
|
pointer-events: none;
|
|
724
769
|
animation: cursor-blink 1.06s step-end infinite;
|
|
@@ -772,6 +817,14 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
772
817
|
}
|
|
773
818
|
/* Question vs change-request is a small colored pill on the kind label — no heavy left bar. */
|
|
774
819
|
.mc-card-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px 6px; color: var(--muted); }
|
|
820
|
+
.mc-target { margin-left: auto; font: 11px Monaco, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; color: var(--muted); opacity: 0.9; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 62%; }
|
|
821
|
+
/* While composing a comment, the textarea owns the only caret — hide the file's inline caret and the
|
|
822
|
+
cursor-row highlights (diff box-shadow + markdown/csv row tint) so attention stays on the composer. */
|
|
823
|
+
body.mc-composing .code-cursor { display: none; }
|
|
824
|
+
body.mc-composing .mc-diff-cursor-row .d2h-code-side-line { box-shadow: none; }
|
|
825
|
+
body.mc-composing .source-row.cursor-line .md-cell,
|
|
826
|
+
body.mc-composing .source-row.csv-row.cursor-line .csv-cell { background: transparent; }
|
|
827
|
+
body.mc-composing .source-row.cursor-line .num { color: inherit; }
|
|
775
828
|
.mc-kind {
|
|
776
829
|
font-weight: 700; font-size: 10px; letter-spacing: 0.05em; text-transform: uppercase;
|
|
777
830
|
padding: 2px 8px; border-radius: 999px;
|
|
@@ -805,8 +858,15 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
805
858
|
.mc-modal-panel { width: min(900px, calc(100vw - 40px)); height: 80vh; max-height: 80vh; display: grid; grid-template-rows: auto minmax(0, 1fr); border: 1px solid var(--border); border-radius: 10px; background: var(--panel); overflow: hidden; }
|
|
806
859
|
.mc-modal-head { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--border); color: var(--text); font-weight: 650; }
|
|
807
860
|
.mc-modal-head span { margin-right: auto; }
|
|
808
|
-
.mc-modal-text { width: 100%; height: 100%; box-sizing: border-box; resize: none; border: 0; padding: 12px; background: var(--bg); color: var(--text); font: 12px/1.55 Monaco, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
861
|
+
.mc-modal-text { width: 100%; height: 100%; box-sizing: border-box; resize: none; border: 0; padding: 12px; background: var(--bg); color: var(--text); caret-color: var(--text); font: 12px/1.55 Monaco, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
|
|
809
862
|
.mc-modal-text:focus { outline: none; }
|
|
863
|
+
.mc-dropdown { position: fixed; z-index: 70; min-width: 150px; background: var(--panel); border: 1px solid var(--border); border-radius: 8px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45); padding: 4px; }
|
|
864
|
+
.mc-dropdown-item { display: block; width: 100%; text-align: left; padding: 7px 12px; border: 0; background: transparent; color: var(--text); border-radius: 6px; font-size: 13px; cursor: pointer; white-space: nowrap; }
|
|
865
|
+
.mc-dropdown-item.active, .mc-dropdown-item:hover { background: var(--active); color: #fff; }
|
|
866
|
+
#mc-toasts { position: fixed; left: 16px; bottom: 16px; z-index: 80; display: flex; flex-direction: column; gap: 8px; max-width: 360px; pointer-events: none; }
|
|
867
|
+
.mc-toast { background: var(--panel); color: var(--text); border: 1px solid var(--border); border-left: 3px solid var(--active); border-radius: 8px; padding: 10px 14px; font-size: 13px; line-height: 1.45; box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4); opacity: 0; transform: translateY(8px); transition: opacity .25s ease, transform .25s ease; }
|
|
868
|
+
.mc-toast.show { opacity: 1; transform: translateY(0); }
|
|
869
|
+
.mc-toast.hide { opacity: 0; transform: translateY(8px); }
|
|
810
870
|
/* Prompt memo: split editor | live Markdown preview inside the standard modal shell. */
|
|
811
871
|
.mc-memo-body { display: grid; grid-template-columns: 1fr 1fr; min-height: 0; height: 100%; }
|
|
812
872
|
.mc-memo-edit { height: 100%; border-right: 1px solid var(--border); }
|
|
@@ -819,6 +879,9 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
819
879
|
.tok-number { color: var(--token-number); }
|
|
820
880
|
.tok-literal { color: var(--token-literal); }
|
|
821
881
|
.tok-tag { color: var(--token-tag); font-weight: 650; }
|
|
882
|
+
.tok-function { color: var(--token-function); }
|
|
883
|
+
.tok-type { color: var(--token-type); }
|
|
884
|
+
.tok-decorator { color: var(--token-decorator); font-style: italic; }
|
|
822
885
|
.quick-open {
|
|
823
886
|
position: fixed;
|
|
824
887
|
inset: 0;
|
|
@@ -920,9 +983,10 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
920
983
|
.quick-open-badge { align-self: center; color: var(--muted); font-size: 12px; }
|
|
921
984
|
.quick-open-empty { padding: 28px 14px; color: var(--muted); font-size: 13px; }
|
|
922
985
|
@media (max-width: 900px) {
|
|
923
|
-
body { grid-template-columns: 1fr; }
|
|
924
|
-
.sidebar {
|
|
925
|
-
.content { padding: 16px; }
|
|
986
|
+
body { grid-template-columns: 1fr; grid-template-rows: auto minmax(0, 1fr) auto; }
|
|
987
|
+
.sidebar { grid-row: 1; grid-column: 1; height: auto; border-right: 0; border-bottom: 1px solid var(--border); }
|
|
988
|
+
.content { grid-row: 2; grid-column: 1; padding: 16px; }
|
|
989
|
+
.terminal-panel { grid-column: 1; grid-row: 3; }
|
|
926
990
|
.toolbar { margin: -16px -16px 16px; padding: 12px 16px; }
|
|
927
991
|
.d2h-files-diff { grid-template-columns: 1fr; }
|
|
928
992
|
.d2h-file-side-diff:first-child { border-right: 0; border-bottom: 1px solid var(--border); }
|
|
@@ -1055,7 +1119,7 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
1055
1119
|
}
|
|
1056
1120
|
.md-cell > :first-child { margin-top: 0; }
|
|
1057
1121
|
.md-cell > :last-child { margin-bottom: 0; }
|
|
1058
|
-
.md-h { line-height: 1.3; margin: 0.25em 0; font-weight: 650; color:
|
|
1122
|
+
.md-h { line-height: 1.3; margin: 0.25em 0; font-weight: 650; color: var(--text); }
|
|
1059
1123
|
.md-h1 { font-size: 1.7em; }
|
|
1060
1124
|
.md-h2 { font-size: 1.4em; }
|
|
1061
1125
|
.md-h3 { font-size: 1.18em; }
|
|
@@ -1064,7 +1128,7 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
1064
1128
|
.md-p { margin: 0.2em 0; }
|
|
1065
1129
|
.md-cell a { color: var(--active); text-decoration: none; }
|
|
1066
1130
|
.md-cell a:hover { text-decoration: underline; }
|
|
1067
|
-
.md-cell strong { color:
|
|
1131
|
+
.md-cell strong { color: var(--text); }
|
|
1068
1132
|
.md-cell del { color: var(--muted); }
|
|
1069
1133
|
.md-cell code {
|
|
1070
1134
|
font: 0.86em Monaco, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
@@ -1078,6 +1142,14 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
1078
1142
|
.md-list li { margin: 0.15em 0; }
|
|
1079
1143
|
.md-hr { border: 0; border-top: 1px solid var(--border); margin: 0.5em 0; }
|
|
1080
1144
|
.md-img { max-width: 100%; border-radius: 6px; }
|
|
1145
|
+
/* Embedded raw HTML in Markdown (README <div>/<img>/<table>/…). Minimal styling so it reads sanely. */
|
|
1146
|
+
.md-html { overflow-x: auto; }
|
|
1147
|
+
.md-html img { max-width: 100%; height: auto; }
|
|
1148
|
+
.md-html table { border-collapse: collapse; margin: 0.3em 0; }
|
|
1149
|
+
.md-html th, .md-html td { border: 1px solid var(--border); padding: 4px 10px; }
|
|
1150
|
+
.md-html h1, .md-html h2, .md-html h3, .md-html h4 { margin: 0.5em 0 0.3em; line-height: 1.3; }
|
|
1151
|
+
.md-html p { margin: 0.3em 0; }
|
|
1152
|
+
.md-html [align="center"] { text-align: center; }
|
|
1081
1153
|
.md-table { border-collapse: collapse; margin: 0.3em 0; font-size: 0.92em; }
|
|
1082
1154
|
.md-table th, .md-table td { border: 1px solid var(--border); padding: 5px 11px; text-align: left; }
|
|
1083
1155
|
.md-table thead th { background: var(--line); }
|
|
@@ -1092,12 +1164,10 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
1092
1164
|
/* --- Integrated terminal panel (Electron only): fixed to the content column's bottom, height-resizable.
|
|
1093
1165
|
The active border-top marks it as the merged-prompt send target ("highlighted while it's open"). --- */
|
|
1094
1166
|
.terminal-panel {
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
bottom: 0;
|
|
1167
|
+
grid-column: 2;
|
|
1168
|
+
grid-row: 2;
|
|
1169
|
+
min-height: 0;
|
|
1099
1170
|
height: var(--terminal-height, 320px);
|
|
1100
|
-
z-index: 40;
|
|
1101
1171
|
display: flex;
|
|
1102
1172
|
flex-direction: column;
|
|
1103
1173
|
background: var(--bg);
|
|
@@ -1144,6 +1214,6 @@ h1 { margin: 0; font-size: 18px; }
|
|
|
1144
1214
|
body.terminal-send-mode .sidebar,
|
|
1145
1215
|
body.terminal-send-mode .content,
|
|
1146
1216
|
body.terminal-send-mode .sidebar-resizer { opacity: 0.25; pointer-events: none; }
|
|
1147
|
-
/*
|
|
1148
|
-
|
|
1217
|
+
/* The terminal now occupies a real grid row (see body grid-template-rows), so content shrinks above it
|
|
1218
|
+
and nothing scrolls behind it — no padding/scroll-padding hacks needed. */
|
|
1149
1219
|
.terminal-toggle.is-active { color: var(--active); }
|