Menu

#200 Autocompletion cosmetic and performance enhancements

closed
None
5
2005-03-29
2005-03-17
No

Neil et al

I've been doing quite a lot more work on autocompletion
to address some
cosmetic issues, and also the speed of display of large
lists. With the
exception of (1) and (2), these changes affect the
Windows build only,
although I've pushed some code down from
AutoComplete.cxx into the platform
specific ListBoxX implementations in order to speed up
the list population.
Specifically the changes are:

1) I've added SCI_AUTOCSET/GETMAXHEIGHT to allow
one to configure the number
of visible rows. The motivation for this is that the number
of visible rows
is currently hard-coded at 5, which I find a bit cramped.
The default is
still 5 so existing behaviour is maintained.
2) I've added SCI_AUTOCSET/GETMAXWIDTH to allow
one to configure the maximum
"width" of the list, where the width is expressed as a
maximum number of
characters. Of course this is an inaccurate measure
with proportional fonts,
but it is better than nothing. This is to allow one to
prevent Scintilla
showing a a ridiculously wide list, which can happen if
the auto-completion
choices include very lengthy "words". The default
setting is 0, which allows
Scintilla to auto-calcluate the width based on the widest
item as before
(though see below), thus maintaining existing behaviour.

[Regarding the choice of names for the new messages,
I'm not terribly happy
with MAXHEIGHT and MAXWIDTH since these imply
maximum pixel dimensions. I'm
open to other suggestions]

3) The calculation of the width of the widest item is now
based on the space
required to draw the actual text of the widest item,
rather than an estimate
based on the average character width. This is still not
perfect, because the
widest item is selected based on the number of
characters. However it
reduces the problem I was frequently seeing of the text
of items being
truncated.
4) Contributing to the problem of the list being
incorrectly sized (2) was
the hard-coding of extra spacing to allow for the size of
the window frame,
with this having only including a border for the height
and not the width.
I've changed this to use the AdjustWindowRect() API to
correctly account for
the frame, regardless of display settings.
5) Another cosmetic improvement is that ellipsis are
now drawn if an item
has to be truncated, e.g. because it exceeds the new
maximum width.
6) The list is now a "popup" window rather than a child.
This means it is
not clipped to the Scintilla window, which is important
when working in a
small window in a multi-window IDE. It also fixes the
cosmetic issue of the
left edge being clipped when an autocompletion list is
opened after typing a
character or two at the left edge of even a large window.
And believe me,
the activation/focus issues were pretty difficult to deal
with when making
this change :-).
7) The list now has a minimum and maximum tracking
sizes when resized by the
user to prevent it being made too small or larger than
necessary. Also it
disallows resizing that would hide the caret (i.e. if the
list is below the
caret, you can't resize the list by dragging the top edge
up). Unfortunately
the list is still flickers a bit on resize, but it is no worse
than it was
before and if anything slightly better.
8) The list box uses LBS_NOINTEGRALHEIGHT in
order to avoid leaving an
undrawn area when the user resizes the window to an
intermediate size.
9) The auto-completion list was very slow to populate for
large lists such
as one might have in an IDE when the user requests an
autocompletion list
without having typed a prefix when all global types are
syntactically valid.
By way of example I was finding it could take Scintilla in
excess of 1.5
seconds to populate a list with about 33k items in it. Of
course one might
question the usefulness of a list with 30,000 items in it,
but if the user
requests such a list with a shortcut key then they
should get it because it
is very annoying when commands sometimes work and
sometimes not. Anyway I've
managed to cut this time by almost 90% by storing the
item strings
externally rather than in the ListBox control itself and
some other
optimisations. Its still not really quite fast enough, but I
don't think it
can be made much faster using the old ListBox control
which is quite slow to
populate - in fact I found that commenting out the
SendMessage(LB_...) in my
code cut the time down to ~50mS. To address this
properly we need to switch
over to using the newer SysListView32 control because
it supports a
"virtual" mode (LVS_OWNERDATA) where one
populates it by sending it a single
message telling it how many items there are, and it
calls back to get
display information for the visible items. Or alternatively
just implement a
completely custom list - its not that far away already. I
haven't had time
to make this change yet, but to facilitate it (and for other
performance
reasons) I have reorganised the code so that the entire
list is set through
one ListBox class method call rather than the
AutoComplete class appending
all the items individually.

Lastly, a question. Does anyone have an opinion, for the
Windows platform,
on whether or not the image associated with an
autocompletion list entry
should be highlighted along with a selected item?
Currently it is
highlighted, but the native controls do not normally do
this, just
highlighting the text.

I've attached a zip containing the complete source files
that I have
modified.

Regards

Blair McGlashan
http://www.object-arts.com

Discussion

  • Neil Hodgson

    Neil Hodgson - 2005-03-20
    • assigned_to: nobody --> nyamatongwe
     
  • chris

    chris - 2005-03-21

    Logged In: YES
    user_id=1148040

    Looks nice, but i have problems compiling this. :-/

    scintilla\win32>mingw32-make
    g++ -DNDEBUG -W -Wall -pedantic -I ../include -I ../src -Os
    -fno-exceptions -fn
    o-rtti -mno-cygwin -c ScintillaWin.cxx
    g++ -DNDEBUG -W -Wall -pedantic -I ../include -I ../src -Os
    -fno-exceptions -fn
    o-rtti -mno-cygwin -c ../src/ScintillaBase.cxx
    ../src/ScintillaBase.cxx: In member function `void
    ScintillaBase::AutoCompleteSt
    art(int, const char*)':
    ../src/ScintillaBase.cxx:269: error: no matching function
    for call to `AutoCompl
    ete::Show(bool)'
    ../src/AutoComplete.h:60: note: candidates are: void
    AutoComplete::Show()
    ../src/ScintillaBase.cxx: In member function `void
    ScintillaBase::AutoCompleteCo
    mpleted()':
    ../src/ScintillaBase.cxx:324: error: no matching function
    for call to `AutoCompl
    ete::Show(bool)'
    ../src/AutoComplete.h:60: note: candidates are: void
    AutoComplete::Show()
    mingw32-make: *** [ScintillaBase.o] Error 1

    I am using Scintilla 162 and the current version of the
    MinGW Compiler under Windows XP.

     
  • Nobody/Anonymous

    Logged In: NO

    Have you synchronised the latest from CVS? This change
    builds on the previous change (accepted into CVS, but not in
    the original 1.62 release) which added the
    AutoComplete::Show() member function.

     
  • chris

    chris - 2005-03-21

    Logged In: YES
    user_id=1148040

    Thanks for the fast answer.

    Now it works. :)

    AutoCompletion is now much better!

     
  • Blair McGlashan

    Blair McGlashan - 2005-03-23

    Logged In: YES
    user_id=48836

    Second attempt attached, modified as per Neil's comments
    (dependencies on SString.h and Scintilla.h removed, unicode
    string width fixed. Also:
    1) Centres the current nearest match if below mid-point
    2) Does not highlight the image on selection
    3) Paint is double-buffered to avoid flicker on resize/scrolling
    4) Couple of minor resizing issues fixed.

     
  • Blair McGlashan

    Blair McGlashan - 2005-03-23

    2nd version of modified files, replaces original

     
  • chris

    chris - 2005-03-23

    Logged In: YES
    user_id=1148040

    Hi Blair,

    resizing is better now, but now i have problems with
    scrolling. If i scroll down the first time, the list looks
    like this: http://www.future-coding.de/temp/error.png

    And the behavior of the list is bad. If I open the list and
    type something it selects an item, but in most cases it does
    not select an other item after that.

    I want to handle the codecompletion like those in Visual
    Studio, Delphi or those in many other IDE's.

    And it is possible to change the Font seperatly for the
    codecompletion? Would be great. :)

    Bye

     
  • Blair McGlashan

    Blair McGlashan - 2005-03-23

    Logged In: YES
    user_id=48836

    Thanks for your comment:

    Regarding the repaint issue on resizing, I don't experience
    this issue running on Windows Server 2003, but you
    prompted me to try it on Windows 2000, and I was able to
    reproduce it. It appears to be related to whether list box
    smooth scrolling is enabled - turning it on in 2k3 produced
    the same effect. I'll take a look and sort that out.

    Regarding the selection issue, I can find no problem with
    that. Can you elaborate or provide steps to reproduce?

    I'd like the auto-completion list to be at least comparable to
    that in VS.NET (or better, since the list is resizable), which is
    why I am working on it, but I have no current intention to
    make a change to allow the font to be configured separately.
    Please go ahead and make such a change if you want it.

    Regards

    Blair

     
  • Neil Hodgson

    Neil Hodgson - 2005-03-24

    Logged In: YES
    user_id=12579

    I still see some flicker possiblybecause some drawing is
    done outside WM_PAINT upon key events. One way to avoid
    flicker, depending on card/driver is to avoid touching any
    pixel twice by using ExtTextOut to draw both the item
    rectangle and the text in one go.

    rcImage.right = rcBox.left - 1;
    

    Rectangles are semi-inclusive and should be subdivided using
    the same value:
    rcImage.right = rcBox.left;

     
  • Neil Hodgson

    Neil Hodgson - 2005-03-24

    Logged In: YES
    user_id=12579

    Black blobs, similar to ganxta's example, can be caused by
    items that don't have an icon as the icon area is not filled
    then.

     
  • chris

    chris - 2005-03-24

    Logged In: YES
    user_id=1148040

    Hi,

    it's easy to reproduce the selection stuff, just take this
    items for the list:

    abs absolute function test abstest

    So I use this code to start autocompletion (it's Delphi):

    Scintilla.AutoCShow(0, 'abs absolute function test abstest');

    If I start the autocompletion, i cant select the item
    abstest by typing. If i write abs it selects abs (right),
    but if i enter the letter t of abstest it aborts (should
    select abstest). What is wrong?

    And what's about a seperatly font for the codecompletion?

    regards
    Chris

     
  • Blair McGlashan

    Blair McGlashan - 2005-03-24

    Logged In: YES
    user_id=48836

    Responding to Chris (ganxta):

    Re incremental search (selection). Quoting from the docs for
    SCI_AUTOCSHOW "The list of words should be in sorted
    order.". This is because the search is done by a binary chop,
    so it won't find the item if the list is not ordered. This is not
    something I've changed.

    Re font: As I said, not something I have plans to implement
    at present, so you will have to do it yourself if you need it. I
    believe there is a spare predefined style number that could be
    used (Neil?).

    Regards

    Blair

     
  • chris

    chris - 2005-03-24

    Logged In: YES
    user_id=1148040

    Ah, no it works. Thanks. :)

    Maybe I can try to implement the font stuff. Is there a
    style number for this? If not, i will try to implement this.

    regards
    Chris

     
  • Blair McGlashan

    Blair McGlashan - 2005-03-24

    Logged In: YES
    user_id=48836

    Neil, Chris

    Thanks for your feedback.

    I've fixed the redrawing issues associated with smooth
    scrolling and maybe some other cases where
    WM_DRAWITEM is sent outside of WM_PAINT. Turned out
    to be a stupid mistake in erasing the wrong rectangle. I've
    also addressed the one case where I think flickering might
    still be possible (which is when the selection changes and is
    re-centred at the same time). Please let me know of any
    other cases.

    I've attached the single revised file to be used to replace
    PlatWin.cxx in the previous zip.

    Chris: It might be possible to use style number 38 for the list
    text style, which is in the predefined range, but currently
    unused as far as I can tell. Neil would have to confirm that its
    unused and that consuming such as scarce resource as a
    predefined style number would be acceptable, otherwise
    specific SCI_xxx messages could be added to set the font
    characteristics. Depending on Neil's response (and if he
    accepts my autocompletion changes :-)) I might have a go at
    it in thanks for your help with testing. I notice from the
    archives that it is a FAQ.

    Regards

    Blair

     
  • Blair McGlashan

    Blair McGlashan - 2005-03-24
     
  • chris

    chris - 2005-03-24

    Logged In: YES
    user_id=1148040

    Hi,

    The redrawing issues doesn't appear any longer. Good work. :)

    For my own use I choosed Style Number 126 for the
    CodeCompletion (and 125 for CallTips).

    38 seems to be unused, but what should be used for CallTips?

    regards
    Chris

     
  • Neil Hodgson

    Neil Hodgson - 2005-03-25

    Logged In: YES
    user_id=12579

    Lexers already use styles 125 and 126. HTML uses 125 for PHP
    comments and 126 for PHP variables within strings.

    Why do you dislike using the font of the text? For the
    autocompletion list it may be possible to send WM_SETFONT to
    the list as that is what is done internally. I'm going to
    want more justification before allocating one of the few
    available style IDs for this.

     
  • Neil Hodgson

    Neil Hodgson - 2005-03-25

    Logged In: YES
    user_id=12579

    Modification committed with minor changes for warnings and
    layout.

     
  • Blair McGlashan

    Blair McGlashan - 2005-03-27

    Logged In: YES
    user_id=48836

    Neil

    Thanks for accepting the changes.

    Regarding the styles of autocompletion list and calltips, I
    would agree with you that it makes sense for these to use
    the same font as the text, especially the former. Oh the other
    hand using a style allows for control over the colours as well
    though, in a way that is consistent with other styles making
    it easier to manage for config dialogs, etc. Have you thought
    about using style numbers outside the valid range for the
    configuration of styles that cannot be used in the main text
    (e.g. margins, autocompletion, calltips)? These style
    numbers could start from 128 or higher (or be negative), and
    so not impinge on the number of styles available for use by
    lexers.

    Regards

    Blair

     
  • Neil Hodgson

    Neil Hodgson - 2005-03-29
    • status: open --> closed
     
  • Neil Hodgson

    Neil Hodgson - 2005-03-29

    Logged In: YES
    user_id=12579

    A well implemented addition that used ID numbers >= 256
    would be good but it would have to do something about
    minimizing the amount of style realization overhead so that
    this doesn't result in extra slowness.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.