From 5aaf41793e8dd5958bffc5ebe0b2e2dc1f82b89f Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Sat, 10 Jan 2026 12:22:23 -0300 Subject: [PATCH 01/10] Fix filemanager mouse click --- filemanager-plugin/filemanager.lua | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index fef17d4..74ef4cd 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -1085,14 +1085,11 @@ function onPreviousSplit(view) end -- On click, open at the click's y -function preMousePress(view, event) +function onMousePress(view) if view == tree_view then - local x, y = event:Position() - -- Fixes the y because softwrap messes with it - local new_x, new_y = tree_view:GetMouseClickLocation(x, y) -- Try to open whatever is at the click's y index -- Will go into/back dirs based on what's clicked, nothing gets expanded - try_open_at_y(new_y) + try_open_at_y(tree_view.Cursor.Loc.Y) -- Don't actually allow the mousepress to trigger, so we avoid highlighting stuff return false end From fd42ee3c30b3c178740977f48ce6a9b6ead1edfd Mon Sep 17 00:00:00 2001 From: Omar El Laden <109101498+omarelladen@users.noreply.github.com> Date: Sat, 10 Jan 2026 17:44:44 -0300 Subject: [PATCH 02/10] Update filemanager plugin version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jöran Karl <3951388+JoeKar@users.noreply.github.com> --- filemanager-plugin/filemanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index 74ef4cd..eb286c5 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -1,4 +1,4 @@ -VERSION = "3.5.1" +VERSION = "3.5.2" local micro = import("micro") local config = import("micro/config") From d7d295c9df477d0a10703e21c430a7b3f7364ec4 Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Sun, 11 Jan 2026 08:46:11 -0300 Subject: [PATCH 03/10] Use function try_open_at_cursor for Tab and mouse click action --- filemanager-plugin/filemanager.lua | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index eb286c5..5bc0ea7 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -958,11 +958,9 @@ function goto_parent_dir() end function try_open_at_cursor() - if micro.CurPane() ~= tree_view or scanlist_is_empty() then - return + if micro.CurPane() == tree_view then + try_open_at_y(tree_view.Cursor.Loc.Y) end - - try_open_at_y(tree_view.Cursor.Loc.Y) end -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1089,7 +1087,7 @@ function onMousePress(view) if view == tree_view then -- Try to open whatever is at the click's y index -- Will go into/back dirs based on what's clicked, nothing gets expanded - try_open_at_y(tree_view.Cursor.Loc.Y) + try_open_at_cursor() -- Don't actually allow the mousepress to trigger, so we avoid highlighting stuff return false end @@ -1136,7 +1134,7 @@ function preIndentSelection(view) tab_pressed = true -- Open the file -- Using tab instead of enter, since enter won't work with Readonly - try_open_at_y(tree_view.Cursor.Loc.Y) + try_open_at_cursor() -- Don't actually insert a tab return false end From bae9ab6e0c42a83c301bd9eb6aecc0196cbf3179 Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Mon, 26 Jan 2026 15:31:24 -0300 Subject: [PATCH 04/10] Fix "rm" outside tree --- filemanager-plugin/filemanager.lua | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index 5bc0ea7..0178bc8 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -438,6 +438,12 @@ end -- Prompts the user for deletion of a file/dir when triggered -- Not local so Micro can access it function prompt_delete_at_cursor() + + if micro.CurPane() ~= tree_view then + micro.InfoBar():Message('"rm" only works with the cursor in the tree!') + return + end + local y = get_safe_y() -- Don't let them delete the top 3 index dir/separator/.. if y == 0 or scanlist_is_empty() then From bfe1023ad6426a743900de146edc8f350d1fa4a9 Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Mon, 26 Jan 2026 15:32:21 -0300 Subject: [PATCH 05/10] Add (y/n) to "rm" prompt --- filemanager-plugin/filemanager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index 0178bc8..2fb02b8 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -452,7 +452,7 @@ function prompt_delete_at_cursor() return end - micro.InfoBar():YNPrompt("Do you want to delete the " .. (scanlist[y].dirmsg ~= "" and "dir" or "file") .. ' "' .. scanlist[y].abspath .. '"? ', function(yes, canceled) + micro.InfoBar():YNPrompt("Do you want to delete the " .. (scanlist[y].dirmsg ~= "" and "dir" or "file") .. ' "' .. scanlist[y].abspath .. '"? (y/n) ', function(yes, canceled) if yes and not canceled then -- Use Go's os.Remove to delete the file local go_os = import("os") From 3a116fb9ab3524581123527dec4ae262478968c0 Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Mon, 26 Jan 2026 15:52:15 -0300 Subject: [PATCH 06/10] Fix renaming to existing file/dir --- filemanager-plugin/filemanager.lua | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index 2fb02b8..91164cd 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -647,6 +647,13 @@ function rename_at_cursor(bp, args) local old_path = scanlist[y].abspath -- Join the path into their supplied rename, so that we have an absolute path local new_path = dirname_and_join(old_path, new_name) + + -- Check if the name is already taken by a file/dir + if path_exists(new_path) then + micro.InfoBar():Error("You can't create a file/dir with a pre-existing name") + return + end + -- Use Go's os package for renaming the file/dir local golib_os = import("os") -- Actually rename the file From 056c38070bdc20942bc4ce129c17521f014ebef1 Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Mon, 26 Jan 2026 17:31:44 -0300 Subject: [PATCH 07/10] Remove duplicate imports of "os" lib --- filemanager-plugin/filemanager.lua | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index 91164cd..9296f2b 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -53,10 +53,8 @@ end -- A check for if a path is a dir local function is_dir(path) - -- Used for checking if dir - local golib_os = import("os") -- Returns a FileInfo on the current file/path - local file_info, stat_error = golib_os.Stat(path) + local file_info, stat_error = os.Stat(path) -- Wrap in nil check for file/dirs without read permissions if file_info ~= nil then -- Returns true/false if it's a dir @@ -454,10 +452,8 @@ function prompt_delete_at_cursor() micro.InfoBar():YNPrompt("Do you want to delete the " .. (scanlist[y].dirmsg ~= "" and "dir" or "file") .. ' "' .. scanlist[y].abspath .. '"? (y/n) ', function(yes, canceled) if yes and not canceled then - -- Use Go's os.Remove to delete the file - local go_os = import("os") -- Delete the target (if its a dir then the children too) - local remove_log = go_os.RemoveAll(scanlist[y].abspath) + local remove_log = os.RemoveAll(scanlist[y].abspath) if remove_log == nil then micro.InfoBar():Message("Filemanager deleted: ", scanlist[y].abspath) -- Remove the target (and all nested) from scanlist[y + 1] @@ -602,14 +598,13 @@ end -- Stat a path to check if it exists, returning true/false local function path_exists(path) - local go_os = import("os") -- Stat the file/dir path we created -- file_stat should be non-nil, and stat_err should be nil on success - local file_stat, stat_err = go_os.Stat(path) + local file_stat, stat_err = os.Stat(path) -- Check if what we tried to create exists if stat_err ~= nil then -- true/false if the file/dir exists - return go_os.IsExist(stat_err) + return os.IsExist(stat_err) elseif file_stat ~= nil then -- Assume it exists if no errors return true @@ -654,10 +649,8 @@ function rename_at_cursor(bp, args) return end - -- Use Go's os package for renaming the file/dir - local golib_os = import("os") -- Actually rename the file - local log_out = golib_os.Rename(old_path, new_path) + local log_out = os.Rename(old_path, new_path) -- Output the log, if any, of the rename if log_out ~= nil then micro.Log("Rename log: ", log_out) @@ -717,16 +710,14 @@ local function create_filedir(filedir_name, make_dir) return end - -- Use Go's os package for creating the files - local golib_os = import("os") -- Create the dir or file if make_dir then -- Creates the dir - golib_os.Mkdir(filedir_path, golib_os.ModePerm) + os.Mkdir(filedir_path, os.ModePerm) micro.Log("Filemanager created directory: " .. filedir_path) else -- Creates the file - golib_os.Create(filedir_path) + os.Create(filedir_path) micro.Log("Filemanager created file: " .. filedir_path) end From 2b2576c245ccecef658948a12d50b5d60fc8669c Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Tue, 27 Jan 2026 12:00:26 -0300 Subject: [PATCH 08/10] Fix Git detection in filemanager.lua (thanks to humannum14916) --- filemanager-plugin/filemanager.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index 9296f2b..a2e1cdf 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -72,7 +72,7 @@ end local function get_ignored_files(tar_dir) -- True/false if the target dir returns a non-fatal error when checked with 'git status' local function has_git() - local git_rp_results = shell.ExecCommand('git -C "' .. tar_dir .. '" rev-parse --is-inside-work-tree') + local git_rp_results = shell.ExecCommand('git', '-C', tar_dir, 'rev-parse', '--is-inside-work-tree') return git_rp_results:match("^true%s*$") end local readout_results = {} @@ -80,7 +80,7 @@ local function get_ignored_files(tar_dir) if has_git() then -- If the dir is a git dir, get all ignored in the dir local git_ls_results = - shell.ExecCommand('git -C "' .. tar_dir .. '" ls-files . --ignored --exclude-standard --others --directory') + shell.ExecCommand('git', '-C', tar_dir, 'ls-files', '.', '--ignored', '--exclude-standard', '--others', '--directory') -- Cut off the newline that is at the end of each result for split_results in string.gmatch(git_ls_results, "([^\r\n]+)") do -- git ls-files adds a trailing slash if it's a dir, so we remove it (if it is one) From f0a0d8f3daa15d910301a70f84f0ff4b1c1505eb Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Tue, 27 Jan 2026 12:01:14 -0300 Subject: [PATCH 09/10] Fix filemanager options --- filemanager-plugin/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/filemanager-plugin/README.md b/filemanager-plugin/README.md index 79d983d..44adc9d 100644 --- a/filemanager-plugin/README.md +++ b/filemanager-plugin/README.md @@ -20,11 +20,11 @@ If the directory is expanded, there will be a `+` to the left of it. If it is co | Option | Purpose | Default | | :--------------------------- | :----------------------------------------------------------- | :------ | -| `filemanager-showdotfiles` | Show dotfiles (hidden if false) | `true` | -| `filemanager-showignored` | Show gitignore'd files (hidden if false) | `true` | -| `filemanager-compressparent` | Collapse the parent dir when left is pressed on a child file | `true` | -| `filemanager-foldersfirst` | Sorts folders above any files | `true` | -| `filemanager-openonstart` | Automatically open the file tree when starting Micro | `false` | +| `filemanager.showdotfiles` | Show dotfiles (hidden if false) | `true` | +| `filemanager.showignored` | Show gitignore'd files (hidden if false) | `true` | +| `filemanager.compressparent` | Collapse the parent dir when left is pressed on a child file | `true` | +| `filemanager.foldersfirst` | Sorts folders above any files | `true` | +| `filemanager.openonstart` | Automatically open the file tree when starting Micro | `false` | ### Commands and Keybindings From aafbacdd422256d7c9655c6249a5229ea4d085e3 Mon Sep 17 00:00:00 2001 From: Omar El Laden Date: Tue, 27 Jan 2026 18:34:30 -0300 Subject: [PATCH 10/10] Move part of README to help file and import it into the help system (thanks to AndrewDDavis) --- filemanager-plugin/README.md | 49 ------------------------ filemanager-plugin/filemanager.lua | 3 ++ filemanager-plugin/help/filemanager.md | 52 ++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 49 deletions(-) create mode 100644 filemanager-plugin/help/filemanager.md diff --git a/filemanager-plugin/README.md b/filemanager-plugin/README.md index 44adc9d..342739b 100644 --- a/filemanager-plugin/README.md +++ b/filemanager-plugin/README.md @@ -5,52 +5,3 @@ A simple plugin that allows for easy navigation of a file tree. ![Example picture](./example.jpg?raw=true "Example") **Installation:** run `plugin install filemanager` and restart Micro. - -## Basics - -The top line always has the current directory's path to show you where you are.\ -The `..` near the top is used to move back a directory, from your current position. - -All directories have a `/` added to the end of it, and are syntax-highlighted as a `special` character.\ -If the directory is expanded, there will be a `+` to the left of it. If it is collapsed there will be a `-` instead. - -**NOTE:** If you change files without using the plugin, it can't know what you did. The only fix is to close and open the tree. - -### Options - -| Option | Purpose | Default | -| :--------------------------- | :----------------------------------------------------------- | :------ | -| `filemanager.showdotfiles` | Show dotfiles (hidden if false) | `true` | -| `filemanager.showignored` | Show gitignore'd files (hidden if false) | `true` | -| `filemanager.compressparent` | Collapse the parent dir when left is pressed on a child file | `true` | -| `filemanager.foldersfirst` | Sorts folders above any files | `true` | -| `filemanager.openonstart` | Automatically open the file tree when starting Micro | `false` | - -### Commands and Keybindings - -The keybindings below are the equivalent to Micro's defaults, and not actually set by the plugin. If you've changed any of those keybindings, then that key is used instead. - -If you want to [keybind](https://github.com/zyedidia/micro/blob/master/runtime/help/keybindings.md#rebinding-keys) any of the operations/commands, bind to the labeled API in the table below. - -| Command | Keybinding(s) | What it does | API for `bindings.json` | -| :------- | :------------------------- | :------------------------------------------------------------------------------------------ | :------------------------------------ | -| `tree` | - | Open/close the tree | `filemanager.toggle_tree` | -| - | Tab & MouseLeft | Open a file, or go into the directory. Goes back a dir if on `..` | `filemanager.try_open_at_cursor` | -| - | | Expand directory in tree listing | `filemanager.uncompress_at_cursor` | -| - | | Collapse directory listing | `filemanager.compress_at_cursor` | -| - | Shift ⬆ | Go to the target's parent directory | `filemanager.goto_parent_dir` | -| - | Alt Shift { | Jump to the previous directory in the view | `filemanager.goto_next_dir` | -| - | Alt Shift } | Jump to the next directory in the view | `filemanager.goto_prev_dir` | -| `rm` | - | Prompt to delete the target file/directory your cursor is on | `filemanager.prompt_delete_at_cursor` | -| `rename` | - | Rename the file/directory your cursor is on, using the passed name | `filemanager.rename_at_cursor` | -| `touch` | - | Make a new file under/into the file/directory your cursor is on, using the passed name | `filemanager.new_file` | -| `mkdir` | - | Make a new directory under/into the file/directory your cursor is on, using the passed name | `filemanager.new_dir` | - -#### Notes - -- `rename`, `touch`, and `mkdir` require a name to be passed when calling.\ - Example: `rename newnamehere`, `touch filenamehere`, `mkdir dirnamehere`.\ - If the passed name already exists in the current dir, it will cancel instead of overwriting (for safety). - -- The Ctrl w keybinding is to switch which buffer your cursor is on.\ - This isn't specific to the plugin, it's just part of Micro, but many people seem to not know this. diff --git a/filemanager-plugin/filemanager.lua b/filemanager-plugin/filemanager.lua index a2e1cdf..b93b460 100644 --- a/filemanager-plugin/filemanager.lua +++ b/filemanager-plugin/filemanager.lua @@ -1362,9 +1362,12 @@ function init() config.MakeCommand("mkdir", new_dir, config.NoComplete) -- Delete a file/dir, and anything contained in it if it's a dir config.MakeCommand("rm", prompt_delete_at_cursor, config.NoComplete) + -- Adds colors to the ".." and any dir's in the tree view via syntax highlighting -- TODO: Change it to work with git, based on untracked/changed/added/whatever config.AddRuntimeFile("filemanager", config.RTSyntax, "syntax.yaml") + -- Add the help file + config.AddRuntimeFile("filemanager", config.RTHelp, "help/filemanager.md") -- NOTE: This must be below the syntax load command or coloring won't work -- Just auto-open if the option is enabled diff --git a/filemanager-plugin/help/filemanager.md b/filemanager-plugin/help/filemanager.md new file mode 100644 index 0000000..650ef49 --- /dev/null +++ b/filemanager-plugin/help/filemanager.md @@ -0,0 +1,52 @@ +# Filemanager Plugin + +A simple plugin that allows for easy navigation of a file tree. + +## Basics + +The top line always has the current directory's path to show you where you are.\ +The `..` near the top is used to move back a directory, from your current position. + +All directories have a `/` added to the end of it, and are syntax-highlighted as a `special` character.\ +If the directory is expanded, there will be a `+` to the left of it. If it is collapsed there will be a `-` instead. + +**NOTE:** If you change files without using the plugin, it can't know what you did. The only fix is to close and open the tree. + +### Options + +| Option | Purpose | Default | +| :--------------------------- | :----------------------------------------------------------- | :------ | +| `filemanager.showdotfiles` | Show dotfiles (hidden if false) | `true` | +| `filemanager.showignored` | Show gitignore'd files (hidden if false) | `true` | +| `filemanager.compressparent` | Collapse the parent dir when left is pressed on a child file | `true` | +| `filemanager.foldersfirst` | Sorts folders above any files | `true` | +| `filemanager.openonstart` | Automatically open the file tree when starting Micro | `false` | + +### Commands and Keybindings + +The keybindings below are the equivalent to Micro's defaults, and not actually set by the plugin. If you've changed any of those keybindings, then that key is used instead. + +If you want to [keybind](https://github.com/zyedidia/micro/blob/master/runtime/help/keybindings.md#rebinding-keys) any of the operations/commands, bind to the labeled API in the table below. + +| Command | Keybinding(s) | What it does | API for `bindings.json` | +| :------- | :------------------------- | :------------------------------------------------------------------------------------------ | :------------------------------------ | +| `tree` | - | Open/close the tree | `filemanager.toggle_tree` | +| - | Tab & MouseLeft | Open a file, or go into the directory. Goes back a dir if on `..` | `filemanager.try_open_at_cursor` | +| - | | Expand directory in tree listing | `filemanager.uncompress_at_cursor` | +| - | | Collapse directory listing | `filemanager.compress_at_cursor` | +| - | Shift ⬆ | Go to the target's parent directory | `filemanager.goto_parent_dir` | +| - | Alt Shift { | Jump to the previous directory in the view | `filemanager.goto_next_dir` | +| - | Alt Shift } | Jump to the next directory in the view | `filemanager.goto_prev_dir` | +| `rm` | - | Prompt to delete the target file/directory your cursor is on | `filemanager.prompt_delete_at_cursor` | +| `rename` | - | Rename the file/directory your cursor is on, using the passed name | `filemanager.rename_at_cursor` | +| `touch` | - | Make a new file under/into the file/directory your cursor is on, using the passed name | `filemanager.new_file` | +| `mkdir` | - | Make a new directory under/into the file/directory your cursor is on, using the passed name | `filemanager.new_dir` | + +#### Notes + +- `rename`, `touch`, and `mkdir` require a name to be passed when calling.\ + Example: `rename newnamehere`, `touch filenamehere`, `mkdir dirnamehere`.\ + If the passed name already exists in the current dir, it will cancel instead of overwriting (for safety). + +- The Ctrl w keybinding is to switch which buffer your cursor is on.\ + This isn't specific to the plugin, it's just part of Micro, but many people seem to not know this.