translate.lua 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. local common = require "core.common"
  2. local config = require "core.config"
  3. -- functions for translating a Doc position to another position
  4. -- these functions can be passed to Doc:move_to|select_to|delete()
  5. local translate = {}
  6. local function is_non_word(char)
  7. return config.non_word_chars:find(char, nil, true)
  8. end
  9. function translate.previous_char(doc, line, col)
  10. repeat
  11. line, col = doc:position_offset(line, col, -1)
  12. until not common.is_utf8_cont(doc:get_char(line, col))
  13. return line, col
  14. end
  15. function translate.next_char(doc, line, col)
  16. repeat
  17. line, col = doc:position_offset(line, col, 1)
  18. until not common.is_utf8_cont(doc:get_char(line, col))
  19. return line, col
  20. end
  21. function translate.previous_word_boundary(doc, line, col)
  22. local char = doc:get_char(doc:position_offset(line, col, -1))
  23. local inword = not is_non_word(char)
  24. repeat
  25. local line2, col2 = line, col
  26. line, col = doc:position_offset(line, col, -1)
  27. if line == line2 and col == col2 then
  28. break
  29. end
  30. local c = doc:get_char(doc:position_offset(line, col, -1))
  31. until inword and is_non_word(c) or not inword and c ~= char
  32. return line, col
  33. end
  34. function translate.next_word_boundary(doc, line, col)
  35. local char = doc:get_char(line, col)
  36. local inword = not is_non_word(char)
  37. repeat
  38. local line2, col2 = line, col
  39. line, col = doc:position_offset(line, col, 1)
  40. if line == line2 and col == col2 then
  41. break
  42. end
  43. local c = doc:get_char(line, col)
  44. until inword and is_non_word(c) or not inword and c ~= char
  45. return line, col
  46. end
  47. function translate.start_of_word(doc, line, col)
  48. while true do
  49. local line2, col2 = doc:position_offset(line, col, -1)
  50. local char = doc:get_char(line2, col2)
  51. if is_non_word(char)
  52. or line == line2 and col == col2 then
  53. break
  54. end
  55. line, col = line2, col2
  56. end
  57. return line, col
  58. end
  59. function translate.end_of_word(doc, line, col)
  60. while true do
  61. local line2, col2 = doc:position_offset(line, col, 1)
  62. local char = doc:get_char(line, col)
  63. if is_non_word(char)
  64. or line == line2 and col == col2 then
  65. break
  66. end
  67. line, col = line2, col2
  68. end
  69. return line, col
  70. end
  71. function translate.previous_start_of_block(doc, line, col)
  72. while true do
  73. line = line - 1
  74. if line <= 1 then
  75. return 1, 1
  76. end
  77. if doc.lines[line-1]:match("^%s*$")
  78. and not doc.lines[line]:match("^%s*$") then
  79. return line, (doc.lines[line]:find("%S"))
  80. end
  81. end
  82. end
  83. function translate.next_start_of_block(doc, line, col)
  84. while true do
  85. line = line + 1
  86. if line >= #doc.lines then
  87. return #doc.lines, 1
  88. end
  89. if doc.lines[line-1]:match("^%s*$")
  90. and not doc.lines[line]:match("^%s*$") then
  91. return line, (doc.lines[line]:find("%S"))
  92. end
  93. end
  94. end
  95. function translate.start_of_line(doc, line, col)
  96. return line, 1
  97. end
  98. function translate.end_of_line(doc, line, col)
  99. return line, math.huge
  100. end
  101. function translate.start_of_doc(doc, line, col)
  102. return 1, 1
  103. end
  104. function translate.end_of_doc(doc, line, col)
  105. return #doc.lines, #doc.lines[#doc.lines]
  106. end
  107. return translate