diff options
Diffstat (limited to 'modules/textadept')
-rw-r--r-- | modules/textadept/editing.lua | 62 | ||||
-rw-r--r-- | modules/textadept/keys.lua | 3 | ||||
-rw-r--r-- | modules/textadept/menu.lua | 1 |
3 files changed, 66 insertions, 0 deletions
diff --git a/modules/textadept/editing.lua b/modules/textadept/editing.lua index 1624ee6d..35016c71 100644 --- a/modules/textadept/editing.lua +++ b/modules/textadept/editing.lua @@ -230,6 +230,68 @@ events.connect(events.FILE_BEFORE_SAVE, function() end) --- +-- Pastes the text from the clipboard, taking into account the buffer's +-- indentation settings and the indentation of the current and preceding lines. +-- @name paste_reindent +function M.paste_reindent() + local line = buffer:line_from_position(buffer.selection_start) + -- Strip leading indentation from clipboard text. + local text = ui.clipboard_text + if not buffer.encoding then text = text:iconv('CP1252', 'UTF-8') end + if buffer.eol_mode == buffer.EOL_CRLF then + text = text:gsub('^\n', '\r\n'):gsub('([^\r])\n', '%1\r\n') + end + local lead = text:match('^[ \t]*') + if lead ~= '' then text = text:sub(#lead + 1):gsub('\n'..lead, '\n') end + -- Change indentation to match buffer indentation settings. + local tab_width = math.huge + text = text:gsub('\n([ \t]+)', function(indentation) + if indentation:find('^\t') then + if buffer.use_tabs then return '\n'..indentation end + return '\n'..indentation:gsub('\t', string.rep(' ', buffer.tab_width)) + else + tab_width = math.min(tab_width, #indentation) + local indent = math.floor(#indentation / tab_width) + local spaces = string.rep(' ', math.fmod(#indentation, tab_width)) + if buffer.use_tabs then return '\n'..string.rep('\t', indent)..spaces end + return '\n'..string.rep(' ', buffer.tab_width):rep(indent)..spaces + end + end) + -- Re-indent according to whichever of the current and preceding lines has the + -- higher indentation amount. However, if the preceding line is a fold header, + -- indent by an extra level. + local i = line - 1 + while i >= 0 and buffer:get_line(i):find('^[\r\n]+$') do i = i - 1 end + if i < 0 or buffer.line_indentation[i] < buffer.line_indentation[line] then + i = line + end + local indentation = buffer:text_range(buffer:position_from_line(i), + buffer.line_indent_position[i]) + local fold_header = i ~= line and + buffer.fold_level[i] & buffer.FOLDLEVELHEADERFLAG > 0 + if fold_header then + indentation = indentation..(buffer.use_tabs and '\t' or + string.rep(' ', buffer.tab_width)) + end + text = text:gsub('\n', '\n'..indentation) + -- Paste the text and adjust first and last line indentation accordingly. + local start_indent = buffer.line_indentation[i] + if fold_header then start_indent = start_indent + buffer.tab_width end + local end_line = buffer:line_from_position(buffer.selection_end) + local end_indent = buffer.line_indentation[end_line] + local end_column = buffer.column[buffer.selection_end] + buffer:begin_undo_action() + buffer:replace_sel(text) + buffer.line_indentation[line] = start_indent + if text:find('\n') then + local line = buffer:line_from_position(buffer.current_pos) + buffer.line_indentation[line] = end_indent + buffer:goto_pos(buffer:find_column(line, end_column)) + end + buffer:end_undo_action() +end + +--- -- Comments or uncomments the selected lines based on the current language. -- As long as any part of a line is selected, the entire line is eligible for -- commenting/uncommenting. diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua index df4359f7..2d9cc31f 100644 --- a/modules/textadept/keys.lua +++ b/modules/textadept/keys.lua @@ -30,6 +30,7 @@ local M = {} -- Ctrl+X<br/>Shift+Del |⌘X<br/>⇧⌦|^X |Cut -- Ctrl+C<br/>Ctrl+Ins |⌘C |^C |Copy -- Ctrl+V<br/>Shift+Ins |⌘V |^V |Paste +-- Ctrl+Shift+V |⌘⇧V |M-V |Paste Reindent -- Ctrl+D |⌘D |None |Duplicate line -- Del |⌦<br/>^D |Del<br/>^D |Delete -- Alt+Del |^⌦ |M-Del<br/>M-D |Delete word @@ -297,6 +298,8 @@ keys[not OSX and GUI and 'cZ' or 'mZ'] = buffer.redo keys[not OSX and 'cx' or 'mx'] = buffer.cut keys[not OSX and 'cc' or 'mc'] = buffer.copy keys[not OSX and 'cv' or 'mv'] = buffer.paste +keys[not OSX and (GUI and 'cV' or 'mv') + or 'mV'] = textadept.editing.paste_reindent if GUI then keys[not OSX and 'cd' or 'md'] = buffer.line_duplicate end keys.del = buffer.clear keys[not OSX and (GUI and 'adel' or 'mdel') diff --git a/modules/textadept/menu.lua b/modules/textadept/menu.lua index 55371b4e..caaa3463 100644 --- a/modules/textadept/menu.lua +++ b/modules/textadept/menu.lua @@ -82,6 +82,7 @@ local default_menubar = { {_L['Cu_t'], buffer.cut}, {_L['_Copy'], buffer.copy}, {_L['_Paste'], buffer.paste}, + {_L['Paste Re_indent'], textadept.editing.paste_reindent}, {_L['Duplicate _Line'], buffer.line_duplicate}, {_L['_Delete'], buffer.clear}, {_L['D_elete Word'], function() |