Skip to content

Commit ecc1187

Browse files
Ability to save and compile a class from editor
1 parent 535793a commit ecc1187

File tree

2 files changed

+129
-7
lines changed

2 files changed

+129
-7
lines changed

cos.js

Lines changed: 112 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ const workspace = vscode.workspace
33
const window = vscode.window
44
const API = require('cos-api4node')
55
const fs = require('fs')
6+
const pkg = require('./package.json')
7+
8+
const COS_LANG_IDS = pkg[ 'contributes' ][ 'languages' ].map( lang => lang.id )
69

710
const createBar = () => {
811

@@ -22,7 +25,10 @@ const activate = context => {
2225

2326
const output = window.createOutputChannel( 'cos' )
2427

25-
const log = msg => output.appendLine( msg )
28+
const log = msg => {
29+
output.appendLine( msg )
30+
return true
31+
}
2632

2733
const conn = workspace.getConfiguration( 'cos' ).get( 'conn' )
2834

@@ -42,7 +48,106 @@ const activate = context => {
4248
bar.set( conn )
4349

4450
})
51+
52+
/**
53+
* Import and compile current file.
54+
*/
55+
const cosCompile = () => {
56+
57+
if ( !window.activeTextEditor )
58+
return log( 'No active editor, open one at first' )
59+
60+
const openedDoc = window.activeTextEditor.document
61+
62+
if ( !openedDoc )
63+
return log( 'Open a Caché ObjectScript file first.' )
64+
65+
const fileName = openedDoc.fileName;
66+
67+
if ( !fileName || COS_LANG_IDS.indexOf(openedDoc.languageId) === -1 )
68+
return log( `Document ${ fileName } cannot be compiled in Caché (type ${ openedDoc.languageId } unsupported)` )
69+
70+
log( `Saving ${ fileName }...` )
71+
72+
let cacheDocName;
73+
const fileBody = openedDoc.getText()
74+
const isClass = /\.cls$/i.test( fileName )
75+
const content = fileBody.split( /\r?\n/g )
76+
77+
if ( isClass ) {
78+
// Caché class files can be placed hierarchically (e.g. /src/Package/Class.cls),
79+
// so we pick the class name from the class definition itself
80+
cacheDocName = (fileBody.replace( /\/\/[^\r\n]*\r?\n/g, '' ).match( /Class ([^\s]+)/i ) || [])[ 1 ] || ""
81+
const nameParts = cacheDocName.split( /\./g ).filter(s => !!s)
82+
if ( nameParts.length < 2 )
83+
return log( `Unable to detect class name in source code of ${ fileName }.\n`
84+
+ `Is it a valid Caché ObjectScript class?` )
85+
const matchingFileName = ( fileName.match(/[^\\\/]+$/) || [] )[ 0 ]
86+
if ( ( cacheDocName.toLowerCase() + '.cls' ).indexOf(matchingFileName.toLowerCase()) === -1 )
87+
return log( `You tried to compile class named "${ cacheDocName }" in file "${ matchingFileName }".\n`
88+
+ `Did you forget to rename the file/class to correspond to each other?` )
89+
cacheDocName += '.cls'
90+
} else {
91+
// routine: cacheDocName = actual filename
92+
cacheDocName = ( fileName.match( /[\\\/]([^\\\/]+)$/ ) || [] )[ 1 ] || ""
93+
}
94+
95+
const anyErrors = (err, res, keyword) => {
96+
97+
if ( err )
98+
return log( `Unable to ${ keyword } ${ cacheDocName }: ${ err.code ? err.code + ' ' + err.message : err }` )
99+
100+
if ( !res || !res.status || !(res.status.errors instanceof Array) )
101+
return log( `Unknown response from Atelier API while trying to ${
102+
keyword } ${ cacheDocName }: ${ res }` )
103+
104+
if ( res.result && res.result.status )
105+
return log( res.result.status )
106+
107+
if ( res.status.errors.length !== 0 )
108+
return log( `Unable to ${ keyword } ${ cacheDocName }: ${ res.status.errors.summary }\n\n${
109+
res.console }\n\n${ res.status.errors.join('\n') }` )
110+
111+
return false;
112+
113+
}
114+
115+
const consoleOutput = (output, defaultOutput = "") => {
116+
117+
let out = output instanceof Array
118+
? output.join( '\n' )
119+
: ( output || defaultOutput ) + '';
120+
out = out.replace( /^[\s\r\n]+/, '' );
121+
122+
if ( out ) {
123+
log( out )
124+
}
125+
126+
}
127+
128+
api.putDoc( cacheDocName, { enc: false, content }, { ignoreConflict: true }, ( err, res ) => {
129+
130+
if ( anyErrors( err, res, 'save' ) )
131+
return;
132+
133+
consoleOutput( res.console )
134+
135+
api.compile( cacheDocName, ( err, res ) => {
136+
137+
if ( anyErrors( err, res, 'compile' ) )
138+
return;
139+
140+
consoleOutput( res.console || "Done." )
141+
142+
} )
143+
144+
} )
145+
146+
}
45147

148+
/**
149+
* Export all classes/routines in a namespace to working directory.
150+
*/
46151
const cosExport = () => {
47152

48153
const exportDoc = ( doc, cb ) => {
@@ -103,15 +208,15 @@ const activate = context => {
103208

104209
const onGetDocs = ( err, json ) => {
105210

106-
if ( err ) return log( 'getDocs ERROR')
211+
if ( err ) return log( 'getDocs ERROR' )
107212

108213
const list = json.result.content
109214
log( '' )
110215
log( 'list: ' + list.length )
111216
const docs = list.filter( doc => ( doc.cat !== 'CSP' ) && ( doc.name.substring( 0, 1 ) !== '%' ) && ( doc.name.substring( 0, 12 ) !== 'INFORMATION.' ) )
112217
log( 'without % and CSP and INFORMATION: ' + docs.length )
113218
log( '' )
114-
exportDocs( docs, ()=>{
219+
exportDocs( docs, () => {
115220
log( '' )
116221
log( 'Export completed.' )
117222
})
@@ -123,8 +228,10 @@ const activate = context => {
123228
}
124229

125230
// command 'cos.server' defined in statusBar
126-
const cmd = vscode.commands.registerCommand( 'cos.export', cosExport )
127-
context.subscriptions.push( cmd )
231+
context.subscriptions.push(
232+
vscode.commands.registerCommand( 'cos.export', cosExport ),
233+
vscode.commands.registerCommand( 'cos.compile', cosCompile )
234+
)
128235

129236
}
130237

package.json

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "vscode-cos",
33
"displayName": "Caché ObjectScript",
44
"description": "Caché ObjectScript language support for Visual Studio Code",
5-
"version": "0.0.6",
5+
"version": "0.1.0",
66
"icon": "images/logo.png",
77
"categories": [
88
"Languages",
@@ -13,6 +13,9 @@
1313
"url": "https://github.com/doublefint/vscode-cos.git"
1414
},
1515
"publisher": "doublefint",
16+
"contributors": [
17+
{ "name": "Nikita Savchenko", "email": "[email protected]" }
18+
],
1619
"engines": {
1720
"vscode": "^1.5.0"
1821
},
@@ -59,9 +62,21 @@
5962
{
6063
"category": "cos",
6164
"command": "cos.export",
62-
"title": "export sources"
65+
"title": "Export sources"
66+
},
67+
{
68+
"category": "cos",
69+
"command": "cos.compile",
70+
"title": "Import and compile current file"
6371
}
6472
],
73+
"keybindings": [
74+
{
75+
"command": "cos.compile",
76+
"key": "Ctrl+F7",
77+
"mac": "Cmd+F7"
78+
}
79+
],
6580
"configuration": {
6681
"title": "cos",
6782
"type": "object",

0 commit comments

Comments
 (0)