1
0

prompt.rb 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. # Copyright 2010 Wincent Colaiuta. All rights reserved.
  2. #
  3. # Redistribution and use in source and binary forms, with or without
  4. # modification, are permitted provided that the following conditions are met:
  5. #
  6. # 1. Redistributions of source code must retain the above copyright notice,
  7. # this list of conditions and the following disclaimer.
  8. # 2. Redistributions in binary form must reproduce the above copyright notice,
  9. # this list of conditions and the following disclaimer in the documentation
  10. # and/or other materials provided with the distribution.
  11. #
  12. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  13. # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  14. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  15. # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
  16. # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  17. # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  18. # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  19. # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  20. # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  21. # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  22. # POSSIBILITY OF SUCH DAMAGE.
  23. module CommandT
  24. # Abuse the status line as a prompt.
  25. class Prompt
  26. attr_accessor :abbrev
  27. def initialize
  28. @abbrev = '' # abbreviation entered so far
  29. @col = 0 # cursor position
  30. @has_focus = false
  31. end
  32. # Erase whatever is displayed in the prompt line,
  33. # effectively disposing of the prompt
  34. def dispose
  35. ::VIM::command 'echo'
  36. ::VIM::command 'redraw'
  37. end
  38. # Clear any entered text.
  39. def clear!
  40. @abbrev = ''
  41. @col = 0
  42. redraw
  43. end
  44. # Insert a character at (before) the current cursor position.
  45. def add! char
  46. left, cursor, right = abbrev_segments
  47. @abbrev = left + char + cursor + right
  48. @col += 1
  49. redraw
  50. end
  51. # Delete a character to the left of the current cursor position.
  52. def backspace!
  53. if @col > 0
  54. left, cursor, right = abbrev_segments
  55. @abbrev = left.chop! + cursor + right
  56. @col -= 1
  57. redraw
  58. end
  59. end
  60. # Delete a character at the current cursor position.
  61. def delete!
  62. if @col < @abbrev.length
  63. left, cursor, right = abbrev_segments
  64. @abbrev = left + right
  65. redraw
  66. end
  67. end
  68. def cursor_left
  69. if @col > 0
  70. @col -= 1
  71. redraw
  72. end
  73. end
  74. def cursor_right
  75. if @col < @abbrev.length
  76. @col += 1
  77. redraw
  78. end
  79. end
  80. def cursor_end
  81. if @col < @abbrev.length
  82. @col = @abbrev.length
  83. redraw
  84. end
  85. end
  86. def cursor_start
  87. if @col != 0
  88. @col = 0
  89. redraw
  90. end
  91. end
  92. def redraw
  93. if @has_focus
  94. prompt_highlight = 'Comment'
  95. normal_highlight = 'None'
  96. cursor_highlight = 'Underlined'
  97. else
  98. prompt_highlight = 'NonText'
  99. normal_highlight = 'NonText'
  100. cursor_highlight = 'NonText'
  101. end
  102. left, cursor, right = abbrev_segments
  103. components = [prompt_highlight, '>>', 'None', ' ']
  104. components += [normal_highlight, left] unless left.empty?
  105. components += [cursor_highlight, cursor] unless cursor.empty?
  106. components += [normal_highlight, right] unless right.empty?
  107. components += [cursor_highlight, ' '] if cursor.empty?
  108. set_status *components
  109. end
  110. def focus
  111. unless @has_focus
  112. @has_focus = true
  113. redraw
  114. end
  115. end
  116. def unfocus
  117. if @has_focus
  118. @has_focus = false
  119. redraw
  120. end
  121. end
  122. private
  123. # Returns the @abbrev string divided up into three sections, any of
  124. # which may actually be zero width, depending on the location of the
  125. # cursor:
  126. # - left segment (to left of cursor)
  127. # - cursor segment (character at cursor)
  128. # - right segment (to right of cursor)
  129. def abbrev_segments
  130. left = @abbrev[0, @col]
  131. cursor = @abbrev[@col, 1]
  132. right = @abbrev[(@col + 1)..-1] || ''
  133. [left, cursor, right]
  134. end
  135. def set_status *args
  136. # see ':help :echo' for why forcing a redraw here helps
  137. # prevent the status line from getting inadvertantly cleared
  138. # after our echo commands
  139. ::VIM::command 'redraw'
  140. while (highlight = args.shift) and (text = args.shift) do
  141. text = VIM::escape_for_single_quotes text
  142. ::VIM::command "echohl #{highlight}"
  143. ::VIM::command "echon '#{text}'"
  144. end
  145. ::VIM::command 'echohl None'
  146. end
  147. end # class Prompt
  148. end # module CommandT