2008-09-29 16:49:18 +02:00
|
|
|
---------------------------------------------------------------------------
|
2016-12-11 20:35:20 +01:00
|
|
|
--- Prompt module for awful.
|
|
|
|
--
|
2016-12-30 06:52:54 +01:00
|
|
|
-- **Keyboard navigation**:
|
|
|
|
--
|
|
|
|
-- The following readline keyboard shortcuts are implemented as expected:
|
|
|
|
-- <table class='widget_list' border=1>
|
|
|
|
-- <tr><th>Name</th><th>Usage</th></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+A</kbd></td><td>beginning-of-line</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+B</kbd></td><td>backward-char</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+C</kbd></td><td>cancel</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+D</kbd></td><td>delete-char</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+E</kbd></td><td>end-of-line</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+J</kbd></td><td>accept-line</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+M</kbd></td><td>accept-line</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+F</kbd></td><td>move-cursor-right</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+H</kbd></td><td>backward-delete-char</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+K</kbd></td><td>kill-line</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+U</kbd></td><td>unix-line-discard</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+W</kbd></td><td>unix-word-rubout</td></tr>
|
|
|
|
-- <tr><td><kbd>CTRL+BACKSPACE</kbd></td><td>unix-word-rubout</td></tr>
|
|
|
|
-- <tr><td><kbd>SHIFT+INSERT</kbd></td><td>paste</td></tr>
|
|
|
|
-- <tr><td><kbd>HOME</kbd></td><td>beginning-of-line</td></tr>
|
|
|
|
-- <tr><td><kbd>END</kbd></td><td>end-of-line</td></tr>
|
|
|
|
-- </table>
|
|
|
|
--
|
|
|
|
-- The following shortcuts implement additional history manipulation commands
|
|
|
|
-- where the search term is defined as the substring of the command from first
|
|
|
|
-- character to cursor position.
|
|
|
|
--
|
|
|
|
-- * <kbd>CTRL+R</kbd>: reverse history search, matches any history entry
|
|
|
|
-- containing search term.
|
|
|
|
-- * <kbd>CTRL+S</kbd>: forward history search, matches any history entry
|
|
|
|
-- containing search term.
|
|
|
|
-- * <kbd>CTRL+UP</kbd>: ZSH up line or search, matches any history entry
|
|
|
|
-- starting with search term.
|
|
|
|
-- * <kbd>CTRL+DOWN</kbd>: ZSH down line or search, matches any history
|
|
|
|
-- entry starting with search term.
|
|
|
|
-- * <kbd>CTRL+DELETE</kbd>: delete the currently visible history entry from
|
|
|
|
-- history file. This does not delete new commands or history entries under
|
|
|
|
-- user editing.
|
|
|
|
--
|
2016-12-30 06:45:49 +01:00
|
|
|
-- **Basic usage**:
|
|
|
|
--
|
2016-12-11 20:35:20 +01:00
|
|
|
-- By default, `rc.lua` will create one `awful.widget.prompt` per screen called
|
|
|
|
-- `mypromptbox`. It is used for both the command execution (`mod4+r`) and
|
|
|
|
-- Lua prompt (`mod4+x`). It can be re-used for random inputs using:
|
|
|
|
--
|
2016-12-30 06:45:49 +01:00
|
|
|
-- @DOC_wibox_awidget_prompt_simple_EXAMPLE@
|
2016-12-11 20:35:20 +01:00
|
|
|
--
|
2016-12-30 06:45:49 +01:00
|
|
|
-- -- Then **IN THE globalkeys TABLE** add a new shortcut
|
|
|
|
-- awful.key({ modkey }, "e", echo_test,
|
|
|
|
-- {description = "Echo a string", group = "custom"}),
|
2016-12-11 20:35:20 +01:00
|
|
|
--
|
|
|
|
-- Note that this assumes an `rc.lua` file based on the default one. The way
|
|
|
|
-- to access the screen prompt may vary.
|
2014-05-20 13:02:39 +02:00
|
|
|
--
|
2016-12-30 07:26:46 +01:00
|
|
|
-- **Extra key hooks**:
|
|
|
|
--
|
|
|
|
-- The Awesome prompt also supports adding custom extensions to specific
|
|
|
|
-- keyboard keybindings. Those keybindings have precedence over the built-in
|
|
|
|
-- ones. Therefor, they can be used to override the default ones.
|
|
|
|
--
|
|
|
|
-- *[Example one] Adding pre-configured `awful.spawn` commands:*
|
|
|
|
--
|
|
|
|
-- @DOC_wibox_awidget_prompt_hooks_EXAMPLE@
|
|
|
|
--
|
2016-12-30 07:30:13 +01:00
|
|
|
-- *[Example two] Modifying the command (+ vi like input)*:
|
|
|
|
--
|
|
|
|
-- The hook system also allows to modify the command before interpreting it in
|
|
|
|
-- the `exe_callback`.
|
|
|
|
--
|
|
|
|
-- @DOC_wibox_awidget_prompt_vilike_EXAMPLE@
|
|
|
|
--
|
2016-12-30 07:32:07 +01:00
|
|
|
-- *[Example three] Key listener*:
|
|
|
|
--
|
|
|
|
-- The 2 previous examples were focused on changing the prompt behavior. This
|
|
|
|
-- one explains how to "spy" on the prompt events. This can be used for
|
|
|
|
--
|
|
|
|
-- * Implementing more complex mutator
|
|
|
|
-- * Synchronising other widgets
|
|
|
|
-- * Showing extra tips to the user
|
|
|
|
--
|
|
|
|
-- @DOC_wibox_awidget_prompt_keypress_EXAMPLE@
|
2016-12-30 07:26:46 +01:00
|
|
|
--
|
2016-12-30 09:47:32 +01:00
|
|
|
-- **highlighting**:
|
|
|
|
--
|
|
|
|
-- The prompt also support custom highlighters:
|
|
|
|
--
|
|
|
|
-- @DOC_wibox_awidget_prompt_highlight_EXAMPLE@
|
|
|
|
--
|
2008-09-29 16:49:18 +02:00
|
|
|
-- @author Julien Danjou <julien@danjou.info>
|
|
|
|
-- @copyright 2008 Julien Danjou
|
2014-05-20 13:02:39 +02:00
|
|
|
-- @module awful.prompt
|
2008-09-29 16:49:18 +02:00
|
|
|
---------------------------------------------------------------------------
|
|
|
|
|
2017-01-22 19:13:50 +01:00
|
|
|
--- The prompt cursor foreground color.
|
|
|
|
-- @beautiful beautiful.prompt_fg_cursor
|
|
|
|
-- @param color
|
|
|
|
-- @see gears.color
|
|
|
|
|
|
|
|
--- The prompt cursor background color.
|
|
|
|
-- @beautiful beautiful.prompt_bg_cursor
|
|
|
|
-- @param color
|
|
|
|
-- @see gears.color
|
|
|
|
|
|
|
|
--- The prompt text font.
|
|
|
|
-- @beautiful beautiful.prompt_font
|
|
|
|
-- @param string
|
|
|
|
-- @see string
|
|
|
|
|
2008-09-29 16:49:18 +02:00
|
|
|
-- Grab environment we need
|
|
|
|
local assert = assert
|
|
|
|
local io = io
|
|
|
|
local table = table
|
2008-09-30 09:36:40 +02:00
|
|
|
local math = math
|
2009-04-27 21:04:15 +02:00
|
|
|
local ipairs = ipairs
|
2010-08-26 20:42:22 +02:00
|
|
|
local pcall = pcall
|
2008-09-29 16:49:18 +02:00
|
|
|
local capi =
|
|
|
|
{
|
2009-01-04 17:44:37 +01:00
|
|
|
selection = selection
|
2008-09-29 16:49:18 +02:00
|
|
|
}
|
2016-02-07 14:45:53 +01:00
|
|
|
local unpack = unpack or table.unpack -- luacheck: globals unpack (compatibility with Lua 5.1)
|
2012-04-30 17:47:37 +02:00
|
|
|
local keygrabber = require("awful.keygrabber")
|
2008-09-29 16:49:18 +02:00
|
|
|
local util = require("awful.util")
|
2008-11-13 11:53:41 +01:00
|
|
|
local beautiful = require("beautiful")
|
2016-06-19 06:23:46 +02:00
|
|
|
local akey = require("awful.key")
|
2017-02-20 06:24:04 +01:00
|
|
|
local debug = require('gears.debug')
|
2017-03-08 21:18:33 +01:00
|
|
|
local gtable = require("gears.table")
|
2017-03-03 00:02:03 +01:00
|
|
|
local gcolor = require("gears.color")
|
2008-09-29 16:49:18 +02:00
|
|
|
|
2012-06-12 20:13:09 +02:00
|
|
|
local prompt = {}
|
2008-09-29 16:49:18 +02:00
|
|
|
|
|
|
|
--- Private data
|
|
|
|
local data = {}
|
|
|
|
data.history = {}
|
|
|
|
|
2011-10-24 18:54:55 +02:00
|
|
|
local search_term = nil
|
|
|
|
local function itera (inc,a, i)
|
2016-12-11 20:39:05 +01:00
|
|
|
i = i + inc
|
|
|
|
local v = a[i]
|
|
|
|
if v then return i,v end
|
2011-10-24 18:54:55 +02:00
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Load history file in history table
|
2015-02-26 22:06:34 +01:00
|
|
|
-- @param id The data.history identifier which is the path to the filename.
|
|
|
|
-- @param[opt] max The maximum number of entries in file.
|
2008-09-29 16:49:18 +02:00
|
|
|
local function history_check_load(id, max)
|
2016-12-11 20:39:05 +01:00
|
|
|
if id and id ~= "" and not data.history[id] then
|
|
|
|
data.history[id] = { max = 50, table = {} }
|
2008-09-29 16:49:18 +02:00
|
|
|
|
2016-12-11 20:39:05 +01:00
|
|
|
if max then
|
2008-09-29 16:49:18 +02:00
|
|
|
data.history[id].max = max
|
2016-12-11 20:39:05 +01:00
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
|
2016-12-11 20:39:05 +01:00
|
|
|
local f = io.open(id, "r")
|
|
|
|
if not f then return end
|
2008-09-29 16:49:18 +02:00
|
|
|
|
2016-12-11 20:39:05 +01:00
|
|
|
-- Read history file
|
|
|
|
for line in f:lines() do
|
2017-03-08 21:18:33 +01:00
|
|
|
if gtable.hasitem(data.history[id].table, line) == nil then
|
2016-12-11 20:39:05 +01:00
|
|
|
table.insert(data.history[id].table, line)
|
|
|
|
if #data.history[id].table >= data.history[id].max then
|
|
|
|
break
|
2011-10-22 15:56:30 +02:00
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
2016-12-11 20:39:05 +01:00
|
|
|
end
|
|
|
|
f:close()
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-07-03 21:23:35 +02:00
|
|
|
local function is_word_char(c)
|
|
|
|
if string.find("[{[(,.:;_-+=@/ ]", c) then
|
|
|
|
return false
|
|
|
|
else
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function cword_start(s, pos)
|
|
|
|
local i = pos
|
|
|
|
if i > 1 then
|
|
|
|
i = i - 1
|
|
|
|
end
|
|
|
|
while i >= 1 and not is_word_char(s:sub(i, i)) do
|
|
|
|
i = i - 1
|
|
|
|
end
|
|
|
|
while i >= 1 and is_word_char(s:sub(i, i)) do
|
|
|
|
i = i - 1
|
|
|
|
end
|
|
|
|
if i <= #s then
|
|
|
|
i = i + 1
|
|
|
|
end
|
|
|
|
return i
|
|
|
|
end
|
|
|
|
|
|
|
|
local function cword_end(s, pos)
|
|
|
|
local i = pos
|
|
|
|
while i <= #s and not is_word_char(s:sub(i, i)) do
|
|
|
|
i = i + 1
|
|
|
|
end
|
|
|
|
while i <= #s and is_word_char(s:sub(i, i)) do
|
|
|
|
i = i + 1
|
|
|
|
end
|
|
|
|
return i
|
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Save history table in history file
|
2008-09-29 16:49:18 +02:00
|
|
|
-- @param id The data.history identifier
|
|
|
|
local function history_save(id)
|
|
|
|
if data.history[id] then
|
|
|
|
local f = io.open(id, "w")
|
|
|
|
if not f then
|
|
|
|
local i = 0
|
|
|
|
for d in id:gmatch(".-/") do
|
|
|
|
i = i + #d
|
|
|
|
end
|
|
|
|
util.mkdir(id:sub(1, i - 1))
|
|
|
|
f = assert(io.open(id, "w"))
|
|
|
|
end
|
2016-12-11 20:39:05 +01:00
|
|
|
for i = 1, math.min(#data.history[id].table, data.history[id].max) do
|
2008-09-29 16:49:18 +02:00
|
|
|
f:write(data.history[id].table[i] .. "\n")
|
|
|
|
end
|
|
|
|
f:close()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Return the number of items in history table regarding the id
|
2008-09-29 16:49:18 +02:00
|
|
|
-- @param id The data.history identifier
|
|
|
|
-- @return the number of items in history table, -1 if history is disabled
|
|
|
|
local function history_items(id)
|
|
|
|
if data.history[id] then
|
|
|
|
return #data.history[id].table
|
|
|
|
else
|
|
|
|
return -1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Add an entry to the history file
|
2008-09-29 16:49:18 +02:00
|
|
|
-- @param id The data.history identifier
|
|
|
|
-- @param command The command to add
|
|
|
|
local function history_add(id, command)
|
2011-12-04 02:03:40 +01:00
|
|
|
if data.history[id] and command ~= "" then
|
2017-03-08 21:18:33 +01:00
|
|
|
local index = gtable.hasitem(data.history[id].table, command)
|
2011-12-04 02:03:40 +01:00
|
|
|
if index == nil then
|
2008-09-29 16:49:18 +02:00
|
|
|
table.insert(data.history[id].table, command)
|
|
|
|
|
|
|
|
-- Do not exceed our max_cmd
|
|
|
|
if #data.history[id].table > data.history[id].max then
|
|
|
|
table.remove(data.history[id].table, 1)
|
|
|
|
end
|
|
|
|
|
2011-12-04 02:03:40 +01:00
|
|
|
history_save(id)
|
|
|
|
else
|
|
|
|
-- Bump this command to the end of history
|
|
|
|
table.remove(data.history[id].table, index)
|
|
|
|
table.insert(data.history[id].table, command)
|
2008-09-29 16:49:18 +02:00
|
|
|
history_save(id)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2015-02-20 15:45:53 +01:00
|
|
|
--- Draw the prompt text with a cursor.
|
|
|
|
-- @tparam table args The table of arguments.
|
|
|
|
-- @field text The text.
|
|
|
|
-- @field font The font.
|
|
|
|
-- @field prompt The text prefix.
|
|
|
|
-- @field text_color The text color.
|
|
|
|
-- @field cursor_color The cursor color.
|
|
|
|
-- @field cursor_pos The cursor position.
|
|
|
|
-- @field cursor_ul The cursor underline style.
|
|
|
|
-- @field selectall If true cursor is rendered on the entire text.
|
2009-08-31 21:34:46 +02:00
|
|
|
local function prompt_text_with_cursor(args)
|
|
|
|
local char, spacer, text_start, text_end, ret
|
|
|
|
local text = args.text or ""
|
2012-06-12 20:13:09 +02:00
|
|
|
local _prompt = args.prompt or ""
|
2009-08-31 21:34:46 +02:00
|
|
|
local underline = args.cursor_ul or "none"
|
|
|
|
|
|
|
|
if args.selectall then
|
|
|
|
if #text == 0 then char = " " else char = util.escape(text) end
|
|
|
|
spacer = " "
|
|
|
|
text_start = ""
|
|
|
|
text_end = ""
|
|
|
|
elseif #text < args.cursor_pos then
|
2008-09-29 16:49:18 +02:00
|
|
|
char = " "
|
2008-11-19 13:40:13 +01:00
|
|
|
spacer = ""
|
2009-08-31 21:34:46 +02:00
|
|
|
text_start = util.escape(text)
|
|
|
|
text_end = ""
|
2008-09-29 16:49:18 +02:00
|
|
|
else
|
2009-08-31 21:34:46 +02:00
|
|
|
char = util.escape(text:sub(args.cursor_pos, args.cursor_pos))
|
2008-11-19 13:40:13 +01:00
|
|
|
spacer = " "
|
2009-08-31 21:34:46 +02:00
|
|
|
text_start = util.escape(text:sub(1, args.cursor_pos - 1))
|
|
|
|
text_end = util.escape(text:sub(args.cursor_pos + 1))
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
2009-08-31 21:34:46 +02:00
|
|
|
|
2017-03-03 00:02:03 +01:00
|
|
|
local cursor_color = gcolor.ensure_pango_color(args.cursor_color)
|
|
|
|
local text_color = gcolor.ensure_pango_color(args.text_color)
|
2015-07-11 00:11:45 +02:00
|
|
|
|
2016-12-30 09:34:02 +01:00
|
|
|
if args.highlighter then
|
|
|
|
text_start, text_end = args.highlighter(text_start, text_end)
|
|
|
|
end
|
|
|
|
|
2015-07-11 00:11:45 +02:00
|
|
|
ret = _prompt .. text_start .. "<span background=\"" .. cursor_color ..
|
|
|
|
"\" foreground=\"" .. text_color .. "\" underline=\"" .. underline ..
|
|
|
|
"\">" .. char .. "</span>" .. text_end .. spacer
|
2009-08-31 21:34:46 +02:00
|
|
|
return ret
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
|
|
|
|
2016-12-30 08:14:34 +01:00
|
|
|
--- The callback function to call with command as argument when finished.
|
|
|
|
-- @usage local function my_exe_cb(command)
|
|
|
|
-- -- do something
|
|
|
|
-- end
|
|
|
|
-- @callback exe_callback
|
|
|
|
-- @tparam string command The command (as entered).
|
|
|
|
|
|
|
|
--- The callback function to call to get completion.
|
|
|
|
-- @usage local function my_completion_cb(command_before_comp, cur_pos_before_comp, ncomp)
|
|
|
|
-- return command_before_comp.."foo", cur_pos_before_comp+3, 1
|
|
|
|
-- end
|
|
|
|
--
|
|
|
|
-- @callback completion_callback
|
|
|
|
-- @tparam string command_before_comp The current command.
|
|
|
|
-- @tparam number cur_pos_before_comp The current cursor position.
|
|
|
|
-- @tparam number ncomp The number of completion elements.
|
|
|
|
-- @treturn string command
|
|
|
|
-- @treturn number cur_pos
|
|
|
|
-- @treturn number matches
|
|
|
|
|
|
|
|
--- The callback function to always call without arguments, regardless of
|
|
|
|
-- whether the prompt was cancelled.
|
|
|
|
-- @usage local function my_done_cb()
|
|
|
|
-- -- do something
|
|
|
|
-- end
|
|
|
|
-- @callback done_callback
|
|
|
|
|
|
|
|
--- The callback function to call with command as argument when a command was
|
|
|
|
-- changed.
|
|
|
|
-- @usage local function my_changed_cb(command)
|
|
|
|
-- -- do something
|
|
|
|
-- end
|
|
|
|
-- @callback changed_callback
|
|
|
|
-- @tparam string command The current command.
|
|
|
|
|
|
|
|
--- The callback function to call with mod table, key and command as arguments
|
|
|
|
-- when a key was pressed.
|
|
|
|
-- @usage local function my_keypressed_cb(mod, key, command)
|
|
|
|
-- -- do something
|
|
|
|
-- end
|
|
|
|
-- @callback keypressed_callback
|
|
|
|
-- @tparam table mod The current modifiers (like "Control" or "Shift").
|
|
|
|
-- @tparam string key The key name.
|
|
|
|
-- @tparam string command The current command.
|
|
|
|
|
|
|
|
--- The callback function to call with mod table, key and command as arguments
|
|
|
|
-- when a key was released.
|
|
|
|
-- @usage local function my_keyreleased_cb(mod, key, command)
|
|
|
|
-- -- do something
|
|
|
|
-- end
|
|
|
|
-- @callback keyreleased_callback
|
|
|
|
-- @tparam table mod The current modifiers (like "Control" or "Shift").
|
|
|
|
-- @tparam string key The key name.
|
|
|
|
-- @tparam string command The current command.
|
|
|
|
|
2016-12-30 09:34:02 +01:00
|
|
|
--- A function to add syntax highlighting to the command.
|
|
|
|
-- @usage local function my_highlighter(before_cursor, after_cursor)
|
|
|
|
-- -- do something
|
|
|
|
-- return before_cursor, after_cursor
|
|
|
|
-- end
|
|
|
|
-- @callback highlighter
|
|
|
|
-- @tparam string before_cursor
|
|
|
|
-- @tparam string after_cursor
|
|
|
|
|
2016-12-30 21:20:21 +01:00
|
|
|
--- A callback when a key combination is triggered.
|
|
|
|
-- This callback can return many things:
|
|
|
|
--
|
|
|
|
-- * a modified command
|
|
|
|
-- * `true` If the command is successful (then it won't exit)
|
|
|
|
-- * nothing or `nil` to execute the `exe_callback` and `done_callback` and exit
|
|
|
|
--
|
|
|
|
-- An optional second return value controls if the prompt should exit or simply
|
|
|
|
-- update the command (from the first return value) and keep going. The default
|
|
|
|
-- is to execute the `exe_callback` and `done_callback` before exiting.
|
|
|
|
--
|
|
|
|
-- @usage local function my_hook(command)
|
|
|
|
-- return command.."foo", false
|
|
|
|
-- end
|
|
|
|
--
|
|
|
|
-- @callback hook
|
|
|
|
-- @tparam string command The current command.
|
|
|
|
|
2008-09-29 16:49:18 +02:00
|
|
|
--- Run a prompt in a box.
|
2015-02-20 15:41:19 +01:00
|
|
|
--
|
2016-09-29 08:36:13 +02:00
|
|
|
-- @tparam[opt={}] table args A table with optional arguments
|
|
|
|
-- @tparam[opt] gears.color args.fg_cursor
|
|
|
|
-- @tparam[opt] gears.color args.bg_cursor
|
|
|
|
-- @tparam[opt] gears.color args.ul_cursor
|
|
|
|
-- @tparam[opt] widget args.prompt
|
|
|
|
-- @tparam[opt] string args.text
|
|
|
|
-- @tparam[opt] boolean args.selectall
|
|
|
|
-- @tparam[opt] string args.font
|
|
|
|
-- @tparam[opt] boolean args.autoexec
|
|
|
|
-- @tparam widget args.textbox The textbox to use for the prompt.
|
2016-12-30 09:34:02 +01:00
|
|
|
-- @tparam[opt] function args.highlighter A function to add syntax highlighting to
|
|
|
|
-- the command.
|
2016-09-29 08:36:13 +02:00
|
|
|
-- @tparam function args.exe_callback The callback function to call with command as argument
|
|
|
|
-- when finished.
|
|
|
|
-- @tparam function args.completion_callback The callback function to call to get completion.
|
|
|
|
-- @tparam[opt] string args.history_path File path where the history should be
|
|
|
|
-- saved, set nil to disable history
|
|
|
|
-- @tparam[opt] function args.history_max Set the maximum entries in history
|
|
|
|
-- file, 50 by default
|
|
|
|
-- @tparam[opt] function args.done_callback The callback function to always call
|
|
|
|
-- without arguments, regardless of whether the prompt was cancelled.
|
|
|
|
-- @tparam[opt] function args.changed_callback The callback function to call
|
|
|
|
-- with command as argument when a command was changed.
|
|
|
|
-- @tparam[opt] function args.keypressed_callback The callback function to call
|
|
|
|
-- with mod table, key and command as arguments when a key was pressed.
|
2016-09-29 08:46:04 +02:00
|
|
|
-- @tparam[opt] function args.keyreleased_callback The callback function to call
|
|
|
|
-- with mod table, key and command as arguments when a key was pressed.
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
-- @tparam[opt] table args.hooks The "hooks" argument uses a syntax similar to
|
|
|
|
-- `awful.key`. It will call a function for the matching modifiers + key.
|
|
|
|
-- It receives the command (widget text/input) as an argument.
|
2015-09-27 18:01:18 +02:00
|
|
|
-- If the callback returns a command, this will be passed to the
|
|
|
|
-- `exe_callback`, otherwise nothing gets executed by default, and the hook
|
|
|
|
-- needs to handle it.
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
-- hooks = {
|
|
|
|
-- -- Apply startup notification properties with Shift-Return.
|
|
|
|
-- {{"Shift" }, "Return", function(command)
|
2016-09-30 22:46:51 +02:00
|
|
|
-- awful.screen.focused().mypromptbox:spawn_and_handle_error(
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
-- command, {floating=true})
|
|
|
|
-- end},
|
|
|
|
-- -- Override default behavior of "Return": launch commands prefixed
|
|
|
|
-- -- with ":" in a terminal.
|
|
|
|
-- {{}, "Return", function(command)
|
|
|
|
-- if command:sub(1,1) == ":" then
|
2015-09-27 18:01:18 +02:00
|
|
|
-- return terminal .. ' -e ' .. command:sub(2)
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
-- end
|
2015-11-09 18:37:47 +01:00
|
|
|
-- return command
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
-- end}
|
|
|
|
-- }
|
2016-09-29 08:41:01 +02:00
|
|
|
-- @param textbox The textbox to use for the prompt. [**DEPRECATED**]
|
2014-08-28 19:45:46 +02:00
|
|
|
-- @param exe_callback The callback function to call with command as argument
|
2016-09-29 08:41:01 +02:00
|
|
|
-- when finished. [**DEPRECATED**]
|
2014-08-28 19:45:46 +02:00
|
|
|
-- @param completion_callback The callback function to call to get completion.
|
2016-09-29 08:41:01 +02:00
|
|
|
-- [**DEPRECATED**]
|
2015-02-26 22:06:34 +01:00
|
|
|
-- @param[opt] history_path File path where the history should be
|
2016-09-29 08:41:01 +02:00
|
|
|
-- saved, set nil to disable history [**DEPRECATED**]
|
2015-02-26 22:06:34 +01:00
|
|
|
-- @param[opt] history_max Set the maximum entries in history
|
2016-09-29 08:41:01 +02:00
|
|
|
-- file, 50 by default [**DEPRECATED**]
|
2015-02-26 22:06:34 +01:00
|
|
|
-- @param[opt] done_callback The callback function to always call
|
2014-08-28 19:45:46 +02:00
|
|
|
-- without arguments, regardless of whether the prompt was cancelled.
|
2016-09-29 08:41:01 +02:00
|
|
|
-- [**DEPRECATED**]
|
2015-02-26 22:06:34 +01:00
|
|
|
-- @param[opt] changed_callback The callback function to call
|
2016-09-29 08:41:01 +02:00
|
|
|
-- with command as argument when a command was changed. [**DEPRECATED**]
|
2015-02-26 22:06:34 +01:00
|
|
|
-- @param[opt] keypressed_callback The callback function to call
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
-- with mod table, key and command as arguments when a key was pressed.
|
2016-09-29 08:41:01 +02:00
|
|
|
-- [**DEPRECATED**]
|
2016-11-20 10:01:39 +01:00
|
|
|
-- @see gears.color
|
2015-02-09 20:16:48 +01:00
|
|
|
function prompt.run(args, textbox, exe_callback, completion_callback,
|
|
|
|
history_path, history_max, done_callback,
|
|
|
|
changed_callback, keypressed_callback)
|
2012-04-30 17:47:37 +02:00
|
|
|
local grabber
|
2008-09-29 16:49:18 +02:00
|
|
|
local theme = beautiful.get()
|
|
|
|
if not args then args = {} end
|
2008-11-17 19:25:11 +01:00
|
|
|
local command = args.text or ""
|
2008-09-29 16:49:18 +02:00
|
|
|
local command_before_comp
|
|
|
|
local cur_pos_before_comp
|
|
|
|
local prettyprompt = args.prompt or ""
|
2017-01-22 19:13:50 +01:00
|
|
|
local inv_col = args.fg_cursor or theme.prompt_fg_cursor or theme.fg_focus or "black"
|
|
|
|
local cur_col = args.bg_cursor or theme.prompt_bg_cursor or theme.bg_focus or "white"
|
2008-11-06 18:07:12 +01:00
|
|
|
local cur_ul = args.ul_cursor
|
2008-11-17 19:25:11 +01:00
|
|
|
local text = args.text or ""
|
2017-01-22 19:13:50 +01:00
|
|
|
local font = args.font or theme.prompt_font or theme.font
|
2009-08-31 21:37:18 +02:00
|
|
|
local selectall = args.selectall
|
2016-12-30 09:34:02 +01:00
|
|
|
local highlighter = args.highlighter
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
local hooks = {}
|
2008-09-29 16:49:18 +02:00
|
|
|
|
2017-02-18 19:39:19 +01:00
|
|
|
local deprecated = function(name)
|
|
|
|
util.deprecate(string.format(
|
|
|
|
'awful.prompt.run: the argument %s is deprecated, please use args.%s instead',
|
|
|
|
name, name), {raw=true})
|
2016-09-29 08:41:01 +02:00
|
|
|
end
|
2017-02-18 19:39:19 +01:00
|
|
|
if textbox then deprecated('textbox') end
|
|
|
|
if exe_callback then deprecated('exe_callback') end
|
|
|
|
if completion_callback then deprecated('completion_callback') end
|
|
|
|
if history_path then deprecated('history_path') end
|
|
|
|
if history_max then deprecated('history_max') end
|
|
|
|
if done_callback then deprecated('done_callback') end
|
|
|
|
if changed_callback then deprecated('changed_callback') end
|
|
|
|
if keypressed_callback then deprecated('keypressed_callback') end
|
2016-09-29 08:41:01 +02:00
|
|
|
|
2016-09-29 08:29:38 +02:00
|
|
|
-- This function has already an absurd number of parameters, allow them
|
|
|
|
-- to be set using the args to avoid a "nil, nil, nil, nil, foo" scenario
|
|
|
|
keypressed_callback = keypressed_callback or args.keypressed_callback
|
|
|
|
changed_callback = changed_callback or args.changed_callback
|
|
|
|
done_callback = done_callback or args.done_callback
|
|
|
|
history_max = history_max or args.history_max
|
|
|
|
history_path = history_path or args.history_path
|
|
|
|
completion_callback = completion_callback or args.completion_callback
|
|
|
|
exe_callback = exe_callback or args.exe_callback
|
|
|
|
textbox = textbox or args.textbox
|
|
|
|
|
2011-10-24 18:54:55 +02:00
|
|
|
search_term=nil
|
|
|
|
|
2008-09-29 16:49:18 +02:00
|
|
|
history_check_load(history_path, history_max)
|
|
|
|
local history_index = history_items(history_path) + 1
|
|
|
|
-- The cursor position
|
2009-08-31 21:37:18 +02:00
|
|
|
local cur_pos = (selectall and 1) or text:wlen() + 1
|
2008-09-29 16:49:18 +02:00
|
|
|
-- The completion element to use on completion request.
|
|
|
|
local ncomp = 1
|
2016-12-11 20:19:25 +01:00
|
|
|
if not textbox then
|
2008-09-29 16:49:18 +02:00
|
|
|
return
|
|
|
|
end
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
|
|
|
|
-- Build the hook map
|
2016-02-07 15:02:25 +01:00
|
|
|
for _,v in ipairs(args.hooks or {}) do
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
if #v == 3 then
|
2016-02-07 15:02:25 +01:00
|
|
|
local _,key,callback = unpack(v)
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
if type(callback) == "function" then
|
|
|
|
hooks[key] = hooks[key] or {}
|
|
|
|
hooks[key][#hooks[key]+1] = v
|
|
|
|
else
|
2017-02-20 06:24:04 +01:00
|
|
|
debug.print_warning("The hook's 3rd parameter has to be a function.")
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
end
|
|
|
|
else
|
2017-02-20 06:24:04 +01:00
|
|
|
debug.print_warning("The hook has to have 3 parameters.")
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2011-04-14 07:04:48 +02:00
|
|
|
textbox:set_font(font)
|
2010-10-06 21:27:42 +02:00
|
|
|
textbox:set_markup(prompt_text_with_cursor{
|
2009-08-31 21:34:46 +02:00
|
|
|
text = text, text_color = inv_col, cursor_color = cur_col,
|
2009-08-31 21:37:18 +02:00
|
|
|
cursor_pos = cur_pos, cursor_ul = cur_ul, selectall = selectall,
|
2016-12-30 09:34:02 +01:00
|
|
|
prompt = prettyprompt, highlighter = highlighter})
|
2009-08-31 21:34:46 +02:00
|
|
|
|
2016-11-16 08:25:31 +01:00
|
|
|
local function exec(cb, command_to_history)
|
2010-10-11 12:33:38 +02:00
|
|
|
textbox:set_markup("")
|
2016-11-16 08:25:31 +01:00
|
|
|
history_add(history_path, command_to_history)
|
2012-04-30 17:47:37 +02:00
|
|
|
keygrabber.stop(grabber)
|
2016-12-11 20:19:25 +01:00
|
|
|
if cb then cb(command) end
|
2010-10-11 12:33:38 +02:00
|
|
|
if done_callback then done_callback() end
|
|
|
|
end
|
|
|
|
|
2012-03-01 18:01:23 +01:00
|
|
|
-- Update textbox
|
|
|
|
local function update()
|
|
|
|
textbox:set_font(font)
|
|
|
|
textbox:set_markup(prompt_text_with_cursor{
|
|
|
|
text = command, text_color = inv_col, cursor_color = cur_col,
|
|
|
|
cursor_pos = cur_pos, cursor_ul = cur_ul, selectall = selectall,
|
2016-12-30 09:34:02 +01:00
|
|
|
prompt = prettyprompt, highlighter = highlighter })
|
2012-03-01 18:01:23 +01:00
|
|
|
end
|
|
|
|
|
2012-04-30 17:47:37 +02:00
|
|
|
grabber = keygrabber.run(
|
2009-04-27 21:04:15 +02:00
|
|
|
function (modifiers, key, event)
|
|
|
|
-- Convert index array to hash table
|
|
|
|
local mod = {}
|
2016-02-07 15:02:25 +01:00
|
|
|
for _, v in ipairs(modifiers) do mod[v] = true end
|
2012-03-01 18:33:22 +01:00
|
|
|
|
2016-09-29 08:46:04 +02:00
|
|
|
if event ~= "press" then
|
|
|
|
if args.keyreleased_callback then
|
|
|
|
args.keyreleased_callback(mod, key, command)
|
|
|
|
end
|
|
|
|
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2012-03-01 18:33:22 +01:00
|
|
|
-- Call the user specified callback. If it returns true as
|
|
|
|
-- the first result then return from the function. Treat the
|
|
|
|
-- second and third results as a new command and new prompt
|
|
|
|
-- to be set (if provided)
|
|
|
|
if keypressed_callback then
|
|
|
|
local user_catched, new_command, new_prompt =
|
|
|
|
keypressed_callback(mod, key, command)
|
|
|
|
if new_command or new_prompt then
|
|
|
|
if new_command then
|
|
|
|
command = new_command
|
|
|
|
end
|
|
|
|
if new_prompt then
|
|
|
|
prettyprompt = new_prompt
|
|
|
|
end
|
|
|
|
update()
|
|
|
|
end
|
|
|
|
if user_catched then
|
|
|
|
if changed_callback then
|
|
|
|
changed_callback(command)
|
|
|
|
end
|
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-06-19 06:23:46 +02:00
|
|
|
local filtered_modifiers = {}
|
|
|
|
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
-- User defined cases
|
|
|
|
if hooks[key] then
|
2016-06-19 06:23:46 +02:00
|
|
|
-- Remove caps and num lock
|
|
|
|
for _, m in ipairs(modifiers) do
|
2017-03-08 21:18:33 +01:00
|
|
|
if not gtable.hasitem(akey.ignore_modifiers, m) then
|
2016-06-19 06:23:46 +02:00
|
|
|
table.insert(filtered_modifiers, m)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2016-02-07 15:02:25 +01:00
|
|
|
for _,v in ipairs(hooks[key]) do
|
2016-06-19 06:23:46 +02:00
|
|
|
if #filtered_modifiers == #v[1] then
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
local match = true
|
2016-02-07 15:02:25 +01:00
|
|
|
for _,v2 in ipairs(v[1]) do
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
match = match and mod[v2]
|
|
|
|
end
|
2016-11-16 08:25:31 +01:00
|
|
|
if match then
|
2015-09-27 18:01:18 +02:00
|
|
|
local cb
|
2016-12-30 06:43:04 +01:00
|
|
|
local ret, quit = v[3](command)
|
2016-11-16 08:25:31 +01:00
|
|
|
local original_command = command
|
2016-12-30 06:43:04 +01:00
|
|
|
|
|
|
|
-- Support both a "simple" and a "complex" way to
|
|
|
|
-- control if the prompt should quit.
|
|
|
|
quit = quit == nil and (ret ~= true) or (quit~=false)
|
|
|
|
|
|
|
|
-- Allow the callback to change the command
|
|
|
|
command = (ret ~= true) and ret or command
|
|
|
|
|
|
|
|
-- Quit by default, but allow it to be disabled
|
|
|
|
if ret and type(ret) ~= "boolean" then
|
2015-09-27 18:01:18 +02:00
|
|
|
cb = exe_callback
|
2016-12-30 06:43:04 +01:00
|
|
|
if not quit then
|
|
|
|
cur_pos = ret:wlen() + 1
|
|
|
|
update()
|
|
|
|
end
|
|
|
|
elseif quit then
|
2015-09-27 18:01:18 +02:00
|
|
|
-- No callback.
|
|
|
|
cb = function() end
|
|
|
|
end
|
2016-12-30 06:43:04 +01:00
|
|
|
|
|
|
|
-- Execute the callback
|
|
|
|
if cb then
|
|
|
|
exec(cb, original_command)
|
|
|
|
end
|
|
|
|
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2008-09-29 16:49:18 +02:00
|
|
|
-- Get out cases
|
2008-11-13 14:06:22 +01:00
|
|
|
if (mod.Control and (key == "c" or key == "g"))
|
|
|
|
or (not mod.Control and key == "Escape") then
|
2012-04-30 17:47:37 +02:00
|
|
|
keygrabber.stop(grabber)
|
2010-10-06 21:27:42 +02:00
|
|
|
textbox:set_markup("")
|
2014-03-09 15:18:56 +01:00
|
|
|
history_save(history_path)
|
2008-11-13 14:06:22 +01:00
|
|
|
if done_callback then done_callback() end
|
|
|
|
return false
|
|
|
|
elseif (mod.Control and (key == "j" or key == "m"))
|
2008-11-29 02:07:06 +01:00
|
|
|
or (not mod.Control and key == "Return")
|
|
|
|
or (not mod.Control and key == "KP_Enter") then
|
2016-11-16 08:25:31 +01:00
|
|
|
exec(exe_callback, command)
|
2008-11-24 11:56:42 +01:00
|
|
|
-- We already unregistered ourselves so we don't want to return
|
|
|
|
-- true, otherwise we may unregister someone else.
|
2012-03-04 21:53:49 +01:00
|
|
|
return
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Control cases
|
|
|
|
if mod.Control then
|
2009-08-31 21:37:18 +02:00
|
|
|
selectall = nil
|
2008-09-29 16:49:18 +02:00
|
|
|
if key == "a" then
|
|
|
|
cur_pos = 1
|
|
|
|
elseif key == "b" then
|
|
|
|
if cur_pos > 1 then
|
|
|
|
cur_pos = cur_pos - 1
|
|
|
|
end
|
|
|
|
elseif key == "d" then
|
|
|
|
if cur_pos <= #command then
|
|
|
|
command = command:sub(1, cur_pos - 1) .. command:sub(cur_pos + 1)
|
|
|
|
end
|
2015-07-03 21:23:35 +02:00
|
|
|
elseif key == "p" then
|
|
|
|
if history_index > 1 then
|
|
|
|
history_index = history_index - 1
|
|
|
|
|
|
|
|
command = data.history[history_path].table[history_index]
|
|
|
|
cur_pos = #command + 2
|
|
|
|
end
|
|
|
|
elseif key == "n" then
|
|
|
|
if history_index < history_items(history_path) then
|
|
|
|
history_index = history_index + 1
|
|
|
|
|
|
|
|
command = data.history[history_path].table[history_index]
|
|
|
|
cur_pos = #command + 2
|
|
|
|
elseif history_index == history_items(history_path) then
|
|
|
|
history_index = history_index + 1
|
|
|
|
|
|
|
|
command = ""
|
|
|
|
cur_pos = 1
|
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
elseif key == "e" then
|
|
|
|
cur_pos = #command + 1
|
2011-10-24 18:54:55 +02:00
|
|
|
elseif key == "r" then
|
|
|
|
search_term = search_term or command:sub(1, cur_pos - 1)
|
|
|
|
for i,v in (function(a,i) return itera(-1,a,i) end), data.history[history_path].table, history_index do
|
2014-02-22 12:24:59 +01:00
|
|
|
if v:find(search_term,1,true) ~= nil then
|
2011-10-24 18:54:55 +02:00
|
|
|
command=v
|
|
|
|
history_index=i
|
|
|
|
cur_pos=#command+1
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif key == "s" then
|
|
|
|
search_term = search_term or command:sub(1, cur_pos - 1)
|
|
|
|
for i,v in (function(a,i) return itera(1,a,i) end), data.history[history_path].table, history_index do
|
2014-02-22 12:24:59 +01:00
|
|
|
if v:find(search_term,1,true) ~= nil then
|
2011-10-24 18:54:55 +02:00
|
|
|
command=v
|
|
|
|
history_index=i
|
|
|
|
cur_pos=#command+1
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
elseif key == "f" then
|
|
|
|
if cur_pos <= #command then
|
|
|
|
cur_pos = cur_pos + 1
|
|
|
|
end
|
|
|
|
elseif key == "h" then
|
|
|
|
if cur_pos > 1 then
|
|
|
|
command = command:sub(1, cur_pos - 2) .. command:sub(cur_pos)
|
|
|
|
cur_pos = cur_pos - 1
|
|
|
|
end
|
|
|
|
elseif key == "k" then
|
|
|
|
command = command:sub(1, cur_pos - 1)
|
|
|
|
elseif key == "u" then
|
|
|
|
command = command:sub(cur_pos, #command)
|
|
|
|
cur_pos = 1
|
2011-10-24 18:54:55 +02:00
|
|
|
elseif key == "Up" then
|
2014-02-22 12:21:09 +01:00
|
|
|
search_term = command:sub(1, cur_pos - 1) or ""
|
2011-10-24 18:54:55 +02:00
|
|
|
for i,v in (function(a,i) return itera(-1,a,i) end), data.history[history_path].table, history_index do
|
2014-02-22 12:24:59 +01:00
|
|
|
if v:find(search_term,1,true) == 1 then
|
2011-10-24 18:54:55 +02:00
|
|
|
command=v
|
|
|
|
history_index=i
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
elseif key == "Down" then
|
2014-02-22 12:21:09 +01:00
|
|
|
search_term = command:sub(1, cur_pos - 1) or ""
|
2011-10-24 18:54:55 +02:00
|
|
|
for i,v in (function(a,i) return itera(1,a,i) end), data.history[history_path].table, history_index do
|
2014-02-22 12:24:59 +01:00
|
|
|
if v:find(search_term,1,true) == 1 then
|
2011-10-24 18:54:55 +02:00
|
|
|
command=v
|
|
|
|
history_index=i
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
2010-10-21 09:05:40 +02:00
|
|
|
elseif key == "w" or key == "BackSpace" then
|
2008-09-29 16:49:18 +02:00
|
|
|
local wstart = 1
|
|
|
|
local wend = 1
|
2016-02-07 15:02:25 +01:00
|
|
|
local cword_start_pos = 1
|
|
|
|
local cword_end_pos = 1
|
2008-09-29 16:49:18 +02:00
|
|
|
while wend < cur_pos do
|
2009-05-10 08:10:35 +02:00
|
|
|
wend = command:find("[{[(,.:;_-+=@/ ]", wstart)
|
2008-09-29 16:49:18 +02:00
|
|
|
if not wend then wend = #command + 1 end
|
|
|
|
if cur_pos >= wstart and cur_pos <= wend + 1 then
|
2016-02-07 15:02:25 +01:00
|
|
|
cword_start_pos = wstart
|
|
|
|
cword_end_pos = cur_pos - 1
|
2008-09-29 16:49:18 +02:00
|
|
|
break
|
|
|
|
end
|
|
|
|
wstart = wend + 1
|
|
|
|
end
|
2016-02-07 15:02:25 +01:00
|
|
|
command = command:sub(1, cword_start_pos - 1) .. command:sub(cword_end_pos + 1)
|
2016-02-15 02:00:39 +01:00
|
|
|
cur_pos = cword_start_pos
|
2014-03-09 15:18:56 +01:00
|
|
|
elseif key == "Delete" then
|
|
|
|
-- delete from history only if:
|
|
|
|
-- we are not dealing with a new command
|
|
|
|
-- the user has not edited an existing entry
|
|
|
|
if command == data.history[history_path].table[history_index] then
|
|
|
|
table.remove(data.history[history_path].table, history_index)
|
|
|
|
if history_index <= history_items(history_path) then
|
|
|
|
command = data.history[history_path].table[history_index]
|
|
|
|
cur_pos = #command + 2
|
|
|
|
elseif history_index > 1 then
|
|
|
|
history_index = history_index - 1
|
|
|
|
|
|
|
|
command = data.history[history_path].table[history_index]
|
|
|
|
cur_pos = #command + 2
|
|
|
|
else
|
|
|
|
command = ""
|
|
|
|
cur_pos = 1
|
|
|
|
end
|
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
2015-07-03 21:23:35 +02:00
|
|
|
elseif mod.Mod1 or mod.Mod3 then
|
|
|
|
if key == "b" then
|
|
|
|
cur_pos = cword_start(command, cur_pos)
|
|
|
|
elseif key == "f" then
|
|
|
|
cur_pos = cword_end(command, cur_pos)
|
|
|
|
elseif key == "d" then
|
|
|
|
command = command:sub(1, cur_pos - 1) .. command:sub(cword_end(command, cur_pos))
|
|
|
|
elseif key == "BackSpace" then
|
2016-02-07 15:02:25 +01:00
|
|
|
local wstart = cword_start(command, cur_pos)
|
2015-07-03 21:23:35 +02:00
|
|
|
command = command:sub(1, wstart - 1) .. command:sub(cur_pos)
|
|
|
|
cur_pos = wstart
|
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
else
|
|
|
|
if completion_callback then
|
2009-01-05 11:16:08 +01:00
|
|
|
if key == "Tab" or key == "ISO_Left_Tab" then
|
2008-09-29 16:49:18 +02:00
|
|
|
if key == "ISO_Left_Tab" then
|
2012-03-04 21:53:49 +01:00
|
|
|
if ncomp == 1 then return end
|
2008-09-29 16:49:18 +02:00
|
|
|
if ncomp == 2 then
|
|
|
|
command = command_before_comp
|
2011-04-14 07:04:48 +02:00
|
|
|
textbox:set_font(font)
|
2010-10-06 21:27:42 +02:00
|
|
|
textbox:set_markup(prompt_text_with_cursor{
|
2009-08-31 21:34:46 +02:00
|
|
|
text = command_before_comp, text_color = inv_col, cursor_color = cur_col,
|
2009-08-31 21:37:18 +02:00
|
|
|
cursor_pos = cur_pos, cursor_ul = cur_ul, selectall = selectall,
|
2011-04-14 07:04:48 +02:00
|
|
|
prompt = prettyprompt })
|
2012-03-04 21:53:49 +01:00
|
|
|
return
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
ncomp = ncomp - 2
|
|
|
|
elseif ncomp == 1 then
|
|
|
|
command_before_comp = command
|
|
|
|
cur_pos_before_comp = cur_pos
|
|
|
|
end
|
2010-10-11 12:33:38 +02:00
|
|
|
local matches
|
|
|
|
command, cur_pos, matches = completion_callback(command_before_comp, cur_pos_before_comp, ncomp)
|
2008-09-29 16:49:18 +02:00
|
|
|
ncomp = ncomp + 1
|
|
|
|
key = ""
|
2010-10-11 12:33:38 +02:00
|
|
|
-- execute if only one match found and autoexec flag set
|
|
|
|
if matches and #matches == 1 and args.autoexec then
|
prompt: Add the ability to add new shortcuts to awful.prompt
Example:
awful.prompt.run({ prompt = "Run: ", hooks = {
{{ },"Return",function(command)
local result = awful.util.spawn(command)
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Mod1" },"Return",function(command)
local result = awful.util.spawn(command,{sticky=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end},
{{"Shift" },"Return",function(command)
local result = awful.util.spawn(command,{ontop=true,floating=true})
mypromptbox[mouse.screen].widget:set_text(type(result) == "string" and result or "")
return true
end}
}
},...)
2014-10-13 23:14:33 +02:00
|
|
|
exec(exe_callback)
|
2012-03-04 21:53:49 +01:00
|
|
|
return
|
2010-10-11 12:33:38 +02:00
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
else
|
|
|
|
ncomp = 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Typin cases
|
2009-01-04 17:44:37 +01:00
|
|
|
if mod.Shift and key == "Insert" then
|
|
|
|
local selection = capi.selection()
|
|
|
|
if selection then
|
|
|
|
-- Remove \n
|
|
|
|
local n = selection:find("\n")
|
|
|
|
if n then
|
|
|
|
selection = selection:sub(1, n - 1)
|
|
|
|
end
|
2010-08-31 13:48:59 +02:00
|
|
|
command = command:sub(1, cur_pos - 1) .. selection .. command:sub(cur_pos)
|
2009-01-04 17:44:37 +01:00
|
|
|
cur_pos = cur_pos + #selection
|
|
|
|
end
|
|
|
|
elseif key == "Home" then
|
2008-09-29 16:49:18 +02:00
|
|
|
cur_pos = 1
|
|
|
|
elseif key == "End" then
|
|
|
|
cur_pos = #command + 1
|
|
|
|
elseif key == "BackSpace" then
|
|
|
|
if cur_pos > 1 then
|
|
|
|
command = command:sub(1, cur_pos - 2) .. command:sub(cur_pos)
|
|
|
|
cur_pos = cur_pos - 1
|
|
|
|
end
|
2009-05-07 22:03:04 +02:00
|
|
|
elseif key == "Delete" then
|
2008-09-29 16:49:18 +02:00
|
|
|
command = command:sub(1, cur_pos - 1) .. command:sub(cur_pos + 1)
|
|
|
|
elseif key == "Left" then
|
|
|
|
cur_pos = cur_pos - 1
|
|
|
|
elseif key == "Right" then
|
|
|
|
cur_pos = cur_pos + 1
|
|
|
|
elseif key == "Up" then
|
|
|
|
if history_index > 1 then
|
|
|
|
history_index = history_index - 1
|
|
|
|
|
|
|
|
command = data.history[history_path].table[history_index]
|
|
|
|
cur_pos = #command + 2
|
|
|
|
end
|
|
|
|
elseif key == "Down" then
|
|
|
|
if history_index < history_items(history_path) then
|
|
|
|
history_index = history_index + 1
|
|
|
|
|
|
|
|
command = data.history[history_path].table[history_index]
|
|
|
|
cur_pos = #command + 2
|
|
|
|
elseif history_index == history_items(history_path) then
|
|
|
|
history_index = history_index + 1
|
|
|
|
|
|
|
|
command = ""
|
|
|
|
cur_pos = 1
|
|
|
|
end
|
|
|
|
else
|
2008-12-15 14:06:22 +01:00
|
|
|
-- wlen() is UTF-8 aware but #key is not,
|
2008-09-29 16:49:18 +02:00
|
|
|
-- so check that we have one UTF-8 char but advance the cursor of # position
|
2008-12-15 14:06:22 +01:00
|
|
|
if key:wlen() == 1 then
|
2009-08-31 21:37:18 +02:00
|
|
|
if selectall then command = "" end
|
2008-09-29 16:49:18 +02:00
|
|
|
command = command:sub(1, cur_pos - 1) .. key .. command:sub(cur_pos)
|
|
|
|
cur_pos = cur_pos + #key
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if cur_pos < 1 then
|
|
|
|
cur_pos = 1
|
|
|
|
elseif cur_pos > #command + 1 then
|
|
|
|
cur_pos = #command + 1
|
|
|
|
end
|
2009-08-31 21:37:18 +02:00
|
|
|
selectall = nil
|
2008-09-29 16:49:18 +02:00
|
|
|
end
|
|
|
|
|
2010-08-26 20:42:22 +02:00
|
|
|
local success = pcall(update)
|
|
|
|
while not success do
|
|
|
|
-- TODO UGLY HACK TODO
|
|
|
|
-- Setting the text failed. Most likely reason is that the user
|
|
|
|
-- entered a multibyte character and pressed backspace which only
|
|
|
|
-- removed the last byte. Let's remove another byte.
|
|
|
|
if cur_pos <= 1 then
|
|
|
|
-- No text left?!
|
|
|
|
break
|
|
|
|
end
|
|
|
|
|
|
|
|
command = command:sub(1, cur_pos - 2) .. command:sub(cur_pos)
|
|
|
|
cur_pos = cur_pos - 1
|
|
|
|
success = pcall(update)
|
|
|
|
end
|
2012-03-01 18:33:22 +01:00
|
|
|
|
|
|
|
if changed_callback then
|
|
|
|
changed_callback(command)
|
|
|
|
end
|
2008-09-29 16:49:18 +02:00
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
2012-06-12 20:13:09 +02:00
|
|
|
return prompt
|
|
|
|
|
2011-09-11 16:50:01 +02:00
|
|
|
-- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|