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.
4
  • 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 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 at 9: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 at 13:59
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
1
  • Thanks, got it. I ended up doing something like this. text-mode-syntax-table was right for me.
    – sixter
    May 28 at 8:58

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.