Using one buffer as "information screen"

0 views
Skip to first unread message

Fredrik

unread,
Nov 22, 2008, 5:00:50 AM11/22/08
to vim_use
I would like to set up my Vim so that I have two buffers visible, and
as I am typing in one buffer the other buffer is showing information
about the first buffer. What I specifically want to do is that each
time I press Enter, the second buffer is updated to show all lines
from the first buffer that matches (in some way) the line I just
entered in the first buffer. Did you understand that..? :)

Does anybody know of anything like this, that I can look at and learn
from?

Thanks for any help!

Marc Weber

unread,
Nov 22, 2008, 9:20:25 AM11/22/08
to vim...@googlegroups.com
> Does anybody know of anything like this, that I can look at and learn
> from?
>
> Thanks for any help!
>
Have a look at
http://www.vim.org/scripts/script.php?script_id=2014

it does somewhat what you're requesting for. however you have to tweak
it.
What do you really want to do ? You know about line completion c-x l ?

But maye you have to do that all manually by invoking :sp :b nr etc
yourself updating the text.

Sincerly
Marc Weber

Fredrik

unread,
Nov 22, 2008, 11:59:04 PM11/22/08
to vim_use
I am making notes of my spendings in a cashbook. I am inputting a line
like this:

-10 Beer

So I was thinking that it would be nice if I could in a second buffer
see all my previous entries regarding beer (to give me an idea of just
how much money I am actually spending on beer). The matching part of
the problem I know how to do, but I am a bit unsure of how to make two
buffers work together like this. I guess it just boils down to map the
Enter key like this:
<CR> ---> <Esc><C-w>j !!MyFilterScript<C-w>k o

But how do I tell the second buffer which line I was at in the first
buffer then..? Well, I'm on loose ground generally. I'm not proficient
in Vim. :)

Best regards,
Fredrik

John Beckett

unread,
Nov 23, 2008, 2:47:07 AM11/23/08
to vim...@googlegroups.com
Fredrik wrote:
> I am making notes of my spendings in a cashbook. I am
> inputting a line like this:
>
> -10 Beer
>
> So I was thinking that it would be nice if I could in a
> second buffer see all my previous entries regarding beer (to
> give me an idea of just how much money I am actually spending
> on beer).

---file scan.vim---
function! Scan()
let line = getline('.')
let word = matchstr(line, '\s\zs\w\+')
if !empty(word)
normal mz
let @z = ''
execute 'g/\c'.word.'/y Z'
wincmd p
$put z
wincmd p
normal `z
endif
endfunction
inoremap <F8> <C-o>:call Scan()<CR>
---end---

After saving scan.vim, enter command (source current file):
:so %

You can now close scan.vim (e.g. :bd). Arrange two windows, one with your file, and
the other blank. In your file, with the cursor on a line of interest and in insert
mode, press F8.

You could make it <CR> rather than <F8>, but I suspect it would become tiresome.

John

Tom Link

unread,
Nov 23, 2008, 2:52:11 AM11/23/08
to vim_use
> Enter key like this:
> <CR>  --->   <Esc><C-w>j !!MyFilterScript<C-w>k o
>
> But how do I tell the second buffer which line I was at in the first
> buffer then..?

I'd rather let the function do the buffer switching. I.e. let the
function collect matching lines, maybe calculate a sum, switch to the
buffer containing the overview (I assume this could be done by name),
delete the current contents, insert the lines, switch back.

Agathoklis D. Hatzimanikas

unread,
Nov 23, 2008, 4:15:49 AM11/23/08
to vim...@googlegroups.com
On Sat, Nov 22, at 08:59 Fredrik wrote:
>
> I am making notes of my spendings in a cashbook. I am inputting a line
> like this:
>
> -10 Beer
>
> So I was thinking that it would be nice if I could in a second buffer
> see all my previous entries regarding beer (to give me an idea of just
> how much money I am actually spending on beer). The matching part of
> the problem I know how to do, but I am a bit unsure of how to make two
> buffers work together like this. I guess it just boils down to map the
> Enter key like this:
> <CR> ---> <Esc><C-w>j !!MyFilterScript<C-w>k o
>
> But how do I tell the second buffer which line I was at in the first
> buffer then..? Well, I'm on loose ground generally. I'm not proficient
> in Vim. :)
>

Using the internal grep and the quickfix window?
Here is function to get an idea:

(Assuming in the following sample, that the last word
in the current line is the entry in your cashbook
or else you can (possible) use: expand('<cword>'))

function! UpdateRecords()
let pat = get(split(getline('.')), -1, '')
if !empty(pat)
execute 'vimgrep /'.pat.'/j %'
copen
if &buftype == 'quickfix'
wincmd k
endif
endif
endfunction

imap <buffer> <Char-0x0d> <C-o>:call UpdateRecords()<CR><Esc>o

> Best regards,
> Fredrik

Regards,
Ag.

Agathoklis D. Hatzimanikas

unread,
Nov 23, 2008, 6:29:33 AM11/23/08
to vim...@googlegroups.com

Oh, and if you want to print the summary of all your "beers" in the first
line in the quickfix window and assuming you have standard (uniform fields)
records in every line in your cashbook, like the one you've already
mentioned,

-10 beer

then, the function can be modified further, here is a way to do it:

function! UpdateRecords()
let pat = get(split(getline('.')), -1, '')
if !empty(pat)

try

execute 'vimgrep /'.pat.'/j %'

catch /.*/
let dic = {'text' : 'NO MATCH'}
call setqflist([dic])
return ''
endtry
let list = getqflist()
let sum = 0
for i in list
let sum -= str2float(split(i['text'])[0])
endfor
let dic = {'text' : 'Summary: '.float2nr(sum).' € for '.pat}
call setqflist([dic])
call setqflist(list, 'a')


copen
if &buftype == 'quickfix'
wincmd k
endif
endif
endfunction

Regards,
Ag.

Fredrik

unread,
Nov 23, 2008, 7:25:30 AM11/23/08
to vim_use
Hmm, looks good but I don't have that MzScheme on my Unbuntu machine
though. That could be replaced by vimgrep then, I guess... Thanks!

Fredrik

unread,
Nov 23, 2008, 7:28:16 AM11/23/08
to vim_use
That's a really sweet and simple solution! The quickfix window
contains a bit more information than I care about, but it's working
nicely. Thanks.

On Nov 23, 6:15 pm, "Agathoklis D. Hatzimanikas" <a.hat...@gmail.com>
wrote:

Fredrik

unread,
Nov 23, 2008, 7:37:31 AM11/23/08
to vim_use
Nice! Except the fact that I get an error "unknown function:
str2float". I'll go and look for that function...
However, not all my lines contain an entry. Some lines are dates:

2008-11-23
-10 Beer
-50 Food
2008-11-22
-17 Haircut

/Fredrik

On Nov 23, 8:29 pm, "Agathoklis D. Hatzimanikas" <a.hat...@gmail.com>
wrote:

Tony Mechelynck

unread,
Nov 23, 2008, 8:02:01 AM11/23/08
to vim...@googlegroups.com
On 23/11/08 13:37, Fredrik wrote:
> Nice! Except the fact that I get an error "unknown function:
> str2float". I'll go and look for that function...
[...]

For that function, you need Vim 7.2 with +float compiled-in.
(Floating-point support is a rather recent addition). Also, you better
use 7.2.011 or later because earlier versions have known bugs in
floating-point handling.


Best regards,
Tony.
--
Good day to avoid cops. Crawl to school.

Agathoklis D. Hatzimanikas

unread,
Nov 23, 2008, 8:58:15 AM11/23/08
to vim...@googlegroups.com
On Sun, Nov 23, at 04:37 Fredrik wrote:
>
> Nice! Except the fact that I get an error "unknown function:
> str2float". I'll go and look for that function...

Oh you need vim-7.2 for floating point support.

> However, not all my lines contain an entry. Some lines are dates:
>
> 2008-11-23
> -10 Beer
> -50 Food
> 2008-11-22
> -17 Haircut
>

Thanks to you, finally I spend some minutes to write a function (for
my own use) to do a similar job. Here are some more details.

I have a very simple calendar (thanks to a function by Siegfried Bublitz)[1],
which the entries looks like these below:

===========================================
Mo 22 @CAR@ 200 € Λάστιχα 91.000 χιλιόμετρα
Tu 23 @HOME@ 75 € Ξυλεία
...
Sa 27 @TZAKI08@ 150 €
.....
Tu 14 @EVENTS@ Γέννησε η Αζορίνα 5 σκυλάκια
===========================================

So I wrote the following function (similar to the one I posted) to have
a quick sum for my spendings.

function! personal#sumofcalendar(pat)
try
execute 'vimgrep /'.a:pat.'/j %'


catch /.*/
let dic = {'text' : 'NO MATCH'}
call setqflist([dic])
return ''
endtry
let list = getqflist()
let sum = 0
for i in list

let nr = str2float(split(i['text'])[3])
let sum += nr
endfor
let dic = {'text' : 'Summary: '.float2nr(sum).' € for '.a:pat}


call setqflist([dic])
call setqflist(list, 'a')
copen
if &buftype == 'quickfix'
wincmd k
endif

endfunction

(Note that this is an autoload function, see :help autoload-functions)

I can call this function like:

:call personal#sumofcalendar('@TZAKI08@')

Or create a command:

command! -nargs=1 Calsum call personal#sumofcalendar('<args>')

so I can do:

:Calsum TZAKI08

or if I have the cursor on the entry I'm interested:

:Calsum <C-R><C-W>

this will pull the current word and use it as an argument.

I could and I'll probably change the function to return the summary
so I could reuse the returned value, so I could do:

:let var = personal#sumofcalendar('@TZAKI08@')

or from insert mode:

<C-R>= personal#sumofcalendar('@TZAKI08@')

which this will put the returned value on the file.

You can also use the (i)map'ping I've already posted in my previous
email, although using "enter" in a mapping, it might have some unpleasant
consequences or it might not! :), it's much depending on the way you are
using the editor in that particular file.
Vim is capable to do a lot of things with a lot of different ways and style. :)


Anyway, the trick when you are working with that kind of files is to
have uniform fields, then it's a matter to find a way to process the data.
Especially now that current version (7.2) has gained floating point support,
makes vim very capable to do a lot of that kind of operations and do
that very reliable, since firstly vim has mechanisms to check and convert
the type of data and secondly it's easy to reuse the data types
(especially if you are using 'anonymous-functions').

For instance look at the function above.
Vim is using dictionaries and lists to store the information from
'vimgrep' and then prints them to the quickfix window.
It was easy to take that info - which it was already available - and to
reuse it for a completely different thing (to make a summary of a field
matching a pattern (awk's job!)).


1. http://vim.wikia.com/wiki/Generate_calendar_file

> /Fredrik

Regards,
Ag.

Fredrik

unread,
Nov 23, 2008, 11:49:52 AM11/23/08
to vim_use
>
> Anyway, the trick when you are working with that kind of files is to
> have uniform fields, then it's a matter to find a way to process the data.

That's really true. I'll have to change the format of my file. I was
thinking that I don't want to clutter my file with a lot of dates
since I might make 10 entries on the same day. I guess I'll make my
cashbook in this format instead:

2008-11-23 -10 Beer
2008-11-23 - 50 Food
2008-11-22 -17 Haircut

It's a bit less readable, but I wont be reading through all my
spendings anyway... :) So then I definitely have to map Enter to
imap <CR> <CR><Esc>!!date

Thanks for your input!

Regards,
Fredrik

John Beckett

unread,
Nov 23, 2008, 7:01:41 PM11/23/08
to vim...@googlegroups.com
Fredrik wrote:
> Hmm, looks good but I don't have that MzScheme on my Unbuntu
> machine though. That could be replaced by vimgrep then, I
> guess... Thanks!

I don't know why you mentioned MzScheme. The script I posted should work on any Vim
7 without any extra tools. However, the vimgrep idea might be better.

John

Fredrik

unread,
Nov 23, 2008, 8:05:08 PM11/23/08
to vim_use
I looked at your code and was wondering what that "normal mz" was. I
type :h mz and the help file refers me to something called MzScheme. I
thought that's what is used in your script?

Tony Mechelynck

unread,
Nov 23, 2008, 9:36:30 PM11/23/08
to vim...@googlegroups.com
On 24/11/08 02:05, Fredrik wrote:
> I looked at your code and was wondering what that "normal mz" was. I
> type :h mz and the help file refers me to something called MzScheme. I
> thought that's what is used in your script?
>

For the meaning of "normal mz", look at ":help m" (without the quotes).
(Also, of course, ":help :normal", but I think you know what _that_ means.)


Best regards,
Tony.
--
Why is it that there are so many more horses' asses than there are
horses?
-- G. Gordon Liddy

Reply all
Reply to author
Forward
0 new messages