@@ -3,12 +3,10 @@ package language
33import (
44 "context"
55 "fmt"
6- "io"
76 "os"
87 "path/filepath"
98 "strings"
109
11- "github.com/wakatime/wakatime-cli/pkg/file"
1210 "github.com/wakatime/wakatime-cli/pkg/heartbeat"
1311 "github.com/wakatime/wakatime-cli/pkg/log"
1412)
@@ -63,6 +61,8 @@ func WithDetection(config Config) heartbeat.HandleOption {
6361// Detect detects the language of a specific file. If guessLanguage is true,
6462// Chroma will be used to detect a language from the file contents.
6563func Detect (ctx context.Context , fp string , guessLanguage bool ) (heartbeat.Language , error ) {
64+ logger := log .Extract (ctx )
65+
6666 if language , ok := detectSpecialCases (ctx , fp ); ok {
6767 return language , nil
6868 }
@@ -74,7 +74,16 @@ func Detect(ctx context.Context, fp string, guessLanguage bool) (heartbeat.Langu
7474 language = languageChroma
7575 }
7676
77- language = detectOverrideCases (ctx , fp , language , weight )
77+ head , err := fileHead (ctx , fp )
78+ if err != nil {
79+ logger .Warnf ("failed to load head from file %q: %s" , fp , err )
80+ }
81+
82+ languageVim , weightVim , okVim := detectVimModeline (string (head ))
83+ if okVim && weightVim > weight {
84+ // use language from vim modeline, if weight is higher
85+ language = languageVim
86+ }
7887
7988 if language == heartbeat .LanguageUnknown {
8089 return heartbeat .LanguageUnknown , fmt .Errorf ("could not detect the language of file %q" , fp )
@@ -129,54 +138,6 @@ func detectSpecialCases(ctx context.Context, fp string) (heartbeat.Language, boo
129138 return heartbeat .LanguageUnknown , false
130139}
131140
132- // detectOverrideCases overwrides the Chroma detected language based on file contents.
133- func detectOverrideCases (ctx context.Context , fp string , language heartbeat.Language , weight float32 ) heartbeat.Language {
134- logger := log .Extract (ctx )
135-
136- f , err := file .OpenNoLock (fp ) // nolint:gosec
137- if err != nil {
138- logger .Debugf ("failed to open file: %s" , err )
139- return language
140- }
141-
142- defer func () {
143- if err := f .Close (); err != nil {
144- logger .Debugf ("failed to close file: %s" , err )
145- }
146- }()
147-
148- buf := make ([]byte , 4096 )
149- c , err := f .Read (buf )
150- if err != nil && err != io .EOF {
151- logger .Debugf ("failed to open file: %s" , err )
152- return language
153- }
154-
155- text := string (buf [:c ])
156-
157- languageVim , weightVim , okVim := detectVimModeline (text )
158- if okVim && weightVim > weight {
159- language = languageVim
160- }
161-
162- _ , file := filepath .Split (fp )
163- ext := strings .ToLower (filepath .Ext (file ))
164-
165- if ext == ".fs" {
166- languageForth , weightForth , okForth := detectForthFromContents (text )
167- if okForth && weightForth >= weight {
168- language = languageForth
169- }
170-
171- languageFSharp , weightFSharp , okFSharp := detectFSharpFromContents (text )
172- if okFSharp && weightFSharp >= weight {
173- language = languageFSharp
174- }
175- }
176-
177- return language
178- }
179-
180141// folderContainsCFiles returns true, if filder contains c files.
181142func folderContainsCFiles (ctx context.Context , dir string ) bool {
182143 if dir == "" {
0 commit comments