-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from sailshq/feat/get-sails-completion
[feat] get sails completion
- Loading branch information
Showing
6 changed files
with
156 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
const lsp = require('vscode-languageserver/node') | ||
const loadSails = require('../helpers/load-sails') | ||
|
||
module.exports = async function sailsCompletions(document, position) { | ||
const text = document.getText() | ||
const offset = document.offsetAt(position) | ||
const line = text.substring(0, offset).split('\n').pop() | ||
|
||
const match = line.match(/sails((?:\.[a-zA-Z_$][0-9a-zA-Z_$]*)*)\.$/) | ||
if (match) { | ||
try { | ||
return await loadSails(document.uri, (sailsApp) => { | ||
const path = match[1].split('.').filter(Boolean) | ||
return getNestedCompletions(sailsApp, path) | ||
}) | ||
} catch (error) { | ||
return [] | ||
} | ||
} | ||
|
||
return null | ||
} | ||
|
||
function getNestedCompletions(obj, path) { | ||
let current = obj | ||
for (const key of path) { | ||
if (current && typeof current === 'object' && key in current) { | ||
current = current[key] | ||
} else { | ||
return [] | ||
} | ||
} | ||
|
||
if (typeof current !== 'object' || current === null) { | ||
return [] | ||
} | ||
|
||
const completions = Object.keys(current).map((key) => { | ||
const value = current[key] | ||
let kind = lsp.CompletionItemKind.Property | ||
let detail = 'Property' | ||
|
||
if (typeof value === 'function') { | ||
kind = lsp.CompletionItemKind.Method | ||
detail = 'Method' | ||
} else if (typeof value === 'object' && value !== null) { | ||
detail = 'Object' | ||
} | ||
|
||
return { | ||
label: key, | ||
kind: kind, | ||
detail: detail, | ||
documentation: `Access to sails${path.length ? '.' + path.join('.') : ''}.${key}`, | ||
sortText: key.startsWith('_') ? `z${key}` : key // Add this line | ||
} | ||
}) | ||
|
||
// Sort the completions | ||
completions.sort((a, b) => a.sortText.localeCompare(b.sortText)) | ||
|
||
return completions | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
const path = require('path') | ||
const url = require('url') | ||
const fs = require('fs').promises | ||
|
||
module.exports = async function findProjectRoot(uri) { | ||
let currentPath = path.dirname(url.fileURLToPath(uri)) | ||
const root = path.parse(currentPath).root | ||
|
||
while (currentPath !== root) { | ||
try { | ||
await fs.access(path.join(currentPath, 'package.json')) | ||
return currentPath | ||
} catch (error) { | ||
currentPath = path.dirname(currentPath) | ||
} | ||
} | ||
throw new Error('Could not find project root') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
const path = require('path') | ||
const fs = require('fs') | ||
const findProjectRoot = require('./find-project-root') | ||
|
||
module.exports = async function findSails(workspaceUri) { | ||
const projectRoot = await findProjectRoot(workspaceUri) | ||
const sailsPath = path.join(projectRoot, 'node_modules', 'sails') | ||
if (fs.existsSync(sailsPath)) { | ||
return { sailsPath, projectRoot } | ||
} | ||
throw new Error('Sails not found in node_modules') | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
const findSails = require('./find-sails') | ||
|
||
module.exports = async function loadSails(workspaceUri, operation) { | ||
let Sails | ||
let sailsApp | ||
|
||
try { | ||
const { sailsPath } = await findSails(workspaceUri) | ||
Sails = require(sailsPath).constructor | ||
|
||
sailsApp = await new Promise((resolve, reject) => { | ||
new Sails().load( | ||
{ | ||
hooks: { shipwright: false }, | ||
log: { level: 'silent' } | ||
}, | ||
(err, sails) => { | ||
if (err) { | ||
console.error('Failed to load Sails app:', err) | ||
return reject(err) | ||
} | ||
resolve(sails) | ||
} | ||
) | ||
}) | ||
|
||
// Execute the operation with the loaded Sails app | ||
return await operation(sailsApp) | ||
} catch (error) { | ||
console.error('Error loading or working with Sails app:', error) | ||
throw error | ||
} finally { | ||
// Ensure Sails is lowered even if an error occurred | ||
if (sailsApp && typeof sailsApp.lower === 'function') { | ||
await new Promise((resolve) => sailsApp.lower(resolve)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters