@@ -2,6 +2,18 @@ local buffer = require("nvim-surround.buffer")
22
33local M = {}
44
5+ -- Gets the EOL character for the current buffer, based on the file format.
6+ --- @return s string @The EOL character for the buffer.
7+ --- @nodiscard
8+ local end_of_line = function ()
9+ if vim .bo .fileformat == " dos" then
10+ return " \r\n "
11+ elseif vim .bo .fileformat == " mac" then
12+ return " \r "
13+ end
14+ return " \n "
15+ end
16+
517-- Converts a 1D index into the buffer to the corresponding 2D buffer position.
618--- @param index integer The index of the character in the buffer (viewed as a single ` \n` -joined string ).
719--- @return position @The position of the character in the buffer.
1830--- @return integer @The index of the character into the buffer.
1931--- @nodiscard
2032M .pos_to_index = function (pos )
21- return vim .api .nvim_buf_get_offset (0 , pos [1 ] - 1 ) + pos [2 ]
33+ local index = vim .api .nvim_buf_get_offset (0 , pos [1 ] - 1 ) + pos [2 ]
34+ -- The API call assumes that the EOL character is 1 byte, but on Windows machines CRLF is 2 bytes. Here we add back
35+ -- the expected number of `\r` bytes when computing the index.
36+ if vim .bo .fileformat == " dos" then
37+ index = index + pos [1 ] - 1
38+ end
39+
40+ return index
2241end
2342
2443-- Expands a selection to properly contain multi-byte characters.
3857M .get_selection = function (find )
3958 -- Get the current cursor position, buffer contents
4059 local curpos = buffer .get_curpos ()
41- local buffer_text = table.concat (buffer .get_lines (1 , - 1 ), " \n " )
60+ local buffer_text = table.concat (buffer .get_lines (1 , - 1 ), end_of_line () )
4261 -- Find which character the cursor is in the file
4362 local cursor_index = M .pos_to_index (curpos )
4463 -- Find the character positions of the pattern in the file (after/on the cursor)
@@ -48,7 +67,7 @@ M.get_selection = function(find)
4867 -- Linewise search for the pattern before/on the cursor
4968 for lnum = curpos [1 ], 1 , - 1 do
5069 -- Get the file contents from the first line to current line
51- local cur_text = table.concat (buffer .get_lines (1 , lnum - 1 ), " \n " )
70+ local cur_text = table.concat (buffer .get_lines (1 , lnum - 1 ), end_of_line () )
5271 -- Find the character positions of the pattern in the file (before the cursor)
5372 b_first , b_last = buffer_text :find (find , # cur_text + 1 )
5473 if b_first and b_first <= cursor_index then
112131--- @nodiscard
113132M .get_selections = function (selection , pattern )
114133 local offset = M .pos_to_index (selection .first_pos )
115- local str = table.concat (buffer .get_text (selection ), " \n " )
134+ local str = table.concat (buffer .get_text (selection ), end_of_line () )
116135 -- Get the surrounding pair, and the start/end indices
117136 local ok , _ , left_delimiter , first_index , right_delimiter , last_index = str :find (pattern )
118137 -- Validate that a match was found
0 commit comments