aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept
diff options
context:
space:
mode:
authormitchell <70453897+667e-11@users.noreply.github.com>2007-08-10 17:12:50 -0400
committermitchell <70453897+667e-11@users.noreply.github.com>2007-08-10 17:12:50 -0400
commit6362d808eab3b9a7adf591d306687b439ba85031 (patch)
tree3934c3e539d0bfd5902bb09e013bf7216b4bee2f /modules/textadept
parent473c7c0973a3f0760efac0e54c68b420695baff9 (diff)
downloadtextadept-6362d808eab3b9a7adf591d306687b439ba85031.tar.gz
textadept-6362d808eab3b9a7adf591d306687b439ba85031.zip
Macros can now be recorded, saved, played, browsed, etc.
Diffstat (limited to 'modules/textadept')
-rw-r--r--modules/textadept/init.lua1
-rw-r--r--modules/textadept/key_commands.lua11
-rw-r--r--modules/textadept/macros.lua176
3 files changed, 185 insertions, 3 deletions
diff --git a/modules/textadept/init.lua b/modules/textadept/init.lua
index ee985df3..ea744c75 100644
--- a/modules/textadept/init.lua
+++ b/modules/textadept/init.lua
@@ -7,6 +7,7 @@ module('_m.textadept', package.seeall)
require 'textadept.editing'
require 'textadept.keys'
+require 'textadept.macros'
require 'textadept.mlines'
require 'textadept.snippets'
require 'textadept.key_commands' -- last
diff --git a/modules/textadept/key_commands.lua b/modules/textadept/key_commands.lua
index 55f038e4..c7239c7c 100644
--- a/modules/textadept/key_commands.lua
+++ b/modules/textadept/key_commands.lua
@@ -6,11 +6,11 @@ module('_m.textadept.key_commands', package.seeall)
--[[
C: G Q
- A: A C G J K L M O Q R W X Z
+ A: A C G J K L O Q R W X Z
CS: C D G J L Q R S T U W
SA: A C D E G H I J K L M O Q R S T W X Z
- CA: A C G H J K L M O Q R S T V W X Y Z
- CSA: C D G H J K L M O Q R S T U W X Z
+ CA: A C G H J K L O Q R S T V W X Y Z
+ CSA: C D G H J K L O Q R S T U W X Z
]]--
---
@@ -126,6 +126,10 @@ keys.am = {
c = { m_mlines.clear },
}
+local m_macro = _m.textadept.macros
+keys.cam = { m_macro.toggle_record }
+keys.csam = { m_macro.play }
+
keys.cr = { textadept.io.open }
keys.co = { 'save', b }
keys.cso = { 'save_as', b }
@@ -161,6 +165,7 @@ keys.ct.ss = { 'split', v } -- vertical
keys.ct.n = { textadept.new_buffer }
keys.ct.b = { pm_activate, 'buffers' }
keys.ct.c = { pm_activate, 'ctags' }
+keys.ct.m = { pm_activate, 'macros' }
keys.ct.x = { function() view:unsplit() return true end }
keys.ct.sx = { function() while view:unsplit() do end end }
keys.ct.f = { function()
diff --git a/modules/textadept/macros.lua b/modules/textadept/macros.lua
new file mode 100644
index 00000000..0ba966c6
--- /dev/null
+++ b/modules/textadept/macros.lua
@@ -0,0 +1,176 @@
+-- Copyright 2007 Mitchell mitchell<att>caladbolg.net. See LICENSE.
+
+---
+-- Support for recording, saving, and playing macros for the textadept module.
+module('_m.textadept.macros', package.seeall)
+
+local MACRO_FILE = _HOME..'/saved_macros'
+
+---
+-- The list of available macros.
+-- Each key is the macro name, and the value is a numerically indexed table of
+-- commands. Each command is a table with a structure as follows:
+-- { command, wParam, lParam, type = 'function' or 'property' }
+-- where command is the buffer function or property name (depending on type)
+-- and wParam and lParam are the arguments for it.
+-- @class table
+-- @name list
+list = {}
+
+---
+-- [Local table] The currently recording macro.
+-- It is a numerically indexed table of commands with each command having the
+-- same structure as described in list.
+-- @class table
+-- @name current
+-- @see list
+local current = {}
+
+local recording = false
+
+---
+-- [Local function] Handles a Scintilla macro notification.
+-- If a macro is being recorded, add this command to 'current'.
+-- @param msg The Scintilla message ID.
+local function macro_notification(msg, wParam, lParam)
+ if recording then
+ current[#current + 1] = { msg, wParam or '', lParam or '' }
+ textadept.statusbar_text = 'Macro recording'
+ end
+end
+textadept.handlers.add_function_to_handler('macro_record', macro_notification)
+
+---
+-- Starts recording a macro.
+function start_recording()
+ if recording then return end
+ buffer:start_record()
+ current = {}
+ recording = true
+ textadept.statusbar_text = 'Macro recording'
+end
+
+---
+-- Stops recording a macro.
+-- Each command's msg in the recorded macro is changed to the name of the
+-- message and the type of the command is changed appropriately (function or
+-- property). Then the user is prompted for a macro name and the macro is saved
+-- to the current macro list and macro file.
+function stop_recording()
+ if not recording then return end
+ buffer:stop_record()
+ recording = false
+ local textadept = textadept
+ local bf, bp = textadept.buffer_functions, textadept.buffer_properties
+ local macro_name =
+ io.popen('zenity --entry --text "Macro name:"'):read('*all'):sub(1, -2)
+ if #macro_name > 0 then
+ for _, command in ipairs(current) do
+ command.type = 'function'
+ local msg = command[1]
+ for f, t in pairs(bf) do
+ if t[1] == msg then command[1] = f break end
+ end
+ if type( command[1] ) ~= 'string' then
+ command.type = 'property'
+ for p, t in pairs(bp) do
+ if t[1] == msg or t[2] == msg then command[1] = p break end
+ end
+ end
+ end
+ list[macro_name] = current
+ save()
+ textadept.statusbar_text = 'Macro saved'
+ textadept.handlers.handle('macro_saved')
+ else
+ textadept.statusbar_text = 'Macro not saved'
+ end
+end
+
+---
+-- Toggles between recording a macro and not recording one.
+function toggle_record()
+ (not recording and start_recording or stop_recording)()
+end
+
+---
+-- Plays a specified macro.
+-- @param macro_name The name of the macro to play. If none specified, the user
+-- is prompted to choose one from a list of available macros.
+function play(macro_name)
+ if not macro_name then
+ local macro_list = ''
+ for name in pairs(list) do macro_list = macro_list..name..' ' end
+ macro_name = io.popen('zenity --list --text "Select a Macro" '..
+ '--column Name '..macro_list):read('*all'):sub(1, -2)
+ end
+ local macro = list[macro_name]
+ if not macro then return end
+ local buffer = buffer
+ for _, command in ipairs(macro) do
+ local cmd, wParam, lParam = unpack(command)
+ if command.type == 'function' then
+ buffer[cmd](buffer, wParam, lParam)
+ else
+ buffer[cmd] = #wParam > 0 and wParam or lParam
+ end
+ end
+end
+
+---
+-- Deletes a specified macro.
+-- @param macro_name The name of the macro to delete.
+function delete(macro_name)
+ if list[macro_name] then
+ list[macro_name] = nil
+ save()
+ textadept.handlers.handle('macro_deleted')
+ end
+end
+
+---
+-- Saves the current list of macros to a specified file.
+-- @param filename The absolute path to the file to save the macros to.
+function save(filename)
+ if not filename then filename = MACRO_FILE end
+ local f = assert( io.open(filename, 'w') )
+ for name, macro in pairs(list) do
+ f:write(name, '\n')
+ for _, command in ipairs(macro) do
+ f:write( ("%s\t%s\t%s\t%s\n"):format( command.type, unpack(command) ) )
+ end
+ f:write('\n')
+ end
+ f:close()
+end
+
+---
+-- Loads macros from a specified file.
+-- @param filename The absolute path to the file to load the macros from.
+function load(filename)
+ if not filename then filename = MACRO_FILE end
+ local f = io.open(filename)
+ if not f then return end
+ local name, current_macro
+ for line in f:lines() do
+ if not name then -- new macro
+ name = line
+ current_macro = {}
+ else
+ if line == '' then -- finished; save current macro
+ list[name] = current_macro
+ name = nil
+ else
+ local type, cmd, wParam, lParam =
+ line:match('^([^\t]+)\t([^\t]+)\t?([^\t]*)\t?(.*)$')
+ if type and cmd then
+ local command = { cmd, wParam, lParam }
+ command.type = type
+ current_macro[#current_macro + 1] = command
+ end
+ end
+ end
+ end
+end
+
+load() -- load saved macros on startup