Class ui.Panel
A panel widget is the central component in MC’s display.
It lists files.
Events
<<activate>> | Triggered when a panel becomes the current one. |
<<before-chdir>> | Triggered before the directory is changed. |
<<draw>> | Triggered after a panel has been painted. |
<<flush>> | Triggered when the user reloads (C-r ) the panel. |
<<load>> | Triggered after a directory has been read into the panel. |
<<panelize>> | Triggered after a panel has been panelized. |
<<select-file>> | Triggered when a file is selected in the panel. |
General methods
ui.Panel.current rw | Returns the current file. |
ui.Panel.dir rw | The panel’s directory. |
ui.Panel:files() | Iterates over the files displayed in the panel. |
ui.Panel.filter rw | The filter. |
ui.Panel:filter_by_fn(fn) | Filter files by a predicate function. |
ui.Panel:panelize_by_command(command) | Populates the panel with the output of a shell command. |
ui.Panel:panelize_by_list(list) | Populates the panel with a list of files. |
ui.Panel.panelized rw | Whether the listing is “panelized”. |
ui.Panel:reload() | Reloads the panel. |
ui.Panel.vdir rw | The panel’s directory (as a vpath). |
Marking and unmarking files
ui.Panel:clear() | Unmarks all the files. |
ui.Panel:glob(pattern) | Marks files by glob pattern. |
ui.Panel:mark(list) | Marks files by name. |
ui.Panel:mark_by_fn(fn) | Marks files by a predicate function. |
ui.Panel.marked rw | Returns a table of the marked files. |
ui.Panel:unglob(pattern) | Unmarks files by glob pattern. |
ui.Panel:unmark(list) | Unmarks files by name. |
ui.Panel:unmark_by_fn(fn) | Unmarks files by a predicate function. |
The view
ui.Panel.custom_format rw | Custom format for the listing. |
ui.Panel.custom_mini_status rw | Whether to show a custom format for the mini status. |
ui.Panel.custom_mini_status_format rw | Custom format for the mini status. |
ui.Panel.list_type rw | The list type. |
ui.Panel.num_brief_cols rw | Number of columns for the “brief” list type. |
ui.Panel.sort_field rw | The field by which to sort. |
ui.Panel.sort_reverse rw | Whether to reverse the sort. |
Low-level methods
ui.Panel:_get_current_index() | Gets the index of the current (“selected”) file. |
ui.Panel:_get_file_by_index(i, skip_stat) | Gets meta information about a file. |
ui.Panel:_get_max_index() | Gets the number of files in the panel. |
ui.Panel:_get_metrics() | Returns various measurements. |
ui.Panel:_mark_file_by_index(i, mark) | Changes the mark status of a file. |
ui.Panel:_remove(i) | Removes a file. |
ui.Panel:_set_current_index(i) | Sets the the current (“selected”) file, by index. |
Static panel functions
ui.Panel.current r | The “current” panel. |
ui.Panel.left r | The left panel. |
ui.Panel.other r | The “other” panel. |
ui.Panel.right r | The right panel. |
Static panel functions and properties
ui.Panel.bind_if_commandline_empty(keyseq, fn) | Binds a key, when the command-line is empty. |
ui.Panel.register_field(info) | Registers a field. |
Events
- <<activate>>
-
Triggered when a panel becomes the current one.
(E.g., as a result of tabbing to it.)
ui.Panel.bind("<<activate>>", function(pnl) .... end)
Example: The set-gterm-cwd.lua script uses this event, together with <<load>>, to inform GNOME Terminal of the current directory.
- <<before-chdir>>
-
Triggered before the directory is changed.
In other words, it is triggered before the user navigates to another directory (e.g., by pressing ENTER on a directory).
Compare this with <<load>>, which is triggered after the directory has changed.
Example:
-- This simple code makes the selection (the marked files) -- persistent. local selections = {} ui.Panel.bind("<<before-chdir>>", function(pnl) selections[pnl.dir] = pnl.marked end) ui.Panel.bind("<<load>>", function(pnl) pnl.marked = selections[pnl.dir] end)
- <<draw>>
-
Triggered after a panel has been painted.
You may use this event to add more information to a panel’s display.
-- Prints the directory at the panel's bottom. ui.Panel.bind('<<draw>>', function(pnl) local c = pnl:get_canvas() c:set_style(tty.style('yellow, red')) c:goto_xy(2, pnl.rows - 1) c:draw_string(pnl.dir) end)
- <<flush>>
-
Triggered when the user reloads (
C-r
) the panel.You may use this event to clear expensive caches, as demonstrated in the user guide.
ui.Panel.bind("<<flush>>", function(pnl) .... end)
- <<load>>
-
Triggered after a directory has been read into the panel.
This happens, for example, when you navigate to a new directory, when you return from running a shell command, or when you reload (
C-r
) the panel.You may use this event to clear caches, as demonstrated in the user guide. You may also use it, together with <<activate>>, to inform the environment of the current directory.
ui.Panel.bind("<<load>>", function(pnl) .... end)
- <<panelize>>
-
Triggered after a panel has been panelized.
ui.Panel.bind("<<panelize>>", function(pnl) .... end)
There’s no
<<unpanelize>>
event (you should probably use <<load>> for that).This event is also triggered after you set the panelized property, to any value.
- <<select-file>>
-
Triggered when a file is selected in the panel.
-- Read aloud the current filename, after the user -- rests on it for a second. local say = timer.debounce(function(text) -- Note: we run espeak in the background (&) or else -- we'll be blocked till it finishes voicing the text. os.execute(('espeak %q &'):format(text)) end, 1000) ui.Panel.bind("<<select-file>>", function(pnl) say(pnl.current) end)
General methods
- ui.Panel.current rw
-
Returns the current file.
That is, the file on which the “cursor” stands:
ui.Panel.bind("C-y", function(pnl) alert(pnl.current) end
Besides the filename, several more values are returned. You have to use the method calling syntax —
:get_current()
— to access them:-- Ask for confirmation before editing a huge file. ui.Panel.bind("f4", function(pnl) local filename, stat = pnl:get_current() if stat.size < 5000000 or prompts.confirm(T"This file is huge. You really want to edit it?") then return false -- continue to the default action. end end)
Returns:
- the filename
- the StatBuf
- boolean: whether the file is marked.
- boolean: whether the file is the “current” one.
- boolean: whether this is a broken symlink.
- boolean: whether it’s a directory whose size has been computed (this size is recorded in the StatBuf).
- ui.Panel.dir rw
-
The panel’s directory.
-- Insert the panel's directory name into the command line. ui.Panel.bind("f16", function(pnl) local ipt = ui.current_widget("Input") if ipt then ipt:insert(pnl.dir) end end) -- This is a better version of the above, which works for -- any input line. ui.Input.bind("f16", function(ipt) -- When using /usr/bin/mcedit there are no panels, hence -- the "and" check below. ipt:insert(ui.Panel.current and ui.Panel.current.dir or "") end) -- An even better version! ui.Input.bind("f16", function(ipt) ipt:insert(fs.current_dir()) end)
See also vdir.
- ui.Panel:files()
-
Iterates over the files displayed in the panel.
The values returned by the iterator are the ones described at current.
ui.Panel.bind('C-y', function(pnl) local count = 0 for fname, stat in pnl:files() do if stat.type == "directory" and fname ~= ".." then count = count + 1 end end alert(locale.format_plural( "There is %d directory here", "There are %d directories here", count)) end)
- ui.Panel.filter rw
-
The filter.
A shell pattern determining the files to show. Set it to nil if you want to clear the filter. Example:
ui.Panel.bind('C-y', function(pnl) pnl.filter = '*.c' end)
- ui.Panel:filter_by_fn(fn)
-
Filter files by a predicate function.
Only files for which the function returns true will remain. The arguments the function receives are the ones described at current.
-- Filter the display to only the marked files. (Press C-r to go -- back to full view.) -- -- (This is quite useful, as sometimes you wish to see which -- files are marked without having to scroll in a giant list.) ui.Panel.bind("M-f", function(pnl) pnl:filter_by_fn(function(fname, stat, is_marked) return is_marked end) end)
- ui.Panel:panelize_by_command(command)
-
Populates the panel with the output of a shell command.
This is known as “external panelize” in MC’s lingo.
-- Make the panel show all MP3 files in the -- current folder and all subfolders. ui.Panel.bind('C-y', function(pnl) pnl:panelize_by_command('find . -iname "*.mp3" -print') end)
Another example:
-- Make the panel show only the files having the -- same extension as the current file. -- Files in subfolders too are shown. ui.Panel.bind('C-y', function(pnl) local original_current = pnl.current local extension = pnl.current:match '.*(%..*)' or '' pnl:panelize_by_command(('find . -name "*"%q -print'):format(extension)) -- Restore the cursor to the file we've been standing on originally: pnl.current = original_current end)
- ui.Panel:panelize_by_list(list)
-
Populates the panel with a list of files.
-- Make the panel show all MP3 files in the -- current folder and all subfolders. ui.Panel.bind('C-y', function(pnl) pnl:panelize_by_list( fs.tglob('**/*.mp3') ) end)
- ui.Panel.panelized rw
- Whether the listing is “panelized”.
- ui.Panel:reload()
-
Reloads the panel.
(An operation also known as “rescan” or “reread” in MC.)
Currently, because of some deficiency in MC’s API, this method reloads both panels.
- ui.Panel.vdir rw
- The panel’s directory (as a vpath).
Marking and unmarking files
- ui.Panel:clear()
- Unmarks all the files.
- ui.Panel:glob(pattern)
-
Marks files by glob pattern.
pnl:glob("*.c")
- ui.Panel:mark(list)
-
Marks files by name.
Marks all the files given as the list parameter.
pnl:clear() pnl:mark({"Makefile", "hook.c"}) -- Add all the files marked on the other panel: pnl:mark(ui.Panel.other.marked) -- And the selected file: pnl:mark(pnl.current)
See another example in mark_files_by_contents.lua.
Parameters:
- list A table of file names. Can also be a string. Can also be nil (in which case it’s a no-op).
- ui.Panel:mark_by_fn(fn)
-
Marks files by a predicate function.
Mark all files satisfying some condition. Receives as an argument a function that’s to return true if a file is to be marked. The arguments the function receives are the ones described at current.
ui.Panel.bind("C-x plus s", function(pnl) local min_size_s = prompts.input(T'Mark all files bigger than: (enter, for example, "200K", "50M", ...)') if min_size_s then local min_size = abortive(utils.text.parse_size(min_size_s)) pnl:mark_by_fn(function(fname, stat) return stat.size >= min_size end) end end)
- ui.Panel.marked rw
-
Returns a table of the marked files.
If no files are marked, returns nil; this makes it easier to provide a default value using “or”:
local files_to_operate_on = pnl.marked or { pnl.current }
This property is writable, which simply makes it an alternative to clear+mark:
-- Mark all web pages saved from Wikipedia. ui.Panel.bind('C-y', function(pnl) pnl.marked = prompts.please_wait(T"Locating files", function() return fs.tglob('*.mht', {conditions={ function(path) return fs.read(path, 1024):find('Content-Location: http://en.wikipedia.org', 1, true) end }}) end ) end)
(A variation of the code above is available as mark_files_by_contents.lua.)
- ui.Panel:unglob(pattern)
- Unmarks files by glob pattern.
- ui.Panel:unmark(list)
-
Unmarks files by name.
Unmarks all the files given as the list parameter.
See further details at mark.
- ui.Panel:unmark_by_fn(fn)
-
Unmarks files by a predicate function.
See mark_by_fn.
The view
- ui.Panel.custom_format rw
-
Custom format for the listing.
When list_type is set to “custom”, this property specifies the format to use.
ui.Panel.bind('C-y', function(pnl) pnl.list_type = "custom" pnl.custom_format = "half type name | size | perm | gitstatus | gitdate | gitauthor | gitmessage" end)
The syntax of the format string is:
all := panel_format? format panel_format := [full|half] [1-9] format := one_format | format , one_format one_format := align FIELD_ID [opt_width] align := [<=>] opt_width := : size [opt_expand] width := [0-9]+ opt_expand := +
(This syntax description was copied, with some minor modifications, from a comment in src/filemanager/panel.c.)
- ui.Panel.custom_mini_status rw
-
Whether to show a custom format for the mini status.
Boolean.
- ui.Panel.custom_mini_status_format rw
-
Custom format for the mini status.
When custom_mini_status is enabled, this property is the format to use.
ui.Panel.bind('C-y', function(pnl) pnl.custom_mini_status = true pnl.custom_mini_status_format = "half type name:20 | gitcommit:10 | gitmessage" end)
- ui.Panel.list_type rw
-
The list type.
How files are listed. It is one of “full”, “brief”, “long”, or “custom”. For “custom”, the format is specified with custom_format.
- ui.Panel.num_brief_cols rw
-
Number of columns for the “brief” list type.
Valid values are 1 to 9 (if you provide a value outside this range it will be clamped to fit the range).
Setting this property does not automatically set the list type to “brief” (You'll have to do this yourself, as shown in the example).
Example:
-- Quickly change the number of columns with the +/- keys. ui.Panel.bind('C-y plus', function(pnl) pnl.list_type = 'brief' pnl.num_brief_cols = pnl.num_brief_cols + 1 end) ui.Panel.bind('C-y minus', function(pnl) pnl.list_type = 'brief' pnl.num_brief_cols = pnl.num_brief_cols - 1 end)
- ui.Panel.sort_field rw
-
The field by which to sort.
It is a string identifying a built-in field, like
"name"
,"size"
,"mtime"
,"extension"
, a custom field you yourself created, or"unsorted"
for the disk’s raw order.-- Toggle between two sorts. ui.Panel.bind('C-y', function(pnl) if pnl.sort_field == "name" then pnl.sort_field = "size" else pnl.sort_field = "name" end)
- ui.Panel.sort_reverse rw
-
Whether to reverse the sort.
ui.Panel.bind('C-y', function(pnl) pnl.sort_reverse = not pnl.sort_reverse end)
Low-level methods
- ui.Panel:_get_current_index()
- Gets the index of the current (“selected”) file.
- ui.Panel:_get_file_by_index(i, skip_stat)
-
Gets meta information about a file.
Multiple values are returned. See current for details.
Parameters:
- i index
- skip_stat Whether to return a nil instead of the StatBuf (for efficiency).
- ui.Panel:_get_max_index()
- Gets the number of files in the panel.
- ui.Panel:_get_metrics()
-
Returns various measurements.
Returns several values, in this order:
- The index of the top file displayed.
- The number of screen lines used for displaying files.
- The number of columns.
- ui.Panel:_mark_file_by_index(i, mark)
-
Changes the mark status of a file.
Parameters:
- i index
- mark Boolean. Whether to mark or unmark the file.
- ui.Panel:_remove(i)
-
Removes a file.
Removes a file from the listing (not from disk, of course), by its index.
This can be used to implement filtering.
(The panel is not redrawn —for efficiency— as it’s assumed you might want to remove multiple files. You have to call :redraw() yourself.)
Parameters:
- i index
- ui.Panel:_set_current_index(i)
- Sets the the current (“selected”) file, by index.
Static panel functions
- ui.Panel.current r
-
The “current” panel.
This is the active panel, the one that has the focus.
Example:
-- Insert the panel's dir into the edited text. (tip: -- replace "Editbox" with "Input" to make it work with -- any input box.) ui.Editbox.bind('C-y', function(edt) -- "<none>" is emitted when using mcedit. edt:insert(ui.Panel.current and ui.Panel.current.dir or "<none>") end)
- ui.Panel.left r
- The left panel.
- ui.Panel.other r
-
The “other” panel.
That’s the panel which is not the current one.
ui.Panel.bind('f5', function(pnl) alert(T"You wanna copy something from here to %s":format( ui.Panel.other and ui.Panel.other.dir or T"<nowhere>")) end)
- ui.Panel.right r
- The right panel.
Static panel functions and properties
- ui.Panel.bind_if_commandline_empty(keyseq, fn)
-
Binds a key, when the command-line is empty.
This function is similar to ui.Panel.bind except that the key is active only when nothing is already typed on the command-line.
You already recognize this behavior from MC’s built-in keys “+” (Select), “–” (Unselect), etc., which aren’t effective when the command-line isn’t empty. Naturally, if you pick a printable key you'd pick one that doesn’t usually start a shell command, and you probably won’t find the need to use the modifiers
ALT
orCTRL
.Example:
-- By pressing '@', when then command-line is empty, you -- select/unselect files with the same extension as the -- current file. ui.Panel.bind_if_commandline_empty('@', function(pnl) pnl:command 'SelectExt' pnl:redraw() end)
- ui.Panel.register_field(info)
-
Registers a field.
The subject of creating fields is covered extensively in the reference and user guide.