]>
Commit | Line | Data |
---|---|---|
1 | """Buffer class.""" | |
2 | ||
3 | __author__ = "Patrick K. O'Brien <pobrien@orbtech.com>" | |
4 | __cvsid__ = "$Id$" | |
5 | __revision__ = "$Revision$"[11:-2] | |
6 | ||
7 | from interpreter import Interpreter | |
8 | import imp | |
9 | import os | |
10 | import sys | |
11 | ||
12 | import document | |
13 | ||
14 | ||
15 | class Buffer: | |
16 | """Buffer class.""" | |
17 | ||
18 | id = 0 | |
19 | ||
20 | def __init__(self, filename=None): | |
21 | """Create a Buffer instance.""" | |
22 | Buffer.id += 1 | |
23 | self.id = Buffer.id | |
24 | self.interp = Interpreter(locals={}) | |
25 | self.name = '' | |
26 | self.editors = {} | |
27 | self.editor = None | |
28 | self.modules = sys.modules.keys() | |
29 | self.syspath = sys.path[:] | |
30 | while True: | |
31 | try: | |
32 | self.syspath.remove('') | |
33 | except ValueError: | |
34 | break | |
35 | while True: | |
36 | try: | |
37 | self.syspath.remove('.') | |
38 | except ValueError: | |
39 | break | |
40 | self.open(filename) | |
41 | ||
42 | def addEditor(self, editor): | |
43 | """Add an editor.""" | |
44 | self.editor = editor | |
45 | self.editors[editor.id] = editor | |
46 | ||
47 | def hasChanged(self): | |
48 | """Return True if text in editor has changed since last save.""" | |
49 | if self.editor: | |
50 | return self.editor.hasChanged() | |
51 | else: | |
52 | return False | |
53 | ||
54 | def new(self, filepath): | |
55 | """New empty buffer.""" | |
56 | if not filepath: | |
57 | return | |
58 | if os.path.exists(filepath): | |
59 | self.confirmed = self.overwriteConfirm(filepath) | |
60 | else: | |
61 | self.confirmed = True | |
62 | ||
63 | def open(self, filename): | |
64 | """Open file into buffer.""" | |
65 | self.doc = document.Document(filename) | |
66 | self.name = self.doc.filename or ('Untitled:' + str(self.id)) | |
67 | self.modulename = self.doc.filebase | |
68 | # XXX This should really make sure filedir is first item in syspath. | |
69 | # XXX Or maybe this should be moved to the update namespace method. | |
70 | if self.doc.filedir and self.doc.filedir not in self.syspath: | |
71 | # To create the proper context for updateNamespace. | |
72 | self.syspath.insert(0, self.doc.filedir) | |
73 | if self.doc.filepath and os.path.exists(self.doc.filepath): | |
74 | self.confirmed = True | |
75 | if self.editor: | |
76 | text = self.doc.read() | |
77 | self.editor._setBuffer(buffer=self, text=text) | |
78 | ||
79 | def overwriteConfirm(filepath): | |
80 | """Confirm overwriting an existing file.""" | |
81 | return False | |
82 | ||
83 | def save(self): | |
84 | """Save buffer.""" | |
85 | filepath = self.doc.filepath | |
86 | if not filepath: | |
87 | return # XXX Get filename | |
88 | if not os.path.exists(filepath): | |
89 | self.confirmed = True | |
90 | if not self.confirmed: | |
91 | self.confirmed = self.overwriteConfirm(filepath) | |
92 | if self.confirmed: | |
93 | self.doc.write(self.editor.getText()) | |
94 | if self.editor: | |
95 | self.editor.setSavePoint() | |
96 | ||
97 | def saveAs(self, filename): | |
98 | """Save buffer.""" | |
99 | self.doc = document.Document(filename) | |
100 | self.name = self.doc.filename | |
101 | self.modulename = self.doc.filebase | |
102 | self.save() | |
103 | ||
104 | def updateNamespace(self): | |
105 | """Update the namespace for autocompletion and calltips. | |
106 | ||
107 | Return True if updated, False if there was an error.""" | |
108 | if not self.interp or not hasattr(self.editor, 'getText'): | |
109 | return False | |
110 | syspath = sys.path | |
111 | sys.path = self.syspath | |
112 | text = self.editor.getText() | |
113 | text = text.replace('\r\n', '\n') | |
114 | text = text.replace('\r', '\n') | |
115 | name = self.modulename or self.name | |
116 | module = imp.new_module(name) | |
117 | newspace = module.__dict__.copy() | |
118 | try: | |
119 | try: | |
120 | code = compile(text, name, 'exec') | |
121 | except: | |
122 | raise | |
123 | # return False | |
124 | try: | |
125 | exec code in newspace | |
126 | except: | |
127 | raise | |
128 | # return False | |
129 | else: | |
130 | # No problems, so update the namespace. | |
131 | self.interp.locals.clear() | |
132 | self.interp.locals.update(newspace) | |
133 | return True | |
134 | finally: | |
135 | sys.path = syspath | |
136 | for m in sys.modules.keys(): | |
137 | if m not in self.modules: | |
138 | del sys.modules[m] |