multi-word abbrev expansion - emacs

I found this mailing list message about multi-word abbreviations, but
still can't get expansion to work.
I have these two abbreviations defined:
"agw" 0 "a great whale"
"a g w" 0 "a great whale"
pressing space after "agw" works, but not "a g w". However if I call
(abbrev-expansion "a g w"), then the correct expansion is returned.
The question is how to get Emacs to search beyond one word boundary backwards?
Yes, yasnippet exists and I use it, but abbrev is more seamless (e.g. press
space after "1/2" turns it into unicode half). I also don't want to change
the syntax table.

SPACE, before inserting itself, will look for an abbrev before point to expand. It uses `backward-word', which will stop at the previous space. Thus SPACE can't expand spaces inside abbrevs.

As explained by Andreas, it does not work because by default abbrevs only work if they are made up of chars that are "word constituent" and " " is not a word constituent. You can change this rule, tho, for a given table, with something like (abbrev-table-put <table> :regexp <regexp>) where a regexp like "\\<\\(\\w+:?\\)\\W*" would pretty much reproduce the default behavior.
Now for your case, you want a regexp that will match "a g w" and "agw" but note that it shouldn't match the "agw" of "dawg" and neither should it match "a g agw", which makes it a bit tricky. One way to do that is to define your regexp as (concat "\\<" (regexp-opt '("agw" "a g w")) "\\W*"), which is fairly simple to do but has the downside that it requires changing the regexp any time you add an abbrev.

Related

Emacs highlighting: how to deal with highlighting messed up by unusual usage of special characters?

Problem:
In Emacs configuration modes (e.g. conf-xdefaults-mode or conf-space-mode), some special characters are used in unusual ways, for instance when they define keybindings. This messes up the highlighting for the rest of the buffer.
Example:
The ranger rc.conf file uses conf-space-mode which greatly helps its readability. But lines such as:
map # console shell -p%space
map "<any> tag_toggle tag=%any
mess up the highlighting since # usually defines a comment and is followed by font-lock-comment-face until the end of the line and " defines the beginning of a string and is followed by font-lock-string-face until it encounters a closing quote.
Escaping those characters is not an option because it would prevent them from defining the keybindings.
Possible solution:
The best solution I can think of is to fiddle with font lock settings for those configuration modes to remove the highlighting after those special characters. But I will then loose the proper highlighting after those characters when it is suitable.
A compromise could be to keep highlighting after # since this only messes up one line and there are a lot of comments in those configuration files, while removing the highlighting after single and double quotes since those mess up the entire rest of the buffer and strings are not so common in configuration files.
Question:
What is the proper way to deal with these situations?
Is there a way to reset the highlighting at a point in the buffer? or to insert a character which would affect the highlighting (to fix it) without affecting the code? or is there a way to "escape" some characters for the highlighting only without affecting the code?
The easy way
It's probably easiest to just live with it but keep things constrained. Here, I took ranger's default rc.conf and re-arranged some of the font-lock errors.
Let's ignore the blue "map" for now. We have two visible font-lock errors. The map #... is font-locking as a comment, and the map "... font-locking as a string to the end of the buffer. The first error is self-constrained. Comments end at the end of the line. The second error we constrain by adding a comment. (I don't know if ranger would accept comments in the middle of the line, so I'm only using beginning-of-line comments here.)
The second error is now constrained to one line, but a couple more errors have popped up. Quickly adjusting these we get.
This is something that I could live with, as I'm not in conf files all day long (as opposed to say, source code.) It would be even neater if our new "comments" could be included on the same line.
The hard way
You'll want to use Emacs font-lock-add-keywords. Let's get back to that blue map in the first image. It's rendering blue because conf-space-mode thinks that a string, followed by any amount of whitespace, followed by an opening brace should be rendered in font-lock-type-face (the actually regexp that triggers this is ^[_space__tab_]*\\(.+?\\)[_space__tab_\n]*{[^{}]*?$ where _space_ and _tab_ are actual space and tab characters.)
We can override this in a simple fashion by evaluating
(font-lock-remove-keywords
'conf-space-mode
'(("^\\<\\(map\\)\\>" 1 font-lock-variable-name-face)))
and reloading the buffer with C-x C-v RET. Now, every time that the word "map" appears at the beginning of a line it's rendered as font-lock-variable-name-face (yellow in our example.)
You can make this change permanent by adding a hook to your init file.
(add-hook 'conf-space-mode-hook (lambda ()
(font-lock-remove-keywords
nil
'(("^\\<\\(map\\)\\>" 1 font-lock-variable-name-face)))))
This method doesn't appear to work for your comment (#) and string (' ") delimiters as they're defined in the syntax table. Modifying the syntax table to provide special cases is probably more effort than it's worth.

Emacs incorrectly wraps text with fill-paragraph

So in Emacs, word-wraping is called filling and is done by M-q or M-x fill-paragraph. Is there any way to modify this function to respect spaces that should be non-breaking? For example, if we have the following sentence:
This is a black sentence with a yellow word at the end.
and tell Emacs to fill-paragraph at mark 50, it wraps it like this:
This is a black sentence with a yellow word at the
end.
However, if I do the same with C-u M-x shell-command-on-region and enter fold -sw 50, I get the following (correct) output:
This is a black sentence with a yellow word at
the end.
A similar problem happens when the end of a sentence is followed by something in parentheses:
This is a black sentence with a yellow word here. (This is something in parens)
The above sentence is wrapped with M-q at mark 50 in the following way:
This is a black sentence with a yellow word
here. (This is something in parens)
However, fold -sw 50 wraps it correctly:
This is a black sentence with a yellow word here.
(This is something in parens)
I know I could just write a function that uses fold and use that but I'm curious as to why fill-paragraph behaves like this and if it can be modified.
I am not sure what your definition of "non-breaking" space is.
However, you can achieve what you want in your examples by doing:
(add-to-list 'fill-nobreak-predicate 'fill-single-word-nobreak-p)
(setq sentence-end-double-space nil)
Documentation (and comment) of fill-single-word-nobreak-p says:
"Don't break a line after the first or before the last word of a sentence."
;; Actually, allow breaking before the last word of a sentence, so long as
;; it's not the last word of the paragraph.
You can add your own predicates to the fill-nobreak-predicate list.

how to avoid emacs' replacing quotation marks in French

When you use babel with French (set by, \usepackage[francais]{babel} emacs replaces automatically quotations marks (") by \og and \fg (you need only to restart emacs after adding babel).
It could be quite cool. But I'm using csquotes package which allows to have the good quotation marks by simply writing ".
\usepackage[babel]{csquotes}
\MakeOuterQuote{"}
So this amazing feature of emacs (the automatic replacement of " by \og or \fg) is useless for me and even painful.
How do I remove it?
It seems it is the font-latex-quotes variable which manage this. But options are only French (<< >>) or German (>> <<). I would like to redefine this variable to consider "test" as quote with test in color.
Assuming you are using auctex. you need to customize the value of variable TeX-quote-language to 'override.
This special value makes that language-related styles inhibit to modify its value, so quoting magic is deactivated.
I fixed this issue by modifying the variables LaTeX-csquotes-open-quote and LaTeX-csquotes-close-quote.
I define the first variable as \enquote{ and the second as }.

adding another letter to already existing autohotkey

My title doesn't make any sense, but here's an example of what I want to do:
If I type abc it should be replaced with ABC. Additionally, if I type abcc it should replace with Always Be Closing. In other words abc auto-capitalizes, and abcc spells this acronym out.
Currently, I have...
:*:abc::ABC
:*:abcc::Always Be Closing
...so when I type abcc it just comes out as ABCc
I know there's a lot more to it than this, but I can't figure out (new to this). Thanks for any help.
The * are your hotstring options, where the * indicated that it will replace it as soon as you type the last letter c in abc. Removing the * like this will make it replace only if you press a non-alphanumeric character: (or enter, or whatever)
::abc::ABC
::abcc::Always Be Closing
The above lines is probably what you want. (You can add the c option to make it case sensitive for example, if you want)
Also see the documentation of Hotstrings, in particular the Options block.

How to make part of a word bold in org-mode

How can I make org-mode markup work for a part of a word? For example, I'd like it to work for cases like this:
=Class=es
and this:
/Method/s
Based on my tests it seems like org-mode markup syntax works on complete words only.
These days, there is a way to do this (without using quoted HTML tags):
(setcar org-emphasis-regexp-components " \t('\"{[:alpha:]")
(setcar (nthcdr 1 org-emphasis-regexp-components) "[:alpha:]- \t.,:!?;'\")}\\")
(org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
Explanation
The manual says that org-emphasis-regexp-components can be used to
fine tune what characters are allowed before and after the markup characters [...].
It is a list containing five entries. The first entry lists characters that are allowed to immediately precede markup characters, and the second entry lists characters that are allowed to follow markup characters. By default, letters are not included in either one of these entries. So in order to successfully apply formatting to strings immediately preceded or followed by a letter, we have to add [:alpha:] (which matches any letter) to both entries.
This is what the calls to setcar do. The purpose of the third line is to rebuild the regular expression for emphasis based on the modified version of org-emphasis-regexp-components.
I don't think you can do it so that it shows up in the buffer as bold. If you just need it so that it appears bold when you export it to html, you can use:
th#<b>is is ha#</b>lf bold
See Quoting HTML tags
No, you can't do that. I searched for the same solution before and found nothing. A (very) bad hack is to do something like *Class* es (with a whitespace).
Perhaps you can write a short message to the creator, Carsten Dominik (Homepage), and ask him for a solution. He seems to be a nice guy.
A solution that has not been mentioned is to use a unicode zero width space (U+200B) in between the desired bolded and unbolded parts of a word.
To get the desired bolding of the word "Classes":
Type 'Class*es' in the buffer (without quotes).
Move the cursor between the '*' and 'e' characters.
Press C-x 8 RET (to execute the insert-char command).
Type 'zero width space' (without quotes) and press RET.
Move the cursor to the beginning of the word and insert a '*' character.
The word "Classes" should now have the desired appearance.
Note that there is the possibility that this will cause problems when exporting.
src_latex{\textbf{Class}es and \textit{Method}s}
Building up on the previous excellent answer
I had to modify it a bit in order to make it work with spacemacs. Indeed, from the spacamacs org-layer documentation, available here, we can read
Because of autoloading, calling to org functions will trigger the
loading up of the org shipped with emacs which will induce conflicts.
One way to avoid conflict is to wrap your org config code in a
with-eval-after-load block [...]
So, I put the following lines inside my dotspacemacs/user-config ()
(eval-after-load "org"
'(progn
(setcar org-emphasis-regexp-components " \t('\"{[:alpha:]")
(setcar (nthcdr 1 org-emphasis-regexp-components) "[:alpha:]- \t.,:!?;'\")}\\")
(org-set-emph-re 'org-emphasis-regexp-components org-emphasis-regexp-components)
))