-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkitty.js
More file actions
149 lines (120 loc) · 3.65 KB
/
Copy pathkitty.js
File metadata and controls
149 lines (120 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
const { execFileSync, execSync, spawn } = require('child_process');
const fs = require('fs');
const path = require('path');
const { DEFAULT_KITTY_PATH, DEFAULT_OPENER } = require('./constants');
let KITTY_PATH = DEFAULT_KITTY_PATH;
let OPENER = DEFAULT_OPENER;
function setKittyPath(kittyPath) {
KITTY_PATH = kittyPath;
}
function setOpener(opener) {
OPENER = opener;
}
function getKittyPath() {
return KITTY_PATH;
}
function getOpener() {
return OPENER;
}
function getKittySocket() {
const envSocket = process.env.KITTY_LISTEN_ON;
if (envSocket) return envSocket;
const tmpFiles = fs.readdirSync('/tmp');
for (const file of tmpFiles) {
if (!file.startsWith('locator_vim_kitty-')) continue;
const fullPath = `/tmp/${file}`;
const stats = fs.statSync(fullPath);
if (stats.isSocket()) {
return `unix:${fullPath}`;
}
}
return null;
}
function runKittyCmd(args, socket = null) {
const cmdArgs = ['@'];
if (socket) {
cmdArgs.push('--to', socket);
}
cmdArgs.push(...args);
return execFileSync(KITTY_PATH, cmdArgs, { encoding: 'utf8' });
}
function getKittyWindows(socket = null) {
const result = runKittyCmd(['ls'], socket);
return JSON.parse(result);
}
function findKittyTabForProject(filePath, kittyData) {
if (!kittyData) return null;
filePath = path.resolve(filePath);
let bestMatch = null;
let bestMatchLength = 0;
for (const osWindow of kittyData) {
const osWindowId = osWindow.id;
for (const tab of osWindow.tabs || []) {
const tabId = tab.id;
const tabWindows = tab.windows || [];
for (const window of tabWindows) {
const windowId = window.id;
const foregroundProcesses = window.foreground_processes || [];
for (const proc of foregroundProcesses) {
const cwd = proc.cwd;
if (!filePath.startsWith(cwd)) continue;
if (cwd.length > bestMatchLength) {
bestMatchLength = cwd.length;
const cmdline = proc.cmdline || [];
const isVim = cmdline.some(c => String(c).toLowerCase().includes(OPENER));
bestMatch = {
osWindowId,
tabId,
vimWindowId: isVim ? windowId : null,
cwd,
};
}
}
}
}
}
return bestMatch;
}
function activateKittyApp() {
execSync('osascript -e \'tell application "kitty" to activate\'', { timeout: 2000 });
}
function launchKittyInstance(projectDir, filePath, line) {
activateKittyApp();
spawn(KITTY_PATH, ['--directory', projectDir, OPENER, `+${line}`, filePath], {
detached: true,
stdio: 'ignore',
}).unref();
}
function focusKittyTab(tabInfo, socket = null) {
activateKittyApp();
runKittyCmd(['focus-tab', '--match', `id:${tabInfo.tabId}`], socket);
const windowId = tabInfo.vimWindowId;
if (windowId) {
runKittyCmd(['focus-window', '--match', `id:${windowId}`], socket);
}
}
function sendVimCommand(windowId, filePath, line, socket = null) {
const windowMatch = `id:${windowId}`;
const escapedPath = filePath.replace(/ /g, '\\ ').replace(/'/g, "\\'");
const vimCmd = `\x1b:e +${line} ${escapedPath}\r`;
runKittyCmd(['send-text', '--match', windowMatch, vimCmd], socket);
}
function launchInNewTab(projectDir, filePath, line, socket = null) {
const launchCmd = `${OPENER} +${line} '${filePath}'`;
runKittyCmd(['launch', '--type=tab', '--cwd', projectDir, '/bin/zsh', '-lc', launchCmd], socket);
}
module.exports = {
setKittyPath,
setOpener,
getKittyPath,
getOpener,
getKittySocket,
runKittyCmd,
getKittyWindows,
findKittyTabForProject,
activateKittyApp,
focusKittyTab,
sendVimCommand,
launchInNewTab,
launchKittyInstance,
};