def act(controller, bundle, options): context = tea.get_context(controller) snippet = tea.get_option(options, 'snippet', '') maintain_selection = tea.get_option(options, 'maintain_selection', False) text, range = tea.selection_and_range(context) snippet = tea.indent_snippet(context, snippet, range) snippet = tea.clean_line_endings(context, snippet) # Set up target selection sel_loc = snippet.find('$SELECTED_TEXT') cursor_loc = snippet.find('$0') if maintain_selection: select_range = tea.new_range(sel_loc + range.location, range.length) elif cursor_loc != -1: select_range = tea.new_range(snippet.find('$0') + range.location, 0) else: select_range = None snippet = snippet.replace('$SELECTED_TEXT', text) snippet = snippet.replace('$0', '') if select_range is not None: tea.insert_text_and_select(context, snippet, range, select_range) else: tea.insert_text(context, snippet, range)
def act(context, default=None, fallback_url='', undo_name=None, **syntaxes): ''' Required action method A flexible link generator which uses the clipboard text (if there's a recognizable link there) and formats the snippet based on the active syntax of the context ''' if default is None: return False # Get the text and range text, range = tea.get_single_selection(context, True) if text == None: return False # Get the clipboard contents, parse for a URL process = subprocess.Popen(['pbpaste'], stdout=subprocess.PIPE) clipboard, error = process.communicate(None) # Construct the default link url = format_hyperlink(clipboard, fallback_url) # Get the snippet based on the root zone snippet = tea.select_from_zones(context, range, default, **syntaxes) # Indent the snippet snippet = tea.indent_snippet(context, snippet, range) snippet = tea.construct_snippet(text, snippet) snippet = snippet.replace('$URL', tea.sanitize_for_snippet(url)) return tea.insert_snippet_over_range(context, snippet, range, undo_name)
def act(context, first_snippet='', following_snippet='', final_append='', undo_name=None): ''' Required action method This only allows a single selection (enforced through the utility functions) then parses over the lines and inserts a snippet Theoretically we could allow discontiguous selections; have to consider it if recipes get snippet capabilities ''' text, range = tea.get_single_selection(context, True) if text == None: return False # Split the text into lines, maintaining the linebreaks lines = text.splitlines(True) # Compile the regex for quicker action on lots of lines parser = re.compile(r'(\s*)(.*?)(\s*(\r?\n)|$)') # Indent the snippets first = tea.indent_snippet(context, first_snippet, range) following = tea.indent_snippet(context, following_snippet, range) # Loop over lines and construct the snippet snippet = '' # This is the number of snippets processed, not lines count = 1 for line in lines: content = parser.search(line) # Only wrap the line if there's some content if content.group(2) != '': if count == 1: segment = tea.construct_snippet(content.group(2), first) else: segment = tea.construct_snippet(content.group(2), following) snippet += content.group(1) + segment + content.group(3) count += 1 else: snippet += line snippet += final_append return tea.insert_snippet_over_range(context, snippet, range, undo_name)
def act(context, first_snippet='', following_snippet='', final_append='', undo_name=None): ''' Required action method Wraps the selected text in a snippet Support for discontiguous selections will be implemented when recipes can support snippets; until then only first_snippet will be used ''' # TODO: change to a loop once snippets in recipes are supported # This function will handle the logic of when to use open vs. multi text, range = tea.get_single_selection(context) if text == None: text = '' # Indent the snippet snippet = tea.indent_snippet(context, first_snippet + final_append, range) snippet = tea.construct_snippet(text, snippet) return tea.insert_snippet_over_range(context, snippet, range, undo_name)
def act(context, default=None, undo_name=None, **syntaxes): ''' Required action method Inserts an arbitrary text snippet after the cursor with provisions for syntax-specific alternatives Accepts $SELECTED_TEXT placeholder This method requires at least the snippet default to be defined in the XML ''' if default is None: return False # Get the cursor position text, range = tea.get_single_selection(context) # Check for root-zone specific override snippet = tea.select_from_zones(context, range, default, **syntaxes) # Indent the snippet snippet = tea.indent_snippet(context, snippet, range) # Construct the snippet snippet = tea.construct_snippet(text, snippet) # Insert that snippet! return tea.insert_snippet_over_range(context, snippet, range, undo_name)
def act(controller, bundle, options): context = tea.get_context(controller) # Get the options alpha_numeric = tea.get_option(options, 'alpha_numeric', True) extra_characters = tea.get_option(options, 'extra_characters', '_-') bidirectional = tea.get_option(options, 'bidirectional', True) snippet = tea.get_option(options, 'snippet', '<$SELECTED_TEXT>$0</$WORD>') mode = tea.get_option(options, 'mode', '') # Fetch the word range = context.selectedRange() word, new_range = tea.get_word_or_selection(context, range, alpha_numeric, extra_characters, bidirectional) if word == '': # No word, so nothing further to do return False # If we're using $WORD, make sure the word is just a word if snippet.find('$WORD') >= 0: fullword = word word = tea.parse_word(word) if word is None: word = '' else: fullword = word # Process that sucker! if mode == 'zen' and fullword.find(' ') < 0: # Explicitly load zen settings zen_settings = settings_loader.load_settings() zen_core.update_settings(zen_settings) # Set up the config variables zen_core.newline = tea.get_line_ending(context) zen_settings['variables']['indentation'] = tea.get_indentation_string(context) # This allows us to use smart incrementing tab stops in zen snippets point_ix = [0] def place_ins_point(text): if not point_ix[0]: point_ix[0] += 1 return '$0' else: return '' zen_core.insertion_point = place_ins_point # Determine doctype as best we can based on file extension doc_type = tea.get_zen_doctype(context) # Prepare the snippet snippet = zen_core.expand_abbreviation(fullword, doc_type, 'xhtml') elif mode == 'zen' and tea.is_selfclosing(word): # Self-closing, so construct the snippet from scratch snippet = '<' + fullword if fullword == word and not fullword in ['br', 'hr']: snippet += ' $0 />' else: snippet += ' />$0' # Indent the snippet snippet = tea.indent_snippet(context, snippet, new_range) snippet = tea.clean_line_endings(context, snippet) # Special replacement in case we're using $WORD snippet = snippet.replace('$WORD', word) snippet = snippet.replace('$SELECTED_TEXT', fullword) cursor_loc = snippet.find('$0') if cursor_loc != -1: select_range = tea.new_range(cursor_loc + new_range.location, 0) snippet = snippet.replace('$0', '') tea.insert_text_and_select(context, snippet, new_range, select_range) else: tea.insert_text(context, snippet, new_range)
def wrap(self, context, abbr, profile_name='xhtml'): # Set up the config variables zen_settings = settings_loader.load_settings() zen.update_settings(zen_settings) zen.newline = self.safe_str(tea.get_line_ending(context)) zen_settings['variables']['indentation'] = self.safe_str(tea.get_indentation_string(context)) # This allows us to use smart incrementing tab stops in zen snippets point_ix = [0] def place_ins_point(text): if not point_ix[0]: point_ix[0] += 1 return '$0' else: return '' zen.insertion_point = place_ins_point text, rng = tea.selection_and_range(context) if not text: # no selection, find matching tag content = context.string() start, end = html_matcher.match(content, rng.location) if start is None: # nothing to wrap return False def is_space(char): return char.isspace() or char in r'\n\r' # narrow down selection until first non-space character while start < end: if not is_space(content[start]): break start += 1 while end > start: end -= 1 if not is_space(content[end]): end += 1 break rng = tea.new_range(start, end - start) text = tea.get_selection(context, rng) # Fetch the doctype based on file extension doc_type = tea.get_zen_doctype(context) text = self.unindent(context, text) # Damn Python's encodings! Have to convert string to ascii before wrapping # and then back to utf-8 result = zen.wrap_with_abbreviation(self.safe_str(abbr), self.safe_str(text), doc_type, profile_name) result = unicode(result, 'utf-8') result = tea.indent_snippet(context, result, rng) result = tea.clean_line_endings(context, result) cursor_loc = result.find('$0') if cursor_loc != -1: select_range = tea.new_range(cursor_loc + rng.location, 0) result = result.replace('$0', '') tea.insert_text_and_select(context, result, rng, select_range) else: tea.insert_text(context, result, rng)
def act( context, default=None, alpha_numeric=True, extra_characters="", bidirectional=True, mode=None, close_string="", undo_name=None, **syntaxes ): """ Required action method Transforms the word under the cursor (or the word immediately previous to the cursor) into a snippet (or processes it using zen-coding) The snippet offers two placeholders: $SELECTED_TEXT: replaced with the word, or any selected text $WORD: if text is selected, replaced just with the first word """ if default is None: return False range = tea.get_single_range(context, True) if range == None: return False # Check for specific zone override snippet = tea.select_from_zones(context, range, default, **syntaxes) # Fetch the word word, new_range = tea.get_word_or_selection(context, range, alpha_numeric, extra_characters, bidirectional) if word == "": # No word, so nothing further to do return False # If we're using $WORD, make sure the word is just a word if snippet.find("$WORD") >= 0: fullword = word word = tea.parse_word(word) if word is None: word = "" else: fullword = word # We've got some extra work if the mode is HTML or zen # This is a really hacky solution, but I can't think of a concise way to # represent this functionality via XML if mode == "zen" and fullword.find(" ") < 0: # Set up the config variables zen_core.newline = tea.get_line_ending(context) # This allows us to use smart incrementing tab stops in zen snippets global point_ix point_ix = 0 def place_ins_point(text): globals()["point_ix"] += 1 return "$%s" % point_ix zen_core.insertion_point = place_ins_point zen_core.sub_insertion_point = place_ins_point zen_core.selfclosing_string = tea.get_tag_closestring(context) zen_settings["indentation"] = tea.get_indentation_string(context) # Detect the type of document we're working with zones = {"css, css *": "css", "xsl, xsl *": "xsl", "xml, xml *": "xml"} doc_type = tea.select_from_zones(context, range, "html", **zones) # Prepare the snippet snippet = zen_core.expand_abbr(fullword, doc_type) elif (mode == "zen" or mode == "html") and tea.is_selfclosing(word): # Self-closing, so construct the snippet from scratch snippet = "<" + fullword if fullword == word and not fullword in ["br", "hr"]: snippet += " $1" snippet += "$E_XHTML>$0" # Indent the snippet snippet = tea.indent_snippet(context, snippet, new_range) # Special replacement in case we're using $WORD snippet = snippet.replace("$WORD", word) # Construct the snippet snippet = tea.construct_snippet(fullword, snippet) return tea.insert_snippet_over_range(context, snippet, new_range, undo_name)