<commit_before><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>beforeRunningCommand</key>
	<string>saveActiveFile</string>
	<key>command</key>
	<string>#!/usr/bin/env ruby -Ku
require ENV['TM_SUPPORT_PATH'] + '/lib/ui.rb'
require ENV['TM_SUPPORT_PATH'] + "/lib/escape.rb"
require ENV['TM_SUPPORT_PATH'] + "/lib/tm/require_cmd.rb"
require ENV['TM_SUPPORT_PATH'] + "/lib/tm/htmloutput.rb"
require ENV['TM_SUPPORT_PATH'] + "/lib/web_preview"

# current document
document = []
File.open(ENV['TM_FILEPATH'], "r+") do |file|
  document = file.readlines
end

# byte offset of cursor position from the beginning of file
cursor = document[ 0, ENV['TM_LINE_NUMBER'].to_i - 1].join().length + ENV['TM_LINE_INDEX'].to_i
output = `$TM_GOCODE -f=csv -in=#{e_sh ENV['TM_FILEPATH']} autocomplete #{cursor}`

# quit if no completions found
TextMate.exit_show_tool_tip("No completions found.") if output.length == 0

# set up images for use by DIALOG
# this probably should be done only once, somehow.
icon_plist = "{ " + [ "const", "func", "package", "type", "var" ].map { |v| 
  "#{v} = '#{ENV['TM_BUNDLE_SUPPORT']}/icons/#{v}.png';"
}.join(" ") + " }"
system( ENV['DIALOG'], "images", "--register", icon_plist )

# helper function to build the choice hash
def make_completion_hash(line)
  comp = line.split(",,", 3)

  match = comp[1]
  image = comp[0]

  display = " " + comp[1]
  display += comp[0] == "func" ? comp[2].gsub(/^func/, "") : " " + comp[2]
  
  # input : "foo(x func(func())) (z int, k int)"
  # output: "0000111111122222210001111111111110"
  def depth_at_i(sig)
    depths = Array.new
    depth = 0
    sig.chars { |ch|
      depth-=1 if ch == ")"
      depths &lt;&lt; depth
      depth+=1 if ch == "("
    }
    return depths
  end

  # returns function arguments in the form "x arg, y arg"
  def get_f_args(sig)
    depths = depth_at_i(sig)
    pos = sig.index(")")
    while pos != nil &amp;&amp; depths[pos] &gt; 0
      pos = sig.index(")", pos+1)
    end
    return sig[ Range.new(sig.index("(")+1, pos - 1) ]
  end
  
  def split_args(sig)
    args = Array.new
    depths = depth_at_i(sig)
    start = 0
    pos = sig.index(",")

    while pos != nil
      if depths[pos] == 0
        args &lt;&lt; sig[ Range.new(start, pos-1) ]  
        start = pos+1
      end
      pos = sig.index(",", pos+1)
    end

    lastarg = sig[ Range.new(start, sig.length) ].strip
    args &lt;&lt; lastarg unless lastarg == ""
    return args
  end

  if comp[0] == "func"
    i = 0
    insert = "(" + split_args( get_f_args( display )).map { |m| "${#{i += 1}:"+e_snp(m)+"}" }.join(", ") + ")$0"
  else
    insert = ""
  end
  
  return { 'match' =&gt; match, 'display' =&gt;  display, 'insert' =&gt; insert, 'image' =&gt; image }
end

# build the list of completion choices.
hash = output.split("\n").collect { |v| make_completion_hash( v ) }
options = { :extra_chars =&gt; "_", :case_insensitive =&gt; false }

# if there is only one match, insert. no need to show the menu
if hash.length == 1
  word = ENV['TM_CURRENT_WORD'] || ""
  snippet = hash[0]["match"].gsub(/^#{Regexp.escape(word)}/, "") + hash[0]["insert"]
  #`"$DIALOG" x-insert --snippet #{e_sh snippet}`
  #full = document.join()
  #print e_sn(full[0..cursor]) + "$0" + e_sn(full[cursor+1..-1])
  TextMate.exit_insert_snippet( snippet )
else
  TextMate::UI.complete( hash , options )
end</string>
	<key>fallbackInput</key>
	<string>word</string>
	<key>hideFromUser</key>
	<string>true</string>
	<key>input</key>
	<string>none</string>
	<key>inputFormat</key>
	<string>text</string>
	<key>keyEquivalent</key>
	<string></string>
	<key>name</key>
	<string>Complete</string>
	<key>outputCaret</key>
	<string>afterOutput</string>
	<key>outputFormat</key>
	<string>text</string>
	<key>outputLocation</key>
	<string>atCaret</string>
	<key>requiredCommands</key>
	<array>
		<dict>
			<key>command</key>
			<string>gocode</string>
			<key>moreInfoURL</key>
			<string>https://github.com/nsf/gocode</string>
			<key>variable</key>
			<string>TM_GOCODE</string>
		</dict>
	</array>
	<key>scope</key>
	<string>source.go</string>
	<key>uuid</key>
	<string>FE908865-7729-4926-9FAC-2D54895BEA48</string>
	<key>version</key>
	<integer>2</integer>
</dict>
</plist>
<commit_msg>Change (advanced) completion command’s key equivalent to ⌥⎋<commit_after><?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>beforeRunningCommand</key>
	<string>saveActiveFile</string>
	<key>command</key>
	<string>#!/usr/bin/env ruby -Ku
require ENV['TM_SUPPORT_PATH'] + '/lib/ui.rb'
require ENV['TM_SUPPORT_PATH'] + "/lib/escape.rb"
require ENV['TM_SUPPORT_PATH'] + "/lib/tm/require_cmd.rb"
require ENV['TM_SUPPORT_PATH'] + "/lib/tm/htmloutput.rb"
require ENV['TM_SUPPORT_PATH'] + "/lib/web_preview"

# current document
document = []
File.open(ENV['TM_FILEPATH'], "r+") do |file|
  document = file.readlines
end

# byte offset of cursor position from the beginning of file
cursor = document[ 0, ENV['TM_LINE_NUMBER'].to_i - 1].join().length + ENV['TM_LINE_INDEX'].to_i
output = `$TM_GOCODE -f=csv -in=#{e_sh ENV['TM_FILEPATH']} autocomplete #{cursor}`

# quit if no completions found
TextMate.exit_show_tool_tip("No completions found.") if output.length == 0

# set up images for use by DIALOG
# this probably should be done only once, somehow.
icon_plist = "{ " + [ "const", "func", "package", "type", "var" ].map { |v| 
  "#{v} = '#{ENV['TM_BUNDLE_SUPPORT']}/icons/#{v}.png';"
}.join(" ") + " }"
system( ENV['DIALOG'], "images", "--register", icon_plist )

# helper function to build the choice hash
def make_completion_hash(line)
  comp = line.split(",,", 3)

  match = comp[1]
  image = comp[0]

  display = " " + comp[1]
  display += comp[0] == "func" ? comp[2].gsub(/^func/, "") : " " + comp[2]
  
  # input : "foo(x func(func())) (z int, k int)"
  # output: "0000111111122222210001111111111110"
  def depth_at_i(sig)
    depths = Array.new
    depth = 0
    sig.chars { |ch|
      depth-=1 if ch == ")"
      depths &lt;&lt; depth
      depth+=1 if ch == "("
    }
    return depths
  end

  # returns function arguments in the form "x arg, y arg"
  def get_f_args(sig)
    depths = depth_at_i(sig)
    pos = sig.index(")")
    while pos != nil &amp;&amp; depths[pos] &gt; 0
      pos = sig.index(")", pos+1)
    end
    return sig[ Range.new(sig.index("(")+1, pos - 1) ]
  end
  
  def split_args(sig)
    args = Array.new
    depths = depth_at_i(sig)
    start = 0
    pos = sig.index(",")

    while pos != nil
      if depths[pos] == 0
        args &lt;&lt; sig[ Range.new(start, pos-1) ]  
        start = pos+1
      end
      pos = sig.index(",", pos+1)
    end

    lastarg = sig[ Range.new(start, sig.length) ].strip
    args &lt;&lt; lastarg unless lastarg == ""
    return args
  end

  if comp[0] == "func"
    i = 0
    insert = "(" + split_args( get_f_args( display )).map { |m| "${#{i += 1}:"+e_snp(m)+"}" }.join(", ") + ")$0"
  else
    insert = ""
  end
  
  return { 'match' =&gt; match, 'display' =&gt;  display, 'insert' =&gt; insert, 'image' =&gt; image }
end

# build the list of completion choices.
hash = output.split("\n").collect { |v| make_completion_hash( v ) }
options = { :extra_chars =&gt; "_", :case_insensitive =&gt; false }

# if there is only one match, insert. no need to show the menu
if hash.length == 1
  word = ENV['TM_CURRENT_WORD'] || ""
  snippet = hash[0]["match"].gsub(/^#{Regexp.escape(word)}/, "") + hash[0]["insert"]
  #`"$DIALOG" x-insert --snippet #{e_sh snippet}`
  #full = document.join()
  #print e_sn(full[0..cursor]) + "$0" + e_sn(full[cursor+1..-1])
  TextMate.exit_insert_snippet( snippet )
else
  TextMate::UI.complete( hash , options )
end</string>
	<key>fallbackInput</key>
	<string>word</string>
	<key>hideFromUser</key>
	<string>true</string>
	<key>input</key>
	<string>none</string>
	<key>inputFormat</key>
	<string>text</string>
	<key>keyEquivalent</key>
	<string>~</string>
	<key>name</key>
	<string>Complete</string>
	<key>outputCaret</key>
	<string>afterOutput</string>
	<key>outputFormat</key>
	<string>text</string>
	<key>outputLocation</key>
	<string>atCaret</string>
	<key>requiredCommands</key>
	<array>
		<dict>
			<key>command</key>
			<string>gocode</string>
			<key>moreInfoURL</key>
			<string>https://github.com/nsf/gocode</string>
			<key>variable</key>
			<string>TM_GOCODE</string>
		</dict>
	</array>
	<key>scope</key>
	<string>source.go</string>
	<key>uuid</key>
	<string>FE908865-7729-4926-9FAC-2D54895BEA48</string>
	<key>version</key>
	<integer>2</integer>
</dict>
</plist>

{'fraction_non_alphanumeric': 0.19585859741448347, 'fraction_numerical': 0.022880677268047135, 'mean_word_length': 3.819184123484013, 'pattern_counts': {'":': 0, '<': 163, '<?xml version=': 2, '>': 163, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '329620', 'n_tokens_mistral': 3556, 'n_tokens_neox': 3387, 'n_words': 727}