2026.11.05
- project/session switching no longer closes the old tabs itself: the
  closing is left to CudaText's own session load (PROC_LOAD_SESSION
  closes all ui-tabs under APPSTATE_SESSION_LOAD_BEGIN_PRE, issue
  #6496), so plugins can tell these closes from user closes. Fixes the
  interplay with cuda_differ (Differ 2): its compare tabs were
  unregistered from cuda_differ2_state.json when the Project Manager
  closed their tab with cmd_FileCloseAll -- after switching back, the
  tab returned from the session as a dead plain split tab (no toolbar,
  no overview, no compare). Affected flows: opening/switching/closing
  projects (when the target session exists), creating an empty
  project, and switching project sessions. The modified flags are
  still cleared after the state was saved into its session (the app's
  load asks 'Save modified tab?' per modified tab, and Cancel aborts
  the whole load with the session pointer already switched); when the
  save failed the flags stay and the load asks -- unsaved text is
  never discarded silently. The explicit closing remains ONLY where no
  session load follows: legacy session-less project files, a missing
  default session file on 'Close project', and deleting the active
  session (its registrations must not survive -- the session never
  comes back). Minor behavior change: 'Create new empty project' now
  also resets the tab-group layout to the default single group (the
  empty session1 the flow loads carries no group settings)
- a CANCELLED session load during a switch is now repaired: the load's
  'Save modified tab?' confirm (a pre-pass -- it runs before any tab is
  closed, so on Cancel every tab is still open) is only reachable when
  the slot save failed, and it aborted the load with the app session
  pointer already switched, so the ~40 s session autosave / the exit
  save wrote the still-open old tabs into the NOT-loaded target
  session, clobbering its saved tab set (a sibling session of
  session_load, the opened project's last_session slot; session_delete
  even went on deleting the session while its tabs were still open).
  Every switch's PROC_LOAD_SESSION now goes through
  _load_session_repairing_abort: on cancel it re-points the app session
  to the session owning the still-open tabs (_current_state_session_ptr,
  captured before the flow re-pointed it) -- lossless, since nothing
  was closed yet; on a parse-fail (tabs closed, nothing restored) it
  only reports. 'New project' skips the empty-session1 save on abort
  (it would bake the old tabs into the new project), session_delete
  aborts the deletion, 'Close project' reports the cancelled state and
  repairs its no-default-session close path the same way
- new rotating backups of the open project file, covering what
  CudaText's own session backup never covered: it rotates plain
  session FILES (ui_backup_sessions, the .N.cuda-session files), while
  a project's sessions live INSIDE the .cuda-proj JSON, so the project
  file had no backup at all. After every session save into the project
  (APPSTATE_SESSION_SAVE_AFTER fires for the ~40 s autosave with real
  tab changes, session switches, project saves/switches, and the exit
  save alike), the whole file (nodes, vars, all embedded sessions) is
  copied into the backup folder — but only when it really changed on
  disk (size+mtime compared with the newest backup, detected across
  restarts too; saves which rewrote nothing write nothing). Backups:
  "<project>.cuda-proj.1.bak" ... ".N.bak" (oldest dropped on
  rotation). The copy is atomic (temp file + rename); a torn project
  file (tail not ending like complete JSON) is never propagated into
  the backups; errors are reported once per path. New options:
  "backup_enabled" (default on), "backup_folder" (default
  ".cudatext/proj_bckp" next to the project file; absolute or relative
  to the project file, both "/" and "\" separators work on Windows,
  macOS and Linux), "backup_count" (default 4). New command 'Backup
  project file now' makes a snapshot on demand
- backups, follow-up: the automatic backup no longer prints to the
  status bar (it fires every ~40 s while typing -- spam); it reports
  one line to the console panel instead, with the trigger and the
  time, e.g. 'Project Manager: project backup by timer at 4:23:07
  AM: <path>'. 'by timer' labels the saves CudaText makes on its own
  (the session autosave / the session manager); 'on session save',
  'on session switch', 'on project save', 'on project switch', 'on
  project close', 'on exit' label the saves the plugin's own commands
  make. The status bar is reserved for the manual 'Backup project
  file now', which is now also in the panel context menu ('Project
  file' section, under 'Save project as...') and works regardless of
  the backup options: with the automatic backups unchecked, and with
  'Backups to keep' 0 (a manual snapshot always keeps the single
  newest copy). Documented the dependence on CudaText's session
  saving: with 'Restore session' (ui_reopen_session) off, or the
  session autosave interval (ui_session_save_interval) 0, the
  periodic session saves stop -- and with them the periodic automatic
  backups; the switch/save/exit ones remain, the manual command is
  unaffected
- backups, follow-up 2: a command which saves the session several
  times in a row no longer rotates the backup set once per save.
  'Save session as...' saves the currently active session slot AND the
  new one (two rewrites of the whole .cuda-proj in one click), and
  each save fired APPSTATE_SESSION_SAVE_AFTER, so the set got two
  copies -- the first a half-done state which lacked the very session
  the command was creating (visible in the console as two 'project
  backup on session save' lines for one 'Save session as...'). Now
  the saves made inside a plugin command are only remembered (the
  project files they touched); ONE backup per touched file is made
  when the command ends, from the final file -- 'Save session as...'
  makes a single copy. 'Save project as...' into a new path still
  makes two, one per project file (the old project's final state and
  the new file's: two different files, not a double). Saves CudaText
  makes on its own (~40 s autosave, exit save) are backed up
  immediately as before -- single saves, nothing to coalesce. On exit
  two backups remain by design: one for the plugin's own exit save
  (the full state, unsaved texts included) and one for the app's exit
  save right after it (the final file). Saves triggered by tree edits
  (adding/removing/reordering nodes, moving a node on disk, 'Set as
  main file', project properties, deleting a tracked file) were
  reported 'by timer' although no timer ran: these flows are plugin
  commands too, and are now labeled 'on project save'
- new events for other plugins: APPSTATE_PROJECT_NODE_ADD /
  APPSTATE_PROJECT_NODE_DEL (on_state) fire when nodes are added to or
  removed from the open project's tree. Until now only project
  open/close had an event (APPSTATE_PROJECT, fired by the core when
  this plugin calls PROC_SET_PROJECT), so a plugin watching the node
  list had to poll global_project_info. The events are fired with the
  new app_proc commands PROC_PROJECT_NODE_ADD / PROC_PROJECT_NODE_DEL
  (app API additions of 1.239.0); global_project_info is refreshed
  before firing, so a listener already sees the new node list. Fired
  once per finished operation ('Clean up missing paths' removes a
  whole batch with one event); moving a node on disk fires DEL+ADD
  (the path was replaced); a pure reorder of root nodes fires nothing
  (same nodes, new order)

2026.11.03
- fixed #6587: the auto-unfolding of a folder during a drag&drop did not
  work at all. Two reasons:
  1. the hover state was driven by mouse-move events alone, and a cursor
     held STILL over a folder (the normal hover gesture) fires no events,
     so the 0.7s timeout could never elapse;
  2. on Windows no events existed at all during a drag: the inner
     drag&drop is the OLE 'drag_files' round-trip (no mouse events while
     it runs), and the OS file manager drag is entirely outside the
     plugin until the drop.
  The unfold-on-hover is now driven by a 100ms plugin timer over a
  "drag-hover session", fed from every event source which exists:
  tree_mouse_move (non-Windows inner drag&drop) and the new form event
  'on_drag_over' (app support: fired by the panel's OLE drop target on
  DragEnter/DragOver, (-1,-1) on DragLeave; covers the Windows inner
  drag&drop AND files dragged in from the OS file manager). The session
  is ended by mouse-up, drag-leave, any drop, and (safety net) by the
  timer itself when no mouse button is held anymore. Bonus: during the
  Windows inner drag&drop the drop target under the cursor is now
  highlighted, like the mouse-tracked inner drag&drop on other OS-es
  always did.

2026.11.02 (@badrelmers)
- fixed the problem found while testing the previous fix: paths in the
  drop event were truncated to 15 characters, which broke everything:
  1. files/folders dropped from the OS file manager were rejected with
     "Cannot add dropped paths to the project: ... (not found)" although
     they exist
  2. the inner drag&drop was rejected with "inner drop ignored, dropped
     paths do not match the dragged node"
  Reason: the app-internal event type (TAppVariantItem in
  proc_appvariant.pas) stored dict values of plugin events in a
  ShortString limited to 15 chars, so the "files" value of the
  on_drop_files event was cut. Core fix: the value is a full-length
  string now; no plugin change was needed

2026.11.02 (@badrelmers)
- fixed the 2 problems found while testing the previous fix:
  1. drops from the OS file manager onto the panel showed "Cannot add
     dropped paths to the project" and nothing was added. The drop is
     loud and diagnostic now: every rejected path is shown with its
     reason (not found / hidden) in the statusbar message, quoted paths
     are normalized, and a drop event without files is reported instead
     of silently ignored
  2. the inner drag&drop did nothing at all (no message, no dialogs).
     The self-drop event was fired from inside IDropTarget::Drop, still
     inside the app's own DoDragDrop (the plugin's modal confirmation
     dialogs in that context are unsafe), and the delivery depended on
     the OLE hit-test resolving the release position to the panel's
     form. The inner drag&drop no longer depends on it:
     - the self-drop event is now fired AFTER the OLE drag returned
       (recorded during the drop, fired by the drag-out code in a clean
       context), with the exact drop position
     - NEW FALLBACK: when the drop was not accepted by any drop target
       (eg no drop target resolved the release position) and the button
       was released over the panel, the release position is reported as
       the self-drop instead, so the inner drag&drop cannot get lost
     - only the form which started the drag records the drop-back; a
       drop of that drag on another form is ignored
- all failure paths of the inner drag&drop are loud now (statusbar
  messages: "The dragged node is not in the tree anymore", "Drop
  position unknown", "Cannot find the tree control", "Drop the node
  onto another node in the project tree"); an inner drop whose paths
  do not match the dragged node is reported too - a broken drop can
  never be silent again

2026.11.02 (@badrelmers)
- reworked the drag&drop of the previous fix, after testing:
  - RESTORED the drag-out of tree items to other applications (regression
    of the previous fix: the drag-out was made to start only when the
    cursor left the tree, but the tree does not get mouse events outside
    its bounds, so the drag-out never started). On Windows the drag-out
    again starts right on the mouse drag, like it always worked
  - an inner drag&drop (drop back onto the panel's tree) is now detected
    as the round-trip of that drag-out: CudaText reports the drop with
    the new flag self_drag and the drop position, the plugin hit-tests
    the tree at the drop position. On non-Windows OS-es (no OLE drag-out)
    the inner drag&drop is tracked by mouse events over the tree, as
    before
  - new rules of the inner drag&drop, every drop asks for confirmation:
    - dragging a NODE of the project only changes its order (dialog
      "Change the order of the node '...'?"); a node is never moved
      inside another node; dropping onto the project header moves the
      node to the end of the list
    - dragging a FILE/FOLDER from inside a node onto another FOLDER node
      moves it on disk (dialog "Move '...' from folder '...' to folder
      '...'?"), with the same safety checks as before (no overwriting,
      no move into itself / its own subfolder / the folder it is in)
    - other drops are refused with an explaining statusbar message
  - when "Sorting order" is not "none" and the user does an inner
    drag&drop which changes the order, a dialog explains that the manual
    order would be overwritten by sorting and offers to disable sorting
    (buttons "Disable sorting" / "Cancel"; cancelling cancels the
    drag&drop)
  - REMOVED the drag&drop of selected text from the editor onto the
    tree (dialog API control events "on_drag_over"/"on_drag_drop" and
    the plugin's handlers): it was not wanted, drag&drop of text works
    again exactly as it did before

2026.11.01 (@badrelmers)
- fixed the 3 problems found while testing PR #6571 (drag files out of
  CudaText, merged as 1.238.1):
  1. dropping a file from the OS file manager onto the Project panel opened
     it in the editor; it must be added to the project. The panel now uses
     the new dialog API event "on_drop_files" (Windows: the panel's form is
     registered as an OLE drop target, which takes priority over the main
     window's target, so the plugin gets the files dropped on the panel;
     other OS-es use the LCL drop-files support). Dropped files/folders are
     added as root nodes of the current project; drops anywhere else in
     CudaText keep the old behavior (open in the editor / "open folder")
  2. drag&drop inside the project tree did not work: ANY mouse drag started
     the drag-out to other apps (the "drag_files" property was set on the
     first 5-px move), so an inner drop was impossible. An inner drag&drop
     was implemented (see the next entry for the final version)
  3. drag&drop from the CudaText editor onto the project tree did not work
     (implemented via new dialog API events, removed again in the next
     entry: it was about dragging a TAB, not text, and tab dragging lives
     in the external ATTabs component, out of reach of the plugin)
- app history gets the matching API changelog entries (dlg_proc form event
  "on_drop_files", tree_proc TREE_ITEM_FIND_BY_POS; the control events
  "on_drag_over"/"on_drag_drop" were removed again)

2026.11.01 (@badrelmers)
- fixed regression: dragging a folder from Explorer onto CudaText crashed
  with "AttributeError: 'Command' object has no attribute 'open_dir'".
  open_dir() and new_project_open_dir() are not called from this plugin's
  own code — CudaText itself calls them ("open_dir" when a folder is
  dropped onto the editor, "new_project_open_dir" for the "File - Open
  folder..." menu command), so they were wrongly removed as "unused"
  together with the Git/SVN auto-project clean-up. Both are restored:
  a dropped folder is added as a root node of the current project (with
  no project open, of a new untitled project) as before, and
  "File - Open folder..." creates the project file inside the picked
  folder, named after the folder, in one step (if the folder already
  contains that project file, it is opened instead)
- fixed: "Close project" did not remove the plugin's on_start
  subscription from plugins.ini, so the plugin kept loading on every
  CudaText start even with no project in use. The subscription now
  mirrors "a project is in use" exactly: it is written on every project
  open/create/save and removed on every path that ends with no project
  (Close project, the startup detach when the restored session is not
  the project's, the external-session-switch close, and exit with no
  project). With no project loaded, the plugin never loads at the next
  CudaText start
- options dialog: "File type icons" and "Toolbar icons" are now marked
  with (*) — a new icon theme needs a CudaText restart, because the
  side panel (with its icon image lists) is created once per run; the
  marker was already used for "Sorting order"

2026.11.01 (@badrelmers)
- second full data-loss audit; all fixes below are for bugs found in it
- fixed: unsaved text could be lost when tabs were closed without their
  session being saved first. CudaText sessions store the text of
  modified and untitled tabs, so a state saved into a session loses
  nothing — but these flows closed tabs with no session save at all:
  "Open project..." / "Open recent project..." / opening a .cuda-proj
  from File>Open with NO project open (the open tabs belonged to the
  app session, which was never written), "Close project" and "Create
  new empty project..." with no project open, and "Open session..."
  picking the session that was ALREADY active (the save was skipped for
  it). Now every flow that closes tabs first saves the state into the
  session it belongs to (the project's session slot, or the app's own
  session file when no project is open — the file CudaText's autosave
  writes anyway); if that save fails, tabs keep their "modified" flag
  and CudaText's own "save changes?" prompt appears — unsaved text is
  never discarded silently
- "Save project as...": the active session now keeps its NAME in the
  new file (it was reset to "session1"), and the old project file gets
  the latest state too (it used to lag one save behind)
- all project/options file writes are now atomic (write to a temp file,
  then replace): a crash, power loss or full disk can no longer leave a
  truncated .cuda-proj behind, which would have destroyed ALL project
  data (nodes + every embedded session); either the file is replaced
  completely or the previous complete file stays
- fixed: "Clean up missing paths..." skipped entries when several
  missing paths stood next to each other (the node list was modified
  while being iterated) — with three consecutive missing paths only two
  were reported and one stayed in the project
- fixed: "Delete session..." could crash with KeyError right after
  updating the file, when the in-memory session list lagged behind the
  project file
- deleting the ACTIVE session now lets CudaText ask "save changes?" for
  modified tabs before they close (the session is deleted on purpose,
  but files can still be saved to disk)
- startup with a session-less project file (left over by old builds)
  now creates "session1" immediately (a project is itself a session, it
  always keeps one); previously this waited for the ~40s session
  autosave
- folder paste no longer uses distutils (removed in Python 3.12) and no
  longer silently merges into an existing folder — shutil.copytree
  refuses to overwrite and reports an error
- readme.txt: internal implementation details moved to the new
  doc_for_dev.md (for plugin authors); the user documentation now
  describes only user-visible behavior

2026.11.01 (@badrelmers)
- fixed severe data loss: text typed in a session was lost after a restart
  if the user switched to another session before closing CudaText (switch
  session1 -> session2, close, restart, switch back -> old text). CudaText
  saves session sub-keys straight into the .cuda-proj file (on every session
  switch, the ~40s autosave and on exit), but the plugin kept its own
  in-memory copy of "sessions" and dumped it over the file on every project
  save — including the on_exit save — reverting every non-current session
  to the state from when the project was opened. The project save now
  always takes the fresh "sessions"/"last_session" from the file on disk
  ("Save project as..." carries them over from the old project file), and
  the in-memory copy is refreshed after every session save

2026.11.01 (@badrelmers)
- restored "menu=op" in install.inf for "Project properties..." and
  "Config..." (upstream had it on both): the two settings dialogs are
  also shown in CudaText's Settings menu — the key was wrongly dropped
  as stale in the menu rework
+ context menu: added the commands that were only in the Plugins menu —
  "Add current file", "Add all opened files", "Add folder of current
  file" (in "Root nodes"), "Go to main file", "Open main file", "Show
  current file in project tree" and "Config..." (top level, Config at
  the very end)
+ Plugins menu: added "Clean up missing paths..." (was only in the panel
  context menu), closing the "Add to project" group
* context menu reorganized for quicker navigation: the top level now
  groups panel commands (Refresh, Show current file in project tree),
  navigation (Go to file..., Go to main file, Open main file), "Project
  sessions" and "Config..."; in "Selected file", "Set as main file"
  moved next to "Open in default application" (project-specific actions
  first, generic file operations below)

2026.11.01 (@badrelmers)
- fixed: switching project sessions could lose changes — "Save session as..."
  only wrote the new session, so the previously active session kept its old
  state; now switching ALWAYS saves the active session into its slot first,
  and "Save session as..." writes the current state into both the new
  session and the previously active one
- removed the "Save current state to the session ...?" prompt on switching:
  the state is always saved (CudaText's ~40s session autosave would write
  it out anyway, so the prompt protected nothing)
- fixed catastrophic bug: deleting the ACTIVE project session switched the
  app session to default.cuda-session while the project stayed open, so the
  ~40s session autosave overwrote that external file with the project's
  tabs; now the user picks another session OF THE PROJECT to load instead,
  and the app session never leaves the project for an external one
- a project always keeps at least one session (a project is a session):
  the last remaining session cannot be deleted — the menu item is disabled
  and the command explains it in a dialog; opening a project file with no
  sessions creates "session1" so the app session is always internal
- replaced the "default session" concept with "last_session": the project
  file stores the last used session, it is updated on every session switch
  and loaded when the project is opened; on restart CudaText restores the
  last used session itself (the plugin only records it); removed the
  "Set session to load on project open..." command, its menu items and all
  its code; older files with "def_session" are migrated on open
- "Save session as..." no longer closes tabs not belonging to the project:
  the full current state is saved as is; the ONLY commands that close
  foreign tabs are the two "Close tabs not belonging to project" commands
  (the internal no-op caller at startup is removed as well)
- "Open project folder" now always opens the folder containing the
  .cuda-proj file (added folders have their own "Reveal in file manager")
- renamed "New empty project..." -> "Create new empty project...",
  "New project from open tabs..." -> "Create new project from open tabs..."
- session_save lost the dead "and_forget" parameter (it could switch the
  app onto an external session while a project is open)
- new_project simplified to the pure state reset it always was in practice
  (its save/close/foreign-tabs branches were unreachable at startup)

2026.11.01 (@badrelmers)
* menus reorganized (per the #6352 discussion): Plugins-menu commands are
  grouped by purpose with separators — panel, navigation, project
  lifecycle, add-to-project, "Project sessions" submenu, close-tabs,
  settings (Config at the end); the hidden menu=0 entries and their 12
  "Context menu\..." duplicates are removed, together with the
  contextmenu_* wrapper methods; "New project from folder..." removed —
  the same result is reached with "New empty project..." + "Add folder..."
* context menu: new "Project sessions" submenu (same items as the
  toolbar sessions menu, which is now built by the same code), new
  "Open project folder" item; in the sessions menu "Save session" now
  comes before "Save session as..."
+ new command "Open project folder" (context menu + Plugins menu): opens
  the project's folder in the OS file manager (first folder root of the
  project, or the .cuda-proj file's folder)
+ new commands "Add to project: folder..." and "Add to project: file..."
  (browse dialogs, same actions as the context-menu items)
- fixed: "Set session to load on project open..." was effectively dead:
  every project save overwrote the chosen default with the then-current
  session, and on restart CudaText restored the last used session; now an
  existing default survives project saves, and on start the plugin
  switches from the restored session to the default one (the restored
  session is saved back into its own slot first, so nothing is lost);
  the command now also reports its result in the status bar; deleting
  the default session makes the first remaining session the default
* "Close tabs not belonging to project" is the old simple code again,
  with one change: PROP_MODIFIED is not cleared anymore, so tabs with
  unsaved changes get CudaText's own save prompt; "... (no prompt)" and
  the internal callers (session saving) use the existing confirm=False
  path — no dialogs at all, exactly as before
* APPSTATE_SESSION_SET / APPSTATE_SESSION_LOAD are used directly, without
  a fallback: this plugin ships inside CudaText, so the constants always
  exist (the "needs a recent CudaText" assumption was wrong)
* wording fixes: "New project from open tabs..." (was "Save current
  session as new project..."), "Reveal in file manager" (was "Focus in
  file manager"), "Stop tracking this folder/file", "Project is already
  open", "No project open" (was a mix of "Project not loaded/opened"),
  "Removed missing paths: ..." (was "[Project] Remove deleted nodes"),
  "Located in project" (was "Project jump"), "missing item(s)" (was
  "deleted item(s)") in the open-project status
- fixed: the "cannot find path" message passed "MB_OK or MB_ICONERROR",
  so the error icon was never shown
- removed dead code: session_forget, session_forget_ex,
  session_delete_all, is_project_filename, do_unfold_first

2026.11.01 (@badrelmers)
- fixed: the config dialog had shifted control indices: clicking Cancel ran
  the OK parsing and crashed with ValueError (int('')), while clicking OK
  silently discarded all changes; indices recomputed and combo parsing made
  crash-proof
+ new command "Close tabs not belonging to project (no prompt)": closes all
  foreign tabs at once, without any dialogs (the old behavior of the main
  command)
- external session switch detection now also uses APPSTATE_SESSION_SET
  (issue #6366): when another plugin changes the app's session via
  PROC_SET_SESSION while a project is open, the project closes silently so
  the two sessions don't conflict; session changes made by the plugin
  itself are ignored (guard flag)
- renamed for clarity: "New project" -> "New empty project", "Sync to
  editor file" / toolbar "Sync project-tree with current editor file" ->
  "Show current file in project tree", "Set default session" -> "Set
  session to load on project open", option "Always sync project-tree with
  current editor file" -> "Automatically show current file in project tree"
- removed the Git/SVN auto-project feature and all its code (decided in
  #6352): the "check_git" option and its config-dialog checkbox, the
  on_open handler and its plugins.ini subscription, the temporary
  "temporary.cuda-proj" auto-project, and the unused open_dir() helper

2026.11.01 (@badrelmers)
+ old-format project files are upgraded automatically on open, without a
  confirmation dialog: a backup of the original is saved next to the file
  ("<file>.bak", or "<file>.<date>.bak" when that name is taken — existing
  backups are never overwritten), then the file is rewritten in the current
  format; the status bar and console report the upgrade and the backup name
  (the user can delete the backup when everything works fine)
+ when the on-disk upgrade is impossible (read-only folder, locked file),
  the project still opens with the upgraded data in memory and the file is
  upgraded on the first successful save
+ when a sibling "<project>.cuda-session" file is detected during an
  upgrade, a console hint points to "Import external session..."

2026.11.01 (@badrelmers)
+ project file versioning: files are written with "version": 2; opening a
  version-less (old format) file shows a one-time upgrade dialog which only
  adds missing standard keys (nothing is removed), as promised in #6352
+ command "Save current session as new project..." (current tabs become
  session "session1" of a new project, tabs stay open), as promised in #6352
+ command "Import external session..." (migrates an external .cuda-session
  file into the project as an internal session; first import becomes the
  default if the project had none), as promised in #6352
+ opening an empty (0-byte) project file offers to create a new project in it
+ project files are fully validated on open: unreadable / invalid JSON /
  not a JSON object / wrong "nodes" or "sessions" types are reported with
  a dialog; files with a format version newer than supported are refused
+ def_session is auto-filled with the first existing session when opening
  old projects that have sessions but no default session
* session_save_as no longer refuses node-less projects: every project now
  keeps a session, even before any folder/file is added (per #6352 design)
* "Save session as..." / "Save session" menu items are enabled whenever a
  project file exists, not only when the project has root nodes
* the temporary git auto-project file is also written with "version": 2
- fixed: KeyError 'nodes' when opening old project files without the "nodes"
  key (files that only ever held sessions); the plugin used to stay
  half-open and then crash on every later command (Close project, Project
  session menu, Open/New project, recent projects, exit) until restart
- fixed: tabs were closed before the newly opened project file was
  validated — a broken file is now reported with all tabs intact
- fixed: action_save_project_as wrote a stale copy of the embedded sessions
  over the just-saved session (session state could lag one save behind; on
  exit the latest tab state could be lost)
- fixed: "Save project as..." saved the session into the old file path
  instead of the newly chosen one
- fixed: str(None) made the "Untitled project" guard in session_save_as /
  session_load / session_cur_name / session_get_names ineffective
  (produced 'None|/sessions/...' session pointers)
- fixed: missing return after "Untitled project" message in session_save_as

2026.10.31 (@badrelmers)
* per review by Alexey-T: install.inf no longer declares non-lazy on_start —
  all install.inf events are lazy ('~'), so they never load the plugin on start;
  CudaText stays fast for users who don't use Project Manager at all
* on_start is again subscribed conditionally via plugins.ini [events]:
  the plugin writes it when a project is opened/created/saved (hidden option
  "on_start" restored for this), and removes it otherwise
* on_open (check_git) subscription via plugins.ini restored and the on_open
  handler re-enabled
* options on_start, on_start_activate added to the defaults dict so they
  survive save_options filtering and persist in cuda_project_man.json

2026.07.24 (@badrelmers)
+ command "New project" now prompts for save location and creates session "session1" inside the project
+ command "Save project" (in-place save, no dialog)
+ command "Close project" (closes tabs, loads default.cuda-session without overwriting it)
+ command "Save session" (in-place save to current session slot)
+ menu item "Project properties..." in Project menu
+ on_state event subscription for external session switch detection
+ settings auto-merge: missing options are filled from defaults on load, stale options are dropped on save
+ options check_git, icon_theme, toolbar_theme added to defaults dict so they persist
+ history.json read on startup to detect session/project mismatch and avoid "save changes?" prompts
+ temporary git auto-project now activates the Project panel and uses a minimal project file (no session)
* renamed "Remove root node" to "Stop tracking this Folder/File"
* renamed "Remove deleted root nodes..." to "Clean up missing paths..."
* renamed "Save session..." to "Save session as..."
* session_load uses close_all_tabs (no DEF_SES switch within a project)
* session_forget_ex uses close_all_tabs (clears modified flag and unpins tabs in all groups)
* action_save_project_as preserves current session name instead of hardcoding "new"
* action_project_for_git creates minimal project without session operations
* on_exit skips saving the temporary git auto-project
* check_git option disabled by default
* options dialog: removed dead "Suggest to close tabs not belonging to project" option
* on_start auto-opens the most recent project if the restored session matches
  (runs only when the plugin is loaded at start via plugins.ini subscription)
* rewritten documentation (readme.txt)
- removed command "Clear project..." (redundant with New project + overwrite)
- removed command "Forget session, close all tabs" (dangerous — overwrote default session)
- removed temporary.cuda-proj auto-save on adding first node (New project now requires a real path)
- fixed: closing tabs in only the active group (other groups kept modified tabs)
- fixed: cmd_FileCloseAll skipped pinned tabs (previous project's pinned tabs leaked)
- fixed: Open project stacked new session's tabs on top of old ones
- fixed: New project overwrote default.cuda-session with empty state
- fixed: external session switch overwrote project's session data
- fixed: startup prompted "save changes?" when history.json session matched the project
- fixed: settings not saved for check_git, icon_theme, toolbar_theme
- fixed: new options missing from old config files until Options dialog was opened

2026.07.21 (@ildarkhasanshin)
+ command "New project" now close all open tabs
+ when saving the project for the first time, create a new session and make it the default

2026.03.17
+ add command "Remove deleted nodes"

2025.12.04
+ add Enter/Space-key for fold/unfold directories

2024.09.26
+ add sorting order "none"

2019.10.27
+ feature of Kate editor: on opening a file from Git/SVN repo, project is created and target file is focused in that project; added option for this
+ make super-fast Go To command, not unfolding the entire project
+ make super-fast listing of all files in project
+ delete pathlib.py
* move items in context menu

2018.03.06
+ option in Config dialog "Toolbar icons"
* moved toolbar icons to CudaText's data/projtoolbaricons/default_16x16

2018.01
+ support project variables {ProjMainFileNameOnly}, {ProjMainFileNameNoExt}
- fix: avoid deprecated toolbar API

2017.11.24
+ added console messages on opening/saving project
+ show x icon for files deleted on disk

2017.09.25
+ refact
- fix: avoid deleted APIs

2017.09.08
+ added commands "Go to main file", "Open main file"
- fix: dont allow duplicate nodes on adding nodes
- fix: Windows high-dpi

2017.08.29
+ added cmd "Add to project: current file"
+ added cmd "Add to project: all opened files"
* deleted cmd "Focus proj panel" ("Show" focuses it)

2017.07.10
+ added option "Open file after 'Go to file' command"
+ added reaction to Enter in treeview
- fixed "Go to file" command: a) show found tree item, b) it unfolds entire tree, workaround, needed because tree loading is lazy

2017.06.28
+ added option "Icons theme" in dialog
+ used file-type-icons from CudaText

2017.06.15
+ added toolbar with 6 buttons
+ options dialog: opt "Show toolbar"

2017.06.14
+ show X icon for file/dir deleted from disk
+ now not all sub-dirs are read from disk, but only dirs of top level; next subdirs are read on unfolding them; much faster for dirs with huge count of dirs/files, e.g. "/usr" [patch by pohmelie]

2017.06.13
+ don't use deprecated APIs, port to new API: menu_proc(), app_proc(proc_sidepanel_add_dialog)

2017.05.31
+ method open_dir to integrate with CudaText

2016.11.02
+ cmd "sync to curr file"

2016.09.26
+ new context-menu, compact
- must force UTF8, for Mac

2016.09.09
* moved icon-files

2016.09.07
+ commands-item "Focus Project panel"

2016.09.06
+ add project_variables() api

2016.09.02
+ Plugins item "Project properties"
+ ctx menu item "Set as main file"
+ proj saves vars + mainfile

2016.08.31
+ ctx-menu item for dirs: "Find in directory", calls dialog in plugin "Find in files"

2016.08.06
+ warn msgbox on deleting file/dir

2016.08.04
+ cmds differ for selected file/dir/prj
+ new menu cmds for file/dir selected

2016.07.26
+ add global_project_info for oth plugins

2016.07.19
+ cmd "Go to file"
+ more statusbar msgs

2016.07.18
+ dlg Commands has items for context-menu items
+ option dialog reworked

2016.07.18
+ allow to open project from Open dialog
+ more menu items in Plugins
+ filter in Open/Save dialog

2016.07.14
initial version
