import sublime, sublime_plugin

class SwapStringsCommand(sublime_plugin.TextCommand):

	def run(self, edit, stringA=None, stringB=None):

		if not stringA and not stringB:
			inputView = sublime.active_window().show_input_panel(
				"Specify the strings which shall be swapped. <> functions as a separator.",
				"\"<>'",
				self.onConfirm,
				None,
				None
			)

		else:
			view = self.view
			selection = view.sel()

			for region in selection:
				if region.a == region.b:
					# use entire line if regions is only a point
					region = view.line(region)

				regionStr = view.substr(region)

				swapToken = self.generateSwapToken(regionStr, stringA, stringB)

				if len(stringB) > len(stringA):
					# ensures that swapping is correct even if stringA is in stringB
					stringA, stringB = stringB, stringA

				regionStr = regionStr \
					.replace(stringA, swapToken) \
					.replace(stringB, stringA) \
					.replace(swapToken, stringB)

				view.replace(edit, region, regionStr)


	def generateSwapToken(self, regionStr, stringA, stringB):

		# requirements:
		# swapToken must not be in regionStr, stringA and stringB
		# TODO: regionStr, stringA and stringB must not be in swapToken

		swapToken = "tmp_token"
		while swapToken in regionStr + stringA + stringB:
			swapToken += "4b5c7fb7"

		return swapToken


	def onConfirm(self, swapString):

		a, b = swapString.split("<>")
		self.view.run_command("swap_strings", dict(stringA=a, stringB=b))


@@ -372,16 +372,56 @@
 e%0D%0A%09%09%09)%0D
+%0A%09%09%09inputView.run_command(%22select_all%22)%0D
 %0A%0D%0A%09%09els
@@ -471,16 +471,74 @@
 w.sel()%0D
+%0A%09%09%09stringA, stringB = self.ensureOrder(stringA, stringB)%0D
 %0A%0D%0A%09%09%09fo
@@ -710,26 +710,24 @@
 tr(region)%0D%0A
-%0D%0A
 %09%09%09%09swapToke
@@ -789,158 +789,8 @@
 %0D%0A%0D%0A
-%09%09%09%09if len(stringB) %3E len(stringA):%0D%0A%09%09%09%09%09# ensures that swapping is correct even if stringA is in stringB%0D%0A%09%09%09%09%09stringA, stringB = stringB, stringA%0D%0A
 %0D%0A%09%09
@@ -981,177 +981,654 @@
 def 
-generateSwapToken(self, regionStr, stringA, stringB):%0D%0A%0D%0A%09%09# requirements:%0D%0A%09%09# swapToken must not be in regionStr, stringA and stringB%0D%0A%09%09# TODO: regionStr, stringA and
+ensureOrder(self, stringA, stringB):%0D%0A%0D%0A%09%09# ensures that len(stringA) %3E= len(stringB)%0D%0A%09%09# this is important for the edge case in which stringA is a substring of stringB%0D%0A%0D%0A%09%09if len(stringB) %3E len(stringA):%0D%0A%09%09%09stringA, stringB = stringB, stringA%0D%0A%0D%0A%09%09return stringA, stringB%0D%0A%0D%0A%0D%0A%09def generateSwapToken(self, regionStr, stringA, stringB):%0D%0A%0D%0A%09%09# requirements derived by the three replacements:%0D%0A%09%09# 1: uncritical since stringA %3E= stringB.%0D%0A%09%09# 2: stringB must not be in swapToken.%0D%0A%09%09# 3: swapToken must not be in stringA and not in regionStr.%0D%0A%09%09# %09 mind that stringA is not necessarily a substring of regionStr.%0D%0A%0D%0A%09%09#%09choose swapToken so that
  str
@@ -1624,37 +1624,35 @@
 so that stringB 
-must 
+can
 not be in swapTo
@@ -1656,18 +1656,16 @@
 pToken%0D%0A
-%0D%0A
 %09%09swapTo
@@ -1674,19 +1674,22 @@
 n = 
-%22tmp_token%22
+stringB%5B:-1%5D%0D%0A
 %0D%0A%09%09
@@ -1711,37 +1711,93 @@
  in 
-regionStr + stringA +
+stringA + regionStr:%0D%0A%09%09%09# extend swapToken with a character so that it isn't
  stringB
 :%0D%0A%09
@@ -1792,19 +1792,19 @@
  stringB
-:
 %0D%0A
+ 
 %09%09%09swapT
@@ -1815,18 +1815,39 @@
  += 
-%224b5c7fb7%22
+chr(ord(stringB%5B-1%5D) + 1 %25 255)
 %0D%0A%0D%0A
@@ -1913,12 +1913,14 @@
 %0D%0A%09%09
+(
 a, b
+)
  = s

implement proper algorithm for choosing a suitable swapToken; refactor