/collects/framework/private/search.rkt

http://github.com/gmarceau/PLT · Racket · 99 lines · 97 code · 2 blank · 0 comment · 23 complexity · a84b5d9d060a150de261f88c050155b7 MD5 · raw file

  1. #lang scheme/base
  2. (require scheme/contract
  3. scheme/class
  4. scheme/gui/base)
  5. (provide/contract
  6. [find-string-embedded
  7. (->* ((is-a?/c text%)
  8. string?)
  9. ((symbols 'forward 'backward)
  10. (or/c (symbols 'start) number?)
  11. (or/c (symbols 'eof) number?)
  12. boolean?
  13. boolean?
  14. boolean?)
  15. (values (is-a?/c editor<%>)
  16. (or/c false/c number?)))])
  17. (define find-string-embedded
  18. (lambda (edit
  19. str
  20. [direction 'forward]
  21. [start 'start]
  22. [end 'eof]
  23. [get-start #t]
  24. [case-sensitive? #t]
  25. [pop-out? #f])
  26. (let/ec k
  27. (let* ([start (if (eq? start 'start)
  28. (send edit get-start-position)
  29. start)]
  30. [end (if (eq? 'eof end)
  31. (if (eq? direction 'forward)
  32. (send edit last-position)
  33. 0)
  34. end)]
  35. [flat (send edit find-string str direction
  36. start end get-start
  37. case-sensitive?)]
  38. [pop-out
  39. (Îť ()
  40. (let ([admin (send edit get-admin)])
  41. (if (is-a? admin editor-snip-editor-admin<%>)
  42. (let* ([snip (send admin get-snip)]
  43. [edit-above (send (send snip get-admin) get-editor)]
  44. [pos (send edit-above get-snip-position snip)]
  45. [pop-out-pos (if (eq? direction 'forward) (add1 pos) pos)])
  46. (find-string-embedded
  47. edit-above
  48. str
  49. direction
  50. pop-out-pos
  51. (if (eq? direction 'forward) 'eof 0)
  52. get-start
  53. case-sensitive?
  54. pop-out?))
  55. (values edit #f))))])
  56. (let loop ([current-snip (send edit find-snip start
  57. (if (eq? direction 'forward)
  58. 'after-or-none
  59. 'before-or-none))])
  60. (let ([next-loop
  61. (Îť ()
  62. (if (eq? direction 'forward)
  63. (loop (send current-snip next))
  64. (loop (send current-snip previous))))])
  65. (cond
  66. [(or (not current-snip)
  67. (and flat
  68. (let* ([start (send edit get-snip-position current-snip)]
  69. [end (+ start (send current-snip get-count))])
  70. (if (eq? direction 'forward)
  71. (and (<= start flat)
  72. (< flat end))
  73. (and (< start flat)
  74. (<= flat end))))))
  75. (if (and (not flat) pop-out?)
  76. (pop-out)
  77. (values edit flat))]
  78. [(is-a? current-snip editor-snip%)
  79. (let-values ([(embedded embedded-pos)
  80. (let ([media (send current-snip get-editor)])
  81. (if (and media
  82. (is-a? media text%))
  83. (begin
  84. (find-string-embedded
  85. media
  86. str
  87. direction
  88. (if (eq? 'forward direction)
  89. 0
  90. (send media last-position))
  91. 'eof
  92. get-start case-sensitive?))
  93. (values #f #f)))])
  94. (if (not embedded-pos)
  95. (next-loop)
  96. (values embedded embedded-pos)))]
  97. [else (next-loop)])))))))