8

I want to modify files with vim without changing the creation time stamps.

The docs doesn't seem to mention anything about such possibility.

I'd like to achieve this without turning off the swap/recover feature.

One alternative would be to store the time somewhere and then overwrite it when exiting, I guess.

  • 2
    What OS are you on? Some OS' don't store creation times, so it could make a difference. – blm Nov 6 '15 at 18:46
  • I'm on OS X 10.8.5. – 1.61803 Nov 6 '15 at 22:00
2

Sato's answer would be correct on a standard Unix-derivative, where ctime is often mistaken for creation time but is actually inode change time, and "preserving" it doesn't really make sense. However, I asked what OS the poster is using because Mac OS X maintains a separate create time that is an actual creation date and time, and isn't updated by modifying the file in place or changing the file's mode or anything like that, all of which do update ctime.

You can see the creation time by doing a Get Info on a file in the Finder or GetFileInfo <file> from a command line (GetFileInfo requires the developer tools to be installed). The time can be modified using SetFile -d <datetime> <file> (also requiring developer tools).

So it seems reasonable (to me, don't know about Bram :-) ) to ask for vim to maintain the create time on Mac OS X, by copying the create time from the original file to the new file, but it clearly doesn't, and glancing through the vim sources, I don't see anywhere where it does so. So, unfortunately, it appears the answer to the poster's question is "It's not currently possible." Because Mac OS X (with developer tools) does allow getting and setting the create time from the command line, it may be possible to put together a vim script that does that, although that's (currently) beyond my vim scripting abilities.

Edit

I decided to play around with scripting something and actually got it to work!

Add the following to your .vimrc:

autocmd BufReadPre * call SaveFileCreateTime()
autocmd BufWritePost * call RestoreFileCreateTime()

function! SaveFileCreateTime()
    let l:path = expand('%:p')

    if l:path != ''
        let b:created = system("GetFileInfo -d " . shellescape(bufname("%")))
    endif
endfunction

function! RestoreFileCreateTime()
    if exists('b:created')
        execute system(
          \ 'SetFile -d ' .
          \ shellescape(b:created) .
          \ ' ' .
          \ shellescape(bufname("%")))
    endif
endfunction

That sets auto commands to run before a file is read (for editing in a buffer, not for things like :read) and after it's written. The first calls SaveFileCreateTime which uses GetFileInfo -d to get the file's create time and store it in the buffer local variable b:created. After a file is written, RestoreFileCreateTime is called. If b:created exists, it's used in a system command to use SetFile -d to set the time.

Here's an example:

$ echo hello >file.txt
$ stat -c%z file.txt;GetFileInfo -d file.txt
2015-11-07 11:44:04.000000000 -0800
11/07/2015 11:44:04
$ vim file.txt
a earth<esc>:wq
$ cat file.txt
hello earth
$ stat -c%z file.txt;GetFileInfo -d file.txt
2015-11-07 11:44:24.000000000 -0800
11/07/2015 11:44:04

You can see the inode change time (as displayed by stat) has changed, but the file create time (as displayed by GetFileInfo) hasn't. Success!

As noted above, this requires the developer tools to be installed to get GetFileInfo and SetFile. Also, this is my first real script, so feel free to point out all the hideous errors I've made!

  • Would a vim script be a wrapper or alter vim's runtime using those tools, which I do have installed btw, to preserve the creation date? – 1.61803 Nov 7 '15 at 19:33
  • It would be some functions you put in your .vimrc. I decided to play around with it and actually got something that works! I'll edit my answer to include that. – blm Nov 7 '15 at 19:39
  • @1.61803 Ok, edited my answer to include the vimscript to save and restore the time. Let me know if it works for you. – blm Nov 7 '15 at 19:51
  • I tested it while vimdiffing files owned by root and user. So far so good. You should post this in the Vim Tips wiki. That was a great answer, thanks. – 1.61803 Nov 8 '15 at 0:44
  • Btw, your stat command is for Linux, I guess. In OS X 10.8.5 you'd use stat -f %Sc. – 1.61803 Nov 8 '15 at 1:37
2

Add set backupcopy=yes to your vimrc file to preserve file creation time on macOS.

For more info, see :help 'backupcopy'.

Source: How can I get VIM to maintain the creation date for a file? (OS X)

  • 1
    It works, thanks! – 1.61803 Jun 11 at 9:37
  • @1.61803 Sure! :-) – ma11hew28 Jun 11 at 14:01
1

What you want is not possible to implement in UNIX using standard userspace functions. The ctime of a file is updated automatically by the kernel when the file's inode changes. Unlike atime and mtime, there is no user-accessible function to set ctime to an arbitrary value.

  • Could vim, instead of swapping files, just cp test.swp test.txt? – 1.61803 Nov 7 '15 at 12:52
  • @1.61803, less test.swp should answer your question. – romainl Nov 7 '15 at 14:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.