Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashes when loading in RStudio #9

Open
josegonzalezpastor opened this issue Aug 1, 2024 · 1 comment
Open

Crashes when loading in RStudio #9

josegonzalezpastor opened this issue Aug 1, 2024 · 1 comment

Comments

@josegonzalezpastor
Copy link

Loading the library crashes RStudio.

A quick fix in the setLanguage.R file solved the issue, but I cannot push it. File content is copied here below:

RStudio version:
RStudio 2022.07.1+554 "Spotted Wakerobin" Release (7872775ebddc40635780ca1ed238934c3345c5de, 2022-07-22) for Windows
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) QtWebEngine/5.12.8 Chrome/69.0.3497.128 Safari/537.36

sessionInfo()
R version 4.2.0 (2022-04-22 ucrt)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows Server x64 (build 14393)

Matrix products: default

locale:
[1] LC_COLLATE=Dutch_Belgium.1252 LC_CTYPE=Dutch_Belgium.1252 LC_MONETARY=Dutch_Belgium.1252 LC_NUMERIC=C LC_TIME=Dutch_Belgium.1252

attached base packages:
[1] stats graphics grDevices utils datasets methods base

loaded via a namespace (and not attached):
[1] compiler_4.2.0 tools_4.2.0

R/setLanguage.R with fix:

Management of locales and message translation using msgcat

#' Change or get the language used in R and Tcl/Tk, strings translation in Tcl
#'
#' The function changes dynamically the language used by both R (messages only)
#' and Tcl/Tk, retrieves its current value, and manage string translation in
#' Tcl.
#'
#' @param lang An identification for the targeted language, for instance, "en"
#' for English, "en_US" for american English, "fr" for French, "de" for
#' German, "it" for Italian, etc. Facultative argument for [tclmclocale()].
#' @param msg A single character string with the message to translate.
#' @param translation The corresponding version in lang. Substitutions markers
#' like %s for strings, or %d for numbers are allowed (same syntax as
#' [base::gettextf()]). These translations are added in the Tcl catalog in the
#' main domain, i.e., you don't need to give a domain name with [tclmc()] to
#' retrieve the translation.
#' @param fmt A single character vector of format string.
#' @param ... Values to be passed into \code{fmt} for the substitution.
#' @param domain The 'domain", i;e., Tcl namespace where the translation is
#' defined. Use NULL (the default) or "" for the main domain where
#' translations using [tclmcset()] are stored.
#'
#' @return
#' [setLanguage()] returns TRUE if language was successfully changed in
#' Tcl/Tk, FALSE otherwise. [getLanguage()] returns a string with current
#' language in use for R, or an empty string if it cannot determinate which is
#' the language currently used, and a tcl.language attribute with the
#' different catalogs that are used in priority order (ending with "" for no
#' translation, i.e., Tcl translations do not return an error, but the initial
#' string if the item is not found in the catalog).
#' [tclmclocale()] allows to change and get language for Tcl only, without
#' changing anything for R.
#'
#' The two functions [tclmcset()] and [tclmc()] allow to record and retrieve the
#' translation of strings in the main R domain. Moreover, [tclmc()] also allows
#' to retrieve translations of Tcl strings in other Tcl namespaces (a.k.a.,
#' domains), see the examples.
#'
#' @note You need the msgcat Tcl package to use this (but it is provided with
#' all recent distributions of Tcl/Tk by default).
#'
#' @author Philippe Grosjean
#' @export
#' @Keywords utilities
#' @concept Tcl/Tk language translation
#'
#' @examples
#' # What is the language used by Tcl?
#' tclmclocale()
#'
#' # Define a simple translation in French and German
#' tclmcset("de", "Yes", "Ja")
#' tclmcset("fr", "Yes", "Oui")
#'
#' # Determine which language is currently in use in R
#' (oldlang <- getLanguage())
#' if (oldlang != "") {
#' # Switch to English; test a command that issues a warning and a Tcl string
#' setLanguage("en_US")
#' 1:3 + 1:2
#' tclmc("Yes")
#'
#' # Switch to German and test
#' setLanguage("de")
#' 1:3 + 1:2
#' tclmc("Yes")
#'
#' # Switch to Belgian French and test
#' setLanguage("fr_BE")
#' 1:3 + 1:2
#' tclmc("Yes")
#'
#' # A more complex trnaslation message with a substitution
#' tclmcset("fr", "Directory contains %d files",
#' "Le repertoire contient %d fichiers")
#' tclmc("Directory contains %d files", 9)
#' # or from a R/Tcl variable...
#' nfiles <- tclVar(12)
#' tclmc("Directory contains %d files", tclvalue(nfiles))
#'
#' # Retrieve a translation defined in the "tk" domain
#' tclmc("Replace existing file?", domain = "tk")
#'
#' # Tcl dialog boxes are translated according to the current language
#' \dontrun{
#' tkgetOpenFile()
#' }
#'
#' # Restore previous language
#' setLanguage(oldlang)
#' }
setLanguage <- function(lang) {

Change locale for both R and Tcl/Tk

Sys.setenv(language = lang)
Sys.setenv(LANG = lang)
#try(Sys.setlocale("LC_MESSAGES", lang), silent = TRUE) # Fails on Windows!
res <- tclRequire("msgcat")
if (inherits(res, "tclObj")) {
.Tcl("namespace import msgcat::")
# If the tcl.language attribute is defined, use it
tcllang <- attr(lang, "tcl.language")
if (!is.null(tcllang) && tcllang[1] != "") {
lang <- tcllang[1] # Use only first item
} else {
# Tcl does not accept locales like en_US.UF-8: must be en_us only
lang <- tolower(sub("^([^.]+)\..
$", "\1", lang))
}
tclmclocale(lang)
TRUE
} else {
FALSE
}
}

#' @export
#' @Rdname setLanguage
getLanguage <- function() {

Try to recover current language used for messages and GUI stuff in R

lang <- Sys.getenv("language")
if (lang == "")
lang <- Sys.getlocale("LC_MESSAGES")

This is a bad hack that probably does not work all the time, but at least,

it works under Windows for getting "fr" for French language

if (lang == "")
lang <- tolower(substr(Sys.getlocale("LC_COLLATE"), 1, 2))

Try to get language information from Tcl

tcllang <- try(as.character(tcl("mcpreferences")), silent = TRUE)
attr(lang, "tcl.language") <- tcllang

lang
}

#' @export
#' @Rdname setLanguage
tclmclocale <- function(lang) {
if (missing(lang)) {
as.character(tcl("mclocale"))
} else {
# Make sure lang is made compatible to Tcl
lang <- tolower(sub("^([^.]+)\..*$", "\1", lang))
as.character(tcl("mclocale", lang))
}
}

#' @export
#' @Rdname setLanguage
tclmcset <- function(lang, msg, translation)
invisible(tclvalue(tcl("mcset", lang, msg, translation)))

#' @export
#' @Rdname setLanguage
tclmc <- function(fmt, ..., domain = NULL) {
if (is.null(domain) || domain == "") {
# Simpler form
tclvalue(tcl("mc", fmt, ...))
} else {
# Need to evaluate in 'domain' Tcl namespace
transl <- .Tcl(paste0("namespace eval ", domain, " {set ::Rtransl [mc {",
fmt, "}]}"))
sprintf(tclvalue(transl), ...)
}
}

@GegznaV
Copy link

GegznaV commented Sep 15, 2024

@josegonzalezpastor, can you create a pull request?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants