Scite Ext Man |
|
此最新版本 (2006-11-10) 修正了 Linux 版本中的一個嚴重錯誤,並採用了更穩健的方法來判斷輸入的行是在編輯器或輸出窗格中。它也允許您使用「重新載入腳本」(Ctrl+Shift+R) 重新載入 extman 控制的 Lua 腳本。包含了一些額外的範例:* prompt.lua,提供了一個簡單的互動式 Lua 提示。* select_string.lua,允許您用雙擊選取整個字串 (或註解)。* select_block.lua,允許您在折疊列旁的邊界處按一下來選取區塊。
您可以在 Files:wiki_insecure/editors/SciTE/extman.lua 找到 extman;範例和程式碼在 Files:wiki_insecure/editors/SciTE/extman.zip 中;它完全用 Lua 編寫,可配合任何最近的 SciTE 版本使用。
SciTE Lua 介面非常強大,但目前沒有辦法讓非平凡的腳本得以「順利」一起執行。考慮一下 SciteBufferSwitch;處理常式 OnOpen
、OnSwitchFile
和 OnUserListSelection
都已覆寫以追蹤緩衝區變更並顯示緩衝區下拉清單。這類腳本會妨礙任何其他有需要監控這些事件的腳本。
使用 extman 之後,這個腳本看起來像這樣 (函式 buffer_switch
是相同的)
scite_OnOpen(buffer_switch) scite_OnSwitchFile(buffer_switch) scite_Command 'Switch Buffer|do_buffer_list|Ctrl+J' function do_buffer_list() scite_UserListShow(buffers,2,scite.Open) end
(最新版 extman 還提供了 OnOpenSwitch
,當檔案透過開啟或切換緩衝區而變為有效時便會呼叫此函式。看看 switch_buffers.lua
範例)
在內部,extman 會保留處理常式清單。例如,scite_OnOpen
會將函式新增到 OnOpen
事件呼叫的處理常式清單中。現在,另一個腳本完全有可能監聽 OnOpen
事件,而不會造成衝突。類似地,還有 scite_OnChar
、scite_OnSave
等,不過 OnUserListSelection
則不同,處理方式不一樣。
除了標準 SciTE Lua 事件之外,extman 還提供了 OnWord
、OnEditorLine
和 OnOutputLine
。它們建構在基本事件之上,並為了方便起見而納入其中。
以下是以 extman 重新編寫的「懶惰字」替換範例。OnWord
處理常式會接收到一張表格,其中有欄位 word
、startp
、endp
、ch
,它們分別為找到的字、它的起始位置、結束位置以及在字之後立即找到的字元。
function on_word(w) local subst = word_substitute(w.word) if subst ~= w.word then editor:SetSel(w.startp-1,w.endp-1) local was_whitespace = string.find(w.ch,'%s') if was_whitespace then subst = subst..w.ch end editor:ReplaceSel(subst) local word_end = editor.CurrentPos if not was_whitespace then editor:GotoPos(word_end + 1) end end end scite_OnWord(on_word)
OnOutputLine
僅在於有輸入一行至輸出窗格時會觸發。以下是給 SciTE 用的簡單但實用的 Lua 主控台
local prompt = '> ' print 'Scite/Lua' trace(prompt) scite_OnOutputLine (function (line) local sub = string.sub if sub(line,1,2) == prompt then line = sub(line,3) end if sub(line,1,1) == '=' then line = 'print('..sub(line,2)..')' end local f,err = loadstring(line,'local') if not f then print(err) else local ok,res = pcall(f) if ok then if res then print('result= '..res) end else print(res) end end trace(prompt) return true end)
OnEditorLine
是一個類似事件,但只在下使用者在編輯器窗格中輸入一行時發生。一個重要的差異是,它絕不會干擾正常字元處理。可以使用這個函式來追蹤輸入的任何宣告,等等。下一個範例相當奇怪,但顯示我們如何將捷徑與字母綁定為一個動作。
scite_Command 'AltX|do_altx_commands|Alt+X' function do_altx_commands() editor:BeginUndoAction() scite_OnChar('once',function (ch) editor:EndUndoAction() editor:Undo() if ch == 's' then print('ess') elseif ch == 'f' then editor:BeginUndoAction() scite_OnEditorLine(handle_line) end return true end) end
在您輸入 Alt+X 後,這個函式會安裝一次性執行 OnChar
的處理常式。它只對「s」或「f」感興趣,但總是會「吃掉」按下的下一個字元。Emacs 使用者可能會覺得這些按鍵組合很自然,而且它們一定比 Alt+Ctrl+Shift 的組合容易輸入。 OnChar
都不會看到特殊字元,所以限於字母和標點符號。(我的手指還記得在 Borland 環境中,按下 Ctrl+Q 後面接一個數字,可移動到一個標記位置 – 請參閱 SciteNumberedBookmarks)。
Alt+X 搭配「f」是為了讓使用者可以在緩衝區中輸入一個檔名。該檔名會由 editor:Undo
立即移除,然後開啟該檔案。
local function handle_line(line) editor:EndUndoAction() editor:Undo() scite_OnEditorLine(handle_line,'remove') scite.Open(line) end
extman 也提供一些有用的實用函式。在某些狀況下(例如檔案存取),它們彌補了 Lua 函式庫中遺失的功能。例如:如果 SciTE 包含 lfs (Lua File System),那麼使用者即使實作已變更,仍可持續使用 scite_Files
。
scite_UserListShow(list,start,fn)
是存取 Scintilla 使用者清單的簡化方式 – 它會建構一個適當的區隔字串,等等。您可以指定清單的開始索引 – 這裡我使用它來避免顯示目前的緩衝區。
scite_GetProp(key,default)
是 props
偽表格的一個簡單包裝器。如果屬性 key
不存在,那麼 props[key]
會傳回一個空字串,而不是 nil;如果未指定 default
,那麼如果屬性不存在,這個函式確實會傳回 nil。
scite_Files(mask)
會傳回提供的路徑+遮罩中所有檔案(例如:「d:/downloads/scite_lua/*.lua」– 在 Windows 中,正斜線也會被接受)。如果找到 SciteOther 函式庫,那麼它會使用安靜的 Execute
,否則使用 os.execute
。
scite_FileExists(f)
如果可以開啟檔案以供讀取,則傳回 true。
scite_dofile(f)
與 dofile
相似,但它總是會載入相對於 SciTE 的預設起始位置的檔案,並安靜地失敗。
scite_Command(cmds)
是將 Lua 函式與「工具」功能表項目和按鍵捷徑關聯的非常有用的函式。您可以傳給它一個字串或一個字串清單;字串的格式為 <name>|<function>|<shortcut>,其中 <shortcut> 是選用項目。
將 sciTE 目錄中的檔案解壓縮,並記住保留資料夾名稱。Extman 是用來作為 Lua 的主啟動腳本(當然也可以把它放在其他地方)
ext.lua.startup.script=$(SciteDefaultHome)/extman.lua
在啟動時,它會搜尋 scite_lua
目錄中所有副檔名為「.lua」的檔案,預設位於預設首頁目錄中。你可以使用 ext.lua.directory
強制把它指定到其他地方。
這些檔案會被載入,所以你 *不應該* 把 extman.lua 放在該目錄中!這些檔案有機會呼叫 scite_Command
來註冊其函式。它們很可能會需要載入其他先前的腳本,所以已經加入了 scite_require()
。如果一個檔案已經透過此函式明示載入,那麼 extman 會將其視為已載入。
下列程式碼片段允許 Lua 延伸模組選擇性地針對 OnChar
使用 extman,讓能支援 extman 的腳本即便沒有 extman 還是能運作。
它會先檢查處理常式是否已經存在。接著,如果缺少 extman 函式,例如 scite_OnChar
,便會建立一個非常簡單的替代處理常式。當然,這個測試 extman 並非萬無一失。其餘程式碼就能利用 extman 函式,彷彿一切正常一樣。簡單的 scite_OnChar
函式只能處理一個處理常式;如果東西複雜得多,你最好強迫使用者安裝 extman。
if OnChar and not scite_OnChar then error("Please use extman if you want to run more than one handler") elseif not scite_OnChar then local _OnChar scite_OnChar = function(f, remove) if remove then _OnChar = nil else _OnChar = f end end OnChar = function(c) if _OnChar then return _OnChar(c) end end end
Extman 很棒,不過如果我能控制它產生 scite_temp1 檔案的位置會更好。我通常會建立一次檔案,並且註解掉產生程式碼,然後重新導向 extman 到已建立的檔案,在 scite 可執行檔案所在的目錄中開啟該檔案。
曾經嘗試使用 extman.zip 附帶的 switch_headers.lua,並且使用 SciTE 1.74,不過執行時遇到了一些問題。必須變更下列程式碼。從
for i,v in list do變成
for i,v in pairs(list) do以及從
for i,ext in extensions do變成
for i,ext in pairs (extensions) do
9a10 > if string.find(f,'[\\/]$') then return end 11a13 > if (f ~= "") then 20a23 > end 30c33,35 < scite_UserListShow(buffers,2,scite.Open) --- > if (table.getn(buffers) > 0) then > scite_UserListShow(buffers,1,scite.Open) > end
scite_Files
將 test.lua
和 test.lua~
都比對 *.lua
,並載入兩者(後者覆寫前者)。後者是 Emacs 保存的臨時備份檔案,並且花了點時間找出為什麼我編輯的 test.lua
雖然被載入,但是卻沒有任何效果。在 Windows 中,我建議使用 dir *.*
來比對目錄中的所有檔案,然後使用 FileGlob 中的 globtopattern
函式來篩選清單。順便一提,SciteDebug [1] 在 extman.lua 中對 scite_Files
有不同的實作。它會呼叫 scite_Popen
,視可用性選擇性包覆 spawner.popen
或 os.execute
。我不確定這樣做的確切目的,但確實可以避免呼叫此函數時可能會暫時彈出的 DOS 命令視窗 (至少我在嘗試時如此)。將兩個版本的 extman.lua 合併可能很有用。--DavidManura
-- 回覆於另一版本 extman.lua 的上述評論,如果我沒記錯,spawner.popen 會使用共用程式庫 (在 Windows 上是 dll)。它的創建目的是為了處理 DOS 命令視窗開啟和關閉以及 SciTE 程式因此在 Windows 中失去焦點的問題。執行時仍然會有明顯的視覺副作用,但因為不會失去焦點,所以比 os.execute 好。我個人的偏好是在 lua 目錄中的腳本數量實際改變時生成 scite_temp1 一次,然後直接讀取檔案。這樣就可避免使用任何方法進行 shell 外傳,以及在每次開啟 SciTE 時產生視覺上的中斷。
剛在網路上搜尋 extman.lua 程式碼的最新版本,沒想到現在已經有相當多版本,其中一些具有重大擴充功能。如果有人能彙整一個新 wiki 頁面,其中有一個版本包含所有這些功能的精華,或至少可以在這裡新增一個連結到網路上某個網站上的版本,該版本是最新的,並且能與大部分 lua 腳本最佳相容,那就太好了。 --(Lua User)
依我之見,應該手動包含檔案,而不是包含來自資料夾中的所有檔案。這也可以消除使用 spawner dll 或檢視臨時命令提示的需求。舉例來說,您可以在 SciteReadTags 中看到我的縮小版 extman.lua。 --ParsKorata
此腳本的用處是...嗯,自動繼續註解!
把它儲存在 ../scite_lua/ 資料夾中,檔名為 <filename>.lua,然後重新啟動 SciTE。(它應該是與平台無關的!)
--auto_continue_comments.lua --determine correct eol marker (later) from this lookup table local eol_tbl = {[0]="\r\n", [1]="\r", [2]="\n"} function auto_continue_comment(line) -- Multiline comment continue local multi = line:match("^(%s*)==%s*$") if multi then --line contains "==", start multiline comment local eol = eol_tbl[editor.EOLMode] editor:BeginUndoAction() editor:LineUp() editor:LineDelete() editor:AddText("--[=[" .. eol .. eol .. "--]=]" .. eol) editor:LineUp(); editor:LineUp() editor:AddText(multi) editor:EndUndoAction() -- block comment continue elseif line:find("^%s*%-%-%s*$") then --line is only '--', terminate comment editor:LineUp() editor:LineDelete() elseif line:find("^%s*%-%-") then --line is comment, auto continue it editor:AddText("-- ") end return false --allow other methods to respond to event end --register handler with extman scite_OnEditorLine(auto_continue_comment)
輸入 '--' 接著文字,按下 Enter 鍵,然後 '--' 已經插入在下一行了!如果不想要,只要再按一次 Enter 鍵即可刪除!輸入 '==' 並按 Enter 鍵,即可建立多行註解,然後將游標置於其中!感謝 SirAlaran? 的啟發。請看以下的範例工作階段。--PeterMacDonald
-- <- followed by text starts a block comment -- and it carries on until a line with only "--" -- A tab or spaces before "-- some text", will -- start an indented block comment, like this! --[=[ Entering "==" on a line, like this: == will start a multiline comment, like this one! --]=] --[=[ A tab or spaces before the "==" will start an indented multiline comment, like this! --]=]