原文地址:http://www.lm1024.xyz/?p=40
1、寫該腳本的原因
自從xcode8以后蘋果禁止使用插件后,以前用來格式化代碼的插件就不可使用了,雖然后來用Xcode Source Editor Extension寫了一個,但是插件有時候不穩(wěn)定,有出現(xiàn)插件不工作或者xcode啟動之后插件沒加載進來的情況,使用起來不方便。后來受這篇文章的啟發(fā)。能不能用AppleScript寫一個腳本配合clang-format來格式化項目代碼。
2、流程圖
說干就干,簡單的了解下appleScript 語法之后就開始擼代碼了。 appleScript很容易學(xué),簡單了解下就能寫出點東西。下面是流程圖:
3、使用automator建立一個workflow
workflow 圖片如下:
我的這個workflow有兩個模塊:
- 模塊一
on run {input, parameters}
(* Your script goes here *)
set formatFilePath to ""
tell application "Xcode"
set CurrentActiveDocument to document 1 whose name ends with (word -1 of (get name of window 1))
set fullPath to path of CurrentActiveDocument
set formatFilePath to fullPath as POSIX file
end tell
return formatFilePath
end run
這個模塊只做一件了一件事情, 從xcode中獲取當(dāng)前打開文件的路徑 然后講該文件的路徑傳遞給第二個模塊
- 模塊二
on run {input, parameters}
(* Your script goes here *)
formatFile(input)
return input
end run
on formatFile(filePath)
-- clang-format 工具目錄
set clangformat to "$HOME" & "/clang-format "
set clangStyle to " -i"
-- .clang-format 文件目錄
set shellString to "-assume-filename=" & "$HOME" & "/.clang-format "
set fileList to traversalFile(filePath)
tell application "Xcode"
repeat with pathString in fileList
set shellString to clangformat & shellString & pathString & clangStyle
tell me to do shell script shellString
end repeat
end tell
return true
end formatFile
on isDirectory(filePosixPath)
set diskPath to POSIX path of filePosixPath
set fileType to (do shell script "file -b " & diskPath)
set typeString to fileType as string
if typeString ends with "directory" then return true
return false
end isDirectory
on traversalFile(filePosixPath)
set fileList to {}
if (not isDirectory(filePosixPath)) then
set filePath to POSIX path of filePosixPath
if isCanFormatFile(filePath) then
set the end of fileList to filePath
end if
else
-- 文件夾 遍歷文件夾中所有符合要求的文件
set _item to (alias (filePosixPath))
set _list to list folder _item without invisibles
repeat with path in _list
set dir to POSIX path of filePosixPath
set filePath to dir & path
set posixFilePath to filePath as POSIX file
if (not isDirectory(posixFilePath)) then
if isCanFormatFile(filePath) then
set the end of fileList to filePath
end if
end if
end repeat
end if
return fileList
end traversalFile
on isCanFormatFile(filePath)
-- set filePathLength to the length of filePath
set formatArray to {".h", ".m", ".java", ".cs", ".cpp", ".mm", ".c"}
repeat with formatString in formatArray
if filePath ends with formatString then
return true
end if
end repeat
return false
end isCanFormatFile
模塊二一共五個方法:
-
on run {input, parameters}
方法 相當(dāng)于模塊二的main方法,模塊一執(zhí)行結(jié)束后會執(zhí)行模塊二的run
方法,參數(shù)input
是由模塊一種run
執(zhí)行結(jié)束后 return的值 -
on formatFile(filePath)
為自己寫的格式化代碼函數(shù) -
on isDirectory(filePosixPath)
函數(shù)用來判斷一個文件路徑是文件夾還是文件。 -
on traversalFile(filePosixPath)
函數(shù)用來遍歷摸個路徑下的所用文件,現(xiàn)在還不能深層遍歷文件夾,后續(xù)會改進。 -
on isCanFormatFile(filePath)
函數(shù)判斷文件是否支持格式化。這里只是簡單的判斷了下文件后綴。
4、使用
1、在automator上面調(diào)試好腳本后(腳本可以用visual studio編寫和進行第一步調(diào)試,測試通過后然后放在automator中調(diào)試),導(dǎo)出成workflow文件。
2、點擊到處文件,安裝workflow。然后重新啟動xcode此時會發(fā)現(xiàn) xcode->services下面多了個xcode-codeForamt的服務(wù)
3、然后把我們的 clang-format文件和.clang-format文件放到電腦根目錄下
為什么選擇放入到該目錄下面。因為該目錄是可以通過 $HOME 來獲取的。這樣不需要修改腳本代碼就能給組里面的人使用。
4、為了方便我們可以在鍵盤->快捷鍵
里面設(shè)置一個快捷鍵,用來啟動該服務(wù)。
寫在最后
appleScript腳本簡單易懂,想學(xué)習(xí)可以去找《AppleScript.pdf》這本書,一兩天就能看完。
源碼地址 里面有測試的源碼和我做好的可使用的一個workflow。 安裝后 講clang-format 和 .clang-format文件放到指定的位置就能使用了。