diff --git a/data/core/commands/core.lua b/data/core/commands/core.lua index 18b76bc9..d818c391 100644 --- a/data/core/commands/core.lua +++ b/data/core/commands/core.lua @@ -90,8 +90,20 @@ command.add(nil, { if view.doc and view.doc.abs_filename then core.command_view:set_text(common.home_encode(view.doc.abs_filename)) end - core.command_view:enter("Open File", function(text) - core.root_view:open_doc(core.open_doc(common.home_expand(text))) + core.command_view:enter("Open File", function(text, item) + local filename = common.home_expand(item and item.text or text) + local info = system.get_file_info(filename) + print('file', filename, common.serialize(info)) + if info then + if info.type == "file" then + core.add_project_file(filename) + print('done add_project_file') + core.root_view:open_doc(core.open_doc(filename)) + print('done open_doc') + else + core.add_project_directory(filename) + end + end end, function (text) return common.home_encode_list(common.path_suggest(common.home_expand(text))) end, nil, function(text) @@ -163,8 +175,8 @@ command.add(nil, { end, ["core:add-directory"] = function() - core.command_view:enter("Add Directory", function(text) - text = common.home_expand(text) + core.command_view:enter("Add Directory", function(text, item) + text = common.home_expand(item and item.text or text) local path_stat, err = system.get_file_info(text) if not path_stat then core.error("cannot open %q: %s", text, err) diff --git a/data/core/init.lua b/data/core/init.lua index f008004c..8f0e8f53 100644 --- a/data/core/init.lua +++ b/data/core/init.lua @@ -58,27 +58,14 @@ function core.reschedule_project_scan() end -function core.set_project_dir(new_dir, change_project_fn) - local chdir_ok = pcall(system.chdir, new_dir) - if chdir_ok then - if change_project_fn then change_project_fn() end - core.project_dir = common.normalize_path(new_dir) - core.project_directories = {} - core.add_project_directory(new_dir) - core.project_files = {} - core.reschedule_project_scan() - return true - end - return false -end - - function core.open_folder_project(dir_path_abs) - if core.set_project_dir(dir_path_abs, core.on_quit_project) then - core.root_view:close_all_docviews() - update_recents_project("add", dir_path_abs) - core.on_enter_project(dir_path_abs) - end + -- if core.set_project_dir(dir_path_abs, core.on_quit_project) then + core.root_view:close_all_docviews() + core.project_entries = {} + -- FIXME: check stat info to verify is a directory + core.add_project_directory(dir_path_abs) + update_recents_project("add", dir_path_abs) + -- core.on_enter_project(dir_path_abs) end @@ -158,23 +145,22 @@ local function project_scan_thread() while true do -- get project files and replace previous table if the new table is -- different - for i = 1, #core.project_directories do - local dir = core.project_directories[i] - local t, entries_count = get_files(dir.name, "") - if diff_files(dir.files, t) then - if entries_count > config.max_project_files then - core.status_view:show_message("!", style.accent, - "Too many files in project directory: stopping reading at ".. - config.max_project_files.." files according to config.max_project_files. ".. - "Either tweak this variable, or ignore certain files/directories by ".. - "using the config.ignore_files variable in your user plugin or ".. - "project config.") + for i = 1, #core.project_entries do + local dir = core.project_entries[i] + if dir.item.type == 'dir' then + local t, entries_count = get_files(dir.name, "") + if diff_files(dir.files, t) then + if entries_count > config.max_project_files then + core.status_view:show_message("!", style.accent, + "Too many files in project directory: stopping reading at ".. + config.max_project_files.." files according to config.max_project_files. ".. + "Either tweak this variable, or ignore certain files/directories by ".. + "using the config.ignore_files variable in your user plugin or ".. + "project config.") + end + dir.files = t + core.redraw = true end - dir.files = t - core.redraw = true - end - if dir.name == core.project_dir then - core.project_files = dir.files end end @@ -185,12 +171,12 @@ end local function project_files_iter(state) - local dir = core.project_directories[state.dir_index] + local dir = core.project_entries[state.dir_index] state.file_index = state.file_index + 1 while dir and state.file_index > #dir.files do state.dir_index = state.dir_index + 1 state.file_index = 1 - dir = core.project_directories[state.dir_index] + dir = core.project_entries[state.dir_index] end if not dir then return end return dir.name, dir.files[state.file_index] @@ -205,8 +191,8 @@ end function core.project_files_number() local n = 0 - for i = 1, #core.project_directories do - n = n + #core.project_directories[i].files + for i = 1, #core.project_entries do + n = n + #core.project_entries[i].files end return n end @@ -317,12 +303,24 @@ function core.load_user_directory() end +function core.add_project_file(path) + path = normalize_path(path) + table.insert(core.project_entries, { + -- type = 'file', + name = path, + item = {filename = common.basename(path), type = "file", topdir = true}, + files = {path} + }) +end + + function core.add_project_directory(path) -- top directories has a file-like "item" but the item.filename -- will be simply the name of the directory, without its path. -- The field item.topdir will identify it as a top level directory. path = common.normalize_path(path) - table.insert(core.project_directories, { + table.insert(core.project_entries, { + -- type = 'dir', name = path, item = {filename = common.basename(path), type = "dir", topdir = true}, files = {} @@ -330,12 +328,12 @@ function core.add_project_directory(path) end -function core.remove_project_directory(path) +function core.remove_project_entry(path) -- skip the fist directory because it is the project's directory - for i = 2, #core.project_directories do - local dir = core.project_directories[i] + for i = 2, #core.project_entries do + local dir = core.project_entries[i] if dir.name == path then - table.remove(core.project_directories, i) + table.remove(core.project_entries, i) return true end end @@ -402,12 +400,18 @@ function core.init() core.log_items = {} core.docs = {} core.window_mode = "normal" + core.project_entries = {} core.threads = setmetatable({}, { __mode = "k" }) core.blink_start = system.get_time() core.blink_timer = core.blink_start local project_dir_abs = system.absolute_path(project_dir) - local set_project_ok = project_dir_abs and core.set_project_dir(project_dir_abs) + if project_dir_abs then + core.add_project_directory(project_dir_abs) + update_recents_project("add", project_dir_abs) + end + -- FIXME: below, check if project_dir_abs is ok as a project directory + local set_project_ok = project_dir_abs --and core.open_folder_project(project_dir_abs) --core.set_project_dir(project_dir_abs) if set_project_ok then if project_dir_explicit then update_recents_project("add", project_dir_abs) @@ -416,11 +420,6 @@ function core.init() if not project_dir_explicit then update_recents_project("remove", project_dir) end - project_dir_abs = system.absolute_path(".") - if not core.set_project_dir(project_dir_abs) then - system.show_fatal_error("Lite XL internal error", "cannot set project directory to cwd") - os.exit(1) - end end core.redraw = true diff --git a/data/core/statusview.lua b/data/core/statusview.lua index 58421c31..168ff6d9 100644 --- a/data/core/statusview.lua +++ b/data/core/statusview.lua @@ -138,7 +138,8 @@ function StatusView:get_items() style.icon_font, "g", style.font, style.dim, self.separator2, #core.docs, style.text, " / ", - #core.project_files, " files" + "(NYI) files" + --- #core.project_files, " files" } end diff --git a/data/plugins/treeview.lua b/data/plugins/treeview.lua index 73f4708c..bc88fdaf 100644 --- a/data/plugins/treeview.lua +++ b/data/plugins/treeview.lua @@ -64,19 +64,27 @@ function TreeView:get_cached(item, dirname) local t = dir_cache[cache_name] if not t then t = {} - local basename = common.basename(item.filename) - if item.topdir then - t.filename = basename - t.expanded = true + if item.type == 'file' and item.topdir then + t.filename = item.filename t.depth = 0 t.abs_filename = dirname + t.name = item.filename + t.type = item.type else - t.filename = item.filename - t.depth = get_depth(item.filename) - t.abs_filename = dirname .. PATHSEP .. item.filename + local basename = common.basename(item.filename) + if item.topdir then + t.filename = basename + t.expanded = true + t.depth = 0 + t.abs_filename = dirname + else + t.filename = item.filename + t.depth = get_depth(item.filename) + t.abs_filename = dirname .. PATHSEP .. item.filename + end + t.name = basename + t.type = item.type end - t.name = basename - t.type = item.type dir_cache[cache_name] = t end return t @@ -95,8 +103,8 @@ end function TreeView:check_cache() -- invalidate cache's skip values if project_files has changed - for i = 1, #core.project_directories do - local dir = core.project_directories[i] + for i = 1, #core.project_entries do + local dir = core.project_entries[i] local last_files = self.last[dir.name] if not last_files then self.last[dir.name] = dir.files @@ -121,10 +129,19 @@ function TreeView:each_item() local w = self.size.x local h = self:get_item_height() - for k = 1, #core.project_directories do - local dir = core.project_directories[k] + for k = 1, #core.project_entries do + local dir = core.project_entries[k] + if dir.item.type == "file" and dir.item.topdir then + print('dir', common.serialize(dir)) + end local dir_cached = self:get_cached(dir.item, dir.name) + if dir.item.type == "file" and dir.item.topdir then + print('cache', common.serialize(dir_cached)) + end coroutine.yield(dir_cached, ox, y, w, h) + if dir.item.type == "file" and dir.item.topdir then + print('file topdir yielded') + end count_lines = count_lines + 1 y = y + h local i = 1 @@ -150,6 +167,9 @@ function TreeView:each_item() end end end -- while files + if dir.item.type == "file" and dir.item.topdir then + print('loop over files terminated') + end end -- for directories self.count_lines = count_lines end) @@ -310,6 +330,7 @@ function TreeView:draw() -- text x = x + spacing + print('item.name', item.name) x = common.draw_text(style.font, color, item.name, nil, x, y, 0, h) end diff --git a/doc/notes-project-implementation.md b/doc/notes-project-implementation.md new file mode 100644 index 00000000..3b52f0f1 --- /dev/null +++ b/doc/notes-project-implementation.md @@ -0,0 +1,42 @@ + +`core.project_directories` => `core.project_entries` +- use a new `type` field to indicate it is a directory or a file + + +`core.{project_dir,project_files}` => removed +`core.set_project_dir` => removed + +`core.on_enter_project` => decide what to do + +No longer use `chdir` command. + +## New functions + +`core.add_project_file` + +## Modified functions + +- `core.add_project_directory` +- `project_files_iter` local function in `core/init.lua` + +Function `remove_project_directory` is renamed to `remove_project_entry`. + +## Broken + +workspace plugin is not working for the moment. +Number of files show in statusview. + +## To be done + +- When using "core:find-file" do not display the full path of the file +- FIX the workspace plugin +- FIX number of files display in statusview +- Add a function to add a file into the project +- Add logic to do not show treeview if it contains only a single file +- Modify "core:open-file" to accept a directory +- Modify "core:open-file" to accept a non-existing file name (new file) + +## Misc observations + +When performing adding directory, pressing enter does not use the item => to be fixed. +The function `system.chdir` is no longer used and could be removed, in theory.