[wiki] Assorted code snippets to customize TeXmacs' behaviour

Many aspects of TeXmacs’ behaviour can be changed/extended by adding Scheme code to the right initialization files. This wiki post collects various such snippets of code to adjust the behaviour of TeXmacs to your liking.

Feel free to add your own. The snippets do not have to be perfect. The intention is very much for users to improve and extend each others’ code. Longer pieces of code may be better suited for the TeXmacs Forge.

How to edit the TeXmacs user initialization files

The code snippets can be copy-pasted into one of your TeXmacs user initialization files. The section headings indicate in which file they should go.

To edit the files in the TeXmacs editor, first enable Tools→Developer Tool, then:

  • For code that should go into my-init-texmacs.scm:

    Click Developer → Open my-init-texmacs.scm.

  • For code that should go into my-init-buffer.scm:

    Click Developer → Open my-init-buffer.scm.

Paste in the snippet of your choice. To paste code from this page you may have to use Edit → Paste from → Html in TeXmacs (Edit → Paste from → Verbatim is also possible).

Save the edited file.

Finally, for the customization to take effect:

  • If you have changed my-init-texmacs.scm:

    Restart TeXmacs.

  • If you have changed my-init-buffer.scm:

    Open a file. (Note that some snippets may be written to only work on new files, not existing files)

Code for my-init-texmacs.scm

Export to a pdf with the same main file name as the current TeXmacs document

(define (propose-pdf-name)
  (with name (propose-name-buffer)
  (if (string-ends? name ".tm")
    (string-append (string-drop-right name 3) ".pdf"))))

(define (export-to-proposed-pdf)
  (let ((pdf-name (propose-pdf-name)))
    (if (url-test? pdf-name "f")
      (user-confirm "File already exists. Really overwrite?" #f
        (lambda (answ)
        (when answ (wrapped-print-to-file pdf-name))))
      (wrapped-print-to-file pdf-name))))

(kbd-map
  ("M-e p" (export-to-proposed-pdf)))

This will add the keyboard shortcut Meta+e p to export directly to a pdf with the same file name.

The Meta key is the Windows key in Windows or Linux, or the Command key on Apple systems. When using these keys, press Meta and e together, then press p.

The Escape key can serve as a fallback Meta key. To use this key, first press Meta, then release and press the e key, finally press the p key.

See Help → Manual → Getting started for more details.

Add extra fonts to the font menu in the toolbar

(delayed (lazy-initialize-force) (menu-bind document-short-font-menu
(former)
---
("Cantarell" (init-font "Cantarell"))
("Kepler" (init-font "Kepler"))
("Garamond" (init-font "Garamond Libre"))
("Montserrat" (init-font "Montserrat"))))

Enable multiline input by default for sessions

(use-modules
 ((dynamic session-edit) #:select (session-multiline-input)))
  (ahash-set! session-multiline-input (cons "julia" "default") #t)
  (ahash-set! session-multiline-input (cons "python" "default") #t)
  (ahash-set! session-multiline-input (cons "jupyter" "julia-1.6") #t)

Extend the line length for LaTeX export

See thread How do I export to Latex without it inserting newlines into the paragraphs?

(delayed (:idle 1000) (output-set-line-length 1000000000))

Evaluate all fields in a plugin session inside a document

See thread Evaluate all in document?

(define (ev-all)
(for-each (lambda (ses) (begin (tree-go-to ses :last 1 0) (session-evaluate-all)))
(tree-search (buffer-tree) subsession-document-context?)))

(kbd-map
("A-e" (ev-all)))

This will add the keyboard shortcut Alt+e to evaluate all cells in the document.

Optionally add an entry to the context menu inside sessions.

(tm-menu (texmacs-popup-menu)
(:require (inside? 'session))
(former)
---
("Evaluate all fields in document" (ev-all)))

For older versions of TeXmacs tree-search isn’t in global namespace and has to be imported using

(use-modules
((link link-extract)
#:select (tree-search)))

Assign arrow movements to key combinations

See thread How to modify the arrow keys?

(delayed
(lazy-keyboard-force)
(kbd-map ("C-a" (kbd-left)))
(kbd-map ("C-f" (kbd-right)))
(kbd-map ("C-s" (kbd-up)))
(kbd-map ("C-d" (kbd-down))))

This will add keyboard shortcuts Ctrl+a, Ctrl+f, etc. as alternatives to the keyboard arrows.

Insert subscript and superscript into sessions

(delayed (lazy-keyboard-force) (kbd-map
  (:mode in-session?)
  ("\\ _ var" (make-script #f #t))
  ("\\ ^ var" (make-script #t #t))))

This will add Jupyter style keyboard shortcuts \ _ Tab and \ ^ Tab to insert subscript and superscript (only when in sessions).

Editor shortcuts

In addition to macros, one can enter in TeXmacs “editor shortcuts” using “LaTeX style commands”. One example is text color; the key sequence \red, followed by a return, is transformed by TeXmacs into <with|color|red|> (visible in source mode) which localizes the environment variable color so that text entered into the empty slot is colored in red.

These editor shortcuts are defined in Scheme code using the macro kbd-commands.

Here is an example; we define a shortcut for the color "dark green". LaTex mode commands do not allow entering spaces, so we name the command "darkgreen" without space. Place the snippet in my-init-texmacs.scm.

(kbd-commands
  ("darkgreen" "" (make-with "color" "dark green")))

With this command, entering \darkgreen will result in <with|color|dark green|> (in source mode—in text mode one gets an empty slot where typing results in dark green text).

Code for my-init-buffer.scm

Add a style file to every new buffer

See thread Solutions in html export of exams using the education package

(if (not (buffer-has-name? (current-buffer)))
  (begin
  (set-style-list (append (get-style-list) '("no-solutions-in-html")))
  (buffer-pretend-saved (current-buffer))))

This will append a style file (in this case no-solutions-in-html, change this to the style file of your preference) to every new file. It will not operate on existing files.

3 Likes

Is it possible to get a list of all “wiki” posts? I found the other one I know (Undocumented internal macros in TeXmacs (wiki)) searching for “wiki”, but I think I found it only because it has the word “wiki” in the title.

I’ve added a “wiki” tag which can be used to signal wiki posts. I’m not sure if there is a better way to do it. Categories are mutually exclusive so if we have a “wiki” category we loose the original category of the post.

1 Like

The Search function has an option to search for wiki’s as well. You can go to Advanced Search, or just enter in:wiki in the search box. I get only two hits.

1 Like

Perhaps a table of contents would be useful for this wiki post: https://meta.discourse.org/t/discotoc-automatic-table-of-contents/111143 shows one, maybe administrators can enable it? If a TOC is enabled for all posts, it could be annoying, reading the link I see that one can choose whether to enable it for each post (with default “off” I hope :slight_smile: ).

Using this on Windows I get a “Could not concretize tuple” error. If you want I can copy by hand the whole message (I do not see how to copy it with a command).

Sorry, I can’t debug it here, as I can’t reproduce the problem.

Maybe you could test by evaluating (propose-pdf-name) in a Scheme session. You could also try putting some display* statements in export-to-proposed-pdf or commenting out parts to see what goes wrong.

(propose-pdf-name) gives the path of the file starting with a slash (e.g. /C/Users/ ...)
The form that fails is (url-test? pdf-name "f") with “Could not concretize tuple” and a nested tuple construct which starts with (concat, C, tuple (concat, Users, tuple (concat, ....
I will investigate more tomorrow.
BTW thanks for the correction on how to enter the Meta key.

On Windows it is not possible to check the values of forms with either display or display* (btw what does the asterisk do?), but it will be possible to look at the value that each form takes by letting it be the output of the computation.

I investigated a bit. My impression (I have not figured out what the code does line by line) is that there is an error of the PDFHummus converter (the error message with which the snippet stops is failed to start PDF), which may be due to the fact that concretize (pdf_file_name) does not work with the value given by (propose-pdf-name).
I will investigate more, I will look at why (url-test? pdf-name "f") causes “Could not concretize tuple”.

The url should be usually converted to string to refer to actual files in the filesystem. Normally one would use url-system or url-concretize to do the job. Maybe check some related scheme code to see what is the usual way to do this.

As far as I understood

the snippet works in the OS that @jeroen is using (I do not know whether that is MacOS or Linux), this means that the Scheme code is ok and in Windows something “internal” does not work well.

@pireddag Could you please try this?

(define (propose-pdf-name)
  (with name (propose-name-buffer)
  (if (string-ends? name ".tm")
    (url->system (string-append (string-drop-right name 3) ".pdf")))))

(define (export-to-proposed-pdf)
  (let ((pdf-name (propose-pdf-name)))
    (if (url-test? pdf-name "f")
      (user-confirm "File already exists. Really overwrite?" #f
        (lambda (answ)
        (when answ (wrapped-print-to-file pdf-name))))
      (wrapped-print-to-file pdf-name))))

(kbd-map
  ("M-e p" (export-to-proposed-pdf)))

Now we get the file path with Windows-style separators:"C\\Users ...
I have seen that to make url-test? work we need a colon after the drive letter. Then there is no “Could not concretize tuple” error, it returns #t if the file exists and the export works.

Ok, I am finally convinced that I have to do this :slight_smile:

What convinced me is that url->system would turn (current-buffer) into a file path, while (propose-name-buffer) uses url->unix which removes the colon after the drive letter.

1 Like

This post disappeared from the “top screen” of the forum and from my awareness as well.
Is there a way to keep it visible? I think it is essential that it be visible in order for people to be encouraged to contribute to it and to use the snippets.