multiple digits

This commit is contained in:
Xinhao Yuan 2019-07-09 22:07:54 -04:00
parent 21cad445ae
commit ad3273f42a
2 changed files with 133 additions and 91 deletions

View File

@ -22,14 +22,13 @@ Call `editor = layout_machi.editor.create()` to create an editor that can intera
### The layout editing command ### The layout editing command
The editing starts with the open area of the entire workarea, takes commands to split the current area into multiple sub-areas, then recursively edits each of them. The editing starts with the open area of the entire workarea, takes commands to split the current area into multiple sub-areas, then recursively edits each of them.
The editor is keyboard driven, each command is a key with at most 2 digits as parameters (A, B) before the command. The editor is keyboard driven, each command is a key with optional digits (namely `D`) before it as parameter (or multiple parameters depending on the command).
Undefined parameters are (mostly) treated as 1.
1. `Up`/`Down`: restore to the history command sequence 1. `Up`/`Down`: restore to the history command sequence
2. `h`/`v`: split the current region horizontally/vertically into 2 regions. The split will respect the ratio A:B. 2. `h`/`v`: split the current region horizontally/vertically into `#D` regions. The split will respect the ratio of digits in `D`.
3. `w`: Take two parameters (A, B), and split the current region equally into A columns and B rows. If no parameter is defined, behave the same as `Space` without parameters. 3. `w`: Take the last two digits from `D` as `D = ...AB` (1 if `D` is shorter than 2 digits), and split the current region equally into A rows and B columns. If no digits are provided at all, behave the same as `Space`.
4. `s`: shift the current editing region with other open regions. If A is defined, shift for A times. 4. `s`: shift the current editing region with other open regions. If digits are provided, shift for that many times.
5. `Space` or `-`: Without parameters, close the current region and move to the next open region. With parameters, set the maximum depth of splitting (default is 2). 5. `Space` or `-`: Without parameters, close the current region and move to the next open region. With digits, set the maximum depth of splitting (the default depth is 2).
6. `Enter`/`.`: close all open regions. When all regions are closed, press `Enter` will save the layout and exit the editor. 6. `Enter`/`.`: close all open regions. When all regions are closed, press `Enter` will save the layout and exit the editor.
7. `Backspace`: undo the last command. 7. `Backspace`: undo the last command.
8. `Escape`: exit the editor without saving the layout. 8. `Escape`: exit the editor without saving the layout.
@ -58,18 +57,15 @@ For examples:
``` ```
`3-13h2v--2h-12v` `131h2v-12v`
Details: Details:
- `3-`: set the maximum editing depth to 3 - `131h`: horizontally split the initial region (entire desktop) to the ratio of 1:3:1
- `13h`: horizontally split the initial region (entire desktop) to the ratio of 1:3 - For the first `1` part:
- For the left part:
- `2v`: vertically split the region to the ratio of 2:1 - `2v`: vertically split the region to the ratio of 2:1
- `--`: ignore further editing the splitted regions - `-`: skip the editing of the middle `3` part
- For the right part: - For the right `1` part:
- `2h`: horizontally split the region to the ratio of 2:1
- `-`: ignore the left part of the splitted regions
- `12v`: split the right part vertically to the ratio of 1:2 - `12v`: split the right part vertically to the ratio of 1:2
Tada! Tada!

View File

@ -154,8 +154,7 @@ local function create(data)
local closed_areas local closed_areas
local open_areas local open_areas
local history local history
local num_1 local args
local num_2
local max_depth local max_depth
local current_info local current_info
local current_cmd local current_cmd
@ -178,8 +177,7 @@ local function create(data)
} }
} }
history = {} history = {}
num_1 = nil args = ""
num_2 = nil
max_depth = init_max_depth max_depth = init_max_depth
current_info = "" current_info = ""
current_cmd = "" current_cmd = ""
@ -188,7 +186,7 @@ local function create(data)
end end
local function push_history() local function push_history()
history[#history + 1] = {#closed_areas, #open_areas, {}, current_info, current_cmd, max_depth, num_1, num_2} history[#history + 1] = {#closed_areas, #open_areas, {}, current_info, current_cmd, max_depth, args}
end end
local function discard_history() local function discard_history()
@ -212,8 +210,7 @@ local function create(data)
current_info = history[#history][4] current_info = history[#history][4]
current_cmd = history[#history][5] current_cmd = history[#history][5]
max_depth = history[#history][6] max_depth = history[#history][6]
num_1 = history[#history][7] args = history[#history][7]
num_2 = history[#history][8]
table.remove(history, #history) table.remove(history, #history)
end end
@ -234,59 +231,117 @@ local function create(data)
local function handle_split(method, alt) local function handle_split(method, alt)
split_count = split_count + 1 split_count = split_count + 1
if num_1 == nil then num_1 = 1 end
if num_2 == nil then num_2 = 1 end
if alt then
local tmp = num_1
num_1 = num_2
num_2 = tmp
end
local a = pop_open_area() local a = pop_open_area()
local lu, rd
print("split " .. method .. " " .. tostring(alt) .. " " .. _area_tostring(a)) print("split " .. method .. " " .. tostring(alt) .. " " .. args .. " " .. _area_tostring(a))
if method == "h" then if method == "h" then
lu = {
x = a.x, y = a.y, if #args == 0 then
width = a.width / (num_1 + num_2) * num_1, height = a.height, args = "11"
elseif #args == 1 then
args = args .. "1"
end
local total = 0
local offset = {}
for i = 1, #args do
local arg
if not alt then
arg = tonumber(args:sub(i, i))
else
arg = tonumber(args:sub(#args - i + 1, #args - i + 1))
end
if arg < 1 then arg = 1 end
offset[#offset + 1] = total
total = total + arg
end
offset[#offset + 1] = total
local children = {}
for i = 1, #offset - 1 do
local child = {
x = a.x + a.width / total * offset[i],
y = a.y,
width = a.width / total * (offset[i + 1] - offset[i]),
height = a.height,
depth = a.depth + 1, depth = a.depth + 1,
group_id = split_count, group_id = split_count,
bl = a.bl, br = false, bu = a.bu, bd = a.bd, bl = i == 1 and a.bl or false,
br = i == #offset and a.br or false,
bu = a.bu,
bd = a.bd,
} }
rd = { children[#children + 1] = child
x = a.x + lu.width, y = a.y, end
width = a.width - lu.width, height = a.height,
depth = a.depth + 1, for i = #children, 1, -1 do
group_id = split_count, open_areas[#open_areas + 1] = children[i]
bl = false, br = a.br, bu = a.bu, bd = a.bd, end
}
open_areas[#open_areas + 1] = rd
open_areas[#open_areas + 1] = lu
elseif method == "v" then elseif method == "v" then
lu = {
x = a.x, y = a.y, if #args == 0 then
width = a.width, height = a.height / (num_1 + num_2) * num_1, args = "11"
elseif #args == 1 then
args = args .. "1"
end
local total = 0
local offset = {}
for i = 1, #args do
local arg
if not alt then
arg = tonumber(args:sub(i, i))
else
arg = tonumber(args:sub(#args - i + 1, #args - i + 1))
end
if arg < 1 then arg = 1 end
offset[#offset + 1] = total
total = total + arg
end
offset[#offset + 1] = total
local children = {}
for i = 1, #offset - 1 do
local child = {
x = a.x,
y = a.y + a.height / total * offset[i],
width = a.width,
height = a.height / total * (offset[i + 1] - offset[i]),
depth = a.depth + 1, depth = a.depth + 1,
group_id = split_count, group_id = split_count,
bl = a.bl, br = a.br, bu = a.bu, bd = false bl = a.bl,
br = a.br,
bu = i == 1 and a.bu or false,
bd = i == #offset and a.bd or false,
} }
rd = { children[#children + 1] = child
x = a.x, y = a.y + lu.height, end
width = a.width, height = a.height - lu.height,
depth = a.depth + 1, for i = #children, 1, -1 do
group_id = split_count, open_areas[#open_areas + 1] = children[i]
bl = a.bl, br = a.br, bu = false, bd = a.bd, end
}
open_areas[#open_areas + 1] = rd
open_areas[#open_areas + 1] = lu
elseif method == "w" then elseif method == "w" then
local x_interval = a.width / num_1
local y_interval = a.height / num_2 if #args == 0 then
for y = num_2, 1, -1 do args = "11"
for x = num_1, 1, -1 do elseif #args == 1 then
args = "1" .. args
end
if alt then args = string.reverse(args) end
local h_split = tonumber(args:sub(#args - 1, #args - 1))
local v_split = tonumber(args:sub(#args, #args))
if h_split < 1 then h_split = 1 end
if v_split < 1 then v_split = 1 end
local x_interval = a.width / h_split
local y_interval = a.height / v_split
for y = v_split, 1, -1 do
for x = h_split, 1, -1 do
local r = { local r = {
x = a.x + x_interval * (x - 1), x = a.x + x_interval * (x - 1),
y = a.y + y_interval * (y - 1), y = a.y + y_interval * (y - 1),
@ -296,18 +351,17 @@ local function create(data)
group_id = split_count, group_id = split_count,
} }
if x == 1 then r.bl = a.bl else r.bl = false end if x == 1 then r.bl = a.bl else r.bl = false end
if x == num_1 then r.br = a.br else r.br = false end if x == h_split then r.br = a.br else r.br = false end
if y == 1 then r.bu = a.bu else r.bu = false end if y == 1 then r.bu = a.bu else r.bu = false end
if y == num_2 then r.bd = a.bd else r.bd = false end if y == v_split then r.bd = a.bd else r.bd = false end
open_areas[#open_areas + 1] = r open_areas[#open_areas + 1] = r
end end
end end
elseif method == "P" then elseif method == "p" then
-- XXX -- XXX
end end
num_1 = nil args = ""
num_2 = nil
end end
local function push_area() local function push_area()
@ -320,7 +374,7 @@ local function create(data)
elseif key == "v" or key == "V" then elseif key == "v" or key == "V" then
handle_split("v", key == "V") handle_split("v", key == "V")
elseif key == "w" or key == "W" then elseif key == "w" or key == "W" then
if num_1 == nil and num_2 == nil then if args == "" then
push_area() push_area()
else else
handle_split("w", key == "W") handle_split("w", key == "W")
@ -330,7 +384,7 @@ local function create(data)
elseif key == "s" or key == "S" then elseif key == "s" or key == "S" then
if #open_areas > 0 then if #open_areas > 0 then
key = "s" key = "s"
local times = num_1 or 1 local times = args == "" and 1 or tonumber(args)
local t = {} local t = {}
while #open_areas > 0 do while #open_areas > 0 do
t[#t + 1] = pop_open_area() t[#t + 1] = pop_open_area()
@ -338,34 +392,26 @@ local function create(data)
for i = #t, 1, -1 do for i = #t, 1, -1 do
open_areas[#open_areas + 1] = t[(i + times - 1) % #t + 1] open_areas[#open_areas + 1] = t[(i + times - 1) % #t + 1]
end end
num_1 = nil args = ""
num_2 = nil
else else
return nil return nil
end end
elseif key == " " or key == "-" then elseif key == " " or key == "-" then
key = "-" key = "-"
if num_1 ~= nil then if args == "" then
max_depth = num_1
num_1 = nil
num_2 = nil
else
push_area() push_area()
else
max_depth = tonumber(args)
args = ""
end end
elseif key == "Return" or key == "." then elseif key == "Return" or key == "." then
key = "." key = "."
while #open_areas > 0 do while #open_areas > 0 do
push_area() push_area()
end end
args = ""
elseif tonumber(key) ~= nil then elseif tonumber(key) ~= nil then
local v = tonumber(key) args = args .. key
if num_1 == nil then
num_1 = v
elseif num_2 == nil then
num_2 = v
else
return nil
end
else else
return nil return nil
end end