Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat]: go to helper #17

Merged
merged 3 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading