├── Commands ├── Copy as RTF.tmCommand ├── Create CSS from Theme.plist ├── Create HTML from Document : Selection with Lines.plist ├── Create HTML from Document : Selection.plist ├── Insert Scratch Snippet.plist ├── Paste Selection : Line Online….tmCommand ├── Record Scratch Snippet.plist └── Restart TextMate.plist ├── Preferences ├── Folding - Regular Expressions.tmPreferences ├── Properties Comments.tmPreferences ├── Properties Completions.tmPreferences ├── Smart Pairs (Regex Character Class).tmPreferences ├── Spell Checking: Disable for CamelCase Words.tmPreferences └── Style: Separator.tmPreferences ├── README.mdown ├── Support ├── lib │ ├── copy_as_rtf.rb │ └── doctohtml.rb └── nibs │ └── pastebin.nib │ ├── classes.nib │ ├── info.nib │ └── keyedobjects.nib ├── Syntaxes ├── FormatString.tmLanguage ├── Properties.tmLanguage └── Regular Expressions (Oniguruma).tmLanguage └── info.plist /Commands/Copy as RTF.tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby18 -rjcode -Ku 9 | 10 | require "#{ENV['TM_BUNDLE_SUPPORT']}/lib/copy_as_rtf.rb" 11 | require "#{ENV['TM_SUPPORT_PATH']}/lib/progress.rb" 12 | 13 | doc = RtfExporter.new.generate_rtf( STDIN.read ) 14 | `echo "hi" | pbcopy` 15 | Kernel.open('|pbcopy','w') do |f| 16 | f.write(doc) 17 | end 18 | print doc 19 | 20 | input 21 | selection 22 | inputFormat 23 | xml 24 | keyEquivalent 25 | ^~@c 26 | name 27 | Copy Document / Selection as RTF 28 | outputCaret 29 | afterOutput 30 | outputFormat 31 | text 32 | outputLocation 33 | discard 34 | uuid 35 | 6F9D791B-B8E5-456D-A574-1B5C71F232FF 36 | version 37 | 2 38 | 39 | 40 | -------------------------------------------------------------------------------- /Commands/Create CSS from Theme.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby18 9 | require "#{ENV['TM_BUNDLE_SUPPORT']}/lib/doctohtml.rb" 10 | print generate_stylesheet_from_theme() 11 | input 12 | none 13 | inputFormat 14 | xml 15 | keyEquivalent 16 | 17 | name 18 | Create CSS From Current Theme 19 | output 20 | openAsNewDocument 21 | uuid 22 | ED204720-38FC-427C-B91E-D6AE866DAE3A 23 | 24 | 25 | -------------------------------------------------------------------------------- /Commands/Create HTML from Document : Selection with Lines.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby18 -rjcode -Ku 9 | require "#{ENV['TM_BUNDLE_SUPPORT']}/lib/doctohtml.rb" 10 | require "#{ENV['TM_SUPPORT_PATH']}/lib/progress.rb" 11 | unit = ENV.has_key?('TM_SELECTED_TEXT') ? 'selection' : 'document' 12 | TextMate.call_with_progress(:message => "Creating HTML version of #{unit}…") do 13 | print document_to_html( STDIN.read, { :line_numbers => true, :include_css => !ENV.has_key?('TM_SELECTED_TEXT') } ) 14 | end 15 | input 16 | selection 17 | inputFormat 18 | xml 19 | name 20 | Create HTML From Document / Selection With Line Numbers 21 | output 22 | openAsNewDocument 23 | require 24 | 25 | 26 | name 27 | Themes 28 | uuid 29 | A4380B27-F366-4C70-A542-B00D26ED997E 30 | 31 | 32 | uuid 33 | 7AE6F783-F162-4063-850D-1441441849D8 34 | 35 | 36 | -------------------------------------------------------------------------------- /Commands/Create HTML from Document : Selection.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby18 -rjcode -Ku 9 | require "#{ENV['TM_BUNDLE_SUPPORT']}/lib/doctohtml.rb" 10 | require "#{ENV['TM_SUPPORT_PATH']}/lib/progress.rb" 11 | unit = ENV.has_key?('TM_SELECTED_TEXT') ? 'selection' : 'document' 12 | TextMate.call_with_progress(:message => "Creating HTML version of #{unit}…") do 13 | print document_to_html( STDIN.read, :include_css => !ENV.has_key?('TM_SELECTED_TEXT') ) 14 | end 15 | 16 | input 17 | selection 18 | inputFormat 19 | xml 20 | name 21 | Create HTML From Document / Selection 22 | output 23 | openAsNewDocument 24 | require 25 | 26 | 27 | name 28 | Themes 29 | uuid 30 | A4380B27-F366-4C70-A542-B00D26ED997E 31 | 32 | 33 | uuid 34 | 950B3108-E2E3-414E-9C4C-EE068F59A895 35 | 36 | 37 | -------------------------------------------------------------------------------- /Commands/Insert Scratch Snippet.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | cat ${TMP:-/tmp}/TextMate-ScratchSnippet.txt 9 | input 10 | none 11 | keyEquivalent 12 | ^~s 13 | name 14 | Insert Scratch Snippet 15 | output 16 | insertAsSnippet 17 | uuid 18 | ADFED53B-16EC-4956-A6A7-3EA2B8140F86 19 | 20 | 21 | -------------------------------------------------------------------------------- /Commands/Paste Selection : Line Online….tmCommand: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/usr/bin/env ruby18 -rjcode -KU 9 | 10 | BUNDLE_SUPPORT = ENV['TM_BUNDLE_SUPPORT'] 11 | SUPPORT_PATH = ENV['TM_SUPPORT_PATH'] 12 | 13 | PASTE_URL = ENV['TM_PASTIE_URL'] || 'http://pastie.org/pastes' 14 | 15 | require "#{BUNDLE_SUPPORT}/lib/doctohtml.rb" 16 | require "#{SUPPORT_PATH}/lib/textmate" 17 | require "#{SUPPORT_PATH}/lib/tm/detach" 18 | require "#{SUPPORT_PATH}/lib/progress" 19 | require "#{SUPPORT_PATH}/lib/escape" 20 | require 'cgi' 21 | require 'zlib' 22 | require "yaml" 23 | require "iconv" 24 | require "tempfile" 25 | 26 | PREFS_FILE = "#{ENV['HOME']}/Library/Preferences/com.macromates.textmate.paste_online.yaml" 27 | 28 | def load_prefs 29 | prefs = File.open(PREFS_FILE) { |file| YAML.load(file) } rescue { } 30 | selected = prefs['selectedDestinations'] || [[0]] 31 | return { 'selectedDestinations' => selected } 32 | end 33 | 34 | def save_prefs(params) 35 | selected = params['selectedDestinations'].dup 36 | File.open(PREFS_FILE, "w") { |file| YAML.dump({ 'selectedDestinations' => selected }, file) } 37 | end 38 | 39 | def get_destinations 40 | proclist = `ps -x -o command` 41 | active = [] 42 | 43 | destinations = [{ 'name' => 'Open in Browser' }, { 'name' => 'Send to Clipboard' }] 44 | node = nil 45 | 46 | active = proclist.scan(%r{^(?:/.*\.app/Contents/MacOS/(Quicksilver)\b)}).flatten 47 | 48 | if active.include?('Quicksilver') 49 | destinations << { 'name' => 'Send to Quicksilver' } 50 | end 51 | 52 | prefs = load_prefs 53 | 54 | window_title = if ENV.has_key? 'TM_SELECTED_TEXT'; 'Paste Selection Online'; else 'Paste Document Online'; end 55 | default_wrap = (ENV['TM_SCOPE'] =~ /^text\./) ? 1 : 0 56 | parameters = { 57 | 'windowTitle' => window_title, 58 | 'destinations' => destinations, 59 | 'selectedDestinations' => prefs['selectedDestinations'], 60 | 'private' => true, 61 | 'lineWrap' => default_wrap, 62 | }.to_plist 63 | 64 | res = %x{ "$DIALOG" -cmp #{e_sh parameters} pastebin } 65 | exit if $? != 0 66 | 67 | res = OSX::PropertyList.load(res) 68 | exit unless res.has_key? 'returnCode' 69 | 70 | save_prefs(res) 71 | 72 | actions = [] 73 | res['selectedDestinations'].to_a.each do |index_array| 74 | path = [] 75 | node = destinations 76 | index_array.each do |index| 77 | path << node[index.to_i]['name'] 78 | node = node[index.to_i]['children'] 79 | end 80 | actions << path.join(' ') 81 | end 82 | 83 | [ actions.join("\n"), res['private'], res['lineWrap'] ] 84 | end 85 | 86 | TM_APP_PATH = TextMate.app_path 87 | 88 | def find_language_ext 89 | bundle_dirs = [ 90 | File.expand_path('~/Library/Application Support/TextMate/Bundles'), 91 | '/Library/Application Support/TextMate/Bundles', 92 | TM_APP_PATH + '/Contents/SharedSupport/Bundles' 93 | ] 94 | 95 | if scope = ENV['TM_SCOPE'] then 96 | scope = scope.split(' ').first 97 | bundle_dirs.each do |dir| 98 | Dir.glob(dir + '/*.tmbundle/Syntaxes/*.{plist,tmLanguage}') do |filename| 99 | File.open(filename) do |io| 100 | begin 101 | plist = OSX::PropertyList.load(io) 102 | if scope == plist['scopeName'].to_s then 103 | return Array(plist['fileTypes']).first || 'txt' 104 | end 105 | rescue Exception => e 106 | abort "Error while parsing “#{filename}”\n\n#{e}" 107 | end 108 | end 109 | end 110 | end 111 | end 112 | 113 | ext = File.extname(ENV['TM_FILENAME'].to_s).sub(/\A\./, '') 114 | ext.empty? ? 'txt' : ext 115 | end 116 | 117 | def strip_leading(text, ch = ' ') 118 | count = text.gsub(/<[^>]+>/, '').split("\n").map { |e| e =~ /^#{ch}*(?!#{ch}|$)/ ? $&.length : nil }.reject { |e| e.nil? }.min 119 | text.send(text.respond_to?(:lines) ? :lines : :to_s).map { |line| count.times { line.sub!(/^((<[^>]+>)*)#{ch}/, '\1') }; line }.join 120 | end 121 | 122 | URL_REGEXP = %r{ 123 | \A(https?://) # scheme 124 | ([0-9a-z_!~*\'()-]+\.)* # tertiary domain(s) -- e.g. www. 125 | ([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\. # second level domain 126 | ([a-z]{2,6}) # first level domain -- e.g. .com or .museum 127 | (:[0-9]{1,4})? # port number -- e.g. :80 128 | ((/?)| # a slash isn’t required if there is no file name 129 | (/[0-9a-z_!~*\'().;?:@&=+$,%#-]+)+/?)\z # path 130 | }xi 131 | 132 | def connect_to_server(name, url, *args) 133 | $status, res, response = :unknown, nil, '???' 134 | 135 | tmpFile = Tempfile.new('tm_paste_headers') 136 | tmpFilePath = tmpFile.path.dup 137 | tmpFile.close! 138 | 139 | server = $1 if url =~ %r{.*?://(.*?)(/.*)?$} 140 | TextMate.call_with_progress(:title => "Paste to #{name}", :message => "Contacting Host “#{server}”…", :cancel => lambda { $status = :cancel; Process.kill("INT", -Process.pid) }) do 141 | thr = Thread.new { sleep 60.0; $status = :timeout; Process.kill("INT", -Process.pid) rescue nil } 142 | 143 | oldpgid = Process.getpgid(0) 144 | Process.setpgid(0, 0) 145 | rd, wr = IO.pipe 146 | pid = fork do 147 | STDOUT.reopen(wr) 148 | rd.close 149 | exec('curl', url, "-D#{tmpFilePath}", '-sLo/dev/null', '-w%{url_effective}', *args) 150 | end 151 | Process.setpgid(0, oldpgid) 152 | wr.close 153 | res = rd.read 154 | Process.wait(pid) 155 | 156 | $status = :success if $?.exitstatus == 0 && $status == :unknown 157 | 158 | thr.kill unless $status == :timeout 159 | thr.join 160 | end 161 | 162 | response = $1 if File.read(tmpFilePath) =~ /\AHTTP\/[0-9.]+ (.*?)\r?\n/ 163 | File.unlink(tmpFilePath) 164 | 165 | $status = :error if res !~ URL_REGEXP || res == url # pastie returns the initial URL on some errors 166 | return $status, res, response 167 | end 168 | 169 | def paste_stdin(priv, wrap) 170 | xml = STDIN.read 171 | 172 | text_file = Tempfile.new('tm_paste_text') 173 | html_file = Tempfile.new('tm_paste_html') 174 | 175 | text_file << CGI::unescapeHTML(xml.gsub(/<[^>]*>/, '')) 176 | text_file.close 177 | 178 | gz = Zlib::GzipWriter.new(html_file) 179 | gz.write(document_to_html(strip_leading(strip_leading(xml, " "), "\t"))) 180 | gz.close 181 | html_file.close 182 | 183 | author = ENV['TM_AUTHOR'] || "#{ENV['TM_FULLNAME']} (#{ENV['USER']})" 184 | ext = find_language_ext 185 | 186 | start_time = Time.now 187 | $status, res, response = connect_to_server("Pastie", PASTE_URL, 188 | "-HExpect:", 189 | "-Fpaste[parser]=plaintext", 190 | "-Fpaste[restricted]=#{priv}", 191 | "-Fpaste[wrap]=#{wrap}", 192 | "-Fpaste[display_name]=#{author}", 193 | "-Fpaste[file_extension]=#{ext}", 194 | "-Fpaste[body]=<#{text_file.path}", 195 | "-Fpaste[textmate_html_gz]=<#{html_file.path}" 196 | ) 197 | 198 | open(File.expand_path('~/Library/Logs/Pastie.log'), 'a') do |io| 199 | amount = (File.size(text_file.path) + File.size(html_file.path)).to_s.gsub(/\d{1,3}(?=(\d{3})+(?!\d))/, '\0,') + " bytes" 200 | time_elapsed = '%.1f seconds' % (Time.now - start_time) 201 | io << start_time.strftime('%F %T %Z: ') << response << " " << 202 | case $status 203 | when :timeout then "Timeout pasting #{amount} after #{time_elapsed}\n" 204 | when :cancel then "User cancelled pasting of #{amount} after #{time_elapsed}\n" 205 | when :error then "Error after #{time_elapsed} pasting #{amount}\n" 206 | else "Pasted #{amount} in #{time_elapsed}: #{res}\n" 207 | end 208 | end 209 | 210 | case $status 211 | when :timeout then TextMate::UI.alert(:warning, "Timeout Pasting", "There was a problem pasting your text (timeout).", "OK") 212 | when :error then TextMate::UI.alert(:warning, "Error Pasting", "There was a problem pasting your text, pastie.org responded with #{response}", "OK") 213 | else false 214 | end 215 | 216 | return $status == :success ? res : nil 217 | end 218 | 219 | TextMate.detach { 220 | dests, priv, wrap = get_destinations 221 | unless dests.empty? 222 | if url = paste_stdin(priv, wrap) 223 | if dests.include?('Send to Clipboard') 224 | IO.popen('pbcopy', 'w') { |io| io << url } 225 | end 226 | if dests.include?('Open in Browser') 227 | %x{ open #{e_sh url} } 228 | end 229 | if dests.include?('Send to Quicksilver') 230 | %x{osascript <<'APPLESCRIPT' 231 | tell application "Quicksilver" 232 | activate 233 | set selection to "#{url}" 234 | end tell 235 | APPLESCRIPT} 236 | end 237 | end 238 | end 239 | } 240 | 241 | fallbackInput 242 | document 243 | input 244 | selection 245 | inputFormat 246 | xml 247 | keyEquivalent 248 | ^~V 249 | name 250 | Paste Document / Selection Online… 251 | outputCaret 252 | afterOutput 253 | outputFormat 254 | text 255 | outputLocation 256 | discard 257 | uuid 258 | 6E779E48-F146-49BF-B60C-EFDFD1380772 259 | version 260 | 2 261 | 262 | 263 | -------------------------------------------------------------------------------- /Commands/Record Scratch Snippet.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | cat > ${TMP:-/tmp}/TextMate-ScratchSnippet.txt 9 | fallbackInput 10 | line 11 | input 12 | selection 13 | name 14 | Record Scratch Snippet 15 | output 16 | discard 17 | uuid 18 | 5F225755-5840-44CF-BC26-2D484DE833A0 19 | 20 | 21 | -------------------------------------------------------------------------------- /Commands/Restart TextMate.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | beforeRunningCommand 6 | nop 7 | command 8 | #!/bin/sh 9 | 10 | { osascript -e "tell app \"$(basename "$TM_APP_PATH")\" to quit" 11 | 12 | while ps >/dev/null -xp "$PPID"; do 13 | if (( ++n == 10 )); then 14 | "$DIALOG" </dev/null alert --title "Relaunch Timed Out" --body "Unable to exit TextMate." --button1 OK 15 | exit 16 | fi 17 | sleep .2; 18 | done 19 | 20 | open "$TM_APP_PATH" --args -disableSessionRestore NO 21 | 22 | } &>/dev/null & 23 | input 24 | none 25 | keyEquivalent 26 | ^@q 27 | name 28 | Relaunch TextMate 29 | output 30 | discard 31 | uuid 32 | E5142394-B07A-11D9-8EC4-000D93589AF6 33 | 34 | 35 | -------------------------------------------------------------------------------- /Preferences/Folding - Regular Expressions.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Folding (Regular Expressions) 7 | scope 8 | source.regexp.oniguruma 9 | settings 10 | 11 | foldingStartMarker 12 | (/\*|\{|\() 13 | foldingStopMarker 14 | (\*/|\}|\)) 15 | 16 | uuid 17 | A856C6FA-D67B-44F1-9440-052F86CB66E8 18 | 19 | 20 | -------------------------------------------------------------------------------- /Preferences/Properties Comments.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Properties: Comments 7 | scope 8 | source.tm-properties 9 | settings 10 | 11 | shellVariables 12 | 13 | 14 | name 15 | TM_COMMENT_START 16 | value 17 | # 18 | 19 | 20 | 21 | uuid 22 | AD495D39-E4CE-4790-8263-92851356C2F2 23 | 24 | 25 | -------------------------------------------------------------------------------- /Preferences/Properties Completions.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Properties: Completions 7 | scope 8 | source.tm-properties 9 | settings 10 | 11 | completions 12 | 13 | exclude 14 | excludeFiles 15 | excludeDirectories 16 | excludeInBrowser 17 | excludeInFolderSearch 18 | excludeInFileChooser 19 | excludeFilesInBrowser 20 | excludeDirectoriesInBrowser 21 | include 22 | includeFiles 23 | includeDirectories 24 | includeInBrowser 25 | includeInFileChooser 26 | includeFilesInBrowser 27 | includeDirectoriesInBrowser 28 | includeFilesInFileChooser 29 | projectDirectory 30 | windowTitle 31 | scopeAttributes 32 | theme 33 | fontName 34 | fontSize 35 | fileType 36 | binary 37 | showInvisibles 38 | tabSize 39 | softTabs 40 | spellChecking 41 | spellingLanguage 42 | 43 | 44 | uuid 45 | CE48C640-F525-4FFC-AADE-5EBB676D0705 46 | 47 | 48 | -------------------------------------------------------------------------------- /Preferences/Smart Pairs (Regex Character Class).tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Smart Typing Pairs (Regex Character Class) 7 | scope 8 | constant.other.character-class.set.regexp 9 | settings 10 | 11 | smartTypingPairs 12 | 13 | 14 | uuid 15 | 247A4984-203C-46ED-B973-82A7196A5C5C 16 | 17 | 18 | -------------------------------------------------------------------------------- /Preferences/Spell Checking: Disable for CamelCase Words.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Spell Checking: Disable for CamelCase Words 7 | scope 8 | meta.word.camel-case 9 | settings 10 | 11 | spellChecking 12 | 0 13 | 14 | uuid 15 | EAACA103-A5C9-4D33-BB23-BA908CB83F22 16 | 17 | 18 | -------------------------------------------------------------------------------- /Preferences/Style: Separator.tmPreferences: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | name 6 | Style: Separator 7 | scope 8 | meta.separator 9 | settings 10 | 11 | background 12 | #3467D1 13 | foreground 14 | #FFFFFF 15 | 16 | uuid 17 | DA3A550A-F4AF-4CFD-935F-8687FA17DC4B 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | You can install this bundle in TextMate by opening the preferences and going to the bundles tab. After installation it will be automatically updated for you. 4 | 5 | # General 6 | 7 | * [Bundle Styleguide](http://kb.textmate.org/bundle_styleguide) — _before you make changes_ 8 | * [Commit Styleguide](http://kb.textmate.org/commit_styleguide) — _before you send a pull request_ 9 | * [Writing Bug Reports](http://kb.textmate.org/writing_bug_reports) — _before you report an issue_ 10 | 11 | # License 12 | 13 | If not otherwise specified (see below), files in this repository fall under the following license: 14 | 15 | Permission to copy, use, modify, sell and distribute this 16 | software is granted. This software is provided "as is" without 17 | express or implied warranty, and with no claim as to its 18 | suitability for any purpose. 19 | 20 | An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a “-license” suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example “tidy” is accompanied by “tidy-license.txt”. -------------------------------------------------------------------------------- /Support/lib/copy_as_rtf.rb: -------------------------------------------------------------------------------- 1 | require 'rexml/document' 2 | 3 | $: << ENV['TM_SUPPORT_PATH'] + '/lib' 4 | require "textmate" 5 | require 'cgi' 6 | 7 | class RtfExporter 8 | 9 | def initialize 10 | @styles={} 11 | @colors = "" 12 | @num_colors=1 13 | end 14 | 15 | def generate_rtf input 16 | generate_stylesheet_from_theme 17 | doc = rtf_document input 18 | CGI::unescapeHTML(doc) 19 | end 20 | 21 | def add_style_recursive scopes, style, styles 22 | current = scopes.shift.strip 23 | styles[current] ||= {} 24 | if scopes.empty? 25 | styles[current][:default] = style 26 | else 27 | add_style_recursive scopes, style, styles[current] 28 | end 29 | end 30 | 31 | def add_style_from_textmate_theme name, settings 32 | style = {} 33 | style_names = name.split ',' 34 | style_names.each do |sn| 35 | add_style_recursive sn.split('.'), style, @styles 36 | end 37 | 38 | if fs = settings['fontStyle'] 39 | style[:bold] = fs =~ /bold/ 40 | style[:italic] if fs =~ /italic/ 41 | style[:underline] if fs =~ /underline/ 42 | end 43 | if col = settings['foreground'] 44 | style[:color] = hex_color_to_rtf col 45 | @colors << style[:color] 46 | style[:color_index] = @num_colors+=1 47 | end 48 | end 49 | 50 | def hex_color_to_rtf hex 51 | hex =~ /#(..)(..)(..)/ 52 | r = $1.hex 53 | g = $2.hex 54 | b = $3.hex 55 | return "\\red#{r}\\green#{g}\\blue#{b};" 56 | end 57 | 58 | def generate_stylesheet_from_theme 59 | require "#{ENV['TM_SUPPORT_PATH']}/lib/osx/plist" 60 | 61 | unless theme_plist = load_theme 62 | print "Could not locate your theme file or it may be corrupt or unparsable!" 63 | abort 64 | end 65 | 66 | @font_name = `"$TM_QUERY" --setting fontName`.chomp || 'Menlo-Regular' 67 | @font_size = (`"$TM_QUERY" --setting fontSize`.chomp || 12).to_s 68 | @font_size.sub! /\.\d+$/, '' 69 | @font_size = @font_size.to_i * 2 70 | 71 | @font_name = '"' + @font_name + '"' if @font_name.include?(' ') && 72 | !@font_name.include?('"') 73 | 74 | theme_plist['settings'].each do | setting | 75 | if (!setting['name'] and setting['settings']) 76 | body_fg = setting['settings']['foreground'] || '#000000' 77 | body_fg = hex_color_to_rtf(body_fg) 78 | @colors << body_fg 79 | @colors = body_fg + @colors 80 | next 81 | end 82 | if setting['name'] && setting['scope'] 83 | scope_name = setting['scope'] 84 | add_style_from_textmate_theme scope_name, setting['settings'] 85 | end 86 | end 87 | end 88 | 89 | def color_table 90 | "{\\colortbl#{@colors}}" 91 | end 92 | 93 | def font_table 94 | "{\\fonttbl {\\f0 #{@font_name};}}" 95 | end 96 | 97 | def rtf_document input 98 | <<-RTF_DOC 99 | {\\rtf 100 | #{font_table} 101 | #{color_table} 102 | {\\pard\\ql 103 | \\f0\\fs#{@font_size} #{document_to_rtf input} 104 | }} 105 | RTF_DOC 106 | end 107 | 108 | # {\\rtf 109 | # #{font_table} 110 | # #{color_table} 111 | # {\\pard\\ql 112 | # \\f0\\fs#{@font_size}\\cf1\\b Hello, World!\\line 113 | # \\tab \\cf2 Next Line\\line 114 | # \\tab\\tab\\i \\cf3 Another line 115 | # }} 116 | 117 | def load_theme 118 | return OSX::PropertyList.load(File.open(ENV['TM_CURRENT_THEME_PATH'])) 119 | end 120 | 121 | def detab(str, width) 122 | lines = str.split(/\n/) 123 | lines.each do | line | 124 | line_sans_markup = line.gsub(/<[^>]*>/, '').gsub(/&[^;]+;/i, '.') 125 | while (index = line_sans_markup.index("\t")) 126 | tab = line_sans_markup[0..index].jlength - 1 127 | padding = " " * ((tab / width + 1) * width - tab) 128 | line_sans_markup.sub!("\t", padding) 129 | line.sub!("\t", padding) 130 | end 131 | end 132 | return lines.join("\n") 133 | end 134 | 135 | def strip_leading(text, ch = ' ') 136 | count = text.gsub(/<[^>]+>/, '').split("\n").map { |e| e =~ /^#{ch}*(?!#{ch}|$)/ ? $&.length : nil }.reject { |e| e.nil? }.min 137 | text.send(text.respond_to?(:lines) ? :lines : :to_s).map { |line| count.times { line.sub!(/^((<[^>]+>)*)#{ch}/, '\1') }; line }.join 138 | end 139 | 140 | def document_to_rtf(input, opt = {}) 141 | # Read the source document / selection 142 | # Convert tabs to spaces using configured tab width 143 | input = detab(input, (ENV['TM_TAB_SIZE'] || '2').to_i) 144 | 145 | input = strip_leading(input, " ") 146 | 147 | input.gsub! /\\/, "__backslash__" 148 | input.gsub! /\\n/, "__newline__" 149 | input.gsub! /\n/, "\\\\line\n" 150 | input.gsub! /\{/, "\\{" 151 | input.gsub! /\}/, "\\}" 152 | input.gsub! /__newline__/, "\\\\\\n" 153 | input.gsub! /__backslash__/, "\\\\\\" 154 | 155 | 156 | @style_stack = [] 157 | 158 | # Meat. The poor-man's tokenizer. Fortunately, our input is simple 159 | # and easy to parse. 160 | tokens = input.split(/(<[^>]*>)/) 161 | code_rtf = '' 162 | tokens.each do |token| 163 | case token 164 | when /^<\// 165 | # closing tag 166 | pop_style 167 | when /^<>$/ 168 | # skip empty tags, resulting from name = '' 169 | when /^]+)>$/ 171 | scope = $1 172 | push_style scope 173 | end 174 | else 175 | next if token.empty? 176 | code_rtf << '{' 177 | style = current_style_as_rtf 178 | if style && !style.empty? && !token.strip.empty? 179 | code_rtf << current_style_as_rtf << ' ' 180 | end 181 | code_rtf << token << '}' 182 | end 183 | end 184 | 185 | return code_rtf 186 | end 187 | 188 | def current_style 189 | @style_stack[0] || {} 190 | end 191 | 192 | def get_style_recursive scopes, styles 193 | #scopes -= ["punctuation", "definition"] # nasty workaround hack 194 | 195 | return nil unless styles 196 | cur = scopes.shift.strip 197 | 198 | style = nil 199 | unless scopes.empty? 200 | style = get_style_recursive(scopes, styles[cur]) || style 201 | end 202 | style ||= styles[:default] 203 | end 204 | 205 | def current_style_as_rtf 206 | cur = current_style 207 | rtf = '' 208 | rtf << "\\cf#{cur[:color_index]}" if cur[:color_index] 209 | rtf << "\\b" if cur[:bold] 210 | rtf << "\\i" if cur[:italic] 211 | rtf << "\\ul" if cur[:underline] 212 | rtf 213 | end 214 | 215 | def push_style name 216 | cur = current_style 217 | new_style = get_style_recursive(name.split('.'), @styles) 218 | # p "current: #{cur.inspect}" 219 | new_style = cur.merge new_style if new_style 220 | new_style ||= cur || {} 221 | unless new_style[:color_index] 222 | new_style[:color_index] = 0 223 | end 224 | @style_stack.unshift new_style 225 | new_style 226 | end 227 | 228 | def pop_style 229 | @style_stack.shift 230 | end 231 | 232 | end 233 | 234 | -------------------------------------------------------------------------------- /Support/lib/doctohtml.rb: -------------------------------------------------------------------------------- 1 | # By Brad Choate -- http://bradchoate.com/ 2 | 3 | $: << ENV['TM_SUPPORT_PATH'] + '/lib' 4 | require "textmate" 5 | 6 | # Provides CSS-friendly variations of common Mac fonts that you 7 | # may use in TextMate. Feel free to edit these to your liking... 8 | FONT_MAP = { 9 | /\bcourier\b/i => 'Courier, "MS Courier New"', 10 | /\bbitstream.*mono\b/i => '"Bitstream Vera Sans Mono"', 11 | /\bandale\b/i => '"Andale Mono"', 12 | /\bDejaVuSansMono\b/i => '"DejaVu Sans Mono"' 13 | } 14 | 15 | def load_theme 16 | return OSX::PropertyList.load(File.open(ENV['TM_CURRENT_THEME_PATH'])) 17 | end 18 | 19 | def to_rgba(color) 20 | colors = color.scan /^#(..)(..)(..)(..)/ 21 | r = colors[0][0].hex 22 | g = colors[0][1].hex 23 | b = colors[0][2].hex 24 | a = colors[0][3].hex 25 | return "rgba(#{r}, #{g}, #{b}, #{ format '%0.02f', a / 255.0 })" 26 | end 27 | 28 | def generate_stylesheet_from_theme(theme_class = nil) 29 | theme_class = '' if theme_class == nil 30 | require "#{ENV['TM_SUPPORT_PATH']}/lib/osx/plist" 31 | 32 | unless theme_plist = load_theme 33 | print "Could not locate your theme file!" 34 | abort 35 | end 36 | 37 | theme_comment = theme_plist['comment'] 38 | theme_name = theme_plist['name'] 39 | theme_class.replace(theme_name) 40 | theme_class.downcase! 41 | theme_class.gsub!(/[^a-z0-9_-]/, '_') 42 | theme_class.gsub!(/_+/, '_') 43 | 44 | font_name = `"$TM_QUERY" --setting fontName`.chomp || 'Menlo-Regular' 45 | font_size = (`"$TM_QUERY" --setting fontSize`.chomp || 12).to_s 46 | font_size.sub! /\.\d+$/, '' 47 | 48 | FONT_MAP.each do | font_re, font_alt | 49 | if (font_re.match(font_name)) 50 | font_name = font_alt 51 | break 52 | end 53 | end 54 | 55 | font_name = '"' + font_name + '"' if font_name.include?(' ') && 56 | !font_name.include?('"') 57 | 58 | theme_styles = '' 59 | body_fg = '' 60 | body_bg = '' 61 | selection_bg = '' 62 | pre_selector = "pre.textmate-source.#{theme_class}" 63 | 64 | theme_plist['settings'].each do | setting | 65 | if (!setting['name'] and setting['settings']) 66 | body_bg = setting['settings']['background'] || '#ffffff' 67 | body_fg = setting['settings']['foreground'] || '#000000' 68 | selection_bg = setting['settings']['selection'] 69 | body_bg = to_rgba(body_bg) if body_bg =~ /#.{8}/ 70 | body_fg = to_rgba(body_fg) if body_fg =~ /#.{8}/ 71 | selection_bg = to_rgba(selection_bg) if selection_bg && selection_bg =~ /#.{8}/ 72 | next 73 | end 74 | next unless setting['name'] and setting['scope'] 75 | theme_styles << "/* " + setting['name'] + " */\n" 76 | scope_name = setting['scope'] 77 | scope_name.gsub! /(^|[ ])-[^ ]+/, '' # strip negated scopes 78 | scope_name.gsub! /\./, '_' # change inner '.' to '_' 79 | scope_name.gsub! /(^|[ ])/, '\1.' 80 | scope_name.gsub! /(^|,\s+)/m, '\1' + pre_selector + ' ' 81 | theme_styles << "#{scope_name} {\n" 82 | if (color = setting['settings']['foreground']) 83 | color = to_rgba(color) if color =~ /#.{8}/ 84 | theme_styles << "\tcolor: " + color + ";\n" 85 | end 86 | if (style = setting['settings']['fontStyle']) 87 | theme_styles << "\tfont-style: italic;\n" if style =~ /\bitalic\b/i 88 | theme_styles << "\ttext-decoration: underline;\n" if style =~ /\bunderline\b/i 89 | theme_styles << "\tfont-weight: bold;\n" if style =~ /\bbold\b/i 90 | end 91 | if (color = setting['settings']['background']) 92 | color = to_rgba(color) if color =~ /#.{8}/ 93 | theme_styles << "\tbackground-color: " + color + ";\n" 94 | end 95 | theme_styles << "}\n\n" 96 | end 97 | 98 | if (selection_bg) 99 | # currently, -moz-selection doesn't appear to support alpha transparency 100 | # so, i'm not assigning it until it does. 101 | selection_style = "#{pre_selector} ::selection { 102 | background-color: #{selection_bg}; 103 | }" 104 | else 105 | selection_style = "" 106 | end 107 | 108 | return <]*>/, '').gsub(/&[^;]+;/i, '.') 159 | while (index = line_sans_markup.index("\t")) 160 | tab = line_sans_markup[0..index].jlength - 1 161 | padding = " " * ((tab / width + 1) * width - tab) 162 | line_sans_markup.sub!("\t", padding) 163 | line.sub!("\t", padding) 164 | end 165 | end 166 | return lines.join("\n") 167 | end 168 | 169 | def number(str) 170 | # number each line of input 171 | lines = str.split(/\n/) 172 | n = 0 173 | lines.each do | line | 174 | n += 1 175 | line.gsub!(/^(<\/span>)?/, "\\1#{ sprintf("%5d", n) } ") 176 | end 177 | return lines.join("\n") 178 | end 179 | 180 | def document_to_html(input, opt = {}) 181 | # Read the source document / selection 182 | # Convert tabs to spaces using configured tab width 183 | input = detab(input, (ENV['TM_TAB_SIZE'] || '8').to_i) 184 | 185 | html = '' 186 | 187 | theme_class = '' 188 | if opt[:include_css] 189 | # If you declare a 'http://...' link as a TM_SOURCE_STYLESHEET 190 | # shell variable, that will be used instead of generating a stylesheet 191 | # based on the current theme. 192 | if (ENV['TM_SOURCE_STYLESHEET']) 193 | styles = "\t\n" 194 | else 195 | styles = generate_stylesheet_from_theme(theme_class) 196 | end 197 | 198 | # Head block 199 | html = %{ 200 | 201 | 202 | #{ ENV['TM_FILENAME'] || 'untitled' } 203 | 206 | 207 | 208 | } 209 | end 210 | 211 | # Meat. The poor-man's tokenizer. Fortunately, our input is simple 212 | # and easy to parse. 213 | tokens = input.split(/(<[^>]*>)/) 214 | code_html = '' 215 | tokens.each do |token| 216 | case token 217 | when /^<\// 218 | code_html << "" 219 | when /^<>$/ 220 | # skip empty tags, resulting from name = '' 221 | when /^]+)>$/ 223 | classes = $1.split(/\./) 224 | list = [] 225 | begin 226 | list.push(classes.join('_')) 227 | end while classes.pop 228 | code_html << "" 229 | end 230 | else 231 | code_html << token 232 | end 233 | end 234 | 235 | code_html = number(code_html) if opt[:line_numbers] 236 | 237 | html << "
#{code_html}
" 240 | 241 | if opt[:include_css] 242 | # Closing 243 | html << "\n\n" 244 | end 245 | 246 | return html 247 | end -------------------------------------------------------------------------------- /Support/nibs/pastebin.nib/classes.nib: -------------------------------------------------------------------------------- 1 | { 2 | IBClasses = ( 3 | { 4 | ACTIONS = {"" = id; }; 5 | CLASS = FirstResponder; 6 | LANGUAGE = ObjC; 7 | SUPERCLASS = NSObject; 8 | }, 9 | {CLASS = NSSegmentedControl; LANGUAGE = ObjC; SUPERCLASS = NSControl; }, 10 | { 11 | ACTIONS = {performButtonClick = id; }; 12 | CLASS = NibController; 13 | LANGUAGE = ObjC; 14 | SUPERCLASS = NSObject; 15 | } 16 | ); 17 | IBVersion = 1; 18 | } -------------------------------------------------------------------------------- /Support/nibs/pastebin.nib/info.nib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IBDocumentLocation 6 | 563 18 356 240 0 0 1024 746 7 | IBFramework Version 8 | 446.1 9 | IBLockedObjects 10 | 11 | IBOpenObjects 12 | 13 | 5 14 | 15 | IBSystem Version 16 | 8L127 17 | 18 | 19 | -------------------------------------------------------------------------------- /Support/nibs/pastebin.nib/keyedobjects.nib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textmate/textmate.tmbundle/e6c9b5e9609da8c9157abf5f77b02eff87b24936/Support/nibs/pastebin.nib/keyedobjects.nib -------------------------------------------------------------------------------- /Syntaxes/FormatString.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | comment 6 | 7 | \\, \$, \( 8 | \n, \t 9 | \U, \L, \E, \u, \l 10 | 11 | $0-n | $foo 12 | 13 | ${«var»:[/upcase][/downcase][/(capitalize|titlecase)][/asciify]} 14 | 15 | ${«var»:?«if»:«else»} 16 | 17 | ${«var»:+«if»} 18 | ${«var»:-«else»} 19 | ${«var»:«else»} 20 | 21 | ${«var»/«regexp»/«format»/[giems]} 22 | 23 | (?«var»:«if»:«else») 24 | (?«var»:«if») 25 | 26 | fileTypes 27 | 28 | hideFromUser 29 | 30 | name 31 | Format String 32 | patterns 33 | 34 | 35 | match 36 | \\[\\$(nt] 37 | name 38 | constant.character.escape.format-string 39 | 40 | 41 | match 42 | \\[ULEul] 43 | name 44 | constant.other.reference.format-string 45 | 46 | 47 | captures 48 | 49 | 1 50 | 51 | name 52 | punctuation.definition.variable.begin.format-string 53 | 54 | 55 | comment 56 | $0-n | $foo 57 | match 58 | (\$)(?:\d+|\w+) 59 | name 60 | variable.other.readwrite.format-string 61 | 62 | 63 | captures 64 | 65 | 1 66 | 67 | name 68 | punctuation.definition.transform.begin.format-string 69 | 70 | 2 71 | 72 | name 73 | punctuation.separator.transform.format-string 74 | 75 | 3 76 | 77 | name 78 | invalid.illegal.unknown-transform.format-string 79 | 80 | 4 81 | 82 | name 83 | punctuation.definition.transform.end.format-string 84 | 85 | 86 | comment 87 | ${«var»:[/upcase][/downcase][/(capitalize|titlecase)][/asciify]} 88 | match 89 | (\$\{)\w+(:/)(?:upcase|downcase|capitalize|titlecase|asciify|(.*?))(\}) 90 | name 91 | variable.other.transform.format-string 92 | 93 | 94 | begin 95 | (\$\{)\w+(:\?) 96 | beginCaptures 97 | 98 | 1 99 | 100 | name 101 | punctuation.definition.condition.begin.format-string 102 | 103 | 2 104 | 105 | name 106 | punctuation.separator.condition.format-string 107 | 108 | 109 | comment 110 | ${«var»:?«if»:«else»} 111 | end 112 | \} 113 | endCaptures 114 | 115 | 1 116 | 117 | name 118 | punctuation.definition.condition.end.format-string 119 | 120 | 121 | name 122 | variable.other.condition.binary.format-string 123 | patterns 124 | 125 | 126 | match 127 | \\[:}] 128 | name 129 | constant.character.escape.format-string 130 | 131 | 132 | include 133 | textmate.format-string 134 | 135 | 136 | begin 137 | : 138 | beginCaptures 139 | 140 | 0 141 | 142 | name 143 | punctuation.separator.condition.format-string 144 | 145 | 146 | end 147 | (?=\}) 148 | patterns 149 | 150 | 151 | match 152 | \\[}] 153 | name 154 | constant.character.escape.format-string 155 | 156 | 157 | include 158 | textmate.format-string 159 | 160 | 161 | 162 | 163 | 164 | 165 | begin 166 | (\$\{)\w+(:[-+]?) 167 | beginCaptures 168 | 169 | 1 170 | 171 | name 172 | punctuation.definition.condition.begin.format-string 173 | 174 | 2 175 | 176 | name 177 | punctuation.separator.condition.format-string 178 | 179 | 180 | comment 181 | ${«var»:+«if»} | ${«var»:-«else»} | ${«var»:«else»} 182 | end 183 | \} 184 | endCaptures 185 | 186 | 1 187 | 188 | name 189 | punctuation.definition.condition.end.format-string 190 | 191 | 192 | name 193 | variable.other.condition.unary.format-string 194 | patterns 195 | 196 | 197 | match 198 | \\} 199 | name 200 | constant.character.escape.format-string 201 | 202 | 203 | include 204 | textmate.format-string 205 | 206 | 207 | 208 | 209 | begin 210 | (\$\{)\w+(/) 211 | beginCaptures 212 | 213 | 1 214 | 215 | name 216 | punctuation.definition.replacement.begin.format-string 217 | 218 | 2 219 | 220 | name 221 | punctuation.separator.replacement.format-string 222 | 223 | 224 | comment 225 | ${«var»/«regexp»/«format»/[giems]} 226 | end 227 | \} 228 | endCaptures 229 | 230 | 1 231 | 232 | name 233 | punctuation.definition.replacement.end.format-string 234 | 235 | 236 | name 237 | variable.other.replacement.format-string 238 | patterns 239 | 240 | 241 | match 242 | \\/ 243 | name 244 | constant.character.escape.format-string 245 | 246 | 247 | include 248 | source.regexp.oniguruma 249 | 250 | 251 | begin 252 | / 253 | beginCaptures 254 | 255 | 0 256 | 257 | name 258 | punctuation.separator.replacement.format-string 259 | 260 | 261 | end 262 | (/)([a-z]*)(?=\}) 263 | endCaptures 264 | 265 | 1 266 | 267 | name 268 | punctuation.separator.replacement.format-string 269 | 270 | 2 271 | 272 | patterns 273 | 274 | 275 | match 276 | [^giems]+ 277 | name 278 | invalid.illegal.unknown-option.format-string 279 | 280 | 281 | 282 | 283 | patterns 284 | 285 | 286 | match 287 | \\/ 288 | name 289 | constant.character.escape.format-string 290 | 291 | 292 | include 293 | textmate.format-string 294 | 295 | 296 | 297 | 298 | 299 | 300 | begin 301 | \(\?\d+: 302 | comment 303 | (?«var»:«if»:«else») | (?«var»:«if») 304 | end 305 | \) 306 | name 307 | invalid.deprecated.condition.format-string 308 | 309 | 310 | scopeName 311 | textmate.format-string 312 | uuid 313 | 405875FC-5E62-41EE-9303-FAE078694E63 314 | 315 | 316 | -------------------------------------------------------------------------------- /Syntaxes/Properties.tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fileTypes 6 | 7 | tm_properties 8 | tmProperties 9 | 10 | name 11 | Properties 12 | patterns 13 | 14 | 15 | begin 16 | ^([a-zA-Z0-9][a-zA-Z0-9_+\-]*)\s*(=)\s* 17 | captures 18 | 19 | 1 20 | 21 | name 22 | support.constant.tm-properties 23 | 24 | 2 25 | 26 | name 27 | punctuation.separator.key-value.tm-properties 28 | 29 | 30 | end 31 | $ 32 | patterns 33 | 34 | 35 | include 36 | #string 37 | 38 | 39 | 40 | 41 | begin 42 | ^\[ 43 | beginCaptures 44 | 45 | 0 46 | 47 | name 48 | punctuation.definition.section.begin.tm-properties 49 | 50 | 51 | end 52 | \] 53 | endCaptures 54 | 55 | 0 56 | 57 | name 58 | punctuation.definition.section.end.tm-properties 59 | 60 | 61 | name 62 | meta.section.tm-properties 63 | patterns 64 | 65 | 66 | include 67 | #string 68 | 69 | 70 | 71 | 72 | include 73 | #comment 74 | 75 | 76 | repository 77 | 78 | comment 79 | 80 | begin 81 | (^[ \t]+)?(?=#) 82 | beginCaptures 83 | 84 | 1 85 | 86 | name 87 | punctuation.whitespace.comment.leading.tm-properties 88 | 89 | 90 | captures 91 | 92 | 1 93 | 94 | name 95 | punctuation.definition.comment.tm-properties 96 | 97 | 98 | end 99 | (?!\G) 100 | patterns 101 | 102 | 103 | begin 104 | # 105 | beginCaptures 106 | 107 | 0 108 | 109 | name 110 | punctuation.definition.comment.tm-properties 111 | 112 | 113 | end 114 | \n 115 | name 116 | comment.line.number-sign.tm-properties 117 | 118 | 119 | 120 | string 121 | 122 | patterns 123 | 124 | 125 | match 126 | [a-zA-Z0-9][a-zA-Z0-9_+\-]* 127 | name 128 | string.unquoted.tm-properties 129 | 130 | 131 | begin 132 | " 133 | beginCaptures 134 | 135 | 0 136 | 137 | name 138 | punctuation.definition.string.begin.tm-properties 139 | 140 | 141 | end 142 | " 143 | endCaptures 144 | 145 | 0 146 | 147 | name 148 | punctuation.definition.string.end.tm-properties 149 | 150 | 151 | name 152 | string.quoted.double.tm-properties 153 | patterns 154 | 155 | 156 | match 157 | \\. 158 | name 159 | constant.character.escape.tm-properties 160 | 161 | 162 | 163 | 164 | begin 165 | ' 166 | beginCaptures 167 | 168 | 0 169 | 170 | name 171 | punctuation.definition.string.begin.tm-properties 172 | 173 | 174 | end 175 | ' 176 | endCaptures 177 | 178 | 0 179 | 180 | name 181 | punctuation.definition.string.end.tm-properties 182 | 183 | 184 | name 185 | string.quoted.single.tm-properties 186 | 187 | 188 | 189 | 190 | scopeName 191 | source.tm-properties 192 | uuid 193 | DE84747E-90A6-4731-92A4-A9C6823D35DE 194 | 195 | 196 | -------------------------------------------------------------------------------- /Syntaxes/Regular Expressions (Oniguruma).tmLanguage: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | comment 6 | Matches Oniguruma's Ruby regexp syntax (TextMate uses Oniguruma in Ruby mode). 7 | fileTypes 8 | 9 | re 10 | 11 | name 12 | Regular Expressions (Oniguruma) 13 | patterns 14 | 15 | 16 | match 17 | \\[bBAZzG]|\^|\$ 18 | name 19 | keyword.control.anchor.regexp 20 | 21 | 22 | match 23 | \\([0-7]{3}|x(\h\h|\{\h{,8}\})) 24 | name 25 | constant.character.numeric.regexp 26 | 27 | 28 | match 29 | \\[1-9]\d* 30 | name 31 | keyword.other.back-reference.regexp 32 | 33 | 34 | captures 35 | 36 | 1 37 | 38 | name 39 | keyword.other.back-reference.named.regexp 40 | 41 | 2 42 | 43 | name 44 | entity.name.section.back-reference 45 | 46 | 3 47 | 48 | name 49 | keyword.other.back-reference.named.regexp 50 | 51 | 52 | match 53 | (\\k\<)([a-z]\w*)(\>) 54 | name 55 | keyword.other.back-reference.named.regexp 56 | 57 | 58 | match 59 | \[\:(\^)?(alnum|alpha|ascii|blank|cntrl|x?digit|graph|lower|print|punct|space|upper)\] 60 | name 61 | constant.other.character-class.posix.regexp 62 | 63 | 64 | match 65 | [?+*][?+]?|\{(\d+,\d+|\d+,|,\d+|\d+)\}\?? 66 | name 67 | keyword.operator.quantifier.regexp 68 | 69 | 70 | match 71 | \| 72 | name 73 | keyword.operator.or.regexp 74 | 75 | 76 | begin 77 | \(\?\# 78 | end 79 | \) 80 | name 81 | comment.block.regexp 82 | 83 | 84 | comment 85 | We are restrictive in what we allow to go after the comment character to avoid false positives, since the availability of comments depend on regexp flags. 86 | match 87 | (?<=^|\s)#\s[[a-zA-Z0-9,. \t?!-:][^\x{00}-\x{7F}]]*$ 88 | name 89 | comment.line.number-sign.regexp 90 | 91 | 92 | match 93 | \(\?[imx-]+\) 94 | name 95 | keyword.other.option-toggle.regexp 96 | 97 | 98 | begin 99 | (\()((\?=)|(\?!)|(\?<=)|(\?<!)) 100 | beginCaptures 101 | 102 | 1 103 | 104 | name 105 | punctuation.definition.group.regexp 106 | 107 | 3 108 | 109 | name 110 | meta.assertion.look-ahead.regexp 111 | 112 | 4 113 | 114 | name 115 | meta.assertion.negative-look-ahead.regexp 116 | 117 | 5 118 | 119 | name 120 | meta.assertion.look-behind.regexp 121 | 122 | 6 123 | 124 | name 125 | meta.assertion.negative-look-behind.regexp 126 | 127 | 128 | end 129 | (\)) 130 | endCaptures 131 | 132 | 1 133 | 134 | name 135 | punctuation.definition.group.regexp 136 | 137 | 138 | name 139 | meta.group.assertion.regexp 140 | patterns 141 | 142 | 143 | include 144 | $self 145 | 146 | 147 | 148 | 149 | begin 150 | (\()((\?(>|[imx-]*:))|(\?<)([a-z]\w*)(>))? 151 | beginCaptures 152 | 153 | 1 154 | 155 | name 156 | punctuation.definition.group.regexp 157 | 158 | 3 159 | 160 | name 161 | keyword.other.group-options.regexp 162 | 163 | 5 164 | 165 | name 166 | keyword.other.group-options.regexp 167 | 168 | 6 169 | 170 | name 171 | entity.name.section.group.regexp 172 | 173 | 7 174 | 175 | name 176 | keyword.other.group-options.regexp 177 | 178 | 179 | end 180 | (\)) 181 | endCaptures 182 | 183 | 1 184 | 185 | name 186 | punctuation.definition.group.regexp 187 | 188 | 189 | name 190 | meta.group.regexp 191 | patterns 192 | 193 | 194 | include 195 | $self 196 | 197 | 198 | 199 | 200 | include 201 | #character-class 202 | 203 | 204 | repository 205 | 206 | character-class 207 | 208 | patterns 209 | 210 | 211 | match 212 | \\[wWsSdDhH]|\. 213 | name 214 | constant.character.character-class.regexp 215 | 216 | 217 | match 218 | \\. 219 | name 220 | constant.character.escape.backslash.regexp 221 | 222 | 223 | begin 224 | (\[)(\^)? 225 | beginCaptures 226 | 227 | 1 228 | 229 | name 230 | punctuation.definition.character-class.regexp 231 | 232 | 2 233 | 234 | name 235 | keyword.operator.negation.regexp 236 | 237 | 238 | end 239 | (\]) 240 | endCaptures 241 | 242 | 1 243 | 244 | name 245 | punctuation.definition.character-class.regexp 246 | 247 | 248 | name 249 | constant.other.character-class.set.regexp 250 | patterns 251 | 252 | 253 | include 254 | #character-class 255 | 256 | 257 | captures 258 | 259 | 2 260 | 261 | name 262 | constant.character.escape.backslash.regexp 263 | 264 | 4 265 | 266 | name 267 | constant.character.escape.backslash.regexp 268 | 269 | 270 | match 271 | (.|(\\.))\-([^\]]|(\\.)) 272 | name 273 | constant.other.character-class.range.regexp 274 | 275 | 276 | match 277 | && 278 | name 279 | keyword.operator.intersection.regexp 280 | 281 | 282 | 283 | 284 | 285 | 286 | scopeName 287 | source.regexp.oniguruma 288 | uuid 289 | D609BF3F-BEDB-41AE-BA6F-903CC77A7BB3 290 | 291 | 292 | -------------------------------------------------------------------------------- /info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | contactEmailRot13 6 | gz-ohaqyrf@znpebzngrf.pbz 7 | contactName 8 | Allan Odgaard 9 | description 10 | This bundle has functionality which add to the application but is not related to a specific task (bundle). 11 | mainMenu 12 | 13 | items 14 | 15 | 6E779E48-F146-49BF-B60C-EFDFD1380772 16 | 6F9D791B-B8E5-456D-A574-1B5C71F232FF 17 | 950B3108-E2E3-414E-9C4C-EE068F59A895 18 | 7AE6F783-F162-4063-850D-1441441849D8 19 | ED204720-38FC-427C-B91E-D6AE866DAE3A 20 | ------------------------------------ 21 | BBB8AE46-0694-4453-B6C5-9B9633B891B2 22 | ------------------------------------ 23 | E5142394-B07A-11D9-8EC4-000D93589AF6 24 | 25 | submenus 26 | 27 | BBB8AE46-0694-4453-B6C5-9B9633B891B2 28 | 29 | items 30 | 31 | 5F225755-5840-44CF-BC26-2D484DE833A0 32 | ADFED53B-16EC-4956-A6A7-3EA2B8140F86 33 | 34 | name 35 | Scratch Snippet 36 | 37 | 38 | 39 | name 40 | TextMate 41 | uuid 42 | 5A9D4FC6-6CBE-11D9-A21B-000D93589AF6 43 | 44 | 45 | --------------------------------------------------------------------------------