Added selection type paragraph (#125)

* added selection type paragraph

* include empty line for paragraph delimiter

* Update src/processTargets.ts

Co-authored-by: Pokey Rule <pokey.rule@gmail.com>

* expand the limited range four paragraph

Co-authored-by: Pokey Rule <pokey.rule@gmail.com>
This commit is contained in:
Andreas Arvidsson 2021-07-25 01:15:41 +02:00 committed by GitHub
parent f5775d29c5
commit f102b62785
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 149 additions and 73 deletions

View File

@ -99,7 +99,7 @@ export type SelectionType =
| "character"
| "token"
| "line"
| "block"
| "paragraph"
| "document";
export type Position = "before" | "after" | "contents";
export type InsideOutsideType = "inside" | "outside" | null;

View File

@ -441,7 +441,7 @@ export function inferRangeEndTarget(
function getContentSelectionType(contents: string[]): SelectionType {
if (contents.every((string) => string.endsWith("\n"))) {
if (contents.every((string) => string.startsWith("\n"))) {
return "block";
return "paragraph";
}
return "line";
}

View File

@ -10,23 +10,18 @@ export function performInsideOutsideAdjustment(
selection.insideOutsideType ?? preferredInsideOutsideType;
if (insideOutsideType === "outside") {
const delimiterRange =
selection.selectionContext.trailingDelimiterRange ??
selection.selectionContext.leadingDelimiterRange;
const usedSelection =
selection.selectionContext.outerSelection ??
selection.selection.selection;
if (delimiterRange == null) {
return update(selection, {
selection: {
selection: () => usedSelection,
},
});
}
const delimiterRange =
selection.selectionContext.trailingDelimiterRange ??
selection.selectionContext.leadingDelimiterRange;
const range = usedSelection.union(delimiterRange);
const range =
delimiterRange != null
? usedSelection.union(delimiterRange)
: usedSelection;
return update(selection, {
selection: {

View File

@ -2,7 +2,7 @@ import { concat, range, zip } from "lodash";
import update from "immutability-helper";
import { SyntaxNode } from "web-tree-sitter";
import * as vscode from "vscode";
import { Selection, Range } from "vscode";
import { Selection, Range, Position } from "vscode";
import { nodeMatchers } from "./languages";
import {
Mark,
@ -253,57 +253,47 @@ function createTypedSelection(
selection: SelectionWithEditor,
selectionContext: SelectionContext
): TypedSelection {
const { selectionType, insideOutsideType } = target;
let start: vscode.Position;
let end: vscode.Position;
const { selectionType, insideOutsideType, position } = target;
const { document } = selection.editor;
switch (selectionType) {
case "token":
return {
selection,
selectionType,
position,
insideOutsideType,
selectionContext: getTokenSelectionContext(selection, selectionContext),
insideOutsideType: target.insideOutsideType ?? null,
position: target.position,
};
case "line":
const originalSelectionStart = selection.selection.start;
const originalSelectionEnd = selection.selection.end;
const startLine = selection.editor.document.lineAt(
originalSelectionStart
);
const endLine = selection.editor.document.lineAt(originalSelectionEnd);
start = new vscode.Position(
originalSelectionStart.line,
case "line": {
const startLine = document.lineAt(selection.selection.start);
const endLine = document.lineAt(selection.selection.end);
const start = new Position(
startLine.lineNumber,
startLine.firstNonWhitespaceCharacterIndex
);
end = endLine.range.end;
const end = endLine.range.end;
const isSelectionReversed = selection.selection.isReversed;
const anchor = isSelectionReversed ? start : end;
const active = isSelectionReversed ? end : start;
const newSelection = new Selection(anchor, active);
selection = {
selection: newSelection,
editor: selection.editor,
};
const newSelection = update(selection, {
selection: (s) =>
s.isReversed ? new Selection(end, start) : new Selection(start, end),
});
return {
selection,
selection: newSelection,
selectionType,
selectionContext: getLineSelectionContext(selection, selectionContext),
insideOutsideType: target.insideOutsideType ?? null,
position: target.position,
position,
insideOutsideType,
selectionContext: getLineSelectionContext(newSelection),
};
case "document":
const document = selection.editor.document;
// From https://stackoverflow.com/a/46427868
}
case "document": {
const firstLine = document.lineAt(0);
const lastLine = document.lineAt(document.lineCount - 1);
start = firstLine.range.start;
end = lastLine.range.end;
const start = firstLine.range.start;
const end = lastLine.range.end;
return {
selection: update(selection, {
@ -313,11 +303,51 @@ function createTypedSelection(
: new Selection(start, end),
}),
selectionType,
position,
insideOutsideType,
selectionContext,
insideOutsideType: target.insideOutsideType ?? null,
position: target.position,
};
case "block":
}
case "paragraph": {
let startLine = document.lineAt(selection.selection.start);
while (startLine.lineNumber > 0) {
const line = document.lineAt(startLine.lineNumber - 1);
if (line.isEmptyOrWhitespace) {
break;
}
startLine = line;
}
const lineCount = document.lineCount;
let endLine = document.lineAt(selection.selection.end);
while (endLine.lineNumber + 1 < lineCount) {
const line = document.lineAt(endLine.lineNumber + 1);
if (line.isEmptyOrWhitespace) {
break;
}
endLine = line;
}
const start = new Position(
startLine.lineNumber,
startLine.firstNonWhitespaceCharacterIndex
);
const end = endLine.range.end;
const newSelection = update(selection, {
selection: (s) =>
s.isReversed ? new Selection(end, start) : new Selection(start, end),
});
return {
selection: newSelection,
position,
selectionType,
insideOutsideType,
selectionContext: getParagraphSelectionContext(newSelection),
};
}
case "character":
throw new Error("Not implemented");
}
@ -428,11 +458,11 @@ function isSelectionContextEmpty(selectionContext: SelectionContext) {
}
function getLineSelectionContext(
selection: SelectionWithEditor,
selectionContext: SelectionContext
selection: SelectionWithEditor
): SelectionContext {
const document = selection.editor.document;
const { start, end } = selection.selection;
const { document } = selection.editor;
const start = selection.selection.start;
const end = selection.selection.end;
const leadingDelimiterRange =
start.line > 0
@ -446,14 +476,9 @@ function getLineSelectionContext(
const trailingDelimiterRange =
end.line + 1 < document.lineCount
? new Range(end.line, 0, end.line + 1, 0)
? new Range(end.line, end.character, end.line + 1, 0)
: null;
// Didn't find any delimiters
if (leadingDelimiterRange == null && trailingDelimiterRange == null) {
return selectionContext;
}
// Outer selection contains the entire lines
const outerSelection = new Selection(
start.line,
@ -462,9 +487,65 @@ function getLineSelectionContext(
selection.editor.document.lineAt(end.line).range.end.character
);
const isInDelimitedList =
leadingDelimiterRange != null || trailingDelimiterRange != null;
return {
isInDelimitedList: true,
containingListDelimiter: "\n",
isInDelimitedList,
containingListDelimiter: isInDelimitedList ? "\n" : undefined,
leadingDelimiterRange,
trailingDelimiterRange,
outerSelection,
};
}
function getParagraphSelectionContext(
selection: SelectionWithEditor
): SelectionContext {
const { document } = selection.editor;
const start = selection.selection.start;
const end = selection.selection.end;
let leadingLine = document.lineAt(selection.selection.start);
while (leadingLine.lineNumber > 0) {
leadingLine = document.lineAt(leadingLine.lineNumber - 1);
if (!leadingLine.isEmptyOrWhitespace) {
break;
}
}
const lineCount = document.lineCount;
let trailingLine = document.lineAt(selection.selection.end);
while (trailingLine.lineNumber + 1 < lineCount) {
trailingLine = document.lineAt(trailingLine.lineNumber + 1);
if (!trailingLine.isEmptyOrWhitespace) {
break;
}
}
const leadingDelimiterRange =
leadingLine.lineNumber !== start.line
? new Range(leadingLine.range.end, start)
: null;
const trailingDelimiterRange =
trailingLine.lineNumber !== end.line
? new Range(end, trailingLine.range.start)
: null;
// Outer selection contains the entire lines
const outerSelection = new Selection(
start.line,
0,
end.line,
selection.editor.document.lineAt(end.line).range.end.character
);
const isInDelimitedList =
leadingDelimiterRange != null || trailingDelimiterRange != null;
return {
isInDelimitedList,
containingListDelimiter: isInDelimitedList ? "\n\n" : undefined,
leadingDelimiterRange,
trailingDelimiterRange,
outerSelection,

View File

@ -1,5 +1,5 @@
import { SelectionType } from "./Types";
export function isLineSelectionType(selectionType: SelectionType) {
return selectionType === "line" || selectionType === "block";
return selectionType === "line" || selectionType === "paragraph";
}

View File

@ -330,7 +330,7 @@ const fixture: Fixture[] = [
},
end: {
type: "primitive",
selectionType: "block",
selectionType: "paragraph",
mark: {
type: "decoratedSymbol",
symbolColor: "red",
@ -349,7 +349,7 @@ const fixture: Fixture[] = [
mark: {
type: "cursor",
},
selectionType: "block",
selectionType: "paragraph",
position: "contents",
modifier: {
type: "identity",
@ -362,7 +362,7 @@ const fixture: Fixture[] = [
symbolColor: "red",
character: "h",
},
selectionType: "block",
selectionType: "paragraph",
position: "contents",
modifier: {
type: "identity",
@ -786,7 +786,7 @@ const fixture: Fixture[] = [
symbolColor: "default",
character: "f",
},
selectionType: "block",
selectionType: "paragraph",
position: "after",
modifier: {
type: "identity",
@ -817,7 +817,7 @@ const fixture: Fixture[] = [
mark: {
type: "cursor",
},
selectionType: "block",
selectionType: "paragraph",
position: "after",
modifier: {
type: "identity",
@ -848,7 +848,7 @@ const fixture: Fixture[] = [
mark: {
type: "cursor",
},
selectionType: "block",
selectionType: "paragraph",
position: "contents",
modifier: {
type: "identity",
@ -908,7 +908,7 @@ const fixture: Fixture[] = [
mark: {
type: "cursor",
},
selectionType: "block",
selectionType: "paragraph",
position: "contents",
modifier: {
type: "identity",
@ -1814,7 +1814,7 @@ const fixture: Fixture[] = [
end: {
type: "primitive",
position: "end",
selectionType: "block",
selectionType: "paragraph",
},
},
],
@ -1839,7 +1839,7 @@ const fixture: Fixture[] = [
mark: {
type: "cursor",
},
selectionType: "block",
selectionType: "paragraph",
position: "end",
modifier: {
type: "identity",