Skip to content

Instantly share code, notes, and snippets.

@SmileYzn
Last active September 23, 2023 13:47
Show Gist options
  • Save SmileYzn/62c102c69cb71c7b50dbfb4fecaefd28 to your computer and use it in GitHub Desktop.
Save SmileYzn/62c102c69cb71c7b50dbfb4fecaefd28 to your computer and use it in GitHub Desktop.
A complete Lite-XL plugin for AMX Mod X build, syntax, auto-completetion and more
-- mod-version:3
--
-- Core requirements
local core = require("core")
local common = require("core.common")
local config = require("core.config")
local command = require("core.command")
local doc = require("core.doc")
local docView = require("core.docview")
local translate = require("core.doc.translate")
local keymap = require("core.keymap")
local rootView = require "core.rootview"
local style = require("core.style")
local syntax = require("core.syntax")
local tokenizer = require("core.tokenizer")
local view = require("core.view")
--
-- Plugins requirements
local console = require("plugins.console")
local settings = require("plugins.settings")
--
-- Settings of plugin
--
-- Plugin Settings
config.plugins.amxx = common.merge
({
--
-- Compiler Path
compiler_path = "",
--
-- Compiler include path
include = "include",
--
-- Compiler executable name
compiler = "amxxpc.exe",
--
-- Plugin output extension
extension = "amxx",
--
-- Plugin extra output folder
output = "",
--
-- Save current document on compile command
save = true,
--
-- Clear console output before each execution
clear = true,
--
-- The config specification used by the settings gui
config_spec =
{
--
-- Setting Label
name = "AMX Mod X Compiler",
--
-- Compiler Path
{
label = "AMX Mod X compiler folder",
description = "Folder of AMX Mod X compiler",
path = "compiler_path",
type = "directory",
default = ""
},
--
-- Compiler include path name
{
label = "AMX Mod X name of 'include' folder",
description = "Name of 'include' folder",
path = "include",
type = "string",
default = "include"
},
--
-- Compiler executable name
{
label = "AMX Mod X compiler executable",
description = "Name of compiler executable",
path = "compiler",
type = "string",
default = "amxxpc.exe"
},
--
-- Plugin output extension
{
label = "AMX Mod X output extension",
description = "Extension of output file (plugin)",
path = "extension",
type = "string",
default = "amxx"
},
--
-- Plugin extra output folder
{
label = "Copy plugin to specific path",
description = "Path to copy result plugin",
path = "output",
type = "directory",
exists = true,
default = ""
},
--
-- Save current document on compile command
{
label = "Save current document on compile",
description = "Save current document before compile command",
path = "save",
type = "boolean",
default = true
},
--
-- Clear console output before each execution
{
label = "Clear output before each execution",
description = "Clear output before each execution",
path = "clear",
type = "boolean",
default = true
},
}
}, config.plugins.amxx)
--
-- Language syntax table
local language_syntax =
{
--
-- Name
name = "amxx",
--
-- File extensions
files = { "%.sma$", "%.inc$" },
--
-- Comment line
comment = "//",
--
-- Comment block
block_comment = {"/*", "*/"},
--
-- Handle spaces ?
space_handling = true,
--
-- Set language patterns
patterns =
{
--
-- Comment Line
{pattern = "//.*", type = "comment"},
--
-- Comment block
{pattern = {"/%*", "%*/"}, type = "comment"},
--
-- String double quotes
{pattern = {'"', '"', "^"}, type = "string"},
--
-- String single quotes
{pattern = {"'", "'", "^"}, type = "string"},
--
-- Hexadecimal
{pattern = "0x%x+", type = "number"},
--
-- Float
{pattern = "%d+[%d%.eE]*f?", type = "number"},
--
-- Numbers
{pattern = "%.?%d+f?", type = "number"},
--
-- Operators
{pattern = "[%+%-=/%*%^%%<>!~|&]", type = "operator"},
--
-- Method type declarations
{pattern = "native%s()[%a_][%w_]*", type = {"keyword", "function"}},
{pattern = "forward%s()[%a_][%w_]*", type = {"keyword", "function"}},
{pattern = "public%s()[%a_][%w_]*", type = {"keyword", "function"}},
{pattern = "stock%s()[%a_][%w_]*", type = {"keyword", "function"}},
--
-- Static declarations
{pattern = "static()%s+()inline", type = { "keyword", "normal", "keyword"}},
{pattern = "static()%s+()const", type = { "keyword", "normal", "keyword"}},
{pattern = "static()%s+()[%a_][%w_]*", type = { "keyword", "normal", "literal"}},
--
-- Match function type declarations
{pattern = "[%a_][%w_]*()%*+()%s+()[%a_][%w_]*%f[%(]", type = { "literal", "operator", "normal", "function"}},
{pattern = "[%a_][%w_]*()%s+()%*+()[%a_][%w_]*%f[%(]", type = { "literal", "normal", "operator", "function"}},
{pattern = "[%a_][%w_]*()%s+()[%a_][%w_]*%f[%(]", type = { "literal", "normal", "function"}},
--
-- Match variable type declarations
{pattern = "[%a_][%w_]*()%*+()%s+()[%a_][%w_]*", type = { "literal", "operator", "normal", "normal"}},
{pattern = "[%a_][%w_]*()%s+()%*+()[%a_][%w_]*", type = { "literal", "normal", "operator", "normal"}},
{pattern = "[%a_][%w_]*()%s+()[%a_][%w_]*()%s*()[;,%[%)]", type = { "literal", "normal", "normal", "normal", "normal"}},
{pattern = "[%a_][%w_]*()%s+()[%a_][%w_]*()%s*()=", type = { "literal", "normal", "normal", "normal", "operator"}},
{pattern = "[%a_][%w_]*()&()%s+()[%a_][%w_]*", type = { "literal", "operator", "normal", "normal"}},
{pattern = "[%a_][%w_]*()%s+()&()[%a_][%w_]*", type = { "literal", "normal", "operator", "normal"}},
--
-- Match scope operator element access
{pattern = "[%a_][%w_]*()%s*():", type = {"literal", "normal", "operator"}},
--
-- Uppercase constants of at least 2 chars in len
{pattern = "_?%u[%u_][%u%d_]*%f[%s%+%*%-%.%)%]}%?%^%%=/<>~|&;:,!]", type = "number"},
--
-- Magic constants
{pattern = "__[%u%l]+__", type = "number"},
--
-- All other functions
{pattern = "[%a_][%w_]*%f[(]", type = "function"},
--
-- Macros
{pattern = "^%s*#%s*define%s+()[%a_][%a%d_]*", type = { "keyword", "symbol"}},
{pattern = "#%s*include%s+()<.->", type = { "keyword", "string"}},
{pattern = "#%s*tryinclude%s+()<.->", type = { "keyword", "string"}},
{pattern = "%f[#]#%s*[%a_][%w_]*", type = "keyword"},
--
-- Everything else to make the tokenizer work properly
{pattern = "[%a_][%w_]*", type = "symbol"},
},
--
-- Load initial symbol list
symbols =
{
--
-- Statements
["assert"] = "keyword",
["break"] = "keyword",
["case"] = "keyword",
["continue"] = "keyword",
["default"] = "keyword",
["do"] = "keyword",
["else"] = "keyword",
["exit"] = "keyword",
["for"] = "keyword",
["goto"] = "keyword",
["if"] = "keyword",
["return"] = "keyword",
["sleep"] = "keyword",
["sstate"] = "keyword",
["switch"] = "keyword",
["while"] = "keyword",
--
-- Operators
["defined"] = "keyword",
["sizeof"] = "keyword",
["state"] = "keyword",
["tagof"] = "keyword",
--
-- Directives
["#assert"] = "keyword",
["#define"] = "keyword",
["#else"] = "keyword",
["#elseif"] = "keyword",
["#endif"] = "keyword",
["#endinput"] = "keyword",
["#error"] = "keyword",
["#file"] = "keyword",
["#if"] = "keyword",
["#include"] = "keyword",
["#line"] = "keyword",
["#pragma"] = "keyword",
["#section"] = "keyword",
["#tryinclude"] = "keyword",
["#undef"] = "keyword",
["#warning"] = "keyword",
--
-- Other
["const"] = "keyword",
["forward"] = "keyword",
["native"] = "keyword",
["new"] = "keyword",
["operator"] = "keyword",
["public"] = "keyword",
["static"] = "keyword",
["stock"] = "keyword",
--
-- Predefined constants
["cellbits"] = "keyword",
["cellmax"] = "keyword",
["cellmin"] = "keyword",
["charbits"] = "keyword",
["charmax"] = "keyword",
["charmin"] = "keyword",
["debug"] = "keyword",
["__line"] = "keyword",
["__Pawn"] = "keyword",
["ucharmax"] = "keyword",
--
-- Literal
["true"] = "literal",
["false"] = "literal",
--
-- Tag Names
["any"] = "keyword2",
["bool"] = "keyword2",
["Fixed"] = "keyword2",
["Float"] = "keyword2",
["Rational"] = "keyword2",
}
}
--
-- Get file list from include folder
local function get_include_file_list()
-- Return file list
local file_list = {}
--
-- Build themes path from current directory
local include_path = system.absolute_path(config.plugins.amxx.compiler_path .. PATHSEP .. config.plugins.amxx.include)
--
-- Loop file names
for _, filename in ipairs(system.list_dir(include_path) or {}) do
--
-- Full path of file
local file_path = system.absolute_path(include_path .. PATHSEP .. filename)
--
-- Get file information
local file_info = system.get_file_info(file_path)
--
-- If has file informationm type is file and have .yaml extension
if file_info and file_info.type == "file" and filename:match("%.inc$") then
--
-- Remove extension from file name
local include_name = filename:gsub("%.inc$", "")
--
-- If has include name
if include_name then -- DEBUG with amxmodx include only
file_list[include_name] = file_path
end
end
end
--
-- Return file list
return file_list
end
--
-- Read File Content
local function get_include_content(path)
--
-- Content table
local content = {}
--
-- Open file
local fp = io.open(path, "rb")
--
-- If is not null
if fp then
--
-- Current line
local line_number = 1
--
-- Read file content
for line in fp:lines() do
if line ~= nil and line ~= "" then
content[line_number] = line
end
--
-- Increment line
line_number = line_number + 1
end
--
-- Close file pointer
fp:close()
--
-- Return content
return content
end
--
-- Return content
return content
end
--
-- Parse functions: native, forward, public and stock
local function parse_function(path, number, line)
--
-- Match function with tag
local type, tag, body = line:match("^(%w+)%s(%w+):(.+)")
--
-- If has type, tag and body
if type and tag and body then
--
-- Get name
local name = line:match("[%a_][%w_]*%f[(]")
--
-- If is not empty
if name then
--
-- Function data
local function_data = {}
--
-- Store function path
function_data.path = path
--
-- Store line number
function_data.line = number
--
-- Store function name
function_data.name = name
--
-- Type (native, forward, public, stock)
function_data.type = type
--
-- Store return type (bool, Float, any)
function_data.tag = tag
--
-- Auto Complete body (The text that will used to insert on documents)
function_data.body = body
--
-- Set complete function line
function_data.text = line
--
-- Function documentation
function_data.doc = line
--
-- Return data
return function_data
end
end
--
-- Match with functions without tag
type, body = line:match("^(%w+)%s(.+)")
--
-- If has type and body
if type and body then
--
-- Get Name
local name = line:match("[%a_][%w_]*%f[(]")
--
-- If is not empty
if name then
--
-- Function data
local function_data = {}
--
-- Store function path
function_data.path = path
--
-- Store line number
function_data.line = number
--
-- Store function name
function_data.name = name
--
-- Type (native, forward, public, stock)
function_data.type = type
--
-- Store return type (bool, Float, any)
function_data.tag = ""
--
-- Auto Complete body (The text that will used to insert on documents)
function_data.body = body
--
-- Set complete function line
function_data.text = line
--
-- Function documentation
function_data.doc = line
--
-- Return data
return function_data
end
end
--
-- Return function data
return nil
end
--
-- Parse function documentation of function starting from function line number
local function parse_function_doc(number, content_table)
--
-- Documentation content, set it as default of current line
local doc_content = ""
--
-- Check previous line is end of comment or something else
if content_table[number-1] ~= nil and (content_table[number-1]:match(language_syntax.patterns[2].pattern[2]) or content_table[number-1]:match(language_syntax.patterns[1].pattern)) then
--
-- Loop reverse from function line number
for i = number, 1, -1 do
--
-- Check if is not nil
if content_table[i] ~= nil then
--
-- Reversed concatenation, we are doing reverse loop thing
doc_content = content_table[i] .. '\n' .. doc_content
--
-- If documentation is start of comment
if content_table[i]:match(language_syntax.patterns[2].pattern[1]) or content_table[i]:match(language_syntax.patterns[1].pattern) then
--
-- We have done here, exit loop
break
end
end
end
end
--
-- Return loaded contetn
return doc_content
end
--
-- Parse include file
local function parse_include_file(path)
--
-- Function List
local function_list = {}
--
-- Get include conetnt on table
local content_table = get_include_content(path)
--
-- If content table is not empty
if content_table then
--
-- Loop lines
for number, line in pairs(content_table) do
--
-- Load function data for this line
local function_data = parse_function(path, number, line)
--
-- If is not empty
if function_data then
--
-- Get function documentation
local documentation = parse_function_doc(number, content_table)
--
-- If file info is not nil
if documentation ~= nil and documentation ~= "" then
--
-- Set documentation on function data
function_data.doc = string.format("%s (%d) - %s\n%s\n\n%s", common.basename(path), number, function_data.type, string.rep("-", 40), documentation)
else
--
-- Set documentation on function data from default
function_data.doc = string.format("%s (%d) - %s\n%s\n\n%s", common.basename(path), number, function_data.type, string.rep("-", 40), function_data.doc)
end
--
-- If has tag in function, pass this as symbol to syntax
if function_data.tag and function_data.tag ~= "" then
--
-- If not exists in table yet
if function_list[function_data.tag] == nil then
--
-- Insert tag of function in list
function_list[function_data.tag] = function_data.tag
end
end
--
-- Insert function in list
function_list[function_data.name] = function_data
end
end
end
--
-- Return function list
return function_list
end
--
-- On Hover
local function on_hover(suggestions_idx, item)
--
-- Some event here, only unused
end
--
-- On Select
local function on_select(suggestions_idx, item)
--
-- Current document view
local doc = core.active_view.doc
--
-- Get current selection
local line2, col2 = doc:get_selection()
--
-- Get current cursor position
local line1, col1 = doc:position_offset(line2, col2, translate.start_of_word)
--
-- Get current partial typed text
local current_partial = doc:get_text(line1, col1, line2, col2)
--
-- Get size of partial
local sz = #current_partial
--
-- Loop all selections in document view
for idx, line1, col1, line2, col2 in doc:get_selections(true) do
--
-- Previous column idx
local n = col1 - 1
--
-- Get current line of document view
local line = doc.lines[line1]
--
-- For each column
for i = 1, sz + 1 do
--
-- Remove one character space
local j = sz - i
--
-- Remove from line the character
local subline = line:sub(n - j, n)
--
-- Remove from partial line the characters
local subpartial = current_partial:sub(i, -1)
--
-- If partial match is equal match of subline
if subpartial == subline then
--
-- Remove partial typed match
doc:remove(line1, col1, line2, n - j)
--
-- Break
break
end
end
end
--
-- Input autocomplete text
doc:text_input(item.data)
--
-- Return to autocomplete plugin that text is placed
return true
end
--
-- Update auto complete
local function update_auto_complete()
--
-- List of include files
local include_list = get_include_file_list()
--
-- Loop include list
for include_name, path in pairs(include_list) do
--
-- Get function list and tags from that include file
local function_list = parse_include_file(path)
--
-- Loop function list result
for name, item_data in pairs(function_list) do
--
-- If type is table, set function in language syntax
if type(item_data) == "table" then
--
-- Include on language syntax
language_syntax.symbols[name] =
{
--
-- Name of function to show in list
text = name,
--
-- Type of autocomplete item
info = (style.syntax[item_data.type] ~= nil and item_data.type or "function"),
--
-- Icon to show in list: "comment", "function", "keyword", "operator" and others
icon = "function",
--
-- Description of that function to show
desc = item_data.doc,
--
-- On hover an item on auto complete list
onhover = on_hover,
--
-- On select an item to replace in
onselect = on_select,
--
-- Parameter of onselet or onhover events (Send text of item to autocomplete)
data = item_data.body,
--
-- Include file
path = item_data.path,
--
-- Include file line
line = item_data.line
}
--
-- If type is string, parse to symbol table as symbol
else
--
-- If if the symbol is not set yet
if language_syntax.symbols[name] == nil then
--
-- Include on language syntax
language_syntax.symbols[name] =
{
--
-- Name of function to show in list
text = name,
--
-- Type of autocomplete item
info = "keyword2",
--
-- Icon to show in list: "comment", "function", "keyword", "operator" and others
icon = "keyword",
--
-- Description of that function to show
desc = string.format("%s Tag Name - %s\n%s\n\n%s", common.basename(path), name, string.rep("-", 40), name),
}
end
end
end
end
end
--
-- Fix tokenizer of docview by Guldoman
local old_each_token = tokenizer.each_token
--
-- Fix tokenizer of docview by Guldoman
function tokenizer.each_token(...)
--
-- Iterate over tokens
local iter, t, _ = old_each_token(...)
--
-- Return anonymous function result for each iterator
return function(t, i)
--
-- Get token data from iterator
local i, _type, text = iter(t, i)
--
-- If type is table
if type(_type) == "table" then
--
-- Set info parameter
_type = _type.info
end
--
-- Return parameters for that token
return i, _type, text
end, t, -1
end
--
-- On release mouse click
local on_mouse_released = docView.on_mouse_released
--
-- On release mouse click
function docView:on_mouse_released(button, x, y, ...)
--
-- Call original release mouse click function
on_mouse_released(self, button, x, y, ...)
--
-- If button was left and ALT was pressed
if button == "left" and keymap.modkeys["alt"] then
--
-- Get line and column of mouse position of click
local line, col = self:resolve_screen_position(x, y)
--
-- If is not null
if line and col then
--
-- For each token of lile
for _, type, text in self.doc.highlighter:each_token(line) do
--
-- Check if has text, and the type of token
if text and type == "function" or type == "native" or type == "forward" or type == "public" or type == "stock" then
--
-- Trim spaces of text
text = text:match("^%s*(.-)%s*$")
--
-- If is not null
if text then
--
-- Check if has syntax symbols with that text, and have path and line of file
if language_syntax.symbols[text] and language_syntax.symbols[text].path and language_syntax.symbols[text].line then
--
-- Try open doc
core.try(function()
--
-- Try to open doc on root view from specified path
local dv = core.root_view:open_doc(core.open_doc(language_syntax.symbols[text].path))
--
-- Update root view layout
core.root_view.root_node:update_layout()
--
-- Set selection on line of syntax symbol in target file
dv.doc:set_selection(language_syntax.symbols[text].line, 1)
--
-- Scroll to target line
dv:scroll_to_line(language_syntax.symbols[text].line, false, true)
end)
end
end
end
end
end
end
end
--
-- On view mouse pressed
local amxx_on_mouse_pressed = view.on_mouse_pressed
--
-- On view mouse pressed callback
function view:on_mouse_pressed(button, x, y, clicks)
--
-- Store result of original function
local result = amxx_on_mouse_pressed(self, button, x, y, clicks)
--
-- If current mouse click is not in console
if self:get_name() ~= "Console" and console.isVisible() then
--
-- Close console
console.close()
end
--
-- Return result
return result
end
--
-- Ask for compiler path
local amxx_ask_compiler_path = function(execute_build)
--
-- AMX Mod X compiler executable
local executablePath = system.absolute_path(config.plugins.amxx.compiler_path .. PATHSEP .. config.plugins.amxx.compiler)
---
-- Check executable before try to compile
if system.get_file_info(executablePath) == nil then
--
-- Show error message
core.error("AMX Mod X Compiler: Compiler not found: " .. executablePath)
--
-- Call for ask for compiler path
core.nag_view:show("AMX Mod X compiler not found", "AMX Mod X compiler not found, did you want to choose path?",
{
{text = "Yes", default_yes = true},
{text = "No", default_no = false}
}, function(item)
--
-- If yes
if item.text == "Yes" then
--
-- Create thread, the nagview is designed that
core.add_thread(function()
--
-- Try to get that path and set
core.command_view:enter("Specify the AMX Mod X Compiler path",
{
--
-- Valudate input text to check if path exists
validate = function(text)
--
-- Check input text if is a valid directory
if system.get_file_info(text) == nil then
--
-- Message
core.error(string.format("Specified path '%s' do not exists.", text))
--
-- Path is not valid
return false
end
--
-- Path is valid
return true
end,
--
-- On submit
submit = function(text)
--
-- Get path
local path = system.absolute_path(text)
--
-- If path is not found, log error
if system.get_file_info(path) == nil then
--
-- Error message
core.error(string.format("Specified path not found: %s.",path))
else
--
-- Set path on current plugin
config.plugins.amxx.compiler_path = path
--
-- If has settings of plugins
if settings.config["plugins"] then
--
-- Create for ths plugin
settings.config["plugins"]["amxx"] = {compiler_path = path}
end
--
-- Reload settings plugin to get new config loaded and saved
settings.ui:new()
--
-- Success message
core.error("AMX Mod X Compiler set: " .. path)
--
-- if has execute build
if execute_build then
--
-- Try to run
command.perform("amxx:build")
end
end
end,
--
-- Suggest directory for amxx compiler finder
suggest = function(text)
-- Expand home directory from text
text = common.home_expand(text)
--
-- Get base dir from project directory
local basedir = common.dirname(core.project_dir)
--
-- Return encoded list with directory fround and recent suggestions
return common.home_encode_list((basedir and text == basedir .. PATHSEP or text == "") and core.recent_projects or common.dir_path_suggest(text))
end
})
end)
end
end)
--
-- Return false
return false
end
--
-- Return true
return true
end
--
-- Check if current file is valid
local amxx_check_active_file_name = function()
--
-- If has active view file name
if core.active_view.doc and core.active_view.doc.filename then
--
-- Loop files sytax table
for _, pattern in pairs(language_syntax.files) do
--
-- If pattern match with filename
if string.match(core.active_view.doc.filename, pattern) then
--
-- Return true
return true
end
end
end
--
-- Return false
return false
end
--
-- Build plugin function
local amxx_build_plugin_func = function()
--
-- If has an valid extension
if amxx_check_active_file_name() then
--
-- AMX Mod X compiler executable
local executablePath = system.absolute_path(config.plugins.amxx.compiler_path .. PATHSEP .. config.plugins.amxx.compiler)
---
-- Check executable before try to compile
if amxx_ask_compiler_path(true) then
--
-- AMX Mod X binary default output file path (Convert old .sma extension to .amxx)
local outputPath = string.format("%s.%s", core.active_view.doc.abs_filename:match("(.+)%..+"), config.plugins.amxx.extension)
--
-- If output path setting is not empty
if config.plugins.amxx.output and config.plugins.amxx.output ~= "" then
--
-- Construct output path based on path specified
outputPath = config.plugins.amxx.output .. PATHSEP .. string.format("%s.%s", common.basename(core.active_view.doc.filename):match("(.+)%..+"), config.plugins.amxx.extension)
end
--
-- AMX Mod X compiler include
local includePath = config.plugins.amxx.path .. PATHSEP .. config.plugins.amxx.include
--
-- AMX Mod X compiler command line
local compileCommand = string.format("%s -i%s -o%s %s", executablePath, includePath, outputPath, core.active_view.doc.abs_filename)
--
-- If compilercommand is null
if compileCommand == nil then
--
-- Send error message
core.error("AMX Mod X Compiler: Command is empty.")
else
--
-- Save current file each run
if config.plugins.amxx.save == true then
--
-- Save
core.active_view.doc:save()
end
--
-- Clear console on each run
if config.plugins.amxx.clear == true then
--
-- Clear console
console.clear();
end
--
-- Run console command
console.run
{
--
-- Command
command = compileCommand,
--
-- Output warning / errors pattern
file_pattern = "(.*)%((.*)%) : (.*)",
--
-- File prefix separator
file_prefix = ".",
--
-- Current directory of command
cwd = ".",
--
-- Error pattern
error_pattern = "error",
--
-- Warning pattern
warning_pattern = "warning",
--
-- On command end
on_complete = function()
core.log("AMX Mod X Compiler: Compilation Complete")
end
}
end
end
else
--
-- Error message if is not an valid file
core.error("AMX Mod X Compiler: " .. common.basename(core.active_view.doc.filename) .. " is not a AMX Mod X source file")
end
end
--
-- On open document
local RootView_open_doc = rootView.open_doc
--
-- On open document
function rootView:open_doc(doc)
--
-- Execute original function to docview
local docview = RootView_open_doc(self, doc)
--
-- If is an .sma or .inc file
if amxx_check_active_file_name() then
--
-- Ask for compiler path if not exists
amxx_ask_compiler_path(false)
end
--
-- Return result
return docview
end
--
-- Update auto complete list
core.add_thread(function()
update_auto_complete()
end)
--
-- Add or reload language syntax
syntax.add(language_syntax)
--
-- Add commands on document view
command.add("core.docview",
{
--
-- AMXX build command
["amxx:build"] = amxx_build_plugin_func
})
--
-- Add CTRL + B
keymap.add({["ctrl+b"] = "amxx:build"})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment