@@ -279,11 +279,16 @@ def rm_command(ctx, file_path, keep_assets, yes):
279279
280280@cli .command ("move" )
281281@click .argument ("source" , required = True )
282- @click .argument ("destination" , required = True )
282+ @click .argument ("destination" , required = False )
283+ @click .option (
284+ "--permalink" ,
285+ "-p" ,
286+ help = "Rename permalink value and asset directory name (destination argument is ignored in this mode)" ,
287+ )
283288@click .option (
284289 "--keep-source-assets" ,
285290 is_flag = True ,
286- help = "Keep the source asset directory (don't move it)" ,
291+ help = "Keep the source asset directory (don't move it) [NOT IMPLEMENTED] " ,
287292)
288293@click .option (
289294 "--yes" ,
@@ -292,60 +297,151 @@ def rm_command(ctx, file_path, keep_assets, yes):
292297 help = "Skip confirmation prompt" ,
293298)
294299@click .pass_context
295- def move_command (ctx , source , destination , keep_source_assets , yes ):
296- """Move or rename a note file/directory and its asset directory.
300+ def move_command (ctx , source , destination , permalink , keep_source_assets , yes ):
301+ """Move or rename a note file/directory and its asset directory, or rename permalink .
297302
298303 \b
299304 Aliases: mv
300305
306+ \b
307+ File Move Mode (default):
308+ Move or rename a note file/directory and its asset directory.
309+
301310 \b
302311 Examples:
312+ # Move/rename file
303313 mkdocs-note move docs/notes/old.md docs/notes/new.md
304314 mkdocs-note mv docs/notes/test.md docs/notes/archive
315+
316+ # Move entire directory
305317 mkdocs-note move docs/notes/drafts docs/notes/published --yes
306318
319+ \b
320+ Permalink Rename Mode (use -p/--permalink):
321+ Rename permalink value in frontmatter and asset directory name.
322+
323+ \b
324+ Examples:
325+ mkdocs-note move docs/notes/my-note.md -p new-permalink
326+ mkdocs-note mv docs/notes/test.md --permalink updated-slug
327+
307328 \b
308329 Arguments:
309- SOURCE: Current path of the note file or directory
310- DESTINATION: Destination path (or parent directory if exists)
330+ SOURCE: Current path of the note file or directory (or file path for permalink mode)
331+ DESTINATION: Destination path (or parent directory if exists). Ignored if --permalink is used.
311332 """
312333 try :
313334 # Load configuration and setup environment
314335 config = MkdocsNoteConfig ()
315336 setup_cli_environment (config )
316337
317338 source_path = Path (source )
318- dest_path = Path (destination )
319339
320340 # Check if source exists
321341 if not source_path .exists ():
322342 click .echo (f"❌ Error: Source does not exist: { source_path } " , err = True )
323343 sys .exit (1 )
324344
325- # Confirmation prompt (unless --yes)
326- if not yes :
327- asset_msg = "with assets" if not keep_source_assets else "(keeping assets)"
328- if not click .confirm (f"Move { source_path } → { dest_path } { asset_msg } ?" ):
329- click .echo ("⚠️ Cancelled" )
330- sys .exit (0 )
331-
332- # Move the note using MoveCommand
333- # Note: Current MoveCommand doesn't have keep_source_assets parameter
334- # It always moves assets, so we need to handle this limitation
335- command = MoveCommand ()
336- command .execute (source_path , dest_path )
337-
338- # Check if move was successful
339- if dest_path .exists () and not source_path .exists ():
340- click .echo ("✅ Successfully moved" )
341- click .echo (f"📝 From: { source_path } " )
342- click .echo (f"📝 To: { dest_path } " )
343- if not keep_source_assets :
344- click .echo ("📁 Assets moved" )
345- else :
346- click .echo ("📁 Assets kept at source" )
345+ # Permalink rename mode
346+ if permalink :
347+ if not source_path .is_file ():
348+ click .echo (
349+ f"❌ Error: Permalink rename only works on files, not directories: { source_path } " ,
350+ err = True ,
351+ )
352+ sys .exit (1 )
353+
354+ # Get current permalink for confirmation message
355+ current_permalink = cli_common .get_permalink_from_file (source_path )
356+
357+ # Confirmation prompt (unless --yes)
358+ if not yes :
359+ current_msg = (
360+ f"'{ current_permalink } '" if current_permalink else "(none)"
361+ )
362+ if not click .confirm (
363+ f"Rename permalink in { source_path } from { current_msg } to '{ permalink } '?"
364+ ):
365+ click .echo ("⚠️ Cancelled" )
366+ sys .exit (0 )
367+
368+ # Rename permalink using MoveCommand
369+ command = MoveCommand ()
370+ command .execute (source_path , destination = None , permalink = permalink )
371+
372+ click .echo ("✅ Successfully renamed permalink" )
373+ click .echo (f"📝 File: { source_path } " )
374+ click .echo (f"🔗 Permalink: { current_permalink or '(none)' } → { permalink } " )
375+ click .echo ("📁 Asset directory renamed" )
347376 sys .exit (0 )
377+
378+ # File move mode (original behavior)
348379 else :
380+ if destination is None :
381+ click .echo (
382+ "❌ Error: DESTINATION is required in file move mode" , err = True
383+ )
384+ sys .exit (1 )
385+
386+ dest_path = Path (destination )
387+
388+ # Confirmation prompt (unless --yes)
389+ if not yes :
390+ asset_msg = (
391+ "with assets" if not keep_source_assets else "(keeping assets)"
392+ )
393+ if not click .confirm (f"Move { source_path } → { dest_path } { asset_msg } ?" ):
394+ click .echo ("⚠️ Cancelled" )
395+ sys .exit (0 )
396+
397+ # Save source type before move (since source_path won't exist after move)
398+ is_source_file = source_path .is_file ()
399+ is_source_dir = source_path .is_dir ()
400+ source_name = source_path .name
401+
402+ # Move the note using MoveCommand
403+ # Note: Current MoveCommand doesn't have keep_source_assets parameter
404+ # It always moves assets, so we need to handle this limitation
405+ command = MoveCommand ()
406+ command .execute (source_path , dest_path )
407+
408+ # Check if move was successful
409+ # For directory destinations, check if file exists in destination
410+ if is_source_file :
411+ # Determine final destination path
412+ if dest_path .exists () and dest_path .is_dir ():
413+ # File moved into directory
414+ final_dest = dest_path / source_name
415+ else :
416+ # File moved/renamed to dest_path
417+ final_dest = dest_path
418+
419+ # Check if move was successful
420+ if final_dest .exists () and not source_path .exists ():
421+ click .echo ("✅ Successfully moved" )
422+ click .echo (f"📝 From: { source_path } " )
423+ click .echo (f"📝 To: { final_dest } " )
424+ if not keep_source_assets :
425+ click .echo ("📁 Assets moved" )
426+ else :
427+ click .echo ("📁 Assets kept at source" )
428+ sys .exit (0 )
429+ elif is_source_dir :
430+ # Directory move - check if destination directory exists
431+ if (
432+ dest_path .exists ()
433+ and dest_path .is_dir ()
434+ and not source_path .exists ()
435+ ):
436+ click .echo ("✅ Successfully moved" )
437+ click .echo (f"📝 From: { source_path } " )
438+ click .echo (f"📝 To: { dest_path } " )
439+ if not keep_source_assets :
440+ click .echo ("📁 Assets moved" )
441+ else :
442+ click .echo ("📁 Assets kept at source" )
443+ sys .exit (0 )
444+
349445 click .echo ("❌ Error: Failed to move note" , err = True )
350446 sys .exit (1 )
351447
@@ -356,16 +452,22 @@ def move_command(ctx, source, destination, keep_source_assets, yes):
356452
357453@cli .command ("mv" )
358454@click .argument ("source" , required = True )
359- @click .argument ("destination" , required = True )
360- @click .option ("--keep-source-assets" , is_flag = True , help = "Keep source assets" )
455+ @click .argument ("destination" , required = False )
456+ @click .option (
457+ "--permalink" , "-p" , help = "Rename permalink value and asset directory name"
458+ )
459+ @click .option (
460+ "--keep-source-assets" , is_flag = True , help = "Keep source assets [NOT IMPLEMENTED]"
461+ )
361462@click .option ("--yes" , "-y" , is_flag = True , help = "Skip confirmation" )
362463@click .pass_context
363- def mv_command (ctx , source , destination , keep_source_assets , yes ):
464+ def mv_command (ctx , source , destination , permalink , keep_source_assets , yes ):
364465 """Alias for 'move' command - Move or rename a note file/directory and its assets."""
365466 ctx .invoke (
366467 move_command ,
367468 source = source ,
368469 destination = destination ,
470+ permalink = permalink ,
369471 keep_source_assets = keep_source_assets ,
370472 yes = yes ,
371473 )
0 commit comments