6

Szukam sposobu na określenie typu pliku w vimie i ustawienie podświetlania składni na podstawie typu pliku. Jedynym haczykiem jest to, że nie mogę użyć rozszerzenia pliku do określenia typu pliku.Wykryj typ pliku w vim bez poprawnego rozszerzenia pliku

Oto mój scenariusz: Używam vimdiff lub gvimdiff jako narzędzia P4DIFF, które pokazuje zmiany między plikami w mojej lokalnej kopii i tymi z serwera perforacji. Siłą rzeczy wydaje się przynieść w plikach z serwera Perforce do katalogu/tmp i używa PID na nazwę pliku, na przykład:

/tmp/tmp.24673.23 

To był dla C++ pliku źródłowego.

Najczęstszymi typami plików, które napotykam w repozytorium perforce są źródła C/C++ i pliki nagłówkowe, pliki Makefile, skrypty Pythona, skrypty perla, skrypty ruby ​​i skrypty tcl.

  • Przyjrzeliśmy się używając modeline, ale większość z tych źródeł w naszym drzewie nie ma tej informacji osadzonych w pliku.

  • This publikowanie wzmianek o możliwym podejściu do wyszukiwania i identyfikacja magicznego wzorca. Nie mogłem znaleźć żadnego spójnego magicznego wzoru, z którym mógłbym osiągnąć wysoki wskaźnik sukcesu.

  • Próbowałem użyć binarny file na moim komputerze linux, aby zobaczyć, jakie wyniki otrzymam. Wydaje się zidentyfikować źródła C/C++ dobrze, ale nie Makefile a nawet skrypty python (które nie mają hashbang)

Jeden dobrą rzeczą jest to, że wśród 2 pliki, które są porównywane pliku po prawej jest z mojej lokalnej kopii, a więc ma poprawną nazwę pliku z rozszerzeniem, dzięki czemu podświetlanie składni jest poprawnie włączone dla pliku po prawej stronie.

Czy istnieje sposób, w jaki mogę wykorzystać to, aby ustawić takie samo podświetlanie składni dla pliku wyświetlanego po lewej stronie?

Wszelkie alternatywne rozwiązania tego problemu są również mile widziane.

Odpowiedz

6

To było ciekawe puzzle. :)

aug SmartDiffType 
    au! 
    au VimEnter * :if &diff && len(&ft) | call setwinvar(2/winnr(),'&ft',&ft) | elseif &diff | let &ft=getwinvar(2/winnr(),'&ft') | endif 
aug END 

Uwagi:

  • z 4 linii powyżej, tylko potrzeba linia au VimEnter, ale jest ogólnie dobra praktyka, aby umieścić w jakiejś grupie autokomend AUTOCOMMAND z resetem (au!) u góry.
  • AUTOCOMMAND na VimEnter bo inaczej diff lub okna nie są właściwie jeszcze
  • vimdiff intialized mogło być wywołane ze starego pliku na prawo lub na lewo od Splitu, więc uważamy oba przypadki.
  • 2/winnr() trik matematyka przerzucanie między 1 i 2 (2/2 = 1, 2/1 = 2)
+0

Bardzo ładne. Uwielbiam sztuczkę '2/winnr()' !! –

+0

Super! To działa naprawdę ładnie ... Po prostu przenieś if-endif do funkcji i zastąpił polecenie wywołaniem funkcji. :) – Tuxdude

3

Zakładając, że masz otwarte tylko 2 podziały i podział na lewo jest lokalny plik można wykonać następujące czynności

:windo let &ft = getwinvar(1, '&ft') 

Spowoduje to ustawienie filetype do wartości górnej lewej największe okno dla wszystkie okna.

Więcej Pomocy Zobacz:

:h :windo 
:h 'ft' 
:h getwinvar(
+0

Dzięki, to działa. Musiałem użyć 'windo let & ft = getwinvar (2, '& ft')', ponieważ prawe okno miało poprawny typ pliku. Czy istnieje sposób dodania go do '.vimrc', aby dla każdego vimdiff robił to automatycznie? Samo dodanie polecenia 'windo' do .vimrc nie rozwiązało problemu. Zgaduję, że może się to zmienić później. – Tuxdude

+0

Chociaż jestem pewien, że taki "autocmd" mógłby zostać utworzony, wydaje mi się, że najprostszym rozwiązaniem byłoby stworzenie niestandardowego polecenia: 'command! -bar -nargs = 0 SameFiletype exe 'windo set ft ='. & ft' Dodaj to do swojego pliku '~/.vimrc'. Następnym razem, gdy pojawi się sytuacja, przejdź do bufora z poprawnym typem pliku i wykonaj ': SameFiletype' –

+0

Dzięki, brzmi to jak rozsądne podejście :) – Tuxdude