5

I have an Elisp function which takes a string and performs capitalization (capitalize) on it, and then inserts it into a file. Apparently capitalize doesn't consider the single quote as a "word constituent" and therefore I get results like "I'M A Cat".

I understand that this is because of the syntax table in place. The default returned by (standard-syntax-table) treats the quote as a "word constituent", so I'm assuming that code execution uses emacs-lisp-mode-syntax-table which has it otherwise.

I tried executing capitalize inside with-temp-buffer but that didn't work for some reason.

So my questions are:

  • Does the functions I have in my config useemacs-lisp-mode-syntax-table when I call them?
  • What's the standard way of dealing with this? What's a way to isolate my functions from inheriting all this context? I don't want to manually create a new table and use with-syntax-table for every function in my config or change the current table using modify-syntax-entry, and I want my strings to be treated like normal English sentences.
Drew
  • 75,699
  • 9
  • 109
  • 225
sixter
  • 113
  • 7
  • https://emacs.stackexchange.com/tags/elisp/info – Drew May 26 '21 at 14:45
  • What's the mode of the buffer you are inserting into? The syntax table of that mode is what matters, so if you are inserting into a text-mode buffer, you should see the capitalization you expect. If you insert into an emacs-lisp buffer, you'll get capitalization according to *its* syntax table. – NickD May 26 '21 at 14:51
  • @NickD I'm not inserting it anywhere. I'm using it as a filename. I tried using `with-temp-buffer` hoping that the default table the buffer inherits would have apostrophe as a word constituent, but apparently that wasn't the case. – sixter May 28 '21 at 09:02
  • Then fix the question: the first sentence says `... and then inserts it into a file`. How are you using it as a filename? Are you inserting it into the minibuffer in response to a prompt? The minibuffer has its own syntax tables: `minibuffer-local-filename-syntax` and `minibuffer-inactive-mode-syntax-table`. I presume the first one is then what matters. – NickD May 28 '21 at 13:59

1 Answers1

4

You say you don't want to have to "manually create a new table and use with-syntax-table for every function in my config or change the current table using modify-syntax-entry."

I think you have to do either that or give yourself a more general function that you can apply to accomplish the same thing.

Here's a particular command, just for capitalizing the region the way you want:

(defun my-capitalize-region (begin end)
  "..."
  (interactive "r")
  (let ((s-table  (copy-syntax-table)))
    (modify-syntax-entry ?' "w" s-table)
    (with-syntax-table s-table (capitalize-region begin end))))

You could use essentially the same code as a helper, to apply to a command, such as capitalize-region passed as an arg.

(defun with-word-apostrophe (command &rest args)
  "..."
  (let ((s-table  (copy-syntax-table)))
    (modify-syntax-entry ?' "w" s-table)
    (with-syntax-table s-table (apply command args))))

(defun my-capitalize-region (begin end)
  "..."
  (interactive "r")
  (with-word-apostrophe #'capitalize-region begin end))

You can't just use standard-syntax-table, e.g.:

(defun with-word-apostrophe (command &rest args)
  "..."
  (with-syntax-table (standard-syntax-table) (apply command args)))

because apostrophe has syntax punctuation in the standard syntax table:

(aref (standard-syntax-table) ?') ; ==> (1), which means punctuation
Drew
  • 75,699
  • 9
  • 109
  • 225
  • Thanks, got it. I ended up doing something like this. `text-mode-syntax-table` was right for me. – sixter May 28 '21 at 08:58