EmmyLua的安裝與使用

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

官方文檔   https://emmylua.github.io/zh_CN/

github      https://github.com/EmmyLua/IntelliJ-EmmyLua

1.安裝IntelliJ IDEA Community Edition 2018.2.4 x64

官網地址 http://www.jetbrains.com/idea/download/#section=windows

直接下載即可,下載 Community 版本,也就是社區版,免費的

這個原本是寫java的,安裝過程中一些選項直接無視即可

2.下載Lua For Windows

https://github.com/rjpcomputing/luaforwindows/releases

下載最新的就行,然後安裝

3.安裝emmylua插件

安裝插件有2種方法,我用的是直接搜的插件庫安裝的,其他方法,參照官方文檔

  • Open settings panel.

  • Select plugins and click Browse repositories

  • 搜索 EmmyLua 並點擊 Install 安裝

  • 安裝完畢重啓IDEA

從zip文件安裝

警告

無需解壓Zip文件

  • 選擇菜單 File -> Settings -> Plugins -> Install plugin from disk
  • 選擇剛下載的EmmyLua.zip文件,安裝完畢重啓IDEA

4.設置lua工程

先隨便創建一個空工程,爲了就是進去後設置

https://img2018.cnblogs.com/blog/1137923/201809/1137923-20180919102733415-119818846.png

選擇你的Lua工程根目錄

5.讀取lua文件,忽略meta文件

也是settings,xlua需要讀的txt,可自行設置,不需要不設置也行

https://img2018.cnblogs.com/blog/1137923/201809/1137923-20180920174451768-694202207.png

 下面還有個忽略文件列表,沒有圖了,上面寫上 *.meta; 即可

6.界面白色太辣眼睛,調整爲黑色

File---settings

https://img2018.cnblogs.com/blog/1137923/201809/1137923-20180919102921156-1535387953.png

7.字體太小了

File---settings

https://img2018.cnblogs.com/blog/1137923/201809/1137923-20180919103115974-2069030723.png

8.添加unity的api提示

File---Project Structure

https://img2018.cnblogs.com/blog/1137923/201809/1137923-20180919103237211-1041191255.png

點 加號 按鈕

https://img2018.cnblogs.com/blog/1137923/201809/1137923-20180919103254583-2047340437.png

找到unity的 UnityEngine.dll 這個

我用的unity 2018 位置在 D:\Unity2018\Editor\Data\Managed 

不同unity版本的文件位置不一樣

(這種添加dll,就會有相應的代碼提示,感覺添加fairygui的dll也可以有fairygui的代碼提示)

9.忽略大小寫,爲了調用api的提示方便

File---settings 紅圈位置取消即可

 https://img2018.cnblogs.com/blog/1137923/201809/1137923-20180919104034094-1680346009.png

10.使用註解

比如寫了如下代碼

local go;

然後在這一行代碼,按下alt 加 enter鍵

會出現一個create type annotation一個選項,再次回車

就可以給go命名類型了,直接輸入gameobject下面會有自動提示UnityEngine.GameObject類型,選中即可

那麼這個go就是UnityEngine.GameObject類型了

然後go. 就能點出unity的api方法了

註解功能是emmylua一個很強大的功能,更多的技巧參考官網

11.其他

①全局搜索

ctrl shift f 注意的快捷鍵沒有衝突

或者edit---find---find in path

或者參考這個  https://blog.csdn.net/gnail_oug/article/details/78281354

②整理代碼格式

code---reformat code

需要選中代碼  

ctrl + alt + L

 ③查看方法的具體實現

alt按住不放,然後鼠標點方法

④查看方法哪裏被調用

alt+F7

⑤代碼摺疊與復原

ctrl  shift -

ctrl  shift +

⑥去除波浪線,拼寫檢查

file-settings-editor-inspections

輸入框裏面輸入spelling-typo 這個關閉 即可

 

///////////////////////////////////////////////////////////////////////////////////////

/////////   EmmyLua for IntelliJ IDEA Document   /////////

@class類聲明註解

  • 完整格式:
--@class MY_TYPE[:PARENT_TYPE] [@comment]
  • 應用目標:
    • local 變量
    • global 變量
  • 示例:
1
2
3
4
5
---@class Car : Transport @define class Car extends Transport
local cls = class()

 
function cls:test()
end
  • 示例說明:

 cls 變量標記爲 Car 類,在其它地方可以使用 @type 註解來標記目標變量類型,以增強代碼提示以及其它功能

@type類型標記註解

註解

利用 @type 註解來標記目標變量的類型,以增強代碼提示以及其它功能

  • 完整格式:
---@type MY_TYPE[|OTHER_TYPE] [@comment]
  • 應用目標:
    • local 變量
1
2
3
4
5
6
---@type Car @instance of car
local car1 = {}

 
---@type Car|Ship @transport tools, car or ship. Since lua is dynamic-typed, a variable may be of different types
---use | to list all possible types
local transport = {}
    • global 變量
1
2
---@type Car @global variable type
global_car = {}
    • property 屬性
1
2
3
local obj = {}
---@type Car @property type
obj.car = getCar()

@alias 別名註解

註解

可以使用 @alias 將一些複雜不容易輸入的類型註冊爲一個新的別名

  • 完整格式:
---@alias NEW_NAME TYPE
  • 示例
  • ---@alias Handler fun(type: string, data: any):void
  •  
  • ---@param handler Handler
  • function addHandler(handler)
end

@param參數類型標記註解

註解

利用 @param 註解來標記函數定義參數的類型,以增強代碼提示以及其它功能

@return 函數返回值註解

註解

利用 @return 註解來標記函數的返回值類型

  • 完整格式:

---@return MY_TYPE[|OTHER_TYPE] [@comment]

  • 應用目標:
    • 函數

1

2

3

4

5

6

7

---@return Car|Ship

local function create()

    ...

end

 

---Here car_or_ship doesn't need @type annotation, EmmyLua has already inferred the type via "create" function

local car_or_ship = create()

1

2

3

4

---@return Car

function factory:create()

    ...

end

@field 屬性註解

註解

利用 @field 註解來標記某個類的額外的屬性(即使這個屬性沒有出現在代碼裏)

  • 完整格式:
---@field [public|protected|private] field_name FIELD_TYPE[|OTHER_TYPE] [@comment]
  • 應用目標:
    •  @class 註解之後
1
2
3
---@class Car
---@field public name string @add name field to class Car, you'll see it in code completion
local cls = class()

@generic 泛型註解

註解

利用 @generic 註解來模擬高級語言中的 泛型

  • 完整格式:
--@generic T1 [: PARENT_TYPE] [, T2 [: PARENT_TYPE]]
  • 應用目標:
    • function
  • 示例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
---@generic T : Transport, K
---@param param1 T
---@param param2 K
---@return T
local function test(param1, param2)
    -- todo
end

 
---@type Car
local car = ...

 
local value = test(car)

@vararg 不定參數註解

註解

使用 @vararg 註解一個函數的不定參數部分的類型

  • 完整格式:
---@vararg TYPE
  • 示例
  • ---@vararg string
  • ---@return string
  • local function format(...)
  •     local tbl = { ... } -- inferred as string[]
end

@language內嵌語言

註解

可以利用 @language 的方式來標註一段文本爲某種代碼格式,從而可以顯示高亮

  • 完整格式:
---@language LANGUAGE_ID
  • 示例:
1
2
3
4
---@language JSON
local jsonText = [[{
    "name":"Emmy"
}]]
  • 效果:

數組類型

註解

可以利用 MY_TYPE[] 的方式來標註一個數據類型爲數組

  • 完整格式:
---@type MY_TYPE[]
  • 示例:
1
2
3
4
5
6
7
8
9
---@type Car[]
local list = {}

 
local car = list[1]
-- car. and you'll see completion

 
for i, car in ipairs(list) do
    -- car. and you'll see completion
end

字典類型

註解

可以利用 table<KEY_TYPE, VALUE_TYPE> 的方式來標註一個數據類型爲字典

  • 完整格式:
---@type table<KEY_TYPE, VALUE_TYPE>
  • 示例:
1
2
3
4
5
6
7
8
9
---@type table<string, Car>
local dict = {}

 
local car = dict['key']
-- car. and you'll see completion

 
for key, car in pairs(dict) do
    -- car. and you'll see completion
end

函數類型

註解

可以利用 fun(param:MY_TYPE):RETURN_TYPE 的方式來標註一個數據類型爲函數

  • 完整格式:
---@type fun(param:MY_TYPE):RETURN_TYPE
  • 示例:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
---@type fun(key:string):Car
local carCreatorFn1

 
local car = carCreatorFn1('key')
-- car. and you see code completion

 
---@type fun():Car[]
local carCreatorFn2

 
for i, car in ipairs(carCreatorFn2()) do
    -- car. and you see completion
end

字面量類型

註解

字面量類型(String literal types)允許你指定字符串作爲固定的代碼提示,結合 @alias 特性可以起到類似枚舉的效果

  • 示例
  • ---@alias Handler fun(type: string, data: any):void
  •  
  • ---@param event string | "'onClosed'" | "'onData'"
  • ---@param handler Handler | "function(type, data) print(data) end"
  • function addEventListener(event, handler)
end

註解

建議使用 @alias 簡化類型複雜度

---@alias Handler fun(type: string, data: any):void

---@alias IOEventEnum string | "'onClosed'" | "'onData'"

---@param event IOEventEnum

---@param handler Handler | "function(type, data) print(data) end"

function addEventListener(event, handler)

end

@see 引用

註解

可以利用 see 的註解來標註一個引用

完整示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
---@class Transport @parent class
---@public field name string
local transport = {}

 
function transport:move()end

 
---@class Car : Transport @Car extends Transport
local car = {}
function car:move()end

 
---@class Ship : Transport @Ship extends Transport
local ship = {}

 
---@param type number @parameter type
---@return Car|Ship @may return Car or Ship
local function create(type)
-- ignored
end

 
local obj = create(1)
---now you can see completion for obj

 
---@type Car
local obj2
---now you can see completion for obj2

 
local list = { obj, obj2 }
---@param v Transport
for _, v in ipairs(list) do
---not you can see completion for v
end

運行與調試

準備

註解

必須將源碼的根目錄設置爲 Sources 目錄。

具體做法是打開菜單 File -> Project Structure 打開 Project Structure 設置面板,點擊右側的 Add Content Root 來添加你的源碼根目錄,然後點擊 Mark as Sources 標記。

開始調試

Attach Debug 附加調試

提示

附加調試目前只能在 Windows 平臺上使用,可以附加到32位和64位應用程序,因附加調試需將EmmyLua的調試模塊 LuaInject.dll 注入到被調試程序進程中,一些殺毒軟件、某衛士可能會彈窗報警告,如果注入過程被攔截則會出現注入失敗的錯誤,導致調試失敗。所以一定要選擇放行或信任。

註解

Attach Debug 目前處於實驗階段,不穩定。如果經常出現被調試程序崩潰的情況請改使用Remote方式調試。如若能提供重現崩潰BUG的工程是最好不過了

1. 執行步驟

  • 運行目標程序,打開IDEA菜單 Run -> Attach to Local Process...

  • 選擇目標程序

  • 注意控制檯LOG,出現下圖LOG表明附加成功

  • 然後就可以在源碼中添加斷點進行調試了

2. 失敗相關問題排查

  • 斷點無效, IDEA控制檯窗口出現 xxx not found 日誌

請確認 Sources 目錄設置正確

  • 附加到目標程序失敗,出現 Error: LuaInject.dll could not be loaded into the process

檢查是否被殺軟、安全衛士攔截了注入過程

Remote Debug 遠程調試

提示

說明:遠程調試通信基於socket,內核基於mobdebug.lua ,依賴於luasocket模塊,所以被調試的程序需要支持luasocket

遠程調試要先啓動,再啓動目標程序

1. 執行步驟

  • 配置Remote調試設置,點擊右上角 Edit Configurations

  • 點擊 + 選擇並創建 Lua Remote(Mobdebug) 配置


設置好相關參數後點擊OK

  • 點擊右上角debug按鈕

  • 注意IDEA控制檯LOG輸出,如下圖所示表示啓動

  • 下載 mobdebug.lua 並在目標程序的lua代碼入口處添加代碼

1

require("mobdebug").start()

或者

1

require("mobdebug").start("host-ip", port) --默認值爲 "localhost", 8172

  • 最後啓動目標程序,並注意IDEA控制檯窗口,出現下圖所示`Connected`則表示調試器連接成功並可以添加斷點並調試了

2. 失敗相關問題排查

  • 運行目標程序後控制檯並沒有出現`Connected`日誌
    • 確認目標程序包含luasocket模塊
    • 確認調試端口一致(默認是8172端口)
  • Connected 日誌有,但斷點無效
    • 檢查 Sources 目錄設置正確
    • 檢查目標程序在運行時提供的文件名與源碼文件的文件名一致(致少除了後綴名的前面的部分一致)

此項檢查快捷方式是在 mobdebug.lua 

1

local function has_breakpoint(file, line)

函數中打印輸出 file

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章