Create new document if file doesn't exist
If a non-existing file is specified with the command "core:open-file" a new document is opened with the given filename provided the directory already exists. The flag new_file is set to true in the Doc instance. The file will be actually created only when the "save" command is used. The document will be marked with the "*" event when no changes are done to mean that it is a new file and is not yet saved. The function common.normalize_path now process the .. and . in the filename. Before was not needed because system.absolute_path already get rid of them but now we need to have the absolute path of files that not yet exists so we cannot use system.absolute_path.
This commit is contained in:
parent
0ce5680ef2
commit
708c2983ef
|
@ -95,11 +95,20 @@ command.add(nil, {
|
|||
end, function (text)
|
||||
return common.home_encode_list(common.path_suggest(common.home_expand(text)))
|
||||
end, nil, function(text)
|
||||
local path_stat, err = system.get_file_info(common.home_expand(text))
|
||||
local filename = common.home_expand(text)
|
||||
local path_stat, err = system.get_file_info(filename)
|
||||
if err then
|
||||
core.error("Cannot open file %q: %q", text, err)
|
||||
elseif path_stat.type == 'dir' then
|
||||
core.error("Cannot open %q, is a folder", text)
|
||||
if err:find("No such file", 1, true) then
|
||||
-- check if the containing directory exists
|
||||
local dirname = common.dirname(filename)
|
||||
local dir_stat = dirname and system.get_file_info(dirname)
|
||||
if not dirname or (dir_stat and dir_stat.type == 'dir') then
|
||||
return true
|
||||
end
|
||||
end
|
||||
core.error("Cannot open file %s: %s", text, err)
|
||||
elseif path_stat.type == 'dir' then
|
||||
core.error("Cannot open %s, is a folder", text)
|
||||
else
|
||||
return true
|
||||
end
|
||||
|
|
|
@ -68,7 +68,12 @@ end
|
|||
|
||||
|
||||
local function save(filename)
|
||||
doc():save(filename and core.normalize_to_project_dir(filename))
|
||||
local abs_filename
|
||||
if filename then
|
||||
filename = core.normalize_to_project_dir(filename)
|
||||
abs_filename = core.project_absolute_path(filename)
|
||||
end
|
||||
doc():save(filename, abs_filename)
|
||||
local saved_filename = doc().filename
|
||||
core.on_doc_save(saved_filename)
|
||||
core.log("Saved \"%s\"", saved_filename)
|
||||
|
@ -323,12 +328,14 @@ local commands = {
|
|||
end
|
||||
core.command_view:set_text(old_filename)
|
||||
core.command_view:enter("Rename", function(filename)
|
||||
doc():save(filename)
|
||||
save(common.home_expand(filename))
|
||||
core.log("Renamed \"%s\" to \"%s\"", old_filename, filename)
|
||||
if filename ~= old_filename then
|
||||
os.remove(old_filename)
|
||||
end
|
||||
end, common.path_suggest)
|
||||
end, function (text)
|
||||
return common.home_encode_list(common.path_suggest(common.home_expand(text)))
|
||||
end)
|
||||
end,
|
||||
}
|
||||
|
||||
|
|
|
@ -203,6 +203,12 @@ function common.basename(path)
|
|||
end
|
||||
|
||||
|
||||
-- can return nil if there is no directory part in the path
|
||||
function common.dirname(path)
|
||||
return path:match("(.+)[\\/][^\\/]+$")
|
||||
end
|
||||
|
||||
|
||||
function common.home_encode(text)
|
||||
if HOME and string.find(text, HOME, 1, true) == 1 then
|
||||
local dir_pos = #HOME + 1
|
||||
|
@ -228,16 +234,6 @@ function common.home_expand(text)
|
|||
end
|
||||
|
||||
|
||||
function common.normalize_path(filename)
|
||||
if PATHSEP == '\\' then
|
||||
filename = filename:gsub('[/\\]', '\\')
|
||||
local drive, rem = filename:match('^([a-zA-Z])(:.*)')
|
||||
return drive and drive:upper() .. rem or filename
|
||||
end
|
||||
return filename
|
||||
end
|
||||
|
||||
|
||||
local function split_on_slash(s, sep_pattern)
|
||||
local t = {}
|
||||
for fragment in string.gmatch(s, "([^/\\]+)") do
|
||||
|
@ -247,8 +243,27 @@ local function split_on_slash(s, sep_pattern)
|
|||
end
|
||||
|
||||
|
||||
function common.normalize_path(filename)
|
||||
if PATHSEP == '\\' then
|
||||
filename = filename:gsub('[/\\]', '\\')
|
||||
local drive, rem = filename:match('^([a-zA-Z])(:.*)')
|
||||
filename = drive and drive:upper() .. rem or filename
|
||||
end
|
||||
local parts = split_on_slash(filename, PATHSEP)
|
||||
local accu = {}
|
||||
for _, part in ipairs(parts) do
|
||||
if part == '..' then
|
||||
table.remove(accu)
|
||||
elseif part ~= '.' then
|
||||
table.insert(accu, part)
|
||||
end
|
||||
end
|
||||
return table.concat(accu, PATHSEP)
|
||||
end
|
||||
|
||||
|
||||
function common.path_belongs_to(filename, path)
|
||||
return filename and string.find(filename, path .. PATHSEP, 1, true) == 1
|
||||
return string.find(filename, path .. PATHSEP, 1, true) == 1
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -36,10 +36,14 @@ local function splice(t, at, remove, insert)
|
|||
end
|
||||
|
||||
|
||||
function Doc:new(filename)
|
||||
function Doc:new(filename, abs_filename, new_file)
|
||||
self.new_file = new_file
|
||||
self:reset()
|
||||
if filename then
|
||||
self:load(filename)
|
||||
self:set_filename(filename, abs_filename)
|
||||
if not new_file then
|
||||
self:load(filename)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -65,16 +69,15 @@ function Doc:reset_syntax()
|
|||
end
|
||||
|
||||
|
||||
function Doc:set_filename(filename)
|
||||
function Doc:set_filename(filename, abs_filename)
|
||||
self.filename = filename
|
||||
self.abs_filename = system.absolute_path(filename)
|
||||
self.abs_filename = abs_filename
|
||||
end
|
||||
|
||||
|
||||
function Doc:load(filename)
|
||||
local fp = assert( io.open(filename, "rb") )
|
||||
self:reset()
|
||||
self:set_filename(filename)
|
||||
self.lines = {}
|
||||
for line in fp:lines() do
|
||||
if line:byte(-1) == 13 then
|
||||
|
@ -91,17 +94,20 @@ function Doc:load(filename)
|
|||
end
|
||||
|
||||
|
||||
function Doc:save(filename)
|
||||
filename = filename or assert(self.filename, "no filename set to default to")
|
||||
function Doc:save(filename, abs_filename)
|
||||
if not filename then
|
||||
assert(self.filename, "no filename set to default to")
|
||||
filename = self.filename
|
||||
abs_filename = self.abs_filename
|
||||
end
|
||||
local fp = assert( io.open(filename, "wb") )
|
||||
for _, line in ipairs(self.lines) do
|
||||
if self.crlf then line = line:gsub("\n", "\r\n") end
|
||||
fp:write(line)
|
||||
end
|
||||
fp:close()
|
||||
if filename then
|
||||
self:set_filename(filename)
|
||||
end
|
||||
self:set_filename(filename, abs_filename)
|
||||
self.new_file = false
|
||||
self:reset_syntax()
|
||||
self:clean()
|
||||
end
|
||||
|
@ -113,7 +119,7 @@ end
|
|||
|
||||
|
||||
function Doc:is_dirty()
|
||||
return self.clean_change_id ~= self:get_change_id()
|
||||
return self.clean_change_id ~= self:get_change_id() or self.new_file
|
||||
end
|
||||
|
||||
|
||||
|
|
|
@ -733,10 +733,30 @@ function core.normalize_to_project_dir(filename)
|
|||
end
|
||||
|
||||
|
||||
-- The function below works like system.absolute_path except it
|
||||
-- doesn't fail if the file does not exist. We consider that the
|
||||
-- current dir is core.project_dir so relative filename are considered
|
||||
-- to be in core.project_dir.
|
||||
-- Please note that .. or . in the filename are not taken into account.
|
||||
-- This function should get only filenames normalized using
|
||||
-- common.normalize_path function.
|
||||
function core.project_absolute_path(filename)
|
||||
if filename:match('^%a:\\') or filename:find('/', 1, true) then
|
||||
return filename
|
||||
else
|
||||
return core.project_dir .. PATHSEP .. filename
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function core.open_doc(filename)
|
||||
local new_file = not filename or not system.get_file_info(filename)
|
||||
local abs_filename
|
||||
if filename then
|
||||
-- normalize filename and set absolute filename then
|
||||
-- try to find existing doc for filename
|
||||
local abs_filename = system.absolute_path(filename)
|
||||
filename = core.normalize_to_project_dir(filename)
|
||||
abs_filename = core.project_absolute_path(filename)
|
||||
for _, doc in ipairs(core.docs) do
|
||||
if doc.abs_filename and abs_filename == doc.abs_filename then
|
||||
return doc
|
||||
|
@ -744,8 +764,7 @@ function core.open_doc(filename)
|
|||
end
|
||||
end
|
||||
-- no existing doc for filename; create new
|
||||
filename = filename and core.normalize_to_project_dir(filename)
|
||||
local doc = Doc(filename)
|
||||
local doc = Doc(filename, abs_filename, new_file)
|
||||
table.insert(core.docs, doc)
|
||||
core.log_quiet(filename and "Opened doc \"%s\"" or "Opened new doc", filename)
|
||||
return doc
|
||||
|
|
Loading…
Reference in New Issue