Emacs 24.1 & Haskell syntax highlighting of Prelude and commonly used functions - haskell

Another question on Emacs 24.1 and Haskell. I've noticed that it does indenting for me and it does very basic highlighting for me (types are in green, for example). But out-of-box Emacs 24.1 doesn't highlight commonly used functions like foldr, map, etc. Is there an ability for Emacs and haskell-mode to highlight commonly used functions?

Fundamentally, standard library functions are just that--functions. In fact, depending on your imports, any of them could be user-supplied rather than from the standard prelude! This actually happens often--for example, if you want to use Control.Category you usually hide id and replace it with a polymorphic version.
So in short, there is no real reason to highlight standard functions. So I really doubt this functionality is present in the standard Haskell mode.
That said, this is Emacs. You can easily add anything you want. If you have a list of all the function names you want to highlight, it should not be difficult to add that to the Haskell mode.
You can add your new functions to the haskell-mode highlighting with code something like this in your .emacs file:
(font-lock-add-keywords 'haskell-mode
'(("\\<\\(map\\|foldr\\|foldl\\)\\>" 1
'(:foreground "#3366FF") t)))
The weird looking string is an Emacs-style regular expression. \< and \> are like \b and \(, \| and \) are for alternation inside a group. Since there are no regex literals, every \ has to be escaped inside the string. The regex would be more readable as \<\(map\|foldr\|foldl\)\>. You can easily add other function names by adding new cases to the expression.
The (:foreground "#3366FF") just sets the color of the text to a rather fetching shade of blue.

Related

Setting Vi abbreviation that includes special character

How to set the abbreviation for a specific word that contains special character like ":,;'." etc., for instance, I want to set an abbreviation for std::map to std::map
:ab std::map std::map<string,int>
is not working
The abbreviation trigger text has restrictions: it has to be of either full-id, end-id, or non-id type (basically, which characters are keywords; see :help abbreviations for details).
For the C / C++ filetypes, the colon : normally is not part of 'iskeyword', that's causing the E474 error. As it's not recommended to mess with that setting (it affects navigation, syntax highlighting, etc.), you have to drop / replace it from the abbreviation:
:ab stdmap std::map<string,int>
The solution I proposed in Using backslashes in vim abbreviations should be adaptable to your case. You will have to adapt the test getline('.')[col('.')-2]=='\' to something like getline('.')[:col('.')-2] =~ '.*std::$' (untested)
But, honestly, you should consider using a snippet engine instead, there are plenty.

VIM Delete Standard Scripting Word Groups

How would you use VIM to delete a word group, which includes white space characters, but is a standard grouping you would want to access when scripting? Specifically, when you have your cursor over some part of the following text, how would delete help="initialize, lines, h2, derivs, tt, history", from below. Maybe one would need to create specific mappings. But on the other hand, it seems pretty natural to want to access text like this if you are using VIM to edit scripting programs.
parser = argparse.ArgumentParser()
parser.add_argument("task", help="initialize, lines, h2, derivs, tt, history", default='yes')
Vim has a variety of text objects built-in, e.g. da" deletes quoted text (including the quotes; di" keeps the quotes). See :help text-objects for more information.
There are some plugins, e.g. textobj-user - Support for user-defined text objects and my own CountJump plugin that make it easy to define your own, "special" text objects. Also, you'll find many such text objects on vim.org. Based on your example, argtextobj.vim - Text-object like motion for arguments may be exactly what you need here.
If you are inside the " you want to delete, I would use:
di"diW
If you were above help=, I would use something like:
d/defEnter
to remove everything until you encounter default, followed by a few x, and left-wise motion, to remove the remaining characters.
I don't really think a new mapping is needed, but your experience may vary.
What makes sense from Vim's perspective and according to its design goals is to provide small and generic elements and a few rules to combine them in order to achieve higher level tasks. It does quite a good job, I'd say, with its numerous text-objects and motions but we always have to repeat domain-specific tasks and that's exactly where Vim's extensibility comes into play. It is where users and plugin authors fill the gap with custom mappings/object/functions and… plugins.
It is fairly easy, for example, to record a macro and map it for later reuse. Or create a quick and dirty custom text-object…
The following snippet should work with your sample.
xnoremap aa /\v["'][,)]/e<CR>o?\v\s+\w+\=<CR>
onoremap aa :normal vaa<CR>
With it, you can do daa, caa, yaa and vaa from anywhere within that argument.
Obviously, this solution is extremely specific and making it more generic would most certainly involve a bit more thought but there are already relatively smart solutions floating around, as in Ingo's answer.

Make vim highlight python builtins when they are not followed by a dot

Is there a way to highlight built in Python functions in vim only when they are preceded by 1 more whitespaces? Furthermore, is there a modular way to do this? That is, I don't want to edit every single syn keyword pythonBuiltinFunc abs chr ... line, I just want to be able to say something like syn keyword pythonBuiltinFunc onlymatchafter="\s+"?
EDIT:
Here's an example, since the two people who answered my question didn't seem to understand what I was asking which is my fault for not being more clear.
When I write the following Python code
import numpy as np
x = np.abs(np.random.randn(10, 10))
The word abs gets highlighted simply because vim is essentially just matching anything that has the word abs in it that is not inside of a string. How can I get vim to highlight the Python builtins WITHOUT highlighting them when they are preceded by a dot?
The matched text of :syn keyword can only be comprised of keyword characters; though that set can be configured (:setlocal iskeyword=...), it would be foolish to include whitespace in there.
You have two options: Either re-write all keywords with :syn match (which can include whitespace), or make all keywords contained and define a :syn region that only starts after whitespace.
Both are rather huge interventions that basically mean you're (re-)writing your own Python syntax. You haven't told us why you'd want that... I'd say it's a bad idea.
Is the reason you want to do this because you want to remind yourself of using a consistent style in Python?
If so, I would like to recommend you adding the syntastic plugin. In combination with a tool such as flake8 it automatically detects and highlights any style errors you wish (by default PEP8 style violations), together with general syntax errors. I use this plugin a lot and highly recommend it.

Vim improperly highlights "very magic" and "very nomagic" regular expressions

I'm editing a .vim syntax file in vim itself, and I'm using "very magic" and "very nomagic" regexes, simply because I think they make more sense. Unfortunately, vim does not in any way highlight these correctly. For example, this regex, using very nomagic:
/\V[/
should match an open bracket. Unfortunately, vim thinks this is an unterminated collection, and so it floods the file with purple highlighting until it finds the next ].
Is there any way to get vim to properly highlight these regular expression modes?
You'd have to override some of the default syntax/vim.vim syntax definitions (in ~/.vim/after/syntax/vim.vim), because the syntax doesn't consider this case, and assumes the default 'magic' regular expression syntax.
I guess the author of this syntax, Chip Campbell, didn't want to further complicate the (already quite large) syntax, and avoid the increased testing effort. It's certainly a good idea to ask him about including support for the \V / \M atoms, or whether he at least would accept a patch to include such an enhancement.

Treat macro arguments in Common Lisp as (case-sensitive) strings

(This is one of those things that seems like it should be so simple that I imagine there may be a better approach altogether)
I'm trying to define a macro (for CLISP) that accepts a variable number of arguments as symbols (which are then converted to case-sensitive strings).
(defmacro symbols-to-words (&body body)
`(join-words (mapcar #'symbol-name '(,#body))))
converts the symbols to uppercase strings, whereas
(defmacro symbols-to-words (&body body)
`(join-words (mapcar #'symbol-name '(|,#body|))))
treats ,#body as a single symbol, with no expansion.
Any ideas? I'm thinking there's probably a much easier way altogether.
The symbol names are uppercased during the reader step, which occurs before macroexpansion, and so there is nothing you can do with macros to affect that. You can globally set READTABLE-CASE, but that will affect all code, in particular you will have to write all standard symbols in uppercase in your source. There is also a '-modern' option for CLISP, which provides lowercased version for names of the standard library and sets the reader to be case-preserving, but it is itself non-standard. I have never used it myself so I am not sure what caveats actually apply.
The other way to control the reader is through reader macros. Common Lisp already has a reader macro implementing a syntax for case-sensitive strings: the double quote. It is hard to offer more advice without knowing why you are not just using it.
As Ramarren correctly says, the case of symbols is determined during read time. Not at macro expansion time.
Common Lisp has a syntax for specifying symbols without changing the case:
|This is a symbol| - using the vertical bar as multiple escape character.
and there is also a backslash - a single escape character:
CL-USER > 'foo\bar
|FOObAR|
Other options are:
using a different global readtable case
using a read macro which reads and preserves case
using a read macro which uses its own reader
Also note that a syntax for something like |,#body| (where body is spliced in) does not exist in Common Lisp. The splicing in does only work for lists - not symbol names. |, the vertical bar, surrounds character elements of a symbol. The explanation in the Common Lisp Hyperspec is a bit cryptic: Multiple Escape Characters.

Resources