Làm thế nào để gọi định dạng clang qua một thư mục dự án cpp?


87

Có cách nào để gọi một cái gì đó giống như clang-format --style=Webkitcho toàn bộ thư mục dự án cpp, thay vì chạy nó riêng biệt cho từng tệp không?

Tôi đang sử dụng clang-format.pyvimđể làm điều này, nhưng tôi cho rằng có một cách để áp dụng điều này một lần.

Câu trả lời:


46

Thế còn:

clang-format -i -style=WebKit *.cpp *.h

trong thư mục dự án. Tùy chọn -i làm cho nó ở vị trí (theo định dạng mặc định đầu ra được ghi vào stdout).


1
hoặc nếu bạn đang sử dụng một tập tin cấu hình và muốn định dạng nhiều loại tập tin: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
mBardos

42
Thật không may, điều đó sẽ không tái diễn vào các thư mục con.
Antimony

4
Có, * .cpp sẽ được mở rộng bởi shell. clang chỉ cần một danh sách các tập tin. Các tùy chọn nâng cao hơn (như đánh bóng đệ quy) phụ thuộc vào các tính năng của shell của bạn. Xem unix.stackexchange.com/questions/49913/recursive-glob về cách sử dụng **cấu trúc.
sbarzowski

Còn với clang-tidythì sao?
Aaron Franke

@AaronFranke Sử dụng *.cppđể tạo danh sách các tệp sẽ hoạt động. Các clang-tidylệnh cho phép đi qua nhiều file. `USAGE: clang-lift [options] <source0> [... <sourceN>]` Tuy nhiên, trong thực tế, đó có thể không phải là cách tốt nhất. Clang-lift thực hiện phân tích sâu hơn nhiều, vì vậy nó yêu cầu các cờ trình biên dịch cho mỗi tệp, v.v. Khi tôi sử dụng clang-lift, tôi thường có "cơ sở dữ liệu biên dịch" - một tệp JSON với các lệnh cho mỗi tệp và một số tập lệnh. qua nó. Đó là một vài năm trở lại, có lẽ có một cách tốt hơn bây giờ.
sbarzowski

85

Thật không may, không có cách nào để áp dụng định dạng clang một cách đệ quy. *.cppsẽ chỉ khớp với các tệp trong thư mục hiện tại, không phải thư mục con. Thậm chí **/*không hoạt động.

May mắn thay, có một giải pháp: lấy tất cả các tên tệp bằng findlệnh và đưa chúng vào. Ví dụ: nếu bạn muốn định dạng tất cả .h.cppcác tệp trong thư foo/bar/mục một cách đệ quy, bạn có thể làm

find foo/bar/ -iname *.h -o -iname *.cpp | xargs clang-format -i

Xem ở đây để thảo luận thêm.


6
Vâng, **/*.cppcó vẻ như hoạt động trong bash (hợp lý hiện đại). Bạn có thể cần phải làm shopt -s globstartrước đó.
sbarzowski

1
Nếu bạn đang sử dụng CMake, bài đăng này chỉ cho bạn cách bạn có thể sử dụng CMake GLOB_RECURSEđể tìm tất cả .cppcác tệp và chuyển chúng đến clang-format.
phượng hoàng

5
Sự kết hợp của findxargsnên sử dụng find ... -print0xargs -0 ...để đảm bảo rằng tất cả các loại tên tệp được xử lý chính xác.
Alexander

4
Lệnh này không thành công nếu có bất kỳ tệp .cpp hoặc .h nào tồn tại trong pwd. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -isẽ khắc phục sự cố.
nyanpasu64,

27

Đầu tiên hãy tạo một .clang-formattệp nếu nó không tồn tại:

clang-format -style=WebKit -dump-config > .clang-format

Chọn bất kỳ kiểu định sẵn nào bạn thích hoặc chỉnh sửa .clang-formattệp kết quả .

cấu hình định dạng clang rất hữu ích.

Sau đó chạy:

find . -regex '.*\.\(cpp\|hpp\|cc\|cxx\)' -exec clang-format -style=file -i {} \;

Phần mở rộng tập tin khác hơn cpp, hpp, cccxxcó thể được sử dụng trong các biểu thức chính quy, chỉ cần đảm bảo để tách chúng bằng \|.


Đối với -style=filecó cách nào để chỉ định một đường dẫn tệp tùy chỉnh? Tôi đã thử -style=~/.clang-formatvà nó không hoạt động.
Aaron Franke

Tôi không biết điều đó, ngoài việc thay đổi thư mục hiện tại.
Alexander

Giải pháp dành cho khu ổ chuột mà tôi nghĩ ra là tạo một hàm chạy trước cp ~/.clang-format .rồi đến lệnh tìm trong câu trả lời của bạn.
Aaron Franke

12

Gần đây tôi đã tìm thấy một tập lệnh bash thực hiện chính xác những gì bạn cần:

https://github.com/eklitzke/clang-format-all

Đây là một tập lệnh bash sẽ chạy clang-format -itrên mã của bạn.

Đặc trưng:

  • Tìm đường dẫn phù hợp đến clang-formattrên Ubuntu / Debian, mã hóa phiên bản LLVM trong clang-formattên tệp
  • Sửa các tệp một cách đệ quy
  • Phát hiện các phần mở rộng tệp phổ biến nhất được sử dụng bởi các dự án C / C ++

Trên Windows, tôi đã sử dụng nó thành công trong Git Bash và WSL.


3

Đối với người dùng Windows: Nếu bạn có hỗ trợ Powershell 3.0, bạn có thể thực hiện:

Get-ChildItem -Path . -Directory -Recurse |
    foreach {
        cd $_.FullName
        &clang-format -i -style=WebKit *.cpp
    }

Lưu ý1: Sử dụng pushd .popdnếu bạn muốn có cùng một thư mục hiện tại trước và sau tập lệnh

Lưu ý 2: Tập lệnh hoạt động trong thư mục làm việc hiện tại

Lưu ý 3: Điều này có thể được viết trong một dòng nếu điều đó thực sự quan trọng đối với bạn


0

Tôi đang sử dụng lệnh sau để định dạng tất cả các tệp mục tiêu C trong thư mục hiện tại một cách đệ quy :

$ find . -name "*.m" -o -name "*.h" | sed 's| |\\ |g' | xargs clang-format -i

Tôi đã xác định bí danh sau trong của mình .bash_profileđể giúp mọi thứ dễ dàng hơn:

# Format objC files (*.h and *.m) under the current folder, recursively
alias clang-format-all="find . -name \"*.m\" -o -name \"*.h\" | sed 's| |\\ |g' | xargs clang-format -i"

0

Đây là một giải pháp tìm kiếm đệ quy và chuyển tất cả các tệp sang định dạng clang dưới dạng danh sách tệp trong một lệnh. Nó cũng loại trừ thư mục "xây dựng" (tôi sử dụng CMake), nhưng bạn chỉ có thể bỏ qua bước "grep" để loại bỏ điều đó.

shopt -s globstar extglob failglob && ls **/*.@(h|hpp|hxx|c|cpp|cxx) | grep -v build | tr '\n' ' ' | xargs clang-format -i

0

Trong bash hiện đại, bạn có thể thu thập dữ liệu một cách đệ quy cây tệp

for file_name in ./src/**/*.{cpp,h,hpp}; do
    if [ -f "$file_name" ]; then
        printf '%s\n' "$file_name"
        clang-format -i $file_name
    fi
done

Ở đây nguồn được giả định là nằm trong ./src.clang-formatchứa thông tin định dạng.


Tôi không nghĩ rằng sao cầu được bật theo mặc định trong bash, vì vậy bạn cần phải đặt nó.
Eric Backus
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.