Skip to content

Commit c9815a9

Browse files
authored
Merge 700d563 into 7dbe36d
2 parents 7dbe36d + 700d563 commit c9815a9

6 files changed

Lines changed: 63 additions & 53 deletions

File tree

source/core.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,28 @@ class NewNVDAInstance:
214214
directory: Optional[str] = None
215215

216216

217+
def computeRestartCLIArgs(removeArgsList: list[str] | None = None) -> list[str]:
218+
"""Generate an equivalent list of CLI arguments from the values in globalVars.appArgs.
219+
:param removeArgsList: A list of value to ignore when looking in globalVars.appArgs.
220+
"""
221+
from __main__ import parser # import from nda.pyw
222+
223+
if not removeArgsList:
224+
removeArgsList = []
225+
args = []
226+
for arg, val in globalVars.appArgs._get_kwargs():
227+
if val == parser.get_default(arg):
228+
continue
229+
if arg in removeArgsList:
230+
continue
231+
flag = [a.option_strings[0] for a in parser._actions if a.dest == arg][0]
232+
args.append(flag)
233+
if isinstance(val, bool):
234+
continue
235+
args.append(f"{val}")
236+
return args
237+
238+
217239
def restartUnsafely():
218240
"""Start a new copy of NVDA immediately.
219241
Used as a last resort, in the event of a serious error to immediately restart NVDA without running any
@@ -239,13 +261,16 @@ def restartUnsafely():
239261
sys.argv.remove(paramToRemove)
240262
except ValueError:
241263
pass
264+
restartCLIArgs = computeRestartCLIArgs(
265+
removeArgsList=["easeOfAccess"],
266+
)
242267
options = []
243268
if NVDAState.isRunningAsSource():
244269
options.append(os.path.basename(sys.argv[0]))
245270
_startNewInstance(
246271
NewNVDAInstance(
247272
sys.executable,
248-
subprocess.list2cmdline(options + sys.argv[1:]),
273+
subprocess.list2cmdline(options + restartCLIArgs),
249274
globalVars.appDir,
250275
),
251276
)
@@ -260,15 +285,9 @@ def restart(disableAddons=False, debugLogging=False):
260285
return
261286
import subprocess
262287

263-
for paramToRemove in (
264-
"--disable-addons",
265-
"--debug-logging",
266-
"--ease-of-access",
267-
) + languageHandler.getLanguageCliArgs():
268-
try:
269-
sys.argv.remove(paramToRemove)
270-
except ValueError:
271-
pass
288+
restartCLIArgs = computeRestartCLIArgs(
289+
removeArgsList=["disableAddons", "debugLogging", "language", "easeOfAccess"],
290+
)
272291
options = []
273292
if NVDAState.isRunningAsSource():
274293
options.append(os.path.basename(sys.argv[0]))
@@ -280,7 +299,7 @@ def restart(disableAddons=False, debugLogging=False):
280299
if not triggerNVDAExit(
281300
NewNVDAInstance(
282301
sys.executable,
283-
subprocess.list2cmdline(options + sys.argv[1:]),
302+
subprocess.list2cmdline(options + restartCLIArgs),
284303
globalVars.appDir,
285304
),
286305
):

source/globalVars.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# A part of NonVisual Desktop Access (NVDA)
2-
# Copyright (C) 2006-2022 NV Access Limited, Łukasz Golonka, Leonard de Ruijter, Babbage B.V.,
2+
# Copyright (C) 2006-2024 NV Access Limited, Łukasz Golonka, Leonard de Ruijter, Babbage B.V.,
33
# Aleksey Sadovoy, Peter Vágner
44
# This file may be used under the terms of the GNU General Public License, version 2 or later.
55
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
@@ -41,7 +41,7 @@ class DefaultAppArgs(argparse.Namespace):
4141
logFileName: Optional[os.PathLike] = ""
4242
logLevel: int = 0
4343
configPath: Optional[os.PathLike] = None
44-
language: str = "en"
44+
language: str | None = None
4545
minimal: bool = False
4646
secure: bool = False
4747
"""

source/gui/settingsDialogs.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -800,16 +800,9 @@ def makeSettings(self, settingsSizer):
800800
self.languageNames = languageHandler.getAvailableLanguages(presentational=True)
801801
languageChoices = [x[1] for x in self.languageNames]
802802
if languageHandler.isLanguageForced():
803-
try:
804-
cmdLangDescription = next(
805-
ld for code, ld in self.languageNames if code == globalVars.appArgs.language
806-
)
807-
except StopIteration:
808-
# In case --lang=Windows is passed to the command line, globalVars.appArgs.language is the current
809-
# Windows language,, which may not be in the list of NVDA supported languages, e.g. Windows language may
810-
# be 'fr_FR' but NVDA only supports 'fr'.
811-
# In this situation, only use language code as a description.
812-
cmdLangDescription = globalVars.appArgs.language
803+
cmdLangDescription = next(
804+
ld for code, ld in self.languageNames if code == globalVars.appArgs.language
805+
)
813806
languageChoices.append(
814807
# Translators: Shown for a language which has been provided from the command line
815808
# 'langDesc' would be replaced with description of the given locale.

source/languageHandler.py

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
"""
1010

1111
import os
12-
import sys
1312
import ctypes
1413

1514
import weakref
@@ -25,7 +24,6 @@
2524
List,
2625
Optional,
2726
Tuple,
28-
Union,
2927
)
3028

3129
# a few Windows locale constants
@@ -44,6 +42,10 @@
4442

4543
LANGS_WITHOUT_TRANSLATIONS: FrozenSet[str] = frozenset(("en",))
4644

45+
_language: str | None = None
46+
"""Language of NVDA's UI.
47+
"""
48+
4749
installedTranslation: Optional[weakref.ReferenceType] = None
4850
"""Saved copy of the installed translation for ease of wrapping.
4951
"""
@@ -291,24 +293,9 @@ def getAvailableLanguages(presentational: bool = False) -> List[Tuple[str, str]]
291293
return langs
292294

293295

294-
def getLanguageCliArgs() -> Tuple[str, ...]:
295-
"""Returns all command line arguments which were used to set current NVDA language
296-
or an empty tuple if language has not been specified from the CLI."""
297-
for argIndex, argValue in enumerate(sys.argv):
298-
if argValue == "--lang":
299-
# Language was provided in a form `--lang lang_CODE`. The next position in `sys.argv` is a language code.
300-
# It is impossible not to provide it in this case as it would be flagged as an error
301-
# during arguments validation.
302-
return (argValue, sys.argv[argIndex + 1])
303-
if argValue.startswith("--lang="):
304-
# Language in a form `--lang=lang_CODE`
305-
return (argValue,)
306-
return tuple()
307-
308-
309296
def isLanguageForced() -> bool:
310297
"""Returns `True` if language is provided from the command line - `False` otherwise."""
311-
return bool(getLanguageCliArgs())
298+
return globalVars.appArgs.language is not None
312299

313300

314301
def getWindowsLanguage():
@@ -326,17 +313,15 @@ def getWindowsLanguage():
326313

327314
def _createGettextTranslation(
328315
localeName: str,
329-
) -> Union[None, gettext.GNUTranslations, gettext.NullTranslations]:
316+
) -> tuple[(None | gettext.GNUTranslations | gettext.NullTranslations), (str | None)]:
330317
if localeName in LANGS_WITHOUT_TRANSLATIONS:
331-
globalVars.appArgs.language = localeName
332-
return gettext.translation("nvda", fallback=True)
318+
return gettext.translation("nvda", fallback=True), localeName
333319
try:
334320
trans = gettext.translation("nvda", localedir="locale", languages=[localeName])
335-
globalVars.appArgs.language = localeName
336-
return trans
321+
return trans, localeName
337322
except IOError:
338323
log.debugWarning(f"couldn't set the translation service locale to {localeName}")
339-
return None
324+
return None, None
340325

341326

342327
def setLanguage(lang: str) -> None:
@@ -347,6 +332,8 @@ def setLanguage(lang: str) -> None:
347332
- Current NVDA language (match the translation service)
348333
- the python locale for the thread (match the translation service, fallback to system default)
349334
"""
335+
global _language
336+
350337
if lang == "Windows":
351338
localeName = getWindowsLanguage()
352339
else:
@@ -356,12 +343,13 @@ def setLanguage(lang: str) -> None:
356343
if winKernel.kernel32.SetThreadLocale(LCID) == 0:
357344
log.debugWarning(f"couldn't set windows thread locale to {lang}")
358345

359-
trans = _createGettextTranslation(localeName)
346+
trans, validatedLocalName = _createGettextTranslation(localeName)
360347
if trans is None and "_" in localeName:
361348
localeName = localeName.split("_")[0]
362-
trans = _createGettextTranslation(localeName)
349+
trans, validatedLocalName = _createGettextTranslation(localeName)
363350
if trans is None:
364-
trans = _createGettextTranslation("en")
351+
trans, validatedLocalName = _createGettextTranslation("en")
352+
_language = validatedLocalName
365353

366354
trans.install(names=["pgettext", "npgettext", "ngettext"])
367355
setLocale(getLanguage())
@@ -451,7 +439,7 @@ def setLocale(localeName: str) -> None:
451439

452440

453441
def getLanguage() -> str:
454-
return globalVars.appArgs.language
442+
return _language
455443

456444

457445
def normalizeLanguage(lang: str) -> Optional[str]:

source/nvda.pyw

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ parser.add_argument(
190190
"The default value is forced if secure mode is enabled.\n",
191191
)
192192
parser.add_argument(
193+
"-n",
193194
"--lang",
194195
dest="language",
195-
default="en",
196+
default=None,
196197
type=stringToLang,
197198
help=(
198199
"Override the configured NVDA language.\n"
@@ -218,7 +219,12 @@ parser.add_argument(
218219
help="Starts NVDA in secure mode",
219220
)
220221
parser.add_argument(
221-
"--disable-addons", action="store_true", dest="disableAddons", default=False, help="Disable all add-ons"
222+
"-d",
223+
"--disable-addons",
224+
action="store_true",
225+
dest="disableAddons",
226+
default=False,
227+
help="Disable all add-ons"
222228
)
223229
parser.add_argument(
224230
"--debug-logging",
@@ -320,6 +326,8 @@ parser.add_argument(
320326
help="Started by Windows Ease of Access",
321327
)
322328
(globalVars.appArgs, globalVars.unknownAppArgs) = parser.parse_known_args()
329+
# Copy original app args
330+
globalVars.originalAppArgs = argparse.Namespace(**{k: v for (k, v) in globalVars.appArgs._get_kwargs()})
323331
# Make any app args path values absolute
324332
# So as to not be affected by the current directory changing during process lifetime.
325333
pathAppArgs = [

user_docs/en/changes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ To use this feature, "allow NVDA to control the volume of other applications" mu
4646
* Component updates:
4747
* Updated LibLouis Braille translator to [3.32.0](https://github.com/liblouis/liblouis/releases/tag/v3.32.0). (#17469, @LeonarddeR)
4848
* Updated CLDR to version 46.0. (#17484, @OzancanKaratas)
49+
* Short versions of the most commonly used command line Options have been added: `-d` for `--disable-addons` and `-n` for `--lang`. (#11644, @CyrilleB79)
4950

5051
### Bug Fixes
5152

@@ -135,6 +136,7 @@ As the NVDA update check URL is now configurable directly within NVDA, no replac
135136
* The `space` keyword argument for `brailleDisplayDrivers.seikantk.InputGesture` now expects an `int` rather than a `bool`. (#17047, @school510587)
136137
* The `[upgrade]` configuration section including `[upgrade][newLaptopKeyboardLayout]` has been removed. (#17191)
137138
* In `NVDAObjects.window.scintilla.ScintillaTextInfo`, if no text is selected, the `collapse` method is overriden to expand to line if the `end` parameter is set to `True` (#17431, @nvdaes)
139+
* `languageHandler.getLanguageCliArgs` has been removed with no replacement. (#17486, @CyrilleB79)
138140

139141
#### Deprecations
140142

0 commit comments

Comments
 (0)