( start, end, replacement_text, vim_buffer )
| 1117 | # NOTE: Works exclusively with bytes() instances and byte offsets as returned |
| 1118 | # by ycmd and used within the Vim buffers |
| 1119 | def ReplaceChunk( start, end, replacement_text, vim_buffer ): |
| 1120 | # ycmd's results are all 1-based, but vim's/python's are all 0-based |
| 1121 | # (so we do -1 on all of the values) |
| 1122 | start_line = start[ 'line_num' ] - 1 |
| 1123 | end_line = end[ 'line_num' ] - 1 |
| 1124 | |
| 1125 | start_column = start[ 'column_num' ] - 1 |
| 1126 | end_column = end[ 'column_num' ] - 1 |
| 1127 | |
| 1128 | # When sending a request to the server, a newline is added to the buffer |
| 1129 | # contents to match what gets saved to disk. If the server generates a chunk |
| 1130 | # containing that newline, this chunk goes past the Vim buffer contents since |
| 1131 | # there is actually no new line. When this happens, recompute the end position |
| 1132 | # of where the chunk is applied and remove all trailing characters in the |
| 1133 | # chunk. |
| 1134 | if end_line >= len( vim_buffer ): |
| 1135 | end_column = len( ToBytes( vim_buffer[ -1 ] ) ) |
| 1136 | end_line = len( vim_buffer ) - 1 |
| 1137 | replacement_text = replacement_text.rstrip() |
| 1138 | |
| 1139 | # NOTE: replacement_text is unicode, but all our offsets are byte offsets, |
| 1140 | # so we convert to bytes |
| 1141 | replacement_lines = SplitLines( ToBytes( replacement_text ) ) |
| 1142 | |
| 1143 | # NOTE: Vim buffers are a list of unicode objects on Python 3. |
| 1144 | start_existing_text = ToBytes( vim_buffer[ start_line ] )[ : start_column ] |
| 1145 | end_line_text = ToBytes( vim_buffer[ end_line ] ) |
| 1146 | end_existing_text = end_line_text[ end_column : ] |
| 1147 | |
| 1148 | replacement_lines[ 0 ] = start_existing_text + replacement_lines[ 0 ] |
| 1149 | replacement_lines[ -1 ] = replacement_lines[ -1 ] + end_existing_text |
| 1150 | |
| 1151 | cursor_line, cursor_column = CurrentLineAndColumn() |
| 1152 | |
| 1153 | vim_buffer[ start_line : end_line + 1 ] = replacement_lines[ : ] |
| 1154 | |
| 1155 | # When the cursor position is on the last line in the replaced area, and ends |
| 1156 | # up somewhere after the end of the new text, we need to reset the cursor |
| 1157 | # position. This is because Vim doesn't know where to put it, and guesses |
| 1158 | # badly. We put it at the end of the new text. |
| 1159 | if cursor_line == end_line and cursor_column >= end_column: |
| 1160 | cursor_line = start_line + len( replacement_lines ) - 1 |
| 1161 | cursor_column += len( replacement_lines[ - 1 ] ) - len( end_line_text ) |
| 1162 | SetCurrentLineAndColumn( cursor_line, cursor_column ) |
| 1163 | |
| 1164 | return { |
| 1165 | 'bufnr': vim_buffer.number, |
| 1166 | 'filename': vim_buffer.name, |
| 1167 | # line and column numbers are 1-based in qflist |
| 1168 | 'lnum': start_line + 1, |
| 1169 | 'col': start_column + 1, |
| 1170 | 'text': replacement_text, |
| 1171 | 'type': 'F', |
| 1172 | } |
| 1173 | |
| 1174 | |
| 1175 | def InsertNamespace( namespace ): |
no test coverage detected