@@ -87,7 +87,7 @@ const persisters = {
8787 // persisters for regular actions
8888 actions : {
8989 getCode : action => action ,
90- save : ( wsk , action ) => {
90+ save : ( wsk , action , editor ) => {
9191 const owOpts = wsk . owOpts ( {
9292 name : action . name ,
9393 namespace : action . namespace ,
@@ -130,11 +130,11 @@ const persisters = {
130130 }
131131 }
132132 } ) ,
133- save : ( wsk , app ) => new Promise ( ( resolve , reject ) => {
133+ save : ( wsk , app , editor ) => new Promise ( ( resolve , reject ) => {
134134 const fs = require ( 'fs' ) ,
135135 tmp = require ( 'tmp' )
136136
137- tmp . file ( { prefix : 'shell-' , postfix : '.js' } , ( err , path , fd , cleanup ) => {
137+ tmp . file ( { prefix : 'shell-' , postfix : '.js' } , ( err , filepath , fd , cleanup ) => {
138138 if ( err ) {
139139 reject ( err )
140140 } else {
@@ -143,12 +143,65 @@ const persisters = {
143143 reject ( err )
144144 } else {
145145 // -r means try to deploy the actions, too
146- return repl . qexec ( `app update "${ app . name } " "${ path } " -r` )
146+ return repl . qexec ( `app update "${ app . name } " "${ filepath } " -r` )
147147 . then ( app => {
148148 cleanup ( )
149- console . error ( '#####' , app )
150149 resolve ( app )
151150 } )
151+ . then ( res => {
152+ // successful compilation, so remove any parse error decorations
153+ editor . clearDecorations ( )
154+ return res
155+ } )
156+ . catch ( err => {
157+ console . error ( '!!!!!!!' , err )
158+ if ( err . statusCode === 'ENOPARSE' ) {
159+ debug ( 'composition did not parse' , err )
160+ const basename = path . basename ( filepath ) ,
161+ pattern = new RegExp ( '\\n([^\n]+)\\n\\s+at\\s+' + basename . replace ( / \. / , '\\.' ) + ':(\\d+):(\\d+)' ) ,
162+ match = err . message . match ( pattern )
163+
164+ debug ( 'pattern' , pattern )
165+ debug ( 'message' , err . message )
166+ if ( match ) {
167+ const problem = match [ 1 ] ,
168+ line = match [ 2 ] ,
169+ column = match [ 3 ]
170+ debug ( 'got match' , problem , line , column )
171+
172+ // see the 'hack it ourselves' just below
173+ const rando = `shell-${ new Date ( ) . getTime ( ) } `
174+
175+ editor . __currentDecorations = editor . deltaDecorations ( editor . __currentDecorations || [ ] , [
176+ { range : new monaco . Range ( line , 1 , line , 1 ) ,
177+ options : { isWholeLine : true ,
178+ //glyphMarginClassName: 'editor__parse-error-gutter-marker editor__parse_error_decoration',
179+ //glyphMarginHoverMessage: problem
180+ linesDecorationsClassName : `editor__parse-error-gutter-marker editor__parse-error-decoration ${ rando } `
181+ }
182+ } ,
183+ { range : new monaco . Range ( line , column , line , column + 1 ) ,
184+ options : {
185+ beforeContentClassName : `editor__parse-error-before-marker editor__parse-error-decoration ${ rando } ` ,
186+ //inlineClassName: 'editor__parse-error-inline-marker',
187+ hoverMessage : problem
188+ }
189+ } ,
190+ ] )
191+
192+ // glyphMarginHoverMessage seems broken; hack it ourselves for now
193+ setTimeout ( ( ) => {
194+ const decos = document . querySelectorAll ( `.${ rando } ` )
195+ if ( decos ) {
196+ for ( let idx = 0 ; idx < decos . length ; idx ++ ) {
197+ const deco = decos [ idx ]
198+ deco . setAttribute ( 'title' , problem )
199+ }
200+ }
201+ } , 0 )
202+ }
203+ }
204+ } )
152205 }
153206 } )
154207 }
@@ -177,7 +230,7 @@ const save = ({wsk, getAction, editor, eventBus}) => ({
177230 // https://github.com/apache/incubator-openwhisk/issues/3237
178231 delete action . version
179232
180- return save ( wsk , action )
233+ return save ( wsk , action , editor )
181234 . then ( action => {
182235 action . persister = persister
183236 eventBus . emit ( '/editor/save' , action , { event : 'save' } )
@@ -385,6 +438,7 @@ const openEditor = wsk => {
385438 minimap : {
386439 enabled : false
387440 } ,
441+ //glyphMargin: true, // needed for error indicators
388442 autoIndent : true ,
389443 codeLens : false ,
390444 quickSuggestions : false ,
@@ -400,6 +454,11 @@ const openEditor = wsk => {
400454 language : 'javascript'
401455 } )
402456
457+ editor . clearDecorations = ( ) => {
458+ debug ( 'clearing decorations' )
459+ editor . __currentDecorations = editor . deltaDecorations ( editor . __currentDecorations || [ ] , [ ] )
460+ }
461+
403462 resolve ( editor )
404463 } )
405464 }
@@ -455,8 +514,11 @@ const openEditor = wsk => {
455514 modified . className = 'is-modified'
456515
457516 // even handlers for saved and content-changed
458- const editsInProgress = ( ) => sidecar . classList . add ( 'is-modified' ) // edits in progress
459- const editsCommitted = action => { // edits committed
517+ const editsInProgress = ( ) => {
518+ sidecar . classList . add ( 'is-modified' )
519+ editor . clearDecorations ( ) // for now, don't trty to be clever; remove decorations on any edit
520+ }
521+ const editsCommitted = action => {
460522 const lockIcon = sidecar . querySelector ( '[data-mode="lock"]' )
461523
462524 sidecar . classList . remove ( 'is-modified' )
0 commit comments