multiple digits
This commit is contained in:
parent
21cad445ae
commit
ad3273f42a
24
README.md
24
README.md
|
@ -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!
|
||||||
|
|
186
editor.lua
186
editor.lua
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue