Hello,
I'm having trouble understanding some parts of Vim's source code. The
problem I'm facing is somewhat specific but I think the questions I
have can be generalized to the one in the title.
I'll start giving some context on my problem and end with the general
questions; feel free to take all the time you want to respond, I
understand you are all really busy:
I am trying to implement support for variable-width fonts in gVim; I
know it is an unattractive feature for lots of people, and I'm not
expecting anyone to jump to coding it, I am fine with me putting in
the effort (until I give up, at least). Also, my general questions
bellow still apply without this feature in mind. I am mostly
interested in the "generalized questions"; so for discussion on the
specific feature I can open a new post if you want.
Note: If I can't make myself understood, tell me and I'll try to
explain it differently; my english is far from perfect.
So far I:
- Started by reading main, vim_main2 and main_loop, to see how it
works generally.
- Investigated some call trees (with ctags & grep).
- Somewhat understood gui initialization: gui_start,
gui_mch_init, etc.
- The gui loop: done with g_main_context_iteration while
waiting for a char in ui_inchar and friends.
- gui_outstr_nowrap prints / draws the string (tested
variable width fonts by disabling the "hack" to make it
fixed width when 'font=' is set; and it somewhat worked).
- ...
- Went through all win_line, commenting and folding it by sections.
(I thought I had undestood the relevant parts of it but now I think
I haven't.)
- ...
TL;DR: I have have exhausted my ideas on how to figure this out.
My concrete problems (to give context):
1. I can't figure out how to get the `font=` highlight attribute (or
it's equivalent 'ae_u.gui.font' entry in attrentry_T) inside
win_line. There's wlv.char_attr (that should be available after the
"Decide which of the highlight attributes to use" block). But I
suspect it must be of a different kind than in other places of the
source (like the aep in gui_outstr_nowrap) because when I read it I
get corrupted values for the font pointer.
2. I have discovered and want to use the n_extra, c_extra, mechanism
to do some replacement of some text with spaces. I also can't get it
right, I suspect it's behaviour is dependent on where you put the
code in between the win_line function. But I can't see any obvious
place where I should put it. (Right now I've tried to put it at the
end of the else of the "Get the next character to put on the screen"
if statement.)
Back to the title and the general questions:
I feel like I must be doing something wrong and there is a more
straight forward way to _really_ read a function and understand its
implications without the need of knowing all the other source code (as
an example, it was difficult for me to see that gui_mch_init is
"hidden" inside termcapinit and set_termname). Right now it's as if
any function can change any variable in the global state (and there is
a lot of global state). It's also as if arguments of the function
don't say anything about what the function "recieves" nor what it
"gives back" to the rest of the code.
So:
1. How do you manage to do it?
I've read somewhere that some just specialize in a part of the code
and know it well, so:
2. How do you deal with fixing a bug that spans multiple subsystems?
Also, I'm not just talking about maintaining the project, I'm
fascinated with the idea of someone, not familiar with the code, and
adding a new somewhat complex feature they need (e.g. concealing is
pretty complex), without having to backtrack all Vim's history and
read everything to understand a small part.
3. So how did you tackle reading the source for the first time?
4. And after being involved for some time, do you have any
suggestions you would have liked to have known in the
beginning?
Thanks to anyone reading this and to anyone that answers, I hope it's
not too boring.
---
Finally, this text is already getting pretty long but I'll try to
explain how I'm thinking of implementing the feature, and justify
myself for thinking it shouldn't be too complicated.
I think the really important part of my email are the general
questions, so you can safely ignore this if you are not really
interested.
If someone ends up interested in this I can open a new discussion if I
figure out how to do some more work on it.
- Add an "attribute" 'vwfont' to the highlight attribute 'gui=' that
enables the feature with the 'font=' set. (For the prototype I was
just trying to enable this always that 'font=' is set.)
- Obviously this feature only makes sense in the gui version, like
the 'font=' attribute.
- Detect the attribute in win_line for a block of text and:
- Activate a feature-specific code that:
- Calculates the width of the resulting occupied string (with
pango, etc.)
- Caches the width values for ascii letters at least (maybe
store it "inside" the font, have the font be represented by
GuiFont and this cache.)
- If it doesn't fit in the screen, do something to make wrap
work (keep in mind that more characters fit than cells in a
row).
- The string itself is stored in the buffer/window, there's no
problem of it not being in ScreenLines.
- Store some kind of global structure array (per row) for
identifying this "variable width block". (Could contain an
x_offsets array calculated later).
- Replace the text (in ScreenLines) with the minimum number of
spaces it would need to fit the width calculated earlier. Using
the n_char, c_char mechanism. Also adding a marker with a
special highlight attribute to signal the drawer later.
- Later, when outputting the string, maybe in gui_outstr_nowrap,
activate some code when the marker is detected, refer to the
allocated array with structure information and draw it. Saving in
the process the x_offsets (pixel horizontal position offset) so
that we can later draw just one character (and the cursor).
- For drawing the cursor detect we are on a "special block" and
completely give control to some feature specific code.
Other ideas I can explain if someone is interested:
- Also taking into account font height. Text bigger than a "fixed
size" row.
- How it would combine monospace and variable width text in a line.
- There's lots of things that lose usefulness for variable width
fonts (like visual block selection), but that doesn't mean the
feature is bad.
- The curor moving up or down (j & k).
- cursorcol, etc.
Thanks, again, for reading this.
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups "vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion visit
https://groups.google.com/d/msgid/vim_dev/defa3fc1-4a2b-4f85-b660-1896bacc11d4%40montoro.cat.