123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- ---- keyboard shortcuts
- -- switch between last used tabs
- local last_buffer
- events.connect(events.BUFFER_BEFORE_SWITCH, function()
- last_buffer = buffer
- end)
- keys['ctrl+\t'] = function() -- ctrl + tab
- if (last_buffer ~= nil) then
- view.goto_buffer(_VIEWS[1], last_buffer)
- end
- end
- keys['ctrl+pgup'] = function() -- ctrl + page down
- view.goto_buffer(_VIEWS[1], -1)
- end
- keys['ctrl+pgdn'] = function() -- ctrl + page down
- view.goto_buffer(_VIEWS[1], 1)
- end
- keys.cT = function() io.open_recent_file() end
- keys['end'] = function() -- end - go to visible end of line (esp, when wrapped)
- buffer.line_end_display(buffer)
- end
- keys['home'] = function() -- home - go to visible beginning of line (esp, when wrapped)
- buffer.home_display(buffer)
- end
- keys['send'] = function() -- shift + end - select till the visible end of line (esp, when wrapped)
- buffer.line_end_display_extend(buffer)
- end
- keys['ctrl+p'] = function() -- ctrl + p
- textadept.menu.select_command()
- end
- keys['ctrl+g'] = textadept.editing.goto_line -- ctrl + g
- ---- theme
- if not CURSES then
- view:set_theme("base16-custom-dark", {
- -- font = "Inconsolata", -- you can set it, if you want
- fontsize = 14
- })
- end
- ---- convenient settings:
- events.connect(events.BUFFER_NEW, function(str)
- -- use tabs, always
- buffer.use_tabs = true
- buffer.tab_width = 4
- -- show whitespace, always
- buffer.view_ws = buffer.WS_VISIBLEALWAYS
- -- wrap long lines, always
- buffer.wrap_mode = buffer.WRAP_WHITESPACE
- -- paste on multiple cursor places
- buffer.multi_paste = buffer.MULTIPASTE_EACH
- end)
- ui.silent_print = true
- --[[
- Braces like Atom.
- Typing brace, e.g. { and pressing enter creates a new line with a tab between the brace.
- ]]
- keys['\n'] = function() -- enter
- local caret_pos = buffer.current_pos
- local match = buffer:brace_match(caret_pos, 0)
- local current_line_number = buffer:line_from_position(caret_pos)
- local current_line = buffer.get_line(buffer, current_line_number)
- buffer.new_line(buffer) -- handle normal enter/return
- if string.match(current_line, "%s%*%s") ~= nil and string.match(current_line, "%s%*%s") ~= '' then
- buffer:add_text( '* ' )
- elseif string.match(current_line, "((.*)/%*%*)") ~= nil and string.match(current_line, "((.*)/%*%*)") ~= '' then
- -- typed /** and pressed enter, creates new line with *
- buffer:add_text( ' * ' )
- end
- if match ~= -1 then -- if braces (), [], {} are found then...
- buffer.goto_pos(buffer, caret_pos)
- buffer.new_line(buffer)
- buffer:add_text('\t')
- end
- end
- --[[
- Javadoc/phpdoc implementation.
- place cursor on previous line than function line,
- then press ctrl+j
- ]]
- keys['ctrl+j'] = function() -- ctrl + j
- local lexer_type = buffer:get_lexer(true)
- if lexer_type == 'php' then
- local current_line_number = buffer:line_from_position(buffer.current_pos)
- local function_line = buffer.get_line(buffer, current_line_number + 1)
- buffer.new_line(buffer)
- buffer.move_selected_lines_up(buffer)
- if string.find(function_line, "function") ~= nil then
- local comment = '/**\n * %1(description)\n *'
- local placeholder_num = 2
- for w in string.gmatch(function_line, "%$[%a_]+[%a%d_]*") do
- comment = comment..'\n * @param %'..placeholder_num..'(type) '..w..' %'..(placeholder_num + 1)..'(description)'
- placeholder_num = placeholder_num + 2
- end
- comment = comment..'\n * return %'..placeholder_num..'(type)\n */'
- textadept.snippets._insert(comment)
- end
- end
- end
- -- delete the line with line number
- -- esp. for delete line
- function delete_line(line_number)
- buffer.goto_line(buffer, line_number)
- buffer.line_end_extend(buffer)
- buffer.clear(buffer)
- buffer.clear(buffer) -- delete line ending
- end
- -- only keep unique items on the table
- -- esp. for delete line
- function unique_table(mytable)
- -- from: https://stackoverflow.com/a/20067270
- local hash = {}
- local res = {}
- for _,v in ipairs(mytable) do
- if (not hash[v]) then
- res[#res+1] = v
- hash[v] = true
- end
- end
- return res
- end
- -- for sorting a table
- -- esp. for delete line
- -- from: https://stackoverflow.com/a/15706820
- function spairs(t, order)
- -- collect the keys
- local keys = {}
- for k in pairs(t) do keys[#keys+1] = k end
- -- if order function given, sort by it by passing the table and keys a, b,
- -- otherwise just sort the keys
- if order then
- table.sort(keys, function(a,b) return order(t, a, b) end)
- else
- table.sort(keys)
- end
- -- return the iterator function
- local i = 0
- return function()
- i = i + 1
- if keys[i] then
- return keys[i], t[keys[i]]
- end
- end
- end
- -- for getting line numbers that are selected or have a (multi)cursor on them
- function get_selected_or_focus_lines()
- local lines = {}
- -- first we determine which lines we want to delete
- for i = 1, buffer.selections do
- local s, e = buffer.selection_n_start[i], buffer.selection_n_end[i]
- -- not a selection, just a cursor placed (supports multi cursor)
- if s == e then
- local line_num = buffer:line_from_position(s)
- table.insert(lines, line_num)
- -- selection (supports multi selection)
- else
- local line_num_start = buffer:line_from_position(s)
- local line_num_end = buffer:line_from_position(e)
- for j = line_num_start, line_num_end do
- table.insert(lines, j)
- end
- end
- end
- -- we list one line only once
- -- this is a fix, if there are two selections in the same line
- lines = unique_table(lines)
- local kkey = 1
- local lines_ = {}
- for k,v in spairs(lines, function(t,a,b) return t[b] > t[a] end) do
- table.insert(lines_, v)
- kkey = kkey + 1
- end
- lines = lines_
- return lines
- end
- -- delete line(s)
- -- supports multi selection, multi cursor or both
- keys['ctrl+K'] = function() -- ctrl + shift + k
- buffer:begin_undo_action()
- local lines = get_selected_or_focus_lines()
- local lines_delete_offset = 0
- for key, line in ipairs(lines) do
- delete_line(line + lines_delete_offset)
- lines_delete_offset = lines_delete_offset - 1
- end
- buffer:end_undo_action()
- end
- -- pair multiline selections together in table
- -- it will help us to process selections differently
- function pair_line_numbers(lines)
- local paired_lines = {}
- local selection_open = false
- local last_begin = 0
- local last_end = 0
- for key, line in ipairs(lines) do
- if lines[key + 1] ~= nil and lines[key + 1] == lines[key] + 1 then
- if selection_open == false then
- last_begin = line
- selection_open = true
- end
- else
- if selection_open == true then
- last_end = line
- selection_open = false
- local data = {
- ['beginning'] = last_begin,
- ['ending'] = last_end
- }
- table.insert(paired_lines, data)
- else
- table.insert(paired_lines, line) -- normal line, not selection
- end
- end
- end
- return paired_lines
- end
- -- duplicate the lines passed
- -- supports multi selections + multi cursors
- function duplicate_line(line_number, offset)
- if (type(line_number) == "table") then
- local lines_queue = {}
- for i = line_number['beginning']+offset, line_number['ending']+offset do
- local line_contents = buffer.get_line(buffer, i)
- table.insert( lines_queue, line_contents )
- end
- buffer.goto_line(buffer, line_number['ending']+offset)
- for key, linetext in pairs(lines_queue) do
- buffer.line_end(buffer)
- buffer.new_line(buffer)
- local cursor_line = buffer:line_from_position( buffer.current_pos )
- textadept.editing.goto_line(cursor_line)
- buffer.line_end_display_extend(buffer)
- buffer.replace_sel(buffer, '')
- buffer.insert_text(buffer, -1, linetext)
- buffer.line_end(buffer)
- buffer.clear(buffer)
- end
- else
- buffer.goto_line(buffer, line_number + offset)
- buffer.line_duplicate()
- end
- end
- -- duplicate line(s)
- -- supports multi selection, multi cursor or both
- keys['ctrl+d'] = function() -- ctrl + d
- buffer:begin_undo_action()
- local lines = get_selected_or_focus_lines()
- local paired_lines = pair_line_numbers(lines)
- local lines_change_offset = 0
- for key, line in pairs(paired_lines) do
- if (type(line) == "table") then
- duplicate_line(line, lines_change_offset)
- lines_change_offset = lines_change_offset + (line['ending'] - line['beginning']) + 1
- else
- duplicate_line(line, lines_change_offset)
- lines_change_offset = lines_change_offset + 1
- end
- end
- buffer:end_undo_action()
- end
- -- highlight trailing whitespace
- -- from: https://foicica.com/wiki/highlight-trailing-whitespace
- local tw_indicator = _SCINTILLA.next_indic_number()
- buffer.indic_style[tw_indicator] = buffer.INDIC_ROUNDBOX
- buffer.indic_fore[tw_indicator] = 0x0000FF
- events.connect(events.UPDATE_UI, function(updated)
- if updated ~= buffer.UPDATE_CONTENT then return end
- buffer.target_start = 0
- buffer.search_flags = buffer.FIND_REGEXP
- buffer.indicator_current = tw_indicator
- buffer:indicator_clear_range(0, buffer.length)
- while true do
- buffer.target_end = buffer.length
- if buffer:search_in_target('[ \t]+$') == -1 then break end
- buffer:indicator_fill_range(
- buffer.target_start, buffer.target_end - buffer.target_start)
- buffer.target_start = buffer.target_end
- end
- end)
- -- from https://github.com/rgieseke/textadept/blob/d184ca77570bdc72a97b9dee02ee8cea9844c9a6/modules/textadept/editing.lua#L208
- function trim_whitespace(buffer)
- buffer:begin_undo_action()
- -- Strip trailing whitespace.
- for line = 0, buffer.line_count - 1 do
- local s, e = buffer:position_from_line(line), buffer.line_end_position[line]
- local i, byte = e - 1, buffer.char_at[e - 1]
- while i >= s and (byte == 9 or byte == 32) do
- i, byte = i - 1, buffer.char_at[i - 1]
- end
- if i < e - 1 then buffer:delete_range(i + 1, e - i - 1) end
- end
- -- Ensure ending newline.
- local e = buffer:position_from_line(buffer.line_count)
- if buffer.line_count == 1 or
- e > buffer:position_from_line(buffer.line_count - 1) then
- buffer:insert_text(e, '\n')
- end
- -- Convert non-consistent EOLs
- buffer:convert_eols(buffer.eol_mode)
- buffer:end_undo_action()
- end
- -- selects the line with the line_number given
- function select_line(line_number)
- local line_beginning = buffer:position_from_line(line_number)
- local line_ending = buffer.line_end_position[line_number]
- buffer.add_selection(line_ending, line_beginning)
- end
- keys['ctrl+l'] = function() -- ctrl + l
- local lines = get_selected_or_focus_lines()
- for key, line in ipairs(lines) do
- select_line(line)
- end
- end
- -- close tab on middle click
- -- patching source is required to work
- if events.TAB_MIDDLE_CLICK then
- events.connect(events.TAB_MIDDLE_CLICK, function()
- io.close_buffer()
- end)
- end
- -- new tab on middle click on blank space
- -- patching source is required to work
- if events.TAB_MIDDLE_CLICK_BLANK then
- events.connect(events.TAB_MIDDLE_CLICK_BLANK, buffer.new)
- end
- -- new tab on double click on blank space
- -- patching source is required to work
- if events.TAB_DOUBLE_CLICK_BLANK then
- events.connect(events.TAB_DOUBLE_CLICK_BLANK, buffer.new)
- end
- -- shows total number of selected characters on statusbar
- events.connect(events.UPDATE_UI, function()
- if buffer.UPDATE_SELECTION ~= 0 then
- local selcount = 0
- for i = 1, buffer.selections do
- selcount = selcount + (buffer.selection_n_end[i] - buffer.selection_n_start[i])
- end
- ui.statusbar_text = 'Sel: '..selcount
- end
- end)
- ---- context menu
- local lua_menu = {
- title = 'Extra',
- {'Copy current filename', function() buffer.copy_text(_G.buffer, _G.buffer.filename) end},
- {'Trim leading whitespace', function() trim_whitespace(_G.buffer) end},
- {'Set Filetype', keys['ctrl+L']},
- }
- local options_menu = textadept.menu.menubar[_L['Tools']]
- options_menu[#options_menu + 1] = lua_menu
- textadept.menu.context_menu[#textadept.menu.context_menu + 1] = lua_menu
- -- various other language related mods
- _M.mods = require 'mods'
- _M.mods = require 'hotexit'
|