[mv3] Add smart spacebar/return auto completion

This commit is contained in:
Raymond Hill 2025-05-31 09:42:53 -04:00
parent e1f2c6f88d
commit 670e8dc367
No known key found for this signature in database
GPG key ID: 25E1490B761470C2

View file

@ -75,9 +75,9 @@ function rangeFromTransaction(transaction) {
}
function addToModifiedRange(transaction) {
const { newDoc } = transaction;
const { from, to } = rangeFromTransaction(transaction);
if ( from === undefined || to === undefined ) { return; }
const { newDoc } = transaction;
const { yamlDocStart, yamlDocEnd } = snapToYamlDocument(newDoc, from, to);
if ( modifiedRange.start === -1 || yamlDocStart < modifiedRange.start ) {
modifiedRange.start = yamlDocStart;
@ -224,6 +224,7 @@ function getAutocompleteCandidates(from) {
],
};
case 'action:responseHeaders:':
case 'action:requestHeaders:':
return {
before: /^ {4}- $/,
candidates: [
@ -231,6 +232,7 @@ function getAutocompleteCandidates(from) {
],
};
case 'action:responseHeaders:header:':
case 'action:requestHeaders:header:':
return {
before: /^ {6}$/,
candidates: [
@ -239,6 +241,7 @@ function getAutocompleteCandidates(from) {
],
};
case 'action:responseHeaders:header:operation:':
case 'action:requestHeaders:header:operation:':
return {
before: /: $/,
candidates: [
@ -587,6 +590,7 @@ function importRulesFromPaste(transaction) {
function smartBackspace(transaction) {
const { from, to } = rangeFromTransaction(transaction);
if ( from === undefined || to === undefined ) { return; }
if ( to !== from ) { return; }
const { newDoc } = transaction;
const line = newDoc.lineAt(from);
if ( /^(?: {2})+-$/.test(line.text) === false ) { return; }
@ -596,6 +600,61 @@ function smartBackspace(transaction) {
/******************************************************************************/
function lineIsArrayItem(doc, lineNo) {
if ( lineNo < 1 || lineNo > doc.lines ) { return false; }
const line = doc.line(lineNo);
return line.text.startsWith(' - ');
}
/******************************************************************************/
function smartArrayItem(doc, from) {
const line = doc.lineAt(from);
if ( lineIsArrayItem(doc, line.number-1) === false ) {
if ( lineIsArrayItem(doc, line.number+1) === false ) { return ''; }
}
const blanks = /^ {2,4}$/.exec(line.text);
if ( blanks === null ) { return ''; }
const count = blanks[0].length;
return `${' '.repeat(4-count)}- `;
}
/******************************************************************************/
function smartReturn(transaction) {
const { from, to } = rangeFromTransaction(transaction);
if ( from === undefined || to === undefined ) { return; }
const { newDoc } = transaction;
const insert = smartArrayItem(newDoc, to);
if ( insert === '' ) { return; }
cmRules.dispatch({
changes: { from: to, insert },
selection: { anchor: to + insert.length },
});
return true;
}
/******************************************************************************/
function smartSpacebar(transaction) {
const { from, to } = rangeFromTransaction(transaction);
if ( from === undefined || to === undefined ) { return; }
if ( (to - from) !== 1 ) { return; }
const { newDoc } = transaction;
const line = newDoc.lineAt(to);
const localTo = to - line.from;
const before = line.text.slice(0, localTo);
if ( /^(?: {1}| {3})$/.test(before) === false ) { return; }
const insert = smartArrayItem(newDoc, to) || ' ';
cmRules.dispatch({
changes: { from: to, insert },
selection: { anchor: to + insert.length },
});
return true;
}
/******************************************************************************/
function cmUpdateListener(info) {
if ( info.docChanged === false ) { return; }
for ( const transaction of info.transactions ) {
@ -605,6 +664,9 @@ function cmUpdateListener(info) {
if ( smartBackspace(transaction) ) { break; }
} else if ( transaction.isUserEvent('input.paste') ) {
if ( importRulesFromPaste(transaction) ) { break; }
} else if ( transaction.isUserEvent('input') ) {
if ( smartReturn(transaction) ) { break; }
if ( smartSpacebar(transaction) ) { break; }
}
}
updateViewAsync();