1

I want to make Emacs aware of the language I input -- in my case, Arabic, English, German -- so that I can use different fonts for each of them. So, for example, I'd like Emacs to use the following fonts when I'm entering text in the following languages:

Arabic  - DejaVu Sans Mono 14  
English - Consolas 11  
German  - Consolas 12  

So:

  • How can I set this up in my init file?
  • Where do I find the exact names of languages in Emacs to be recognized by the code?

(Side note: I'm new to Emacs and am just starting to learn elisp.)

Clarifying to follow-up on comments:

  • I'm using Windows. Ideally, I'd like Emacs to understand what language I'm using based on the Language Bar.

Update:
A better approach to this problem is posted here.

  • Do you mean your operating system's current IME? The currently set keyboard layout? Or are you asking for something that would somehow recognize what language you're inputting, no matter what the operating system level options are (like, it should recognize if you're typing german, even if your keyboard layout is english)? – wasamasa Nov 14 '14 at 13:17
  • yes to the latter. I am using Windows, based on the language shown in the Language bar, i.e., the input language no matter what keyboard layout you have. – doctorate Nov 14 '14 at 13:36
  • Good luck with that then, Emacs surely doesn't expose such functionality (it just receives keysyms, really) and Windows probably has an API call somewhere an external program needs to use. Or an external program could detect such changes (or be invoked directly on changes) and execute code in the running Emacs instance if you were using the daemon. – wasamasa Nov 14 '14 at 13:43
  • Alternatively you could forego size changes for English and German and instead set up DejaVu Sans Mono to be always used for arabic glyphs, this can be set up with fontsets for glyph ranges. However, all fontset recources I've encountered until now are targeted at Linux users, there's only outdated information for Windows users available. – wasamasa Nov 14 '14 at 13:46
  • 2
    Changing the font based on the language is actually rare — it's more common to change the font based on the script (so German and English would use one font, while Arabic and Persian would use another). Emacs supports different fonts for different scripts through fontsets. If you change the input language, do you want to change the font for subsequently inserted text only? For the current buffer/window/frame? For all buffers/windows/frames? – Gilles Nov 16 '14 at 0:15
1

In the comments you said you wanted to depend on the Windows language bar. The Windows Get-WinDefaultInputMethodOverride Cmdlet in Window PowerShell provides the necessary information.

Thus, when creating a new buffer, you need to run PowerShell Get-WinDefaultInputMethodOverride and parse the ouput. If you do this for every buffer, even for temporary buffers, my guess is that this slow you down very much. It would be better to write a function that can be added to hooks such as find-file-hooks. The functions on this hook are only called when you open a file for editing.

Calling a command and capturing the output happens using (shell-command-to-string COMMAND). Comparing a string to some other values happens via (string-match REGEXP STRING). Setting the font for a particular buffer involves calling (face-remap-add-relative FACE &rest SPECS). The face you are interested in is called default. The specs you want are :family and :height, the font family and the font size in tenths of points.

Thus, perhaps (untested, since I'm not on Windows):

(defun my-buffer-setup ()
  (let ((output (shell-command-to-string "PowerShell Get-WinDefaultInputMethodOverride")))
    (cond ((string-match "arabic" output)
           (face-remap-add-relative 'default :family "DejaVu Sans Mono" :height 140))
          ((string-match "english" output)
           (face-remap-add-relative 'default :family "Consolas" :height 110))
          ((string-match "german" output)
           (face-remap-add-relative 'default :family "Consolas" :height 120)))))

(add-hook 'find-file-hook 'my-buffer-setup)

Good luck. :)

  • About your choice of hook – I'll often create temporary buffers for notes. These aren't associated with any file, so find-file-hook is never run. – Sean Allred Nov 16 '14 at 14:32
  • @SeanAllred Yeah, the correct solution depends on how you want to use Emacs. You could look at buffer-list-update-hook. – Alex Schröder Nov 17 '14 at 8:15
  • I could not test it either bcz this powershell command was first introducted in Win8 and it seems there is no equivalent in win7. My machine has Ubuntu too, can you please extend this function to recognize system on machine and run the corresponding function based on system used? I would like to test it on Ubuntu first and meanwhile I have to look for the correct cmd command to inquire about the input lanugage in Windwos 7 32bit. – doctorate Nov 17 '14 at 9:29
  • Somebody else will have to do this, as I don't have access to those systems. – Alex Schröder Nov 17 '14 at 10:28
  • @AlexSchröder, as a workaround can you please care to answer the post here: emacs.stackexchange.com/questions/5519/… – doctorate Dec 18 '14 at 7:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.