@tooee/search 0.1.22 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/search-hook.d.ts +13 -1
- package/dist/search-hook.d.ts.map +1 -1
- package/dist/search-hook.js +30 -7
- package/dist/search-hook.js.map +1 -1
- package/package.json +7 -7
- package/src/search-hook.ts +51 -6
package/dist/search-hook.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
export interface UseSearchOptions {
|
|
2
2
|
match: (query: string) => number[];
|
|
3
3
|
onJump: (index: number) => void;
|
|
4
|
+
/**
|
|
5
|
+
* Register the search commands (default true). `false` leaves the state
|
|
6
|
+
* inert: no `/`, `n`, `shift+n` or cancel command exists.
|
|
7
|
+
*/
|
|
8
|
+
enabled?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Values the searched content is derived from. Matches are memoized on the
|
|
11
|
+
* query, so a committed query goes stale when the content changes underneath
|
|
12
|
+
* it (streaming or reloaded documents). List the content here to re-match.
|
|
13
|
+
* The array length must be stable across renders.
|
|
14
|
+
*/
|
|
15
|
+
deps?: readonly unknown[];
|
|
4
16
|
}
|
|
5
17
|
export interface SearchState {
|
|
6
18
|
searchQuery: string;
|
|
@@ -10,5 +22,5 @@ export interface SearchState {
|
|
|
10
22
|
currentMatchIndex: number;
|
|
11
23
|
submitSearch: () => void;
|
|
12
24
|
}
|
|
13
|
-
export declare function useSearch({ match, onJump }: UseSearchOptions): SearchState;
|
|
25
|
+
export declare function useSearch({ match, onJump, enabled, deps, }: UseSearchOptions): SearchState;
|
|
14
26
|
//# sourceMappingURL=search-hook.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-hook.d.ts","sourceRoot":"","sources":["../src/search-hook.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;IAClC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"search-hook.d.ts","sourceRoot":"","sources":["../src/search-hook.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;IAClC,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,OAAO,CAAA;IACrB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,IAAI,CAAA;CACzB;AAkBD,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,MAAM,EACN,OAAc,EACd,IAAiB,GAClB,EAAE,gBAAgB,GAAG,WAAW,CA6IhC"}
|
package/dist/search-hook.js
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useRef, useState } from "react";
|
|
2
2
|
import { useCommand, useMode, useSetMode } from "@tooee/commands";
|
|
3
3
|
const EMPTY = [];
|
|
4
|
+
const EMPTY_DEPS = [];
|
|
5
|
+
function sameDeps(left, right) {
|
|
6
|
+
if (left.length !== right.length)
|
|
7
|
+
return false;
|
|
8
|
+
return left.every((value, index) => Object.is(value, right[index]));
|
|
9
|
+
}
|
|
4
10
|
const CURSOR_MODES = ["cursor"];
|
|
5
11
|
const ALL_MODES = ["cursor", "select", "insert"];
|
|
6
|
-
export function useSearch({ match, onJump }) {
|
|
12
|
+
export function useSearch({ match, onJump, enabled = true, deps = EMPTY_DEPS, }) {
|
|
7
13
|
const mode = useMode();
|
|
8
14
|
const setMode = useSetMode();
|
|
9
15
|
const [searchQuery, setSearchQuery] = useState("");
|
|
@@ -16,11 +22,24 @@ export function useSearch({ match, onJump }) {
|
|
|
16
22
|
const onJumpRef = useRef(onJump);
|
|
17
23
|
onJumpRef.current = onJump;
|
|
18
24
|
const activeQuery = searchActive ? searchQuery : committedQuery;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
// Memoized on the query *and* the searched content: a committed query must
|
|
26
|
+
// re-match when rows arrive or change. `deps` is caller-sized, so this is a
|
|
27
|
+
// hand-rolled cache rather than a useMemo dependency array.
|
|
28
|
+
const cacheRef = useRef(null);
|
|
29
|
+
let matchingLines;
|
|
30
|
+
if (!activeQuery) {
|
|
31
|
+
matchingLines = EMPTY;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
const cache = cacheRef.current;
|
|
35
|
+
if (cache && cache.query === activeQuery && sameDeps(cache.deps, deps)) {
|
|
36
|
+
matchingLines = cache.matches;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
matchingLines = matchRef.current(activeQuery);
|
|
40
|
+
cacheRef.current = { query: activeQuery, deps: [...deps], matches: matchingLines };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
24
43
|
const matchingLinesRef = useRef(matchingLines);
|
|
25
44
|
matchingLinesRef.current = matchingLines;
|
|
26
45
|
// Imperatively set search query, reset match index, and jump to first match.
|
|
@@ -37,6 +56,7 @@ export function useSearch({ match, onJump }) {
|
|
|
37
56
|
title: "Search",
|
|
38
57
|
hotkey: "/",
|
|
39
58
|
modes: CURSOR_MODES,
|
|
59
|
+
enabled,
|
|
40
60
|
handler: () => {
|
|
41
61
|
preSearchModeRef.current = mode;
|
|
42
62
|
setSearchActive(true);
|
|
@@ -49,6 +69,7 @@ export function useSearch({ match, onJump }) {
|
|
|
49
69
|
title: "Next match",
|
|
50
70
|
hotkey: "n",
|
|
51
71
|
modes: CURSOR_MODES,
|
|
72
|
+
enabled,
|
|
52
73
|
when: () => !searchActive,
|
|
53
74
|
handler: () => {
|
|
54
75
|
const matches = matchingLinesRef.current;
|
|
@@ -69,6 +90,7 @@ export function useSearch({ match, onJump }) {
|
|
|
69
90
|
title: "Previous match",
|
|
70
91
|
hotkey: "shift+n",
|
|
71
92
|
modes: CURSOR_MODES,
|
|
93
|
+
enabled,
|
|
72
94
|
when: () => !searchActive,
|
|
73
95
|
handler: () => {
|
|
74
96
|
const matches = matchingLinesRef.current;
|
|
@@ -89,6 +111,7 @@ export function useSearch({ match, onJump }) {
|
|
|
89
111
|
title: "Cancel search",
|
|
90
112
|
hotkey: "escape",
|
|
91
113
|
modes: ALL_MODES,
|
|
114
|
+
enabled,
|
|
92
115
|
when: () => searchActive,
|
|
93
116
|
handler: () => {
|
|
94
117
|
setSearchActive(false);
|
package/dist/search-hook.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-hook.js","sourceRoot":"","sources":["../src/search-hook.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"search-hook.js","sourceRoot":"","sources":["../src/search-hook.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tooee/search",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Search hook, utilities, and SearchBar component for Tooee",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -35,19 +35,19 @@
|
|
|
35
35
|
"typecheck": "tsc --noEmit"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@tooee/commands": "0.
|
|
39
|
-
"@tooee/themes": "0.
|
|
38
|
+
"@tooee/commands": "0.2.0",
|
|
39
|
+
"@tooee/themes": "0.2.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@opentui/core": "^0.
|
|
43
|
-
"@opentui/react": "^0.
|
|
42
|
+
"@opentui/core": "^0.4.3",
|
|
43
|
+
"@opentui/react": "^0.4.3",
|
|
44
44
|
"@types/bun": "^1.3.10",
|
|
45
45
|
"@types/react": "^19.2.14",
|
|
46
46
|
"typescript": "^5.9.3"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
|
-
"@opentui/core": "^0.
|
|
50
|
-
"@opentui/react": "^0.
|
|
49
|
+
"@opentui/core": "^0.4.3",
|
|
50
|
+
"@opentui/react": "^0.4.3",
|
|
51
51
|
"react": "^18.0.0 || ^19.0.0"
|
|
52
52
|
}
|
|
53
53
|
}
|
package/src/search-hook.ts
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
import { useCallback,
|
|
1
|
+
import { useCallback, useRef, useState } from "react"
|
|
2
2
|
import { useCommand, useMode, useSetMode, type Mode } from "@tooee/commands"
|
|
3
3
|
|
|
4
4
|
export interface UseSearchOptions {
|
|
5
5
|
match: (query: string) => number[]
|
|
6
6
|
onJump: (index: number) => void
|
|
7
|
+
/**
|
|
8
|
+
* Register the search commands (default true). `false` leaves the state
|
|
9
|
+
* inert: no `/`, `n`, `shift+n` or cancel command exists.
|
|
10
|
+
*/
|
|
11
|
+
enabled?: boolean
|
|
12
|
+
/**
|
|
13
|
+
* Values the searched content is derived from. Matches are memoized on the
|
|
14
|
+
* query, so a committed query goes stale when the content changes underneath
|
|
15
|
+
* it (streaming or reloaded documents). List the content here to re-match.
|
|
16
|
+
* The array length must be stable across renders.
|
|
17
|
+
*/
|
|
18
|
+
deps?: readonly unknown[]
|
|
7
19
|
}
|
|
8
20
|
|
|
9
21
|
export interface SearchState {
|
|
@@ -16,10 +28,27 @@ export interface SearchState {
|
|
|
16
28
|
}
|
|
17
29
|
|
|
18
30
|
const EMPTY: number[] = []
|
|
31
|
+
const EMPTY_DEPS: readonly unknown[] = []
|
|
32
|
+
|
|
33
|
+
interface MatchCache {
|
|
34
|
+
query: string
|
|
35
|
+
deps: readonly unknown[]
|
|
36
|
+
matches: number[]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function sameDeps(left: readonly unknown[], right: readonly unknown[]): boolean {
|
|
40
|
+
if (left.length !== right.length) return false
|
|
41
|
+
return left.every((value, index) => Object.is(value, right[index]))
|
|
42
|
+
}
|
|
19
43
|
const CURSOR_MODES: Mode[] = ["cursor"]
|
|
20
44
|
const ALL_MODES: Mode[] = ["cursor", "select", "insert"]
|
|
21
45
|
|
|
22
|
-
export function useSearch({
|
|
46
|
+
export function useSearch({
|
|
47
|
+
match,
|
|
48
|
+
onJump,
|
|
49
|
+
enabled = true,
|
|
50
|
+
deps = EMPTY_DEPS,
|
|
51
|
+
}: UseSearchOptions): SearchState {
|
|
23
52
|
const mode = useMode()
|
|
24
53
|
const setMode = useSetMode()
|
|
25
54
|
|
|
@@ -37,10 +66,22 @@ export function useSearch({ match, onJump }: UseSearchOptions): SearchState {
|
|
|
37
66
|
|
|
38
67
|
const activeQuery = searchActive ? searchQuery : committedQuery
|
|
39
68
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
69
|
+
// Memoized on the query *and* the searched content: a committed query must
|
|
70
|
+
// re-match when rows arrive or change. `deps` is caller-sized, so this is a
|
|
71
|
+
// hand-rolled cache rather than a useMemo dependency array.
|
|
72
|
+
const cacheRef = useRef<MatchCache | null>(null)
|
|
73
|
+
let matchingLines: number[]
|
|
74
|
+
if (!activeQuery) {
|
|
75
|
+
matchingLines = EMPTY
|
|
76
|
+
} else {
|
|
77
|
+
const cache = cacheRef.current
|
|
78
|
+
if (cache && cache.query === activeQuery && sameDeps(cache.deps, deps)) {
|
|
79
|
+
matchingLines = cache.matches
|
|
80
|
+
} else {
|
|
81
|
+
matchingLines = matchRef.current(activeQuery)
|
|
82
|
+
cacheRef.current = { query: activeQuery, deps: [...deps], matches: matchingLines }
|
|
83
|
+
}
|
|
84
|
+
}
|
|
44
85
|
|
|
45
86
|
const matchingLinesRef = useRef(matchingLines)
|
|
46
87
|
matchingLinesRef.current = matchingLines
|
|
@@ -60,6 +101,7 @@ export function useSearch({ match, onJump }: UseSearchOptions): SearchState {
|
|
|
60
101
|
title: "Search",
|
|
61
102
|
hotkey: "/",
|
|
62
103
|
modes: CURSOR_MODES,
|
|
104
|
+
enabled,
|
|
63
105
|
handler: () => {
|
|
64
106
|
preSearchModeRef.current = mode
|
|
65
107
|
setSearchActive(true)
|
|
@@ -73,6 +115,7 @@ export function useSearch({ match, onJump }: UseSearchOptions): SearchState {
|
|
|
73
115
|
title: "Next match",
|
|
74
116
|
hotkey: "n",
|
|
75
117
|
modes: CURSOR_MODES,
|
|
118
|
+
enabled,
|
|
76
119
|
when: () => !searchActive,
|
|
77
120
|
handler: () => {
|
|
78
121
|
const matches = matchingLinesRef.current
|
|
@@ -94,6 +137,7 @@ export function useSearch({ match, onJump }: UseSearchOptions): SearchState {
|
|
|
94
137
|
title: "Previous match",
|
|
95
138
|
hotkey: "shift+n",
|
|
96
139
|
modes: CURSOR_MODES,
|
|
140
|
+
enabled,
|
|
97
141
|
when: () => !searchActive,
|
|
98
142
|
handler: () => {
|
|
99
143
|
const matches = matchingLinesRef.current
|
|
@@ -115,6 +159,7 @@ export function useSearch({ match, onJump }: UseSearchOptions): SearchState {
|
|
|
115
159
|
title: "Cancel search",
|
|
116
160
|
hotkey: "escape",
|
|
117
161
|
modes: ALL_MODES,
|
|
162
|
+
enabled,
|
|
118
163
|
when: () => searchActive,
|
|
119
164
|
handler: () => {
|
|
120
165
|
setSearchActive(false)
|