Skip to content

Commit 844fcd9

Browse files
committed
feat: redesigne typing for more flexible
1 parent 296df63 commit 844fcd9

35 files changed

+2444
-2448
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
codeme
2+
*_test.go

core/detector.go

Lines changed: 218 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,237 @@
11
package core
22

33
import (
4-
"os"
5-
"os/exec"
64
"path/filepath"
75
"strings"
86
)
97

10-
var langMap = map[string]string{
11-
"go": "Go", "js": "JavaScript", "ts": "TypeScript", "py": "Python",
12-
"rb": "Ruby", "java": "Java", "c": "C", "cpp": "C++", "cs": "C#",
13-
"rs": "Rust", "php": "PHP", "swift": "Swift", "kt": "Kotlin",
14-
"lua": "Lua", "vim": "Vim", "sh": "Shell", "bash": "Shell",
15-
"md": "Markdown", "json": "JSON", "yaml": "YAML", "toml": "TOML",
16-
"html": "HTML", "css": "CSS", "scss": "SCSS", "sql": "SQL",
8+
// LanguageDetector detects programming languages from file extensions
9+
type LanguageDetector struct {
10+
extensionMap map[string]string
1711
}
1812

19-
func DetectProject(filePath string) string {
20-
// Try git root first
21-
dir := filepath.Dir(filePath)
22-
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
23-
cmd.Dir = dir
24-
if output, err := cmd.Output(); err == nil {
25-
return filepath.Base(strings.TrimSpace(string(output)))
13+
// NewLanguageDetector creates a new language detector
14+
func NewLanguageDetector() *LanguageDetector {
15+
return &LanguageDetector{
16+
extensionMap: map[string]string{
17+
".go": "Go",
18+
".js": "JavaScript",
19+
".ts": "TypeScript",
20+
".jsx": "React",
21+
".tsx": "React",
22+
".py": "Python",
23+
".java": "Java",
24+
".c": "C",
25+
".cpp": "C++",
26+
".cc": "C++",
27+
".cxx": "C++",
28+
".h": "C/C++",
29+
".hpp": "C++",
30+
".cs": "C#",
31+
".php": "PHP",
32+
".rb": "Ruby",
33+
".rs": "Rust",
34+
".swift": "Swift",
35+
".kt": "Kotlin",
36+
".scala": "Scala",
37+
".r": "R",
38+
".m": "Objective-C",
39+
".mm": "Objective-C++",
40+
".sh": "Shell",
41+
".bash": "Bash",
42+
".zsh": "Zsh",
43+
".fish": "Fish",
44+
".pl": "Perl",
45+
".lua": "Lua",
46+
".vim": "VimScript",
47+
".el": "Emacs Lisp",
48+
".clj": "Clojure",
49+
".ex": "Elixir",
50+
".exs": "Elixir",
51+
".erl": "Erlang",
52+
".hs": "Haskell",
53+
".ml": "OCaml",
54+
".fs": "F#",
55+
".dart": "Dart",
56+
".vue": "Vue",
57+
".svelte": "Svelte",
58+
".html": "HTML",
59+
".htm": "HTML",
60+
".css": "CSS",
61+
".scss": "SCSS",
62+
".sass": "Sass",
63+
".less": "Less",
64+
".sql": "SQL",
65+
".json": "JSON",
66+
".xml": "XML",
67+
".yaml": "YAML",
68+
".yml": "YAML",
69+
".toml": "TOML",
70+
".md": "Markdown",
71+
".tex": "LaTeX",
72+
".proto": "Protocol Buffer",
73+
".graphql": "GraphQL",
74+
".sol": "Solidity",
75+
".v": "Verilog",
76+
".vhd": "VHDL",
77+
".asm": "Assembly",
78+
".s": "Assembly",
79+
},
2680
}
81+
}
82+
83+
// DetectLanguage detects the programming language from a file path
84+
func (ld *LanguageDetector) DetectLanguage(filePath string) string {
85+
ext := strings.ToLower(filepath.Ext(filePath))
2786

28-
// Fallback to directory name
29-
abs, _ := filepath.Abs(filePath)
30-
parts := strings.Split(filepath.Dir(abs), string(os.PathSeparator))
31-
if len(parts) > 0 {
32-
return parts[len(parts)-1]
87+
if lang, ok := ld.extensionMap[ext]; ok {
88+
return lang
3389
}
34-
return "unknown"
35-
}
3690

37-
func DetectLanguage(filePath string) string {
38-
ext := strings.TrimPrefix(filepath.Ext(filePath), ".")
39-
if lang, ok := langMap[ext]; ok {
91+
// Check for special cases without extensions
92+
baseName := strings.ToLower(filepath.Base(filePath))
93+
94+
specialFiles := map[string]string{
95+
"dockerfile": "Docker",
96+
"makefile": "Make",
97+
"justfile": "Just",
98+
"rakefile": "Ruby",
99+
"gemfile": "Ruby",
100+
"podfile": "Ruby",
101+
"vagrantfile": "Ruby",
102+
"cmakelists.txt": "CMake",
103+
".gitignore": "Git",
104+
".dockerignore": "Docker",
105+
".editorconfig": "EditorConfig",
106+
}
107+
108+
if lang, ok := specialFiles[baseName]; ok {
40109
return lang
41110
}
42-
return ext
111+
112+
return "Unknown"
113+
}
114+
115+
// AddLanguageMapping adds a custom language mapping
116+
func (ld *LanguageDetector) AddLanguageMapping(extension, language string) {
117+
if !strings.HasPrefix(extension, ".") {
118+
extension = "." + extension
119+
}
120+
ld.extensionMap[strings.ToLower(extension)] = language
43121
}
44122

45-
func DetectBranch(filePath string) string {
46-
dir := filepath.Dir(filePath)
47-
cmd := exec.Command("git", "rev-parse", "--abbrev-ref", "HEAD")
48-
cmd.Dir = dir
49-
if output, err := cmd.Output(); err == nil {
50-
return strings.TrimSpace(string(output))
123+
// ProjectDetector detects project information from file paths
124+
type ProjectDetector struct {
125+
rootMarkers []string
126+
}
127+
128+
// NewProjectDetector creates a new project detector
129+
func NewProjectDetector() *ProjectDetector {
130+
return &ProjectDetector{
131+
rootMarkers: []string{
132+
".git",
133+
"go.mod",
134+
"package.json",
135+
"pom.xml",
136+
"build.gradle",
137+
"Cargo.toml",
138+
"requirements.txt",
139+
"setup.py",
140+
"composer.json",
141+
"Gemfile",
142+
".project",
143+
"CMakeLists.txt",
144+
},
51145
}
52-
return ""
146+
}
147+
148+
// DetectProject extracts project name from file path
149+
func (pd *ProjectDetector) DetectProject(filePath string) string {
150+
parts := strings.Split(filePath, string(filepath.Separator))
151+
152+
// Look for common project folder patterns
153+
for i, part := range parts {
154+
lower := strings.ToLower(part)
155+
if lower == "src" || lower == "projects" || lower == "workspace" || lower == "repos" {
156+
if i+1 < len(parts) {
157+
return parts[i+1]
158+
}
159+
}
160+
}
161+
162+
// Return the first non-root directory
163+
for _, part := range parts {
164+
if part != "" && part != "." && !strings.HasPrefix(part, ".") {
165+
lower := strings.ToLower(part)
166+
if lower != "users" && lower != "home" && lower != "documents" && lower != "desktop" {
167+
return part
168+
}
169+
}
170+
}
171+
172+
return "Unknown"
173+
}
174+
175+
// AddRootMarker adds a custom project root marker
176+
func (pd *ProjectDetector) AddRootMarker(marker string) {
177+
pd.rootMarkers = append(pd.rootMarkers, marker)
178+
}
179+
180+
// EditorDetector detects the editor from process information
181+
type EditorDetector struct {
182+
editorMap map[string]string
183+
}
184+
185+
// NewEditorDetector creates a new editor detector
186+
func NewEditorDetector() *EditorDetector {
187+
return &EditorDetector{
188+
editorMap: map[string]string{
189+
"vscode": "VS Code",
190+
"code": "VS Code",
191+
"sublime": "Sublime Text",
192+
"sublime_text": "Sublime Text",
193+
"atom": "Atom",
194+
"vim": "Vim",
195+
"nvim": "Neovim",
196+
"neovim": "Neovim",
197+
"emacs": "Emacs",
198+
"idea": "IntelliJ IDEA",
199+
"intellij": "IntelliJ IDEA",
200+
"pycharm": "PyCharm",
201+
"webstorm": "WebStorm",
202+
"goland": "GoLand",
203+
"clion": "CLion",
204+
"rider": "Rider",
205+
"androidstudio": "Android Studio",
206+
"xcode": "Xcode",
207+
"eclipse": "Eclipse",
208+
"netbeans": "NetBeans",
209+
"notepad++": "Notepad++",
210+
"nano": "Nano",
211+
"gedit": "gedit",
212+
"kate": "Kate",
213+
},
214+
}
215+
}
216+
217+
// DetectEditor detects the editor from a process name
218+
func (ed *EditorDetector) DetectEditor(processName string) string {
219+
lower := strings.ToLower(processName)
220+
221+
// Remove common extensions
222+
lower = strings.TrimSuffix(lower, ".exe")
223+
lower = strings.TrimSuffix(lower, ".app")
224+
225+
for key, editor := range ed.editorMap {
226+
if strings.Contains(lower, key) {
227+
return editor
228+
}
229+
}
230+
231+
return "Unknown"
232+
}
233+
234+
// AddEditorMapping adds a custom editor mapping
235+
func (ed *EditorDetector) AddEditorMapping(processName, editor string) {
236+
ed.editorMap[strings.ToLower(processName)] = editor
53237
}

core/detector_test.go

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)