chore: import Local-Cursor v1.1.8 source snapshot
Includes the current working directory changes. Historical commits and release binaries are excluded to limit Gitea storage. Source base: d7515973fbfd6dd2001fa156c483455b8081c7cb
This commit is contained in:
96
internal/cursor/localize_scan_windows.go
Normal file
96
internal/cursor/localize_scan_windows.go
Normal file
@@ -0,0 +1,96 @@
|
||||
//go:build windows
|
||||
|
||||
package cursor
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// maxScanDirs 限制驱动器扫描的目录总数,避免在超大盘上长时间阻塞。
|
||||
const maxScanDirs = 8000
|
||||
|
||||
// skippedRootNames 是驱动器扫描时跳过的系统目录(大且不可能装 Cursor)。
|
||||
var skippedRootNames = map[string]struct{}{
|
||||
"windows": {},
|
||||
"programdata": {},
|
||||
"users": {},
|
||||
"$recycle.bin": {},
|
||||
"system volume information": {},
|
||||
"recovery": {},
|
||||
"perflogs": {},
|
||||
"dumpstack.log.tmp": {},
|
||||
"config.msi": {},
|
||||
"intel": {},
|
||||
"drivers": {},
|
||||
"msocache": {},
|
||||
}
|
||||
|
||||
// scanDriveRootsForCursor 兜底扫描各固定驱动器:
|
||||
// 根目录与二级目录中查找名称含 cursor 且包含 Cursor.exe 的目录。
|
||||
// 纯文件系统探测,不依赖注册表枚举或子进程(部分安全软件会拦截)。
|
||||
func scanDriveRootsForCursor() string {
|
||||
visited := 0
|
||||
for letter := 'C'; letter <= 'Z'; letter++ {
|
||||
drive := string(letter) + `:\`
|
||||
if _, err := os.Stat(drive); err != nil {
|
||||
continue
|
||||
}
|
||||
if dir := scanDirForCursor(drive, &visited); dir != "" {
|
||||
return dir
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// scanDirForCursor 在目录及其一级子目录中查找 Cursor 安装目录。
|
||||
func scanDirForCursor(root string, visited *int) string {
|
||||
entries, err := os.ReadDir(root)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
var deferred []string
|
||||
for _, entry := range entries {
|
||||
if !entry.IsDir() {
|
||||
continue
|
||||
}
|
||||
name := entry.Name()
|
||||
if _, skip := skippedRootNames[strings.ToLower(name)]; skip {
|
||||
continue
|
||||
}
|
||||
*visited++
|
||||
if *visited > maxScanDirs {
|
||||
return ""
|
||||
}
|
||||
full := filepath.Join(root, name)
|
||||
if strings.Contains(strings.ToLower(name), "cursor") {
|
||||
if isCursorInstallDir(full) {
|
||||
return full
|
||||
}
|
||||
continue
|
||||
}
|
||||
deferred = append(deferred, full)
|
||||
}
|
||||
// 二级目录:仅在一级目录名像程序目录时展开,控制扫描量。
|
||||
for _, dir := range deferred {
|
||||
if !looksLikeProgramsDir(filepath.Base(dir)) {
|
||||
continue
|
||||
}
|
||||
if dir := scanDirForCursor(dir, visited); dir != "" {
|
||||
return dir
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// looksLikeProgramsDir 判断目录名是否像程序/工具安装根目录。
|
||||
func looksLikeProgramsDir(name string) bool {
|
||||
lower := strings.ToLower(name)
|
||||
for _, keyword := range []string{"program", "app", "dev", "soft", "tool", "work", "bin"} {
|
||||
if strings.Contains(lower, keyword) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user