aboutsummaryrefslogtreecommitdiffstats
path: root/spellcheck.lua
blob: 487a6734b1ee4c738ccaca113c0e4d698964d48b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
local module = {}
module.lang = os.getenv("LANG"):sub(0,5) or "en_US"
-- TODO use more spellcheckers (aspell/hunspell)
module.cmd = "enchant -d %s -a"

function spellcheck(file, range)
	local cmd = module.cmd:format(module.lang)
	local ret, so, se = vis:pipe(file, range, cmd)

	if ret ~= 0 then
		return ret, se
	end

	local word_corrections = so:gmatch("(.-)\n")
	-- skip header line
	word_corrections()

	local orig = file:content(range)
	local new = orig:gsub("%S+", function(w)
		local correction = word_corrections()
		-- empty correction means a new line in range
		if correction == "" then
			correction = word_corrections()
		end
		if correction and correction ~= "*" then
			-- get corrections
			local orig, pos, sug = correction:match("& (%S+) %d+ (%d+): (.*)")
			if orig ~= w then
				orig = orig or "nil"
				print("Bad things happend!! Correction: " .. orig  .. " is not for " .. w)
				return w
			end
			-- select a correction
			local cmd = 'printf "' .. sug:gsub(", ", "\\n") .. '\\n" | vis-menu'
			local f = io.popen(cmd)
			correction = f:read("*all")
			-- trim correction
			correction = correction:match("%S+")
			f:close()
			if correction then
				return correction
			end
		else
			print("Bad things happend!! No correction available for " .. w)
		end
	end)

	if orig ~= new then
		file:delete(range)
		file:insert(range.start, new)
	end
end

vis:map(vis.modes.NORMAL, "<C-s>", function(keys)
	local win = vis.win
	local file = win.file
	ret, err = spellcheck(file, { start=0, finish=file.size })
	if ret then
		vis:info(err)
	end
	win:draw()
	return 0
end, "Spellcheck the whole file")

vis:map(vis.modes.NORMAL, "<C-w>", function(keys)
	local win = vis.win
	local file = win.file
	local pos = win.cursor.pos
	if not pos then return end
	local range = file:text_object_word(pos > 0 and pos-1 or pos);
	if not range then return end
	if range.start == range.finish then return end
	ret, err = spellcheck(file, range)
	if ret then
		vis:info(err)
	end
	win:draw()
	return 0
end, "Spellcheck word")

return module