13

I want vim (MacVim) to default to a large font for new/short files and dynamically scale down to a smaller font (to a set minimum) as the number of lines grows. Is this possible to do with a plugin? What vim concepts will I need to know to write that plugin?

My reason for wanting this is that I love writing code in a large font, but after files get longer I'd rather squint a little than scroll.

gouch
  • 135
  • 5
  • 1
    Neat idea. I've no idea how to implement it and prefer super-tiny all the time myself, but +1. – Michael Berkowski May 25 '11 at 16:47
  • If your are bored scrolling up and down always in a same file, you can still split the window to watch two different part of the file at the same file. This is very usefull. Also, if you know well the vim shortcuts, you can easily navigate through your source code. You make also take a look at code `folding`. – neodelphi May 25 '11 at 17:03

2 Answers2

20

That's an interesting idea. Not sure if I'd use it :-) — but it's certainly an interesting idea.

You don't need to write a complete plugin, as all it needs to do is to perform some math. More specifically, a rough formula would be:

enter image description here

Where the desired size (S) depends on the current document number of lines (n), a constant determining what is considered a big file (k, in lines), the desired amplitude (a) — meaning how much will the size vary — and a minimum font size (m).

Now that we know that, it's just a matter of implementing it. Quick notes:

  1. To get n we can call the line() function passing "$" as argument
  2. To set the font size, after we have the number we can build a string and execute it with exec

With that in mind, a quick function quite descriptive could be written as:

function! DetermineFontSize()
    let bigFile = 200
    let nLines = line("$")
    let rate = (nLines > bigFile) ? 0 : (1-nLines/(bigFile*1.0))
    exec "set guifont=Menlo:h".float2nr(ceil((rate*5)+11))
endfunction

I'm sure that other Vim masters can improve this a lot. Anyway, a quick explanation:

  1. Set up what we call big file. I've chossen 200 lines for debugging purposes, you probably want a bigger number.
  2. Get the number of lines in the current file.
  3. Do the parenthesis in the previous formula. Note that there is a conditional involved (if you noticed I missed that in the formula, congratulations!). If we have more lines than the maximum constant, 0 is returned. Otherwise, we'd have a negative number — plus calculating something that's obvious.
  4. In the fourth line we build the string to be executed while completing the formula. I choose to hardcode the values for a and m here, since they are used only once and it's easy to modify them. Here a is 5 and m is 11, meaning the font will vary between 11 and 16. The syntax I used here to set the font is valid for Mac. If another reader uses another system you may want to change it accordingly.

Put that in your .vimrc or source it from other file and you'll be ready to test it. On a file with one line, the font is set to 16. If there are 39 lines, also size 16 but size 15 if there are 40. Size goes to 14 when there are 80 lines and so on.

You probably want to call this automatically, so create an auto command as well.

autocmd BufEnter * call DetermineFontSize()

This will work only when you enter a buffer, as the name says. You could change that to include InsertLeave or something like, but keep in mind this will generate more calls to the function. Should not be a performance problem though.

Check :h autocommand-events and build the autocmd as you like.


Update

As ZyX pointed out in the comments, the last line from the function could be written as:

let &guifont='Menlo:h'.float2nr(ceil((rate*5)+11))
sidyll
  • 57,726
  • 14
  • 108
  • 151
  • Why `:exe` and not `let &guifont='Menlo:h'.float2nr(ceil((rate*5)+11))`? – ZyX May 25 '11 at 19:43
  • @ZyX: Why? Hmm, because I didn't have this idea maybe. As I said in the text, I was (and still "am") sure that the masters could improve the function a lot. – sidyll May 26 '11 at 13:54
  • I added this in my .vimrc and get the following each time I enter a new buffer: `Error detected while processing function DetermineFontSize: line 3: E806: using Float as a String E15: Invalid expression: (nLines > bigFile) ? 0 : (1-nLines/(bigFile*1.0)) line 4: E121: Undefined variable: rate E116: Invalid arguments for function ceil((rate*5)+11)) E116: Invalid arguments for function float2nr(ceil((rate*5)+11))` – Henrik Jul 03 '11 at 21:58
  • @hced: Hmm, interesting. I have no idea on where a string could appear (*"using Float as String*). Which version of Vim are you using? – sidyll Jul 03 '11 at 23:35
  • @sidyll: Most recent version of MacVim (with Vim 7.3). My .vimrc is a major mess right now so it might be something in there causing this. Either that or incompatible plugins... I don't expect you to troubleshoot my .vimrc (promise!), but here it is for reference. https://gist.github.com/1069327 – Henrik Jul 07 '11 at 11:33
  • @hced: No, don't say that. It's pretty well commented and so. And I finally found someone else who has mapped space to colon :-) The bad news is: I launched my MacVim using your *.vimrc* and the function works properly. I recommend you to put this in a separate file and source it. Then, start playing with the 3rd line trying to identify which Float is being used as String. Be aware that using this in full-screen brings a bug: when the font size goes down, the window gets smaller and you'll see borders. Please tell me if you could make it work, and sorry that I'm unable to help more directly. – sidyll Jul 07 '11 at 13:22
  • @sidyll: thanks a lot for your helpfulness, alas, I was unable to make it work also after trying to source it from a separate file. Same error message (also after disabling fullscreen). Will let you know if I manage to get it working somehow. – Henrik Jul 07 '11 at 22:26
  • Thanks @hced, I'll be happy to know how the problem was solved. I'd even guess that it's a bug. Maybe, it's related with your locale and float numbers (I'm not american too, but works here). Try removing as much from the function as possible, without removing the error and then post it as a question. Also, check if simple float operations like =2/4.0 in insert-mode are working. – sidyll Jul 08 '11 at 01:38
0

vim executes in a terminal. Font size is terminal dependant, so what you ask may be impossible unless your vim ask directly the terminal to change font size... which may be difficult to do.

neodelphi
  • 2,706
  • 1
  • 15
  • 22
  • I use MacVim, so I didn't realize that. I updated my question to mention that I'm specifically asking about gui vim. – gouch May 25 '11 at 17:07