Tag untuk Emacs: Hubungan antara etags, ebrowse, cscope, GNU Global dan exuberant ctags

102

Saya mengerjakan proyek C ++, dan saya membaca panduan Alex Ott untuk CEDET dan utas lain tentang tag di StackOverflow, tetapi saya masih bingung tentang bagaimana Emacs berinteraksi dengan sistem tag yang berbeda ini untuk memfasilitasi pelengkapan otomatis, mencari definisi, navigasi sumber basis kode atau pratinjau dokumen-string.

  1. Apa perbedaan (misalnya dalam hal fitur) antara etags, ebrowse, exuberant ctags, cscope, GNU Globaldan GTags? Apa yang harus saya lakukan untuk menggunakannya di Emacs ?

  2. Apakah saya memerlukan semantik / senator (CEDET) jika saya ingin menggunakan tag untuk menavigasi / simbol pelengkapan otomatis?

  3. Apa yang dibawa semantik ke tabel di atas utilitas tag yang berbeda ini? Bagaimana antarmuka dengan alat-alat ini?

Amelio Vazquez-Reina
sumber
2
Dilihat dari bagasi , GTagsproyek yang Anda tautkan cukup mati. Jika seseorang membicarakannya gtags, mungkin yang mereka maksud adalah GNU Global.
Gordon Gustafson

Jawaban:

71

Itu pertanyaan yang bagus seperti yang baru-baru ini saya baca di sini, jadi saya akan mencoba menjelaskan perbedaannya secara lebih rinci:

Butir 1:

etagsdan ctagskeduanya menghasilkan file indeks (alias tag / TAGS) dari objek bahasa yang ditemukan di file sumber yang memungkinkan item ini ditemukan dengan cepat dan mudah oleh editor teks atau utilitas lain. Tag menandakan objek bahasa yang entri indeksnya tersedia (atau, sebagai alternatif, entri indeks yang dibuat untuk objek itu). Tag yang dihasilkan oleh ctag lebih kaya dalam hal metadata, tetapi Emacs tidak dapat menafsirkan data tambahan, jadi Anda harus mempertimbangkannya kurang lebih sama (keuntungan utama ctagsadalah dukungannya untuk lebih banyak bahasa). Penggunaan utama untuk file tag adalah mencari kelas / metode / fungsi / konstanta / dll deklarasi / definisi.

cscopejauh lebih kuat (setidaknya sejauh menyangkut C / C ++ dan Java). Sementara itu beroperasi pada prinsip yang kurang lebih sama (menghasilkan file metadata yang berguna) ini memungkinkan Anda melakukan beberapa hal yang lebih menarik seperti menemukan semua referensi ke simbol, melihat di mana suatu fungsi dipanggil, dll (Anda dapat menemukan definisi juga) .

Singkatnya:

ctagssatu memungkinkan Anda untuk menavigasi ke deklarasi / definisi simbol (yang oleh beberapa orang disebut pencarian satu arah ). ctagsadalah alat tujuan umum yang berguna untuk banyak bahasa.

Di sisi lain (seperti yang disebutkan di halaman proyek) cscope memungkinkan Anda untuk:

  • Pergi ke deklarasi simbol
  • Memperlihatkan daftar yang dapat dipilih dari semua referensi ke simbol
  • Telusuri definisi global apa pun
  • Fungsi disebut dengan fungsi
  • Fungsi memanggil suatu fungsi
  • Telusuri string teks
  • Telusuri pola ekspresi reguler
  • Temukan file
  • Temukan semua file termasuk file

Seharusnya tidak mengherankan bagi siapa pun pada saat ini, bahwa ketika saya berurusan dengan proyek C / C ++ saya terlalu banyak menggunakan cscopedan tidak terlalu peduli ctags. Ketika berurusan dengan bahasa lain, situasinya jelas akan terbalik.

Butir 2.

Untuk memiliki pelengkapan otomatis yang cerdas, Anda memerlukan parser kode sumber yang sebenarnya (seperti semantik), jika tidak, Anda tidak akan mengetahui jenis objek (misalnya) dalam aplikasi Anda dan metode yang dapat dipanggil. Anda dapat memiliki pelengkapan otomatis berdasarkan berbagai sumber, tetapi untuk mendapatkan hasil terbaik, Anda memerlukan pengurai. Hal yang sama berlaku untuk penyorotan sintaks - saat ini penyorotan sintaks dalam mode utama Emacs hanya didasarkan pada ekspresi reguler dan itu sangat rapuh dan rawan kesalahan. Mudah-mudahan dengan dimasukkannya semantik di Emacs 23.2 (dulu merupakan paket eksternal sebelum itu) kita akan mulai melihat lebih banyak kegunaan untuknya (seperti menggunakannya untuk menganalisis kode sumber buffer untuk menyorotnya dengan benar)

Karena semantik Emacs 24.1 dapat digunakan dari kerangka penyelesaian Emacs. Cara termudah untuk mengujinya adalah dengan membuka file kode sumber C dan mengetik M-TABatau C-M-imelihat semantik selesai secara otomatis untuk Anda. Untuk bahasa di mana semantik tidak diaktifkan secara default, Anda dapat menambahkannya baris berikut ke hook mode utama pilihan Anda:

(add-to-list 'completion-at-point-functions 'semantic-completion-at-point-function)

Butir 3.

semantic membawa kesadaran kode yang sebenarnya (untuk beberapa bahasa yang saat ini mendukung) dan menutup kesenjangan antara IDE dan Emacs. Ini tidak benar-benar berinteraksi dengan alat seperti etagsdan cscope, tetapi itu tidak berarti Anda tidak dapat menggunakannya bersama.

Semoga penjelasan saya masuk akal dan bermanfaat bagi Anda.

PS Saya tidak begitu akrab dengan globaldan ebrowse, tetapi jika memori melayani saya, mereka menggunakan etag.

Bozhidar Batsov
sumber
1
Ini bagus. Terima kasih! Apakah Anda tahu bagaimana saya bisa menggunakan cscopeEmacs? Saya membaca tentang xcscope.elEmacsWiki di sini tetapi saya tidak dapat menemukan tautan ke file tersebut. Selain itu, .elfile apa yang Anda gunakan untuk mendapatkan cscopeEmacs?
Amelio Vazquez-Reina
1
xcscope.elterletak di cscope/contrib/xcscope/(berada dalam paket distribusi). Itulah yang saya gunakan.
Bozhidar Batsov
Satu pertanyaan lagi: Bagaimana jika semanticdibandingkan dengan cscope? Dalam hal menavigasi melalui kode sumber, apakah semantik menyediakan fungsionalitas yang cscopetidak? Apakah Anda menggunakan keduanya?
Amelio Vazquez-Reina
4
Saya tidak percaya GNU Global menggunakan etags, btw. IIRC memelihara dan menanyakan database yang 'tepat' (daripada memindai file teks datar), yang memiliki banyak manfaat kinerja baik untuk melakukan kueri dan (terutama) untuk memperbarui tag.
phils
@BozhidarBatsov Saat Anda berkata For languages where semantic is not enabled by default, you can add the following line to your major mode hook of choice ... <code>. Apa sebenarnya yang dilakukan cuplikan kode itu?
Amelio Vazquez-Reina
45

Saya akan mencoba menambahkan beberapa penjelasan ke 1.

Apa itu?

  • Etags adalah perintah untuk menghasilkan file 'TAGS' yang merupakan file tag untuk Emacs. Anda dapat menggunakan file dengan etags.el yang merupakan bagian dari paket emacs.
  • Ctags adalah perintah untuk menghasilkan file 'tag' yang merupakan file tag untuk vi. Sekarang Exuberant Ctags dapat menghasilkan file 'TAGS' dengan opsi -e, dan mendukung 41 bahasa pemrograman.
  • Cscope adalah alat penjelajahan kode sumber all-in-one untuk bahasa C. Ini memiliki CUI yang bagus (antarmuka pengguna karakter) dan database tag (cscope.in.out, cscope.out, cscope.po.out). Anda dapat menggunakan cscope dari Emacs menggunakan xcscope.el yang merupakan bagian dari paket cscope.
  • GNU GLOBAL adalah sistem penandaan kode sumber. Meskipun mirip dengan alat di atas, ini berbeda dari mereka pada hal ini tergantung dari editor mana pun, dan tidak memiliki antarmuka pengguna kecuali untuk baris perintah. Gtags adalah perintah untuk membuat file tag untuk GLOBAL (GTAGS, GRTAGS, GPATH). Anda dapat menggunakan GLOBAL dari emacs menggunakan gtags.el yang merupakan bagian dari paket GLOBAL. Selain itu, ada banyak pustaka elisp untuk itu (xgtags.el, ggtags.el, anything-gtags.el, helm-gtags.el, dll).

Perbandingan

  • Ctag dan etag hanya menangani definisi. Cscope dan GNU GLOBAL tidak hanya menangani definisi tetapi juga referensi.
  • Ctags dan etags menggunakan file tag teks datar. Cscope dan GNU GLOBAL menggunakan basis data tag nilai kunci.
  • Cscope dan GNU GLOBAL memiliki grep seperti mesin pencari dan fasilitas pembaruan tambahan dari file tag.

Kombinasi

Anda dapat menggabungkan dukungan bahasa yang kaya dari Exuberant Ctags dan fasilitas database GNU GLOBAL dengan menggunakan ctags sebagai parser plug-in GLOBAL.

Coba yang berikut ini: (masing-masing membutuhkan GLOBAL-6.0, Exuberant Ctags-5.5 atau lebih baru)

Membangun GNU GLOBAL:

$ ./configure --with-exuberant-ctags=/usr/local/bin/ctags
$ sudo make install

Pemakaian:

$ export GTAGSCONF=/usr/local/share/gtags/gtags.conf
$ export GTAGSLABEL=ctags
$ gtags                     # invokes Exuberant Ctags internally
$ emacs -f gtags-mode       # load gtags.el

(Namun, Anda tidak dapat memperlakukan referensi dengan metode ini, karena ctag tidak menangani referensi.)

Anda juga dapat menggunakan cscope sebagai klien GNU GLOBAL. Paket GLOBAL menyertakan perintah bernama 'gtags-cscope' yang merupakan port dari cscope, yaitu cscope itu sendiri kecuali menggunakan GLOBAL sebagai mesin telusur, bukan cscope.

$ gtags-cscope          # this is GLOBAL version of cscope

Dengan kombinasi tersebut, Anda dapat menggunakan cscope untuk 41 bahasa.

Semoga berhasil!

shigio
sumber
1
Untuk pengguna Debian dan turunannya seperti Ubuntu: Halaman web GNU GLOBAL memperingatkan bahwa paket .deb yang dikirimkan dengan distribusi Linux ini sudah usang, dan tidak boleh digunakan. Dalam kasus saya, GLOBAL menggunakan versi 5.7.1, dan saya tidak dapat membuat gtags.el, ggtags.el atau helm-gtags.el berfungsi dengan baik di Emacs 24. Mengompilasi GNU GLOBAL 6.5 dari awal, dengan dukungan untuk Exuberant Ctags ( Saya menggunakan 5,8) berhasil. (Terima kasih atas petunjuk yang luar biasa, @shigio).
Rob
9

File TAGS berisi definisi

Sebuah TAGSfile berisi daftar di mana fungsi dan kelas didefinisikan. Ini biasanya ditempatkan di root proyek dan terlihat seperti ini:

^L
configure,3945
as_fn_success () { as_fn_return 0; }^?as_fn_success^A180,5465
as_fn_failure () { as_fn_return 1; }^?as_fn_failure^A181,5502
as_fn_ret_success () { return 0; }^?as_fn_ret_success^A182,5539
as_fn_ret_failure () { return 1; }^?as_fn_ret_failure^A183,5574

Ini memungkinkan Emacs menemukan definisi. Navigasi dasar sudah ada di dalamnya find-tag, tetapi etags-selectmemberikan UI yang lebih baik bila ada beberapa kecocokan.

Anda juga dapat menggunakan file TAGS untuk pelengkapan kode. Misalnya, backend etag perusahaan menggunakan file TAGS .

File TAGS dapat dibuat dengan alat yang berbeda

ctags(sebelumnya dikenal sebagai 'universal ctags' atau 'exuberant ctags') dapat menghasilkan file TAGS dan mendukung berbagai bahasa. Itu secara aktif dipertahankan di github.

Emacs dikirimkan dengan dua program yang menghasilkan file TAGS, yang disebut etagsdan ctags. Emacs ' ctagshanya etagsdengan antarmuka CLI yang sama dengan ctag universal. Untuk menghindari kebingungan, banyak distro yang mengganti nama program ini (misalnya ctags.emacs24di Debian).

Ada juga alat khusus bahasa untuk membuat file TAGS, seperti jsctagsdan hasktags.

Format file lainnya

ebrowseadalah program C yang disertakan dengan Emacs. Ini mengindeks kode C / C ++ dan menghasilkan BROWSEfile. ebrowse.el menyediakan definisi dan penyelesaian find biasa. Anda juga dapat membuka BROWSEfile secara langsung di Emacs untuk mendapatkan gambaran umum tentang kelas / fungsi yang ditentukan basis kode.

GNU Global memiliki format database sendiri yang terdiri dari a GTAGS, GRTAGSdan GPATHfile. Anda dapat membuat file-file ini dengan gtagsperintah, yang mengurai kode C / C ++. Untuk bahasa lain, GNU Global dapat membaca file yang dibuat oleh ctag universal.

GNU Global juga menyediakan antarmuka CLI untuk mengajukan pertanyaan yang lebih rumit, seperti 'di mana simbol ini disebutkan?'. Ia dikirimkan dengan paket Emacs gtags.el, tetapi ggtags.el juga populer untuk mengakses basis data GNU Global.

Cscope memiliki semangat yang mirip dengan GNU Global: ia mengurai C / C ++ ke dalam format database-nya sendiri. Itu juga dapat menjawab pertanyaan seperti 'temukan semua penelepon / panggilan dari fungsi ini'.

Lihat juga diskusi HN ini yang membandingkan global dan cscope .

Proyek Klien / Server

rtags mem-parsing dan mengindeks C / C ++ menggunakan server persisten. Ini menggunakan pengurai clang, sehingga menangani C ++ dengan sangat baik. Ini dikirimkan dengan paket Emacs untuk melakukan kueri ke server.

google-gtags adalah proyek tempat file TAGS yang besar akan disimpan di server. Saat Anda menanyakan server, itu akan memberikan subset dari file TAGS yang relevan dengan pencarian Anda.

Semantik (CEDET)

Semantic adalah paket Emacs bawaan yang berisi parser untuk C / C ++, sehingga dapat menemukan definisi juga. Itu juga dapat mengimpor data dari file TAGS, database csope, dan sumber lainnya. CEDET juga menyertakan fungsionalitas gaya IDE yang menggunakan data ini, misalnya membuat diagram UML dari hierarki kelas.

Wilfred Hughes
sumber
7

[jawaban diperbarui dari shigio ]

Saya akan mencoba menambahkan beberapa penjelasan untuk bagian 1 pertanyaan.

Apa itu?

  1. Etags menghasilkan TAGSfile yang merupakan format file tag untuk Emacs . Anda dapat menggunakan file Etags etags.elyang merupakan bagian dari Emacs.
  2. Ctagsadalah istilah umum untuk apa pun yang dapat menghasilkan tagsfile, yang merupakan format file tag asli untuk Vi. Universal Ctags (alias UCtags, sebelumnya Exuberant Ctags) juga dapat menghasilkan Etags dengan -eopsi tersebut.
  3. Cscope adalah alat browsing kode sumber-semua-dalam satu untuk C (dengan dukungan yang lebih rendah untuk C ++ dan Java), dengan database sendiri tag ( cscope.in.out, cscope.out, cscope.po.out) dan TUI . Dukungan Cscope sudah terpasang di Vim; Anda dapat menggunakan Cscope dari Emacs menggunakan paket xcscope.el . Ada juga GUI berbasis Cscope .
  4. GNU GLOBAL (aka Gtags) adalah satu lagi sistem penandaan kode sumber (dengan perbedaan yang signifikan - lihat bagian selanjutnya), di dalamnya ia juga menghasilkan berkas tanda.

Perbandingan

  • Ctags dan Etags hanya memperlakukan definisi (dari, misalnya, variabel dan fungsi). Cscope dan Gtags juga menangani referensi.
  • File tag Ctags dan Etags berbentuk datar . Tagfile Cscope dan Gtags adalah database nilai kunci yang lebih kuat , yang memungkinkan (misalnya) pembaruan tambahan.
  • Cscope dan Gtag memiliki file grep mesin pencari yang mirip.
  • Ctags memiliki dukungan bawaan untuk lebih banyak bahasa dan format data: lihat daftar parser Universal Ctags saat ini di dalam repositori . UCtags juga telah mendokumentasikan bagaimana mengembangkan parser Anda sendiri .
  • Cscope dan Gtags tidak bergantung pada editor.
  • Gtags tidak menyediakan antarmuka penggunanya sendiri, tetapi saat ini (Okt 2016) dapat digunakan dari commandline (CLI), Emacs dan kerabat, Vi dan kerabat, less(pager), Doxygen , dan browser web apa pun.
  • Gtags menyediakan gtags.elmelalui paket GLOBAL, tetapi ada juga banyak ekstensi elisp lainnya, termasuk xgtags.el, ggtags.el, anything-gtags.el, helm-gtags.el.

Kombinasi

Anda dapat menggabungkan dukungan bahasa universal Ctags dengan fasilitas database Gtags dan banyak ekstensi dengan menggunakan Ctags sebagai pengurai plug-in GLOBAL :

# build GNU GLOBAL
./configure --with-exuberant-ctags=/usr/local/bin/ctags
sudo make install

# use it
export GTAGSCONF=/usr/local/share/gtags/gtags.conf
export GTAGSLABEL=ctags
gtags                     # invokes Universal Ctags internally
emacs -f gtags-mode       # load gtags.el

Perhatikan lagi bahwa jika Anda menggunakan Ctags sebagai parser untuk Gtag Anda, Anda kehilangan kemampuan untuk menangani referensi (misalnya, penggunaan variabel, pemanggilan fungsi) yang seharusnya disediakan oleh Gtag. Pada dasarnya, Anda menukar pelacakan referensi Gtags untuk dukungan bahasa bawaan Ctag yang lebih besar.

Anda juga dapat menggunakan Cscope sebagai klien Gtag: gtags-cscope .

Semoga berhasil!

TomRoche
sumber
Saya membaca: "Perhatikan lagi bahwa jika Anda menggunakan Ctags sebagai parser untuk Gtag Anda, Anda kehilangan kemampuan untuk memperlakukan referensi (misalnya, penggunaan variabel, panggilan fungsi) yang seharusnya disediakan oleh Gtag. Pada dasarnya, Anda menukar pelacakan referensi Gtag untuk Dukungan bahasa bawaan yang lebih besar dari Ctag. " Apakah itu benar untuk ctag lama yang dikirimkan dengan Emacs, atau apakah itu masih berlaku untuk Universal Ctags? Juga, saya membaca "menggabungkan bahasa kaya Universal Ctag" tetapi dalam cuplikan shell yang digunakannya --with-exuberant-ctags=...saat ini mulai 2019 ada --with-universal-ctagsopsi. Haruskah itu diubah menjadi yang terakhir?
bgoodr
3

Saya belum benar-benar memeriksanya, tetapi menurut manual CEDET ( http://www.randomsample.de/cedetdocs/common/cedet/CScope.html ):

semantik dapat menggunakan CScope sebagai back end untuk pencarian database. Untuk mengaktifkannya, gunakan:

 (semanticdb-enable-cscope-databases)

Ini akan mengaktifkan penggunaan cscope untuk semua buffer C dan C ++.

CScope kemudian akan digunakan untuk pencarian di seluruh proyek sebagai cadangan ketika pencarian database semantik yang sudah ada mungkin belum mengurai semua file Anda.

Clément B.
sumber
1
Ini sepertinya tidak bekerja di Emacs 24.3.1, menggunakan vanilla CEDET 2.0 yang disertakan dengannya (tidak ada metode semanticdb-enable-cscope-databases).
Rob