@@ -37,6 +37,10 @@ enum ManimShellEvent {
37
37
IPYTHON_CELL_FINISHED = 'ipythonCellFinished' ,
38
38
}
39
39
40
+ const MAC_OS_MULTIPLE_COMMANDS_ERROR = `On MacOS, we don't support running`
41
+ + ` multiple Manim commands at the same time. Please wait until the`
42
+ + ` current command has finished.` ;
43
+
40
44
/**
41
45
* Wrapper around the IPython terminal that ManimGL uses. Ensures that commands
42
46
* are executed at the right place and spans a new Manim session if necessary.
@@ -61,6 +65,15 @@ export class ManimShell {
61
65
*/
62
66
private lockDuringStartup = false ;
63
67
68
+ /**
69
+ * Whether to lock the execution of a new command while another command is
70
+ * currently running. On MacOS, we do lock since the IPython terminal *exits*
71
+ * when sending Ctrl+C instead of just interrupting the current command.
72
+ * See issue #16: https://github.com/bhoov/manim-notebook/issues/16
73
+ */
74
+ private shouldLockDuringCommandExecution = false ;
75
+ private isExecutingCommand = false ;
76
+
64
77
/**
65
78
* Whether to detect the end of a shell execution.
66
79
*
@@ -78,6 +91,11 @@ export class ManimShell {
78
91
79
92
private constructor ( ) {
80
93
this . initiateTerminalDataReading ( ) ;
94
+
95
+ // on MacOS
96
+ if ( process . platform === "darwin" ) {
97
+ this . shouldLockDuringCommandExecution = true ;
98
+ }
81
99
}
82
100
83
101
public static get instance ( ) : ManimShell {
@@ -102,22 +120,36 @@ export class ManimShell {
102
120
* @param [waitUntilFinished=false] Whether to wait until the actual command
103
121
* has finished executing, e.g. when the whole animation has been previewed.
104
122
*/
105
- public async executeCommand ( command : string , startLine : number , waitUntilFinished = false ) {
123
+ public async executeCommand ( command : string , startLine : number ,
124
+ waitUntilFinished = false , onCommandIssued ?: ( ) => void ) {
106
125
if ( this . lockDuringStartup ) {
107
126
return vscode . window . showWarningMessage ( "Manim is currently starting. Please wait a moment." ) ;
108
127
}
128
+ if ( this . shouldLockDuringCommandExecution && this . isExecutingCommand ) {
129
+ return vscode . window . showWarningMessage ( MAC_OS_MULTIPLE_COMMANDS_ERROR ) ;
130
+ }
131
+
132
+ this . isExecutingCommand = true ;
109
133
110
134
this . lockDuringStartup = true ;
111
135
const shell = await this . retrieveOrInitActiveShell ( startLine ) ;
112
136
this . lockDuringStartup = false ;
113
137
114
138
this . exec ( shell , command ) ;
139
+ if ( onCommandIssued ) {
140
+ onCommandIssued ( ) ;
141
+ }
115
142
116
143
if ( waitUntilFinished ) {
117
144
await new Promise ( resolve => {
118
145
this . eventEmitter . once ( ManimShellEvent . IPYTHON_CELL_FINISHED , resolve ) ;
119
146
} ) ;
120
147
}
148
+
149
+ this . eventEmitter . once ( ManimShellEvent . IPYTHON_CELL_FINISHED , ( ) => {
150
+ console . log ( "Finished command execution." ) ;
151
+ this . isExecutingCommand = false ;
152
+ } ) ;
121
153
}
122
154
123
155
/**
@@ -126,21 +158,34 @@ export class ManimShell {
126
158
* @param command The command to execute in the VSCode terminal.
127
159
* @param [waitUntilFinished=false] Whether to wait until the actual command
128
160
* has finished executing, e.g. when the whole animation has been previewed.
161
+ * @param [forceExecute=false] Whether to force the execution of the command
162
+ * even if another command is currently running. This is only necessary when
163
+ * the `shouldLockDuringCommandExecution` is set to true.
129
164
* @returns A boolean indicating whether an active shell was found or not.
130
165
* If no active shell was found, the command was also not executed.
131
166
*/
132
167
public async executeCommandEnsureActiveSession (
133
- command : string , waitUntilFinished = false ) : Promise < boolean > {
168
+ command : string , waitUntilFinished = false , forceExecute = false ) : Promise < boolean > {
134
169
if ( ! this . hasActiveShell ( ) ) {
135
170
return Promise . resolve ( false ) ;
136
171
}
172
+ if ( this . shouldLockDuringCommandExecution && ! forceExecute && this . isExecutingCommand ) {
173
+ vscode . window . showWarningMessage ( MAC_OS_MULTIPLE_COMMANDS_ERROR ) ;
174
+ return Promise . resolve ( true ) ;
175
+ }
176
+
177
+ this . isExecutingCommand = true ;
137
178
138
179
this . exec ( this . activeShell as Terminal , command ) ;
139
180
if ( waitUntilFinished ) {
140
181
await new Promise ( resolve => {
141
182
this . eventEmitter . once ( ManimShellEvent . IPYTHON_CELL_FINISHED , resolve ) ;
142
183
} ) ;
143
184
}
185
+
186
+ this . eventEmitter . once ( ManimShellEvent . IPYTHON_CELL_FINISHED , ( ) => {
187
+ this . isExecutingCommand = false ;
188
+ } ) ;
144
189
return Promise . resolve ( true ) ;
145
190
}
146
191
0 commit comments