def act(context, default=None, undo_name=None, **syntaxes): ''' Required action method default parameter is not a snippet, but should contain the $SELECTED_TEXT placeholder ''' # Get the selected ranges ranges = tea.get_ranges(context) if len(ranges) is 1: # Since we've only got one selection we can use a snippet range = ranges[0] insertion = tea.select_from_zones(context, range, default, **syntaxes) # Make sure the range is actually a selection if range.length > 0: text = tea.get_selection(context, range) snippet = '${1:' + insertion.replace('$SELECTED_TEXT', '${2:$SELECTED_TEXT}') + '}$0' else: # Not a selection, just wrap the cursor text = '' snippet = insertion.replace('$SELECTED_TEXT', '$1') + '$0' snippet = tea.construct_snippet(text, snippet) return tea.insert_snippet_over_range(context, snippet, range, undo_name) # Since we're here, it must not have been a single selection insertions = tea.new_recipe() for range in ranges: insertion = tea.select_from_zones(context, range, default, **syntaxes) text = tea.get_selection(context, range) text = insertion.replace('$SELECTED_TEXT', text) insertions.addReplacementString_forRange_(text, range) if undo_name is not None: insertions.setUndoActionName_(undo_name) return context.applyTextRecipe_(insertions)
def act(context, input=None, default=None, **syntaxes): ''' Required action method input dictates what fills the placeholder if there is no selection: - word - line default and syntaxes will replace $EDITOR_SELECTION with a URL escaped version of the selected text (or input, if no selected text) ''' text, range = tea.get_single_selection(context) if text is None: range = tea.get_single_range(context) if input == 'word': text, range = tea.get_word(context, range) elif input == 'line': text, range = tea.get_line(context, range) # If we still don't have text, there's nothing to work with if text is None: return False # URL escape the selected text text = urllib.quote_plus(text) url = tea.select_from_zones(context, range, default, **syntaxes) # Got the URL, let's run the URL # DEPRECATED: please use $EDITOR_SELECTION instead url = url.replace('$SELECTED_TEXT', text) url = url.replace('$EDITOR_SELECTION', text) NSWorkspace.sharedWorkspace().openURL_(NSURL.URLWithString_(url)) # Because this gets passed through to Obj-C, using int prevents beeping return True
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) snippet = tea.construct_snippet(text, snippet) snippet = snippet.replace("$URL", tea.sanitize_for_snippet(url)) return tea.insert_snippet(context, snippet)
def get_syntax(self): """ Returns current editor's syntax mode @return: str """ zones = {"css, css *": "css", "xsl, xsl *": "xsl", "xml, xml *": "xml", "haml, haml *": "haml"} rng = tea.get_first_range(self._context) return tea.select_from_zones(self._context, rng, "html", **zones)
def get_syntax(self): """ Returns current editor's syntax mode @return: str """ zones = { 'css, css *': 'css', 'xsl, xsl *': 'xsl', 'xml, xml *': 'xml', 'haml, haml *': 'haml' } rng = tea.get_first_range(self._context) return tea.select_from_zones(self._context, rng, 'html', **zones)
def act(context, default=None, prefix_selection=False, suffix_selection=False, undo_name=None, **syntaxes): ''' Required action method Inserts arbitrary text over all selections; specific text can be syntax-specific (same procedure as Wrap Selection In Link) If you set prefix_selection to true, the inserted text will precede any selected text; if suffix_selection is true it will follow any selected text; if both are true it will wrap the text ''' # Grab the ranges ranges = tea.get_ranges(context) # Set up our text recipe insertions = tea.new_recipe() for range in ranges: if prefix_selection or suffix_selection: # Get the selected text text = tea.get_selection(context, range) if prefix_selection: text = '$INSERT' + text if suffix_selection: text += '$INSERT' # If empty selection, only insert one if text == '$INSERT$INSERT': text = '$INSERT' else: text = '$INSERT' # Check for zone-specific insertion insert = tea.select_from_zones(context, range, default, **syntaxes) text = text.replace('$INSERT', insert) text = text.replace('$TOUCH', '') # Insert the text, or replace the selected text if range.length is 0: insertions.addInsertedString_forIndex_(text, range.location) else: insertions.addReplacementString_forRange_(text, range) # Set undo name and run the recipe if undo_name != None: insertions.setUndoActionName_(undo_name) reset_cursor = False if len(ranges) is 1 and ranges[0].length is 0: # Thanks to addInsertedString's wonkiness, we have to reset the cursor reset_cursor = True # Espresso beeps if I return True or False; hence this weirdness return_val = context.applyTextRecipe_(insertions) if reset_cursor: new_range = tea.new_range(ranges[0].location + len(text), 0) tea.set_selected_range(context, new_range) return return_val
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 $EDITOR_SELECTION 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) # Construct the snippet snippet = tea.construct_snippet(text, snippet) # Insert that snippet! return tea.insert_snippet(context, snippet)
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: $EDITOR_SELECTION: 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 # TODO remove it 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): point_ix[0] += 1 return '$%s' % point_ix[0] zen_core.insertion_point = place_ins_point # 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) # Setup the zen profile based on doc_type and XHTML status profile = {} if doc_type == 'html': close_string = tea.get_tag_closestring(context) if close_string == '/': profile['self_closing_tag'] = True elif close_string != ' /': profile['self_closing_tag'] = False elif doc_type == 'xml': profile = {'self_closing_tag': True, 'tag_nl': True} zen_core.setup_profile('tea_profile', profile) # Prepare the snippet snippet = zen_core.expand_abbreviation(fullword, doc_type, 'tea_profile') 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' # 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)
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)