Skip to content

Commit

Permalink
Merge pull request #17 from sailshq/feat/go-to-helper
Browse files Browse the repository at this point in the history
[feat]: go to helper
  • Loading branch information
DominusKelvin authored Sep 13, 2024
2 parents fea1dd7 + 418efd4 commit 87f580b
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 18 deletions.
18 changes: 1 addition & 17 deletions packages/language-server/go-to-definitions/go-to-action.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const lsp = require('vscode-languageserver/node')
const path = require('path')
const fs = require('fs').promises
const url = require('url')
const findFnLine = require('../helpers/find-fn-line')

module.exports = async function goToAction(document, position) {
const fileName = path.basename(document.uri)
Expand Down Expand Up @@ -65,18 +64,3 @@ function extractActionInfo(document, position) {
function resolveActionPath(projectRoot, actionPath) {
return path.join(projectRoot, 'api', 'controllers', `${actionPath}.js`)
}

async function findFnLine(filePath) {
try {
const content = await fs.readFile(url.fileURLToPath(filePath), 'utf8')
const lines = content.split('\n')
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes('fn:')) {
return i // Return the line number (0-based index)
}
}
return 0 // If 'fn:' is not found, return the first line
} catch (error) {
return 0 // Return the first line if there's an error
}
}
47 changes: 47 additions & 0 deletions packages/language-server/go-to-definitions/go-to-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const lsp = require('vscode-languageserver/node')
const path = require('path')
const fs = require('fs').promises
const findProjectRoot = require('../helpers/find-project-root')
const findFnLine = require('../helpers/find-fn-line')

module.exports = async function goToHelper(document, position) {
const helperInfo = extractHelperInfo(document, position)

if (!helperInfo) {
return null
}

const projectRoot = await findProjectRoot(document.uri)
const fullHelperPath =
path.join(projectRoot, 'api', 'helpers', ...helperInfo.helperPath) + '.js'

if (fullHelperPath) {
const fnLineNumber = await findFnLine(fullHelperPath)
return lsp.Location.create(
fullHelperPath,
lsp.Range.create(fnLineNumber, 0, fnLineNumber, 0)
)
}
}

function extractHelperInfo(document, position) {
const text = document.getText()
const offset = document.offsetAt(position)

// Regular expression to match sails.helpers.exampleHelper() or sails.helpers.exampleHelper.with()
// Also matches nested helpers like sails.helpers.mail.send() or sails.helpers.mail.send.with()
const regex = /sails\.helpers\.([a-zA-Z0-9.]+)(?:\.with)?\s*\(/g
let match

while ((match = regex.exec(text)) !== null) {
const start = match.index
const end = start + match[0].length

if (start <= offset && offset <= end) {
const helperPath = match[1].split('.').filter((part) => part !== 'with')
return { helperPath }
}
}

return null
}
21 changes: 21 additions & 0 deletions packages/language-server/helpers/find-fn-line.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const fs = require('fs').promises
const url = require('url')

module.exports = async function findFnLine(filePath) {
try {
const resolvedPath = filePath.startsWith('file:')
? url.fileURLToPath(filePath)
: filePath

const content = await fs.readFile(resolvedPath, 'utf8')
const lines = content.split('\n')
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes('fn:')) {
return i // Return the line number (0-based index)
}
}
return 0 // If 'fn:' is not found, return the first line
} catch (error) {
return 0 // Return the first line if there's an error
}
}
11 changes: 10 additions & 1 deletion packages/language-server/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
const lsp = require('vscode-languageserver/node')
const TextDocument = require('vscode-languageserver-textdocument').TextDocument

// Validators
const validateDocument = require('./validators/validate-document')

// Go-to definitions
const goToAction = require('./go-to-definitions/go-to-action')
const goToPolicy = require('./go-to-definitions/go-to-policy')
const goToView = require('./go-to-definitions/go-to-view')
const goToInertiaPage = require('./go-to-definitions/go-to-inertia-page')
const goToHelper = require('./go-to-definitions/go-to-helper')

// Completions
const sailsCompletions = require('./completions/sails-completions')

const connection = lsp.createConnection(lsp.ProposedFeatures.all)
Expand Down Expand Up @@ -40,12 +47,14 @@ connection.onDefinition(async (params) => {
const policyDefinition = await goToPolicy(document, params.position)
const viewDefinition = await goToView(document, params.position)
const inertiaPageDefinition = await goToInertiaPage(document, params.position)
const helperDefinition = await goToHelper(document, params.position)

const definitions = [
actionDefinition,
policyDefinition,
viewDefinition,
inertiaPageDefinition
inertiaPageDefinition,
helperDefinition
].filter(Boolean)

return definitions.length > 0 ? definitions : null
Expand Down

0 comments on commit 87f580b

Please sign in to comment.