Tags cho Emacs: Mối quan hệ giữa thẻ etags, ebrowse, cscope, GNU Global và các thẻ ctags hoa lệ


102

Tôi làm việc trên các dự án C ++ và tôi đã xem qua hướng dẫn của Alex Ott về CEDET và các chủ đề khác về thẻ trong StackOverflow, nhưng tôi vẫn còn nhầm lẫn về cách Emacs giao tiếp với các hệ thống thẻ khác nhau này để tạo điều kiện tự động hoàn thành, tra cứu định nghĩa, điều hướng nguồn cơ sở mã hoặc xem trước các chuỗi doc.

  1. Sự khác biệt (ví dụ về tính năng) giữa là gì etags, ebrowse, exuberant ctags, cscope, GNU GlobalGTags? Tôi cần làm gì để sử dụng chúng trong Emacs ?

  2. Tôi có cần ngữ nghĩa / thượng nghị sĩ (CEDET) nếu tôi muốn sử dụng thẻ để điều hướng / ký hiệu tự động hoàn thành không?

  3. Ngữ nghĩa mang lại gì cho bảng trên cùng của các tiện ích thẻ khác nhau này? Nó giao tiếp với những công cụ này như thế nào?


2
Đánh giá theo thân cây , GTagsdự án bạn liên kết đến khá chết. Nếu ai đó đang nói về gtags, có lẽ họ đang đề cập đến GNU Global.
Gordon Gustafson

Câu trả lời:


71

Đó là một câu hỏi hay như gần đây tôi đã đọc ở đây, vì vậy tôi sẽ cố gắng giải thích sự khác biệt chi tiết hơn:

Điểm 1:

etagsctagscả hai đều tạo tệp chỉ mục (còn gọi là thẻ / TAGS) của các đối tượng ngôn ngữ được tìm thấy trong tệp nguồn cho phép các mục này được định vị nhanh chóng và dễ dàng bằng trình soạn thảo văn bản hoặc tiện ích khác. Thẻ biểu thị một đối tượng ngôn ngữ mà mục nhập chỉ mục có sẵn (hoặc, cách khác, mục nhập chỉ mục được tạo cho đối tượng đó). Các thẻ được tạo bởi ctags phong phú hơn về mặt siêu dữ liệu, nhưng Emacs không thể giải thích dữ liệu bổ sung, vì vậy bạn nên coi chúng ít nhiều giống nhau (ưu điểm chính của ctagsnó là hỗ trợ nhiều ngôn ngữ hơn). Việc sử dụng chính cho các tệp thẻ là tìm kiếm khai báo / định nghĩa lớp / phương thức / hàm / hằng / etc.

cscopelà con thú mạnh mẽ hơn nhiều (ít nhất là về C / C ++ và Java có liên quan). Mặc dù nó hoạt động trên cùng một nguyên tắc (tạo một tệp siêu dữ liệu hữu ích), nó cho phép bạn thực hiện một số việc kỳ lạ hơn như tìm tất cả các tham chiếu đến một biểu tượng, xem vị trí một hàm đang được gọi, v.v. (bạn cũng có thể tìm thấy các định nghĩa) .

Tóm lại:

ctagsmột cho phép bạn điều hướng đến khai báo / định nghĩa ký hiệu (cái mà một số người gọi là tra cứu một chiều ). ctagslà một công cụ mục đích chung hữu ích cho nhiều ngôn ngữ.

Mặt khác (như đã đề cập trên trang của dự án) cscopecho phép bạn:

  • Đi tới phần khai báo của một ký hiệu
  • Hiển thị danh sách có thể chọn gồm tất cả các tham chiếu đến một biểu tượng
  • Tìm kiếm bất kỳ định nghĩa chung nào
  • Các hàm được gọi bởi một hàm
  • Các hàm gọi một hàm
  • Tìm kiếm một chuỗi văn bản
  • Tìm kiếm một mẫu biểu thức chính quy
  • Tìm một tập tin
  • Tìm tất cả các tệp bao gồm một tệp

Sẽ không có gì ngạc nhiên đối với bất kỳ ai vào thời điểm này, rằng khi tôi xử lý các dự án C / C ++, tôi sử dụng nhiều cscopevà rất ít quan tâm đến ctags. Khi xử lý các ngôn ngữ khác, tình hình rõ ràng sẽ được đảo ngược.

Điểm 2.

Để có tính năng tự động hoàn thành thông minh, bạn cần một trình phân tích cú pháp mã nguồn thực sự (như ngữ nghĩa), nếu không bạn sẽ không biết loại đối tượng (ví dụ) trong ứng dụng của mình và các phương thức có thể được gọi trên chúng. Bạn có thể có tự động hoàn thành dựa trên nhiều nguồn khác nhau, nhưng để có được kết quả tốt nhất, cuối cùng bạn sẽ cần trình phân tích cú pháp. Tương tự đối với tô sáng cú pháp - hiện tại tô sáng cú pháp trong các chế độ chính của Emacs chỉ đơn giản dựa trên các cụm từ thông dụng và điều đó rất mỏng manh và dễ xảy ra lỗi. Hy vọng rằng với việc bao gồm ngữ nghĩa trong Emacs 23.2 (nó từng là một gói bên ngoài trước đó), chúng ta sẽ bắt đầu thấy nhiều cách sử dụng hơn cho nó (như sử dụng nó để phân tích mã nguồn đệm để làm nổi bật nó một cách chính xác)

Vì ngữ nghĩa Emacs 24.1 có thể sử dụng được từ khung hoàn thành Emacs. Cách dễ nhất để kiểm tra nó là mở tệp mã nguồn C và nhập M-TABhoặc C-M-ivà xem như ngữ nghĩa hoàn thành tự động cho bạn. Đối với các ngôn ngữ mà ngữ nghĩa không được bật theo mặc định, bạn có thể thêm nó vào dòng sau vào móc chế độ chính mà bạn lựa chọn:

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

Điểm 3.

ngữ nghĩa mang lại nhận thức về mã thực sự (đối với một số ngôn ngữ mà nó hiện hỗ trợ) và thu hẹp khoảng cách giữa IDE và Emac. Nó không thực sự giao diện với các công cụ như etagscscope, nhưng không có nghĩa là bạn không thể sử dụng chúng cùng nhau.

Hy vọng rằng những giải thích của tôi có ý nghĩa và sẽ hữu ích cho bạn.

PS Tôi không quen lắm globalebrowse, nhưng nếu bộ nhớ phục vụ tôi, họ đã sử dụng etags.


1
Điều đó thật tuyệt. Cảm ơn! Bạn có biết làm thế nào tôi có thể sử dụng cscopetrong Emacs? Tôi đã đọc về xcscope.elEmacsWiki ở đây nhưng tôi không thể tìm thấy liên kết đến tệp. Ngoài ra, .elbạn sử dụng tệp nào để lấy cscopeEmacs?
Amelio Vazquez-Reina

1
xcscope.elnằm trong cscope/contrib/xcscope/(cái này nằm trong gói phân phối). Đó là những gì tôi sử dụng.
Bozhidar Batsov

Một câu hỏi nữa: Làm thế nào để semanticso sánh với cscope? Về điều hướng thông qua mã nguồn, ngữ nghĩa có cung cấp bất kỳ chức năng cscopenào không? Bạn có sử dụng cả hai?
Amelio Vazquez-Reina

4
Tôi không tin GNU Global sử dụng etags, btw. IIRC nó duy trì và truy vấn một cơ sở dữ liệu 'thích hợp' (thay vì quét một tệp văn bản phẳng), có nhiều lợi ích về hiệu suất cho cả truy vấn và (đặc biệt) để cập nhật các thẻ.
phils

@BozhidarBatsov Khi bạn nói For languages where semantic is not enabled by default, you can add the following line to your major mode hook of choice ... <code>. Đoạn mã đó chính xác làm gì?
Amelio Vazquez-Reina

45

Tôi sẽ cố gắng thêm một số giải thích cho 1.

Nó là gì?

  • Etags là một lệnh để tạo tệp 'TAGS' là tệp thẻ cho Emacs. Bạn có thể sử dụng tệp với etags.el là một phần của gói emacs.
  • Ctags là một lệnh để tạo tệp 'thẻ' là tệp thẻ cho vi. Bây giờ Exuberant Ctags có thể tạo tệp 'TAGS' bằng tùy chọn -e và hỗ trợ 41 ngôn ngữ lập trình.
  • Cscope là một công cụ duyệt mã nguồn tất cả trong một cho ngôn ngữ C. Nó có CUI riêng (giao diện người dùng ký tự) và cơ sở dữ liệu thẻ (cscope.in.out, cscope.out, cscope.po.out). Bạn có thể sử dụng cscope từ Emacs bằng cách sử dụng xcscope.el, một phần của gói cscope.
  • GNU GLOBAL là một hệ thống gắn thẻ mã nguồn. Mặc dù nó tương tự như các công cụ trên, nó khác chúng ở điểm nó phụ thuộc vào bất kỳ trình soạn thảo nào và nó không có giao diện người dùng ngoại trừ dòng lệnh. Gtags là lệnh tạo tệp thẻ cho GLOBAL (GTAGS, GRTAGS, GPATH). Bạn có thể sử dụng GLOBAL từ emacs bằng gtags.el là một phần của gói GLOBAL. Ngoài ra, có rất nhiều thư viện elisp cho nó (xgtags.el, ggtags.el, anything-gtags.el, helm-gtags.el, v.v.).

So sánh

  • Ctags và etags chỉ coi các định nghĩa. Cscope và GNU GLOBAL không chỉ xử lý các định nghĩa mà còn xem xét các tài liệu tham khảo.
  • Ctags và etags sử dụng tệp thẻ văn bản phẳng. Cscope và GNU GLOBAL sử dụng cơ sở dữ liệu thẻ khóa-giá trị.
  • Cscope và GNU GLOBAL có một công cụ tìm kiếm giống như công cụ tìm kiếm và cơ sở cập nhật gia tăng các tệp thẻ.

Sự phối hợp

Bạn có thể kết hợp hỗ trợ ngôn ngữ phong phú của Exuberant Ctags và cơ sở dữ liệu của GNU GLOBAL bằng cách sử dụng ctags như một trình phân tích cú pháp bổ trợ của GLOBAL.

Hãy thử những cách sau: (yêu cầu GLOBAL-6.0, Exuberant Ctags-5.5 trở lên tương ứng)

Xây dựng GNU GLOBAL:

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

Sử dụng:

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

(Tuy nhiên, bạn không thể xử lý các tham chiếu bằng phương pháp này vì thẻ ctags không xử lý các tham chiếu.)

Bạn cũng có thể sử dụng cscope làm ứng dụng khách của GNU GLOBAL. Gói GLOBAL bao gồm một lệnh có tên 'gtags-cscope' là một cổng của cscope, nghĩa là, chính nó là cscope ngoại trừ việc nó sử dụng GLOBAL làm công cụ tìm kiếm thay vì của cscope.

$ gtags-cscope          # this is GLOBAL version of cscope

Với sự kết hợp, bạn có thể sử dụng cscope cho 41 ngôn ngữ.

Chúc may mắn!


1
Đối với người dùng trên Debian và các dẫn xuất như Ubuntu: Trang web GNU GLOBAL cảnh báo rằng các gói .deb đi kèm với các bản phân phối Linux này đã lỗi thời và không nên được sử dụng. Trong trường hợp của tôi, GLOBAL ở phiên bản 5.7.1 và tôi không thể tải gtags.el, ggtags.el hoặc helm-gtags.el hoạt động bình thường trên Emacs 24. Biên dịch GNU GLOBAL 6.5 từ đầu, với sự hỗ trợ cho Exuberant Ctags ( Tôi đã sử dụng 5,8) đã làm việc một điều trị. (Cảm ơn vì những chỉ dẫn tuyệt vời, @shigio).
Rob

9

TAGS tệp chứa các định nghĩa

Một TAGStệp chứa danh sách các chức năng và lớp được xác định. Nó thường được đặt trong thư mục gốc của một dự án và trông giống như sau:

^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

Điều này cho phép Emacs tìm ra các định nghĩa. Điều hướng cơ bản được tích hợp sẵn find-tag, nhưng etags-selectcung cấp giao diện người dùng đẹp hơn khi có nhiều kết quả trùng khớp.

Bạn cũng có thể sử dụng tệp TAGS để hoàn thành mã. Ví dụ: chương trình phụ trợ etags của công ty sử dụng tệp TAGS .

TAGS tệp có thể được tạo bằng các công cụ khác nhau

ctags(trước đây được gọi là 'thẻ ctags phổ quát' hoặc 'thẻ ctags hoa lệ') có thể tạo tệp TAGS và hỗ trợ phạm vi ngôn ngữ rộng nhất. Nó được duy trì tích cực trên github.

Emacs cung cấp hai chương trình tạo tệp TAGS, được gọi là etagsctags. Emacs ' ctagschỉ etagsvới giao diện CLI giống như thẻ ctags phổ biến. Để tránh nhầm lẫn, nhiều bản phân phối đổi tên các chương trình này (ví dụ ctags.emacs24trên Debian).

Ngoài ra còn có các công cụ dành riêng cho ngôn ngữ để tạo tệp TAGS, chẳng hạn như jsctagshasktags.

Các định dạng tệp khác

ebrowselà một chương trình C được vận chuyển với Emacs. Nó lập chỉ mục mã C / C ++ và tạo một BROWSEtệp. ebrowse.el cung cấp định nghĩa và hoàn thành tìm kiếm thông thường. Bạn cũng có thể mở BROWSEtệp trực tiếp trong Emacs để có cái nhìn tổng quan về các lớp / hàm được xác định một cơ sở mã.

GNU toàn cầu có định dạng cơ sở dữ liệu riêng của mình, trong đó bao gồm một GTAGS, GRTAGSGPATHtập tin. Bạn có thể tạo các tệp này bằng gtagslệnh phân tích mã C / C ++. Đối với các ngôn ngữ khác, GNU Global có thể đọc các tệp được tạo bởi thẻ ctags chung.

GNU Global cũng cung cấp giao diện CLI để đặt những câu hỏi phức tạp hơn, như 'biểu tượng này được đề cập ở đâu?'. Nó đi kèm với gói Emacs gtags.el, nhưng ggtags.el cũng rất phổ biến để truy cập cơ sở dữ liệu GNU Global.

Cscope cũng tương tự như GNU Global: nó phân tích cú pháp C / C ++ thành định dạng cơ sở dữ liệu riêng. Nó cũng có thể trả lời các câu hỏi như 'tìm tất cả người gọi / người gọi của funciton này'.

Xem thêm phần thảo luận HN này so sánh global và cscope .

Dự án Máy khách / Máy chủ

rtags phân tích cú pháp và lập chỉ mục C / C ++ bằng máy chủ liên tục. Nó sử dụng trình phân tích cú pháp clang, vì vậy nó xử lý C ++ thực sự tốt. Nó đi kèm với một gói Emacs để truy vấn máy chủ.

google-gtags là một dự án trong đó tệp TAGS lớn sẽ được lưu trữ trên máy chủ. Khi bạn truy vấn máy chủ, nó sẽ cung cấp một tập hợp con của tệp TAGS có liên quan đến tìm kiếm của bạn.

Ngữ nghĩa (CEDET)

Semantic là một gói Emacs tích hợp có chứa trình phân tích cú pháp cho C / C ++, vì vậy nó cũng có thể tìm thấy các định nghĩa. Nó cũng có thể nhập dữ liệu từ tệp TAGS, cơ sở dữ liệu csope và các nguồn khác. CEDET cũng bao gồm chức năng kiểu IDE sử dụng dữ liệu này, ví dụ như tạo sơ đồ UML của các cấu trúc phân cấp lớp.


7

[câu trả lời được cập nhật từ shigio 's]

Tôi sẽ cố gắng thêm một số giải thích cho phần 1 của câu hỏi.

Nó là gì?

  1. Etags tạo một TAGStệp là định dạng tệp thẻ cho Emacs . Bạn có thể sử dụng tệp Etags etags.ellà một phần của Emacs.
  2. Ctagslà thuật ngữ chung cho bất kỳ thứ gì có thể tạo tagstệp, là định dạng tệp thẻ gốc cho Vi. Universal Ctags (hay còn gọi UCtagslà thẻ Exuberant Ctags) cũng có thể tạo Etags với -etùy chọn này.
  3. Cscope là một công cụ mã nguồn trình duyệt tất cả-trong-một cho C (với sự hỗ trợ ít hơn cho C ++ và Java), với cơ sở dữ liệu thẻ của riêng mình ( cscope.in.out, cscope.out, cscope.po.out) và TUI . Hỗ trợ Cscope được tích hợp sẵn trong Vim; bạn có thể sử dụng Cscope từ Emacs bằng gói xcscope.el . Ngoài ra còn có các GUI dựa trên Cscope .
  4. GNU GLOBAL (hay còn gọi làGtags ) là một hệ thống gắn thẻ mã nguồn khác (với sự khác biệt đáng kể - xem phần tiếp theo), trong đó nó cũng tạo ra các tệp thẻ.

So sánh

  • Ctags và Etags chỉ xử lý các định nghĩa (ví dụ, biến và hàm). Cscope và Gtags cũng xử lý tài liệu tham khảo.
  • Các tệp thẻ Ctags và Etags là phẳng . Các tệp thẻ Cscope và Gtags là các cơ sở dữ liệu khóa-giá trị mạnh mẽ hơn , cho phép (ví dụ) cập nhật gia tăng.
  • Cscope và Gtags có một grepcông cụ tìm kiếm giống như vậy.
  • Ctags có hỗ trợ tích hợp cho nhiều ngôn ngữ và định dạng dữ liệu hơn: xem danh sách bộ phân tích cú pháp Universal Ctags hiện có trong kho . UCtags cũng đã ghi lại cách phát triển trình phân tích cú pháp của riêng bạn .
  • Cscope và Gtags độc lập với trình biên tập.
  • Gtags không cung cấp giao diện người dùng riêng, nhưng hiện tại (tháng 10 năm 2016) có thể được sử dụng từ dòng lệnh (CLI), Emacs và người thân, Vi và người thân, less(máy nhắn tin), Doxygen và bất kỳ trình duyệt web nào.
  • Gtags cung cấp gtags.elthông qua gói GLOBAL, nhưng cũng có nhiều phần mở rộng elisp khác, bao gồm xgtags.el, ggtags.el, anything-gtags.el, helm-gtags.el.

Sự phối hợp

Bạn có thể kết hợp hỗ trợ ngôn ngữ đa dạng của Universal Ctags với cơ sở dữ liệu của Gtags và nhiều tiện ích mở rộng bằng cách sử dụng Ctags làm trình phân tích cú pháp plug-in TOÀN CẦU :

# 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

Một lần nữa lưu ý rằng nếu bạn sử dụng Ctags làm trình phân tích cú pháp cho Gtags của mình, bạn sẽ mất khả năng xử lý các tham chiếu (ví dụ: cách sử dụng biến, lệnh gọi hàm) mà Gtags sẽ cung cấp. Về cơ bản, bạn đánh đổi tính năng theo dõi tham chiếu của Gtags để có hỗ trợ ngôn ngữ tích hợp sẵn tốt hơn của Ctags.

Bạn cũng có thể sử dụng cscope như một khách hàng của Gtags: gtags-cscope.

Chúc may mắn!


Tôi đọc: "Xin lưu ý lại rằng nếu bạn sử dụng Ctags làm trình phân tích cú pháp cho Gtags của mình, bạn sẽ mất khả năng xử lý các tham chiếu (ví dụ: sử dụng biến, lệnh gọi hàm) mà Gtags sẽ cung cấp. Về cơ bản, bạn đánh đổi tính năng theo dõi tham chiếu của Gtags để Hỗ trợ ngôn ngữ tích hợp sẵn tốt hơn của Ctags. " Điều đó có đúng với các ctags cũ được vận chuyển cùng với Emacs hay vẫn đúng với Universal Ctags? Ngoài ra, tôi đã đọc "kết hợp ngôn ngữ đa dạng của Universal Ctag" nhưng trong đoạn mã shell mà nó sử dụng --with-exuberant-ctags=...khi tính đến năm 2019 có một --with-universal-ctagstùy chọn. Cái đó có nên được đổi thành cái sau không?
bgoodr

3

Tôi chưa thực sự kiểm tra, nhưng theo hướng dẫn sử dụng CEDET ( http://www.randomsample.de/cedetdocs/common/cedet/CScope.html ):

ngữ nghĩa có thể sử dụng CScope làm back end cho các tìm kiếm cơ sở dữ liệu. Để kích hoạt nó, hãy sử dụng:

 (semanticdb-enable-cscope-databases)

Điều này sẽ cho phép sử dụng cscope cho tất cả các bộ đệm C và C ++.

Sau đó, CScope sẽ được sử dụng cho các tìm kiếm trên toàn dự án như một bản sao lưu khi các tìm kiếm cơ sở dữ liệu ngữ nghĩa tồn tại từ trước có thể chưa phân tích cú pháp tất cả các tệp của bạn.


1
Điều này dường như không hoạt động trong Emacs 24.3.1, sử dụng CEDET 2.0 vani đi kèm với nó (không có phương pháp cơ sở dữ liệu semanticdb-enable-cscope-databases).
Rob
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.