diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/textadept/editing.lua | 58 | ||||
-rw-r--r-- | modules/textadept/keys.lua | 2 | ||||
-rw-r--r-- | modules/textadept/menu.lua | 6 |
3 files changed, 62 insertions, 4 deletions
diff --git a/modules/textadept/editing.lua b/modules/textadept/editing.lua index 4f6dc61e..75844a44 100644 --- a/modules/textadept/editing.lua +++ b/modules/textadept/editing.lua @@ -11,6 +11,9 @@ local M = {} -- @field strip_trailing_spaces (bool) -- Strip trailing whitespace before saving files. -- The default value is `false`. +-- @field paste_reindents (bool) +-- Reindent pasted text according to the buffer's indentation settings. +-- The default value is `true`. -- @field autocomplete_all_words (bool) -- Autocomplete the current word using words from all open buffers. -- If `true`, performance may be slow when many buffers are open. @@ -23,6 +26,7 @@ module('textadept.editing')]] M.auto_indent = true M.strip_trailing_spaces = false +M.paste_reindents = true M.autocomplete_all_words = false M.INDIC_BRACEMATCH = _SCINTILLA.next_indic_number() M.INDIC_HIGHLIGHT = _SCINTILLA.next_indic_number() @@ -226,6 +230,60 @@ 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 +function M.paste() + local line = buffer:line_from_position(buffer.selection_start) + if not M.paste_reindents or + buffer.selection_start > buffer.line_indent_position[line] then + buffer:paste() + return + end + -- Strip leading indentation from clipboard text. + local text = ui.clipboard_text + local lead = text:match('^%s*') + 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. + 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 s, e = buffer:position_from_line(i), buffer.line_indent_position[i] + text = text:gsub('\n', '\n'..buffer:text_range(s, e)) + -- Paste the text and adjust first and last line indentation accordingly. + local start_indent = buffer.line_indentation[i] + 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 + +--- -- Goes to the current character's matching brace, selecting the text in between -- if *select* is `true`. -- @param select Optional flag indicating whether or not to select the text diff --git a/modules/textadept/keys.lua b/modules/textadept/keys.lua index e5f0d8f5..40ff9ef9 100644 --- a/modules/textadept/keys.lua +++ b/modules/textadept/keys.lua @@ -297,7 +297,7 @@ if not OSX then keys.cy = buffer.redo end 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 'cv' or 'mv'] = textadept.editing.paste 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 82104336..ad23552f 100644 --- a/modules/textadept/menu.lua +++ b/modules/textadept/menu.lua @@ -18,8 +18,8 @@ local SEPARATOR = {''} -- The following buffer functions need to be constantized in order for menu -- items to identify the key associated with the functions. local menu_buffer_functions = { - 'undo', 'redo', 'cut', 'copy', 'paste', 'line_duplicate', 'clear', - 'select_all', 'upper_case', 'lower_case', 'move_selected_lines_up', + 'undo', 'redo', 'cut', 'copy', 'line_duplicate', 'clear', 'select_all', + 'upper_case', 'lower_case', 'move_selected_lines_up', 'move_selected_lines_down', 'zoom_in', 'zoom_out', 'colourise' } for i = 1, #menu_buffer_functions do @@ -81,7 +81,7 @@ local default_menubar = { SEPARATOR, {_L['Cu_t'], buffer.cut}, {_L['_Copy'], buffer.copy}, - {_L['_Paste'], buffer.paste}, + {_L['_Paste'], textadept.editing.paste}, {_L['Duplicate _Line'], buffer.line_duplicate}, {_L['_Delete'], buffer.clear}, {_L['D_elete Word'], function() |