Skip to content

Commit 0418be7

Browse files
feat(editor): Add "Copy Log Event" option to context menu (resolves #179). (#197)
Co-authored-by: Junhao Liao <[email protected]> Co-authored-by: Junhao Liao <[email protected]>
1 parent 7285859 commit 0418be7

File tree

3 files changed

+97
-10
lines changed

3 files changed

+97
-10
lines changed

src/components/Editor/MonacoInstance/actions.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,17 +155,18 @@ const setupCustomActions = (
155155
actions: EditorAction[],
156156
onCustomAction: CustomActionCallback
157157
) => {
158-
actions.forEach(({actionName, label, keyBindings}) => {
158+
actions.forEach(({actionName, label, keyBindings, ...rest}) => {
159159
if (null === actionName) {
160160
return;
161161
}
162162
editor.addAction({
163163
id: actionName,
164-
label: label,
165164
keybindings: keyBindings,
165+
label: label,
166166
run: () => {
167167
onCustomAction(editor, actionName);
168168
},
169+
...rest,
169170
});
170171
});
171172
};

src/components/Editor/index.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,79 @@ import {goToPositionAndCenter} from "./MonacoInstance/utils";
3939
import "./index.css";
4040

4141

42+
/**
43+
* Gets the beginning line number of the log event selected by mouse in editor.
44+
*
45+
* @param editor
46+
* @param beginLineNumToLogEventNum
47+
* @return the beginning line number of the selected log event.
48+
*/
49+
const getSelectedLogEventNum = (
50+
editor: monaco.editor.IStandaloneCodeEditor,
51+
beginLineNumToLogEventNum: BeginLineNumToLogEventNumMap
52+
): Nullable<number> => {
53+
const selectedLineNum = editor.getPosition()?.lineNumber;
54+
if ("undefined" === typeof selectedLineNum) {
55+
return null;
56+
}
57+
58+
return getMapValueWithNearestLessThanOrEqualKey(
59+
beginLineNumToLogEventNum,
60+
selectedLineNum
61+
);
62+
};
63+
64+
/**
65+
* Handles copy log event action in the editor.
66+
*
67+
* @param editor
68+
* @param beginLineNumToLogEventNum
69+
* @throws {Error} if the editor's model cannot be retrieved.
70+
*/
71+
const handleCopyLogEventAction = (
72+
editor: monaco.editor.IStandaloneCodeEditor,
73+
beginLineNumToLogEventNum: BeginLineNumToLogEventNumMap
74+
) => {
75+
const selectedLogEventNum = getSelectedLogEventNum(
76+
editor,
77+
beginLineNumToLogEventNum,
78+
);
79+
80+
if (null === selectedLogEventNum) {
81+
return;
82+
}
83+
const selectedLogEventLineNum =
84+
getMapKeyByValue(beginLineNumToLogEventNum, selectedLogEventNum);
85+
const nextLogEventLineNum =
86+
getMapKeyByValue(beginLineNumToLogEventNum, selectedLogEventNum + 1);
87+
88+
if (null === selectedLogEventLineNum) {
89+
throw new Error("Unable to get the beginning line number of the selected log event.");
90+
}
91+
92+
let endLineNumber: number;
93+
if (null !== nextLogEventLineNum) {
94+
endLineNumber = nextLogEventLineNum - 1;
95+
} else {
96+
// Handle the case when this is the last log event in the file.
97+
const model = editor.getModel();
98+
if (null === model) {
99+
throw new Error("Unable to get the text model.");
100+
}
101+
endLineNumber = model.getLineCount() - 1;
102+
}
103+
104+
const selectionRange = new monaco.Range(
105+
selectedLogEventLineNum,
106+
0,
107+
endLineNumber,
108+
Infinity
109+
);
110+
111+
editor.setSelection(selectionRange);
112+
editor.trigger(handleCopyLogEventAction.name, "editor.action.clipboardCopyAction", null);
113+
};
114+
42115
/**
43116
* Renders a read-only editor for viewing logs.
44117
*
@@ -80,6 +153,9 @@ const Editor = () => {
80153
goToPositionAndCenter(editor, {lineNumber: lineCount, column: 1});
81154
break;
82155
}
156+
case ACTION_NAME.COPY_LOG_EVENT:
157+
handleCopyLogEventAction(editor, beginLineNumToLogEventNumRef.current);
158+
break;
83159
default:
84160
break;
85161
}

src/utils/actions.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@ enum ACTION_NAME {
1212
PAGE_TOP = "pageTop",
1313
PAGE_BOTTOM = "pageBottom",
1414
RELOAD = "reload",
15+
COPY_LOG_EVENT = "copyLogEvent",
1516
}
1617

1718
interface EditorAction {
1819
actionName: Nullable<ACTION_NAME>;
19-
label: string;
20+
contextMenuGroupId?: string;
21+
contextMenuOrder?: number;
2022
keyBindings: monaco.KeyCode[];
23+
label: string;
2124
}
2225

2326
/**
@@ -27,38 +30,45 @@ interface EditorAction {
2730
const EDITOR_ACTIONS : EditorAction[] = [
2831
{
2932
actionName: null,
30-
label: "Focus on Editor",
3133
keyBindings: [monaco.KeyCode.Backquote],
34+
label: "Focus on Editor",
3235
},
3336
{
3437
actionName: ACTION_NAME.FIRST_PAGE,
35-
label: "First page",
3638
keyBindings: [monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.BracketLeft],
39+
label: "First page",
3740
},
3841
{
3942
actionName: ACTION_NAME.PREV_PAGE,
40-
label: "Previous page",
4143
keyBindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.BracketLeft],
44+
label: "Previous page",
4245
},
4346
{
4447
actionName: ACTION_NAME.NEXT_PAGE,
45-
label: "Next page",
4648
keyBindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.BracketRight],
49+
label: "Next page",
4750
},
4851
{
4952
actionName: ACTION_NAME.LAST_PAGE,
50-
label: "Last page",
5153
keyBindings: [monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.BracketRight],
54+
label: "Last page",
5255
},
5356
{
5457
actionName: ACTION_NAME.PAGE_TOP,
55-
label: "Top of page",
5658
keyBindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyU],
59+
label: "Top of page",
5760
},
5861
{
5962
actionName: ACTION_NAME.PAGE_BOTTOM,
60-
label: "Bottom of page",
6163
keyBindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyI],
64+
label: "Bottom of page",
65+
},
66+
{
67+
actionName: ACTION_NAME.COPY_LOG_EVENT,
68+
contextMenuGroupId: "9_cutcopypaste",
69+
contextMenuOrder: 2,
70+
keyBindings: [monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KeyC],
71+
label: "Copy Log Event",
6272
},
6373
];
6474

0 commit comments

Comments
 (0)