local vim = vim local line_splitter = require 'line_splitter' local nvu = require 'nvim_utils' local format = string.format local concat = table.concat local startswith = require 'startswith' local insert = table.insert local remove = table.remove local patterns = [===[ s/const Vector& \([a-zA-Z_]\+\)/\1: \&Vector s/const Matrix& \([a-zA-Z_]\+\)/\1: \&Matrix s/Vector& \([a-zA-Z_]\+\)/\1: \&mut Vector s/Matrix& \([a-zA-Z_]\+\)/\1: \&mut Matrix s/\[\([^\]]\+\)\]\[\([^\]]\+\)\]/[(\1, \2)]/g s/\(Vector\)\s\+\(\w\+\)(\([^)]\+\))\s*[,;]\?\s*/let mut \2 = Vector::zeros(\3);\r\1 /g s/\(Vector\)\s\+\(\w\+\)(\([^)]\+\))\s*[,;]\?\s*/let mut \2 = IVector::zeros(\3);\r\1 /g s/\(Vector\)\s\+\(\w\+\)(\([^)]\+\))\s*[,;]\?\s*/let mut \2 = BVector::default(\3);\r\1 /g s/\(double\)\s\+\(\([a-zA-Z_0-9]\+\),\?\)\+/let mut \3: f64 = 0.0f64;\r\1 /g s/\(unsigned int\)\s\+\(\([a-zA-Z_0-9]\+\),\?\)\+/let mut \3: usize = 0;\r\1 /g s/for (\([ijk]\) = \([^;]\+\); \1 <\s*\([^;]\+\); \1++)/for \1 in (\2)..(\3)/ s/for (\([ijk]\) = \([^;]\+\); \1\s*>=\s*\([^;]\+\);\s*\1--)/for \1 in ((\3)..(\2 + 1)).rev()/ s/scalar_product(\([^,)]\+\),\s*\([^,)]\+\))/\1.dot(\&\2)/g s/std::max(\([^,)]\+\),\s*\([^,)]\+\))/\1.max(\2)/g s/std::min(\([^,)]\+\),\s*\([^,)]\+\))/\1.min(\2)/g s/sqrt(\([^,)]\+\))/(\1).sqrt()/g s/fabs(\([^,)]\+\))/(\1).abs()/g s/std::numeric_limits::epsilon()/f64::EPSILON/g s/\([a-zA-Z0-9_]\+\)++;/\1 += 1;/ s/\([a-zA-Z0-9_]\+\)--;/\1 -= 1;/ s/goto\s\+\([a-zA-Z0-9_]\+\);/continue '\1;/ ]===] return { on_attach = function(fname, root) if vim.bo.ft == 'rust' then nvu.nvim_create_commands({ Transform1 = { function() nvu.nvim_buf_transform_region_lines(0, '<', '>', VISUAL_MODE.line, function(lines) local r = {} local deleting = false local gotos = {} for _, line in ipairs(lines) do if not deleting and line:find("#ifdef", 1, true) then deleting = true end if not deleting then line = line:gsub("^%s*([a-z0-9A-Z_]+):", function(label) if label == "std" then return end gotos[#gotos+1] = label r[#r+1] = format("'%s: loop {", label) return "" end) r[#r+1] = line end if deleting and line:find("#endif", 1, true) then deleting = false end end while #gotos > 0 do local label = remove(gotos) r[#r+1] = format("break '%s;", label) r[#r+1] = "}" end return r end) end; range = true; buffer = true; }; Transform = { function() for pattern in line_splitter().drain(patterns) do for i = 1, 10 do vim.cmd("silent! '<,'>".."+"..i..pattern) end end end; range = true; buffer = true; }; }) end end }