Merge pull request #506 from andrewcsmith/patch-2
[supercollider.git] / editors / sced / scedwin / py / util.py
blobb53c33c873ce3383b3075aba6aefa5acf975f04e
1 # sced (SuperCollider mode for gedit)
3 # Copyright 2012 Jakob Leben
4 # Copyright 2009 Artem Popov and other contributors (see AUTHORS)
6 # sced is free software:
7 # you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 def is_block_beginning(s):
21 s = "".join(s.split())
22 # FIXME: clarify this later
23 if s == "(" or s.startswith("(//") or s.startswith("(/*"):
24 return True
25 else:
26 return False
28 def find_block(doc, where=None):
29 if where is None:
30 i1 = doc.get_iter_at_mark(doc.get_insert())
31 else:
32 i1 = where.copy()
34 # move backward until a block beginning is found
35 while True:
36 i1.set_line_offset(0)
38 i2 = i1.copy()
39 i2.forward_to_line_end()
41 if is_block_beginning(doc.get_text(i1, i2)):
42 break
44 if not i1.backward_line():
45 raise RuntimeError("Couldn't find where code block starts!")
47 i2 = i1.copy()
48 count = 1
50 line_comment = False
51 block_comment = 0
53 # move forward to the end of the block
54 while True:
55 if not i2.forward_char():
56 raise RuntimeError("Couldn't find where code block ends!")
58 char = i2.get_char()
60 i3 = i2.copy()
61 i3.forward_chars(2)
62 ct = i2.get_text(i3)
64 if ct == "*/":
65 block_comment -= 1
66 elif ct == "/*":
67 block_comment += 1
68 elif ct == "//":
69 line_comment = True
70 elif char == "\n" and line_comment:
71 line_comment = False
73 if not block_comment and not line_comment:
74 if char == "(":
75 count += 1
76 elif char == ")":
77 count -= 1
79 if count == 0:
80 break
82 # XXX: include 2 more characters just in case "where" is near the end
83 i2.forward_chars(2)
85 if where.in_range(i1, i2):
86 return i1, i2
87 else:
88 raise RuntimeError("Couldn't find code block!")
92 import re
94 def scpred(c, *args):
95 if re.match("[A-Za-z0-9_]", c):
96 return False
97 return True
99 def find_word(doc, where=None):
100 if where is None:
101 i1 = doc.get_iter_at_mark(doc.get_insert())
102 else:
103 i1 = where.copy()
105 i1.backward_find_char(scpred)
106 i1.forward_char() # <-- FIXME: forward should not normally be required
108 i2 = i1.copy()
109 i2.forward_find_char(scpred)
111 return i1, i2