Refactor code with Clang Format
Bài đăng này đã không được cập nhật trong 3 năm
Mở đầu
Như chúng ta đã biết, phần lớn việc tiếp xúc với code là để đọc hiểu. Do vậy, việc viết code như thế nào là rất quan trọng. Code không chỉ để chương trình chạy nhanh, chạy tốt, mà còn phải đảm bảo việc người đến sau có thể dễ dàng hiểu được code, tiết kiệm thời gian và công sức khi tiếp nhận dự án. Chính vì thế, trong các dự án, code convention đã dần dần trở thành điều bắt buộc để đảm bảo việc maintain cũng như phát triển code được thực hiện dễ dàng hơn.
Tuy vậy, không phải lúc nào code cũng do chúng ta code từ đầu. Với những dự án outsource thì việc phải code trên project có sẵn của khách hàng là điều thường xuyên. Việc refactor code lại theo chuẩn của công ty sẽ mất rất nhiều thời gian và công sức . Do vậy, hôm nay tôi sẽ giới thiệu cho các bạn một công cụ giúp chúng ta có thể hoàn thành việc đó một cách tự đông.
I. Giới thiệu Clang-Format cho Xcode
ClangFormat-Xcode Là một Xcode-plugin giúp cho việc reformat code của bạn có thể thực hiện một cách tự động, được phát triển bởi @travisjeffery
1. Cài đặt
1.1 Cài đặt qua source code của Clang-Format
- Clone Clang-Format repo
- Build project với Xcode.
- Uninstall
rm -r "~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/ClangFormat.xcplugin"
1.2 Cài đặt qua Alcatraz
Việc sử dụng Alcatraz sẽ giúp chúng ta dễ dàng tìm kiếm các plugin phù hợp cũng như quản lý nó một cách dễ dàng. Đơn giản bạn chỉ cần search tên plugin và bấm install.
Xcode > Windows > Package Manager (⌘⇧9) -> Search -> Install
Restart Xcode, khi chạy, Xcode sẽ hỏi xem bạn có muốn load bundle không, chọn Load Bundle
II. Refactor code với Clang-Format
1. Sử dụng Clang-Format
Với Clang-Format chúng ta có thể format 1 đoạn text, 1 file hoặc 1 list file tùy thuộc vào nhu cầu của chúng ta trong việc refactor code.
Để sử dụng chúng tiện lợi hơn, bạn có thể cài đặt short cut cho các menu này để tiện sử dụng
System Preferences > Keyboard > Shortcuts > App Shortcuts > Click +
Application : Xcode
Menu title : Tên chính xác của Menu, ví dụ : "Format File in Focus"
""
Clang Format đã cung cấp sẵn cho chúng ta 5 styles code là LLVM, Google, Chromium, Mozilla và WebKit
Đơn giản bạn chỉ cần Edit > Clang Format > lựa chọn 1 trong 5 styles đó -> Format code -> Done
Việc sử dụng Clang-Format với sự support tận tình như vậy là quá dễ dàng. Tuy vậy, với mỗi công ty, hay thậm chí với các dự án khác nhau, format code được tùy biến đi rất nhiều nên không phải 5 styles này, mà chính là styles custom của bạn mới là thứ chúng ta quan tâm nhất.
2. Custom Clang-Format styles
Khi bạn chọn Edit > Clang Format > File, Clang-Format sẽ tự động tìm kiếm file .clang-format
trong folder gần file mà bạn đang làm việc nhất. Do vậy, thông thường, chúng ta sẽ đặt file .clang-format
ở thư mục root của project (workspace).
Tuy vậy, trong hệ điều hành Mac, các file có tên với dấu . ở trước sẽ bị xem như là một file hệ thống và bị ẩn. Nếu không muốn như vậy, bạn có thể sử dụng tên file là _clang-format
để thay thế
2.1 Cấu trúc file .clang-format
.clang-format
file sử dụng YAML format
#comment.
key1: value1
key2: value2
Để tham khảo tài liệu về một file .clang-format
đầy đủ option bạn có thể xem ở đây
2.2 Custom .clang-format file
Việc cấu hình 1 file .clang-format bao gồm rất nhiều options nên tôi chỉ trình bày qua một số trường quan trọng, và chỉ trong phạm vi ngôn ngữ Objective-C nhé
Language: Cpp
dòng này là bắt buộc để Clang-Format nhận diện ngôn ngữ Objective-C
AllowShortFunctionsOnASingleLine : bool
AllowShortIfStatementsOnASingleLine : bool
AllowShortLoopsOnASingleLine : bool
Các dòng này để xác định việc có cho phép ghép dòng code ngay trên cùng 1 dòng không
BreakBeforeBraces
dòng này sẽ cho chúng ta cài đặt kiểu break trước dấu { vốn là cái mà chúng ta sử dụng rất nhiều trong objective C khi sử dụng các hàm if/else/switch ...
TabWidth: integer
UseTab: Never
2 dòng này thường không có tác dụng vì Xcode sẽ nhận setting phần "Indentation" thay cho 2 dòng này
IndentWidth : integer
ContinuationIndentWidth : integer
Xác định chiều rộng của indent
ColumnLimit : integer
Nếu dòng lệnh vượt quá giá trị của dòng này, nó sẽ được break line tự động
ObjCSpaceAfterProperty : bool
nếu bằng true chúng ta sẽ có kết quả @property (nonatomic)
thay vì @property(nonatomic)
ObjCSpaceBeforeProtocolList : bool
nếu bằng true chúng ta sẽ có Class <Protocol>
thay cho Class<Protocol>
3.Một số vấn đề
Sử dụng Clang Format để refactor code là rất tuyệt, tuy vậy, nó vẫn còn 1 số vấn đề khiến chúng ta cảm thấy phiền phức
1. Vấn đề về việc tự động xuống dòng theo dấu :
Có một điều rất hay gặp khi code objective C là khi bạn xuống dòng trong 1 hàm, Apple sẽ hỗ trợ tự động cho bạn việc căn chỉnh các dòng theo dấu : như sau
[[self alloc] initWithCode:nil
name:@"すべての駅を選択"
checkable:YES
expandable:NO
dataType:PassDataTypeCellCheckAllData];
Đối với 1 số người, việc hỗ trợ này lại là điều làm họ cảm thấy khó chịu . Một hàm objective C thường khá dài do đó tạo cảm giác bị hụt ra phía sau khi đọc code
[tableView dequeueReusableCellWithIdentifier:@"Cell Identifier"
forIndexPath:indexPath];
Tuy vậy, Clang Format lại fix cứng tính năng này nên chúng ta không thể tìm thấy việc custom nó ở đâu cả
Giải pháp ư, có đây nhưng có vẻ hơi rắc rối đấy
2. Clang Format Swift
Rõ ràng, việc sử dụng Swift đang ngày một trở nên phổ biến, và Clang Format lại không nhận ra điều này .
Để hỗ trợ việc này chúng ta có thể sử dụng Swift Format để thay thế, tuy nhiên việc sử dụng nó cũng khá là bất tiện vì phải chạy trên terminal và format của nó đã bị fix cứng trong file format.py
Kết
Trên đây, tôi đã giới thiệu một công cụ giúp việc refactor code trở nên dễ dàng hơn . Tuy trong phạm vi bài viết chỉ nêu các cách cài đặt cũng như cấu hình cho Objective C nhưng Clang Format
hoàn toàn có thể dùng để hỗ trợ việc refactor cho các ngôn ngữ khác như Java, C++. Tuy rằng Clang Format
còn một vài hạn chế nhưng tôi tin rằng với sự tùy biến mà nó mang lại, việc refactor code sẽ trở nên dễ dàng và thuận lợi hơn rất nhiều
All rights reserved