discuss-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Word selection and cursor placement


From: Wolfgang Lux
Subject: Re: Word selection and cursor placement
Date: Sun, 19 Nov 2006 18:02:10 +0100

Andreas Höschler wrote:

[...]
• Selecting 'valueForKey' in

        [self valueForKey:@"hostname"];

and the pressing cursor left puts the cursor
directly to the right of
self which is wrong. The cursor should be placed
between the space and
valueForKey. The behaviour is even worse when
leaving a selction to the
right side. When self was selected this places the
cursor between 's'
and 'elf' which is totally wrong.

NSTextView_actions.m: -moveLeft:


Hints where in the GNustep tree this can be
corrected are greatly
appreciated! Thanks!

I belive the malfuntion actually is in NSLayoutManager

I don't think so. If you look carefully, you will notice that the logic implemented by the various -move methods which do not extend the current selection is incorrectly based on the result of [self _movementOrigin], which returns either the start or end of the current selection depending on whether the current selection affinity is NSSelectionAffinityUpstream or NSSelectionAffinityDownstream, respectively. The selection affinity should be taken only into account when the current selection is extended or reduced (i.e., moveBackwardAndModifySelection: and friends).

Let's have a more detailed look at some of the methods. According to the NSTextView documentation, -moveBackward: and -moveForward: should collapse the selection to its beginning or end, respectively, if the selection is not empty and move the cursor only one character forward or backward otherwise. This suggests the following implementation of these two methods:

- (void) moveBackward: (id)sender
{
  NSRange range = [self selectedRange];

  if (range.length)
    [self _moveTo: range.location select: NO];
  else if (range.location)
    [self _moveTo: range.location - 1 select: NO];
}
- (void) moveForward: (id)sender
{
  NSRange range = [self selectedRange];

  if (range.length)
    [self _moveTo: NSMaxRange(range) select: NO];
  else if (range.location)
    [self _moveTo: range.location + 1 select: NO];
}

[Side note: These two methods should be bound to the keys Control-b and Control-f in DefaultKeyBindings.dict. At present, these two keys are bound to moveLeft: and moveRight:.]

Changing -moveLeft: and -moveRight: is a little bit more complicated because the selection should collapse to the left and right end, respectively. For languages with left-to-right text flow (i.e., western languages), this ends will match the beginning and end of the selection, respectively. Yet, for languages with a right-to-left text flow (e.g. Hebrew or Arabic) the ends of the selection have to be reversed. I leave it as an exercise for someone more knowledgeable than me to fix this shortcoming in the following implementations of moveLeft: and moveRight:.

- (void) moveLeft: (id)sender
{
  NSRange range = [self selectedRange];

  if (range.length)
    // FIXME: this should be the *left* end of the selection
    [self _moveTo: range.location select: NO];
  else
    [self _move: GSInsertionPointMoveLeft
          distance: 0.0
          select: NO];
}

- (void) moveRight: (id)sender
{
  NSRange range = [self selectedRange];

  if (range.length)
    // FIXME: this should be the *right* end of the selection
    [self _moveTo: NSMaxRange(range) select: NO];
  else
    [self _move: GSInsertionPointMoveRight
          distance: 0.0
          select: NO];
}

I also leave it as an exercise to fix the -moveUp: and -moveDown: methods, which according to the documentation should move to the character immediately above the beginning and immediately below the end of the selection, respectively.

Similar fixes will be necessary in methods -moveWordForward: - moveWordBackward:, -moveToBeginningOfParagraph:, - moveToEndOfParagraph:, and maybe others. Look for [self _movementOrigin] to find other places that eventually need to be fixed.

Hope this helps,
Wolfgang





reply via email to

[Prev in Thread] Current Thread [Next in Thread]