Return clicked word

I’m a newbie in applescript studio but i’ve writed in the past hypercard stacks. I want to get a word clicked (in a text view) to play a sound. For example if i click on the word “mouse”, the sound “mouse” is played. It was possible with hypercard but i can’t found with applescript studio

sorry for my english (im french !)


Salut Yvo,

unfortunately handling mouse clicks on single words/characters in a text view is not a standard feature. I don’t think it’s possible with AppleScript.
Here’s a solution using some Objective-C - implemented as a subclass of NSTextView. Since you wrote you were a ‘newbie’ here a step by step guide:

  1. in Interface Builder:
  • click the ‘Classes’ tab of the Nib’s document window
  • select your Text View (not it’s enclosing scroll view)
  • in the Classes tab you should now see the object hierarchy to NSTextView selected
  • Ctrl-Click or Right-Mousebutton-Click (Context Menu) on the class NSTextView and choose ‘Subclass NSTextView’
  • Name the new Subclass - for example MyTextView
  • Choose ‘Create files for …’ from the new subclasses context menu
  • select your text view again and choose ‘Custom Class’ from the Inspector window (or activate it by pressing Apple + 5)
  • choose the new subclass for your text view
  • in the Instances Tab of the nib’s document window: connect File’s Owner to at least one of the handlers in your script
  1. in Xcode:
  • add a handler like this in your script:
on clickedWord(theWord)
	say theWord -- for example
end clickedWord

edit the subclass file MyTextView.m:

#import "MyTextView.h"

@implementation MyTextView

- (void)awakeFromNib {
	[[self window] setAcceptsMouseMovedEvents:YES];

- (void)mouseDown:(NSEvent *)theEvent{

    NSLayoutManager *layoutManager = [self layoutManager];
    NSTextContainer *textContainer = [self textContainer];
    unsigned glyphIndex, charIndex;
    NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
    NSRange lineGlyphRange, lineCharRange, wordCharRange;
	NSRect glyphRect;
    // Convert view coordinates to container coordinates
    point.x -= [self textContainerOrigin].x;
    point.y -= [self textContainerOrigin].y;
    // Convert those coordinates to the nearest glyph index
    glyphIndex = [layoutManager glyphIndexForPoint:point inTextContainer:textContainer];
    // Check to see whether the mouse actually lies over the glyph it is nearest to
    glyphRect = [layoutManager boundingRectForGlyphRange:NSMakeRange(glyphIndex, 1) inTextContainer:textContainer];
    if (NSPointInRect(point, glyphRect)) {
        // Convert the glyph index to a character index
        charIndex = [layoutManager characterIndexForGlyphAtIndex:glyphIndex];

        // Determine the range of glyphs, and of characters, in the corresponding line
        (void)[layoutManager lineFragmentRectForGlyphAtIndex:glyphIndex effectiveRange:&lineGlyphRange];        
        lineCharRange = [layoutManager characterRangeForGlyphRange:lineGlyphRange actualGlyphRange:NULL];
        // Determine the word containing that character
        wordCharRange = NSIntersectionRange(lineCharRange, [self selectionRangeForProposedRange:NSMakeRange(charIndex, 0) granularity:NSSelectByWord]);
 		NSString *clickedWord = [[self string] substringWithRange:wordCharRange];
		NSAppleScript *callASHandler = [[NSAppleScript alloc] initWithSource:
			[NSString stringWithFormat:@"(get my script)'s clickedWord(\"%@\")",clickedWord]];
       [callASHandler executeAndReturnError:nil];
	   [callASHandler release];
	[super mouseDown];


Note: the biggest part of the subclass is ©Apple - ‘stolen’ from the example LayoutManagerDemo …

hope that helps …


thank you very much
i will try it

(sorry for my english !)


You don’t need to apologize for your english, yours is fine. It’s the people who SPEAK english that usually have the worst! :stuck_out_tongue:

Take care,

You could put a button over the text view and then make it invisible.

Hi yvo, Dominik.

You can also use NSTextStorage’s -doubleClickAtIndex: to find the range of a word.
i.e. Following on from what you had:

[code]- (void)mouseDown:(NSEvent *)theEvent
NSLayoutManager *lm = [self layoutManager];
NSTextContainer *tc = [self textContainer];
NSPoint mousePoint = [self convertPoint:[theEvent locationInWindow] fromView:nil];
NSPoint tcOrigin = [self textContainerOrigin];
mousePoint.x -= tcOrigin.x;
mousePoint.y -= tcOrigin.y;

unsigned int glyphIndex = [lm glyphIndexForPoint:mousePoint inTextContainer:tc fractionOfDistanceThroughGlyph:NULL];
NSRect glyphBounds = [lm boundingRectForGlyphRange:NSMakeRange(glyphIndex, 1) inTextContainer:tc];
if (NSPointInRect(mousePoint, glyphBounds)) {
	NSTextStorage *ts = [self textStorage];
	unsigned int charIndex = [lm characterIndexForGlyphAtIndex:glyphIndex];
	/*** Apple's documentation of -doubleClickAtIndex: ***
	 Returns the range of characters that form a word (or other linguistic unit) surrounding the given index, taking language characteristics into account.
	NSRange stringRange = [ts doubleClickAtIndex:charIndex];
	NSString *clickedString = [[ts string] substringWithRange:stringRange];
	// Reject if string is only whitespace
	NSCharacterSet *charSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
	clickedString = [clickedString stringByTrimmingCharactersInSet:charSet];
	if (![clickedString isEqualToString:@""]) {
		// Do something with string

Additions have also been included to reject whitespace-only strings.

The problem is getting the required word under the mouse, not receiving mouse events.

Hi Qwerty,

many thx for the improved code - cool solution!


Hello !
It’s Yvo again.
I’m trying to apply the contents of these messages.
I can’t understand how connect Files’s Owner (an icon with the A of application in the instances tab) with the handler.
What Handler ? the applescript file?

Thanxs 4 your replies


  • in the Instances Tab of the nib’s document window: connect File’s Owner to at least one of the handlers in your script


Hi Yvo,

sorry, I should have been more precise …

  • select the File’s Owner Icon in the instances tab and open the AppleScript Tab of the Inspector for it (hit Apple+8)
  • then check one of the Applescript handlers - for example Application → open
  • it’s not necessary to add any script command in the handler - it might look like this:

on open theObject

end open

This part is necessary for being able to address the clickedWord-handler in my example as “(get my script)'s clickedWord” from the objective-c part …


Thanxxxxxxs you Dominik !
It’s run !
Like it, i can continue to write a small program for the schoolchilds of my class : a program that show images with the word and play the sound of the word (also with the syllabes, phonèmes and the name of the letters).
I’m a teacher !
If i can write this program with the images drawn by schoolchild (for the moment i can use image copyrighted from a schoolbook) and maybe their voices, i will publish it freely and i will post here the link for the download. I will acknowledge strongly Dominik and the MacScripter (



P.S. Sorry for my english again.