iter.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package wcswidth
  3. import (
  4. "fmt"
  5. )
  6. var _ = fmt.Print
  7. type current_cell struct {
  8. head, tail, width int
  9. }
  10. type forward_iterator struct {
  11. width_iter *WCWidthIterator
  12. current_cell current_cell
  13. cell_num, pos int
  14. }
  15. type reverse_iterator struct {
  16. cells []string
  17. pos int
  18. }
  19. func (self *forward_iterator) reset() {
  20. self.width_iter.Reset()
  21. self.current_cell = current_cell{}
  22. self.pos = 0
  23. self.cell_num = 0
  24. }
  25. type CellIterator struct {
  26. text, current string
  27. forward_iter forward_iterator
  28. reverse_iter reverse_iterator
  29. }
  30. func NewCellIterator(text string) *CellIterator {
  31. ans := &CellIterator{text: text}
  32. ans.forward_iter.width_iter = CreateWCWidthIterator()
  33. return ans
  34. }
  35. func (self *CellIterator) GotoStart() *CellIterator {
  36. self.forward_iter.reset()
  37. self.reverse_iter.pos = -1
  38. self.current = ""
  39. return self
  40. }
  41. func (self *CellIterator) GotoEnd() *CellIterator {
  42. self.current = ""
  43. self.reverse_iter.pos = len(self.reverse_iter.cells)
  44. self.forward_iter.pos = len(self.text)
  45. self.forward_iter.cell_num = len(self.text) + 1
  46. return self
  47. }
  48. func (self *CellIterator) Current() string { return self.current }
  49. func (self *CellIterator) forward_one_rune() bool {
  50. for self.forward_iter.pos < len(self.text) {
  51. rune_count_before := self.forward_iter.width_iter.rune_count
  52. self.forward_iter.width_iter.ParseByte(self.text[self.forward_iter.pos])
  53. self.forward_iter.pos++
  54. if self.forward_iter.width_iter.rune_count != rune_count_before {
  55. return true
  56. }
  57. }
  58. return false
  59. }
  60. func (self *CellIterator) Forward() (has_more bool) {
  61. if self.reverse_iter.cells != nil {
  62. if self.reverse_iter.pos < len(self.reverse_iter.cells) {
  63. self.reverse_iter.pos++
  64. }
  65. if self.reverse_iter.pos >= len(self.reverse_iter.cells) {
  66. self.current = ""
  67. return false
  68. }
  69. self.current = self.reverse_iter.cells[self.reverse_iter.pos]
  70. return true
  71. }
  72. fi := &self.forward_iter
  73. cc := &fi.current_cell
  74. for {
  75. width_before := fi.width_iter.current_width
  76. pos_before := fi.pos
  77. if !self.forward_one_rune() {
  78. break
  79. }
  80. change_in_width := fi.width_iter.current_width - width_before
  81. cc.tail = fi.pos
  82. if cc.width > 0 && change_in_width > 0 {
  83. self.current = self.text[cc.head:pos_before]
  84. cc.width = change_in_width
  85. cc.head = pos_before
  86. fi.cell_num++
  87. return true
  88. }
  89. cc.width += change_in_width
  90. }
  91. if cc.tail > cc.head {
  92. self.current = self.text[cc.head:cc.tail]
  93. cc.head = fi.pos
  94. cc.tail = fi.pos
  95. cc.width = 0
  96. fi.cell_num++
  97. return true
  98. }
  99. self.current = ""
  100. return false
  101. }
  102. func (self *CellIterator) Backward() (has_more bool) {
  103. ri := &self.reverse_iter
  104. if ri.cells == nil {
  105. current_cell_num := self.forward_iter.cell_num
  106. cells := make([]string, 0, len(self.text))
  107. self.GotoStart()
  108. for self.Forward() {
  109. cells = append(cells, self.current)
  110. }
  111. ri.pos = min(max(-1, current_cell_num-1), len(cells))
  112. ri.cells = cells
  113. }
  114. if ri.pos > -1 {
  115. ri.pos--
  116. }
  117. if ri.pos < 0 {
  118. self.current = ""
  119. return false
  120. }
  121. self.current = ri.cells[ri.pos]
  122. return true
  123. }