On Dec 26, 2007, at 10:28 PM, Allan Odgaard wrote:

On 26 Dec 2007, at 14:28, Сергей Яковлев wrote:

[...]
  Suggestion 1. It would be useful if TextMate had
  variables like $TM_SELECTION_START and
  $TM_SELECTION_END which would return the
  corresponding offsets in the file (or the cursor
  offset, if nothing is selected).

It does in the form of a line/column position of the start position.

Maybe I am simply misunderstanding you, but are you saying that
TextMate returns line and column position of the start position of
selection?

I'm asking because the $TM_LINE_NUMBER and
$TM_COLUMN_NUMBER variables don't quite work this way.

To illustrate what I mean, let's add a 'Show Position' command
that displays position as a tooltip:

    echo "$TM_LINE_NUMBER:$TM_COLUMN_NUMBER"

and type 'TextMate' into an empty document. Now, if we select
'TextMate' with mouse from left to right, the command returns 1:9.
If we select 'TextMate' with mouse from right to left, the command
returns 1:1. Finally, if we select 'TextMate' by double-clicking
between 't' and 'M', the command returns 1:5.

So, these variables actually return the cursor position, not the
starting position of selection and it is impossible to calculate the
starting and ending positions of selection from
$TM_LINE_NUMBER and $TM_COLUMN_NUMBER variables
(without knowing how the selection was made).

The only way to do this (that is known to me) is to write a macro that
first calls a command that replaces selection with itself wrapped in
U+FFFC characters:

    echo -n $'\357\277\274'$TM_SELECTED_TEXT$'\357\277\274'

and then calls another command that receives the whole document
as an input and can "find" the selection looking for U+FFFC
characters.

It would certainly be easier for the average user (and somewhat
more flexible) if TextMate had something like
$TM_SELECTED_TEXT_START_LINE_NUMBER and
$TM_SELECTED_TEXT_START_COLUMN_NUMBER
variables, or, alternatively, slightly changed semantics of
$TM_LINE_NUMBER and $TM_COLUMN_NUMBER variables
so that they always return the starting position of selection
(no matter how the selection was made).

The reason it does not use a byte offset is that internally TM would have to "calculate" this (by adding the length of each line preceding the selection) and I am generally wary of exporting shell variables that need to be calculated and have an unknown running time ( i.e. in practice the user could have a million lines and each command execution would then always require a million numbers to be added together).

I assumed that these calculations were already being performed,
after I had a look at:

    $ class-dump -C OakTextView TextMate | grep selectedRange
    - (struct _NSRange)selectedRange;
    - (void)setMarkedText:(id)fp8 selectedRange:(struct _NSRange)fp12;

and saw 'selectedRange'. But, evidently, something much more
complicated is going on, and I certainly would not ask you questions
about TextMate internal workings :-)

The only remaining question is what symbol to use as a
mark. I decided to use √ (221A, SQUARE ROOT character,
which you can type with Option-V), but I'm not sure
this is the best choice. Maybe it's better to use some
character from Private Use Area (E000--F8FF)?

We generally use U+FFFC, OBJECT REPLACEMENT CHARACTER.

I've attached a new version of macros using U+FFFC to the original ticket.


Happy New Year!

-- Sergei Yakovlev