src/vs/base/common/history.ts

298 LOC · 284 covered · 14 uncovered · 82 ranges · 49 concepts · 32 introducers · 27 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filesrc/vs/base/common/navigator.ts · 50 LOCcommon/navigator.tshistory.test|title=History Navigator add resets the navigator to last|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator create sets the position after last|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator next on last element returns null and remains on last|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator previous on first element returns null and remains on first|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator previous returns previous element|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.ts ×1 · 1 introduced LOChistory.ts ×1history.test|title=History Navigator next returns object if the current position is not the last one|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator previous returns object if the current position is not the first one|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.ts ×1 · 3 introduced LOChistory.ts ×1history.test|title=History Navigator next returns null if the current position is the last one|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×1 · 2 introduced LOChistory.ts ×1history.test|title=History Navigator add reduces the input to limit|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator first returns first element|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator last returns last element|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator previous returns null if the current position is the first one|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.ts ×4 · 11 introduced LOChistory.ts ×4history.test|title=History Navigator create reduces the input to limit|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator adding an existing item changes the order|occurrence=1, history.test|title=History Navigator adding existing element changes the position|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator next returns next element|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.test|title=History Navigator 2 add - existing value|occurrence=1 · 0 introduced LOChistory.test|title=Histo…history.ts ×1 · 5 introduced LOChistory.ts ×1history.ts ×1 · 4 introduced LOChistory.ts ×1history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×1 · 1 introduced LOChistory.ts ×1history.ts ×1 · 1 introduced LOChistory.ts ×1history.ts ×1 · 5 introduced LOChistory.ts ×1history.ts ×1 · 6 introduced LOChistory.ts ×1history.ts ×2 · 9 introduced LOChistory.ts ×2history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×2 · 23 introduced LOChistory.ts ×2history.ts ×2 · 17 introduced LOChistory.ts ×2history.ts ×2 · 2 introduced LOChistory.ts ×2history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×1 · 6 introduced LOChistory.ts ×1history.ts ×1 · 5 introduced LOChistory.ts ×1history.ts ×1 · 6 introduced LOChistory.ts ×1history.ts ×2 · 3 introduced LOChistory.ts ×2history.ts ×2 · 6 introduced LOChistory.ts ×2history.ts ×6 · 34 introduced LOChistory.ts ×6history.ts ×1 · 2 introduced LOChistory.ts ×1navigator.ts ×1 · 2 introduced LOCnavigator.ts ×1history.ts ×6 · 27 introduced LOChistory.ts ×6history.ts ×1 · 2 introduced LOChistory.ts ×1history.ts ×2 · 2 introduced LOChistory.ts ×2history.ts ×31 · 135 introduced LOChistory.ts ×31history.test|title=History Navigator 2 add - existing value|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 add - existing value|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 add|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 add|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 constructor - capacity limit|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 constructor - capacity limit|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 constructor - duplicate values|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 constructor - duplicate values|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 constructor - initial history is not empty|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 constructor - initial history is not empty|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 constructor|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 constructor|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 navigation|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 navigation|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 prepend|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 prepend|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 replaceLast - existing value|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 replaceLast - existing value|occurrence=1history.test|title=Histo…history.test|title=History Navigator 2 replaceLast|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator 2 replaceLast|occurrence=1history.test|title=Histo…history.test|title=History Navigator add reduces the input to limit|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator add reduces the input to limit|occurrence=1history.test|title=Histo…history.test|title=History Navigator add resets the navigator to last|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator add resets the navigator to last|occurrence=1history.test|title=Histo…history.test|title=History Navigator adding an existing item changes the order|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator adding an existing item changes the order|occurrence=1history.test|title=Histo…history.test|title=History Navigator adding existing element changes the position|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator adding existing element changes the position|occurrence=1history.test|title=Histo…history.test|title=History Navigator clear|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator clear|occurrence=1history.test|title=Histo…history.test|title=History Navigator create reduces the input to limit|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator create reduces the input to limit|occurrence=1history.test|title=Histo…history.test|title=History Navigator create sets the position after last|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator create sets the position after last|occurrence=1history.test|title=Histo…history.test|title=History Navigator first returns first element|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator first returns first element|occurrence=1history.test|title=Histo…history.test|title=History Navigator last returns last element|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator last returns last element|occurrence=1history.test|title=Histo…history.test|title=History Navigator next on last element returns null and remains on last|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator next on last element returns null and remains on last|occurrence=1history.test|title=Histo…history.test|title=History Navigator next returns next element|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator next returns next element|occurrence=1history.test|title=Histo…history.test|title=History Navigator next returns null if the current position is the last one|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator next returns null if the current position is the last one|occurrence=1history.test|title=Histo…history.test|title=History Navigator next returns object if the current position is not the last one|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator next returns object if the current position is not the last one|occurrence=1history.test|title=Histo…history.test|title=History Navigator previous on first element returns null and remains on first|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator previous on first element returns null and remains on first|occurrence=1history.test|title=Histo…history.test|title=History Navigator previous returns null if the current position is the first one|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator previous returns null if the current position is the first one|occurrence=1history.test|title=Histo…history.test|title=History Navigator previous returns object if the current position is not the first one|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator previous returns object if the current position is not the first one|occurrence=1history.test|title=Histo…history.test|title=History Navigator previous returns previous element|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/base/test/common/history.test|title=History Navigator previous returns previous element|occurrence=1history.test|title=Histo…Focused file · src/vs/base/common/history.ts · 298 LOCcommon/history.ts

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- history.ts ×31
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import { SetWithKey } from './collections.js';
7 > import { Event } from './event.js';
8 > import { IDisposable } from './lifecycle.js';
9 > import { ArrayNavigator, INavigator } from './navigator.js';
10 >
11 > export interface IHistory<T> {
12 > delete(t: T): boolean;
13 > add(t: T): this;
14 > has(t: T): boolean;
15 > clear(): void;
16 > forEach(callbackfn: (value: T, value2: T, set: Set<T>) => void, thisArg?: unknown): void;
17 > replace?(t: T[]): void;
18 > readonly onDidChange?: Event<string[]>;
19 > }
20 >
21 > export class HistoryNavigator<T> implements INavigator<T> {
22 > private _limit: number;
23 > private _navigator!: ArrayNavigator<T>;
24 > private _disposable: IDisposable | undefined;
25 >
26 > constructor(
27 > private _history: IHistory<T> = new Set(), history.ts ×6
28 > limit: number = 10,
29 > ) {
30 > this._limit = limit;
31 > this._onChange();
32 > if (this._history.onDidChange) {
33 this._disposable = this._history.onDidChange(() => this._onChange());
34 }
37 > public getHistory(): T[] {
38 return this._elements;
39 }
41 > public add(t: T) {
42 > this._history.delete(t); history.ts ×1
43 > this._history.add(t);
44 > this._onChange();
45 > }
47 > public next(): T | null {
48 > // This will navigate past the end of the last element, and in that case the input should be cleared history.ts ×1
49 > return this._navigator.next();
50 > }
52 > public previous(): T | null {
53 > if (this._currentPosition() !== 0) { history.ts ×2
54 > return this._navigator.previous(); history.ts ×1
55 > }
56 > return null; history.ts ×1
59 > public current(): T | null {
60 > return this._navigator.current(); history.ts ×1
61 > }
63 > public first(): T | null {
64 > return this._navigator.first(); history.ts ×1
65 > }
67 > public last(): T | null {
68 > return this._navigator.last(); history.ts ×1
69 > }
71 > public isFirst(): boolean {
72 > return this._currentPosition() === 0; history.ts ×1
73 > }
75 > public isLast(): boolean {
76 > return this._currentPosition() >= this._elements.length - 1; history.ts ×1
77 > }
79 > public isNowhere(): boolean {
80 > return this._navigator.current() === null; history.ts ×1
81 > }
83 > public has(t: T): boolean {
84 return this._history.has(t);
85 }
87 > public clear(): void {
88 > this._history.clear(); history.ts ×1
89 > this._onChange();
90 > }
92 > private _onChange() {
93 > this._reduceToLimit(); history.ts ×6
94 > const elements = this._elements;
95 > this._navigator = new ArrayNavigator(elements, 0, elements.length, elements.length);
96 > }
98 > private _reduceToLimit() {
99 > const data = this._elements; history.ts ×6
100 > if (data.length > this._limit) {
101 > const replaceValue = data.slice(data.length - this._limit); history.ts ×2
102 > if (this._history.replace) {
103 this._history.replace(replaceValue);
104 > } else { history.ts ×2
105 > this._history = new Set(replaceValue);
106 > }
107 > }
108 > } history.ts ×6
110 > private _currentPosition(): number {
111 > const currentElement = this._navigator.current(); history.ts ×2
112 > if (!currentElement) {
113 > return -1; history.ts ×1
114 > }
116 > return this._elements.indexOf(currentElement);
117 > } history.ts ×2
119 > private get _elements(): T[] {
120 > const elements: T[] = []; history.ts ×6
121 > this._history.forEach(e => elements.push(e));
122 > return elements;
123 > }
125 > public dispose(): void {
126 if (this._disposable) {
127 this._disposable.dispose();
128 this._disposable = undefined;
129 }
130 }
131 > } history.ts ×31
132 >
133 > interface HistoryNode<T> {
134 > value: T;
135 > previous: HistoryNode<T> | undefined;
136 > next: HistoryNode<T> | undefined;
137 > }
138 >
139 > /**
140 > * The right way to use HistoryNavigator2 is for the last item in the list to be the user's uncommitted current text. eg empty string, or whatever has been typed. Then
141 > * the user can navigate away from the last item through the list, and back to it. When updating the last item, call replaceLast.
142 > */
143 > export class HistoryNavigator2<T> {
144 >
145 > private valueSet: Set<T>;
146 > private head: HistoryNode<T>;
147 > private tail: HistoryNode<T>;
148 > private cursor: HistoryNode<T>;
149 > private _size: number;
150 > get size(): number { return this._size; }
151 >
152 > constructor(history: readonly T[], private capacity: number = 10, private identityFn: (t: T) => unknown = t => t) {
153 > if (history.length < 1) { history.ts ×2
154 > throw new Error('not supported'); history.ts ×1
155 > }
157 > this._size = 1;
158 > this.head = this.tail = this.cursor = {
159 > value: history[0],
160 > previous: undefined,
161 > next: undefined
162 > };
163 >
164 > this.valueSet = new SetWithKey<T>([history[0]], identityFn);
165 > for (let i = 1; i < history.length; i++) {
166 > this.add(history[i]);
167 > }
168 > } history.ts ×2
170 > add(value: T): void {
171 > const node: HistoryNode<T> = { history.ts ×6
172 > value,
173 > previous: this.tail,
174 > next: undefined
175 > };
176 >
177 > this.tail.next = node;
178 > this.tail = node;
179 > this.cursor = this.tail;
180 > this._size++;
181 >
182 > if (this.valueSet.has(value)) {
183 > this._deleteFromList(value); history.ts ×1
184 > } else { history.ts ×6
185 > this.valueSet.add(value);
186 > }
187 >
188 > while (this._size > this.capacity) {
189 > this.valueSet.delete(this.head.value); history.ts ×1
190 >
191 > this.head = this.head.next!;
192 > this.head.previous = undefined;
193 > this._size--;
194 > }
195 > } history.ts ×6
197 > /**
198 > * @returns old last value
199 > */
200 > replaceLast(value: T): T {
201 > if (this.identityFn(this.tail.value) === this.identityFn(value)) { history.ts ×4
202 return value;
203 }
205 > const oldValue = this.tail.value;
206 > this.valueSet.delete(oldValue);
207 > this.tail.value = value;
208 >
209 > if (this.valueSet.has(value)) {
210 > this._deleteFromList(value); history.ts ×1
211 > } else { history.ts ×4
212 > this.valueSet.add(value); history.ts ×1
213 > }
215 > return oldValue;
216 > }
218 > prepend(value: T): void {
219 > if (this._size === this.capacity || this.valueSet.has(value)) { history.ts ×2
220 > return;
221 > }
222 >
223 > const node: HistoryNode<T> = {
224 > value,
225 > previous: undefined,
226 > next: this.head
227 > };
228 >
229 > this.head.previous = node;
230 > this.head = node;
231 > this._size++;
232 >
233 > this.valueSet.add(value);
234 > }
236 > isAtEnd(): boolean {
237 > return this.cursor === this.tail; history.ts ×6
238 > }
240 > current(): T {
241 > return this.cursor.value; history.ts ×6
242 > }
244 > previous(): T {
245 > if (this.cursor.previous) { history.ts ×1
246 > this.cursor = this.cursor.previous;
247 > }
248 >
249 > return this.cursor.value;
250 > }
252 > next(): T {
253 > if (this.cursor.next) { history.ts ×2
254 > this.cursor = this.cursor.next;
255 > }
256 >
257 > return this.cursor.value;
258 > }
260 > has(t: T): boolean {
261 > return this.valueSet.has(t); history.ts ×1
262 > }
264 > resetCursor(): T {
265 > this.cursor = this.tail; history.ts ×2
266 > return this.cursor.value;
267 > }
269 > *[Symbol.iterator](): Iterator<T> {
270 > let node: HistoryNode<T> | undefined = this.head; history.ts ×2
271 >
272 > while (node) {
273 > yield node.value;
274 > node = node.next;
275 > }
276 > }
278 > private _deleteFromList(value: T): void {
279 > let temp = this.head; history.ts ×2
280 >
281 > const valueKey = this.identityFn(value);
282 > while (temp !== this.tail) {
283 > if (this.identityFn(temp.value) === valueKey) {
284 > if (temp === this.head) {
285 > this.head = this.head.next!; history.ts ×1
286 > this.head.previous = undefined;
287 > } else { history.ts ×2
288 > temp.previous!.next = temp.next;
289 > temp.next!.previous = temp.previous;
290 > }
291 >
292 > this._size--;
293 > }
294 >
295 > temp = temp.next!;
296 > }
297 > }
298 > } history.ts ×31