Function: set-locale-environment

set-locale-environment is an interactive and byte-compiled function defined in mule-cmds.el.gz.

Signature

(set-locale-environment &optional LOCALE-NAME FRAME INHIBIT-REFRESH)

Documentation

Set up multilingual environment for using LOCALE-NAME.

This sets the language environment, the coding system priority, the default input method and sometimes other things.

LOCALE-NAME should be a string which is the name of a locale supported by the system. Often it is of the form xx_XX.CODE, where xx is a language, XX is a country, and CODE specifies a character set and coding system. For example, the locale name "ja_JP.EUC" might name a locale for Japanese in Japan using the japanese-iso-8bit coding-system. The name may also have a modifier suffix, e.g. @euro or @cyrillic.

If LOCALE-NAME is nil, its value is taken from the environment variables LC_ALL, LC_CTYPE and LANG (the first one that is set).

The locale names supported by your system can typically be found in a directory named /nix/store/1dax567dy7cf55x25a1ryg6z6hl3lvzw-gettext-0.25.1/share/locale or /usr/lib/locale. LOCALE-NAME will be translated according to the table specified by locale-translation-file-name.

If FRAME is non-nil, only set the keyboard coding system and the terminal coding system for the terminal of that frame, and don't touch session-global parameters like the language environment.

This function sets the current-locale-environment variable. To change the locale temporarily, with-locale-environment can be used.

By default, this function will redraw the current frame. If INHIBIT-REFRESH is non-nil, this isn't done.

See also locale-charset-language-names, locale-language-names, locale-preferred-coding-systems and locale-coding-system.

View in manual

Probably introduced at or before Emacs version 21.1.

Key Bindings

Source Code

;; Defined in /usr/src/emacs/lisp/international/mule-cmds.el.gz
(defun set-locale-environment (&optional locale-name frame inhibit-refresh)
  "Set up multilingual environment for using LOCALE-NAME.
This sets the language environment, the coding system priority,
the default input method and sometimes other things.

LOCALE-NAME should be a string which is the name of a locale supported
by the system.  Often it is of the form xx_XX.CODE, where xx is a
language, XX is a country, and CODE specifies a character set and
coding system.  For example, the locale name \"ja_JP.EUC\" might name
a locale for Japanese in Japan using the `japanese-iso-8bit'
coding-system.  The name may also have a modifier suffix, e.g. `@euro'
or `@cyrillic'.

If LOCALE-NAME is nil, its value is taken from the environment
variables LC_ALL, LC_CTYPE and LANG (the first one that is set).

The locale names supported by your system can typically be found in a
directory named `/nix/store/1dax567dy7cf55x25a1ryg6z6hl3lvzw-gettext-0.25.1/share/locale' or `/usr/lib/locale'.  LOCALE-NAME
will be translated according to the table specified by
`locale-translation-file-name'.

If FRAME is non-nil, only set the keyboard coding system and the
terminal coding system for the terminal of that frame, and don't
touch session-global parameters like the language environment.

This function sets the `current-locale-environment' variable.  To
change the locale temporarily, `with-locale-environment' can be
used.

By default, this function will redraw the current frame.  If
INHIBIT-REFRESH is non-nil, this isn't done.

See also `locale-charset-language-names', `locale-language-names',
`locale-preferred-coding-systems' and `locale-coding-system'."
  (interactive (list (completing-read "Set environment for locale: "
                                      (get-locale-names))))
  ;; Do this at runtime for the sake of binaries possibly transported
  ;; to a system without X.
  (setq locale-translation-file-name
	(let ((files
	       '("/usr/share/X11/locale/locale.alias" ; e.g. X11R7
		 "/usr/lib/X11/locale/locale.alias" ; e.g. X11R6.4
		 "/usr/X11R6/lib/X11/locale/locale.alias" ; XFree86, e.g. RedHat 4.2
		 "/usr/openwin/lib/locale/locale.alias" ; e.g. Solaris 2.6
		 ;;
		 ;; The following name appears after the X-related names above,
		 ;; since the X-related names are what X actually uses.
		 "/nix/store/1dax567dy7cf55x25a1ryg6z6hl3lvzw-gettext-0.25.1/share/locale/locale.alias" ; GNU/Linux sans X
		 )))
	  (while (and files (not (file-exists-p (car files))))
	    (setq files (cdr files)))
	  (car files)))

  (let ((locale locale-name))

    (unless locale
      ;; Use the first of these three environment variables
      ;; that has a nonempty value.
      (let ((vars '("LC_ALL" "LC_CTYPE" "LANG")))
	(while (and vars
		    (= 0 (length locale))) ; nil or empty string
	  (setq locale (getenv (pop vars) frame)))))

    (when locale
      (setq locale (locale-translate locale))
      (setq current-locale-environment locale)

      ;; Leave the system locales alone if the caller did not specify
      ;; an explicit locale name, as their defaults are set from
      ;; LC_MESSAGES and LC_TIME, not LC_CTYPE, and the user might not
      ;; want to set them to the same value as LC_CTYPE.
      (when locale-name
	(setq system-messages-locale locale)
	(setq system-time-locale locale))

      (if (string-match "^[a-z][a-z]" locale)
          ;; The value of 'current-iso639-language' is matched against
          ;; the ':lang' property of font-spec objects when selecting
          ;; and prioritizing available fonts for displaying
          ;; characters; see fontset.c.
	  (setq current-iso639-language
                ;; The call to 'downcase' is for w32, where the
                ;; MS-Windows locale names are in caps, as in "ENU",
                ;; the equivalent of the Posix "en_US".  Since the
                ;; match mentioned above uses memq, and ':lang'
                ;; properties have lower-case values, the letter-case
                ;; must match exactly.
                (intern (downcase (match-string 0 locale))))))

    (setq woman-locale
          (or system-messages-locale
              (let ((msglocale (getenv "LC_MESSAGES" frame)))
                (if (zerop (length msglocale))
                    locale
                  (locale-translate msglocale)))))

    (when locale
      (setq locale (downcase locale))

      (let ((language-name
	     (locale-name-match locale locale-language-names))
	    (charset-language-name
	     (locale-name-match locale locale-charset-language-names))
	    (default-eol-type (coding-system-eol-type
			       (default-value 'buffer-file-coding-system)))
	    (coding-system
	     (or (locale-name-match locale locale-preferred-coding-systems)
		 (when locale
		   (if (string-match "\\.\\([^@]+\\)" locale)
		       (locale-charset-to-coding-system
			(match-string 1 locale)))))))

	(if (consp language-name)
	    ;; locale-language-names specify both lang-env and coding.
	    ;; But, what specified in locale-preferred-coding-systems
	    ;; has higher priority.
	    (setq coding-system (or coding-system
				    (nth 1 language-name))
		  language-name (car language-name))
	  ;; Otherwise, if locale is not listed in locale-language-names,
	  ;; use what listed in locale-charset-language-names.
	  (if (not language-name)
	      (setq language-name charset-language-name)))

	;; If a specific EOL conversion was specified in the default
	;; buffer-file-coding-system, preserve it in the coding system
	;; we will be using from now on.
	(if (and (memq default-eol-type '(0 1 2 unix dos mac))
		 coding-system
		 (coding-system-p coding-system))
	    (setq coding-system (coding-system-change-eol-conversion
				 coding-system default-eol-type)))

	(when language-name

	  ;; Set up for this character set.  This is now the right way
	  ;; to do it for both unibyte and multibyte modes.
	  (unless frame
	    (set-language-environment language-name))

	  (set-display-table-and-terminal-coding-system
	   language-name coding-system frame inhibit-refresh)

	  ;; Set the `keyboard-coding-system' if appropriate (tty
	  ;; only).  At least X and MS Windows can generate
	  ;; multilingual input.
	  ;; XXX This was disabled unless `window-system', but that
	  ;; leads to buggy behavior when a tty frame is opened
	  ;; later.  Setting the keyboard coding system has no adverse
	  ;; effect on X, so let's do it anyway. -- Lorentey
	  (let ((kcs (or coding-system
			 (car (get-language-info language-name
						 'coding-system)))))
	    (if kcs (set-keyboard-coding-system kcs frame)))

	  (unless frame
	    (setq locale-coding-system
		  (car (get-language-info language-name 'coding-priority)))))

	(when (and (not frame)
		   coding-system
		   (not (coding-system-equal coding-system
					     locale-coding-system)))
	  (prefer-coding-system coding-system)
	  ;; Fixme: perhaps prefer-coding-system should set this too.
	  ;; But it's not the time to do such a fundamental change.
	  (setq default-sendmail-coding-system coding-system)
	  (setq locale-coding-system coding-system))))

    ;; On Windows, override locale-coding-system,
    ;; default-file-name-coding-system, keyboard-coding-system,
    ;; terminal-coding-system with the ANSI or console codepage.
    (when (and (eq system-type 'windows-nt)
               (boundp 'w32-ansi-code-page))
      (let* ((ansi-code-page-coding
              (intern (format "cp%d" w32-ansi-code-page)))
             (code-page-coding
              (if noninteractive
                  (intern (format "cp%d" (w32-get-console-codepage)))
                ansi-code-page-coding))
             (output-coding
              (if noninteractive
                  (intern (format "cp%d" (w32-get-console-output-codepage)))
                code-page-coding))
             (multibyte-code-page-coding
              (or (and (boundp 'w32-multibyte-code-page)
                       (not (zerop w32-multibyte-code-page))
                       (intern (format "cp%d" w32-multibyte-code-page)))
                  code-page-coding))
             (locale-coding
              (if noninteractive
                  code-page-coding
                multibyte-code-page-coding)))
	(when (and (coding-system-p code-page-coding)
                   (coding-system-p locale-coding))
          (or output-coding (setq output-coding code-page-coding))
	  (unless frame (setq locale-coding-system locale-coding))
	  (set-keyboard-coding-system code-page-coding frame)
	  (set-terminal-coding-system output-coding frame inhibit-refresh)
	  (setq default-file-name-coding-system ansi-code-page-coding))))

    (when (eq system-type 'darwin)
      ;; On Darwin, file names are always encoded in utf-8, no matter
      ;; the locale.
      (setq default-file-name-coding-system 'utf-8-unix)
      ;; macOS's Terminal.app by default uses utf-8 regardless of
      ;; the locale.
      (when (and (null window-system)
		 (equal (getenv "TERM_PROGRAM" frame) "Apple_Terminal"))
	(set-terminal-coding-system 'utf-8 nil inhibit-refresh)
	(set-keyboard-coding-system 'utf-8)))

    ;; Default to A4 paper if we're not in a C, POSIX or US locale.
    ;; (See comments in Flocale_info.)
    (unless frame
      (let ((paper (locale-info 'paper))
            locale)
	(if paper
	    (cond
	     ((equal paper '(216 279))
	      (setq ps-paper-type 'letter))
	     ((equal paper '(210 297))
	      (setq ps-paper-type 'a4)))
	  (let ((vars '("LC_ALL" "LC_PAPER" "LANG")))
	    (while (and vars (= 0 (length locale)))
	      (setq locale (getenv (pop vars) frame))))
	  (when locale
	    ;; As of glibc 2.2.5, these are the only US Letter locales,
	    ;; and the rest are A4.
	    (setq ps-paper-type
		  (or (locale-name-match locale '(("c$" . letter)
						  ("posix$" . letter)
						  (".._us" . letter)
						  (".._pr" . letter)
						  (".._ca" . letter)
						  ("enu$" . letter) ; Windows
						  ("esu$" . letter)
						  ("enc$" . letter)
						  ("frc$" . letter)))
		      'a4)))))))
  nil)