[PATCH] contrib: introduce spell.py for checking comments, output and documentation

Mads Kiilerich mads at kiilerich.com
Tue Aug 28 18:33:03 CDT 2012


# HG changeset patch
# User Mads Kiilerich <mads at kiilerich.com>
# Date 1344893419 -7200
# Node ID 5077cd9311331a9e1231d509d1d291cff2369529
# Parent  573e80049cad31e140f9365e079c3bb233c66d86
contrib: introduce spell.py for checking comments, output and documentation

spell.py extracts code, strings and comments from the source using a huge
regexp inspired by check-code. It is assumed that all words appearing in the
actual code by definition is spelled correctly. By automatically whitelisting
these words we avoid spell checking internal names not known to any dictionary.

Strings that looks like they contain constants - such as command or
configuration names or meta programming - are also automatically whitelisted
instead of checked. That helps validating that the references are spelled 100%
correctly.

Other strings and comments are sanitized a bit, and everything that looks like
words are checked.

Normal words that don't appear in the source are listed in whitelist files.
That avoids runtime dependencies to using a specific kind and version spell
checker and dictionary. Spell checkers can however be used when reviewing the
whitelists.

Different categories of words have been placed in different whitelists to make
it easier to review.


This method of spell checking has found a lot of minor problems. It has mostly
been trivial spelling errors. In some places it has pointed out 'real' problems
in docstrings and comments. This method might improve the code 'quality' a bit,
but it will obviously not find the more important grammatical or semantic errors.

It is not obvious whether it is worth the effort to maintain this.

diff --git a/contrib/spell/constants.white b/contrib/spell/constants.white
new file mode 100644
--- /dev/null
+++ b/contrib/spell/constants.white
@@ -0,0 +1,36 @@
+HH
+HHHHHH
+HHiH
+YY
+Ynesfdaq
+Z0
+Za
+abcdefghijklmnopqrstuvwxyz
+almr
+almrx
+b_
+becho
+breduce
+brepo
+btest
+bui
+cfi
+cfn
+ic
+ilmsux
+kIi
+lmar
+rnt
+sd
+selse
+u'None
+uDC00
+uDCFF
+uDxxx
+xr
+yn
+ynmpcq
+z0
+zA
+za
+zc
diff --git a/contrib/spell/en-aspell.white b/contrib/spell/en-aspell.white
new file mode 100644
--- /dev/null
+++ b/contrib/spell/en-aspell.white
@@ -0,0 +1,3167 @@
+ARISING
+AUX
+AV
+Abstraction
+Activating
+Adapt
+Additionally
+Advantages
+Ah
+Alexander
+Alternately
+Apps
+Arrange
+Asian
+Asks
+Assigns
+Attic
+Aug
+Authentic
+Automated
+BAT
+BSD
+BUSINESS
+Bails
+Bell
+Beware
+Boston
+Bryan
+CERTIFICATE
+CONSEQUENTIAL
+CONTRACT
+COW
+CPU
+Caveat
+Chinese
+Choosing
+Christian
+Cleaned
+Cluster
+Collapsed
+Concept
+Construction
+Contributor
+Cook
+Creek
+DAMAGE
+DAMAGES
+DAYS
+DISCLAIMED
+DOS
+Daniel
+Debian
+Decompose
+EXEMPLARY
+EXPRESS
+East
+Ebert
+Emacs
+English
+Eric
+Europeans
+Examines
+FITNESS
+Fifth
+Fingerprints
+Floor
+Fog
+Fortunately
+Foundation
+Franklin
+Fred
+Furthermore
+Google
+Gregory
+HOLDERS
+HOST
+I'll
+I'm
+I've
+INCIDENTAL
+INDIRECT
+INTERRUPTION
+Illustrated
+Incorporate
+Inform
+Inserts
+Inspiration
+Interaction
+Invalidates
+Japanese
+Jeff
+Jonathon
+Josef
+LAN
+LIABILITY
+LIABLE
+LOVE
+Labs
+Lastly
+Leaking
+Legend
+License
+Likewise
+Listens
+Loosely
+Ltd
+Luckily
+MAR
+MIPS
+Martin
+Matt
+Medical
+Michael
+Mon
+Monkey
+Movement
+NEGLIGENCE
+Nicolas
+Nope
+Notes
+Notifies
+Noun
+Nth
+Omitting
+Organization
+POSSIBILITY
+PROCUREMENT
+PROFITS
+Paisley
+Par
+Parenthesis
+Participating
+Patrick
+Perforce
+PhD
+Placing
+Pluralized
+Portability
+Positional
+Positioning
+Prefixing
+Principles
+Protect
+RAM
+Redistribution
+Registering
+Rendezvous
+Reroute
+Restarting
+Ryan
+SHALL
+Scanners
+Shun
+Sigh
+Spend
+Stallion
+Steven
+Street
+Strips
+Substitutes
+Suppose
+TORT
+Technologies
+Ticks
+Tue
+USA
+Unity
+Verb
+Volume
+WAN
+WARRANTIES
+Ward
+Wed
+Widget
+Wine
+Worse
+Writers
+You'll
+ZOE
+Zoe
+abandon
+abandoned
+abbreviated
+abbreviation
+abbreviations
+abilities
+ability
+able
+aborted
+aborting
+aborts
+about
+above
+absolute
+abstract
+abstracts
+accelerate
+acceleration
+accented
+acceptable
+accepted
+accepting
+accepts
+accessed
+accesses
+accessible
+accessing
+accident
+accidentally
+accommodate
+accompanying
+according
+accordingly
+account
+accumulates
+accuracy
+accurate
+achieve
+achieves
+acquired
+across
+activate
+activated
+activates
+actively
+activity
+acts
+actually
+adapted
+adding
+addition
+additions
+addressed
+addresses
+adequate
+adjacent
+adjuncts
+adjust
+adjusted
+advanced
+advantage
+advertise
+advertises
+advised
+advisory
+affect
+affected
+affecting
+affects
+afterwards
+again
+against
+agent
+agnostic
+ago
+agree
+agreed
+ahead
+aiming
+aka
+algorithm
+algorithms
+aliased
+align
+alike
+alive
+allocate
+allowing
+allows
+almost
+alone
+along
+alongside
+alpha
+alphabet
+alphabetical
+alphabetically
+alphanumeric
+already
+alright
+also
+alter
+altered
+alternate
+alternative
+alternatively
+although
+ambiguous
+ambiguously
+amended
+amending
+among
+amp
+analogous
+analysis
+analyze
+analyzing
+ancestral
+ancestry
+anchored
+ancient
+angle
+annotated
+annotates
+annotation
+annotations
+announce
+announced
+another
+answered
+answering
+anybody
+anymore
+anyone
+anything
+anyway
+anywhere
+apart
+apparently
+appear
+appearance
+appeared
+appearing
+appears
+appended
+appending
+appends
+apple
+applicable
+applications
+applies
+applying
+approach
+appropriate
+appropriately
+approve
+approximate
+approximately
+arbitrarily
+arbitrary
+arch
+archiving
+are
+area
+aren't
+argument
+around
+arrive
+arrived
+arrives
+arriving
+ascending
+asked
+asking
+aspects
+assign
+assigned
+assigning
+assignment
+associate
+associated
+assume
+assumed
+assumes
+assuming
+assumption
+asterisk
+asynchronous
+atom
+atomic
+atomically
+attachments
+attacks
+attempt
+attempted
+attempting
+attempts
+attribute
+attributes
+audience
+audio
+augment
+augmented
+authenticate
+authenticated
+authenticating
+authentication
+authoritative
+authorization
+authorized
+automatic
+automatically
+availability
+available
+average
+avg
+avoid
+avoidance
+avoided
+avoids
+aware
+awareness
+away
+awful
+backed
+background
+backing
+backs
+backslash
+backslashes
+backward
+backwards
+badly
+bail
+baked
+balance
+band
+bandwidth
+banned
+bare
+bars
+based
+basic
+basis
+bat
+batched
+batches
+batching
+baton
+bazaar
+be
+beats
+because
+become
+becomes
+been
+begins
+behalf
+behave
+behaves
+behaving
+behavior
+behaviors
+behaviour
+behaviours
+behind
+being
+believe
+belong
+belonging
+belongs
+below
+beneath
+benefit
+besides
+best
+bet
+beta
+better
+biased
+big
+bigger
+biggest
+binding
+bisection
+blacklist
+blacklisting
+blanket
+blind
+blocked
+blocking
+blow
+blown
+blows
+bogus
+bookmarked
+boost
+born
+borrow
+borrowed
+both
+bother
+bounce
+bound
+boundary
+box
+braces
+brackets
+brain
+branching
+bread
+breadth
+breakout
+breaks
+brevity
+brief
+brighter
+bring
+bringing
+broader
+broken
+brought
+browse
+browsing
+buffers
+buggy
+build
+building
+builds
+built
+bullets
+bunch
+bundles
+bundling
+busted
+but
+by
+byte
+caches
+calculate
+calculated
+calculating
+calculation
+callable
+called
+caller
+callers
+calling
+came
+can
+can't
+canceled
+cannot
+canonical
+capability
+capitalize
+capture
+captured
+carbon
+care
+careful
+carefully
+carriage
+carried
+carry
+case
+cases
+catalog
+catch
+caught
+cause
+caused
+causes
+causing
+cave
+cease
+ceased
+ceases
+cell
+central
+centralized
+certain
+certificates
+chained
+chance
+changing
+characteristics
+characters
+charge
+chars
+chatter
+cheap
+cheaper
+cheats
+checker
+checking
+checkouts
+checks
+cherry
+chomp
+chopped
+chose
+chosen
+chucks
+circuit
+circular
+circumstances
+claim
+clash
+clashes
+clashing
+classes
+classic
+classical
+classified
+clause
+cleaning
+cleanly
+cleared
+clearly
+clients
+clobber
+clobbering
+clocks
+clones
+cloning
+closer
+closes
+closing
+closure
+cob
+codes
+coding
+coherent
+collaborate
+collapses
+collapsing
+collected
+collecting
+collection
+collide
+collides
+collision
+collisions
+colons
+colorizing
+com
+comb
+combination
+combinations
+combine
+combined
+combines
+combining
+come
+comes
+coming
+comma
+commas
+commented
+committed
+committing
+commonly
+communicated
+communicating
+communications
+compact
+comparable
+compared
+compares
+comparing
+compatibility
+compatible
+competing
+compiled
+compiler
+compilers
+complain
+complaining
+completed
+completely
+completeness
+completes
+completion
+complex
+compliant
+component
+compressible
+comprise
+computation
+compute
+computed
+computer
+computes
+computing
+concatenated
+concatenating
+concatenation
+concept
+concern
+concerned
+concise
+concurrent
+conditional
+conditions
+configurable
+configuration
+configurations
+configure
+configured
+configures
+configuring
+confined
+confirmation
+conflicted
+conflicting
+conform
+confuse
+confused
+confusing
+confusion
+conjunction
+connected
+connecting
+connections
+consequently
+conservative
+consider
+considerable
+consideration
+considered
+consist
+consistency
+consistent
+consistently
+consisting
+consists
+console
+consoles
+constant
+constants
+constitute
+constraint
+constraints
+construct
+constructed
+constructing
+constructor
+constructs
+consulted
+consulting
+consume
+consumers
+consumes
+consuming
+contain
+contained
+containers
+containing
+contexts
+continuation
+continuations
+continues
+continuing
+continuous
+contribute
+contributed
+contributors
+control
+controlled
+controlling
+controls
+convenience
+convenient
+convention
+conventional
+conventions
+converse
+conversely
+conversion
+conversions
+converting
+converts
+convoluted
+cooperating
+cope
+copying
+copyright
+correct
+corrected
+correction
+corrections
+correctly
+correctness
+correspond
+correspondence
+corresponding
+corresponds
+corrupt
+corrupted
+corruption
+cost
+costly
+could
+couldn't
+counted
+counter
+counters
+counting
+counts
+couple
+course
+courtesy
+cover
+covering
+crafting
+crashed
+crashes
+crashing
+crazy
+creates
+creating
+creations
+creator
+credential
+credentials
+crew
+critical
+cross
+crosschecking
+crossed
+crosses
+cube
+culprit
+cumulative
+curly
+currently
+custom
+customize
+customized
+cycle
+cycles
+cycling
+daily
+damage
+damaged
+dance
+dangerous
+dangling
+darn
+dash
+database
+deactivate
+deactivated
+deadlock
+deal
+dealing
+deals
+dealt
+debugging
+decide
+decided
+deciding
+decision
+declaration
+declarations
+declare
+declared
+declines
+decoded
+decoders
+decodes
+decoding
+decorated
+decrease
+decreased
+decreases
+decreasing
+decremented
+dedicated
+deduce
+deep
+deeper
+defaulting
+defend
+defer
+deferring
+deficiencies
+define
+defined
+defines
+defining
+definite
+definitely
+definitions
+deflate
+delayed
+delaying
+delegate
+delegated
+deletes
+deleting
+deletion
+deletions
+delimited
+delimiter
+delimiters
+deltas
+demand
+demonstration
+denied
+denies
+denote
+denotes
+denoting
+depend
+dependant
+dependents
+depending
+depends
+depot
+deprecated
+deprecates
+deprecation
+derivatives
+derive
+derived
+descended
+descends
+describe
+described
+describes
+describing
+descriptions
+descriptive
+descriptor
+descriptors
+deserves
+design
+designers
+desirable
+desired
+despite
+destinations
+destroy
+destroying
+destroys
+destruction
+detached
+detaches
+detailed
+detailing
+details
+detect
+detecting
+detection
+detects
+determination
+determine
+determined
+determines
+determining
+deterministic
+develop
+developers
+development
+device
+devices
+dictionaries
+dictionary
+did
+didn't
+die
+diffed
+differ
+differences
+different
+differentiate
+differently
+differing
+differs
+difficult
+diffing
+digit
+digraph
+direct
+directed
+direction
+directions
+directive
+directives
+directly
+disables
+disabling
+disagree
+disallowed
+disambiguate
+disappeared
+disappears
+discarding
+disclaimer
+disconnected
+discouraged
+discover
+discovered
+discovering
+discovers
+discussion
+disjoint
+disk
+disown
+dispatching
+displayed
+displaying
+displays
+disposed
+disregarding
+distances
+distant
+distinct
+distinguish
+distribute
+distributed
+distribution
+distributions
+ditch
+ditto
+divergence
+divergent
+dives
+divide
+divider
+dividing
+do
+document
+documentation
+documented
+does
+doesn't
+doing
+don't
+dot
+dotted
+double
+doubled
+doubling
+down
+downgrade
+downhill
+download
+downloaded
+downloading
+downloads
+downstream
+draw
+drawback
+drawn
+drift
+drive
+driver
+dropped
+drops
+dry
+due
+duped
+duplex
+duplicate
+duplicated
+duplicates
+duration
+during
+dynamic
+each
+earlier
+earliest
+ease
+easier
+easiest
+easily
+east
+easy
+eating
+eats
+echo
+ed
+editing
+editors
+edits
+effective
+effectively
+efficiency
+efficient
+efficiently
+effort
+eggs
+eight
+either
+element
+eligible
+eliminated
+elsewhere
+emails
+embedded
+emit
+emits
+emitted
+emptied
+emulate
+emulation
+emulator
+enables
+enabling
+encapsulate
+enclosed
+encoded
+encodes
+encounter
+encountered
+encounters
+ended
+ending
+endings
+endorse
+endpoint
+ends
+enforce
+enforced
+enhanced
+enhancement
+enhances
+enhancing
+enough
+ensure
+ensured
+ensures
+ensuring
+enter
+entered
+entering
+entire
+entirely
+entities
+entity
+entropy
+enumerating
+envelope
+environments
+epsilon
+equality
+equals
+equivalent
+equivalents
+erroneously
+es
+escapes
+escaping
+especially
+essentially
+establish
+established
+establishing
+estimated
+eta
+evaluate
+evaluated
+evaluates
+evaluation
+even
+eventually
+ever
+every
+everybody
+everyone
+everything
+everywhere
+evidence
+evil
+exactly
+examine
+examined
+examining
+example
+examples
+exceeded
+exceeds
+excess
+exchange
+exchanged
+exchanging
+excl
+exclamation
+excludes
+excluding
+exclusion
+executed
+executes
+executing
+execution
+exhibits
+exist
+existed
+existence
+existent
+exited
+exiting
+expanded
+expands
+expansion
+expansions
+expectation
+expecting
+expects
+expense
+expensive
+experimental
+experimentally
+expire
+explained
+explains
+explicit
+explicitly
+explode
+explore
+exported
+exporting
+expose
+exposed
+exposing
+expressed
+expression
+expressions
+extending
+extensive
+externalized
+externally
+extracting
+extracts
+extremely
+face
+facilitate
+facility
+facing
+fact
+factors
+failing
+fails
+failure
+failures
+fairly
+fake
+faked
+fall
+falling
+falls
+fancy
+far
+fashion
+faster
+fastest
+fatal
+fate
+faulty
+features
+feeds
+fetched
+fetching
+few
+fewer
+figure
+figuring
+filled
+filling
+filtered
+filtering
+finalized
+finding
+finds
+fine
+finishes
+finishing
+fire
+fired
+fit
+fits
+fixed
+fixer
+fixers
+fixes
+flat
+flexibility
+flip
+flipped
+floating
+flushed
+flushing
+fly
+folder
+folds
+folks
+followed
+following
+follows
+fonts
+forbid
+forbidden
+forcefully
+forces
+forcibly
+forcing
+foreign
+forest
+forever
+forgetting
+formatting
+formed
+former
+formerly
+forms
+forth
+forward
+forwards
+fourth
+fragile
+fragments
+framework
+free
+freely
+frequency
+frequently
+fresh
+friendlier
+friendly
+friends
+front
+fully
+fun
+functional
+functionality
+functions
+further
+furthest
+fuzzed
+gain
+gaining
+gains
+gamma
+gap
+garbage
+gather
+gathered
+gathering
+gave
+general
+generally
+generate
+generated
+generates
+generating
+gets
+getting
+ghost
+giant
+give
+given
+gives
+giving
+globally
+globs
+go
+goes
+going
+gonna
+goofy
+got
+grab
+grabber
+gracefully
+grafted
+grafting
+grafts
+grain
+grant
+granted
+grants
+granularity
+graphical
+graphs
+gratuitous
+greater
+greatest
+grouped
+grouping
+grow
+gt
+guarantee
+guaranteed
+guarantees
+guessed
+hack
+hacks
+had
+hairy
+half
+ham
+hamming
+hand
+handled
+handles
+handling
+hands
+handy
+happen
+happened
+happening
+happens
+happy
+hard
+harder
+harm
+harmful
+hashing
+hasn't
+hate
+have
+haven't
+having
+heap
+heave
+helper
+helpers
+helpful
+helpfully
+helps
+hence
+here
+herein
+heuristic
+hexadecimal
+hides
+hiding
+hierarchy
+high
+higher
+highest
+highlighting
+highly
+histogram
+historical
+history
+hit
+hitting
+hobbit
+hold
+holding
+holds
+honor
+honoured
+hooking
+hope
+horizontal
+hostile
+hot
+hotshot
+hovered
+how
+however
+huge
+human
+hybrid
+hyperlinks
+ickier
+idea
+ideally
+identical
+identifiable
+identification
+identified
+identifier
+identifiers
+identifies
+identifying
+idle
+ignores
+ignoring
+ill
+illegal
+image
+images
+immediate
+immediately
+impact
+implausible
+implement
+implementation
+implementations
+implemented
+implementing
+implements
+implicit
+implicitly
+implied
+implies
+imply
+importer
+importing
+imports
+impose
+impossible
+improve
+improved
+improvement
+improvements
+improves
+inadequate
+inadvertent
+inbound
+incl
+included
+includes
+including
+inclusion
+inclusive
+incompatible
+incomplete
+inconsistencies
+inconsistency
+inconsistent
+incorporated
+incorporating
+incorrect
+incorrectly
+increase
+increased
+increases
+increasing
+increment
+incremental
+incrementally
+incur
+indentation
+indented
+indention
+independent
+independently
+indeterminate
+indexes
+indicate
+indicated
+indicates
+indicating
+indication
+indirectly
+individual
+individually
+induce
+ineffective
+infer
+infinite
+influencing
+informally
+information
+informational
+informative
+informed
+inherently
+inherit
+inheritance
+inherited
+initialization
+initialized
+initializing
+initially
+injection
+inner
+input
+inputs
+insanity
+insecurely
+insensitive
+insensitivity
+inserted
+inserting
+insertion
+insertions
+inside
+inspired
+install
+installation
+installations
+installed
+installing
+installs
+instant
+instantiate
+instantiated
+instantiating
+instead
+instruction
+instrumenting
+insufficient
+integer
+integers
+integrally
+integrating
+integration
+integrity
+intelligent
+intended
+intending
+intent
+intentionally
+inter
+interactively
+interested
+interface
+interfaces
+interim
+intermediate
+internally
+internationalization
+internet
+interpolating
+interpretation
+interpreted
+interpreting
+interprets
+interrogate
+interrupt
+interrupted
+interruptions
+intersection
+intersections
+interval
+intervening
+interwoven
+into
+introduce
+introduced
+introduces
+introduction
+introductory
+invalidated
+invalidating
+invalidation
+invent
+invocation
+invocations
+invoke
+invoked
+involved
+involves
+irreversibly
+isn't
+isolated
+isolation
+issue
+issued
+issues
+it
+it'll
+iterating
+iteration
+iterations
+iterative
+iterators
+its
+itself
+jack
+job
+juggle
+jump
+jumping
+junction
+just
+keeping
+keeps
+kernel
+kernels
+keyed
+killed
+kinds
+kludge
+know
+knowing
+knows
+labeling
+labelled
+lack
+lacks
+ladder
+laid
+lake
+language
+larger
+late
+later
+latter
+launching
+layer
+layering
+layout
+layouts
+lazily
+lazy
+lead
+leading
+leads
+leaf
+least
+leave
+leaving
+led
+leftover
+legacy
+legal
+less
+lesser
+let
+lets
+letter
+letters
+letting
+levels
+lexicographic
+lib
+liberal
+libraries
+library
+licensing
+lie
+life
+lifetime
+lifted
+light
+lightweight
+like
+likely
+liking
+limitations
+limited
+limiting
+linear
+linked
+linking
+links
+listed
+listening
+listing
+lists
+literals
+little
+loaded
+loading
+localization
+localized
+locally
+locked
+locking
+logged
+logic
+logically
+logo
+logos
+logs
+lone
+longer
+longest
+look
+looked
+looking
+looks
+loop
+loops
+lose
+loses
+losing
+loss
+lost
+lot
+lots
+low
+lowercase
+lowered
+lowest
+luck
+machine
+made
+magically
+magnitude
+mailbox
+mailer
+mailing
+mails
+main
+maintain
+maintaining
+major
+majority
+make
+makes
+making
+malformed
+manage
+managed
+management
+manager
+manages
+managing
+mandatory
+mangle
+mangled
+manifests
+manipulated
+manipulating
+manipulation
+manner
+manual
+manually
+many
+mappings
+maps
+marked
+marking
+markup
+masked
+materials
+matter
+matters
+mature
+maximum
+may
+maybe
+me
+mean
+meaning
+meaningful
+means
+meant
+measure
+measured
+measures
+mechanics
+mechanism
+mechanisms
+medium
+meet
+megabytes
+meld
+member
+members
+memory
+mentioned
+mentioning
+menu
+merely
+merger
+merging
+messes
+messing
+met
+microseconds
+middle
+midnight
+might
+migrate
+milliseconds
+mime
+mimic
+mimics
+minimal
+minimize
+minimized
+minimum
+misbehaves
+misinterpreting
+misleads
+mismanaged
+mismatch
+mismatched
+missed
+mistake
+mistakenly
+mistakes
+misty
+mix
+mixed
+modeling
+modelled
+modes
+modification
+modifications
+modifying
+monitoring
+most
+mostly
+mount
+mountains
+movable
+moved
+moving
+much
+multiple
+must
+mutt
+mutual
+mutually
+my
+naive
+naked
+namely
+naming
+narrowed
+narrowing
+nasty
+natural
+nature
+navigable
+nearly
+necessarily
+necessary
+needing
+needn't
+negating
+negative
+neither
+nesting
+net
+network
+neuter
+newer
+newest
+newly
+news
+nicely
+nick
+nil
+nobody
+noise
+noisy
+nominal
+non
+nonexistent
+nonsensical
+nonstandard
+nor
+normalized
+normally
+nos
+notably
+notation
+notations
+noted
+notes
+noticeable
+notices
+notification
+notifications
+notified
+notion
+nth
+nuisance
+numeric
+ob
+obey
+objects
+observes
+obsoleted
+obstructed
+obtain
+obtained
+obtaining
+obtains
+obviously
+occasional
+occasionally
+occur
+occurred
+occurs
+octet
+octopus
+odd
+oddball
+odds
+offer
+offering
+offsets
+often
+older
+oldest
+omit
+omitted
+once
+ones
+ongoing
+only
+onto
+opened
+opening
+opens
+operate
+operating
+operation
+operations
+operator
+operators
+opposed
+optimistically
+optimization
+optimized
+optimizes
+optimizing
+optional
+optionally
+orange
+ordered
+ordering
+org
+oriented
+original
+originally
+originals
+originate
+orphan
+otherwise
+our
+ours
+ourselves
+outbound
+outer
+outermost
+outputs
+outrank
+outside
+outstanding
+over
+overall
+overflow
+overhead
+overlap
+overlapping
+overlaps
+overridden
+override
+overriding
+overview
+overwrites
+overwriting
+overwritten
+own
+owned
+owning
+package
+packaged
+packager
+packages
+packaging
+packets
+padded
+page
+paged
+pages
+paginate
+panics
+parameter
+parameters
+parented
+parenthesized
+parses
+parsing
+partially
+particular
+partly
+party
+passed
+passes
+passing
+passive
+passwords
+past
+patched
+patching
+patient
+peers
+people
+per
+percentage
+perform
+performance
+performances
+performed
+performing
+performs
+period
+periods
+permanent
+permanently
+permission
+permitted
+persist
+persistent
+persistently
+pertaining
+picked
+picking
+pickup
+piece
+pink
+pipes
+piping
+pixels
+place
+placed
+placeholder
+placeholders
+places
+plan
+platforms
+play
+please
+plugin
+plumb
+point
+pointed
+pointer
+pointers
+pointing
+points
+polling
+poor
+popping
+pops
+populated
+populating
+portability
+portion
+portions
+ports
+positive
+possibilities
+possible
+possibly
+potential
+potentially
+potentials
+power
+powerful
+practical
+practice
+precede
+preceded
+precedence
+precedes
+preceding
+precise
+precisely
+precision
+predecessor
+predefined
+predicate
+predicates
+prefer
+preferable
+preference
+preferred
+prefers
+prefixed
+prefixing
+premature
+prepared
+preparing
+presence
+presented
+preserve
+preserved
+preserves
+preserving
+presumably
+pretend
+prevent
+preventing
+prevents
+previewed
+previewing
+previous
+previously
+primarily
+prime
+printable
+printing
+prints
+prior
+prioritized
+private
+probabilistic
+probability
+probably
+problem
+problematic
+proceed
+processes
+processing
+produce
+produced
+produces
+product
+products
+profiles
+programs
+prohibited
+projects
+promote
+prompted
+prompting
+prompts
+prop
+propagate
+propagates
+proper
+properly
+proportional
+proposed
+protection
+provide
+provided
+provides
+providing
+provision
+provisions
+provoke
+prunes
+pruning
+pseudo
+published
+pukes
+pulled
+pulling
+punt
+pure
+purposes
+pushed
+pushes
+pushing
+putting
+python
+quadratic
+qualified
+querying
+queued
+quick
+quicker
+quickly
+quilt
+quit
+quot
+quotation
+quotes
+quoting
+race
+raced
+racy
+raised
+raises
+raising
+randomly
+ranges
+rank
+rare
+rarely
+rather
+ratio
+reach
+reached
+reaches
+reaching
+readability
+readily
+reading
+reads
+really
+reaped
+reaping
+reapplying
+rearrange
+reasonable
+reasonably
+reasons
+reboot
+rebuilding
+rebuilt
+receive
+received
+receives
+receiving
+recent
+recently
+recipient
+reclaim
+reclaimed
+recognition
+recognize
+recognized
+recognizes
+recommended
+recommends
+recompute
+recomputed
+recomputing
+reconcile
+reconnecting
+reconsider
+reconstruct
+recorded
+recording
+records
+recovered
+recovery
+recreate
+recreated
+recreates
+recreating
+recursion
+recursively
+redefine
+redefined
+redefines
+redirected
+redirection
+redirects
+redistribute
+redo
+redundantly
+refer
+reference
+referenced
+references
+referencing
+referred
+refers
+refill
+refined
+reflect
+reflected
+reflects
+refreshed
+refreshes
+refuse
+refused
+refuses
+regarded
+regardless
+regenerating
+regexps
+regions
+registers
+registration
+registry
+regression
+regular
+reinserts
+reinstate
+reintroduced
+reject
+relatedness
+relates
+relating
+relation
+relationship
+relationships
+relatively
+relatives
+releases
+releasing
+relevant
+reliable
+reliably
+relies
+reloading
+reloads
+rely
+relying
+remains
+remapping
+remember
+remotely
+remotes
+remount
+removal
+removals
+removing
+rendered
+renumbered
+reopen
+reopening
+reordering
+reorganization
+reorganize
+repeatable
+repeated
+repeatedly
+replacements
+replaces
+replacing
+replayed
+replies
+reply
+reported
+reporting
+reports
+repositories
+represent
+representation
+representations
+represented
+representing
+represents
+reproduce
+reproducible
+reproducing
+requested
+requesting
+requests
+require
+required
+requirement
+requiring
+rereading
+rereads
+reserved
+reserves
+resets
+reside
+residing
+resolves
+resolving
+resort
+resources
+respect
+respective
+respectively
+responded
+responding
+responds
+responsibility
+responsible
+restored
+restores
+restoring
+restriction
+restrictions
+restricts
+resulted
+resulting
+resumed
+resuming
+retain
+retained
+retains
+retract
+retrieval
+retrieve
+retrieves
+retrieving
+retry
+retrying
+returned
+returning
+returns
+reuse
+reused
+reuses
+reusing
+reversible
+reverted
+reverting
+reverts
+review
+reviewing
+revise
+rewind
+rewrites
+rewriting
+rewritten
+rights
+ring
+ripped
+risking
+rm
+roll
+rollbacks
+rolled
+rolling
+roman
+room
+rooted
+rounding
+routines
+rude
+rule
+runs
+safely
+safety
+said
+sake
+sampling
+sandbox
+sanity
+satisfied
+satisfies
+satisfy
+saved
+saves
+saving
+saw
+say
+says
+scanned
+scanning
+schedule
+schedules
+scheduling
+schema
+scopes
+scratch
+screw
+script
+scripting
+scripts
+searched
+searches
+searching
+sec
+secrete
+secure
+security
+see
+seeded
+seeing
+seem
+seems
+sees
+segment
+selected
+selecting
+selection
+selects
+semantic
+semantically
+semantics
+sending
+sends
+sense
+sensible
+sensitive
+sensitivity
+sent
+separate
+separated
+separately
+separators
+sequence
+sequences
+sequential
+sequentially
+serialization
+serialize
+serious
+served
+servers
+servicing
+serving
+session
+sessions
+settings
+several
+sh
+shallow
+shamelessly
+shape
+shares
+sharing
+shells
+shim
+shipped
+shipping
+shortcut
+shortened
+shorthand
+should
+shouldn't
+showing
+shown
+shows
+shrinkage
+shrinking
+shuffle
+shuffling
+shut
+sides
+signaling
+signature
+signatures
+signed
+significant
+signing
+silence
+silent
+silently
+silly
+similarly
+simpler
+simplified
+simplifies
+simplify
+simply
+simulate
+simulator
+simultaneous
+simultaneously
+since
+singleton
+sit
+site
+sites
+situation
+situations
+sizes
+skeleton
+skipping
+slashes
+slicing
+slightly
+slot
+slots
+slow
+slower
+slowly
+smaller
+smarter
+snapshots
+sniffed
+sniffing
+sockets
+software
+solution
+some
+somebody
+someone
+something
+sometimes
+somewhat
+somewhere
+sooner
+sorting
+sorts
+spacing
+spam
+spanning
+spans
+spawned
+spawns
+speaking
+specific
+specifically
+specification
+specifications
+specificity
+specified
+specifier
+specifies
+specify
+specifying
+speedup
+spelling
+spent
+spit
+splice
+spliced
+splitting
+sprinkled
+squeeze
+squid
+stable
+stack
+stacks
+stage
+staged
+stale
+stand
+standalone
+standard
+stands
+started
+starting
+stash
+statement
+stating
+statistical
+statistics
+statuses
+stay
+stayed
+stays
+steps
+sticky
+still
+stock
+stolen
+stomp
+stopgap
+stopped
+stopping
+storage
+stored
+stores
+storing
+straight
+strange
+strategy
+stray
+streamed
+streaming
+streams
+strength
+strictly
+strings
+stripe
+stripped
+stripping
+strongly
+structure
+structured
+structures
+stub
+stupid
+stupidly
+styled
+styling
+subclass
+subdivision
+submitted
+subscriber
+subsequent
+subsequently
+subsets
+substituted
+substituting
+substitution
+substitutions
+subsystem
+subtle
+subtly
+subverted
+succeed
+succeeded
+succeeds
+successful
+successfully
+successive
+successively
+successor
+such
+suddenly
+suffice
+sufficient
+sufficiently
+suffixed
+suffixes
+suggest
+suggests
+suitable
+suitably
+suite
+summaries
+summarize
+summarizing
+summing
+sums
+superfluous
+superseded
+supersedes
+supplied
+supply
+support
+supporting
+supports
+suppose
+supposed
+suppress
+suppressed
+suppresses
+suppressing
+sure
+surprise
+surprising
+surrogate
+surround
+survived
+susceptible
+suspect
+swap
+swarms
+switch
+switched
+switching
+symbolic
+symmetrical
+sync
+synced
+synchronization
+synchronize
+synchronizing
+syncing
+synonym
+synonyms
+synthesize
+synthesized
+systems
+tables
+tabs
+tagging
+tailor
+take
+taken
+takes
+taking
+talk
+talking
+tarball
+tasks
+technically
+techniques
+telling
+tells
+temporarily
+temporary
+tend
+tends
+terminal
+terminals
+terminate
+termination
+terminator
+terminology
+terms
+testable
+testing
+texts
+textual
+than
+thanks
+that
+the
+their
+theirs
+them
+themselves
+theory
+there
+thereby
+therefore
+thereof
+these
+theta
+they
+they're
+things
+think
+thinking
+third
+this
+thoroughly
+those
+though
+thought
+threads
+through
+throughout
+thus
+tick
+timed
+timing
+tiny
+toasted
+today
+tokens
+told
+tolerate
+tolerated
+too
+took
+topmost
+topological
+topologically
+topology
+toss
+totally
+touch
+touching
+towards
+trace
+tracing
+track
+tracked
+tracker
+tracks
+trade
+traditional
+trail
+trailer
+trailers
+trailing
+traits
+transfer
+transferred
+transferring
+transfers
+transform
+transformations
+transformed
+transforming
+transforms
+transient
+transitive
+translate
+translated
+translates
+translations
+translator
+transmits
+transparently
+transplanting
+transported
+transports
+trap
+traversal
+traverse
+traverses
+traversing
+treat
+treated
+treating
+treats
+trees
+trick
+tricky
+tried
+trigger
+triggered
+triggers
+trim
+trip
+triple
+tripped
+trips
+trivial
+trivially
+trouble
+troublesome
+trumps
+truncating
+truncation
+trusting
+trying
+turn
+turned
+turning
+turns
+tweak
+tweaked
+twice
+typically
+typo
+uglier
+ugly
+unable
+unacceptable
+unaccounted
+unambiguous
+unauthenticated
+unavailable
+unbounded
+unbroken
+uncaught
+unclean
+unclear
+uncommitted
+uncommon
+undefined
+under
+underlined
+underlying
+understand
+understands
+understood
+undesirable
+undocumented
+undoes
+undone
+unexpected
+unexpectedly
+unfiltered
+unfinished
+unfortunately
+unharmed
+unhooking
+unification
+unify
+uninteresting
+uniquely
+units
+unknowns
+unless
+unlike
+unlikely
+unlimited
+unloaded
+unmatched
+unmodified
+unmounted
+unnamed
+unnecessarily
+unnecessary
+unneeded
+unobtainable
+unpacked
+unpacking
+unpublished
+unquoted
+unreadable
+unrecognized
+unregistered
+unrelated
+unseen
+unsigned
+unspecified
+unsuccessful
+unsuitable
+unsupported
+until
+untouched
+untranslated
+unused
+unusual
+unwanted
+unwrapped
+unzip
+updates
+updating
+upfront
+upgraded
+upload
+uploading
+upon
+uppercase
+upset
+upstream
+usable
+usage
+use
+useful
+useless
+uses
+usual
+usually
+utilities
+utility
+validated
+validating
+validation
+valued
+vanished
+vanishing
+var
+variable
+variables
+variants
+variations
+variety
+various
+vector
+vectors
+vendor
+verification
+verifying
+vertical
+very
+via
+vice
+viewer
+viewing
+violates
+violation
+visibility
+visible
+visiting
+visual
+visualize
+visualized
+void
+volumes
+waiting
+waits
+walking
+walks
+wall
+wants
+warranty
+was
+wasn't
+waste
+wasted
+wastes
+watch
+watched
+watches
+watching
+way
+ways
+we
+we'd
+we'll
+we're
+we've
+weak
+website
+weird
+well
+went
+were
+weren't
+west
+western
+whatever
+whenever
+whereas
+whether
+which
+whichever
+who
+whole
+whom
+whose
+widespread
+wild
+will
+win
+windowed
+wire
+wish
+with
+within
+without
+won
+won't
+workaround
+worked
+worker
+works
+worms
+worry
+worth
+worthwhile
+would
+wrapped
+wrappers
+wrapping
+wraps
+wrinkle
+writer
+writes
+writing
+written
+wrong
+xx
+xxx
+yet
+yielding
+yields
+you
+you're
+your
+yourself
+zebra
+zero
+zeta
+zombie
+zone
diff --git a/contrib/spell/en-other.white b/contrib/spell/en-other.white
new file mode 100644
--- /dev/null
+++ b/contrib/spell/en-other.white
@@ -0,0 +1,222 @@
+AIX
+API
+Booleans
+DAGs
+DER
+DVCS
+ECMA
+Exim
+FastCGI
+Interactiveness
+Interruptible
+LANs
+LGPL
+LaTeX
+MERCHANTABILITY
+MTA
+Machintosh
+Mbps
+Microsoft
+NB
+NTFS
+PEM
+Pythons
+RFC
+RGB
+SCM
+SCMs
+SQL
+SQLite
+Samba
+Satisfiable
+TCP
+Tcl
+Tk
+TortoiseHg
+UDP
+URIs
+VCS
+VFAT
+accessor
+acyclic
+autogenerated
+backport
+backported
+backporting
+backports
+bitmask
+blecch
+boldify
+boolean
+bugfix
+builtin
+canonicalization
+canonicalize
+cd
+centric
+cheapish
+checksum
+checksums
+chmods
+clueful
+codec
+codepath
+compat
+computable
+conformant
+contrib
+copyfrom
+coroutine
+criss
+dereference
+dereferencing
+destructors
+diffable
+encodings
+eof
+everytime
+evolutions
+fastpath
+favicon
+fifo
+filesize
+filesystem
+filesystems
+foldable
+fsck
+gnupg
+graphviz
+gunzip
+hardlinked
+hardlinking
+hardlinks
+hashable
+hashvalue
+headerless
+highlevel
+hoc
+href
+iff
+indices
+initialisation
+instantiation
+integrations
+invalidations
+invariants
+iso
+joinable
+journaling
+jpg
+jython
+kb
+latin
+linearization
+linearizing
+linkable
+logins
+lookups
+lossless
+lossy
+malformated
+monkeypatch
+monkeypatches
+mozilla
+multi
+multipart
+nasties
+natively
+nfs
+nonnegative
+nonoverlapping
+normalisation
+obfuscated
+onwards
+pack'ed
+perl
+pragma
+prepend
+prepended
+prepends
+profilers
+proxied
+proxying
+quo
+radix
+reachability
+readonly
+rebases
+rebasing
+recognised
+recompress
+reconciliate
+recursing
+redirections
+reencoding
+reimplements
+reinstall
+relinkable
+relinking
+rescan
+rescanning
+restartable
+resynchronize
+roundtrip
+roundtripped
+runtime
+runtimes
+schemas
+serialisation
+startup
+stylesheet
+subclassed
+subclasses
+subclassing
+subdirectories
+subdirectory
+submittable
+submodule
+submodules
+suboptimal
+subproject
+subsecond
+substring
+subtract
+subtree
+superset
+symlinked
+symlinks
+templated
+themself
+timeslot
+timezones
+tracebacks
+transactional
+transcoding
+truncations
+tuples
+unbare
+unbuffered
+unbundled
+uncompress
+unconflicted
+undeleting
+unencoded
+unescape
+unexpand
+unexpanded
+unfinalized
+unhandled
+unicast
+uniquified
+unix
+unlinked
+unlinking
+unmanaged
+unsatisfiable
+uptodate
+usernames
+vanishingly
+versa
+vertices
+webserver
+xhtml
diff --git a/contrib/spell/examples.white b/contrib/spell/examples.white
new file mode 100644
--- /dev/null
+++ b/contrib/spell/examples.white
@@ -0,0 +1,123 @@
+B1
+B2
+CHANGESETHASH
+CMFPlone
+DONT
+Doe
+FF0000
+Firstname
+FooSoftware
+HtmlMerge
+John
+Joseph
+MYBRANCH
+MYBRANCH2
+NODE1
+NODE2
+OUTFILESPEC
+PATCH1
+PATCH2
+Plone
+PloneTestCase
+ProgramFiles
+REPOCLONE
+REVs
+Rfoo
+TEMPLATEMAP
+XX
+XXs
+XYZZY
+XdYYh
+XhYYm
+XmYYs
+XwYYd
+XyYYw
+_a
+_x
+a21ccf
+address1
+address2
+alice
+au
+autobuild
+b56ce7b07c52de7d5fd79fb89701ea538af65746
+bcc1
+bcc2
+betty
+bla
+bob
+brian
+c561b4e977df
+cc1
+cc2
+cdiff
+cnn
+crt
+d6
+d8d2fcd0e319
+de
+diff3
+diffargs
+doc_writer
+ea
+ee
+elc
+end_foos
+f8
+ff58a7ffb771907c4ff68995eada1c4da068d328
+file3
+file4
+filter1
+filter2
+fnameescape
+foodir
+gdiff
+gollum
+gvim
+gvimdiff
+hgignore2
+hookname
+iis
+intevation
+jul
+last_foo
+lst
+mnt
+modulename
+myHtmlTool
+myfeature
+myimgmerge
+mylocalnetwork
+myproxy
+myrepo
+new_branch_name
+newrepo
+no_foos
+oldrepo
+original_branch_name
+plugh
+pn
+prosciutto
+pyc
+quux
+r'C
+rN
+range_handler
+recipient1
+recipient2
+release_engineer
+rev3
+rev4
+rfc
+sbin
+serrano
+stable5
+start_foos
+symlink_here
+tmprepos
+user6
+vcproj
+vimdiff
+vimrc
+x80
+xff
diff --git a/contrib/spell/hg.white b/contrib/spell/hg.white
new file mode 100644
--- /dev/null
+++ b/contrib/spell/hg.white
@@ -0,0 +1,657 @@
+ACL
+ACLs
+ACTION
+ADDR
+ADVISED
+AFS
+ALWAYS
+AND
+ANSI
+ANSI_X3
+ANY
+APIs
+ARE
+ARG_MAX
+AS
+ASCII
+AUTH
+AbstractDigestAuthHandler
+AbstractHTTPHandler
+BASE
+BE
+BEGIN
+BOM
+BOOKMARK
+BOTH
+BRANCH
+BRANCHNAME
+BUNDLE
+BUT
+BY
+BYTE
+BasicAuth
+CA
+CAUSED
+CGI
+CIA
+CMD
+COM
+COMMAND
+COMPLETELY
+CONFIG
+CONTRIBUTORS
+COPYRIGHT
+CPython
+CRLs
+CRs
+CTRL
+CURRENT_USER
+CoreGraphics
+CreateFile
+DAG
+DATA
+DATE
+DEAD
+DEST
+DESTINATION
+DETAILS
+DIFFER
+DIFFERENT
+DIR
+DIRECT
+DO
+DOES
+DWORD
+DirDiff
+DirDiffDynamicDiffText
+EISDIR
+ENCODE
+END
+EOF
+ERROR
+EVEN
+EVENT
+EXACTLY
+EXCEPTION
+EXE
+FILE
+FILENAME
+FILESPEC
+FIXME
+FOR
+FORMAT
+FS
+FTP
+FUNCTIONS
+GIT
+GNU
+GNUPG
+GOODS
+GPLv2
+GUARD
+GUI
+HASH
+HFS
+HFSX
+HG_ERROR
+HG_KEY
+HG_LOCAL
+HG_NAMESPACE
+HG_NEW
+HG_OLD
+HG_OPTS
+HG_PARENT1
+HG_PARENT2
+HG_PATS
+HG_RESULT
+HG_SOURCE
+HG_TAG
+HG_VALUES
+HG_foo
+HOWEVER
+HTML
+HTTP
+HgArg
+HgHttp2
+IC
+ID
+IDN
+IF
+IIS
+IMPLIED
+IN
+INCLUDING
+INDEX
+INDEXFILE
+IO
+IP
+IPv4
+IS
+ISAPI
+ISO
+ISO8601
+InterWiki
+IsapiModule
+JRendezvous
+JSON
+KEY
+LIMIT
+LIMITED
+LNAME
+LOCAL_MACHINE
+LOGNAME
+LONG_PTR
+LOSS
+LPARAM
+MA
+MBCS
+MIME
+MODE
+MQ
+MUST
+Mbinary
+MiB
+NAME
+NAMESPACE
+NEW
+NFS
+NG
+NNN
+NO
+NOP
+NOT
+NOTE
+NT
+NUL
+NUM
+O
+OBSOLETED
+OF
+OK
+OLD
+ON
+ONE
+OPT
+OPTION
+OPTIONS
+OR
+ORIGIN
+OS
+OTHER
+OTHERWISE
+OUT
+OWNER
+P4
+PARENT
+PARTICULAR
+PATCH
+PATTERN
+PID
+PORT
+POSIX
+PREFIX
+PROPFIND
+PROPNAME
+PROVIDED
+PURPOSE
+PWD
+PYTHONPATH
+PatchSet
+PyWin32
+Py_ssize_t
+Pythonic
+QUEUE
+RANGE
+RCFILE
+RCS
+RD
+READONLY
+REMOVED
+REPL
+REPLACEMENT
+REPO
+REPOS
+REQUEST
+REST
+RETR
+REV
+REV1
+REV2
+REVMAP
+REVRANGE
+RFC822
+RPC
+RST
+Redistributions
+Resources_
+RevlogNG
+SA
+SEEK_END
+SERVICES
+SGR
+SHA
+SIMILARITY
+SOFTWARE
+SOURCE
+SPECIAL
+SSH
+STARTREV
+STATUS
+STRICT
+STYLE
+SUBSTITUTE
+SUCH
+SVN
+SZ
+Scalable
+SetFileAttributes
+Solaris
+StrangeBerry
+Subrepositories
+T
+TAG
+TEMPLATE
+TEST
+TESTDIR
+TESTTMP
+TEXT
+THE
+THEN
+THEORY
+THIS
+TIME
+TLS
+TO
+TODO
+TOOL
+TOPIC
+TOUCH
+TTL
+TWO
+TXT
+TYPE
+UI
+UINT_PTR
+UNC
+UNIX
+UNKNOWN
+URI
+URL
+URL1
+URL2
+URLS
+USE
+USER
+USERNAME
+UTF
+UUID
+VALUE
+W
+WARNING
+WARRANTY
+WAY
+WHETHER
+WILL
+WITHOUT
+WPARAM
+WSGI
+XHTML
+XML
+XMLRPC
+XXX
+Y2K
+YOU
+_all_
+_and_
+_dns
+_hg
+_hgignore
+_hgrc
+_http
+_protocol_
+_services
+_sort
+_tcp
+_this_
+_udp
+a_lines
+alias1
+alias2
+allowbz2
+allowgz
+allowzip
+apos
+argh
+asctime
+atime
+b85
+b_lines
+backlinks
+backref
+backrefs
+base_lines
+ber
+bichued
+big5
+big5hkscs
+bmp
+bookmarkname
+branchcache
+branchhead
+branchheadcache
+branchmapsummary
+brightblue
+bug_when
+bugs_activity
+buildmember
+bytestring
+bytestrings
+cachetip
+callables
+camelcase
+casefolding
+changecontext
+changectxs
+changelists
+changelogs
+changerev
+checkin
+chunkgroup
+chunkgroups
+context_lines
+converter_sources
+coreutils
+cp932
+cp950
+crosslinks
+csbig5
+css
+csshiftjis
+currenttip
+cvs2svn
+cvsimport
+cvsnt
+cvspurge
+cygdrive
+d1b16a746db6
+dat
+debugcmdserver
+deltastart
+demandimporters
+demandload
+demandloading
+depotFile
+descendent
+dicts
+dll
+docstring
+docstrings
+doctests
+dotted_as_names
+dotted_name
+duckpunch
+easy_install
+egrep
+email_in
+encbatch
+errormessage
+et
+exceptionlist
+extchanges
+facebook
+fcgi
+fielddefs
+fieldid
+filecontext
+filectxs
+fileextension
+filelogs
+filepath
+filespec
+filtersmarker
+first_byte
+firsthunk
+fix_import
+fixutf8
+flushmarkers
+formail
+fs
+gendoc
+getdefaultencoding
+getlogrevs
+getrecursionlimit
+gincoming
+gitchanges
+gitpatch
+gittishsh
+gnu_getopt
+has_function
+header_lines
+headrev
+hg_archival
+hgchurn
+hgeol
+hgext_
+hggettext
+hghook
+hgicon
+hglf
+hgrcs
+hgrename
+hgsep
+hgsh
+hgsigs
+hgsub
+hgsubstate
+hgsubversion
+hgtags
+hgwebdir_wsgi
+hgwebs
+hkscs
+hostinfo
+htmlonly
+httpplus
+httprepository
+hunk_lines
+ick
+idxs
+import_name
+incomingchangesetlist
+ing
+internaltoolsmarker
+isdisjoint
+issue1088
+issue1320
+issue1364
+issue1802
+issue1922
+issue1964
+issue1974
+issue2062
+issue2543
+issue2915
+issue3225
+issue3254
+issue3507
+issue3533
+issue3543
+issue4617
+issue5853
+issue833
+kanji
+kdiff3
+keepalives
+keylist
+keywordsmarker
+kwarg
+kwstatus
+labelname
+last_byte
+latin1
+legacypeer
+levelname
+libsvn_subr
+linebreak
+linecontent
+list_of_tuples
+localstring
+login_name
+longdesc
+longdescs
+looooong
+lowerencoded
+lt
+mDNSResponder
+macosx
+mailto
+makefile
+manifestnodes
+matchers
+md5sum
+memmove
+mergeable
+mergefrombranch
+mergetobranch
+metacharacters
+metadatadict
+metadatasize
+missinghead
+mod_python
+mod_wsgi
+ms932
+ms950
+mskanji
+msx
+ndetails
+nencoding
+ness
+next_col
+ng
+nlst
+ntransfercmd
+objectname
+ossep
+outheads
+outroots
+package_name
+parentnode
+patchbombs
+patchset
+pathalias
+pathnames
+perf
+pipefds
+po
+precomputed
+predicatesmarker
+prescan
+printf
+processmail
+proxyauthinfo
+pushkeys
+pvecs
+py2exe
+py3k
+py3kcompat
+pyOpenSSL
+pydoc
+pyflakes
+pypy
+qrefresh'ing
+r'c
+r'class
+r'in
+r70772
+randomdata
+reStructuredText
+refactored
+refname
+regexes
+remerge
+remoterepo
+restatting
+revlogng
+revlogs
+revlogv2
+rpc
+s_jis
+s_jisx0213
+scp
+script_name
+sed
+sendbugmail
+sendcharset
+setup3k
+setuptools
+sha1s
+shift_jis
+shift_jis_2004
+shift_jisx0213
+shiftjis
+shiftjis2004
+shiftjisx0213
+sink_rev_id
+sjis
+sjis2004
+sjis_2004
+sjisx0213
+sort_
+source_rev_id
+source_synopsis
+sshrepo
+sshrepository
+stdlib
+structformat
+subrepositories
+subrepository
+subscriptionsfile
+sudo
+svn_uri__char_validity
+svnsync
+tag_parent_revision
+tag_revision
+targetsize
+td
+technote
+th
+thetext
+tipmost
+tmplrewrite
+tty
+tzoff
+uncomment
+underbars
+ungraftable
+unmerged
+unparsed
+unpruned
+unpublishing
+unrebased
+unregistration
+unrooted
+unschedules
+unstored
+unsyncedheads
+unterminated
+untracked
+urandom
+urlencoded
+urlgrabber
+usr
+utf
+v0
+v10
+vc
+wdir
+webdir
+whitelist
+whitelisting
+whitelists
+wildcard
+win32comext
+winerror
+wirerepo
+workingctxs
+www
+xo
+xterm
diff --git a/contrib/spell/names.white b/contrib/spell/names.white
new file mode 100644
--- /dev/null
+++ b/contrib/spell/names.white
@@ -0,0 +1,95 @@
+Adam
+Aleix
+Alexis
+Allouche
+Arendsen
+Arrenbrecht
+Augie
+Barisione
+Benoit
+Boissinot
+Brendan
+Calderone
+Carvalho
+Chris
+Christen
+Conchillo
+Cully
+Cunha
+Dahlin
+Dirkjan
+Dumazet
+Edward
+Fackler
+Fahnoe
+Flaque
+Foldager
+Frank
+Geisler
+Gelfer
+GmbH
+Greg
+Hague
+Hein
+Hideya
+Holth
+Hopper
+Hupp
+Intelerad
+Intevation
+Itamar
+Jake
+Jelmer
+Jim
+Joel
+Johan
+Jorgensen
+Jp
+Kevin
+Kingswood
+Kubica
+Kuchlingi
+Lee
+Logilab
+Mackall
+Marco
+Marek
+Mason
+Mezard
+Mikkel
+O'Sullivan
+OHASHI
+Ochtman
+Parra
+Peter
+Pierre
+Renato
+Rosdahl
+Shtull
+Sipek
+Solovyov
+Soria
+Stefano
+Stenner
+Sune
+Thananchayan
+Thomas
+Tomayko
+Tortarolo
+Trauring
+Vadim
+Vernooij
+Yves
+allouche
+david
+durin42
+gmail
+ichi
+mbp
+mstenner
+murphy
+paul
+scott
+stefan
+stefano
+tortarolo
diff --git a/contrib/spell/spell.py b/contrib/spell/spell.py
new file mode 100755
--- /dev/null
+++ b/contrib/spell/spell.py
@@ -0,0 +1,167 @@
+#!/usr/bin/env python
+
+import sys
+import re
+import optparse
+import glob
+
+repython = re.compile(r"""(?msx)
+    (?P<comment>\#.*?$)
+    |
+    ((?P<_>\b_\()?
+     (?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!")))
+     (?P<string>(([^\\]|\\.)*?))
+     (?P=quote)
+     (?P<split>\.split\(\))?)
+    |
+    (?P<codeword>\b\w+\b)
+    """)
+
+# match everything but words - leaving words when used for split
+reword = re.compile(r"\b[_a-zA-Z][_a-zA-Z0-9']*\b")
+
+# match on string with exactly one word
+rewords = re.compile(r'^\^?\w+([|.]\w+)*$')
+
+# match '.fileextension' and '>structformat'
+reextensionformat = re.compile('^[.>]\w+$')
+
+# match stuff to ignore everywhere
+reignore = re.compile(r'''(?x)
+  (\b(http|https|ssh)://[-a-zA-Z0-9 at .:/_?%{}#]+) # URLs
+  |
+  (\b[-a-zA-Z0-9._]+@[-a-zA-Z0-9]+(\.[-a-zA-Z0-9]+)+\b) # email addresses
+  |
+  (\<[-a-zA-Z0-9._]+\ at\ [-a-zA-Z0-9]+(\.[-a-zA-Z0-9]+)+\>) # obfuscated
+  ''')
+
+# match stuff to ignore in strings
+restringignore = re.compile(r'''(?x)
+  (\\([rnt\\]|x\w\w)) # backslash escapes
+  |
+  ((^|\W)-[a-zA-Z]+) # match -optns
+  |
+  (%[0-9 .]*[sd%]) # match %s and %d
+  ''')
+
+# match doctests
+redoctest = re.compile(r'(?m)^( *)>>>.*\n(\1[^>].*\n)*')
+
+# match (x)xxx
+rparent1st = re.compile(r'\((.)\)(\w+)')
+def fparen1st(mo):
+    return mo.group(1) + mo.group(2)
+
+def addwords(wordset, string):
+    '''find words in string and add them to wordset'''
+    wordset.update(reword.findall(string))
+
+def pymatch(mo, whitewords, textwords):
+    # whitelist strings appearing in code
+    codeword = mo.group('codeword')
+    if codeword:
+        addwords(whitewords, codeword)
+    # words in python strings should be checked
+    string = mo.group('string')
+    if string:
+        if rewords.match(string) and not mo.group('_') or mo.group('split'):
+            # whitelist words in strings that are used as code
+            addwords(whitewords, string)
+        elif reextensionformat.match(string):
+            # ignore strings that doesn't look like text
+            pass
+        else:
+            # ignore doctests
+            string = redoctest.sub('', string)
+            # fix '(x)' markup for option chosen by letter x
+            string = rparent1st.sub(fparen1st, string)
+            # fix '&' markup of default choice in prompts
+            string = string.replace('&', '')
+            # hide stuff that should be ignored
+            string = reignore.sub(' ', string)
+            string = restringignore.sub(' ', string)
+            addwords(textwords, string)
+    # check comments
+    comment = mo.group('comment')
+    if comment:
+        # hide stuff that should be ignored
+        comment = reignore.sub(' ', comment)
+        addwords(textwords, comment)
+
+def spellcheck(fns, whitelistdir='.', update=False, debug=False):
+    textwords = set()
+    whitewords = set('')
+
+    # read whitelists
+    for fn in glob.glob(whitelistdir + '/*.white'):
+        if debug:
+            print >> sys.stderr, 'reading', fn
+        words = set(l.strip() for l in file(fn))
+        for w in sorted(set.intersection(words, whitewords)):
+            print >> sys.stderr, 'duplicate whitelisting of', w
+        whitewords.update(words)
+
+    # parse all files
+    for fn in fns:
+        try:
+            s = file(fn).read()
+        except IOError, e:
+            print >> sys.stderr, e
+            continue
+        if fn.endswith('.py'):
+            repython.sub(lambda mo: pymatch(mo, whitewords, textwords), s)
+        elif fn.endswith('.txt'):
+            # hide stuff that should be ignored
+            s = reignore.sub(' ', s)
+            addwords(textwords, s)
+
+    # strip all 's from textwords
+    textwords = set(w.endswith("'s") and w[:-2] or w for w in textwords)
+
+    if debug:
+        file('text.words', 'w').write(''.join(s + '\n'
+                                              for s in sorted(textwords)))
+
+    # update whitelists that need an update
+    if update:
+        for fn in glob.glob(whitelistdir + '/*.white'):
+            oldwords = [l.strip() for l in file(fn)]
+            white = set(l.strip() for l in file(fn))
+            newwords = sorted(set.intersection(white, textwords))
+            if newwords != oldwords:
+                print >> sys.stderr, 'updating', fn
+                file(fn, 'w').write(''.join(s + '\n' for s in newwords))
+
+    # find unknown words - mixed case that exists in lower is ok
+    lowwhitewords = set.union(whitewords, textwords)
+    badtextwords = set(s for s in (textwords - whitewords)
+                       if s.islower() or s.isupper()
+                       or s.lower() not in lowwhitewords)
+
+    if badtextwords:
+        print >> sys.stderr, 'unknown:'
+        for w in sorted(badtextwords):
+            print w
+        return 1
+    return 0
+
+if __name__ == "__main__":
+    parser = optparse.OptionParser("%prog [options] [files]")
+    parser.add_option("", "--whitelistdir", action="store",
+                      help="directory with *.white files")
+    parser.add_option("-u", "--update", action="store_true",
+                      help="update whitelists")
+    parser.add_option("", "--debug", action="store_true",
+                      help="show debug information")
+
+    parser.set_defaults(update=False, debug=False, whitelistdir='.')
+    (options, args) = parser.parse_args()
+
+    if len(args) == 0:
+        check = glob.glob("*")
+    else:
+        check = args
+
+    ret = spellcheck(check, whitelistdir=options.whitelistdir,
+                     update=options.update, debug=options.debug)
+    sys.exit(ret)
diff --git a/tests/test-spell b/tests/test-spell
new file mode 100755
--- /dev/null
+++ b/tests/test-spell
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+cd "$TESTDIR"/..
+
+if hg identify -q > /dev/null; then :
+else
+    echo "skipped: not a Mercurial working dir" >&2
+    exit 80
+fi
+
+hg manifest | egrep -v '^(tests/|i18n/|doc/.*\.py$|contrib/.*\.txt$|setup.py$)' | \
+    xargs python contrib/spell/spell.py --whitelistdir contrib/spell/ --update


More information about the Mercurial-devel mailing list