martanne / vis

A vi-like editor based on Plan 9's structural regular expressions
Other
4.19k stars 259 forks source link

[question] newline at end of file #1088

Closed dkwo closed 1 year ago

dkwo commented 1 year ago

what is the recommended way to place a newline at the end of file in vis? currently i get \ No newline at end of file all the time in git

Thanks.

mcepl commented 1 year ago

We were just discussing this on the #vis-editor channel and the conclusion was that the safest way would be adding to your ~/.config/vis/visrc.lua something like this (see vis API documentation for more information):

-- adds a newline before each write if there is no newline
vis.events.subscribe(vis.events.FILE_SAVE_PRE, function (file, path)
    if
            file.size==0
            or file.size==1 and file:content(0,1)~="\n"
            or file.size>1 and file:content(file.size-2,file.size)~="\n\n"
    then
            file:delete(file.size,file.size)
            file:insert(file.size,"\n")
    end
    return true
end)

Alternative condition would be

if file:content(file.size-1,file.size)~="\n" then

Something like this would help?

dkwo commented 1 year ago

Thank you. That produces visrc.lua:2: attempt to index a nil value (field 'events'). I must note that my visrc.lua was previously empty. Is there anything I'm missing, or even a sensible visrc that I could look at?

mcepl commented 1 year ago

Start with the default visrc.lua.

dkwo commented 1 year ago

Thanks a lot!

dkwo commented 1 year ago

With

$ cat .config/vis/visrc.lua 
-- load standard vis module, providing parts of the Lua API
require('vis')

vis.events.subscribe(vis.events.INIT, function()
-- Your global configuration options
end)

vis.events.subscribe(vis.events.WIN_OPEN, function(win)
    -- luacheck: no unused args
    -- Your per window configuration options e.g.
    -- vis:command('set number')
end)

-- adds a newline before each write if there is no newline
vis.events.subscribe(vis.events.FILE_SAVE_PRE, function (file, path)
    if
        file.size==0
        or file.size==1 and file:content(0,1)~="\n"
        or file.size>1 and file:content(file.size-2,file.size)~="\n\n"
    then
        file:delete(file.size,file.size)
        file:insert(file.size,"\n")
    end
    return true
end)

there's an undesired effect that, if a newline is already present, then another line is added at the end of file. Can this be avoided?

ninewise commented 1 year ago

Something like this should work? (Using mcepls alternative)

-- ensure none-empty files have a line ending
vis.events.subscribe(vis.events.FILE_SAVE_PRE, function(file, path)
›   if file.size ~= 0 and file:content(file.size - 1, 1) ~= "\n" then
›   ›   file:insert(file.size, "\n")
›   end
›   return true
end)
dkwo commented 1 year ago

Thanks, that seems to work as desired.