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")
Exemple #2
0
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")
Exemple #4
0
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 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")
Exemple #8
0
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 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
Exemple #11
0
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
Exemple #14
0
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
Exemple #15
0
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")
Exemple #18
0
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
Exemple #21
0
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_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")
Exemple #26
0
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")
Exemple #30
0
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_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")
Exemple #37
0
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")
Exemple #38
0
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