Previously this was done by exposing iterators but for this to go into the abstract base class we sort of need abstract iterators and that is too complex and visitor interface is sufficient for our single use case.
This introduces new scope setting - excludeFromParagraphSelection, that
prevents extending selection to some scopes, eg. on comment.line.
Previously when reformatting paragraph comment lines were selected as paragraph
lines, this have led to mixing comment content into reformatted paragraph
content breaking the syntax of reformatted code, eg.:
some very long ... line of text
# some comment
some other long ... line of text
As an effect we got:
some very long ...
... text # some comment some other ...
... line of text
The problem described above was especially visible when using ⌃Q to Reformat
block of Git commit message, when below of the typed text there was a Git
default comment. Also this problem could be noticeable by authors using LaTeX.
This change checks whether a candidate line scope for paragraph extension has a
excludeFromParagraphSelection set to true and breaks upon such line, eg.
comment line.
Doing Select Paragraph ⌃⌥P again will select the comment as well.
TextMate highlights certain character pairs (e.g. { }) when the caret passes over either of the characters. It can be useful to double click to select the text in between and including the character pairs for deleting code, copying code, for visually differentiating the affected code, etc. Add a select_unit_type, kSelectionExtendToWordOrTypingPair, to select the inclusive bounds of a typing pair if a match is found, or otherwise select a word as normal.
This patch is free and released into the public domain.
If there are multiple (discontinuous) selections then this action will drop the last one.
If there are multiple carets (with no selections) then this action will drop all but the first caret.
These settings are also consulted for “pair movement”, i.e. ⌃↓/⌃↑ and ⇧⌘B, so by using regular expressions we can match begin/end tags and navigate between these.
The algorithm now handle overlapping character ranges like: ‘(f{o)o}’ and unpaired characters surrounded by character pairs.
This is for selecting (⇧⌘B) and moving to the begin or end of the range (⌃↓/⌃↑).
If there is one or more selections:
dyn.selection
If there is a single zero-width selection:
dyn.caret.mixed.columnar
If there are multiple carets and/or selections:
dyn.caret.mixed
When there is only a single caret or a single continuous selection the left scope may contain:
dyn.caret.begin.line
dyn.caret.begin.document
Likewise the right scope may contain:
dyn.caret.end.line
dyn.caret.end.document
The methods going to “begin of indented line” will go to the first non-whitespace character on the line, unless the caret is already there or to the left of this character, in which case it will go to the actual beginning of the line.
The “end of indented line” methods work similarly.
If you want [⇪]⌘⇠/⇢ and ⌘⌫/⌦ to use this behavior, you can add the following to your key bindings file:
"@\UF702" = "moveToBeginningOfIndentedLine:";
"$@\UF702" = "moveToBeginningOfIndentedLineAndModifySelection:";
"@\UF703" = "moveToEndOfIndentedLine:";
"$@\UF703" = "moveToEndOfIndentedLineAndModifySelection:";
"@\U007F" = "deleteToBeginningOfIndentedLine:";
"@\UF728" = "deleteToEndOfIndentedLine:";
This will find (forwards or backwards) but preserve the existing selection.
Presently if the current selection is a zero-width selection (i.e. caret) then we still preserve it. This might not be desired, but one could imagine “extend selection” used with a regular expression which use a look-around assertion (resulting in zero-width matches).