aboutsummaryrefslogtreecommitdiffhomepage
path: root/core
diff options
context:
space:
mode:
authorGravatar mitchell <70453897+667e-11@users.noreply.github.com>2013-09-29 21:09:56 -0400
committerGravatar mitchell <70453897+667e-11@users.noreply.github.com>2013-09-29 21:09:56 -0400
commit18d7be2d1eaaef73c56dc850a3172529726d7a34 (patch)
tree3eeffd78480b6ade940532e8dc3f143304b48cb6 /core
parentef23e13ac57cf6a8bcb04ccce10d2e5b34feec06 (diff)
Added new `ui.dialogs` module for more user-friendly dialog support.
As a result, removed `ui.filteredlist()` and changed `io.open_file()` and `io.snapopen()` APIs to accept tables of files and paths instead of "\n" delimited strings.
Diffstat (limited to 'core')
-rw-r--r--core/.ui.dialogs.luadoc415
-rw-r--r--core/file_io.lua128
-rw-r--r--core/ui.lua111
3 files changed, 538 insertions, 116 deletions
diff --git a/core/.ui.dialogs.luadoc b/core/.ui.dialogs.luadoc
new file mode 100644
index 00000000..dc3e99e8
--- /dev/null
+++ b/core/.ui.dialogs.luadoc
@@ -0,0 +1,415 @@
+-- Copyright 2007-2013 Mitchell mitchell.att.foicica.com. See LICENSE.
+-- This is a DUMMY FILE used for making LuaDoc for built-in functions in the
+-- ui.dialogs table.
+
+--- Provides a set of interactive dialog prompts for user input.
+module('ui.dialogs')
+
+---
+-- Prompts the user with a generic message box dialog defined by dialog options
+-- table *options*, returning the index of the selected button or, if
+-- *options*.`string_output` is `true`, the selected button's label.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the message box.
+--
+-- * `title`: The dialog's title text.
+-- * `text`: The dialog's main message text.
+-- * `informative_text`: The dialog's extra informative text.
+-- * `icon`: The dialog's GTK stock icon name. Examples are
+-- "gtk-dialog-error", "gtk-dialog-info", "gtk-dialog-question", and
+-- "gtk-dialog-warning". The dialog does not display an icon by default.
+-- * `icon_file`: The dialog's icon file path. This option has no effect when
+-- `icon` is set.
+-- * `button1`: The right-most button's label. The default value is
+-- `_L['_OK']`.
+-- * `button2`: The middle button's label.
+-- * `button3`: The left-most button's label. This option requires `button2`
+-- to be set.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code
+-- @usage ui.dialogs.msgbox{title = 'EOL Mode', text = 'Which EOL?',
+-- icon = 'gtk-dialog-question', button1 = 'CRLF', button2 = 'CR',
+-- button3 = 'LF'}
+function msgbox(options) end
+
+---
+-- Prompts the user with a generic message box dialog defined by dialog options
+-- table *options* and with localized "Ok" and "Cancel" buttons, returning the
+-- index of the selected button or, if *options*.`string_output` is `true`, the
+-- selected button's label.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the message box.
+--
+-- * `title`: The dialog's title text.
+-- * `text`: The dialog's main message text.
+-- * `informative_text`: The dialog's extra informative text.
+-- * `icon`: The dialog's GTK stock icon name. Examples are
+-- "gtk-dialog-error", "gtk-dialog-info", "gtk-dialog-question", and
+-- "gtk-dialog-warning". The dialog does not display an icon by default.
+-- * `icon_file`: The dialog's icon file path. This option has no effect when
+-- `icon` is set.
+-- * `no_cancel`: Do not display the "Cancel" button. The default value is
+-- `false`.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code
+function ok_msgbox(options) end
+
+---
+-- Prompts the user with a generic message box dialog defined by dialog options
+-- table *options* and with localized "Yes", "No", and "Cancel" buttons,
+-- returning the index of the selected button or, if *options*.`string_output`
+-- is `true`, the selected button's label.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the message box.
+--
+-- * `title`: The dialog's title text.
+-- * `text`: The dialog's main message text.
+-- * `informative_text`: The dialog's extra informative text.
+-- * `icon`: The dialog's GTK stock icon name. Examples are
+-- "gtk-dialog-error", "gtk-dialog-info", "gtk-dialog-question", and
+-- "gtk-dialog-warning". The dialog does not display an icon by default.
+-- * `icon_file`: The dialog's icon file path. This option has no effect when
+-- `icon` is set.
+-- * `no_cancel`: Do not display the "Cancel" button. The default value is
+-- `false`.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code
+function yesno_msgbox(options) end
+
+---
+-- Prompts the user with a one-line input box dialog defined by dialog options
+-- table *options*, returning the index of the selected button along with the
+-- input text or, if *options*.`string_output` is `true`, the selected button's
+-- label along with the input text.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the input box.
+--
+-- * `title`: The dialog's title text.
+-- * `informative_text`: The dialog's main message text.
+-- * `text`: The dialog's initial input text.
+-- * `button1`: The right-most button's label. The default value is
+-- `_L['_OK']`.
+-- * `button2`: The middle button's label.
+-- * `button3`: The left-most button's label. This option requires `button2`
+-- to be set.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, input text
+-- @usage ui.dialogs.inputbox{title = 'Goto Line', informative_text = 'Line:',
+-- text = '1'}
+function inputbox(options) end
+
+---
+-- Prompts the user with a one-line input box dialog defined by dialog options
+-- table *options* and with localized "Ok" and "Cancel" buttons, returning the
+-- index of the selected button along with the input text or, if
+-- *options*.`string_output` is `true`, the selected button's label along with
+-- the input text.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the input box.
+--
+-- * `title`: The dialog's title text.
+-- * `informative_text`: The dialog's main message text.
+-- * `text`: The dialog's initial input text.
+-- * `no_cancel`: Do not display the "Cancel" button. The default value is
+-- `false`.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, input text
+function standard_inputbux(options) end
+
+---
+-- Prompts the user with a one-line masked input box dialog defined by dialog
+-- options table *options*, returning the index of the selected button along
+-- with the input text or, if *options*.`string_output` is `true`, the selected
+-- button's label along with the input text.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the input box.
+--
+-- * `title`: The dialog's title text.
+-- * `informative_text`: The dialog's main message text.
+-- * `text`: The dialog's initial input text.
+-- * `button1`: The right-most button's label. The default value is
+-- `_L['_OK']`.
+-- * `button2`: The middle button's label.
+-- * `button3`: The left-most button's label. This option requires `button2`
+-- to be set.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, input text
+function secure_inputbox(options) end
+
+---
+-- Prompts the user with a one-line masked input box dialog defined by dialog
+-- options table *options* and with localized "Ok" and "Cancel" buttons,
+-- returning the index of the selected button along with the input text or, if
+-- *options*.`string_output` is `true`, the selected button's label along with
+-- the input text.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the input box.
+--
+-- * `title`: The dialog's title text.
+-- * `informative_text`: The dialog's main message text.
+-- * `text`: The dialog's initial input text.
+-- * `no_cancel`: Do not display the "Cancel" button. The default value is
+-- `false`.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, input text
+function secure_standard_inputbox(options) end
+
+---
+-- Prompts the user with a file selection dialog defined by dialog options
+-- table *options*, returning the string file selected or, if
+-- *options*.`select_multiple` is `true`, the list of files selected.
+-- If the user canceled the dialog, returns `nil`.
+-- @param options Table of key-value option pairs for the dialog.
+--
+-- * `title`: The dialog's title text.
+-- * `with_directory`: The initial filesystem directory to show.
+-- * `with_file`: The initially selected filename. This option requires
+-- `with_directory` to be set.
+-- * `with_extension`: The list of extensions selectable files must have.
+-- * `select_multiple`: Allow the user to select multiple files. The default
+-- value is `false`.
+-- * `select_only_directories`: Only allow the user to select directories. The
+-- default value is `false`.
+-- @return filename, list of filenames, or nil
+-- @usage ui.dialogs.fileselect{title = 'Open C File', with_directory = _HOME,
+-- with_extension = {'c', 'h'}, select_multiple = true}
+function fileselect(options) end
+
+---
+-- Prompts the user with a file save dialog defined by dialog options table
+-- *options*, returning the string file chosen.
+-- If the user canceled the dialog, returns `nil`.
+-- @param options Table of key-value option pairs for the dialog.
+--
+-- * `title`: The dialog's title text.
+-- * `with_directory`: The initial filesystem directory to show.
+-- * `with_file`: The initially chosen filename. This option requires
+-- `with_directory` to be set.
+-- * `with_extension`: The list of extensions selectable files must have.
+-- * `no_create_directories`: Prevent the user from creating new directories.
+-- The default value is `false`.
+-- @return filename or nil
+function filesave(options) end
+
+---
+-- Prompts the user with a multiple-line textbox dialog defined by dialog
+-- options table *options*, returning the index of the selected button along
+-- with the textbox text if *options*.`editable` is `true` or, if
+-- *options*.`string_output` is `true`, the selected button's label along with
+-- the textbox text if *options*.`editable` is also `true`.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the dialog.
+--
+-- * `title`: The dialog's title text.
+-- * `informative_text`: The dialog's main message text.
+-- * `text`: The dialog's initial textbox text.
+-- * `text_from_file`: The filename whose contents are loaded into the
+-- textbox. This option has no effect when `text` is given.
+-- * `button1`: The right-most button's label. The default value is
+-- `_L['_OK']`.
+-- * `button2`: The middle button's label.
+-- * `button3`: The left-most button's label. This option requires `button2`
+-- to be set.
+-- * `editable`: Allows the user to edit the text in the textbox. The default
+-- value is `false`.
+-- * `focus_textbox`: Focus the textbox instead of the dialog buttons. The
+-- default value is `false`.
+-- * `scroll_to`: Where to scroll the textbox text when it is not all visible.
+-- The available values are `"top"` and `"bottom"`. The default value is
+-- `"top"`.
+-- * `selected`: Select all textbox text. The default value is `false`.
+-- * `monospaced_font`: Use a monospaced font in the textbox instead of a
+-- proportional one. The default value is `false`.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status instead of the button's index or the exit code. The default value
+-- is `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, textbox text
+-- @usage ui.dialogs.textbox{title = 'License Agreement',
+-- informative_text = 'You agree to:', text_from_file = _HOME..'/LICENSE'}
+function textbox(options) end
+
+---
+-- Prompts the user with a drop down item selection dialog defined by dialog
+-- options table *options*, returning the index of the selected button along
+-- with the index of the selected item or, if *options*.`string_output` is
+-- `true`, the selected button's label along with the selected item's text.
+-- If *options*.`exit_onchange` closed the dialog, returns `4` along with either
+-- the index of the selected item or the selected item's text. If the dialog
+-- timed out, returns `0` or `"timeout"`. If the user canceled the dialog,
+-- returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the drop down dialog.
+--
+-- * `title`: The dialog's title text.
+-- * `text`: The dialog's main message text.
+-- * `items`: The list of string items to show in the drop down.
+-- * `button1`: The right-most button's label. The default value is
+-- `_L['_OK']`.
+-- * `button2`: The middle button's label.
+-- * `button3`: The left-most button's label. This option requires `button2`
+-- to be set.
+-- * `exit_onchange`: Close the dialog after selecting a new item. The default
+-- value is `false`.
+-- * `select`: The index of the initially selected list item. The default
+-- value is `1`.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status along with the selected item's text instead of the button's index
+-- or the exit code along with the item's index. The default value is
+-- `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, selected item
+-- @usage ui.dialogs.dropdown{title = 'Select Encoding', width = 200,
+-- items = io.encodings, string_output = true}
+function dropdown(options) end
+
+---
+-- Prompts the user with a drop down item selection dialog defined by dialog
+-- options table *options* and with localized "Ok" and "Cancel" buttons,
+-- returning the index of the selected button along with the index of the
+-- selected item or, if *options*.`string_output` is `true`, the selected
+-- button's label along with the selected item's text.
+-- If *options*.`exit_onchange` closed the dialog, returns `4` along with either
+-- the index of the selected item or the selected item's text. If the dialog
+-- timed out, returns `0` or `"timeout"`. If the user canceled the dialog,
+-- returns `-1` or `"delete"`.
+-- @param options Table of key-value option pairs for the drop down dialog.
+--
+-- * `title`: The dialog's title text.
+-- * `text`: The dialog's main message text.
+-- * `items`: The list of string items to show in the drop down.
+-- * `no_cancel`: Do not display the "Cancel" button. The default value is
+-- `false`.
+-- * `exit_onchange`: Close the dialog after selecting a new item. The default
+-- value is `false`.
+-- * `select`: The index of the initially selected list item. The default
+-- value is `1`.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status along with the selected item's text instead of the button's index
+-- or the exit code along with the item's index. The default value is
+-- `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, selected item
+function standard_dropdown(options) end
+
+---
+-- Prompts the user with a filtered list item selection dialog defined by dialog
+-- options table *options*, returning the index of the selected button along
+-- with the index(es) of the selected item(s) (depending on whether or not
+-- *options*.`select_multiple` is `true`) or, if *options*.`string_output` is
+-- `true`, the selected button's label along with the selected item's or items'
+-- text.
+-- If the dialog timed out, returns `0` or `"timeout"`. If the user canceled the
+-- dialog, returns `-1` or `"delete"`.
+-- Spaces in the filter text are treated as wildcards.
+-- @param options Table of key-value option pairs for the drop down dialog.
+--
+-- * `title`: The dialog's title text.
+-- * `text`: The dialog's main message text.
+-- * `columns`: The list of string column names for list rows.
+-- * `items`: The list of string items to show in the drop down.
+-- * `button1`: The right-most button's label. The default value is
+-- `_L['_OK']`.
+-- * `button2`: The middle button's label.
+-- * `button3`: The left-most button's label. This option requires `button2`
+-- to be set.
+-- * `select_multiple`: Allow the user to select multiple items. The default
+-- value is `false`.
+-- * `search_column`: The column number to filter the input text against. The
+-- default value is `1`. This option requires `columns` to be set and
+-- contain at least *n* column names.
+-- * `output_column`: The column number to use for `string_output`. The
+-- default value is `1`. This option requires `columns` to be set and
+-- contain at least *n* column names.
+-- * `string_output`: Return the selected button's label or the dialog's exit
+-- status along with the selected item's text instead of the button's index
+-- or the exit code along with the item's index. The default value is
+-- `false`.
+-- * `width`: The pixel width of the dialog.
+-- * `height`: The pixel height of the dialog.
+-- * `float`: Show the dialog on top of all desktop windows. The default value
+-- is `false`.
+-- * `timeout`: The number of seconds the dialog waits for the user to select
+-- a button before timing out. Dialogs do not time out by default.
+-- @return selected button or exit code, selected item or list of selected items
+-- @usage ui.dialogs.filteredlist{title = 'Title', columns = {'Foo', 'Bar'},
+-- items = {'a', 'b', 'c', 'd'}}
+function filteredlist(options) end
diff --git a/core/file_io.lua b/core/file_io.lua
index ce3bf8ec..09533196 100644
--- a/core/file_io.lua
+++ b/core/file_io.lua
@@ -91,22 +91,22 @@ io.boms = {
io.encodings = {'UTF-8', 'ASCII', 'ISO-8859-1', 'MacRoman'}
---
--- Opens *filenames*, a "\n" delimited string of filenames, or user-selected
--- files.
+-- Opens *filenames*, a string filename, table of filenames, or user-selected
+-- filenames.
-- Emits a `FILE_OPENED` event.
--- @param filenames Optional string list filenames to open. If `nil`, the user
--- is prompted with a fileselect dialog.
+-- @param filenames Optional string filename or table of filenames to open. If
+-- `nil`, the user is prompted with a fileselect dialog.
-- @see _G.events
-- @name open_file
function io.open_file(filenames)
- filenames = filenames or
- ui.dialog('fileselect',
- '--title', _L['Open'],
- '--select-multiple',
- '--with-directory',
- (buffer.filename or ''):match('^.+[/\\]') or '')
- for filename in filenames:gmatch('[^\n]+') do
- filename = filename:gsub('^file://', '')
+ if type(filenames) == 'string' then filenames = {filenames} end
+ filenames = filenames or ui.dialogs.fileselect{
+ title = _L['Open'], select_multiple = true,
+ with_directory = (buffer.filename or ''):match('^.+[/\\]')
+ }
+ if not filenames then return end
+ for i = 1, #filenames do
+ local filename = filenames[i]:gsub('^file://', '')
if WIN32 then filename = filename:gsub('/', '\\') end
for i, buffer in ipairs(_BUFFERS) do
if filename == buffer.filename then view:goto_buffer(i) return end
@@ -235,14 +235,12 @@ end
-- user is prompted for one.
-- @name save_file_as
function io.save_file_as(filename)
- local dir = (buffer.filename or ''):match('^.+[/\\]') or ''
- local name = (buffer.filename or ''):match('[^/\\]+$') or ''
- filename = filename or ui.dialog('filesave',
- '--title', _L['Save'],
- '--with-directory', dir,
- '--with-file', name:iconv('UTF-8', _CHARSET),
- '--no-newline')
- if filename == '' then return end
+ local dir, name = (buffer.filename or ''):match('^(.-[/\\]?)([^/\\]*)$')
+ filename = filename or ui.dialogs.filesave{
+ title = _L['Save'], with_directory = dir,
+ with_file = name:iconv('UTF-8', _CHARSET)
+ }
+ if not filename then return end
buffer.filename = filename
io.save_file()
events.emit(events.FILE_SAVED_AS, filename)
@@ -268,15 +266,13 @@ end
-- @name close_buffer
function io.close_buffer()
local filename = buffer.filename or buffer._type or _L['Untitled']
- if buffer.dirty and ui.dialog('msgbox',
- '--title', _L['Close without saving?'],
- '--text', _L['There are unsaved changes in'],
- '--informative-text',
- filename:iconv('UTF-8', _CHARSET),
- '--icon', 'gtk-dialog-question',
- '--button1', _L['_Cancel'],
- '--button2', _L['Close _without saving'],
- '--no-newline') ~= '2' then
+ if buffer.dirty and ui.dialogs.msgbox{
+ title = _L['Close without saving?'],
+ text = _L['There are unsaved changes in'],
+ informative_text = filename:iconv('UTF-8', _CHARSET),
+ icon = 'gtk-dialog-question', button1 = _L['_Cancel'],
+ button2 = _L['Close _without saving']
+ } ~= 2 then
return nil -- returning false can cause unwanted key command propagation
end
buffer:delete()
@@ -306,19 +302,15 @@ local function update_modified_file()
if not mod_time or not buffer.mod_time then return end
if buffer.mod_time < mod_time then
buffer.mod_time = mod_time
- if ui.dialog('yesno-msgbox',
- '--title', _L['Reload?'],
- '--text', _L['Reload modified file?'],
- '--informative-text',
- ('"%s"\n%s'):format(buffer.filename:iconv('UTF-8', _CHARSET),
- _L['has been modified. Reload it?']),
- '--icon', 'gtk-dialog-question',
- '--button1', _L['_Yes'],
- '--button2', _L['_No'],
- '--no-cancel',
- '--no-newline') == '1' then
- io.reload_file()
- end
+ local msg = string.format('"%s"\n%s',
+ buffer.filename:iconv('UTF-8', _CHARSET),
+ _L['has been modified. Reload it?'])
+ local button = ui.dialogs.msgbox{
+ title = _L['Reload?'], text = _L['Reload modified file?'],
+ informative_text = msg, icon = 'gtk-dialog-question',
+ button1 = _L['_Yes'], button2 = _L['_No']
+ }
+ if button == 1 then io.reload_file() end
end
end
events_connect(events.BUFFER_AFTER_SWITCH, update_modified_file)
@@ -342,14 +334,16 @@ function io.open_recent_file()
for _, filename in ipairs(io.recent_files) do
utf8_filenames[#utf8_filenames + 1] = filename:iconv('UTF-8', _CHARSET)
end
- local i = ui.filteredlist(_L['Open'], _L['File'], utf8_filenames, true,
- CURSES and {'--width', ui.size[1] - 2} or '')
- if i then io.open_file(io.recent_files[i + 1]) end
+ local button, i = ui.dialogs.filteredlist{
+ title = _L['Open'], columns = _L['File'], items = utf8_filenames,
+ width = CURSES and ui.size[1] - 2 or nil
+ }
+ if button == 1 and i then io.open_file(io.recent_files[i]) end
end
---
--- Quickly open files from *paths*, a "\n" delimited string of directory paths,
--- using a filtered list dialog.
+-- Quickly open files from *paths*, a string directory path or table of
+-- directory paths, using a filtered list dialog.
-- Files shown in the dialog do not match any pattern in string or table
-- *filter*, and, unless *exclude_FILTER* is `true`, `lfs.FILTER` as well. A
-- filter table contains Lua patterns that match filenames to exclude, with
@@ -358,13 +352,14 @@ end
-- pattern that follows. Use a table of raw file extensions assigned to an
-- `extensions` key for fast filtering by extension. The number of files in the
-- list is capped at `SNAPOPEN_MAX`.
--- @param paths String list of directory paths to search.
+-- @param paths String directory path or table of directory paths to search.
-- @param filter Optional filter for files and folders to exclude.
-- @param exclude_FILTER Optional flag indicating whether or not to exclude the
-- default filter `lfs.FILTER` in the search. If `false`, adds `lfs.FILTER` to
-- *filter*.
-- The default value is `false` to include the default filter.
--- @param ... Optional additional parameters to pass to `ui.dialog()`.
+-- @param opts Optional additional options to pass to
+-- `ui.dialogs.filteredlist()`.
-- @usage io.snapopen(buffer.filename:match('^.+/')) -- list all files in the
-- current file's directory, subject to the default filter
-- @usage io.snapopen('/project', '!%.lua$') -- list all Lua files in a project
@@ -374,27 +369,32 @@ end
-- @see lfs.FILTER
-- @see SNAPOPEN_MAX
-- @name snapopen
-function io.snapopen(paths, filter, exclude_FILTER, ...)
+function io.snapopen(paths, filter, exclude_FILTER, opts)
+ if type(paths) == 'string' then paths = {paths} end
local utf8_list = {}
- for path in paths:gmatch('[^\n]+') do
- lfs.dir_foreach(path, function(file)
+ for i = 1, #paths do
+ lfs.dir_foreach(paths[i], function(file)
if #utf8_list >= io.SNAPOPEN_MAX then return false end
file = file:gsub('^%.[/\\]', ''):iconv('UTF-8', _CHARSET)
utf8_list[#utf8_list + 1] = file
end, filter, exclude_FILTER)
end
if #utf8_list >= io.SNAPOPEN_MAX then
- ui.dialog('ok-msgbox',
- '--title', _L['File Limit Exceeded'],
- '--text',
- string.format('%d %s %d', io.SNAPOPEN_MAX,
- _L['files or more were found. Showing the first'],
- io.SNAPOPEN_MAX),
- '--icon', 'gtk-dialog-info',
- '--button1', _L['_OK'])
+ local msg = string.format('%d %s %d', io.SNAPOPEN_MAX,
+ _L['files or more were found. Showing the first'],
+ io.SNAPOPEN_MAX)
+ ui.dialogs.msgbox{
+ title = _L['File Limit Exceeded'], text = msg, icon = 'gtk-dialog-info'
+ }
end
- local width = CURSES and {'--width', ui.size[1] - 2} or ''
- local files = ui.filteredlist(_L['Open'], _L['File'], utf8_list, false,
- '--select-multiple', width, ...) or ''
- io.open_file(files:iconv(_CHARSET, 'UTF-8'))
+ local options = {
+ title = _L['Open'], columns = _L['File'], items = utf8_list,
+ button1 = _L['_OK'], button2 = _L['_Cancel'], select_multiple = true,
+ string_output = true, width = CURSES and ui.size[1] - 2 or nil
+ }
+ if opts then for k, v in pairs(opts) do options[k] = v end end
+ local button, files = ui.dialogs.filteredlist(options)
+ if button ~= _L['_OK'] or not files then return end
+ for i = 1, #files do files[i] = files[i]:iconv(_CHARSET, 'UTF-8') end
+ io.open_file(files)
end
diff --git a/core/ui.lua b/core/ui.lua
index 8149b9d7..f1ed2e30 100644
--- a/core/ui.lua
+++ b/core/ui.lua
@@ -70,43 +70,49 @@ function ui._print(buffer_type, ...) pcall(_print, buffer_type, ...) end
-- @name print
function ui.print(...) ui._print(_L['[Message Buffer]'], ...) end
----
--- Convenience function for `ui.dialog('filteredlist', ...)` with "Ok" and
--- "Cancel" buttons that returns the text or index of the selection depending on
--- the boolean value of *int_return*.
--- *title* is the title of the dialog, *columns* is a list of column names, and
--- *items* is a list of items to show.
--- @param title The title for the filtered list dialog.
--- @param columns A column name or list of column names.
--- @param items An item or list of items.
--- @param int_return Optional flag indicating whether to return the integer
--- index of the selected item in the filtered list or the string selected
--- item. A `true` value is not compatible with the `'--select-multiple'`
--- option. The default value is `false`.
--- @param ... Optional additional parameters to pass to `ui.dialog()`.
--- @return Either a string or integer on success; `nil` otherwise. In strings,
--- multiple items are separated by newlines.
--- @usage ui.filteredlist('Title', 'Foo', {'Bar', 'Baz'})
--- @usage ui.filteredlist('Title', {'Foo', 'Bar'}, {'a', 'b', 'c', 'd'}, false,
--- '--output-column', '2')
--- @see dialog
--- @name filteredlist
-function ui.filteredlist(title, columns, items, int_return, ...)
- local out = ui.dialog('filteredlist',
- '--title', title,
- '--button1', _L['_OK'],
- '--button2', _L['_Cancel'],
- '--no-newline',
- int_return and '' or '--string-output',
- '--columns', columns,
- '--items', items,
- ...)
- local patt = int_return and '^(%-?%d+)\n(%d+)$' or '^([^\n]+)\n(.+)$'
- local response, value = out:match(patt)
- if response == (int_return and '1' or _L['_OK']) then
- return not int_return and value or tonumber(value)
+-- Documentation is in core/.ui.dialogs.luadoc.
+ui.dialogs = setmetatable({}, {__index = function(t, k)
+ -- Wrapper for `ui.dialog(k)`, transforming the given table of arguments into
+ -- a set of command line arguments and transforming the resulting standard
+ -- output into Lua objects.
+ -- @param options Table of key-value command line options for gtdialog.
+ -- @return Lua objects depending on the dialog kind
+ return function(options)
+ if not options.button1 then options.button1 = _L['_OK'] end
+ if options.select then options.select = options.select - 1 end
+ -- Transform key-value pairs into command line arguments.
+ local args = {}
+ for option, value in pairs(options) do
+ if value then
+ args[#args + 1] = '--'..option:gsub('_', '-')
+ if value ~= true then args[#args + 1] = value end
+ end
+ end
+ -- Call gtdialog, stripping any trailing newline in the standard output.
+ local result = ui.dialog(k:gsub('_', '-'), table.unpack(args))
+ result = result:match('^(.-)\n?$')
+ -- Depending on the dialog type, transform the result into Lua objects.
+ if k == 'fileselect' or k == 'filesave' then
+ if result == '' then return nil end
+ if k == 'filesave' or not options.select_multiple then return result end
+ local files = {}
+ for file in result:gmatch('[^\n]+') do files[#files + 1] = file end
+ return files
+ elseif k == 'filteredlist' then
+ local button, value = result:match('^([^\n]+)\n?(.*)$')
+ if not options.string_output then button = tonumber(button) end
+ local items = {}
+ for item in value:gmatch('[^\n]+') do
+ items[#items + 1] = options.string_output and item or tonumber(item) + 1
+ end
+ return button, options.select_multiple and items or items[1]
+ elseif not options.string_output then
+ local i, value = result:match('^(%-?%d+)\n?(.*)$')
+ return tonumber(i), k ~= 'dropdown' and value or tonumber(value) + 1
+ end
+ return result:match('([^\n]+)\n(.*)$')
end
-end
+end})
---
-- Prompts the user to select a buffer to switch to.
@@ -120,9 +126,11 @@ function ui.switch_buffer()
items[#items + 1] = (buffer.dirty and '*' or '')..basename
items[#items + 1] = filename
end
- local i = ui.filteredlist(_L['Switch Buffers'], columns, items, true,
- CURSES and {'--width', ui.size[1] - 2} or '--')
- if i then view:goto_buffer(i + 1) end
+ local button, i = ui.dialogs.filteredlist{
+ title = _L['Switch Buffers'], columns = columns, items = items,
+ width = CURSES and ui.size[1] - 2 or nil
+ }
+ if button == 1 and i then view:goto_buffer(i) end
end
---
@@ -357,15 +365,12 @@ events_connect(events.QUIT, function()
list[#list + 1] = filename:iconv('UTF-8', _CHARSET)
end
end
- return #list < 1 or ui.dialog('msgbox',
- '--title', _L['Quit without saving?'],
- '--text',
- _L['The following buffers are unsaved:'],
- '--informative-text', table.concat(list, '\n'),
- '--icon', 'gtk-dialog-question',
- '--button1', _L['_Cancel'],
- '--button2', _L['Quit _without saving'],
- '--no-newline') == '2'
+ return #list < 1 or ui.dialogs.msgbox{
+ title = _L['Quit without saving?'],
+ text = _L['The following buffers are unsaved:'],
+ informative_text = table.concat(list, '\n'), icon = 'gtk-dialog-question',
+ button1 = _L['_Cancel'], button2 = _L['Quit _without saving']
+ } == 2
end)
events_connect(events.ERROR, ui.print)
@@ -388,14 +393,16 @@ local size
The functions below are Lua C functions.
---
--- Displays a [gtdialog][] of kind *kind* with the given string arguments to
--- pass to the dialog and returns a formatted string of the dialog's output.
+-- Low-level function for prompting the user with a [gtdialog][]s of kind *kind*
+-- with the given string and table arguments, returning a formatted string of
+-- the dialog's output.
+-- You probably want to use the higher-level functions in the [`ui.dialogs`][]
+-- module.
-- Table arguments containing strings are allowed and expanded in place. This is
-- useful for filtered list dialogs with many items.
--- For more information on gtdialog, see [http://foicica.com/gtdialog][].
--
-- [gtdialog]: http://foicica.com/gtdialog/02_Usage.html
--- [http://foicica.com/gtdialog]: http://foicica.com/gtdialog
+-- [`ui.dialogs`]: ui.dialogs.html
-- @param kind The kind of gtdialog.
-- @param ... Parameters to the gtdialog.
-- @return string gtdialog result.