Skip to content

Commit f46e7ff

Browse files
acarl005oz-agent
andauthored
Add completion spec: lsof (#196)
Co-authored-by: Oz <oz-agent@warp.dev>
1 parent 5a6c872 commit f46e7ff

5 files changed

Lines changed: 420 additions & 16 deletions

File tree

command-signatures/json/lsof.json

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
{
2+
"name": "lsof",
3+
"description": "List open files",
4+
"options": [
5+
{
6+
"name": [
7+
"-?",
8+
"-h"
9+
],
10+
"description": "Print help and exit"
11+
},
12+
{
13+
"name": "-a",
14+
"description": "Causes list selections to be ANDed"
15+
},
16+
{
17+
"name": "-A",
18+
"description": "Use alternative name list file",
19+
"args": {
20+
"name": "name_list_file",
21+
"template": "filepaths"
22+
}
23+
},
24+
{
25+
"name": "-b",
26+
"description": "Avoid kernel functions that might block: lstat, readlink, stat"
27+
},
28+
{
29+
"name": "-c",
30+
"description": "Select listing for processes whose command begins with c (^ to negate, /c/[bix] for regex)",
31+
"args": {
32+
"name": "c",
33+
"generatorName": "process_names"
34+
}
35+
},
36+
{
37+
"name": "+c",
38+
"insertValue": "+c {cursor}",
39+
"description": "Set COMMAND column width (default 9)",
40+
"args": {
41+
"name": "w"
42+
}
43+
},
44+
{
45+
"name": "-C",
46+
"description": "Do not report any pathname component from kernel's name cache"
47+
},
48+
{
49+
"name": "-D",
50+
"description": "Control use of the device cache file",
51+
"args": {
52+
"name": "function",
53+
"suggestions": [
54+
{
55+
"name": "?",
56+
"description": "Report device cache file paths"
57+
},
58+
{
59+
"name": "b",
60+
"description": "Build the device cache file"
61+
},
62+
{
63+
"name": "i",
64+
"description": "Ignore the device cache file"
65+
},
66+
{
67+
"name": "r",
68+
"description": "Read the device cache file"
69+
},
70+
{
71+
"name": "u",
72+
"description": "Read and update the device cache file"
73+
}
74+
]
75+
}
76+
},
77+
{
78+
"name": "+d",
79+
"insertValue": "+d {cursor}",
80+
"description": "Search for all open instances of directory s and the files and directories it contains at its top level",
81+
"args": {
82+
"name": "s",
83+
"template": "folders"
84+
}
85+
},
86+
{
87+
"name": "-d",
88+
"description": "Specifies a list of file descriptors to exclude (^) or include in the output listing",
89+
"args": {
90+
"name": "s"
91+
}
92+
},
93+
{
94+
"name": "+D",
95+
"insertValue": "+D {cursor}",
96+
"description": "Search for all open instances of directory D and all the files and directories it contains to its complete depth (SLOW)",
97+
"args": {
98+
"name": "D",
99+
"template": "folders"
100+
}
101+
},
102+
{
103+
"name": "+E",
104+
"insertValue": "+E",
105+
"description": "Display endpoint info and files"
106+
},
107+
{
108+
"name": "-E",
109+
"description": "Display endpoint info"
110+
},
111+
{
112+
"name": "-F",
113+
"description": "Select output fields for other programs to parse (-F? for help)",
114+
"args": {
115+
"name": "f",
116+
"isOptional": true
117+
}
118+
},
119+
{
120+
"name": "+f",
121+
"insertValue": "+f {cursor}",
122+
"description": "Enable path name-based kernel lookups for file system names"
123+
},
124+
{
125+
"name": "-f",
126+
"description": "Disable path name-based kernel lookups for file names"
127+
},
128+
{
129+
"name": "-g",
130+
"description": "Exclude (^) or select and print process group IDs",
131+
"args": {
132+
"name": "s",
133+
"isOptional": true
134+
}
135+
},
136+
{
137+
"name": "-i",
138+
"description": "Select listing of IPv[46] files (format: [46][proto][@host|addr][:svc_list|port_list])",
139+
"args": {
140+
"name": "i",
141+
"isOptional": true
142+
}
143+
},
144+
{
145+
"name": "-K",
146+
"description": "List or ignore tasks (kernel threads)",
147+
"args": {
148+
"name": "i",
149+
"isOptional": true
150+
}
151+
},
152+
{
153+
"name": "-l",
154+
"description": "Convert UIDs to login names"
155+
},
156+
{
157+
"name": "+L",
158+
"insertValue": "+L {cursor}",
159+
"description": "List link counts below the specified number",
160+
"args": {
161+
"name": "l",
162+
"isOptional": true
163+
}
164+
},
165+
{
166+
"name": "-L",
167+
"description": "Suppress link count listing",
168+
"args": {
169+
"name": "l",
170+
"isOptional": true
171+
}
172+
},
173+
{
174+
"name": "+m",
175+
"insertValue": "+m {cursor}",
176+
"description": "Use or create mount supplement file",
177+
"args": {
178+
"name": "m",
179+
"isOptional": true,
180+
"template": "filepaths"
181+
}
182+
},
183+
{
184+
"name": "+M",
185+
"insertValue": "+M",
186+
"description": "Enable portMap registration"
187+
},
188+
{
189+
"name": "-M",
190+
"description": "Disable portMap registration"
191+
},
192+
{
193+
"name": "-n",
194+
"description": "Do not convert network numbers to host names"
195+
},
196+
{
197+
"name": "-N",
198+
"description": "Select listing of NFS files"
199+
},
200+
{
201+
"name": "-o",
202+
"description": "List file offset or set offset digits",
203+
"args": {
204+
"name": "o",
205+
"description": "Number of decimal digits for file offset (default 8)",
206+
"isOptional": true
207+
}
208+
},
209+
{
210+
"name": "-O",
211+
"description": "Bypass overhead avoiding strategy (RISKY)"
212+
},
213+
{
214+
"name": "-P",
215+
"description": "Do not convert port numbers to port names"
216+
},
217+
{
218+
"name": "-p",
219+
"description": "Exclude (^) or select processes by PID",
220+
"args": {
221+
"name": "s",
222+
"generatorName": "pids"
223+
}
224+
},
225+
{
226+
"name": "-Q",
227+
"description": "Allow failed search to occur without error"
228+
},
229+
{
230+
"name": "-R",
231+
"description": "Print parent PID (PPID)"
232+
},
233+
{
234+
"name": "+r",
235+
"insertValue": "+r {cursor}",
236+
"description": "Repeat listing every t seconds until no open files found (format: t[m<fmt>])",
237+
"args": {
238+
"name": "t",
239+
"isOptional": true
240+
}
241+
},
242+
{
243+
"name": "-r",
244+
"description": "Repeat listing every t seconds forever (format: t[m<fmt>])",
245+
"args": {
246+
"name": "t",
247+
"isOptional": true
248+
}
249+
},
250+
{
251+
"name": "-s",
252+
"description": "List file size or exclude (^)/select protocol states by name (format: p:s where p is TCP or UDP)",
253+
"args": {
254+
"name": "p:s",
255+
"isOptional": true
256+
}
257+
},
258+
{
259+
"name": "-S",
260+
"description": "Set stat timeout in seconds (default 15)",
261+
"args": {
262+
"name": "t",
263+
"isOptional": true
264+
}
265+
},
266+
{
267+
"name": "-t",
268+
"description": "Produce terse output (PIDs only, no header)"
269+
},
270+
{
271+
"name": "-T",
272+
"description": "Disable TCP/TPI info or select Fl, Q, St info (format: fqs)",
273+
"args": {
274+
"name": "fqs",
275+
"isOptional": true
276+
}
277+
},
278+
{
279+
"name": "-U",
280+
"description": "Select listing of Unix domain socket files"
281+
},
282+
{
283+
"name": "-u",
284+
"description": "Exclude (^) or select by login name or UID",
285+
"args": {
286+
"name": "s",
287+
"generatorName": "users"
288+
}
289+
},
290+
{
291+
"name": "-v",
292+
"description": "List version information"
293+
},
294+
{
295+
"name": "-V",
296+
"description": "Indicate unsuccessfully searched-for items"
297+
},
298+
{
299+
"name": "+w",
300+
"insertValue": "+w",
301+
"description": "Enable warnings"
302+
},
303+
{
304+
"name": "-w",
305+
"description": "Suppress warnings"
306+
},
307+
{
308+
"name": "-X",
309+
"description": "Skip reporting of TCP, UDP, and UDPLITE files"
310+
},
311+
{
312+
"name": "-x",
313+
"description": "Cross over file systems or symbolic links when using +d or +D",
314+
"args": {
315+
"name": "fl",
316+
"description": "f to cross file systems, l to cross symbolic links",
317+
"isOptional": true
318+
}
319+
},
320+
{
321+
"name": "-Z",
322+
"description": "Specify SELinux security context",
323+
"args": {
324+
"name": "Z",
325+
"isOptional": true
326+
}
327+
}
328+
],
329+
"args": {
330+
"name": "names",
331+
"description": "Named files or file systems to select",
332+
"isOptional": true,
333+
"isVariadic": true,
334+
"template": "filepaths"
335+
}
336+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use warp_completion_metadata::{CommandBuilder, Generator, GeneratorResultsCollector, Suggestion};
2+
3+
/// Returns a cross-platform generator that lists local user names.
4+
///
5+
/// Uses `getent passwd` on Linux, `dscl` on macOS, and falls back to `/etc/passwd`.
6+
pub fn users_generator() -> Generator {
7+
Generator::script(
8+
CommandBuilder::single_command(
9+
"sh -c 'if command -v getent >/dev/null 2>&1; then getent passwd | cut -d: -f1; elif command -v dscl >/dev/null 2>&1; then dscl . -list /Users; else cut -d: -f1 /etc/passwd; fi'",
10+
),
11+
|output| {
12+
output
13+
.trim()
14+
.lines()
15+
.filter(|line| {
16+
!line.is_empty() && !line.starts_with('_') && !line.starts_with('#')
17+
})
18+
.map(|name| Suggestion::with_description(name.trim(), "User"))
19+
.collect_unordered_results()
20+
},
21+
)
22+
}

command-signatures/src/generators/killall.rs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,11 @@ use warp_completion_metadata::{
22
CommandBuilder, CommandSignatureGenerators, Generator, GeneratorResultsCollector, Suggestion,
33
};
44

5+
use super::common;
6+
57
pub fn generator() -> CommandSignatureGenerators {
68
CommandSignatureGenerators::new("killall")
7-
.add_generator(
8-
"user_name",
9-
Generator::script(
10-
CommandBuilder::pipe(
11-
CommandBuilder::single_command("dscl . -list /Users"),
12-
CommandBuilder::single_command("grep -v '^_'"),
13-
),
14-
|output| {
15-
output
16-
.trim()
17-
.lines()
18-
.map(Suggestion::new)
19-
.collect_unordered_results()
20-
},
21-
),
22-
)
9+
.add_generator("user_name", common::users_generator())
2310
.add_generator(
2411
"process_name",
2512
Generator::script(

0 commit comments

Comments
 (0)