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文件
- 从 JetBrains Plugin Repository 下载
- 从 Github release page 下载(可能不是最新版本)
- 从QQ群文件下载(最新版首先在群内发布测试,群号:29850775 )
警告
无需解压Zip文件
-
选择菜单 File -> Settings -> Plugins -> Install
- 选择刚下载的EmmyLua.zip文件,安装完毕重启IDEA
4.设置lua工程
先随便创建一个空工程,为了就是进去后设置
选择你的Lua工程根目录
5.读取lua文件,忽略meta文件
也是settings,xlua需要读的txt,可自行设置,不需要不设置也行
下面还有个忽略文件列表,没有图了,上面写上 *.meta; 即可
6.界面白色太辣眼睛,调整为黑色
File---settings
7.字体太小了
File---settings
8.添加unity的api提示
File---Project Structure
点 加号 按钮
找到unity的 UnityEngine.dll 这个
我用的unity 2018 位置在 D:\Unity2018\Editor\Data\Managed
不同unity版本的文件位置不一样
(这种添加dll,就会有相应的代码提示,感觉添加fairygui的dll也可以有fairygui的代码提示)
9.忽略大小写,为了调用api的提示方便
File---settings 红圈位置取消即可
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类声明注解
- 完整格式:
aaa@qq.com MY_TYPE[:PARENT_TYPE] [@comment]
-
应用目标:
- local 变量
- global 变量
- 示例:
|
|
- 示例说明:
将 cls 变量标记为 Car 类,在其它地方可以使用 @type 注解来标记目标变量类型,以增强代码提示以及其它功能
@type类型标记注解
注解
利用 @type 注解来标记目标变量的类型,以增强代码提示以及其它功能
- 完整格式:
aaa@qq.com MY_TYPE[|OTHER_TYPE] [@comment]
-
应用目标:
- local 变量
|
|
-
- global 变量
|
|
-
- property 属性
|
|
@alias 别名注解
注解
可以使用 @alias 将一些复杂不容易输入的类型注册为一个新的别名
- 完整格式:
aaa@qq.com NEW_NAME TYPE
- 示例
- aaa@qq.com Handler fun(type: string, data: any):void
- aaa@qq.com handler Handler
- function addHandler(handler)
end
@param参数类型标记注解
注解
利用 @param 注解来标记函数定义参数的类型,以增强代码提示以及其它功能
@return 函数返回值注解
注解
利用 @return 注解来标记函数的返回值类型
- 完整格式:
---@return MY_TYPE[|OTHER_TYPE] [@comment]
-
应用目标:
- 函数
1 2 3 4 5 6 7 |
aaa@qq.com 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 |
aaa@qq.com Car function factory:create() ... end |
@field 属性注解
注解
利用 @field 注解来标记某个类的额外的属性(即使这个属性没有出现在代码里)
- 完整格式:
aaa@qq.com [public|protected|private] field_name FIELD_TYPE[|OTHER_TYPE] [@comment]
-
应用目标:
- 在 @class 注解之后
|
|
@generic 泛型注解
注解
利用 @generic 注解来模拟高级语言中的 泛型
- 完整格式:
aaa@qq.com T1 [: PARENT_TYPE] [, T2 [: PARENT_TYPE]]
-
应用目标:
- function
- 示例:
|
|
@vararg 不定参数注解
注解
使用 @vararg 注解一个函数的不定参数部分的类型
- 完整格式:
aaa@qq.com TYPE
- 示例
- aaa@qq.com string
- aaa@qq.com string
- local function format(...)
- local tbl = { ... } -- inferred as string[]
end
@language内嵌语言
注解
可以利用 @language 的方式来标注一段文本为某种代码格式,从而可以显示高亮
- 完整格式:
aaa@qq.com LANGUAGE_ID
- 示例:
|
|
- 效果:
数组类型
注解
可以利用 MY_TYPE[] 的方式来标注一个数据类型为数组
- 完整格式:
aaa@qq.com MY_TYPE[]
- 示例:
|
|
字典类型
注解
可以利用 table<KEY_TYPE,
VALUE_TYPE> 的方式来标注一个数据类型为字典
- 完整格式:
aaa@qq.com table<KEY_TYPE, VALUE_TYPE>
- 示例:
|
|
函数类型
注解
可以利用 fun(param:MY_TYPE):RETURN_TYPE 的方式来标注一个数据类型为函数
- 完整格式:
aaa@qq.com fun(param:MY_TYPE):RETURN_TYPE
- 示例:
|
|
字面量类型
注解
字面量类型(String literal types)允许你指定字符串作为固定的代码提示,结合 @alias 特性可以起到类似“枚举”的效果
- 示例
- aaa@qq.com Handler fun(type: string, data: any):void
- aaa@qq.com event string | "'onClosed'" | "'onData'"
- aaa@qq.com handler Handler | "function(type, data) print(data) end"
- function addEventListener(event, handler)
end
注解
建议使用 @alias 简化类型复杂度
aaa@qq.com Handler fun(type: string, data: any):void
aaa@qq.com IOEventEnum string | "'onClosed'" | "'onData'"
aaa@qq.com event IOEventEnum
aaa@qq.com handler Handler | "function(type, data) print(data) end"
function addEventListener(event, handler)
end
@see 引用
注解
可以利用 see 的注解来标注一个引用
完整示例
|
|
运行与调试
准备
注解
必须将源码的根目录设置为 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
- 选择目标程序
- 注意控制台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
- 点击 + 选择并创建 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
推荐阅读