Shifting Selected Text to the right or left

This lesson shows you how to handle tabs and shift text to the right or left when the user presses the tab key.

The tabKey message

The tabKey message is sent to the current control whenever the user presses the Tab key. For example, if the insertion point is in a field, when the user presses the Tab key, a tabKey message is sent to that field.

The tabKey handler

The tabKey handler is added to the script of a field. If the cursor is in a field when the user presses the tab key the tabKey message is sent to the field.

The handler shifts all lines that are completely or partially select by inserting or removing a tab character at the start of each line. If there is no selection but there is an insertion point a tab character is inserted at the insertion point. If a line is already shifted all the way to the left (in other words, if it has no leading tabs), shifting it to the left doesn't affect it.

The selectedText function

The first thing the handler does is check the selectedText function to find out whether any text is selected. If the selectedText is empty, there is an insertion point but no text is selected. In this case, the handler passes the tabKey message on to the engine, allowing the Tab key to operate normally: as long as the field's tabStops property is not empty, the Tab key inserts a tab character.

The selectedLines function

Next, the handler finds out what part of the text is selected. The selectedLines function returns one of two forms:

  • If more than one line is selected, it returns an expression of the form line x to y of field x. In this case, the handler puts the first selected line ("x") into a variable called tFirstLine, and the last selected line ("y") into a variable called tLastLine.
  • If one line is selected, or the selection is less than one line, or there is an insertion point but nothing is selected, it returns an expression of the form line x of field z. In this case, the handler puts the selected line number into both the tFirstLine and tLastLine variables. This simplifies the logic in the repeat loop later in the handler.

The shift key

Next, the handler checks whether the user is holding down the shift key or not. If so, the handler shifts the selected lines to the left by removing leading tabs; if not, it shifts the lines to the right by inserting tabs.

Shifting left

To shift left, the handler uses a repeat control structure to go through each of the lines in the selection. If the tFirstLine variable is the same as the tLastLine variable (if only one line or portion of a line is selected) the statements in the loop are executed only once.

For each line, the repeat loop checks whether the first character is a tab. If so, it removes it. If the first character isn't a tab, that line is already shifted all the way to the left, so the handler doesn't change it.

Shifting right

Shifting right is similar, but there is no need to check whether the first character of each line is a tab: the handler simply adds a tab to the beginning of each affected line.

Reselecting text

Finally, the handler re-selects the lines that were selected before the user pressed the Tab key. This is not strictly necessary, but it's less disorienting and more convenient for the user to retain the selection. It also helps make it clear that the Tab key affects all lines where there is even a partial selection, because the handler selects the entire line.

Many variations on this handler are possible. For example, you might prefer to shift lines using a space, or a run of several spaces, instead of a tab character. Or you might want to add or delete leading ">" characters for use with email or Usenet applications, where quoted lines from previous messages are indicated using this convention.

The tabKey code

on tabKey
	local tSelectedLines, tFirstLine, tLastLine
   
	if the selectedText is empty then
		## there's an insertion point, but no selection,
		## allow the tab key operate normally
		pass tabKey
	else
		put the selectedLines into tSelectedLines 
		put word 2 of the selectedLines into tFirstLine
		if word 3 of the selectedLines is "to" then
			## multiple lines are selected
			put word 4 of the selectedLines into tLastLine
		else
			## single line is selected
			put tFirstLine into tLastLine
		end if
		
		if the shiftKey is down then 
			## shift left - remove a tab
			repeat with tLine = tFirstLine to tLastLine
				if char 1 of line tLine of (the text of the selectedField) is tab then
					## remove leading tab
					delete char 1 of line tLine of the selectedField 
				end if
			end repeat
		else 
			## shift key not down, so shift right - add a tab:
			repeat with tLine = tFirstLine to tLastLine
				## add a leading tab to each line in the selection
				put tab before line tLine of the selectedField
			end repeat
		end if
		
		## (re)select all affected lines
		select tSelectedLines
	end if
end tabKey

0 Comments

Add your comment

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.