Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Plugin] Dvorak-friendly Remappings #1184

Closed
VehementHam opened this issue Apr 29, 2024 · 10 comments
Closed

[Plugin] Dvorak-friendly Remappings #1184

VehementHam opened this issue Apr 29, 2024 · 10 comments

Comments

@VehementHam
Copy link

VehementHam commented Apr 29, 2024

What feature would you like to see?

As a user of the Dvorak keyboard layout, I hate how everything is designed for QWERTY. I have gone ahead and remapped the keys in almost every application that I use to better fit the Dvorak keyboard layout.

Here is what I did to Vis:

  • Remapped the mappings involving HJKL to the corrasponding DHTN keys on the Dvorak keyboaord.
  • All mappings involving the keys hjkl and their capitol counterparts are remaped.
  • Because binds involving d, n, t already exist, all binds involving dnt are remmapped to klj.
    This provides for a much more ergonomic workflow as intended by Vim's design for the QWERTY layout.

I am having trouble re-adding descriptions to the bindings. That is WIP.

The code for rebinding in this way is as follows:

-- ...

vis.events.subscribe(vis.events.INIT, function()
	-- Your global configuration options

	-- Dvorak-friendly Remappings
	
	-- key unmapppings
	vis:unmap(vis.modes.NORMAL, "<M-C-j>")
	vis:unmap(vis.modes.NORMAL, "<M-C-k")
	vis:unmap(vis.modes.NORMAL, "<C-w>j")
	vis:unmap(vis.modes.NORMAL, "gj")
	vis:unmap(vis.modes.NORMAL, "gJ")

	vis:unmap(vis.modes.OPERATOR_PENDING, "j")
	vis:unmap(vis.modes.OPERATOR_PENDING, "il")
	vis:unmap(vis.modes.OPERATOR_PENDING, "al")
	vis:unmap(vis.modes.OPERATOR_PENDING, "gj")

	vis:unmap(vis.modes.VISUAL, "<C-j>")
	vis:unmap(vis.modes.VISUAL, "il")
	vis:unmap(vis.modes.VISUAL, "al")
	vis:unmap(vis.modes.VISUAL, "gj")
	vis:unmap(vis.modes.NORMAL, "gJ")

	-- key mappings -- followed by bind it replaces
	vis:map(vis.modes.NORMAL, "d", "<vis-motion-char-prev>") -- h
	vis:map(vis.modes.NORMAL, "h", "<vis-motion-line-down>") -- j
	vis:map(vis.modes.NORMAL, "t", "<vis-motion-line-up>") -- k
	vis:map(vis.modes.NORMAL, "n", "<vis-motion-char-next>") -- l
	vis:map(vis.modes.NORMAL, "D", "<vis-motion-window-line-top>") -- H
	vis:map(vis.modes.NORMAL, "H", "<vis-join-lines>") -- J
	vis:map(vis.modes.NORMAL, "N", "<vis-motion-window-line-bottom>") -- L
	vis:map(vis.modes.NORMAL, "l", "<vis-motion-search-repeat>") -- n
	vis:map(vis.modes.NORMAL, "L", "<vis-motion-search-repeat-backward>") -- N
	vis:map(vis.modes.NORMAL, "k", "<vis-operator-delete>") -- d
	vis:map(vis.modes.NORMAL, "K", "k$") -- D, d$
	vis:map(vis.modes.NORMAL, "<M-C-h>", "<vis-new-selection-lines-below-last>") -- <M-C-j>
	vis:map(vis.modes.NORMAL, "<M-C-t>", "<vis-new-selection-lines-above-first>") -- <M-C-k>
	vis:map(vis.modes.NORMAL, "<C-w>d", "<C-w>t") -- <C-w>h, <C-w>k
	vis:map(vis.modes.NORMAL, "<C-w>h", "<vis-window-next>") -- <C-w>j
	vis:map(vis.modes.NORMAL, "<C-w>t", "<vis-window-prev>") -- <C-w>k
	vis:map(vis.modes.NORMAL, "<C-w>n", "<C-w>h") -- <C-w>l, <C-w>j
	vis:map(vis.modes.NORMAL, "<C-w>l", ":open<Enter>") -- <C-w>n
	vis:map(vis.modes.NORMAL, "<C-h>", "<new-selection-lines-below>") -- <C-j>
	vis:map(vis.modes.NORMAL, "<C-t>", "<new-selection-lines-above>") -- <C-k>
	vis:map(vis.modes.NORMAL, "<C-n>", "<vis-selections-remove-column-except>") -- <C-l>
	vis:map(vis.modes.NORMAL, "<C-k>", "<vis-selection-next>") -- <C-d>
	vis:map(vis.modes.NORMAL, "<C-l>", "viw") -- <C-n>
	vis:map(vis.modes.NORMAL, "+", "h^") -- +, j^
	vis:map(vis.modes.NORMAL, "-", "t^") -- -, k^
	vis:map(vis.modes.NORMAL, "X", "kd") -- X, dh
	vis:map(vis.modes.NORMAL, "s", "cn") -- s, cl
	vis:map(vis.modes.NORMAL, "gD", "<vis-motion-byte-left>") -- gH
	vis:map(vis.modes.NORMAL, "gH", "<vis-join-lines-trim>") -- gJ
	vis:map(vis.modes.NORMAL, "gN", "<vis-motion-byte-right>") -- gL
	vis:map(vis.modes.NORMAL, "gL", "vgL") -- gN, vgN
	vis:map(vis.modes.NORMAL, "gd", "<vis-motion-codepoint-prev>") -- gh
	vis:map(vis.modes.NORMAL, "gh", "<vis-motion-screenline-down>") -- gj
	vis:map(vis.modes.NORMAL, "gt", "<vis-motion-screenline-up>") -- gk
	vis:map(vis.modes.NORMAL, "gn", "<vis-motion-codepoint-next>") -- gl
	vis:map(vis.modes.NORMAL, "gl", "vgl") -- gn, vgn
	vis:map(vis.modes.NORMAL, "j", "vis-motion-till-line-right") -- t
	vis:map(vis.modes.NORMAL, "J", "vis-motion-till-line-left") -- T

	vis:map(vis.modes.OPERATOR_PENDING, "k", "<vis-operator-delete>") -- d
	vis:map(vis.modes.OPERATOR_PENDING, "d", "<vis-motion-char-prev>") -- h
	vis:map(vis.modes.OPERATOR_PENDING, "h", "<vis-motion-line-down>") -- j
	vis:map(vis.modes.OPERATOR_PENDING, "t", "<vis-motion-line-up>") -- k
	vis:map(vis.modes.OPERATOR_PENDING, "n", "<vis-motion-char-next>")  -- l
	vis:map(vis.modes.OPERATOR_PENDING, "D", "<vis-motion-window-line-top>") -- H
	vis:map(vis.modes.OPERATOR_PENDING, "N", "<vis-motion-window-line-bottom>") -- L
	vis:map(vis.modes.OPERATOR_PENDING, "l", "<vis-motion-search-repeat>") -- n
	vis:map(vis.modes.OPERATOR_PENDING, "L", "<vis-motion-search-repeat-backward>") -- N
	vis:map(vis.modes.OPERATOR_PENDING, "in", "<vis-textobject-line-inner>") -- il
	vis:map(vis.modes.OPERATOR_PENDING, "an", "<vis-textobject-line-outer>") -- al
	vis:map(vis.modes.OPERATOR_PENDING, "+", "h^") -- +, j^
	vis:map(vis.modes.OPERATOR_PENDING, "-", "t^") -- -, k^
	vis:map(vis.modes.OPERATOR_PENDING, "gD", "<vis-motion-byte-left>") -- gH
	vis:map(vis.modes.OPERATOR_PENDING, "gN", "<vis-motion-byte-right>") -- gL
	vis:map(vis.modes.OPERATOR_PENDING, "gL", "<vis-textobject-search-backward>") -- gN
	vis:map(vis.modes.OPERATOR_PENDING, "gd", "<vis-motion-codepoint-prev>") -- gh
	vis:map(vis.modes.OPERATOR_PENDING, "gh", "<vis-motion-screenline-down>") -- gj
	vis:map(vis.modes.OPERATOR_PENDING, "gt", "<vis-motion-screenline-up>") -- gk
	vis:map(vis.modes.OPERATOR_PENDING, "gn", "<vis-motion-codepoint-next>") -- gl
	vis:map(vis.modes.OPERATOR_PENDING, "gl", "<vis-textobject-search-forward>") -- gn
	vis:map(vis.modes.OPERATOR_PENDING, "j", "vis-motion-till-line-right") -- t
	vis:map(vis.modes.OPERATOR_PENDING, "J", "vis-motion-till-line-left") -- T

	vis:map(vis.modes.VISUAL, "d", "<vis-motion-char-prev>") -- h
	vis:map(vis.modes.VISUAL, "h", "<vis-motion-line-down>") -- j
	vis:map(vis.modes.VISUAL, "t", "<vis-motion-line-up>") -- k
	vis:map(vis.modes.VISUAL, "n", "<vis-motion-char-next>") -- l
	vis:map(vis.modes.VISUAL, "D", "<vis-motion-window-line-top>") -- H
	vis:map(vis.modes.VISUAL, "H", "<vis-join-lines>") -- J
	vis:map(vis.modes.VISUAL, "N", "<vis-motion-window-line-bottom>") -- L
	vis:map(vis.modes.VISUAL, "l", "<vis-motion-search-repeat>") -- n
	vis:map(vis.modes.VISUAL, "L", "<vis-motion-search-repeat-backward>") -- N
	vis:map(vis.modes.VISUAL, "k", "<vis-operator-delete>") -- d
	vis:map(vis.modes.VISUAL, "<C-h>", "<C-k>") -- <C-j>, <C-d>
	vis:map(vis.modes.VISUAL, "<C-t>", "<C-u>") -- <C-k>
	vis:map(vis.modes.VISUAL, "<C-n>", "<vis-selections-remove-column-except>") -- <C-l>
	vis:map(vis.modes.VISUAL, "<C-l>", "<vis-selection-new-match-next>") -- <C-n>
	vis:map(vis.modes.VISUAL, "<C-k>", "<vis-selection-next>") -- <C-d>
	vis:map(vis.modes.VISUAL, "in", "<vis-textobject-line-inner>") -- il
	vis:map(vis.modes.VISUAL, "an", "<vis-textobject-line-outer>") -- al
	vis:map(vis.modes.VISUAL, "x", "k") -- x, d
	vis:map(vis.modes.VISUAL, "gD", "<vis-motion-byte-left>") -- gH
	vis:map(vis.modes.VISUAL, "gH", "<vis-join-lines-trim>") -- gJ
	vis:map(vis.modes.VISUAL, "gN", "<vis-motion-byte-right>") -- gL
	vis:map(vis.modes.VISUAL, "gL", "<vis-textobject-search-backward>") -- gN
	vis:map(vis.modes.VISUAL, "gd", "<vis-motion-codepoint-prev>") -- gh
	vis:map(vis.modes.VISUAL, "gh", "<vis-motion-screenline-down>") -- gj
	vis:map(vis.modes.VISUAL, "gt", "<vis-motion-screenline-up>") -- gk
	vis:map(vis.modes.VISUAL, "gn", "<vis-motion-codepoint-next>") -- gl
	vis:map(vis.modes.VISUAL, "gl", "<vis-textobject-search-forward>") -- gn
	vis:map(vis.modes.VISUAL, "j", "vis-motion-till-line-right") -- t
	vis:map(vis.modes.VISUAL, "J", "vis-motion-till-line-left") -- T

	vis:map(vis.modes.INSERT, "<C-d>", "<Backspace>") -- <C-h>
	vis:map(vis.modes.INSERT, "<C-h>", "<vis-insert-verbatim>u000a") -- <C-j>
	vis:map(vis.modes.INSERT, "<C-t>", function(keys) 
		if #keys < 2 then
			return -1 -- need more input
		end
		local file = io.popen(string.format("vis-digraph '%s' 2>&1", keys:gsub("'", "'\\''")))
		local output = file:read('*all')
		local success, msg, status = file:close()
		if success then
			if vis.mode == vis.modes.INSERT then
				vis:insert(output)
			elseif vis.mode == vis.modes.REPLACE then
				vis:replace(output)
			end
		elseif msg == 'exit' then
			if status == 2 then
				return -1 -- prefix need more input
			end
			vis:info(output)
		end
		return #keys
	end, "Insert digraph") -- <C-k>
	vis:map(vis.modes.INSERT, "<C-k>", "<vis-operator-shift-left><vis-operator-shift-left>") -- <C-d>
	vis:map(vis.modes.INSERT, "<C-l>", function()
		local win = vis.win
		local file = win.file
		local pos = win.selection.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.finish > pos then range.finish = pos end
		if range.start == range.finish then return end
		local prefix = file:content(range)
		if not prefix then return end

		vis:feedkeys("<vis-selections-save><Escape><Escape>")
		-- collect words starting with prefix
		vis:command("x/\\b" .. prefix .. "\\w+/")
		local candidates = {}
		for sel in win:selections_iterator() do
			table.insert(candidates, file:content(sel.range))
		end
		vis:feedkeys("<Escape><Escape><vis-selections-restore>")
		if #candidates == 1 and candidates[1] == "\n" then return end
		candidates = table.concat(candidates, "\n")

		local cmd = "printf '" .. candidates .. "' | sort -u | vis-menu"
		local status, out, err = vis:pipe(cmd)
		if status ~= 0 or not out then
			if err then vis:info(err) end
			return
		end
		out = out:sub(#prefix + 1, #out - 1)
		file:insert(pos, out)
		win.selection.pos = pos + #out
		-- restore mode to what it was on entry
		vis.mode = vis.modes.INSERT
	end, "Complete word in file") -- <C-n>
	vis:map(vis.modes.INSERT, "<C-j>", "<vis-operator-shift-right><vis-operator-shift-right>") -- <C-t>
end)

-- ...
@VehementHam
Copy link
Author

VehementHam commented Apr 29, 2024

BTW Michael Forney uses Dvorak.

@mcepl
Copy link
Contributor

mcepl commented Apr 29, 2024

This very much looks like the best candidate for a separate plugin you would manage. The beauty of vis is that it is so simple to create new plugins in Lua and then just to keep them around.

@VehementHam
Copy link
Author

Good idea. I might make a plugin. Sounds like a lot better of an idea than adding to the wiki

@VehementHam
Copy link
Author

VehementHam commented Apr 29, 2024

Still having issues with adding a description. I add a third argument, a string, as the description, but it doesn't display on the :help file.

@VehementHam
Copy link
Author

VehementHam commented Apr 29, 2024

I guess that this constitutes a plugin.

Of course, I will make a git repo for it and whatnot after I resolve description issue, and return the respective descriptions.

require("vis")

vis.events.subscribe(vis.events.INIT, function()
	-- key unmapppings
	vis:unmap(vis.modes.NORMAL, "<M-C-j>")
	vis:unmap(vis.modes.NORMAL, "<M-C-k")
	vis:unmap(vis.modes.NORMAL, "<C-w>j")
	vis:unmap(vis.modes.NORMAL, "gj")
	vis:unmap(vis.modes.NORMAL, "gJ")

	vis:unmap(vis.modes.OPERATOR_PENDING, "j")
	vis:unmap(vis.modes.OPERATOR_PENDING, "il")
	vis:unmap(vis.modes.OPERATOR_PENDING, "al")
	vis:unmap(vis.modes.OPERATOR_PENDING, "gj")

	vis:unmap(vis.modes.VISUAL, "<C-j>")
	vis:unmap(vis.modes.VISUAL, "il")
	vis:unmap(vis.modes.VISUAL, "al")
	vis:unmap(vis.modes.VISUAL, "gj")
	vis:unmap(vis.modes.NORMAL, "gJ")

	-- key mappings -- followed by bind it replaces
	vis:map(vis.modes.NORMAL, "d", "<vis-motion-char-prev>") -- h
	vis:map(vis.modes.NORMAL, "h", "<vis-motion-line-down>") -- j
	vis:map(vis.modes.NORMAL, "t", "<vis-motion-line-up>") -- k
	vis:map(vis.modes.NORMAL, "n", "<vis-motion-char-next>") -- l
	vis:map(vis.modes.NORMAL, "D", "<vis-motion-window-line-top>") -- H
	vis:map(vis.modes.NORMAL, "H", "<vis-join-lines>") -- J
	vis:map(vis.modes.NORMAL, "N", "<vis-motion-window-line-bottom>") -- L
	vis:map(vis.modes.NORMAL, "l", "<vis-motion-search-repeat>") -- n
	vis:map(vis.modes.NORMAL, "L", "<vis-motion-search-repeat-backward>") -- N
	vis:map(vis.modes.NORMAL, "k", "<vis-operator-delete>") -- d
	vis:map(vis.modes.NORMAL, "K", "k$") -- D, d$
	vis:map(vis.modes.NORMAL, "<M-C-h>", "<vis-new-selection-lines-below-last>") -- <M-C-j>
	vis:map(vis.modes.NORMAL, "<M-C-t>", "<vis-new-selection-lines-above-first>") -- <M-C-k>
	vis:map(vis.modes.NORMAL, "<C-w>d", "<C-w>t") -- <C-w>h, <C-w>k
	vis:map(vis.modes.NORMAL, "<C-w>h", "<vis-window-next>") -- <C-w>j
	vis:map(vis.modes.NORMAL, "<C-w>t", "<vis-window-prev>") -- <C-w>k
	vis:map(vis.modes.NORMAL, "<C-w>n", "<C-w>h") -- <C-w>l, <C-w>j
	vis:map(vis.modes.NORMAL, "<C-w>l", ":open<Enter>") -- <C-w>n
	vis:map(vis.modes.NORMAL, "<C-h>", "<new-selection-lines-below>") -- <C-j>
	vis:map(vis.modes.NORMAL, "<C-t>", "<new-selection-lines-above>") -- <C-k>
	vis:map(vis.modes.NORMAL, "<C-n>", "<vis-selections-remove-column-except>") -- <C-l>
	vis:map(vis.modes.NORMAL, "<C-k>", "<vis-selection-next>") -- <C-d>
	vis:map(vis.modes.NORMAL, "<C-l>", "viw") -- <C-n>
	vis:map(vis.modes.NORMAL, "+", "h^") -- +, j^
	vis:map(vis.modes.NORMAL, "-", "t^") -- -, k^
	vis:map(vis.modes.NORMAL, "X", "kd") -- X, dh
	vis:map(vis.modes.NORMAL, "s", "cn") -- s, cl
	vis:map(vis.modes.NORMAL, "gD", "<vis-motion-byte-left>") -- gH
	vis:map(vis.modes.NORMAL, "gH", "<vis-join-lines-trim>") -- gJ
	vis:map(vis.modes.NORMAL, "gN", "<vis-motion-byte-right>") -- gL
	vis:map(vis.modes.NORMAL, "gL", "vgL") -- gN, vgN
	vis:map(vis.modes.NORMAL, "gd", "<vis-motion-codepoint-prev>") -- gh
	vis:map(vis.modes.NORMAL, "gh", "<vis-motion-screenline-down>") -- gj
	vis:map(vis.modes.NORMAL, "gt", "<vis-motion-screenline-up>") -- gk
	vis:map(vis.modes.NORMAL, "gn", "<vis-motion-codepoint-next>") -- gl
	vis:map(vis.modes.NORMAL, "gl", "vgl") -- gn, vgn
	vis:map(vis.modes.NORMAL, "j", "vis-motion-till-line-right") -- t
	vis:map(vis.modes.NORMAL, "J", "vis-motion-till-line-left") -- T

	vis:map(vis.modes.OPERATOR_PENDING, "k", "<vis-operator-delete>") -- d
	vis:map(vis.modes.OPERATOR_PENDING, "d", "<vis-motion-char-prev>") -- h
	vis:map(vis.modes.OPERATOR_PENDING, "h", "<vis-motion-line-down>") -- j
	vis:map(vis.modes.OPERATOR_PENDING, "t", "<vis-motion-line-up>") -- k
	vis:map(vis.modes.OPERATOR_PENDING, "n", "<vis-motion-char-next>")  -- l
	vis:map(vis.modes.OPERATOR_PENDING, "D", "<vis-motion-window-line-top>") -- H
	vis:map(vis.modes.OPERATOR_PENDING, "N", "<vis-motion-window-line-bottom>") -- L
	vis:map(vis.modes.OPERATOR_PENDING, "l", "<vis-motion-search-repeat>") -- n
	vis:map(vis.modes.OPERATOR_PENDING, "L", "<vis-motion-search-repeat-backward>") -- N
	vis:map(vis.modes.OPERATOR_PENDING, "in", "<vis-textobject-line-inner>") -- il
	vis:map(vis.modes.OPERATOR_PENDING, "an", "<vis-textobject-line-outer>") -- al
	vis:map(vis.modes.OPERATOR_PENDING, "+", "h^") -- +, j^
	vis:map(vis.modes.OPERATOR_PENDING, "-", "t^") -- -, k^
	vis:map(vis.modes.OPERATOR_PENDING, "gD", "<vis-motion-byte-left>") -- gH
	vis:map(vis.modes.OPERATOR_PENDING, "gN", "<vis-motion-byte-right>") -- gL
	vis:map(vis.modes.OPERATOR_PENDING, "gL", "<vis-textobject-search-backward>") -- gN
	vis:map(vis.modes.OPERATOR_PENDING, "gd", "<vis-motion-codepoint-prev>") -- gh
	vis:map(vis.modes.OPERATOR_PENDING, "gh", "<vis-motion-screenline-down>") -- gj
	vis:map(vis.modes.OPERATOR_PENDING, "gt", "<vis-motion-screenline-up>") -- gk
	vis:map(vis.modes.OPERATOR_PENDING, "gn", "<vis-motion-codepoint-next>") -- gl
	vis:map(vis.modes.OPERATOR_PENDING, "gl", "<vis-textobject-search-forward>") -- gn
	vis:map(vis.modes.OPERATOR_PENDING, "j", "vis-motion-till-line-right") -- t
	vis:map(vis.modes.OPERATOR_PENDING, "J", "vis-motion-till-line-left") -- T

	vis:map(vis.modes.VISUAL, "d", "<vis-motion-char-prev>") -- h
	vis:map(vis.modes.VISUAL, "h", "<vis-motion-line-down>") -- j
	vis:map(vis.modes.VISUAL, "t", "<vis-motion-line-up>") -- k
	vis:map(vis.modes.VISUAL, "n", "<vis-motion-char-next>") -- l
	vis:map(vis.modes.VISUAL, "D", "<vis-motion-window-line-top>") -- H
	vis:map(vis.modes.VISUAL, "H", "<vis-join-lines>") -- J
	vis:map(vis.modes.VISUAL, "N", "<vis-motion-window-line-bottom>") -- L
	vis:map(vis.modes.VISUAL, "l", "<vis-motion-search-repeat>") -- n
	vis:map(vis.modes.VISUAL, "L", "<vis-motion-search-repeat-backward>") -- N
	vis:map(vis.modes.VISUAL, "k", "<vis-operator-delete>") -- d
	vis:map(vis.modes.VISUAL, "<C-h>", "<C-k>") -- <C-j>, <C-d>
	vis:map(vis.modes.VISUAL, "<C-t>", "<C-u>") -- <C-k>
	vis:map(vis.modes.VISUAL, "<C-n>", "<vis-selections-remove-column-except>") -- <C-l>
	vis:map(vis.modes.VISUAL, "<C-l>", "<vis-selection-new-match-next>") -- <C-n>
	vis:map(vis.modes.VISUAL, "<C-k>", "<vis-selection-next>") -- <C-d>
	vis:map(vis.modes.VISUAL, "in", "<vis-textobject-line-inner>") -- il
	vis:map(vis.modes.VISUAL, "an", "<vis-textobject-line-outer>") -- al
	vis:map(vis.modes.VISUAL, "x", "k") -- x, d
	vis:map(vis.modes.VISUAL, "gD", "<vis-motion-byte-left>") -- gH
	vis:map(vis.modes.VISUAL, "gH", "<vis-join-lines-trim>") -- gJ
	vis:map(vis.modes.VISUAL, "gN", "<vis-motion-byte-right>") -- gL
	vis:map(vis.modes.VISUAL, "gL", "<vis-textobject-search-backward>") -- gN
	vis:map(vis.modes.VISUAL, "gd", "<vis-motion-codepoint-prev>") -- gh
	vis:map(vis.modes.VISUAL, "gh", "<vis-motion-screenline-down>") -- gj
	vis:map(vis.modes.VISUAL, "gt", "<vis-motion-screenline-up>") -- gk
	vis:map(vis.modes.VISUAL, "gn", "<vis-motion-codepoint-next>") -- gl
	vis:map(vis.modes.VISUAL, "gl", "<vis-textobject-search-forward>") -- gn
	vis:map(vis.modes.VISUAL, "j", "vis-motion-till-line-right") -- t
	vis:map(vis.modes.VISUAL, "J", "vis-motion-till-line-left") -- T

	vis:map(vis.modes.INSERT, "<C-d>", "<Backspace>") -- <C-h>
	vis:map(vis.modes.INSERT, "<C-h>", "<vis-insert-verbatim>u000a") -- <C-j>
	vis:map(vis.modes.INSERT, "<C-t>", function(keys) 
		if #keys < 2 then
			return -1 -- need more input
		end
		local file = io.popen(string.format("vis-digraph '%s' 2>&1", keys:gsub("'", "'\\''")))
		local output = file:read('*all')
		local success, msg, status = file:close()
		if success then
			if vis.mode == vis.modes.INSERT then
				vis:insert(output)
			elseif vis.mode == vis.modes.REPLACE then
				vis:replace(output)
			end
		elseif msg == 'exit' then
			if status == 2 then
				return -1 -- prefix need more input
			end
			vis:info(output)
		end
		return #keys
	end, "Insert digraph") -- <C-k>
	vis:map(vis.modes.INSERT, "<C-k>", "<vis-operator-shift-left><vis-operator-shift-left>") -- <C-d>
	vis:map(vis.modes.INSERT, "<C-l>", function()
		local win = vis.win
		local file = win.file
		local pos = win.selection.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.finish > pos then range.finish = pos end
		if range.start == range.finish then return end
		local prefix = file:content(range)
		if not prefix then return end

		vis:feedkeys("<vis-selections-save><Escape><Escape>")
		-- collect words starting with prefix
		vis:command("x/\\b" .. prefix .. "\\w+/")
		local candidates = {}
		for sel in win:selections_iterator() do
			table.insert(candidates, file:content(sel.range))
		end
		vis:feedkeys("<Escape><Escape><vis-selections-restore>")
		if #candidates == 1 and candidates[1] == "\n" then return end
		candidates = table.concat(candidates, "\n")

		local cmd = "printf '" .. candidates .. "' | sort -u | vis-menu"
		local status, out, err = vis:pipe(cmd)
		if status ~= 0 or not out then
			if err then vis:info(err) end
			return
		end
		out = out:sub(#prefix + 1, #out - 1)
		file:insert(pos, out)
		win.selection.pos = pos + #out
		-- restore mode to what it was on entry
		vis.mode = vis.modes.INSERT
	end, "Complete word in file") -- <C-n>
	vis:map(vis.modes.INSERT, "<C-j>", "<vis-operator-shift-right><vis-operator-shift-right>") -- <C-t>
end)

@VehementHam VehementHam changed the title [Feature Request][Wiki][Tips and Tricks] Dvorak-friendly Remappings [Plugin] Dvorak-friendly Remappings Apr 29, 2024
@pippi1otta
Copy link

Still having issues with adding a description. I add a third argument, a string, as the description, but it doesn't display on the :help file. ~@VehementHam

https://martanne.github.io/vis/doc/#Vis:map

You are using the third signature of Vis:map:

Vis:map(mode, key, alias)

It doesn't accept a help argument. Only the first one does:

Vis:map(mode, key, func[, help])

@rnpnr
Copy link
Collaborator

rnpnr commented Apr 30, 2024

It doesn't accept a help argument. Only the first one does:

Heres a little function I have used in the past to help with that case:

-- returns a function that when called runs vis:feedkeys(keys)
local fk = function(keys)
	return function ()
		vis:feedkeys(keys)
	end
end

vis:map(vis.modes.NORMAL, "d", fk("<vis-motion-char-prev>"), "Help Text")

I'm not sure there is a good way of doing the help text though without just copying all of it directly. You could distribute a dvorak config.h instead which wouldn't require the copying.

@VehementHam
Copy link
Author

I might make a seperate config.h in addition to the plugin.

Just wondering, how come you do this?

fk("<vis-motion-char-prev>")

What is the purpose of the fk()?

@rnpnr
Copy link
Collaborator

rnpnr commented Apr 30, 2024

What is the purpose of the fk()?

It's mostly a style thing. You could define the function inline:

vis:map(vis.modes.NORMAL, "d", function() vis:feedkeys("<vis-motion-char-prev>") end, "Help Text")

But that I find that very ugly if you aren't doing anything else in the body. You can't put vis:feedkeys there directly as it will get called when vis:map gets called and not do what you want.

@VehementHam
Copy link
Author

VehementHam commented Apr 30, 2024

I see why, because you have to map to a function (in order to make use of the help text argument).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants