[PATCH] pretty-print plural nouns in some status messages

Chris Peterson cpeterso at cpeterso.com
Sun May 4 13:49:20 CDT 2008


Here is a patch (against the hg repo's tip as of yesterday) that uses
python's translation.ngettext() to pretty-print some ui.status() messages
that contain nouns that may or may not be plural. For example:

1 changeset found
2 changesets found

I only changed a couple calls to ui.status(), just to float the idea before
doing a lot of extra work. :) I didn't change any calls to ui.debug()
because end users won't typically see those.

An argument against this patch is that the new status messages might make
life more difficult for any scripts that try to parse hg's stdout. But
perhaps those scripts should be importing hg as a python module?

Since i18n.py maps i18n._() to translation.gettext(), I followed the pattern
and mapped i18n.__() to translation.ngettext(). But I personally don't think
__() is a very good function name. :) Perhaps i18n.ngettext() would be
better, though more verbose. ngettext() which takes three arguments:
singular string, plural string, and a number to test == 1.

A localization problem (beyond the scope of this patch) is that some
mercurial code still creates messages by stitching together _() strings.
This will pose a problem for non-English languages that might have different
sentence orders (like German).

chris




diff -r 626cb86a6523 mercurial/i18n.py
--- a/mercurial/i18n.py    Thu Apr 24 17:16:02 2008 +0200
+++ b/mercurial/i18n.py    Sun May 04 11:46:00 2008 -0700
@@ -10,4 +10,6 @@
 import gettext
 t = gettext.translation('hg', fallback=1)
 gettext = t.gettext
+ngettext = t.ngettext
 _ = gettext
+__ = ngettext
diff -r 626cb86a6523 mercurial/localrepo.py
--- a/mercurial/localrepo.py    Thu Apr 24 17:16:02 2008 +0200
+++ b/mercurial/localrepo.py    Sun May 04 11:46:00 2008 -0700
@@ -6,7 +6,7 @@
 # of the GNU General Public License, incorporated herein by reference.

 from node import bin, hex, nullid, nullrev, short
-from i18n import _
+from i18n import _, __
 import repo, changegroup
 import changelog, dirstate, filelog, manifest, context, weakref
 import lock, transaction, stat, errno, ui
@@ -1583,7 +1583,8 @@

     def changegroupinfo(self, nodes, source):
         if self.ui.verbose or source == 'bundle':
-            self.ui.status(_("%d changesets found\n") % len(nodes))
+            count = len(nodes)
+            self.ui.status(__('%d changeset found\n', '%d changesets
found\n', count) % count)
         if self.ui.debugflag:
             self.ui.debug(_("List of changesets:\n"))
             for node in nodes:
@@ -2027,11 +2028,16 @@
             newheads = len(self.changelog.heads())
             heads = ""
             if oldheads and newheads != oldheads:
-                heads = _(" (%+d heads)") % (newheads - oldheads)
+                count = newheads - oldheads
+                headstr = __("head", "heads", count)
+                heads = _(" (%+d %s)") % (count, headstr)

-            self.ui.status(_("added %d changesets"
-                             " with %d changes to %d files%s\n")
-                             % (changesets, revisions, files, heads))
+            changesetstr = __("changeset", "changesets", changesets)
+            changestr = __("change", "changes", revisions)
+            filestr = __("file", "files", files)
+
+            self.ui.status(_("added %d %s with %d %s to %d %s%s\n")
+                             % (changesetstr, changestr, filestr, heads))

             if changesets > 0:
                 self.hook('pretxnchangegroup', throw=True,
@@ -2081,8 +2087,9 @@
         except (ValueError, TypeError):
             raise util.UnexpectedOutput(
                 _('Unexpected response from remote server:'), l)
-        self.ui.status(_('%d files to transfer, %s of data\n') %
-                       (total_files, util.bytecount(total_bytes)))
+        filestr = __('file', 'files', total_files)
+        self.ui.status(_('%d %s to transfer (%s bytes)\n') %
+                       (total_files, filestr, util.bytecount(total_bytes)))
         start = time.time()
         for i in xrange(total_files):
             # XXX doesn't support '\n' or '\r' in filenames
diff -r 626cb86a6523 mercurial/patch.py
--- a/mercurial/patch.py    Thu Apr 24 17:16:02 2008 +0200
+++ b/mercurial/patch.py    Sun May 04 11:46:00 2008 -0700
@@ -6,7 +6,7 @@
 # This software may be used and distributed according to the terms
 # of the GNU General Public License, incorporated herein by reference.

-from i18n import _
+from i18n import _, __
 from node import hex, nullid, short
 import base85, cmdutil, mdiff, util, context, revlog, diffhelpers, copies
 import cStringIO, email.Parser, os, popen2, re, errno
@@ -376,14 +376,10 @@

         if not self.rej:
             return
-        if self.hunks != 1:
-            hunkstr = "s"
-        else:
-            hunkstr = ""
-
+        hunkstr = __('hunk', 'hunks', self.hunks)
         fname = self.fname + ".rej"
         self.ui.warn(
-            _("%d out of %d hunk%s FAILED -- saving rejects to file %s\n")
%
+            _("%d out of %d %s FAILED -- saving rejects to file %s\n") %
             (len(self.rej), self.hunks, hunkstr, fname))
         try: os.unlink(fname)
         except:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://selenic.com/pipermail/mercurial-devel/attachments/20080504/ec0c4bfa/attachment.htm 


More information about the Mercurial-devel mailing list