Yes(, but currently not possible through right-click):
I added a function “magneto copy: the nearest label”, i.e. alt-m to help realize your dream (idea coming from Copy the nearest Format around Cursor).
when creating a Flabel+Backrefs, now could switch from Prompt to Label Picker through Ctrl-Alt-,
when creating a Blabel+Forthref, now every Prompt is replaced by Label Picker by default.
| | , (<) | . (>) |
|---|---|---|
| Ctrl- | [[prompt | (select)C]] copy:L[1] |
[[picker | (select)C]] copy:L |
| Ctrl-Alt- | [[pickerC | (select)]] copy:L(A[2]) |
[[picker | (paste)C]] copy:Nothing |
| Ctrl-Shift- | [[select (or prompt) | C]] copy:L |
[[paste (or picker) | (select)C]] copy:L |
| Alt- | GoTo: Flabel | GoTo: Blabel |
| Alt-M | Cursor: Copy Nearest Label |
function getSelectedText()
local sel = editor.getSelection()
if not sel or sel.from == sel.to then return nil end
local text = editor.getText()
return text:sub(sel.from + 1, sel.to)
end
function setSelectedText(newText)
local sel = editor.getSelection()
if not sel or sel.from == sel.to then return nil end
editor.replaceRange(sel.from, sel.to, newText)
end
function usrPrompt(hinText, iniText)
local iniText = iniText or ""
local input = editor.prompt(hinText, iniText)
if not input then
editor.flashNotification("Cancelled", "warn")
end
return input
end
function pickerBox_labelName(hinText, iniText)
local iniText = iniText or ""
local allLabels = query[[
from index.tag "link"
where toPage and toPage:find(anchorSymbol, 1, true) and alias:find(suffixBlabel, 1, true)
order by _.toPage
]]
local labels = query[[from allLabels select {name = _.toPage:gsub(anchorSymbol, ""), description = _.page .. "@" .. _.pos}]]
local sel = editor.filterBox("🔌 Insert", labels, hinText, iniText)
if sel then return sel.name end
if not sel then
editor.flashNotification("Cancelled", "warn")
end
return nil
end
function pickerBox_FlabelRef(hinText, iniText)
local iniText = iniText or ""
local allFlabels = query[[
from index.tag "link"
where toPage and toPage:find(anchorSymbol, 1, true) and alias:find(suffixBlabel, 1, true)
order by _.toPage
]]
local Flabels = query[[from allFlabels select {name = _.toPage:gsub(anchorSymbol, "") .. suffixBlabel .. _.alias:gsub(suffixBlabel, ""), description = _.page .. "@" .. _.pos, Flabel = _.toPage:gsub(anchorSymbol, "")}]]
local sel = editor.filterBox("🔎 Flabel", Flabels, hinText, iniText)
if sel then return sel.description, sel.Flabel end
if not sel then
editor.flashNotification("Cancelled", "warn")
end
return nil, nil
end
function pickerBox_BlabelRef(hinText, iniText)
local iniText = iniText or ""
local allBlabels = query[[
from index.tag "link"
where toPage and toPage:find(anchorSymbol, 1, true) and alias:find(suffixFlabel, 1, true)
order by _.toPage .. alias
]]
local Blabels = query[[from allBlabels select {name = _.toPage:gsub(anchorSymbol, "") .. siblings .. _.alias, description = _.page .. "@" .. _.pos, Flabel = _.toPage:gsub(anchorSymbol, "")}]]
local sel = editor.filterBox("🔎 Blabel", Blabels, hinText, iniText)
if sel then return sel.description, sel.Flabel end
if not sel then
editor.flashNotification("Cancelled", "warn")
end
return nil, nil
end
command.define {
name = "Go to: Forth Anchor",
key = "Alt-,",
run = function()
local FlabelRef, Flabel = pickerBox_FlabelRef('Select: Flabel (to GOTO)', js.window.navigator.clipboard.readText())
if not FlabelRef then return end
-- editor.flashNotification(FlabelRef)
editor.navigate(FlabelRef)
-- local pos = tonumber(FlabelRef:match("@(.*)$"))
-- if pos then
-- editor.moveCursor(pos, true)
-- end
editor.invokeCommand("Navigate: Center Cursor")
editor.copyToClipboard(Flabel)
end
}
command.define {
name = "Go to: Back Anchor",
key = "Alt-.",
run = function()
local BlabelRef, Flabel = pickerBox_BlabelRef('GOTO: Blabel', js.window.navigator.clipboard.readText())
if not BlabelRef then return end
-- editor.flashNotification(BlabelRef)
editor.navigate(BlabelRef)
-- local pos = tonumber(BlabelRef:match("@(.*)$"))
-- if pos then
-- editor.moveCursor(pos, true)
-- end
editor.invokeCommand("Navigate: Center Cursor")
editor.copyToClipboard(Flabel)
end
}
local anchorSymbol = "⚓"
local suffixFlabel = "🧑🤝🧑"
local suffixBlabel = "🔙"
local siblings = "➡️"
-- =========== Forth Anchor + Back Refs ==================
local function tableBack(Flabel)
local aspiringPage = Flabel .. anchorSymbol
return query[[
from index.tag "link"
where toPage == aspiringPage and alias:find(suffixFlabel, 1, true)
order by _.thBlabel
select {ref=_.ref, thBlabel=_.thBlabel}
]]
end
function backRefs(Flabel)
local str = template.each(tableBack(Flabel), template.new[==[[[${_.ref}|${_.thBlabel}]]]==])
if #str == 0 then return "" end
return str
end
command.define {
name = "Insert: ForthAnchor + BackRefs (sel: alias)",
key = "Ctrl-,",
run = function()
local alias = getSelectedText() or ""
local Flabel = usrPrompt('Enter: label (to be Referred)', '')
if not Flabel then return end
local aspiringPage = Flabel .. anchorSymbol
local forthAnchor = "[[" .. aspiringPage .. "||^|" .. suffixBlabel .. "]]"
local backRefs = '${backRefs("' .. Flabel .. '")}'
local fullText = forthAnchor .. backRefs
if alias and alias ~= "" then setSelectedText("") end
editor.insertAtPos(fullText, editor.getCursor(), true)
editor.copyToClipboard(Flabel)
editor.insertAtCursor(alias, false) -- scrollIntoView?
editor.invokeCommand("Widgets: Refresh All")
end
}
command.define {
name = "Insert: ForthAnchor + BackRefs (pick: label)",
key = "Ctrl-Alt-,",
run = function()
local alias = getSelectedText() or ""
local Flabel = pickerBox_labelName('Enter: label (to be Referred)', js.window.navigator.clipboard.readText())
if not Flabel then return end
Flabel = usrPrompt('Enter: label (to be Referred)', Flabel)
if not Flabel then return end
local forthAnchor = "[[" .. Flabel .. "|^|" .. anchorSymbol .. "|" .. alias .. suffixBlabel .. "]]"
local backRefs = '${backRefs("' .. Flabel .. '")}'
local fullText = forthAnchor .. backRefs
editor.copyToClipboard(Flabel)
if alias and alias ~= "" then
setSelectedText("")
editor.copyToClipboard(alias)
end
editor.insertAtPos(fullText, editor.getCursor(), true)
-- editor.copyToClipboard(Flabel)
-- editor.insertAtCursor(alias, false) -- scrollIntoView?
editor.invokeCommand("Widgets: Refresh All")
end
}
command.define {
name = "Insert: ForthAnchor + BackRefs (sel: label)",
key = "Ctrl-Shift-,",
run = function()
local iniText = getSelectedText() or ""
local Flabel
if iniText and iniText ~= "" then
Flabel = iniText
else
Flabel = usrPrompt('Enter: label (to be Referred)', '')
end
if not Flabel then return end
local aspiringPage = Flabel .. anchorSymbol
local forthAnchor = "[[" .. aspiringPage .. "||^|" .. suffixBlabel .. "]]"
local backRefs = '${backRefs("' .. Flabel .. '")}'
local fullText = forthAnchor .. backRefs
if iniText and iniText ~= "" then setSelectedText("") end
editor.insertAtPos(fullText, editor.getCursor(), true)
editor.copyToClipboard(Flabel)
editor.invokeCommand("Widgets: Refresh All")
end
}
-- =========== Back Anchor + Forth Ref ==================
local function tableBack_noSelf(Flabel, thBlabelNum)
local aspiringPage = Flabel .. anchorSymbol
return query[[
from index.tag "link"
where toPage == aspiringPage and alias:find(suffixFlabel, 1, true) and thBlabelNum ~= _.thBlabel
order by _.thBlabel
select {ref=_.ref, thBlabel=_.thBlabel}
]]
end
function backRefs_noSelf(Flabel, thBlabelNum)
local str = template.each(tableBack_noSelf(Flabel, thBlabelNum), template.new[==[[[${_.ref}|${_.thBlabel}]]]==])
if #str == 0 then return "" end
return str
end
local function tableForth(Flabel)
local aspiringPage = Flabel .. anchorSymbol
return query[[
from index.tag "link"
where toPage == aspiringPage and alias:find(suffixBlabel, 1, true)
select {ref=_.ref}
]]
end
function forthRef(Flabel)
local str = template.each(tableForth(Flabel), template.new("[[${_.ref}|" .. siblings .. "]]"))
if #str == 0 then return "" end
return str
end
command.define {
name = "Insert: BackAnchor + ForthRef (label: pick)",
key = "Ctrl-.",
run = function()
local alias = getSelectedText() or ""
local Flabel = pickerBox_labelName('Pick: label (to Compose)', js.window.navigator.clipboard.readText())
if not Flabel then return end
local thBlabelNum = #tableBack(Flabel) + 1
local aspiringPage = Flabel .. anchorSymbol
local backAnchor = "[[" .. aspiringPage .. "||^|" .. suffixFlabel .. thBlabelNum .. "]]"
local forthRef = '${forthRef("' .. Flabel .. '")}'
local backRefs_noSelf = '${backRefs_noSelf("' .. Flabel .. '",' .. thBlabelNum .. ')}'
local fullText = backAnchor .. forthRef .. backRefs_noSelf
if alias and alias ~= "" then setSelectedText("") end
editor.insertAtPos(fullText, editor.getCursor(), true)
editor.copyToClipboard(Flabel)
editor.insertAtCursor(alias, false) -- scrollIntoView?
editor.invokeCommand("Widgets: Refresh All")
end
}
command.define {
name = "Insert: BackAnchor + ForthRef (alias: paste)",
key = "Ctrl-Alt-.",
run = function()
local iniText = getSelectedText() or ""
local alias = js.window.navigator.clipboard.readText()
local Flabel = pickerBox_labelName('Pick: label (to Compose)', iniText)
if not Flabel then return end
local thBlabelNum = #tableBack(Flabel) + 1
local aspiringPage = Flabel .. anchorSymbol
local backAnchor = "[[" .. aspiringPage .. "||^|" .. suffixFlabel .. thBlabelNum .. "]]"
local forthRef = '${forthRef("' .. Flabel .. '")}'
local backRefs_noSelf = '${backRefs_noSelf("' .. Flabel .. '",' .. thBlabelNum .. ')}'
local fullText = backAnchor .. forthRef .. backRefs_noSelf
if iniText and iniText ~= "" then setSelectedText("") end
editor.insertAtPos(fullText, editor.getCursor(), true)
-- editor.copyToClipboard(Flabel)
editor.insertAtCursor(alias, false) -- scrollIntoView?
editor.invokeCommand("Widgets: Refresh All")
end
}
command.define {
name = "Insert: BackAnchor + ForthRef (label: paste)",
key = "Ctrl-Shift-.",
run = function()
local alias = getSelectedText() or ""
local iniText = js.window.navigator.clipboard.readText()
local Flabel
if iniText and iniText ~= "" then
Flabel = iniText
else
Flabel = pickerBox_labelName('Pick: label (to Build)', '')
end
if not Flabel then return end
local thBlabelNum = #tableBack(Flabel) + 1
local aspiringPage = Flabel .. anchorSymbol
local backAnchor = "[[" .. aspiringPage .. "||^|" .. suffixFlabel .. thBlabelNum .. "]]"
local forthRef = '${forthRef("' .. Flabel .. '")}'
local backRefs_noSelf = '${backRefs_noSelf("' .. Flabel .. '",' .. thBlabelNum .. ')}'
local fullText = backAnchor .. forthRef .. backRefs_noSelf
if alias and alias ~= "" then setSelectedText("") end
editor.insertAtPos(fullText, editor.getCursor(), true)
editor.copyToClipboard(Flabel)
editor.insertAtCursor(alias, false) -- scrollIntoView?
editor.invokeCommand("Widgets: Refresh All")
end
}
index.defineTag {
name = "link",
metatable = {
__index = function(self, attr)
if attr == "thBlabel" then
return tonumber(string.match(self.alias, suffixFlabel .. "([0-9]+)"))
end
end
}
}
-- =========== Magneto Copy: Nearest Label ==================
function SelectiondistanceToCursor(startPos, endPos, cursorPos)
if cursorPos < startPos then return startPos - cursorPos end
if cursorPos > endPos then return cursorPos - endPos end
return 0
end
function getCursorPos()
local cur = editor.getCursor()
local cursor_pos = (type(cur) == "table" and cur.pos) or cur
return cursor_pos
end
function findNearestLabel()
local pageText = editor.getText()
local curPos = getCursorPos()
local pattern = "%[%[[^\n%]]+" .. anchorSymbol .. "|"
local nearest = nil
local init = 1
local ok, err = pcall(function()
while true do
local s, e = pageText:find(pattern, init)
if not s then break end
local dist = SelectiondistanceToCursor(s, e, curPos)
if not nearest or dist < nearest.dist then
nearest = { start = s, stop = e, text = pageText:sub(s, e), dist = dist }
end
init = (e >= init) and (e + 1) or (init + 1)
end
end)
return nearest
end
command.define{
name = "Cursor: Copy Nearest Label",
description = "Copy the raw page name of the nearest Wiki Link",
key = "Alt-m",
run = function()
local match = findNearestLabel()
if not match then
editor.flashNotification("No Label found.")
return
end
local inner = match.text:sub(3, -3)
editor.copyToClipboard(inner)
editor.flashNotification(inner .. anchorSymbol)
end
}
Edit: Alt-m (marker) and Ctrl-Shift-. (quote selection) is system CMDs by default, one needs to update them like https://github.com/ChenZhu-Xie/xczphysics_SilverBullet/blob/main/STYLE/Builtin_Formats.md