File: anjuta-python-autocomplete.py

package info (click to toggle)
anjuta 2%3A3.34.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 72,196 kB
  • sloc: ansic: 207,444; sh: 47,499; cpp: 11,461; makefile: 3,588; yacc: 2,821; perl: 2,094; lex: 1,546; xml: 904; python: 149; sql: 99; java: 10
file content (147 lines) | stat: -rwxr-xr-x 5,241 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import getopt
import sys
from collections import namedtuple
from rope.base.project import Project 
from rope.contrib import codeassist
from rope.contrib import autoimport
import os, re
import pkg_resources
from distutils.version import LooseVersion as V

BUILDER_EXTENSION = '.ui'
ROPE_VERSION = ''

CompletionItem = namedtuple('CompletionItem', 'name info type scope location')
def new_completion_item(**i):
        return CompletionItem('_','_','_','_','_')._replace(**i)

class BuilderComplete(object):
	def __init__(self, project_path, resource_path, source_code, code_point, project_files):
		self.code_point = code_point
		self.src_dir = os.path.join(project_path, os.path.dirname(resource_path))
		self.source_code = source_code
		#grab all of the ui files from the project source files
		self.builder_files = [f for f in project_files if f.endswith(BUILDER_EXTENSION) and os.path.exists(f)]

		#suggest completions whenever someone types get_object(' in some form
		self.should_autocompelte_re = re.compile(r'get_object\s*\(\s*[\'"](\w*)$')
	def get_proposals(self, skip_verify=False):
		""" return possible completions based on objects in ui files.
		skip_verify=False will check to make sure preceeding the
		current cursor position is something of the form 'get_object("' """
		starting_word = ""
		if skip_verify is False:
			curr_line = self.source_code[:self.code_point].split('\n')[-1]
			reg_search = self.should_autocompelte_re.search(curr_line)
			if not reg_search:
				return []
			starting_word = reg_search.groups()[0]

		possible_completions = self.get_all_builder_objects(self.builder_files)
		#return only the ones with valid start
		return [item for item in possible_completions if item.name.startswith(starting_word)]

	def get_all_builder_objects(self, file_list):
		""" go through every file in file_list and extract all <object/>
		tags and return their ids """
		from xml.dom import minidom
		ret = []
		for f in file_list:
			md = minidom.parse(f)
			for e in md.getElementsByTagName('object'):
				item = new_completion_item(name=e.getAttribute('id'), scope='external', location=f, type='builder_object')
				ret.append(item)
		return ret

class RopeComplete(object):
	def __init__(self, project_path, source_code, resource_path, code_point):
		self.project = Project(project_path)
		self.project.pycore._init_python_files()
		
		self.resource = self.project.get_resource(resource_path)
		self.source_code = source_code
		self.code_point = code_point

	def __del__(self):
		self.project.close()

	def get_proposals(self):
		ret = []
		proposals = codeassist.code_assist(self.project, self.source_code, self.code_point, resource=self.resource, maxfixes=10)
		proposals = codeassist.sorted_proposals(proposals)

		if V(ROPE_VERSION) <= V('0.9.2'):
			for proposal in proposals:
				ret.append(new_completion_item(name=proposal.name, scope=proposal.kind, type=proposal.type))
		else:
			for proposal in proposals:
				ret.append(new_completion_item(name=proposal.name, scope=proposal.scope, type=proposal.type))

		return ret

	def get_calltip(self):
		calltip = codeassist.get_doc(self.project, self.source_code, self.code_point, resource=self.resource, maxfixes=10)
		return calltip

def parse_arguments(args):
	""" Returns a dictionary containing all the parsed args
	and a string containing the source_code """
	ret = {}

	options, remainder = getopt.getopt(args, 'o:p:s:r:f:b:')
	for opt, arg in options:
		if opt in ('-o', '--option'):
			option_arg = arg
		elif opt in ('-p', '--project'):
			project_arg = arg
		elif opt == '-s':
			source_code_arg = arg
		elif opt == '-r':
			res_arg = arg
		elif opt == '-f':
			offset_arg = arg
		elif opt == '-b':
			builder_files_arg = arg

	ret['option'] = option_arg;
	ret['project_path'] = str.replace(project_arg, 'file://', '') if project_arg.startswith('file://') else project_arg
	ret['resource_path'] = os.path.relpath(res_arg, ret['project_path'])
	if ret['option'] != 'calltip':
		ret['project_files'] = builder_files_arg.split('|')
	ret['position'] = int(offset_arg)

	input = open(source_code_arg, 'r')
	ret['source_code'] = input.read()


	return ret

if __name__ == '__main__':
	try:
		ROPE_VERSION = pkg_resources.get_distribution('rope').version
	except:
		print '|Missing python-rope module!|.|.|.|.|'
		sys.exit(1)
	try:
		args = parse_arguments(sys.argv[1:])

		suggestions = []
		calltip = ''
		if args['option'] == 'autocomplete':
			#get any completions Rope offers us
			comp = RopeComplete(args['project_path'], args['source_code'], args['resource_path'], args['position'])
			suggestions.extend(comp.get_proposals())
			#see if we've typed get_object(' and if so, offer completions based upon the builder ui files in the project
			comp = BuilderComplete(args['project_path'], args['resource_path'], args['source_code'], args['position'], args['project_files'])
			suggestions.extend(comp.get_proposals())
		elif args['option'] == 'calltip':
			calltip_obj = RopeComplete(args['project_path'], args['source_code'], args['resource_path'], args['position'])
			calltip = calltip_obj.get_calltip()

		for s in suggestions:
			print "|{0}|{1}|{2}|{3}|{4}|".format(s.name, s.scope, s.type, s.location, s.info)
		print calltip
	except:
		pass