word.tcl 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. # word.tcl --
  2. #
  3. # This file defines various procedures for computing word boundaries in
  4. # strings. This file is primarily needed so Tk text and entry widgets behave
  5. # properly for different platforms.
  6. #
  7. # Copyright (c) 1996 Sun Microsystems, Inc.
  8. # Copyright (c) 1998 Scritpics Corporation.
  9. #
  10. # See the file "license.terms" for information on usage and redistribution
  11. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12. # The following variables are used to determine which characters are
  13. # interpreted as white space.
  14. if {$::tcl_platform(platform) eq "windows"} {
  15. # Windows style - any but a unicode space char
  16. if {![info exists ::tcl_wordchars]} {
  17. set ::tcl_wordchars {\S}
  18. }
  19. if {![info exists ::tcl_nonwordchars]} {
  20. set ::tcl_nonwordchars {\s}
  21. }
  22. } else {
  23. # Motif style - any unicode word char (number, letter, or underscore)
  24. if {![info exists ::tcl_wordchars]} {
  25. set ::tcl_wordchars {\w}
  26. }
  27. if {![info exists ::tcl_nonwordchars]} {
  28. set ::tcl_nonwordchars {\W}
  29. }
  30. }
  31. # Arrange for caches of the real matcher REs to be kept, which enables the REs
  32. # themselves to be cached for greater performance (and somewhat greater
  33. # clarity too).
  34. namespace eval ::tcl {
  35. variable WordBreakRE
  36. array set WordBreakRE {}
  37. proc UpdateWordBreakREs args {
  38. # Ignores the arguments
  39. global tcl_wordchars tcl_nonwordchars
  40. variable WordBreakRE
  41. # To keep the RE strings short...
  42. set letter $tcl_wordchars
  43. set space $tcl_nonwordchars
  44. set WordBreakRE(after) "$letter$space|$space$letter"
  45. set WordBreakRE(before) "^.*($letter$space|$space$letter)"
  46. set WordBreakRE(end) "$space*$letter+$space"
  47. set WordBreakRE(next) "$letter*$space+$letter"
  48. set WordBreakRE(previous) "$space*($letter+)$space*\$"
  49. }
  50. # Initialize the cache
  51. UpdateWordBreakREs
  52. trace add variable ::tcl_wordchars write ::tcl::UpdateWordBreakREs
  53. trace add variable ::tcl_nonwordchars write ::tcl::UpdateWordBreakREs
  54. }
  55. # tcl_wordBreakAfter --
  56. #
  57. # This procedure returns the index of the first word boundary after the
  58. # starting point in the given string, or -1 if there are no more boundaries in
  59. # the given string. The index returned refers to the first character of the
  60. # pair that comprises a boundary.
  61. #
  62. # Arguments:
  63. # str - String to search.
  64. # start - Index into string specifying starting point.
  65. proc tcl_wordBreakAfter {str start} {
  66. variable ::tcl::WordBreakRE
  67. set result {-1 -1}
  68. regexp -indices -start $start -- $WordBreakRE(after) $str result
  69. return [lindex $result 1]
  70. }
  71. # tcl_wordBreakBefore --
  72. #
  73. # This procedure returns the index of the first word boundary before the
  74. # starting point in the given string, or -1 if there are no more boundaries in
  75. # the given string. The index returned refers to the second character of the
  76. # pair that comprises a boundary.
  77. #
  78. # Arguments:
  79. # str - String to search.
  80. # start - Index into string specifying starting point.
  81. proc tcl_wordBreakBefore {str start} {
  82. variable ::tcl::WordBreakRE
  83. set result {-1 -1}
  84. regexp -indices -- $WordBreakRE(before) [string range $str 0 $start] result
  85. return [lindex $result 1]
  86. }
  87. # tcl_endOfWord --
  88. #
  89. # This procedure returns the index of the first end-of-word location after a
  90. # starting index in the given string. An end-of-word location is defined to be
  91. # the first whitespace character following the first non-whitespace character
  92. # after the starting point. Returns -1 if there are no more words after the
  93. # starting point.
  94. #
  95. # Arguments:
  96. # str - String to search.
  97. # start - Index into string specifying starting point.
  98. proc tcl_endOfWord {str start} {
  99. variable ::tcl::WordBreakRE
  100. set result {-1 -1}
  101. regexp -indices -start $start -- $WordBreakRE(end) $str result
  102. return [lindex $result 1]
  103. }
  104. # tcl_startOfNextWord --
  105. #
  106. # This procedure returns the index of the first start-of-word location after a
  107. # starting index in the given string. A start-of-word location is defined to
  108. # be a non-whitespace character following a whitespace character. Returns -1
  109. # if there are no more start-of-word locations after the starting point.
  110. #
  111. # Arguments:
  112. # str - String to search.
  113. # start - Index into string specifying starting point.
  114. proc tcl_startOfNextWord {str start} {
  115. variable ::tcl::WordBreakRE
  116. set result {-1 -1}
  117. regexp -indices -start $start -- $WordBreakRE(next) $str result
  118. return [lindex $result 1]
  119. }
  120. # tcl_startOfPreviousWord --
  121. #
  122. # This procedure returns the index of the first start-of-word location before
  123. # a starting index in the given string.
  124. #
  125. # Arguments:
  126. # str - String to search.
  127. # start - Index into string specifying starting point.
  128. proc tcl_startOfPreviousWord {str start} {
  129. variable ::tcl::WordBreakRE
  130. set word {-1 -1}
  131. if {$start > 0} {
  132. regexp -indices -- $WordBreakRE(previous) [string range $str 0 $start-1] \
  133. result word
  134. }
  135. return [lindex $word 0]
  136. }