Auto-identation in Lua code language
-
Is it possible? Having to tabulate scoping manually in Lua scripts is quite a hassle to do. In other code languages (like C++) auto-identation works fine.
-
Nothing is built in to do it for Lua, however you can write a script to do it. Ironically using Lua. You need to install LuaScript (through the plugin manager) and add this code to it’s startup script.
-- Regexs to determine when to indent or unindent -- From: https://github.com/sublimehq/Packages/blob/master/Lua/Indent.tmPreferences local decreaseIndentPattern = [[^\s*(elseif|else|end|\})\s*$]] local increaseIndentPattern = [[^\s*(else|elseif|for|(local\s+)?function|if|repeat|until|while)\b((?!end).)*$|\{\s*$]] do_increase = false -- Get the start and end position of a specific line number local function getLinePositions(line_num) local start_pos = editor:PositionFromLine(line_num) local end_pos = start_pos + editor:LineLength(line_num) return start_pos, end_pos end -- Check any time a character is added local function autoIndent_OnChar(ch) if ch == "\n" then -- Get the previous line local line_num = editor:LineFromPosition(editor.CurrentPos) - 1 local start_pos, end_pos = getLinePositions(line_num) if editor:findtext(increaseIndentPattern, SCFIND_REGEXP, start_pos, end_pos) then -- This has to be delayed because N++'s auto-indentation hasn't triggered yet do_increase = true end else local line_num = editor:LineFromPosition(editor.CurrentPos) local start_pos, end_pos = getLinePositions(line_num) if editor:findtext(decreaseIndentPattern, SCFIND_REGEXP, start_pos, end_pos) then -- The pattern matched, now check the previous line's indenation if line_num > 1 and editor.LineIndentation[line_num - 1] <= editor.LineIndentation[line_num] then editor.LineIndentation[line_num] = editor.LineIndentation[line_num] - 4 end end end return false end -- Work around N++'s auto indentation by delaying the indentation change local function autoIndent_OnUpdateUI(flags) if do_increase then do_increase = false -- Now the the indentation can be increased since N++'s auto-indentation is done by now editor:Tab() end return false end -- See if the auto indentation should be turned on or off local function checkAutoIndent(bufferid) if npp.BufferLangType[bufferid] == L_LUA then do_increase = false -- Register the event handlers npp.AddEventHandler("OnChar", autoIndent_OnChar) npp.AddEventHandler("OnUpdateUI", autoIndent_OnUpdateUI) else -- Remove the event handlers npp.RemoveEventHandler("OnChar", autoIndent_OnChar) npp.RemoveEventHandler("OnUpdateUI", autoIndent_OnUpdateUI) end end -- Only turn on the auto indentation when it is actually a lua file -- Check it when the file is switched to and if the language changes npp.AddEventHandler("OnSwitchFile", function(filename, bufferid) checkAutoIndent(bufferid) return false end) npp.AddEventHandler("OnLangChange", function() checkAutoIndent(npp.CurrentBufferID) return false end)
And restart Notepad++.
This does however make some assumptions. It requires Windows or Unix line endings and has a tabwidth of 4 characters. In theory it shouldn’t be too hard to make the changes but it works for what I’ve been doing with it.
I’m not going to say this is perfect but it has very similar behavior to Sublime’s auto indentation. In the following example I never have to press tab, or shift+tab, or backspace at all:
Surprisingly it wouldn’t take alot of changes (and using the appropriate regexs from TextMate’s or Sublime’s config files) to make this work for alot more languages.
-
Thanks for help. Worked like magic.
-
seems like this broke in the letest version of NotePad++ (LuaScript version 9, NotePad++ version 7.7)
-
@patrick-irvold I haven’t tried this code for a while. If there is something broken in the most recent update, you can open an issue at https://github.com/dail8859/LuaScript
-
I just tested this script with LuaScript v9.0 on Notepad v7.7 and it fully works
without any syntax errors. It auto indented the lines as well as press “backspace” when I typed “end”.Thanks for posting this script @dail.