If I understand correctly you want a o write a command which cycles the line between item/task/heading?
If that’s so, you just need to separate the current line from its prefix and change the prefix. I’ve done something similar a while ago to cycle through the heading levels # → ## → ### …etc
command.define {
name = "Line: Toggle paragraph / list / task",
key = "Ctrl-Alt-Tab",
run = function()
local line = editor.getCurrentLine()
if not line or not line.textWithCursor then return end
local s = line.textWithCursor
-- task → paragraph
if s:match("^%s*%- %[[ xX]%] ") then
s = s:gsub("^%s*%- %[[ xX]%] ", "", 1)
-- list → task
elseif s:match("^%s*%- ") then
s = s:gsub("^%s*%- ", "- [ ] ", 1)
-- paragraph → list
elseif s:match("%S") then
s = "- " .. s
else
return
end
editor.replaceRange(line.from, line.to, s, true)
end
}
I think the issue with “Ctrl-Enter” is that is already assigned by the system to: “Navigate: To This Page” and depending on the priority your script is running before the system commands. So your shortcut definition might be overwritten by the core command.
You can try two things, change your script’s priority so it’s executed after the core functions. Or change the shortcut key for the “Navigate: To This Page” command.
I definitely wouldn’t use JS for this. Space-lua would always be my first choice. I use JS only where I need some DOM manipulation where lua can’t keep up.
This works:
-- first we disable the Shortcut of the system command which already has the Keys assigned
command.update {
name = "Navigate: To This Page",
key = "",
mac = ""
}
-- and then define a command with the new shortcut keys
command.define {
name = "Line: Toggle paragraph / list / task",
key = "Ctrl-Enter",
mac = "Cmd-Enter",
run = function()
-- ... your code here ...
end
}
For anyone who’s following along, two small tweaks to @Mr.Red 's solution to better fit my own use case:
Preserved space at the beginning so it works for indents
For my use case, I removed it from cycling through a paragraph. It now toggles between task and list, but if it was a paragraph, then does a one time conversion to list (YMMV)
-- first we disable the Shortcut of the system command which already has the Keys assigned
command.update {
name = "Navigate: To This Page",
key = "",
mac = ""
}
-- and then define a command with the new shortcut keys
command.define {
name = "Line: Toggle paragraph / list / task",
key = "Ctrl-Enter",
run = function()
local line = editor.getCurrentLine()
if not line or not line.textWithCursor then return end
local s = line.textWithCursor
-- task → list
if s:match("^(%s*)%- %[[ xX]%] ") then
s = s:gsub("^(%s*)%- %[[ xX]%] ", "%1- ", 1)
-- list → task
elseif s:match("^(%s*)%- ") then
s = s:gsub("^(%s*)%- ", "%1- [ ] ", 1)
-- paragraph → list (one-time)
elseif s:match("%S") then
s = "- " .. s
-- empty / whitespace-only line
else
return
end
editor.replaceRange(line.from, line.to, s, true)
end
}