Ejemplo n.º 1
0
	def startFileParse(self, fileName):

		if not wf.isJavascriptFile(fileName):
			return False

		# If the filename is already present,
		# and it's not the file we just saved, skip it
		if self.project.hasFileData(fileName) and fileName != self.originFile:
			return False

		nmCount = fileName.count('node_modules')
		mvcCount = fileName.count('alchemymvc')

		# Skip node_module files (except for alchemy)
		if nmCount and not mvcCount:
			return False
		elif nmCount > 1 and mvcCount:
			return False
		else:
			sublime.status_message('Witty is parsing: ' + fileName)
			info('Parsing file "' + fileName + '"')

			fileResult = WittyFile(self.project, fileName)

			# If we got a new WittyFile instance, store it in the project
			if fileResult:

				if fileResult.language == 'nodejs':
					self.project.intelNode.files[fileName] = fileResult
				else:
					self.project.intelBrowser.files[fileName] = fileResult
Ejemplo n.º 2
0
	def queryForCompletions(self, view, prefix, locations):
		
		currentFileName = view.file_name()

		if not wf.isJavascriptFile(currentFileName):
			return

		current_file = view.file_name()

		# Get the region
		region = view.sel()[0]

		# Get the point position of the cursor
		point = region.begin()
		(row,col) = view.rowcol(point)

		# Get the lines from the beginning of the page until the cursor
		to_cursor_lines = view.lines(sublime.Region(0, point))

		lines = []

		for l in to_cursor_lines:
			lines.append(wf.removeComment(view.substr(l).strip()))

		stack = []
		oBraces = 0
		cBraces = 0
		mem = {}

		# Get the last open function line
		for l in lines:
			oBraces += l.count('{')
			cBraces += l.count('}')

			newDif = oBraces-cBraces

			try:
				if stack[0]['difference'] > newDif:
					
					if not oBraces in mem:
						try:
							del stack[0]
						except IndexError:
							pass

					mem[oBraces] = True
			except IndexError:
				pass

			if wf.isFunctionDeclaration(l):
				body = l.split('function', 1)[1]
				
				if body.count('{') > body.count('}'):
					stack.insert(0, {'line': l, 'open': oBraces, 'closed': cBraces, 'difference': oBraces-cBraces})

		try:
			function_scope = stack[0]['line']
		except IndexError:
			function_scope = current_file

		# Get the current line
		full_line = view.substr(view.line(region))

		# Get the line up to the cursor
		left_line = full_line[:col].strip()

		# Get the line after the cursor
		right_line = full_line[col:].strip()

		# All lines to the cursor
		text = '\n'.join(lines)

		# Get the better prefix
		brefix = wf.getBetterPrefix(left_line)

		stats = wf.splitStatements(text, 0)

		if not len(stats):
			lastStat = False
		else:
			lastStat = stats[len(stats)-1]

		scope = self.getScope(current_file, function_scope)

		if scope:

			getScopeVars = True
			normalized = False

			if lastStat and lastStat['openName'] == 'var':
				lastExpr = lastStat['result'][len(lastStat['result'])-1]
				
				if 'expression' in lastExpr:
					expr = lastExpr['expression']['result']['text']

					# Only get more info if the last expression hasn't been terminated!
					if not lastExpr['expression']['terminated']:
						try:
							normalized = wf.tokenizeExpression(expr)
							getScopeVars = False
						except KeyError:
							pass

			elif lastStat and lastStat['openName'] == 'expression':
				expr = lastStat['result']['text']

				if expr:
					normalized = wf.tokenizeExpression(expr)
					getScopeVars = False

			if normalized:
				
				temp = expr.replace(' ', '')
				temp = temp.replace('\n', '')
				temp = temp.replace('\t', '')

				endsWithMember = False

				if temp.endswith('.') or temp.endswith('['):
					endsWithMember = True

				active = {'properties': []}

				pr(normalized)
				
				for token in normalized:

					if not token['type']:
						active = {'properties': []}
						continue

					if 'member' in token and not token['member']:
						active = {}
						active['name'] = token['text']
						active['properties'] = []
					else:
						active['properties'].append(token['text'])

				if 'properties' in active and not endsWithMember and len(active['properties']):
					del active['properties'][len(active['properties'])-1]

				pr(active)

				if 'name' in active:
					foundVar = scope.findVariable(active['name'])

					if foundVar:

						# See if we need to get a property of this var
						if active['properties']:
							pr('Looking for properties')
							pr(active['properties'])
							temp = foundVar.findProperties(active['properties'])
							if temp: foundVar = temp

						# Make a copy of the foundVar properties
						variables = foundVar.getProperties()

						getScopeVars = False

						# # Now get the prototype properties of the foundVar's type
						# if foundVar.types:
						# 	# Create empty object
						# 	variables = {}

						# 	for typeName in foundVar.types:
						# 		pr('Looking for ' + typeName)
						# 		typeVar = scope.findVariable(typeName)

						# 		if 'prototype' in typeVar.properties:
						# 			variables.update(typeVar.properties['prototype'].properties)

						# 	# Now overwrite anything with our own properties
						# 	variables.update(foundVar.properties)

			else:
				getScopeVars = True

			# If variables isn't defined, get all the scope variables
			try:
				variables
			except NameError:
				getScopeVars = True

			if getScopeVars:
				variables = scope.getAllVariables()


			completions = []

			for varname, varinfo in variables.items():
				completions.append((varname + '\t' + str(len(varinfo.propArray)) + '\t' + str(varinfo.type), varname))

			# INHIBIT_WORD_COMPLETIONS = 8 = Only show these completions
			# INHIBIT_EXPLICIT_COMPLETIONS = 16 = ?
			return (completions, sublime.INHIBIT_WORD_COMPLETIONS)
		else:

			info('Scope "' + function_scope + '" in file ' + current_file + ' was not found')

			wittyOnly = True

			if wittyOnly:
				# We only want witty results, so make sure sublime doesn't interfere
				return ([], sublime.INHIBIT_WORD_COMPLETIONS)
			else:
				# Let sublime do what it wants
				return