'use strict' ; import * as vscode from 'vscode' ; import * as path from 'path' ; import { REL_VIEWS , PATTERNS , VIEWS_PATTERNS , } from './constants' ; import { RailsDefinitionInformation } from './interfaces' ; import { RAILS } from './symbols/rails' ; import { findFiles } from './utils' ; const missingFilelMsg = 'Missing file: ' ; const NO_DEFINITION = 'No definition found!' ; param _path param fileType param viewType returns export function findViews ( document , position , _path , fileType = '' , viewType = 'partial' ) { console . log ( `findViews` , arguments ) ; let filePath ; const isSameDirPartial = /^[a-zA-Z0-9_-]+$/ . test ( _path ) , isViewsRelativePath = _path . indexOf ( '/' ) !== - 1 , ext = path . parse ( _path ) . ext , _underscore = viewType . endsWith ( 'partial' ) ? '_' : '' , definitionInformation = { file : null , line : 0 , column : 0 , } ; if ( isSameDirPartial ) { const fileName = vscode . workspace . asRelativePath ( document . fileName ) , dir = path . dirname ( fileName ) ; filePath = path . join ( dir , `${ _underscore }${ _path }${ fileType }.*` ) ; definitionInformation . file = filePath ; } else if ( ext ) { filePath = path . join ( REL_VIEWS , _path ) ; definitionInformation . file = filePath ; } else if ( isViewsRelativePath ) { filePath = path . join ( REL_VIEWS , path . dirname ( _path ) , `${ _underscore }${ path . basename ( _path ) }${ fileType }.*` ) ; definitionInformation . file = filePath ; } else { return Promise . reject ( 'not a view' ) ; } console . log ( viewType , filePath , isViewsRelativePath , isSameDirPartial ) ; const promise = new Promise < RailsDefinitionInformation > ( definitionResolver ( document , definitionInformation ) ) ; return promise ; } returns export function definitionResolver ( document , definitionInformation , exclude = null , maxNum = null ) { console . log ( `definitionResolver` , arguments ) ; return ( resolve , reject ) => { findFiles ( document , vscode . workspace . asRelativePath ( definitionInformation . file ) ) . then ( ( uris ) => { if ( ! uris . length ) { reject ( missingFilelMsg + definitionInformation . file ) ; } else if ( uris . length === 1 ) { definitionInformation . file = uris [ 0 ] . fsPath ; resolve ( definitionInformation ) ; } else { reject ( NO_DEFINITION ) ; } } , ( ) => { reject ( missingFilelMsg + definitionInformation . file ) ; } ) ; } ; } returns export function definitionLocation ( document , position , goConfig ? , token ? ) { console . log ( `definitionLocation` , arguments ) ; const wordRange = document . getWordRangeAtPosition ( position , /([A-Za-z\/0-9_-]+)(\.[A-Za-z0-9]+)*/ ) ; if ( ! wordRange ) { return Promise . resolve ( null ) ; } const lineText = document . lineAt ( position . line ) . text . trim ( ) ; const lineStartToWord = document . getText ( new vscode . Range ( new vscode . Position ( position . line , 0 ) , wordRange . end ) ) . trim ( ) ; const lineStartToWordStart = document . getText ( new vscode . Range ( new vscode . Position ( position . line , 0 ) , wordRange . start ) ) . trim ( ) ; const matched = lineStartToWordStart . match ( PATTERNS . RENDER_MATCH ) , preWord = matched && matched [ matched . length - 1 ] , viewType = preWord && ! preWord . includes ( 'render' ) ? preWord : 'partial' ; console . log ( `viewType:${ viewType }` ) ; const word = document . getText ( wordRange ) ; console . log ( word ) ; if ( ! goConfig ) { goConfig = vscode . workspace . getConfiguration ( 'rails' ) ; } const symbol = new RegExp ( '(((::)?[A-Za-z]+)*(::)?' + word + ')' ) . exec ( lineStartToWord ) [ 1 ] ; if ( RAILS . prefix ( symbol . toLowerCase ( ) ) . isProper ) { return Promise . reject ( 'Rails symbols' ) ; } const renderMatched = lineText . match ( VIEWS_PATTERNS . RENDER_PATTERN ) ; if ( renderMatched ) { console . log ( renderMatched ) ; return findViews ( document , position , word , '' , viewType ) ; } else { return findViews ( document , position , word , '' , viewType ) ; } } export class ViewDefinitionProvider implements vscode . DefinitionProvider { private goConfig = null ; constructor ( goConfig ? ) { this . goConfig = goConfig ; } public provideDefinition ( document , position , token ) { return definitionLocation ( document , position , this . goConfig , token ) . then ( ( definitionInfo ) => { if ( definitionInfo === null || definitionInfo . file === null ) { return null ; } const definitionResource = vscode . Uri . file ( definitionInfo . file ) ; const pos = new vscode . Position ( definitionInfo . line , definitionInfo . column || 0 ) ; return new vscode . Location ( definitionResource , pos ) ; } , ( err ) => { if ( err ) { if ( typeof err === 'string' && err . startsWith ( missingFilelMsg ) ) { } else { return Promise . reject ( NO_DEFINITION ) ; } } return Promise . reject ( NO_DEFINITION ) ; } ) ; } }