Project-specific dictionaries - possible solution

I really would like project-specific dictionaries. I understand that you’re just hooking into the OSX spell-checker, but I think I have a solution.

I noticed that when I right-click on a misspelled word and select “Ignore Spelling” that the underline goes away. Further, it will then offer up that word as a possible choice when it encounters a similar word. It’s pretty much everything I want, except it doesn’t persist. But that’s where Scrivener comes in.

Could there be a special document which is just a list of words, and when the project is opened up the words in the list are programmatically added to that session’s ignored words via the standard API? I realize that there are two major potential limitations: if two projects are opened at once, they may need to share the ignored spellings list; it’s probably not possible to hook into the API so that when a new word is ignored via the right-click menu, it’s automatically added to the list.

Some people may not want to maintain this separate list and that’s fine; they’ll be no worse off than they are now. But for those of us who do…maybe there’s hope.

It’s certainly a creative idea (and very much like the workarounds I have to come up with for various features every day), so I appreciate the thought behind it. Unfortunately, you’ve noted one of the main problems with it. The spell-checker is global to the application (that’s the main problem here - there is no way to associate a different spell-checker with each project), which means that the lists of words for all open projects would be loaded. This would seem like buggy behaviour to many users, so it would open up extra support demands. (I suppose it could try to tell the spell-checker to learn a word when a project is activated and unlearn the word when it is deactivated, come to think of it, but it would be a very fragile approach.)

All the best,
Keith

Instead of using “Ignore” try using “Learn”. Ignore is a session based exclusion, and more useful for things that you know are incorrect in general but happens to be contextually correct, but you don’t want to it to be in your global dictionary.

When you use the “Learn” function, it will do exactly what you are describing in the first part. The word will be written into a simple text file, and this file is used by all applications on the system to dynamically exclude certain words from the spell check engine. Since this is just a normal text file (located in your ~/Library/Spelling folder) that you can edit by hand, that means you could swap these files out when working on a particular project, or even manage them by hand, merging and cutting entries between various files that you keep elsewhere until needed.

The main problem with any kind of management of this from within Scrivener is that Scrivener really has no authority to be doing that since this list is used for everything from your Safari search bar tool to Mail to Scrivener, and as such there aren’t any programming interfaces that we can use to manage it with more precision. It sure would have been nice if they designed it that way from the start, though, as it would resolve the main drawback to the otherwise very nice global spell check capability of the Mac.

Now, as for us doing anything custom on top of that in memory, I don’t think that would be possible either—like a word list in your project meta-data that is applied to the system level dynamically when the project is loaded—I just don’t think that is technically possible, since the extent of the spell check code in Scrivener is essentially just asking the Mac to turn it on or off and pass through all of its management functions to the contextual menus and Edit menu.

I’ve pondered this very problem, and done some haphazard research on it. There are two paths that are hypothetically possible, but I’m too busy/lazy to learn how to create a proof of concept.

The first is to have a setting for each project to either use the system-wide spell-checking language files, or for Scrivener to create a link to the language file currently in use, but name it for the project. Then the custom dictionaries created for that language file would be separate (maybe?) from the original. the tricky part would be to have Scrivener switch languages for you every time the focus left that project’s windows, and then switch back to that custom language when it regained focus.

Sounds like a nightmare of fragile state switches that could expose bugs in the spelling code that would never normally have a chance to surface.

The other way would be to do something with aspell/ispell for mac os. That would generate complaints, as there seem to be a lot of words that are missing from aspell’s lists.

Sounds like a huge headache. I think we’re just going to have to storm Cupertino HQ and occupy the OS X developer offices.

IANACP (I am not a Cocoa programmer) but it seems like it may be possible to differentiate word lists by project:

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/SpellCheck/Tasks/CheckingTextSpelling.html#//apple_ref/doc/uid/20000721-98120-CJBFIHIG

See the section under “Matching a List of Ignored Words with the Document It Belongs To”. It talks about associating an ignored words list to an arbitrary ID. When the project is closed you can query for the ignored words list specific to this ID and save them. When the project is re-opened you could restore the ignored words list (I would guess you would get a new ID and use that; I doubt you’d save the ID across sessions). So there’s no intermediate state that needs saving by Scrivener, just the start and end.

How this interfaces with Scrivener’s micro-saving every few seconds is a different question. And you’d probably want a global preference to see if the user wants a global ignored-words list or a per-project list. But they don’t seem like overly-difficult things to figure out.

All of the above said with the IANACP caveat.

I was wondering if there had been any progress on finding a workable solution for this issue? I’m a new Scrivener user and I see there’s been a fair amount of chatter on the forums about having project-specific dictionaries, but I don’t see any kind of definitive solution.