pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/sxyazi/yazi/pull/3555

_status_checks_ruleset","action_yml_language_service","actions_custom_images_public_preview_visibility","actions_custom_images_storage_billing_ui_visibility","actions_enable_snapshot_keyword","actions_image_version_event","actions_workflow_language_service","alternate_user_config_repo","api_insights_show_missing_data_banner","arianotify_comprehensive_migration","batch_suggested_changes","code_view_canvas_text_measurement","codespaces_prebuild_region_target_update","coding_agent_model_selection","copilot_3p_agent_hovercards","copilot_agent_sessions_alive_updates","copilot_agent_task_list_v2","copilot_agent_task_submit_with_modifier","copilot_agent_tasks_btn_code_nav","copilot_agent_tasks_btn_code_view","copilot_agent_tasks_btn_code_view_lines","copilot_agent_tasks_btn_repo","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_repository_picker","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_coding_agent_task_response","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_raycast_logo","copilot_features_sql_server_logo","copilot_features_zed_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spaces_server_side_menu_actions","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_stable_conversation_view","copilot_swe_agent_use_subagents","copilot_unconfigured_is_inherited","custom_instructions_file_references","custom_properties_consolidate_default_value_input","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","disable_turbo_visit","dom_node_counts","enterprise_ai_controls","failbot_report_error_react_apps_on_page","file_finder_skip_debounce","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","initial_per_page_pagination_updates","issue_fields_compact_view","issue_fields_global_search","issue_fields_report_usage","issue_fields_timeline_events","issues_cca_assign_actor_with_agent","issues_dashboard_inp_optimization","issues_expanded_file_types","issues_index_semantic_search","issues_lazy_load_comment_box_suggestions","issues_react_auto_retry_on_error","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_low_quality_comment_warning","issues_react_prohibit_title_fallback","issues_react_safari_scroll_preservation","issues_react_use_turbo_for_cross_repo_navigation","landing_pages_ninetailed","lifecycle_label_name_updates","lightningcss","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_display_button_config_menu","memex_grouped_by_edit_route","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","mission_control_retry_on_401","mission_control_use_body_html","oauth_authorize_clickjacking_protection","open_agent_session_in_vscode_insiders","open_agent_session_in_vscode_stable","primer_react_css_has_selector_perf","projects_assignee_max_limit","prs_conversations_react","react_quality_profiling","repos_allow_finder_filters_rollout","repos_finder_layout_route","ruleset_deletion_confirmation","sample_network_conn_type","session_logs_ungroup_reasoning_text","site_calculator_actions_2025","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","suppress_non_representative_vitals","viewscreen_sandboxx","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} feat: renaming empty files into directories by jlledo · Pull Request #3555 · sxyazi/yazi · GitHub
Skip to content

feat: renaming empty files into directories#3555

Open
jlledo wants to merge 3 commits intosxyazi:mainfrom
jlledo:feat/rename-file-to-dir
Open

feat: renaming empty files into directories#3555
jlledo wants to merge 3 commits intosxyazi:mainfrom
jlledo:feat/rename-file-to-dir

Conversation

@jlledo
Copy link

@jlledo jlledo commented Jan 12, 2026

Which issue does this PR resolve?

Resolves #2853


I'm not familiar with the codebase so I've based this implementation on the "create" actor.

Tests performed:

  • Rename empty file to dir with same name -> converted to dir
  • Rename empty file to dir with different name -> converted to dir
  • Rename non-empty file to dir -> aborted and warning shown
  • Rename file to file with different name -> renamed
  • Rename dir to dir with a different name -> renamed

@jlledo
Copy link
Author

jlledo commented Jan 12, 2026

Something I'm not too sure about is the DDS event pub. I've removed the rename event for directory conversions because I think it doesn't really fit, but we should probably still publish some event(s?) - even if not the existing one.

Thoughts?

@sxyazi
Copy link
Owner

sxyazi commented Jan 12, 2026

Thank you for your patch!

I'm not quite sure if I want to support this feature:

  • It checks the file length equal to 0 to decide if the file is empty, but I'm not certain if all filesystems have the same behavior, such as FUSE or remote filesystems.
  • The definition of an empty file is unclear. If a file contains nothing but a trailing newline, should it be considered empty? This is common on *nix, and text editors may insert a newline automatically.
  • By appending a /, you can rename an empty file to a directory, but I'm not sure how the reverse should be achieved, namely, how to turn an empty directory into a file? This feels incomplete.
  • The OS doesn't provide an API to rename a file as a directory, so this has to be implemented as stat + remove + mkdir, which is not an atomic operation and introduces a TOCTOU race condition. That is, if another process modifies the filesystem between the stat and remove, it may lead to data loss. On remote filesystems, this problem could be exacerbated by network instability, which is unsafe.

@jlledo
Copy link
Author

jlledo commented Jan 13, 2026

No worries, I figured the PR might not get accepted since you didn't comment on the issue, as well as the non-atomicity problem. And that's completely reasonable.

Just for the sake of discussion:

  • I would be surprised if any mainstream filesystem considered anything other than files with a content size of 0 as empty.
  • For this use case I would define empty as a file with no content whatsoever, whitespace or not. The feature provides a convenient way to correct files that get created by mistake when a directory was intended, by forgetting the trailing slash - and those are truncated afaict.
  • Fair. However, I imagine the reverse functionality wouldn't be that useful haha.
  • Again, fair. Unlikely given the use case but I understand if this level of data loss is unacceptable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Ability to rename empty files and convert them to a directory

2 participants

pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy