mirror of
https://github.com/naturalcrit/homebrewery.git
synced 2026-09-28 02:22:57 +00:00
make makelink use proper shortcut and work for multiple lines
This commit is contained in:
@@ -182,72 +182,60 @@ const removeSpace = (view)=>forEachSelection(view, (state, range)=>{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const makeLink = (view)=>{
|
const makeLink = (view)=>forEachSelection(view, (state, range)=>{
|
||||||
const ranges = view.state.selection.ranges;
|
const { from, to } = range;
|
||||||
|
const selected = state.doc.sliceString(from, to).trim();
|
||||||
|
|
||||||
// Multiple selections: pair them as alt text + URL
|
// If the selection is already a Markdown link, unwrap it
|
||||||
if(ranges.length > 1) {
|
const existingLink = /^\[(.*)\]\((.*)\)$/.exec(selected);
|
||||||
const changes = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < ranges.length - 1; i += 2) {
|
if(existingLink) {
|
||||||
const alt = view.state.doc.sliceString(
|
const [, text, url] = existingLink;
|
||||||
ranges[i].from,
|
const insert = `${text} ${url}`;
|
||||||
ranges[i].to
|
|
||||||
).trim();
|
|
||||||
|
|
||||||
const url = view.state.doc.sliceString(
|
return {
|
||||||
ranges[i + 1].from,
|
changes : {
|
||||||
ranges[i + 1].to
|
from,
|
||||||
).trim();
|
to,
|
||||||
|
insert,
|
||||||
changes.push({
|
},
|
||||||
from : ranges[i].from,
|
range : EditorSelection.range(
|
||||||
to : ranges[i + 1].to,
|
from,
|
||||||
insert : `[${alt}](${url})`
|
from + insert.length
|
||||||
});
|
),
|
||||||
}
|
};
|
||||||
|
|
||||||
view.dispatch({ changes });
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single selection: existing behavior
|
// If the selection is a URL, use its domain as the link text.
|
||||||
const { from, to } = view.state.selection.main;
|
const isUrl =
|
||||||
const selected = view.state.doc.sliceString(from, to).trim();
|
|
||||||
|
|
||||||
const isLink = /^\[(.*)\]\((.*)\)$/.exec(selected);
|
|
||||||
|
|
||||||
let text;
|
|
||||||
|
|
||||||
if(isLink) {
|
|
||||||
text = `${isLink[1]} ${isLink[2]}`;
|
|
||||||
} else {
|
|
||||||
const isUrl =
|
|
||||||
/^(https?:\/\/|www\.)\S+$/i.test(selected) ||
|
/^(https?:\/\/|www\.)\S+$/i.test(selected) ||
|
||||||
/^[a-z0-9-]+(\.[a-z0-9-]+)+([/?#]\S*)?$/i.test(selected);
|
/^[a-z0-9-]+(\.[a-z0-9-]+)+([/?#]\S*)?$/i.test(selected);
|
||||||
|
|
||||||
if(isUrl) {
|
if(isUrl) {
|
||||||
const url = selected;
|
const domain = selected
|
||||||
const domain = url
|
|
||||||
.replace(/^https?:\/\//i, '')
|
.replace(/^https?:\/\//i, '')
|
||||||
.replace(/^www\./i, '')
|
.replace(/^www\./i, '')
|
||||||
.split(/[/?#]/)[0];
|
.split(/[/?#]/)[0];
|
||||||
|
|
||||||
const name = domain.split('.')[0];
|
const name = domain.split('.')[0];
|
||||||
|
|
||||||
text = `[${name}](${url})`;
|
const insert = `[${name}](${selected})`;
|
||||||
} else {
|
|
||||||
text = `[${selected || 'alt text'}](url)`;
|
return {
|
||||||
}
|
changes : { from, to, insert },
|
||||||
|
range : EditorSelection.range(from, from + insert.length),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
view.dispatch({
|
// If the selection is just text, use it as alt text and set url as placeholder
|
||||||
changes : { from, to, insert: text }
|
const insert = `[${selected || 'alt text'}](url)`;
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
changes : { from, to, insert },
|
||||||
|
range : EditorSelection.range(from, from + insert.length),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const makeList = (prefix)=>(view)=>forEachSelection(view, (state, selectionRange)=>{
|
const makeList = (prefix)=>(view)=>forEachSelection(view, (state, selectionRange)=>{
|
||||||
const { from, to } = selectionRange;
|
const { from, to } = selectionRange;
|
||||||
@@ -265,12 +253,10 @@ const makeList = (prefix)=>(view)=>forEachSelection(view, (state, selectionRange
|
|||||||
selectedLines.push(state.doc.line(lineNumber));
|
selectedLines.push(state.doc.line(lineNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
const allLinesHavePrefix = selectedLines.every((line)=>line.text.startsWith(prefix)
|
const allLinesHavePrefix = selectedLines.every((line)=>line.text.startsWith(prefix));
|
||||||
);
|
|
||||||
|
|
||||||
const changes = selectedLines.map((line)=>{
|
const changes = selectedLines.map((line)=>{
|
||||||
const shouldRemovePrefix =
|
const shouldRemovePrefix = allLinesHavePrefix && line.text.startsWith(prefix);
|
||||||
allLinesHavePrefix && line.text.startsWith(prefix);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
from : line.from,
|
from : line.from,
|
||||||
@@ -349,7 +335,7 @@ export const markdownKeymap = Prec.highest(keymap.of([
|
|||||||
{ key: 'Mod-m', run: wrapSelection('{{', '}}') },
|
{ key: 'Mod-m', run: wrapSelection('{{', '}}') },
|
||||||
{ key: 'Shift-Mod-m', run: wrapSelection('{{\n', '\n}}') },
|
{ key: 'Shift-Mod-m', run: wrapSelection('{{\n', '\n}}') },
|
||||||
{ key: 'Mod-/', run: wrapSelection('<!-- ', ' -->') },
|
{ key: 'Mod-/', run: wrapSelection('<!-- ', ' -->') },
|
||||||
{ key: 'Mod-k', run: makeLink },
|
{ key: 'Mod-Shift-k', run: makeLink },
|
||||||
{ key: 'Mod-Shift-u', run: makeList('- ') },
|
{ key: 'Mod-Shift-u', run: makeList('- ') },
|
||||||
{ key: 'Mod-Shift-o', run: makeList('1. ') },
|
{ key: 'Mod-Shift-o', run: makeList('1. ') },
|
||||||
{ key: 'Shift-Mod-1', run: makeHeader(1) },
|
{ key: 'Shift-Mod-1', run: makeHeader(1) },
|
||||||
|
|||||||
Reference in New Issue
Block a user