18 Star 39 Fork 1

mathmhb / Makefile

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
extman.lua 19.17 KB
一键复制 编辑 原始数据 按行查看 历史
mathmhb 提交于 2022-10-25 16:52 . change extman.lua
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
--[mhb] added
--~ print('loading '.._VERSION..' extman ...')
--lua >=5.2.x renamed functions:
local unpack = table.unpack or unpack
math.mod = math.fmod or math.mod
string.gfind = string.gmatch or string.gfind
table.getn = table.getn or function(tbl) return #tbl end
getn = table.getn
--lua >=5.2.x replaced table.getn(x) with #x
-- Extman is a Lua script manager for SciTE. It enables multiple scripts to capture standard events
-- without interfering with each other. For instance, scite_OnDoubleClick() will register handlers
-- for scripts that need to know when a double-click event has happened. (To know whether it
-- was in the output or editor pane, just test editor.Focus). It provides a useful function scite_Command
-- which allows you to define new commands without messing around with property files (see the
-- examples in the scite_lua directory.)
-- extman defines three new convenience handlers as well:
--scite_OnWord (called when user has entered a word)
--scite_OnEditorLine (called when a line is entered into the editor)
--scite_OnOutputLine (called when a line is entered into the output pane)
-- this is an opportunity for you to make regular Lua packages available to SciTE
--~ package.path = package.path..';C:\\lang\\lua\\lua\\?.lua'
--~ package.cpath = package.cpath..';c:\\lang\\lua\\?.dll'
-- useful function for getting a property, or a default if not present.
function scite_GetProp(key,default)
local val = props[key]
if val and val ~= '' then return val
else return default end
end
function scite_GetPropBool(key,default)
local res = scite_GetProp(key,default)
if not res or res == '0' or res == 'false' then return false
else return true
end
end
local GTK = scite_GetProp('PLAT_GTK')
local _MarginClick,_DoubleClick,_SavePointLeft = {},{},{}
local _SavePointReached,_Open,_SwitchFile = {},{},{}
local _BeforeSave,_Save,_Char = {},{},{}
local _Word,_LineEd,_LineOut = {},{},{}
local _OpenSwitch = {}
local _UpdateUI = {}
local _UserListSelection
-- new with 1.74!
local _Key = {}
local _DwellStart = {}
local _Close = {}
-- new
local _remove = {}
local append = table.insert
local find = string.find
local size = table.getn
local sub = string.sub
local gsub = string.gsub
-- file must be quoted if it contains spaces!
function quote_if_needed(target)
local quote = '"'
if find(target,'%s') and sub(target,1,1) ~= quote then
target = quote..target..quote
end
return target
end
function OnUserListSelection(tp,str)
if _UserListSelection then
local callback = _UserListSelection
_UserListSelection = nil
return callback(str)
else return false end
end
local function DispatchOne(handlers,arg)
for i,handler in pairs(handlers) do
local fn = handler
if _remove[fn] then
handlers[i] = nil
_remove[fn] = nil
end
local ret = fn(arg)
if ret then return ret end
end
return false
end
local function Dispatch4(handlers,arg1,arg2,arg3,arg4)
for i,handler in pairs(handlers) do
local fn = handler
if _remove[fn] then
handlers[i] = nil
_remove[fn] = nil
end
local ret = fn(arg1,arg2,arg3,arg4)
if ret then return ret end
end
return false
end
-- these are the standard SciTE Lua callbacks - we use them to call installed extman handlers!
function OnMarginClick()
return DispatchOne(_MarginClick)
end
function OnDoubleClick()
return DispatchOne(_DoubleClick)
end
function OnSavePointLeft()
return DispatchOne(_SavePointLeft)
end
function OnSavePointReached()
return DispatchOne(_SavePointReached)
end
function OnChar(ch)
return DispatchOne(_Char,ch)
end
function OnSave(file)
return DispatchOne(_Save,file)
end
function OnBeforeSave(file)
return DispatchOne(_BeforeSave,file)
end
function OnSwitchFile(file)
return DispatchOne(_SwitchFile,file)
end
function OnOpen(file)
return DispatchOne(_Open,file)
end
function OnUpdateUI()
if editor.Focus then
return DispatchOne(_UpdateUI)
else
return false
end
end
-- new with 1.74
function OnKey(key,shift,ctrl,alt)
return Dispatch4(_Key,key,shift,ctrl,alt)
end
function OnDwellStart(pos,s)
return Dispatch4(_DwellStart,pos,s)
end
function OnClose()
return DispatchOne(_Close)
end
-- may optionally ask that this handler be immediately
-- removed after it's called
local function append_unique(tbl,fn,rem)
local once_only
if type(fn) == 'string' then
once_only = fn == 'once'
fn = rem
rem = nil
if once_only then
_remove[fn] = fn
end
else
_remove[fn] = nil
end
local idx
for i,handler in pairs(tbl) do
if handler == fn then idx = i; break end
end
if idx then
if rem then
table.remove(tbl,idx)
end
else
if not rem then
append(tbl,fn)
end
end
end
-- this is how you register your own handlers with extman
function scite_OnMarginClick(fn,rem)
append_unique(_MarginClick,fn,rem)
end
function scite_OnDoubleClick(fn,rem)
append_unique(_DoubleClick,fn,rem)
end
function scite_OnSavePointLeft(fn,rem)
append_unique(_SavePointLeft,fn,rem)
end
function scite_OnSavePointReached(fn,rem)
append_unique(_SavePointReached,fn,rem)
end
function scite_OnOpen(fn,rem)
append_unique(_Open,fn,rem)
end
function scite_OnSwitchFile(fn,rem)
append_unique(_SwitchFile,fn,rem)
end
function scite_OnBeforeSave(fn,rem)
append_unique(_BeforeSave,fn,rem)
end
function scite_OnSave(fn,rem)
append_unique(_Save,fn,rem)
end
function scite_OnUpdateUI(fn,rem)
append_unique(_UpdateUI,fn,rem)
end
function scite_OnChar(fn,rem)
append_unique(_Char,fn,rem)
end
function scite_OnOpenSwitch(fn,rem)
append_unique(_OpenSwitch,fn,rem)
end
--new 1.74
function scite_OnKey(fn,rem)
append_unique(_Key,fn,rem)
end
function scite_OnDwellStart(fn,rem)
append_unique(_DwellStart,fn,rem)
end
function scite_OnClose(fn,rem)
append_unique(_Close,fn,rem)
end
local function buffer_switch(f)
--- OnOpen() is also called if we move to a new folder
if not find(f,'[\\/]$') then
DispatchOne(_OpenSwitch,f)
end
end
scite_OnOpen(buffer_switch)
scite_OnSwitchFile(buffer_switch)
local next_user_id = 13 -- arbitrary
-- the handler is always reset!
function scite_UserListShow(list,start,fn)
local separators = {' ', ';', '@', '?', '~', ':'}
local separator
local s = table.concat(list)
for i, sep in ipairs(separators) do
if not string.find(s, sep, 1, true) then
s = table.concat(list, sep, start)
separator = sep
break
end
end
-- we could not find a good separator, set it arbitrarily
if not separator then
separator = '@'
s = table.concat(list, separator, start)
end
_UserListSelection = fn
local pane = editor
if not pane.Focus then pane = output end
pane.AutoCSeparator = string.byte(separator)
pane:UserListShow(next_user_id,s)
pane.AutoCSeparator = string.byte(' ')
return true
end
local word_start,in_word,current_word
-- (Nicolas) this is in Ascii as SciTE always passes chars in this "encoding" to OnChar
local wordchars = '[A-Za-z--]' -- wuz %w
local function on_word_char(s)
if not in_word then
if find(s,wordchars) then
-- we have hit a word!
word_start = editor.CurrentPos
in_word = true
current_word = s
end
else -- we're in a word
-- and it's another word character, so collect
if find(s,wordchars) then
current_word = current_word..s
else
-- leaving a word; call the handler
local word_end = editor.CurrentPos
DispatchOne(_Word, {word=current_word,
startp=word_start,endp=editor.CurrentPos,
ch = s
})
in_word = false
end
end
-- don't interfere with usual processing!
return false
end
function scite_OnWord(fn,rem)
append_unique(_Word,fn,rem)
if not rem then
scite_OnChar(on_word_char)
else
scite_OnChar(on_word_char,'remove')
end
end
local last_pos = 0
function get_line(pane,lineno)
if not pane then pane = editor end
if not lineno then
local line_pos = pane.CurrentPos
lineno = pane:LineFromPosition(line_pos)-1
end
-- strip linefeeds (Windows is a special case as usual!)
local endl = 2
if pane.EOLMode == 0 then endl = 3 end
local line = pane:GetLine(lineno)
if not line then return nil end
return string.sub(line,1,-endl)
end
-- export this useful function...
scite_Line = get_line
local function on_line_char(ch,was_output)
if ch == '\n' then
local in_editor = editor.Focus
if in_editor and not was_output then
DispatchOne(_LineEd,get_line(editor))
return false -- DO NOT interfere with any editor processing!
elseif not in_editor and was_output then
DispatchOne(_LineOut,get_line(output))
return true -- prevent SciTE from trying to evaluate the line
end
end
return false
end
local function on_line_editor_char(ch)
return on_line_char(ch,false)
end
local function on_line_output_char(ch)
return on_line_char(ch,true)
end
local function set_line_handler(fn,rem,handler,on_char)
append_unique(handler,fn,rem)
if not rem then
scite_OnChar(on_char)
else
scite_OnChar(on_char,'remove')
end
end
function scite_OnEditorLine(fn,rem)
set_line_handler(fn,rem,_LineEd,on_line_editor_char)
end
function scite_OnOutputLine(fn,rem)
set_line_handler(fn,rem,_LineOut,on_line_output_char)
end
local path_pattern
local tempfile
local dirsep
if GTK then
tempfile = '/tmp/.scite-temp-files'
path_pattern = '(.*)/[^%./]+%.%w+$'
dirsep = '/'
else
tempfile = '\\scite_temp1'
path_pattern = '(.*)\\[^%.\\]+%.%w+$'
dirsep = '\\'
end
function path_of(s)
local _,_,res = find(s,path_pattern)
if _ then return res else return s end
end
local extman_path = path_of(props['ext.lua.startup.script'])
local lua_path = scite_GetProp('ext.lua.directory',extman_path..dirsep..'scite_lua')
function extman_Path()
return extman_path
end
-- this version of scite-gdb uses the new spawner extension library.
local fn,err,spawner_path
if package then loadlib = package.loadlib end
-- by default, the spawner lib sits next to extman.lua
spawner_path = scite_GetProp('spawner.extension.path',extman_path)
if GTK then
fn,err = loadlib(spawner_path..'/unix-spawner-ex.so','luaopen_spawner')
else
fn,err = loadlib(spawner_path..'\\spawner-ex.dll','luaopen_spawner')
end
if fn then
fn() -- register spawner
else
print('cannot load spawner '..err)
end
-- a general popen function that uses the spawner library if found; otherwise falls back
-- on os.execute
function scite_Popen(cmd)
if spawner then
return spawner.popen(cmd)
else
cmd = cmd..' > '..tempfile
if GTK then -- io.popen is dodgy; don't use it!
os.execute(cmd)
else
if Execute then -- scite_other was found!
Execute(cmd)
else
os.execute(cmd)
end
end
return io.open(tempfile)
end
end
function dirmask(mask,isdir)
local attrib = ''
if isdir then
if not GTK then
attrib = ' /A:D '
else
attrib = ' -F '
end
end
if not GTK then
mask = gsub(mask,'/','\\')
return 'dir /b '..attrib..quote_if_needed(mask)
else
return 'ls -1 '..attrib..quote_if_needed(mask)
end
end
-- grab all files matching @mask, which is assumed to be a path with a wildcard.
function scite_Files(mask)
local f,path,cmd,_
if not GTK then
cmd = dirmask(mask)
path = mask:match('(.*\\)') or '.\\'
else
cmd = 'ls -1 '..mask
path = ''
end
f = scite_Popen(cmd)
local files = {}
if not f then return files end
for line in f:lines() do
-- print(path..line)
append(files,path..line)
end
f:close()
return files
end
-- grab all directories in @path, excluding anything that matches @exclude_path
-- As a special exception, will also any directory called 'examples' ;)
function scite_Directories(path,exclude_pat)
local cmd
--print(path)
if not GTK then
cmd = dirmask(path..'\\*.',true)
else
cmd = dirmask(path,true)
end
path = path..dirsep
local f = scite_Popen(cmd)
local files = {}
if not f then return files end
for line in f:lines() do
print(line)
if GTK then
if line:sub(-1,-1) == dirsep then
line = line:sub(1,-2)
else
line = nil
end
end
if line and not line:find(exclude_pat) and line ~= 'examples' then
append(files,path..line)
end
end
f:close()
return files
end
function scite_FileExists(f)
local f = io.open(f)
if not f then return false
else
f:close()
return true
end
end
function scite_CurrentFile()
return props['FilePath']
end
-- (Nicolas)
if GTK then
function scite_DirectoryExists(path)
print('test -d "'..path..'"')
return true
-- return os.execute('test -d "'..path..'"') == 0
end
else
-- what is the Win32 equivalent??
function scite_DirectoryExists(path)
return true
end
end
function split(s,delim)
res = {}
while true do
p = find(s,delim)
if not p then
append(res,s)
return res
end
append(res,sub(s,1,p-1))
s = sub(s,p+1)
end
return res
end
function splitv(s,delim)
print(s)
return unpack(split(s,delim))
end
local idx = 10
local shortcuts_used = {}
local alt_letter_map = {}
local alt_letter_map_init = false
local name_id_map = {}
local function set_command(name,cmd,mode)
local _,_,pattern,md = find(mode,'(.+){(.+)}')
if not _ then
pattern = mode
md = 'savebefore:no'
end
local which = '.'..idx..pattern
props['command.name'..which] = name
props['command'..which] = cmd
props['command.subsystem'..which] = '3'
props['command.mode'..which] = md
name_id_map[name] = 1100+idx
return which
end
local function check_gtk_alt_shortcut(shortcut,name)
-- Alt+<letter> shortcuts don't work for GTK, so handle them directly...
local _,_,letter = shortcut:find('^Alt%+([A-Z])$')
if _ then
alt_letter_map[letter:lower()] = name
if not alt_letter_map_init then
alt_letter_map_init = true
scite_OnKey(function(key,shift,ctrl,alt)
if alt and key < 255 then
local ch = string.char(key)
if alt_letter_map[ch] then
scite_MenuCommand(alt_letter_map[ch])
end
end
end)
end
end
end
local function set_shortcut(shortcut,name,which)
if shortcut == 'Context' then
local usr = 'user.context.menu'
if props[usr] == '' then -- force a separator
props[usr] = '|'
end
props[usr] = props[usr]..'|'..name..'|'..(1100+idx)..'|'
else
local cmd = shortcuts_used[shortcut]
if cmd then
print('Error: shortcut already used in "'..cmd..'"')
else
shortcuts_used[shortcut] = name
if GTK then check_gtk_alt_shortcut(shortcut,name) end
props['command.shortcut'..which] = shortcut
end
end
end
-- allows you to bind given Lua functions to shortcut keys
-- without messing around in the properties files!
-- Either a string or a table of strings; the string format is either
-- menu text|Lua command|shortcut
-- or
-- menu text|Lua command|mode|shortcut
-- where 'mode' is the file extension which this command applies to,
-- e.g. 'lua' or 'c', optionally followed by {mode specifier}, where 'mode specifier'
-- is the same as documented under 'command.mode'
-- 'shortcut' can be a usual SciTE key specifier, like 'Alt+R' or 'Ctrl+Shift+F1',
-- _or_ it can be 'Context', meaning that the menu item should also be added
-- to the right-hand click context menu.
function scite_Command(tbl)
if type(tbl) == 'string' then
tbl = {tbl}
end
for i,v in pairs(tbl) do
local name,cmd,mode,shortcut = splitv(v,'|')
if not shortcut then
shortcut = mode
mode = '.*'
else
mode = '.'..mode
end
-- has this command been defined before?
local old_idx = 0
for ii = 10,idx do
if props['command.name.'..ii..mode] == name then old_idx = ii end
end
if old_idx == 0 then
local which = set_command(name,cmd,mode)
if shortcut then
set_shortcut(shortcut,name,which)
end
idx = idx + 1
end
end
end
-- use this to launch Lua Tool menu commands directly by name
-- (commands are not guaranteed to work properly if you just call the Lua function)
function scite_MenuCommand(cmd)
if type(cmd) == 'string' then
cmd = name_id_map[cmd]
if not cmd then return end
end
scite.MenuCommand(cmd)
end
local loaded = {}
local current_filepath
-- this will quietly fail....
local function silent_dofile(f)
if scite_FileExists(f) then
if not loaded[f] then
dofile(f)
loaded[f] = true
end
return true
end
return false
end
function scite_dofile(f)
f = extman_path..'/'..f
silent_dofile(f)
end
function scite_require(f)
local path = lua_path..dirsep..f
if not silent_dofile(path) then
silent_dofile(current_filepath..dirsep..f)
end
end
if not GTK then
scite_dofile 'scite_other.lua'
end
if not scite_DirectoryExists(lua_path) then
print('Error: directory '..lua_path..' not found')
return
end
function load_script_list(script_list,path)
if not script_list then
print('Error: no files found in '..path)
else
current_filepath = path
for i,file in pairs(script_list) do
print(file)
silent_dofile(file)
end
end
end
function scite_load_all() --[mhb] added: do not call it! please load scripts manually
-- Load all scripts in the lua_path (usually 'scite_lua'), including within any subdirectories
-- that aren't 'examples' or begin with a '_'
local script_list = scite_Files(lua_path..dirsep..'*.lua')
load_script_list(script_list,lua_path)
local dirs = scite_Directories(lua_path,'^_')
for i,dir in ipairs(dirs) do
load_script_list(scite_Files(dir..dirsep..'*.lua'),dir)
end
end
function scite_WordAtPos(pos)
if not pos then pos = editor.CurrentPos end
local p2 = editor:WordEndPosition(pos,true)
local p1 = editor:WordStartPosition(pos,true)
if p2 > p1 then
return editor:textrange(p1,p2)
end
end
function scite_GetSelOrWord()
local s = editor:GetSelText()
if s == '' then
return scite_WordAtPos()
else
return s
end
end
scite_Command 'Reload Script|reload_script|Shift+Ctrl+R'
function reload_script()
current_file = scite_CurrentFile()
print('Reloading... '..current_file)
loaded[current_file] = false
silent_dofile(current_file)
end
--~ require"remdebug.engine"
--~ remdebug.engine.start()
--[mhb] added to support OnStrip
local _Strip={}
function scite_OnStrip(fn,rem)
append_unique(_Strip,fn,rem)
end
function OnStrip(control,change)
print('OnStrip ',control,change)
return Dispatch4(_Strip,control,change)
end
其他
1
https://gitee.com/imbit_mathmhb/Makefile.git
git@gitee.com:imbit_mathmhb/Makefile.git
imbit_mathmhb
Makefile
Makefile
master

搜索帮助