@@ -71,7 +71,7 @@ def main():
7171 encoding = vim .eval ("&encoding" )
7272 buf = get_buffer (encoding )
7373 # Join the buffer into a single string with a terminating newline
74- text = '\n ' .join (buf ) + '\n '
74+ text = ( '\n ' .join (buf ) + '\n ' ). encode ( encoding )
7575
7676 # Determine range to format.
7777 if vim .eval ('exists("l:lines")' ) == '1' :
@@ -90,9 +90,14 @@ def main():
9090 lines = ['-lines' , '%s:%s' % (vim .current .range .start + 1 ,
9191 vim .current .range .end + 1 )]
9292
93- # Determine the cursor position.
94- cursor = int (vim .eval ('line2byte(line("."))+col(".")' )) - 2
95- if cursor < 0 :
93+ # Convert cursor (line, col) to bytes.
94+ # Don't use line2byte: https://github.com/vim/vim/issues/5930
95+ _ , cursor_line , cursor_col , _ = vim .eval ('getpos(".")' ) # 1-based
96+ cursor_byte = 0
97+ for line in text .split (b'\n ' )[:int (cursor_line ) - 1 ]:
98+ cursor_byte += len (line ) + 1
99+ cursor_byte += int (cursor_col ) - 1
100+ if cursor_byte < 0 :
96101 print ('Couldn\' t determine cursor position. Is your file empty?' )
97102 return
98103
@@ -104,7 +109,7 @@ def main():
104109 startupinfo .wShowWindow = subprocess .SW_HIDE
105110
106111 # Call formatter.
107- command = [binary , '-cursor' , str (cursor )]
112+ command = [binary , '-cursor' , str (cursor_byte )]
108113 if lines != ['-lines' , 'all' ]:
109114 command += lines
110115 if style :
@@ -116,7 +121,7 @@ def main():
116121 p = subprocess .Popen (command ,
117122 stdout = subprocess .PIPE , stderr = subprocess .PIPE ,
118123 stdin = subprocess .PIPE , startupinfo = startupinfo )
119- stdout , stderr = p .communicate (input = text . encode ( encoding ) )
124+ stdout , stderr = p .communicate (input = text )
120125
121126 # If successful, replace buffer contents.
122127 if stderr :
@@ -128,18 +133,24 @@ def main():
128133 'Please report to bugs.llvm.org.'
129134 )
130135 else :
131- lines = stdout .decode ( encoding ). split ('\n ' )
132- output = json .loads (lines [ 0 ] )
136+ header , content = stdout .split (b '\n ', 1 )
137+ header = json .loads (header )
133138 # Strip off the trailing newline (added above).
134139 # This maintains trailing empty lines present in the buffer if
135140 # the -lines specification requests them to remain unchanged.
136- lines = lines [ 1 :- 1 ]
141+ lines = content . decode ( encoding ). split ( ' \n ' )[ :- 1 ]
137142 sequence = difflib .SequenceMatcher (None , buf , lines )
138143 for op in reversed (sequence .get_opcodes ()):
139144 if op [0 ] != 'equal' :
140145 vim .current .buffer [op [1 ]:op [2 ]] = lines [op [3 ]:op [4 ]]
141- if output .get ('IncompleteFormat' ):
146+ if header .get ('IncompleteFormat' ):
142147 print ('clang-format: incomplete (syntax errors)' )
143- vim .command ('goto %d' % (output ['Cursor' ] + 1 ))
148+ # Convert cursor bytes to (line, col)
149+ # Don't use goto: https://github.com/vim/vim/issues/5930
150+ cursor_byte = int (header ['Cursor' ])
151+ prefix = content [0 :cursor_byte ]
152+ cursor_line = 1 + prefix .count (b'\n ' )
153+ cursor_column = 1 + len (prefix .rsplit (b'\n ' , 1 )[- 1 ])
154+ vim .command ('call cursor(%d, %d)' % (cursor_line , cursor_column ))
144155
145156main ()
0 commit comments