def remove_tag(editor): """ Gracefully removes tag under cursor @type editor: ZenEditor """ caret_pos = editor.get_caret_pos() content = editor.get_content() # search for tag pair = html_matcher.get_tags(content, caret_pos, editor.get_profile_name()) if pair and pair[0]: if not pair[1]: # simply remove unary tag editor.replace_content(zen_coding.get_caret_placeholder(), pair[0].start, pair[0].end) else: tag_content_range = narrow_to_non_space(content, pair[0].end, pair[1].start) start_line_bounds = get_line_bounds(content, tag_content_range[0]) start_line_pad = get_line_padding(content[start_line_bounds[0]:start_line_bounds[1]]) tag_content = content[tag_content_range[0]:tag_content_range[1]] tag_content = unindent_text(tag_content, start_line_pad) editor.replace_content(zen_coding.get_caret_placeholder() + tag_content, pair[0].start, pair[1].end) return True else: return False
def go_to_matching_pair(editor): """ Moves caret to matching opening or closing tag @param editor: Editor instance @type editor: ZenEditor """ content = editor.get_content() caret_pos = editor.get_caret_pos() if content[caret_pos] == '<': # looks like caret is outside of tag pair caret_pos += 1 tags = html_matcher.get_tags(content, caret_pos, editor.get_profile_name()) if tags and tags[0]: # match found open_tag, close_tag = tags if close_tag: # exclude unary tags if open_tag['start'] <= caret_pos and open_tag['end'] >= caret_pos: editor.set_caret_pos(close_tag['start']) elif close_tag['start'] <= caret_pos and close_tag[ 'end'] >= caret_pos: editor.set_caret_pos(open_tag['start']) return True return False
def go_to_matching_pair(editor): """ Moves caret to matching opening or closing tag @param editor: Editor instance @type editor: ZenEditor """ content = editor.get_content() caret_pos = editor.get_caret_pos() if content[caret_pos] == '<': # looks like caret is outside of tag pair caret_pos += 1 tags = html_matcher.get_tags(content, caret_pos, editor.get_profile_name()) if tags and tags[0]: # match found open_tag, close_tag = tags if close_tag: # exclude unary tags if open_tag['start'] <= caret_pos and open_tag['end'] >= caret_pos: editor.set_caret_pos(close_tag['start']) elif close_tag['start'] <= caret_pos and close_tag['end'] >= caret_pos: editor.set_caret_pos(open_tag['start']) return True return False
def remove_tag(editor): """ Gracefully removes tag under cursor @type editor: ZenEditor """ caret_pos = editor.get_caret_pos() content = editor.get_content() # search for tag pair = html_matcher.get_tags(content, caret_pos, editor.get_profile_name()) if pair and pair[0]: if not pair[1]: # simply remove unary tag editor.replace_content(zen_coding.get_caret_placeholder(), pair[0].start, pair[0].end) else: tag_content_range = narrow_to_non_space(content, pair[0].end, pair[1].start) start_line_bounds = get_line_bounds(content, tag_content_range[0]) start_line_pad = get_line_padding( content[start_line_bounds[0]:start_line_bounds[1]]) tag_content = content[tag_content_range[0]:tag_content_range[1]] tag_content = unindent_text(tag_content, start_line_pad) editor.replace_content( zen_coding.get_caret_placeholder() + tag_content, pair[0].start, pair[1].end) return True else: return False
def get_syntax(self): """ Returns current editor's syntax mode @return: str """ doc_type = 'html' css_exts = ['css', 'less'] xsl_exts = ['xsl', 'xslt'] path = self._context.path() if path is not None: pos = path.rfind('.') if pos != -1: pos += 1 ext = path[pos:] if ext in css_exts: doc_type = 'css' elif ext in xsl_exts: doc_type = 'xsl' elif ext == 'haml': doc_type = 'haml' elif ext == 'xml': doc_type = 'xml' # No luck with the extension; check for inline style tags if doc_type == 'html': caret_pos = self.get_caret_pos() pair = html_matcher.get_tags(self.get_content(), caret_pos) if pair and pair[0] and pair[0].type == 'tag'and pair[0].name.lower() == 'style': # check that we're actually inside the tag if pair[0].end <= caret_pos and pair[1].start >= caret_pos: doc_type = 'css' return doc_type
def insert_formatted_newline(editor, mode='html'): """ Inserts newline character with proper indentation @param editor: Editor instance @type editor: ZenEditor @param mode: Syntax mode (only 'html' is implemented) @type mode: str """ caret_pos = editor.get_caret_pos() nl = zen_coding.get_newline() pad = zen_coding.get_variable('indentation') if mode == 'html': # let's see if we're breaking newly created tag pair = html_matcher.get_tags(editor.get_content(), editor.get_caret_pos(), editor.get_profile_name()) if pair[0] and pair[1] and pair[0]['type'] == 'tag' and pair[0][ 'end'] == caret_pos and pair[1]['start'] == caret_pos: editor.replace_content( nl + pad + zen_coding.get_caret_placeholder() + nl, caret_pos) else: editor.replace_content(nl, caret_pos) else: editor.replace_content(nl, caret_pos) return True
def get_syntax(self): """ Returns current editor's syntax mode @return: str """ syntax = 'html' path = self.get_file_path() if path is not None: pos = path.rfind('.') if pos != -1: pos += 1 syntax = path[pos:] if syntax == 'less': syntax = 'css' elif syntax == 'xslt': syntax = 'xsl' if not zencoding.resources.has_syntax(syntax): syntax = 'html' # No luck with the extension; check for inline style tags if syntax == 'html': caret_pos = self.get_caret_pos() pair = html_matcher.get_tags(self.get_content(), caret_pos) if pair and pair[0] and pair[0].type == 'tag'and pair[0].name.lower() == 'style': # check that we're actually inside the tag if pair[0].end <= caret_pos and pair[1].start >= caret_pos: syntax = 'css' return syntax
def split_join_tag(editor, profile_name=None): """ Splits or joins tag, e.g. transforms it into a short notation and vice versa: <div></div> → <div /> : join <div /> → <div></div> : split @param editor: Editor instance @type editor: ZenEditor @param profile_name: Profile name @type profile_name: str """ caret_pos = editor.get_caret_pos() profile = zencoding.utils.get_profile(profile_name or editor.get_profile_name()) caret = zencoding.utils.get_caret_placeholder() # find tag at current position pair = html_matcher.get_tags(editor.get_content(), caret_pos, profile_name or editor.get_profile_name()) if pair and pair[0]: new_content = pair[0].full_tag if pair[1]: # join tag closing_slash = '' if profile['self_closing_tag'] is True: closing_slash = '/' elif profile['self_closing_tag'] == 'xhtml': closing_slash = ' /' new_content = re.sub(r'\s*>$', closing_slash + '>', new_content) # add caret placeholder if len(new_content) + pair[0].start < caret_pos: new_content += caret else: d = caret_pos - pair[0].start new_content = new_content[0:d] + caret + new_content[d:] editor.replace_content(new_content, pair[0].start, pair[1].end) else: # split tag nl = zencoding.utils.get_newline() pad = zencoding.utils.get_variable('indentation') # define tag content depending on profile tag_content = profile[ 'tag_nl'] is True and nl + pad + caret + nl or caret new_content = '%s%s</%s>' % (re.sub( r'\s*\/>$', '>', new_content), tag_content, pair[0].name) editor.replace_content(new_content, pair[0].start, pair[0].end) return True else: return False
def split_join_tag(editor, profile_name=None): """ Splits or joins tag, e.g. transforms it into a short notation and vice versa: <div></div> → <div /> : join <div /> → <div></div> : split @param editor: Editor instance @type editor: ZenEditor @param profile_name: Profile name @type profile_name: str """ caret_pos = editor.get_caret_pos() profile = zen_coding.get_profile(profile_name or editor.get_profile_name()) caret = zen_coding.get_caret_placeholder() # find tag at current position pair = html_matcher.get_tags(editor.get_content(), caret_pos, profile_name or editor.get_profile_name()) if pair and pair[0]: new_content = pair[0].full_tag if pair[1]: # join tag closing_slash = '' if profile['self_closing_tag'] is True: closing_slash = '/' elif profile['self_closing_tag'] == 'xhtml': closing_slash = ' /' new_content = re.sub(r'\s*>$', closing_slash + '>', new_content) # add caret placeholder if len(new_content) + pair[0].start < caret_pos: new_content += caret else: d = caret_pos - pair[0].start new_content = new_content[0:d] + caret + new_content[d:] editor.replace_content(new_content, pair[0].start, pair[1].end) else: # split tag nl = zen_coding.get_newline() pad = zen_coding.get_variable('indentation') # define tag content depending on profile tag_content = profile['tag_nl'] is True and nl + pad + caret + nl or caret new_content = '%s%s</%s>' % (re.sub(r'\s*\/>$', '>', new_content), tag_content, pair[0].name) editor.replace_content(new_content, pair[0].start, pair[0].end) return True else: return False
def toggle_html_comment(editor): """ Toggle HTML comment on current selection or tag @type editor: ZenEditor @return: True if comment was toggled """ start, end = editor.get_selection_range() content = editor.get_content() if start == end: # no selection, find matching tag pair = html_matcher.get_tags(content, editor.get_caret_pos(), editor.get_profile_name()) if pair and pair[0]: # found pair start = pair[0].start end = pair[1] and pair[1].end or pair[0].end return generic_comment_toggle(editor, '<!--', '-->', start, end)
def toggle_comment(editor): """ Toggle comment on current editor's selection or HTML tag/CSS rule @type editor: ZenEditor """ syntax = editor.get_syntax() if syntax == 'css': # in case out editor is good enough and can recognize syntax from # current token, we have to make sure that cursor is not inside # 'style' attribute of html element caret_pos = editor.get_caret_pos() pair = html_matcher.get_tags(editor.get_content(),caret_pos) if pair and pair[0] and pair[0].type == 'tag' and pair[0].start <= caret_pos and pair[0].end >= caret_pos: syntax = 'html' if syntax == 'css': return toggle_css_comment(editor) else: return toggle_html_comment(editor)
def insert_formatted_newline(editor, mode='html'): """ Inserts newline character with proper indentation @param editor: Editor instance @type editor: ZenEditor @param mode: Syntax mode (only 'html' is implemented) @type mode: str """ caret_pos = editor.get_caret_pos() nl = zen_coding.get_newline() pad = zen_coding.get_variable('indentation') if mode == 'html': # let's see if we're breaking newly created tag pair = html_matcher.get_tags(editor.get_content(), editor.get_caret_pos(), editor.get_profile_name()) if pair[0] and pair[1] and pair[0]['type'] == 'tag' and pair[0]['end'] == caret_pos and pair[1]['start'] == caret_pos: editor.replace_content(nl + pad + zen_coding.get_caret_placeholder() + nl, caret_pos) else: editor.replace_content(nl, caret_pos) else: editor.replace_content(nl, caret_pos) return True
def match_pair_tagname(editor): """ Moves caret to matching opening or closing tag @param editor: Editor instance @type editor: ZenEditor """ content = editor.get_content() caret_pos = editor.get_caret_pos() if content[caret_pos] == '<': # looks like caret is outside of tag pair caret_pos += 1 tags = html_matcher.get_tags(content, caret_pos, editor.get_profile_name()) if tags and tags[0]: # match found open_tag, close_tag = tags sels = [] start_pt = open_tag.start+1; end_pt = start_pt + len(open_tag.name) sels.append((start_pt, end_pt)) if close_tag: for start_pt in xrange(close_tag.start, len(content)): if not content[start_pt] in '</': break end_pt = start_pt + len(open_tag.name) sels.append((start_pt, end_pt)) editor.create_selection(sels=sels) return True return False