Platform-wide Spell Checking
Pretty much every software development environment provides a platform-native way of doing spell checking. Gnome does not. This should change.
The current situation is that almost every Gnome app that provides serious text entry capabilities has some form of spell checking -- for example GEdit, Epiphany/Web (via WebKitGtk), Empathy, Evolution, etc etc. We should consolidate these into a single library that is easy to use and available to everyone.
Various attempts have been made to do such a thing before, so we have SexySpellEntry (a GtkEntry subclass adding spell checking), and GtkSpell, a non-official library adding spell checking (with underlining etc) to GtkTextViews.
Bug #383706 from 2006 makes a similar proposal. However, at the time it was what not clear at what level the API should live; now that GIO exists between GObject and GTK, it's clear that it's a good position in the stack for a spell checking API to live, with hooks in GTK to use it for GtkEntry, GtkTextView and anywhere else it's needed.
The goal of this page is not (at this stage) to come up with a concrete API, but rather decide a high-level design that would satisfy all the goals.
What do other platforms offer?
Windows 8: Spell Checking API
Mac OS X: NSSpellChecker
Android: Spell Checker Framework
- Do we want to provide a system-wide spell-checking service (and wrapper library), or just a library?
- Do we want a standalone library ('libgspell'?), or should the API live in GIO, or in GTK?
- What backend(s) should it support?
- Should it provide autocorrection as well?
How do we provide the infrastructure for the user-visible spell checking goals outlined at Whiteboards/SpellChecking?
- Should the API be word or string focused? (Windows handles this, Hunspell does not)
Let's tackle these one at a time
Do we want a D-Bus Service?
It would be possible to provide an org.freedesktop.SpellChecker service, which would run on the session bus. We could provide a client-side interface in GIO (using GDBus on Linux, or native interfaces on Mac OS and Windows). Android and Mac OS use a system service like this.
- One spell checker to rule them all
- Inherently asynchronous
- Global settings (for example, user-added dictionary words) are instantly available in all apps
- Mac OS and Windows could use their platform-default spellcheckers
- With service activation, apps which don't need spell checking pay no penalty
- Security considerations -- any process can monitor session bus traffic. Not so much of a problem at the moment because X is pretty insecure anyway, but worth thinking about future sandboxing.
- Text would need to be split into appropriately-sized chunks to avoid excessive round-tripping in the one extreme, or excessive copying in the other. Not sure how Android and OS X get around this.
- Would need the API to be agreed by all interested parties
- Yet another D-Bus service?
Standalone, GIO or GTK
We would need to decide whether this becomes part of the ever-expanding GIO, part of GTK, or a standalone library of its own.
- One less library to link
- GIO seems to be the right location for useful non-GUI GObject code these days (GMenu, GIcon etc).
- One less library to link
Existing text handling API already lives here (GtkTextIter, etc)
- (Most?) likely API consumers will be using GTK anyway
- Pango already contains a wealth of APIs for dealing with non-Latin text (word breaking etc), which may prove to be useful -- GTK depends on Pango, but GIO does not.
- Apps which don't need spell checking don't have to carry whatever overhead might come with this system
Which backend(s) to support
Clearly, writing our own spell checking engine is not a goal. There are many engines already out there, but it seems these days the choice boils down to
Hunspell, used by LibreOffice, Firefox, Mac OS 10.6+, Android and others
Enchant, an abstraction API which can use almost any spell checking engine. Used by KDE (Sonnet), AbiWord, WebKitGtk, GtkSpell and many others. Also recommended by the GNU ASpell authors these days. However, it may be unmaintained -- the last release was in April 2010, 3.5 years ago at the time of writing.
Our own abstraction, say GSpellingProvider. Could use Enchant or Hunspell (or o.fd.SpellChecker via D-Bus) on Linux, and native backends on Windows and Mac OS
The easiest option would simply be to provide a GObject wrapper around libenchant, or take the Enchant code and "gobject-ify" it. However, Gnome is moving in the general direction of removing abstraction layers (see the endless iBus discussions), so perhaps hunspell is worth thinking about, particularly as it seems to be the default used by Enchant on all modern distros anyway.
Text boxes in Mac OS optionally provide autocorrection, so "teh" is instantly replaced by "the", for example. Perhaps infamously, so does iOS. The Windows 8 and Android spell checking APIs also return hints to suggest when autocorrection should take place (CORRECTIVE_ACTION_REPLACE and RESULT_ATTR_LOOKS_LIKE_TYPO respectively). We would need to decide whether this is something we'd like to offer as well.
Implementation wise, neither Hunspell nor Enchant offer this functionality, so it would require a separate dictionary. LibreOffice uses 'databases' (actually zipped up XML files) in /usr/share/autocorr to define autocorrections -- we could look into reusing these.
Making the UI designs possible
Well, there isn't all that much in the way of UI design yet, only some general goals. Clearly it would be desirable to have a consistent way to replace misspelt words -- perhaps by supplying a GMenu[Model] with suggestions, which could be displayed in a right-click context menu. We also need to think about what modifications GTK would need -- for example, do we just want a GtkEntry::check-spelling boolean property, or is more fine-grained control necessary?
For automatic spell checking (misspelled words underlined in red, with a right-click context menu), the API can be as simple as adding a boolean proporty in GTK+. But for implementing a dialog window, finer-grained control is needed. The dialog window can navigate through all the misspelled words, there are buttons to ignore, apply to all, add the word to the dictionary, etc.
As an UI example, the gedit spell plugin has both features: automatic spell checking, and a dialog window.