def expand_to_quotes(string, selection_start, selection_end): quotes_regex = re.compile("(['\"])(?:\\\.|.)*?\\1") # iterate over all found quotes pairs for match in quotes_regex.finditer(string): quotes_start = match.start() quotes_end = match.end() # quotes pair end is before selection, stop here and continue loop if quotes_end < selection_start: continue # quotes pair start is after selection, return, no need to continue loop if quotes_start > selection_end: return None # quotes are already selection_end if selection_start == quotes_start and selection_end == quotes_end: return None # the string w/o the quotes, "quotes content" quotes_content_start = quotes_start + 1 quotes_content_end = quotes_end - 1 # "quotes content" is selected, return with quotes if selection_start == quotes_content_start and selection_end == quotes_content_end: return utils.create_return_obj(quotes_start, quotes_end, string, "quotes") # selection is within the found quote pairs, return "quotes content" if selection_start > quotes_start and selection_end < quotes_end: return utils.create_return_obj(quotes_content_start, quotes_content_end, string, "quotes")
def expand_to_quotes(string, selection_start, selection_end): quotes_regex = re.compile("(['\"])(?:\\\.|.)*?\\1") # iterate over all found quotes pairs for match in quotes_regex.finditer(string): quotes_start = match.start() quotes_end = match.end() # quotes pair end is before selection, stop here and continue loop if quotes_end < selection_start: continue # quotes pair start is after selection, return, no need to continue loop if quotes_start > selection_end: return None # quotes are already selection_end if (selection_start == quotes_start and selection_end == quotes_end): return None # the string w/o the quotes, "quotes content" quotes_content_start = quotes_start + 1 quotes_content_end = quotes_end - 1 # "quotes content" is selected, return with quotes if (selection_start == quotes_content_start and selection_end == quotes_content_end): return utils.create_return_obj(quotes_start, quotes_end, string, "quotes") # selection is within the found quote pairs, return "quotes content" if (selection_start > quotes_start and selection_end < quotes_end): return utils.create_return_obj(quotes_content_start, quotes_content_end, string, "quotes")
def expand_to_xml_node(string, start, end): tag_properties = get_tag_properties(string[start:end]) # if we are selecting a tag, then select the matching tag if tag_properties: tag_name = tag_properties["name"] if tag_properties["type"] == "closing": stringStartToTagStart = string[:start] openingTagPosition = find_tag(stringStartToTagStart, "backward", tag_name) if openingTagPosition: return utils.create_return_obj(openingTagPosition["start"], end, string, "complete_node") # if it's a opening tag, find opening tag and return positions elif tag_properties["type"] == "opening": stringNodeEndToStringEnd = string[end:] closingTagPosition = find_tag(stringNodeEndToStringEnd, "forward", tag_name) if closingTagPosition: return utils.create_return_obj(start, end + closingTagPosition["end"], string, "complete_node") # else it's self closing and there is no matching tag # check if current selection is within a tag, if it is expand to the tag # first expand to inside the tag and then to the whole tag is_within_tag_result = is_within_tag(string, start, end) if is_within_tag_result: inner_start = is_within_tag_result["start"] + 1 inner_end = is_within_tag_result["end"] - 1 if start == inner_start and end == inner_end: return utils.create_return_obj(is_within_tag_result["start"], is_within_tag_result["end"], string, "complete_node") else: return utils.create_return_obj(inner_start, inner_end, string, "inner_node") # expand selection to the "parent" node of the current selection stringStartToSelectionStart = string[:start] parent_opening_tag = find_tag(stringStartToSelectionStart, "backward") if (parent_opening_tag): # find closing tag stringNodeEndToStringEnd = string[parent_opening_tag["end"]:] closingTagPosition = find_tag(stringNodeEndToStringEnd, "forward", parent_opening_tag["name"]) if closingTagPosition: # set positions to content of node, w/o the node tags newStart = parent_opening_tag["end"] newEnd = parent_opening_tag["end"] + closingTagPosition["start"] # if this is the current selection, set positions to content of node including start and end tags if (newStart == start and newEnd == end): newStart = parent_opening_tag["start"] newEnd = parent_opening_tag["end"] + closingTagPosition["end"] return utils.create_return_obj(newStart, newEnd, string, "parent_node_content")
def expand_line_without_indent(string, start, end): line = utils.get_line(string, start, end) indent = expand_to_indent.get_indent(string, line) lstart = min(start, line["start"] + indent) lend = max(end, line["end"]) if lstart != start or lend != end: return utils.create_return_obj(lstart, lend, string, "line_no_indent")
def py_expand_to_indent(string, start, end): line = utils.get_line(string, start, end) indent = get_indent(string, line) # we don't expand to indent 0 (whole document) if indent == 0: return None # expand to indent result = _expand_to_indent(string, start, end) if result is None: return None # get the intent of the first lin # if the expansion changed return the result increased if not(result["start"] == start and result["end"] == end): return result pos = result["start"] - 1 while True: if pos < 0: return None # get the indent of the line before before_line = utils.get_line(string, pos, pos) before_indent = get_indent(string, before_line) if not empty_line(string, before_line) and before_indent < indent: start = before_line["start"] end = result["end"] return utils.create_return_obj(start, end, string, "py_indent") # goto the line before the line befor pos = before_line["start"] - 1
def expand_against_surrounding_command(string, start, end): if chart_at(string, start) in ["{", "["] and\ chart_at(string, end - 1) in ["}", "]"]: # span backwards over [..] and {..} while True: try: start = _stretch_over_previous_semantic_unit(string, start) except NoSemanticUnit: break # span forwards over [..] and [..] while True: try: end = _stretch_over_next_semantic_unit(string, end) except NoSemanticUnit: break # span over the previous \command or \command* if chart_at(string, start - 1) == "*": start -= 1 result = expand_to_word.expand_to_word(string, start, start) if result is None: return None start = result["start"] - 1 if chart_at(string, start) == "\\": return utils.create_return_obj(start, end, string, "latex_command_surround")
def expand_against_matching_env(string, start, end): m = _EXCLUSIVE_BEGIN_END_REG.match(string[start:end]) if not m: return None if m.group("command") == "begin": reverse = False # search downwards search_start = end search_end = len(string) else: # == "end" reverse = True # search upwards search_start = 0 search_end = start env_border = _get_closest_env_border(string, search_start, search_end, reverse=reverse) if not env_border: return None if not env_border["name"] == m.group("name"): print( "ExpandRegion, latex.py, Environments not matching '{}' and '{}'". format(env_border["name"], m.group("name"))) return None if not reverse: # search from begin start = start end = env_border["end"] else: # search from end start = env_border["start"] end = end return utils.create_return_obj(start, end, string, "latex_environment_matching")
def expand_against_matching_env(string, start, end): m = _EXCLUSIVE_BEGIN_END_REG.match(string[start:end]) if not m: return None if m.group("command") == "begin": reverse = False # search downwards search_start = end search_end = len(string) else: # == "end" reverse = True # search upwards search_start = 0 search_end = start env_border = _get_closest_env_border(string, search_start, search_end, reverse=reverse) if not env_border: return None if not env_border["name"] == m.group("name"): print("Environments not matching '{}' and '{}'" .format(env_border["name"], m.group("name"))) return None if not reverse: # search from begin start = start end = env_border["end"] else: # search from end start = env_border["start"] end = end return utils.create_return_obj(start, end, string, "latex_environment_matching")
def expand_against_surrounding_command(string, start, end): if chart_at(string, start) in ["{", "["] and\ chart_at(string, end - 1) in ["}", "]"]: # span backwards over [..] and {..} while True: try: start = _stretch_over_previous_semantic_unit(string, start) except NoSemanticUnit: break # span forwards over [..] and [..] while True: try: end = _stretch_over_next_semantic_unit(string, end) except NoSemanticUnit: break # span over the previous \command or \command* if chart_at(string, start - 1) == "*": start -= 1 result = expand_to_tex_word(string, start, start) if result is None: return None start = result["start"] - 1 if chart_at(string, start) == "\\": return utils.create_return_obj(start, end, string, "latex_command_surround")
def expand_to_xml_node(string, start, end): tag_properties = get_tag_properties(string[start:end]) # if we are selecting a tag, then select the matching tag if tag_properties: tag_name = tag_properties["name"] if tag_properties["type"] == "closing": stringStartToTagStart = string[:start] openingTagPosition = find_tag(stringStartToTagStart, "backward", tag_name) if openingTagPosition: return utils.create_return_obj(openingTagPosition["start"], end, string, "complete_node") # if it's a opening tag, find opening tag and return positions elif tag_properties["type"] == "opening": stringNodeEndToStringEnd = string[end:] closingTagPosition = find_tag(stringNodeEndToStringEnd, "forward", tag_name) if closingTagPosition: return utils.create_return_obj(start, end + closingTagPosition["end"], string, "complete_node") # else it's self closing and there is no matching tag # check if current selection is within a tag, if it is expand to the tag # first expand to inside the tag and then to the whole tag is_within_tag_result = is_within_tag(string, start, end) if is_within_tag_result: inner_start = is_within_tag_result["start"] + 1 inner_end = is_within_tag_result["end"] - 1 if start == inner_start and end == inner_end: return utils.create_return_obj(is_within_tag_result["start"], is_within_tag_result["end"], string, "complete_node") else: return utils.create_return_obj(inner_start, inner_end, string, "inner_node") # expand selection to the "parent" node of the current selection stringStartToSelectionStart = string[:start] parent_opening_tag = find_tag(stringStartToSelectionStart, "backward") if(parent_opening_tag): # find closing tag stringNodeEndToStringEnd = string[parent_opening_tag["end"]:] closingTagPosition = find_tag(stringNodeEndToStringEnd, "forward", parent_opening_tag["name"]) if closingTagPosition: # set positions to content of node, w/o the node tags newStart = parent_opening_tag["end"] newEnd = parent_opening_tag["end"] + closingTagPosition["start"] # if this is the current selection, set positions to content of node including start and end tags if(newStart == start and newEnd == end): newStart = parent_opening_tag["start"] newEnd = parent_opening_tag["end"] + closingTagPosition["end"] return utils.create_return_obj(newStart, newEnd, string, "parent_node_content")
def expand_agains_base_command(string, start, end): start -= 1 if chart_at(string, start) == "\\": if chart_at(string, end) == "*": end += 1 result = utils.create_return_obj(start, end, string, "latex_command_base") return result
def expand_python_block_from_start(string, start, end): if string[end - 1:end] != ":": return None result = expand_to_indent.expand_to_indent(string, end + 1, end + 1) if result: # line = utils.get_line(string, start, start) line = utils.get_line(string, start, start) start = line["start"] end = result["end"] return utils.create_return_obj(start, end, string, "py_block_start")
def expand_to_xml_node(string, start, end): # check if current selection is with a tag is_within_tag_result = is_within_tag(string, start, end) if(is_within_tag_result): # save string of tag tagString = string[is_within_tag_result["start"]:is_within_tag_result["end"]] # get tag name and if it's a opening or closing tag getTagNameResult = get_tag_properties(tagString) tagName = getTagNameResult["name"] # if it's a closing tag, find opening tag and return positions if(getTagNameResult["type"] == "closing"): stringStartToTagStart = string[0:is_within_tag_result["start"]] openingTagPosition = find_tag(stringStartToTagStart, "backward", tagName) return utils.create_return_obj(openingTagPosition["start"], is_within_tag_result["end"], string, "complete_node") # it's self closing, just use it, no need to look further elif(getTagNameResult["type"] == "self_closing"): return utils.create_return_obj(is_within_tag_result["start"], is_within_tag_result["end"], string, "complete_node") # if it's a opening tag, find opening tag and return positions else: stringNodeEndToStringEnd = string[is_within_tag_result["end"]:] closingTagPosition = find_tag(stringNodeEndToStringEnd, "forward", tagName) return utils.create_return_obj(is_within_tag_result["start"], is_within_tag_result["end"] + closingTagPosition["end"], string, "complete_node") # expand selection to the "parent" node of the current selection stringStartToSelectionStart = string[0:end] parent_opening_tag = find_tag(stringStartToSelectionStart, "backward") if(parent_opening_tag): # find closing tag stringNodeEndToStringEnd = string[parent_opening_tag["end"]:] closingTagPosition = find_tag(stringNodeEndToStringEnd, "forward", parent_opening_tag["name"]) # set positions to content of node, w/o the node tags newStart = parent_opening_tag["end"] newEnd = parent_opening_tag["end"] + closingTagPosition["start"] # if this is the current selection, set positions to content of node including start and end tags if(newStart == start and newEnd == end): newStart = parent_opening_tag["start"] newEnd = parent_opening_tag["end"] + closingTagPosition["end"] return utils.create_return_obj(newStart, newEnd, string, "parent_node_content")
def expand_python_block_from_start(string, start, end): if string[end-1:end] != ":": return None result = expand_to_indent.expand_to_indent(string, end + 1, end + 1) if result: # line = utils.get_line(string, start, start) line = utils.get_line(string, start, start) start = line["start"] end = result["end"] return utils.create_return_obj(start, end, string, "py_block_start")
def expand_over_line_continuation(string, start, end): if not string[end - 1:end] == "\\": return None line = utils.get_line(string, start, start) next_line = utils.get_line(string, end + 1, end + 1) start = line["start"] end = next_line["end"] next_result = expand_over_line_continuation(string, start, end) # recursive check if there is an other continuation if next_result: start = next_result["start"] end = next_result["end"] return utils.create_return_obj(start, end, string, "line_continuation")
def expand_over_line_continuation(string, start, end): if not string[end-1:end] == "\\": return None line = utils.get_line(string, start, start) next_line = utils.get_line(string, end + 1, end + 1) start = line["start"] end = next_line["end"] next_result = expand_over_line_continuation(string, start, end) # recursive check if there is an other continuation if next_result: start = next_result["start"] end = next_result["end"] return utils.create_return_obj(start, end, string, "line_continuation")
def _expand_to_regex_rule(string, startIndex, endIndex, regex, type): # if there is a selection (and not only a blinking cursor) if (startIndex != endIndex): selection = string[startIndex:endIndex] # make sure, that every character of the selection meets the regex rules, # if not return here if len(regex.findall(selection)) != len(selection): return None # look back searchIndex = startIndex - 1 while True: # begin of string is reached if searchIndex < 0: newStartIndex = searchIndex + 1 break char = string[searchIndex:searchIndex + 1] # character found, that does not fit into the search set if regex.match(char) is None: newStartIndex = searchIndex + 1 break else: searchIndex -= 1 # look forward searchIndex = endIndex while True: # end of string reached if searchIndex > len(string) - 1: newEndIndex = searchIndex break char = string[searchIndex:searchIndex + 1] # character found, that does not fit into the search set if regex.match(char) is None: newEndIndex = searchIndex break else: searchIndex += 1 try: if startIndex == newStartIndex and endIndex == newEndIndex: return None else: return utils.create_return_obj(newStartIndex, newEndIndex, string, type) except NameError: # newStartIndex or newEndIndex might not have been defined above, because # the character was not found. return None
def expand_against_command_args(string, start, end): if not chart_at(string, start) == "\\": return None if chart_at(string, end) not in ["{", "["]: return None original_end = end while True: try: end = _stretch_over_next_semantic_unit(string, end) except NoSemanticUnit: break # if the end did not change: do nothing if original_end == end: return None return utils.create_return_obj(start, end, string, "latex_command_arg")
def _expand_to_regex_rule(string, startIndex, endIndex, regex, type): # if there is a selection (and not only a blinking cursor) if(startIndex != endIndex): selection = string[startIndex:endIndex] # make sure, that every character of the selection meets the regex rules, # if not return here if len(regex.findall(selection)) != len(selection): return None # look back searchIndex = startIndex - 1; while True: # begin of string is reached if searchIndex < 0: newStartIndex = searchIndex + 1 break char = string[searchIndex:searchIndex+1] # character found, that does not fit into the search set if regex.match(char) is None: newStartIndex = searchIndex + 1 break else: searchIndex -= 1 # look forward searchIndex = endIndex; while True: # end of string reached if searchIndex > len(string) - 1: newEndIndex = searchIndex break char = string[searchIndex:searchIndex+1] # character found, that does not fit into the search set if regex.match(char) is None: newEndIndex = searchIndex break else: searchIndex += 1 try: if startIndex == newStartIndex and endIndex == newEndIndex: return None else: return utils.create_return_obj(newStartIndex, newEndIndex, string, type) except NameError: # newStartIndex or newEndIndex might not have been defined above, because # the character was not found. return None
def expand_to_space_in_quotes(result, string, start, end): # TODO: should return when current selection contains a space quotes_string = result['string'] m = re.compile(r'\s') res = m.finditer(quotes_string) space_start_result = result['start'] space_end_result = result['end'] space_break = None for matched_space in res: space_start = matched_space.start() + result['start'] space_end = matched_space.end() + result['start'] print(space_start, space_end) if(end == space_start and start == result['start']): print('space end and quote start') space_break = True break if(start == space_end and end == result['end']): print('space start and quote end') space_break = True break # todo: maybe this can be simplified if((start == space_end and end == space_start_result) or (start == space_end_result and end == space_start_result) or (start == space_end_result and end == space_start)): print('space start and space end') space_break = True break if(start == result['start'] and end == result['end']): print('quote start and quote end') space_break = True break # set space_start_result if(space_end <= start and space_end > space_start_result): space_start_result = space_end # set space_end_result if(space_start > start and space_start < space_end_result and space_start >= end): space_end_result = space_start # should not breaked # should not equal selection start, end # not the same result with quotes if(space_break == None and not (space_start_result == start and space_end_result == end ) and (space_start_result != result['start'] or space_end_result != result['end'])): return utils.create_return_obj(space_start_result, space_end_result, string, "quotes_and_space") else: return False
def expand_against_env(string, start, end): tex_begin = _get_closest_env_border(string, 0, start, reverse=True) tex_end = _get_closest_env_border(string, end, len(string), reverse=False) if tex_begin is None or tex_end is None: return None if tex_begin["name"] != tex_end["name"]: print("Environments not matching '{}' and '{}'" .format(tex_begin["name"], tex_end["name"])) return None inner_env_selected = start == tex_begin["end"] and end == tex_end["start"] if inner_env_selected: start = tex_begin["start"] end = tex_end["end"] else: start = tex_begin["end"] end = tex_end["start"] return utils.create_return_obj(start, end, string, "latex_environment")
def expand_to_line(string, startIndex, endIndex): linebreakRe = re.compile(r'\n') spacesAndTabsRe = re.compile(r'([ \t]+)') searchIndex = startIndex - 1; while True: if searchIndex < 0: newStartIndex = searchIndex + 1 break char = string[searchIndex:searchIndex+1] if linebreakRe.match(char): newStartIndex = searchIndex + 1 break else: searchIndex -= 1 searchIndex = endIndex; while True: if searchIndex > len(string) - 1: newEndIndex = searchIndex break char = string[searchIndex:searchIndex+1] if linebreakRe.match(char): newEndIndex = searchIndex break else: searchIndex += 1 s = string[newStartIndex:newEndIndex] r = spacesAndTabsRe.match(s) if r and r.end() <= startIndex: newStartIndex = newStartIndex + r.end(); try: if startIndex == newStartIndex and endIndex == newEndIndex: return None else: return utils.create_return_obj(newStartIndex, newEndIndex, string, "line") except NameError: return None
def expand_to_line(string, startIndex, endIndex): linebreakRe = re.compile(r"\n") spacesAndTabsRe = re.compile(r"([ \t]+)") searchIndex = startIndex - 1 while True: if searchIndex < 0: newStartIndex = searchIndex + 1 break char = string[searchIndex : searchIndex + 1] if linebreakRe.match(char): newStartIndex = searchIndex + 1 break else: searchIndex -= 1 searchIndex = endIndex while True: if searchIndex > len(string) - 1: newEndIndex = searchIndex break char = string[searchIndex : searchIndex + 1] if linebreakRe.match(char): newEndIndex = searchIndex break else: searchIndex += 1 s = string[newStartIndex:newEndIndex] r = spacesAndTabsRe.match(s) if r and r.end() <= startIndex: newStartIndex = newStartIndex + r.end() try: if startIndex == newStartIndex and endIndex == newEndIndex: return None else: return utils.create_return_obj(newStartIndex, newEndIndex, string, "line") except NameError: return None
def expand_to_css_selector(string, start, end): view = sublime.Window.active_view(sublime.active_window()) line_start = view.line(view.sel()[0]).begin() cur_line = view.substr(view.line(view.sel()[0])) # TODO: Optimize search first none space pos # print('aaaaa', cur_line) # print('aaaaa',len(cur_line)) has_seletor = re.compile(r'\s*[\.\#]{1}([^\s].*[^\s])*\s*[\{|,]') matched = has_seletor.match(cur_line) # print('bbbbb', matched) if matched: print('cccccc', matched.groups(1)) # Retrieve the groups(1)'s start and end. newStartIndex = matched.start(1) + line_start newEndIndex = matched.end(1) + line_start # if is not equal current selection if (not (start == newStartIndex and end == newEndIndex)): print(newStartIndex, newEndIndex) return utils.create_return_obj(newStartIndex, newEndIndex, string, "css_selector")
def expand_to_inline_math(string, start, end): # don't expand if a dollar sign is inside the string if re.search(r"(?:[^\\]|^)\$", string[start:end]): return line = utils.get_line(string, start, end) escape = inside = False open_pos = close_pos = None # we only need to consider one position, because we have checked it does # not contain any $-signs pos = start - line["start"] for i, char in enumerate(string[line["start"]:line["end"]]): # break if we are behind behind = pos < i if not inside and behind: return if escape: escape = False elif char == "\\": escape = True continue elif char == "$": if not inside: # the inner end of the $-sign open_pos = i + 1 elif behind: close_pos = i break inside = not inside if open_pos is not None and close_pos is not None: open_pos = line["start"] + open_pos close_pos = line["start"] + close_pos # expand to the outer end if open_pos == start and close_pos == end: open_pos -= 1 close_pos += 1 return utils.create_return_obj(open_pos, close_pos, string, "latex_inline_math")
def expand_to_inline_math(string, start, end): # don't expand if a dollar sign is inside the string if re.search(r"(?:[^\\]|^)\$", string[start:end]): return line = utils.get_line(string, start, end) escape = inside = False open_pos = close_pos = None # we only need to consider one position, because we have checked it does # not contain any $-signs pos = start - line["start"] for i, char in enumerate(string[line["start"]:line["end"]]): # break if we are behind behind = pos < i if not inside and behind: return if escape: escape = False elif char == "\\": escape = True continue elif char == "$": if not inside: # the inner end of the $-sign open_pos = i + 1 elif behind: close_pos = i break inside = not inside if open_pos is not None and close_pos is not None: open_pos = line["start"] + open_pos close_pos = line["start"] + close_pos # expand to the outer end if open_pos == start and close_pos == end: open_pos -= 1 close_pos += 1 return utils.create_return_obj( open_pos, close_pos, string, "latex_inline_math")
def _expand_to_indent(string, start, end): line = utils.get_line(string, start, end) indent = get_indent(string, line) start = line["start"] end = line["end"] before_line = line while True: # get the line before pos = before_line["start"] - 1 if pos <= 0: break before_line = utils.get_line(string, pos, pos) before_indent = get_indent(string, before_line) # done if the line has a lower indent if not indent <= before_indent and not empty_line(string, before_line): break # if the indent equals the lines indent than update the start if not empty_line(string, before_line) and indent == before_indent: start = before_line["start"] after_line = line while True: # get the line after pos = after_line["end"] + 1 if pos >= len(string): break after_line = utils.get_line(string, pos, pos) after_indent = get_indent(string, after_line) # done if the line has a lower indent if not indent <= after_indent and not empty_line(string, after_line): break # move the end if not empty_line(string, after_line): end = after_line["end"] return utils.create_return_obj(start, end, string, "indent")
def expand_to_symbols(string, selection_start, selection_end): opening_symbols = "([{" closing_symbols = ")]}" symbols_regex = re.compile("[" + re.escape(opening_symbols + closing_symbols) + "]") quotes_regex = re.compile("(['\"])(?:\\1|.*?\\1)") quotes_blacklist = {} # get all quoted strings and create dict with key of index = True # Example: f+"oob"+bar # quotes_blacklist = { # 2: true, 3: true, 4: true, 5: true, 6: true # } for match in quotes_regex.finditer(string): quotes_start = match.start() quotes_end = match.end() i = 0 while True: quotes_blacklist[quotes_start + i] = True i += 1 if quotes_start + i == quotes_end: break counterparts = {"(": ")", "{": "}", "[": "]", ")": "(", "}": "{", "]": "["} # find symbols in selection that are "not closed" selection_string = string[selection_start:selection_end] selection_quotes = symbols_regex.findall(selection_string) backward_symbols_stack = [] forward_symbols_stack = [] if len(selection_quotes) != 0: inspect_index = 0 # remove symbols that have a counterpart, i.e. that are "closed" while True: item = selection_quotes[inspect_index] if counterparts[item] in selection_quotes: del selection_quotes[selection_quotes.index(item)] del selection_quotes[selection_quotes.index(counterparts[item])] else: inspect_index = inspect_index + 1 if inspect_index >= len(selection_quotes): break # put the remaining "open" symbols in the stack lists depending if they are # opening or closing symbols for item in selection_quotes: if item in opening_symbols: forward_symbols_stack.append(item) elif item in closing_symbols: backward_symbols_stack.append(item) search_index = selection_start - 1 # look back from begin of selection while True: # begin of string reached if search_index < 0: return None # skip if current index is within a quote if quotes_blacklist.get(search_index, False) == True: search_index -= 1 continue character = string[search_index : search_index + 1] result = symbols_regex.match(character) if result: symbol = result.group() # symbol is opening symbol and stack is empty, we found the symbol we want to expand to if symbol in opening_symbols and len(backward_symbols_stack) == 0: symbols_start = search_index + 1 break if ( len(backward_symbols_stack) > 0 and backward_symbols_stack[len(backward_symbols_stack) - 1] == counterparts[symbol] ): # last symbol in the stack is the counterpart of the found one backward_symbols_stack.pop() else: backward_symbols_stack.append(symbol) search_index -= 1 symbol_pair_regex = re.compile("[" + re.escape(symbol + counterparts[symbol]) + "]") forward_symbols_stack.append(symbol) search_index = selection_end # look forward from end of selection while True: # skip if current index is within a quote if quotes_blacklist.get(search_index, False) == True: search_index += 1 continue character = string[search_index : search_index + 1] result = symbol_pair_regex.match(character) if result: symbol = result.group() if forward_symbols_stack[len(forward_symbols_stack) - 1] == counterparts[symbol]: # counterpart of found symbol is the last one in stack, remove it forward_symbols_stack.pop() else: forward_symbols_stack.append(symbol) if len(forward_symbols_stack) == 0: symbols_end = search_index break # end of string reached if search_index == len(string): return search_index += 1 if selection_start == symbols_start and selection_end == symbols_end: return utils.create_return_obj(symbols_start - 1, symbols_end + 1, string, "symbol") else: return utils.create_return_obj(symbols_start, symbols_end, string, "symbol")
def expand_to_semantic_unit(string, startIndex, endIndex): symbols = "([{)]}" breakSymbols = ",;=&|\n" lookBackBreakSymbols = breakSymbols + "([{" lookForwardBreakSymbols = breakSymbols + ")]}" symbolsRe = re.compile(r'(['+re.escape(symbols)+re.escape(breakSymbols)+'])') counterparts = { "(":")", "{":"}", "[":"]", ")":"(", "}":"{", "]":"[" } symbolStack = [] searchIndex = startIndex - 1; while True: if(searchIndex < 0): newStartIndex = searchIndex + 1 break char = string[searchIndex:searchIndex+1] result = symbolsRe.match(char) if result: symbol = result.group() if(symbol in lookBackBreakSymbols and len(symbolStack) == 0): newStartIndex = searchIndex + 1 break if symbol in symbols: if len(symbolStack) > 0 and symbolStack[len(symbolStack) - 1] == counterparts[symbol]: symbolStack.pop() else: symbolStack.append(symbol) # print(char, symbolStack) searchIndex -= 1 searchIndex = endIndex; while True: char = string[searchIndex:searchIndex+1] result = symbolsRe.match(char) if result: symbol = result.group() if len(symbolStack) == 0 and symbol in lookForwardBreakSymbols: newEndIndex = searchIndex; break if symbol in symbols: if len(symbolStack) > 0 and symbolStack[len(symbolStack) - 1] == counterparts[symbol]: symbolStack.pop() else: symbolStack.append(symbol) if searchIndex >= len(string) - 1: return None # print(char, symbolStack, searchIndex) searchIndex += 1 s = string[newStartIndex:newEndIndex] trimResult = utils.trim(s) if trimResult: newStartIndex = newStartIndex + trimResult["start"]; newEndIndex = newEndIndex - (len(s) - trimResult["end"]); try: if newStartIndex == startIndex and newEndIndex == endIndex: return None if newStartIndex > startIndex or newEndIndex < endIndex: return None return utils.create_return_obj(newStartIndex, newEndIndex, string, "semantic_unit") except NameError: return None
def expand_to_symbols(string, selection_start, selection_end): opening_symbols = "([{"; closing_symbols = ")]}"; symbols_regex = re.compile("[" + re.escape(opening_symbols + closing_symbols)+"]") counterparts = { "(":")", "{":"}", "[":"]", ")":"(", "}":"{", "]":"[" } # find symbols in selection that are "not closed" selection_string = string[selection_start:selection_end] selection_quotes = symbols_regex.findall(selection_string) backward_symbols_stack = [] forward_symbols_stack = [] if(len(selection_quotes) != 0): inspect_index = 0 # remove symbols that have a counterpart, i.e. that are "closed" while True: item = selection_quotes[inspect_index] if(counterparts[item] in selection_quotes): del selection_quotes[selection_quotes.index(item)] del selection_quotes[selection_quotes.index(counterparts[item])] else: inspect_index = inspect_index + 1 if(inspect_index >= len(selection_quotes)): break; # put the remaining "open" symbols in the stack lists depending if they are # opening or closing symbols for item in selection_quotes: if(item in opening_symbols): forward_symbols_stack.append(item) elif(item in closing_symbols): backward_symbols_stack.append(item) search_index = selection_start - 1; while True: # begin of string reached if(search_index < 0): return None character = string[search_index:search_index + 1] result = symbols_regex.match(character) if result: symbol = result.group() # symbol is opening symbol and stack is empty, we found the symbol we want to expand to if(symbol in opening_symbols and len(backward_symbols_stack) == 0): symbols_start = search_index + 1 break if len(backward_symbols_stack) > 0 and backward_symbols_stack[len(backward_symbols_stack) - 1] == counterparts[symbol]: # last symbol in the stack is the counterpart of the found one backward_symbols_stack.pop() else: backward_symbols_stack.append(symbol) search_index -= 1 symbol_pair_regex = re.compile("[" + re.escape(symbol + counterparts[symbol]) + "]") forward_symbols_stack.append(symbol) search_index = selection_end; while True: character = string[search_index:search_index + 1] result = symbol_pair_regex.match(character) if result: symbol = result.group() if forward_symbols_stack[len(forward_symbols_stack) - 1] == counterparts[symbol]: # counterpart of found symbol is the last one in stack, remove it forward_symbols_stack.pop() else: forward_symbols_stack.append(symbol) if len(forward_symbols_stack) == 0: symbols_end = search_index; break # end of string reached if search_index == len(string): return search_index += 1 if(selection_start == symbols_start and selection_end == symbols_end): return utils.create_return_obj(symbols_start - 1, symbols_end + 1, string, "symbol") else: return utils.create_return_obj(symbols_start, symbols_end, string, "symbol")
def expand_to_symbols(string, selection_start, selection_end): opening_symbols = "([{" closing_symbols = ")]}" symbols_regex = re.compile("[" + re.escape(opening_symbols + closing_symbols) + "]") quotes_regex = re.compile("(['\"])(?:\\1|.*?\\1)") quotes_blacklist = {} # get all quoted strings and create dict with key of index = True # Example: f+"oob"+bar # quotes_blacklist = { # 2: true, 3: true, 4: true, 5: true, 6: true # } for match in quotes_regex.finditer(string): quotes_start = match.start() quotes_end = match.end() i = 0 while True: quotes_blacklist[quotes_start + i] = True i += 1 if (quotes_start + i == quotes_end): break counterparts = {"(": ")", "{": "}", "[": "]", ")": "(", "}": "{", "]": "["} # find symbols in selection that are "not closed" selection_string = string[selection_start:selection_end] selection_quotes = symbols_regex.findall(selection_string) backward_symbols_stack = [] forward_symbols_stack = [] if (len(selection_quotes) != 0): inspect_index = 0 # remove symbols that have a counterpart, i.e. that are "closed" while True: item = selection_quotes[inspect_index] if (counterparts[item] in selection_quotes): del selection_quotes[selection_quotes.index(item)] del selection_quotes[selection_quotes.index( counterparts[item])] else: inspect_index = inspect_index + 1 if (inspect_index >= len(selection_quotes)): break # put the remaining "open" symbols in the stack lists depending if they are # opening or closing symbols for item in selection_quotes: if (item in opening_symbols): forward_symbols_stack.append(item) elif (item in closing_symbols): backward_symbols_stack.append(item) search_index = selection_start - 1 # look back from begin of selection while True: # begin of string reached if (search_index < 0): return None # skip if current index is within a quote if (quotes_blacklist.get(search_index, False) == True): search_index -= 1 continue character = string[search_index:search_index + 1] result = symbols_regex.match(character) if result: symbol = result.group() # symbol is opening symbol and stack is empty, we found the symbol we want to expand to if (symbol in opening_symbols and len(backward_symbols_stack) == 0): symbols_start = search_index + 1 break if len(backward_symbols_stack) > 0 and backward_symbols_stack[ len(backward_symbols_stack) - 1] == counterparts[symbol]: # last symbol in the stack is the counterpart of the found one backward_symbols_stack.pop() else: backward_symbols_stack.append(symbol) search_index -= 1 symbol_pair_regex = re.compile("[" + re.escape(symbol + counterparts[symbol]) + "]") forward_symbols_stack.append(symbol) search_index = selection_end # look forward from end of selection while True: # skip if current index is within a quote if (quotes_blacklist.get(search_index, False) == True): search_index += 1 continue character = string[search_index:search_index + 1] result = symbol_pair_regex.match(character) if result: symbol = result.group() if forward_symbols_stack[len(forward_symbols_stack) - 1] == counterparts[symbol]: # counterpart of found symbol is the last one in stack, remove it forward_symbols_stack.pop() else: forward_symbols_stack.append(symbol) if len(forward_symbols_stack) == 0: symbols_end = search_index break # end of string reached if search_index == len(string): return search_index += 1 if (selection_start == symbols_start and selection_end == symbols_end): return utils.create_return_obj(symbols_start - 1, symbols_end + 1, string, "symbol") else: return utils.create_return_obj(symbols_start, symbols_end, string, "symbol")
def expand_to_semantic_unit(string, startIndex, endIndex): symbols = "([{)]}" breakSymbols = ",;=&|\n" lookBackBreakSymbols = breakSymbols + "([{" lookForwardBreakSymbols = breakSymbols + ")]}" symbolsRe = re.compile(r'([' + re.escape(symbols) + re.escape(breakSymbols) + '])') counterparts = {"(": ")", "{": "}", "[": "]", ")": "(", "}": "{", "]": "["} symbolStack = [] searchIndex = startIndex - 1 while True: if (searchIndex < 0): newStartIndex = searchIndex + 1 break char = string[searchIndex:searchIndex + 1] result = symbolsRe.match(char) if result: symbol = result.group() if (symbol in lookBackBreakSymbols and len(symbolStack) == 0): newStartIndex = searchIndex + 1 break if symbol in symbols: if len(symbolStack) > 0 and symbolStack[ len(symbolStack) - 1] == counterparts[symbol]: symbolStack.pop() else: symbolStack.append(symbol) # print("ExpandRegion, expand_to_semantic_unit.py, " + char + " " + symbolStack) searchIndex -= 1 searchIndex = endIndex while True: char = string[searchIndex:searchIndex + 1] result = symbolsRe.match(char) if result: symbol = result.group() if len(symbolStack) == 0 and symbol in lookForwardBreakSymbols: newEndIndex = searchIndex break if symbol in symbols: if len(symbolStack) > 0 and symbolStack[ len(symbolStack) - 1] == counterparts[symbol]: symbolStack.pop() else: symbolStack.append(symbol) if searchIndex >= len(string) - 1: return None # print("ExpandRegion, latex.py, " + char + " " + symbolStack + " " + searchIndex) searchIndex += 1 s = string[newStartIndex:newEndIndex] # print( utils ) trimResult = utils.trim(s) if trimResult: newStartIndex = newStartIndex + trimResult["start"] newEndIndex = newEndIndex - (len(s) - trimResult["end"]) try: if newStartIndex == startIndex and newEndIndex == endIndex: return None if newStartIndex > startIndex or newEndIndex < endIndex: return None return utils.create_return_obj(newStartIndex, newEndIndex, string, "semantic_unit") except NameError: return None