Skip to content

Commit 0d78b55

Browse files
committed
slurp and barf
SQUASHED: AUTO-COMMIT-src-components-widgets-ast-capabilities.js,AUTO-COMMIT-src-components-widgets-lively-code-mirror.js,
1 parent 83b14c9 commit 0d78b55

File tree

2 files changed

+112
-4
lines changed

2 files changed

+112
-4
lines changed

src/components/widgets/ast-capabilities.js

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,9 @@ export default class ASTCapabilities {
431431
var d = dmp.diff_main(oldText, newText);
432432
// d.inspect()
433433
var index = 0;
434-
let firstChangeStep = true
434+
let firstChangeStep = true;
435435
// prune diffs
436-
const onlySpaces = str => str.trim().length === 0
436+
const onlySpaces = str => str.trim().length === 0;
437437
// d = d.filter(([changeType, text]) => changeType === 0 || !onlySpaces(text));
438438
// d.inspect()
439439
for (let [changeType, text] of d) {
@@ -459,6 +459,105 @@ export default class ASTCapabilities {
459459
return index;
460460
}
461461

462+
/*MD ## Slurping and Barfing MD*/
463+
slurpOrBarf({ slurp = false, barf = false, forward }) {
464+
const cm = this.codeProvider.codeMirror;
465+
var getScrollInfo = () => {
466+
return cm.getScrollInfo();
467+
};
468+
469+
var setScrollInfo = scrollInfo => {
470+
cm.scrollIntoView({
471+
left: scrollInfo.left,
472+
top: scrollInfo.top,
473+
right: scrollInfo.left + scrollInfo.width,
474+
bottom: scrollInfo.top + scrollInfo.height
475+
});
476+
};
477+
478+
const scrollInfo = getScrollInfo();
479+
const selections = cm.listSelections();
480+
481+
const res = this.sourceCode.transformAsAST(({ types: t }) => ({
482+
visitor: {
483+
Program: programPath => {
484+
let path = this.getInnermostPathContainingSelection(programPath, range(selections.first));
485+
let innerBlock = path.find(p => {
486+
487+
if (!p.isBlock()) {
488+
return false;
489+
}
490+
if (barf && p.get('body').length === 0) {
491+
// nothing to barf
492+
return false;
493+
}
494+
return true;
495+
});
496+
497+
if (!innerBlock) {
498+
if (barf) {
499+
lively.warn('nothing to barf');
500+
} else {
501+
lively.warn('no innerBlock found');
502+
}
503+
return;
504+
}
505+
506+
let outerStatement = innerBlock.find(p => {
507+
if (!(p.parentPath && p.parentPath.isBlock())) {
508+
return false;
509+
}
510+
if (slurp) {
511+
if (forward && !p.getNextSibling().node) {
512+
return false;
513+
}
514+
if (!forward && !p.getPrevSibling().node) {
515+
return false;
516+
}
517+
}
518+
return true;
519+
});
520+
521+
if (slurp) {
522+
if (forward) {
523+
const pathToSlurp = outerStatement.getNextSibling();
524+
innerBlock.pushContainer('body', pathToSlurp.node);
525+
pathToSlurp.remove();
526+
} else {
527+
const pathToSlurp = outerStatement.getPrevSibling();
528+
innerBlock.unshiftContainer('body', pathToSlurp.node);
529+
pathToSlurp.remove();
530+
}
531+
}
532+
if (barf) {
533+
if (forward) {
534+
const pathToBarf = innerBlock.get('body').last;
535+
outerStatement.insertAfter(pathToBarf.node);
536+
pathToBarf.remove();
537+
} else {
538+
const pathToBarf = innerBlock.get('body').first;
539+
outerStatement.insertBefore(pathToBarf.node);
540+
pathToBarf.remove();
541+
}
542+
}
543+
}
544+
}
545+
}));
546+
547+
this.sourceCode = res.code;
548+
549+
cm.setSelections(selections);
550+
setScrollInfo(scrollInfo);
551+
}
552+
553+
slurp(forward) {
554+
this.slurpOrBarf({ slurp: true, forward });
555+
}
556+
557+
barf(forward) {
558+
this.slurpOrBarf({ barf: true, forward });
559+
}
560+
462561
/*MD ## Navigation MD*/
463562
/**
464563
* Get the root path
@@ -1731,7 +1830,7 @@ export default class ASTCapabilities {
17311830
let exitedEarly = false;
17321831

17331832
const pathLocationsToSelect = [];
1734-
debugger
1833+
debugger;
17351834
let transformed = this.sourceCode.transformAsAST(({ types: t, template }) => ({
17361835
visitor: {
17371836
Program: programPath => {

src/components/widgets/lively-code-mirror.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,16 @@ export default class LivelyCodeMirror extends HTMLElement {
340340

341341
this.extraKeys = Object.assign(defaultASTHandlers, {
342342

343-
// #KeyboardShortcut Alt-X shortcut for experomental features
343+
// #KeyboardShortcut Alt-9 slurp backward
344+
"Alt-9": cm => this.astCapabilities(cm).then(ac => ac.slurp(false)),
345+
// #KeyboardShortcut Alt-0 slurp forward
346+
"Alt-0": cm => this.astCapabilities(cm).then(ac => ac.slurp(true)),
347+
// #KeyboardShortcut Alt-[ barf backward
348+
"Alt-[": cm => this.astCapabilities(cm).then(ac => ac.barf(false)),
349+
// #KeyboardShortcut Alt-] barf forward
350+
"Alt-]": cm => this.astCapabilities(cm).then(ac => ac.barf(true)),
351+
352+
// #KeyboardShortcut Alt-X shortcut for experimental features
344353
"Alt-X": cm => this.astCapabilities(cm).then(ac => ac.braveNewWorld()),
345354
// #KeyboardShortcut Alt-B Alt-N wrap selection in lively notify
346355
"Alt-B Alt-N": cm => this.astCapabilities(cm).then(ac => ac.livelyNotify()),

0 commit comments

Comments
 (0)