EditPad Lite has a nice feature (CTRL-E, CTRL-I) which inserts a time stamp e.g. "2008-09-11 10:34:53" into your code.
What is the best way to get this functionality in Vim?
(I am using Vim 6.1 on a Linux server via SSH. In the current situation a number of us share a login so I don't want to create abbreviations in the home directory if there is another built-in way to get a timestamp.)
To make it work cross-platform, just put the following in your vimrc:
nmap <F3> i<C-R>=strftime("%Y-%m-%d %a %I:%M %p")<CR><Esc>
imap <F3> <C-R>=strftime("%Y-%m-%d %a %I:%M %p")<CR>
Now you can just press F3 any time inside Vi/Vim and you'll get a timestamp like 2016-01-25 Mo 12:44 inserted at the cursor.
For a complete description of the available parameters check the documentation of the C function strftime().
http://kenno.wordpress.com/2006/08/03/vim-tip-insert-time-stamp/
Tried it out, it works on my mac:
:r! date
produces:
Thu Sep 11 10:47:30 CEST 2008
This:
:r! date "+\%Y-\%m-\%d \%H:\%M:\%S"
produces:
2008-09-11 10:50:56
Why is everybody using :r!? Find a blank line and type !!date from command-mode. Save a keystroke!
[n.b. This will pipe the current line into stdin, and then replace the line with the command output; hence the "find a blank line" part.]
As an extension to #Swaroop C H's answer,
^R=strftime("%FT%T%z")
is a more compact form that will also print the time zone (actually the difference from UTC, in an ISO-8601-compliant form).
If you prefer to use an external tool for some reason,
:r !date --rfc-3339=s
will give you a full RFC-3339 compliant timestamp; use ns instead of s for Spock-like precision, and pipe through tr ' ' T to use a capital T instead of a space between date and time.
Also you might find it useful to know that
:source somefile.vim
will read in commands from somefile.vim: this way you could set up a custom set of mappings, etc., and then load it when you're using vim on that account.
:r! date
You can then add format to the date command (man date) if you want the exact same format and add this as a vim alias as well
:r! date +"\%Y-\%m-\%d \%H:\%M:\%S"
That produces the format you showed in your example (date in the shell does not use \%, but just %, vim replaces % by the name of the current file, so you need to escape it).
You can add a map in your .vimrc for it to put the command automatically, for instance, each time you press F3:
:map <F3> :r! date +"\%Y-\%m-\%d \%H:\%M:\%S"<cr>
(Edited the from above :) )
(Edit: change text part to code, so that
<F3>
can be displayed)
From the Vim Wikia.
I use this instead of having to move my hand to hit an F key:
:iab <expr> tds strftime("%F %b %T")
Now in Insert mode it just type tds and as soon as I hit the space bar or return, I get the date and keep typing.
I put the %b in there, because I like seeing the month name. The %F gives me something to sort by date. I might change that to %Y%m%d so there are no characters between the units.
Unix,use:
!!date
Windows, use:
!!date /t
More details:see Insert_current_date_or_time
For a unix timestamp:
:r! date +\%s
You can also map this command to a key (for example F12) in VIM if you use it a lot:
Put this in your .vimrc:
map <F12> :r! date +\%s<cr>
I wanted a custom command :Date (not a key mapping) to insert the date at the current cursor position.
Unfortunately straightforward commands like r!date result in a new line. So finally I came up with the following:
command Date execute "normal i<C-R>=strftime('%F %T')<CR><ESC>"
which adds the date/time string at the cursor position without adding any new line (change to normal a add after the cursor position).
I'm using vi in an Eterm for reasons and it turns out that strftime() is not available in vi.
Fought long and hard and finally came up with this:
map T :r! date +"\%m/\%d/\%Y \%H:\%M" <CR>"kkddo<CR>
Result: 02/02/2021 16:45
For some reason, adding the date-time alone resulted in a blank line above the date-time and the cursor set on the date-time line.
date +"[etc]" <CR>
Enters the date-time
"kk
Moves up two lines
dd
Deletes the line above the date-time
o <CR>
Opens a line below the time and adds a carriage return (linefeed)
Bonus:
vi doesn't read ~/.vimrc, it reads ~/.exrc
Also, this is how it looks in vim/.vimrc:
map T "=strftime("%m/%d/%y %H:%M")<CR>po<CR>
Another quick way not included by previous answers: type-
!!date
Related
What script might i use in (vanilla) Vim to insert a snippet with the current date and time into each and every new note generated.
You can use for example:
:pu=strftime('%c')
To put a timestamp into a file in the default timestamp format. The format is adjustable.
You could bind this action to a key (here F5 as an example). Put it to your .vimrc file without the colon in the beginning to make it permanent.
:nnoremap <F5> "=strftime("%c")<CR>P
More examples: https://vim.fandom.com/wiki/Insert_current_date_or_time
In my case I have an insert abbreviation, so, wenever I am typing I just do 'idate'
inoreabbrev idate <C-R>=strftime("%b %d %Y %H:%M")<CR>
Just change the "strftime" to fit your needs
I need to create a list which will hold fqdn's of about 30 servers.
Until now, whenever I needed to create such a list, I would:
Open vim
Manually insert the first line
Yanking the first line and then pasting the line as many times as the amount of servers in the list.
Then, I would manually edit the host names.
For example:
scraper01.nj.company.com
scraper02.nj.company.com
.
.
.
I wanted to know if there's a way to do it (given the fact that the names are the same apart for the chronological number) automatically, maybe by using sed but I don't know how to do it.
Can you please assist me?
Start with:
scraper01.nj.company.com
Press qq to start recording a macro in register q:
qq
Yank the current line:
yy
Paste it below:
p
Increment the number:
<C-a>
Stop recording:
q
Play it back 28 times:
28#q
All together:
qqyyp<C-a>q28#q
Inside vim you could do the following:
:put =map(range(1,30), 'printf(''scraper%02d.nj.company.com'', v:val)')
In a bash, just use printf with a ranged brace expansion:
printf "%s\n" "scraper"{01..30}".nj.company.com"
Prints:
scraper01.nj.company.com
scraper02.nj.company.com
[...]
scraper30.nj.company.com
Or another solution, with a for loop:
for (( i=0; i<=30; i++ )) ; do printf "scraper%02d.nj.company.com\n" $i; done
The solution posted by #chaos works fine, but since you tagged this with vim, here's another Vim way.
First, there is this very useful map for copying lines and blocks:
nnoremap <silent> <M-c> #='"zyy"zp'<CR>
With it, you can write scraper01.nj.company.com, then go to visual mode and press 9Meta-c to add 9 more copies of it (of course, you can replace 9 by any number).
Then install the VisIncr plugin. With it, you can now press Ctrl-v to mark the column of 01, then run :II. This will change the numbers to 01 ... 10. Save, and you're done.
Both the <M-c> map and the VisIncr plugin do more than shown above. They can be quite useful in many other situations.
I'm new to the vi editor and I would like to create a simple custom command in .vimrc that inserts something like 2012-03-13 22:21:17.0 +0100 / Daniel.
Actually, my command (in .vimrc) is as follows:
command! InsertTime :normal a<C-R>=strftime('%F %H:%M:%S.0 %z')<CR>
I also set a variable:
let myname="Daniel"
InsertTime inserts the date perfectly. But how can I concatenate it with the content of my variable?
To concatenate, vim scripts use . caracter. So try this one :
In vimrc:
let myname="Daniel"
command! InsertTime :normal a<C-R>=strftime('%F %H:%M:%S.0 %z') . "/" . myname<CR>
no tested there.
Since you said you're new to "vim" I am going to assume you don't know any of the things I'm about tell you. Mucho sorry if you already know them.
If you're going to do this a lot (insert the line "%F %H:%M:%S.0 %z / Daniel"), instead of defining a command, which you have to invoke with a :command_name, define a macro and/or an input macro that can be invoked with just two or three character.
To define an input macro, do the following at the ':' prompt, or add it to your $HOME/.exrc or $HOME/.vimrc file (without the preceding ':'):
:map <C-X><C-X> Go<ESC>!!date '+\%F \%H:\%M:\%S.0 \%z'<CR>A / Daniel<ESC>
Now when you're in "vi" (but not in input mode), typing control-Xcontrol-X will:
G go to last line in file; replace this with the "motion" keys sequence appropriate for your use (or nothing at all if you want to append the line right after the cursor)
o open a new line
<ESC> escape out of input mode
!!date ... invoke the date command, replace the current line with its stdout (output)
A append at the end of the line (now having the "date")
/ Dan... verbatim intput text
<ESC> escape out of input mode
control-Xcontrol-X can be some unusual sequence that you'd normally not use for anything, nor used by any "vi" operation that you might use. I use as the first character, because in "vi", decrements the next integer on the line after the cursor, if any. That is something I hardly ever do. I define my macros to be invoked with <C-X><C-B>, <C-X><C-D>, <C-X>s1, etc.
To create an input macro, well, that's another whole long subject, and I'm tired of typing today, so, another day. :)
I am trying to save a file name that includes the date and time. However, I would like the date and time to be in UTC. This is what I am doing:
In vimrc:
cmap <F3> <C-R>=strftime("%Y%m%d%H%M")<CR>
I type this when I save the file:
:w i<F3>.txt
and I get a file that is named:
i[localtime].txt
but I want:
i[UTCtime].txt
Is there a way to actually do this, or am I stuck with my local time forever? Vim is my only way to explore various time zones, please help me. :)
Oh and by the way, I will be using both Linux and Windows for this.
Well, I'm not sure whether this will work correctly on Linux or not, but I believe so (I'm on a Mac).
The idea, is that you can use the date utility to retrieve the time with more flexibility. It accepts an option -u which outputs the time in UTC. All you have to to is wrap that in a system() call.
cmap <F3> <C-R>=system('date -u "+%Y%m%d%H%M"')<CR>
And there you have your formatted UTC time.
If a null character appears at the end of the time inserted (it appears as ^#) then you may want to append a [:-2] to strip it from the returning string, right before the <CR> in the mapping above. That comes from the translated newline the system outputs. Check :h NL-used-for-Nul.
About windows, well I have no clue. You may want to try out the utility in Linux before mapping things, but I'm almost sure there will be no differences.
I know there are ways to automatically set the width of text in vim using set textwidth (like Vim 80 column layout concerns). What I am looking for is something similar to = (the indent line command) but to wrap to 80. The use case is sometimes you edit text with textwidth and after joining lines or deleting/adding text it comes out poorly wrapped.
Ideally, this command would completely reorganize the lines I select and chop off long lines while adding to short ones. An example:
long line is long!
short
After running the command (assuming the wrap was 13 cols):
long line is
long! short
If this isn't possible with a true vim command, perhaps there is a command-line program which does this that I can pipe the input to?
After searching I found this reference which has some more options: http://www.cs.swarthmore.edu/help/vim/reformatting.html
Set textwidth to 80 (:set textwidth=80), move to the start of the file (can be done with Ctrl-Home or gg), and type gqG.
gqG formats the text starting from the current position and to the end of the file. It will automatically join consecutive lines when possible. You can place a blank line between two lines if you don't want those two to be joined together.
Michael's solution is the key, but I most often find I want to reformat the rest of the
current paragraph; for this behavior, use gq}.
You can use gq with any movement operators. For example, if you only want to reformat to the end of the current line (i.e. to wrap the line that your cursor is on) you can use gq$
You can also reformat by selecting text in visual mode (using `v and moving) and then typing gq.
There are other options for forcing lines to wrap too.
If you want vim to wrap your lines while you're inserting text in them instead of having to wait till the end to restructure the text, you will find these options useful:
:set textwidth=80
:set wrapmargin=2
(Don't get side-tracked by wrap and linebreak, which only reformat the text displayed on screen, and don't change the text in the buffer)
Thanks to a comment from DonaldSmith I found this, as the textwidth option didn't reformat my long line of text (I was converting playing with hex-to-byte conversions):
:%!fold -w 60
That reformated the whole file (which was one line for me) into lines of length 60.
If you're looking for a non-Vim way, there's always the UNIX commands fmt and par.
Notes:
I can't comment on Unicode, it may or may not behave differently.
#nelstrom has already mentioned using par in his webcast.
Here's how we would use both for your example.
$ echo -e 'long line is long!\nshort' > 3033423.txt
$ cat 3033423.txt
long line is long!
short
$ fmt -w 13 3033423.txt
long line is
long! short
$ par 13gr 3033423.txt
long line is
long! short
To use from inside Vim:
:%! fmt -w 13
:%! par 13gr
You can also set :formatprg to par or fmt and override gq. For more info, call :help formatprg inside Vim.
Almost always I use gq in visual mode. I tell my students it stands for "Gentlemens' Quarterly," a magazine for fastidious people.