Emacs' align fails in plsql-mode - emacs

I've been using a PL/SQL mode available on EmacsWiki and I have been a rather happy with it.
But when I try to align or align-current I just get an error:
align: Wrong type argument: sequencep, plsql-align-rules-list
Example code that I'm trying to align:
declare
foo number;
x number;
y number;
begin
foo := 5;
x := 123;
y:=123;
end;
The expected outcome is:
declare
foo number;
x number;
y number;
begin
foo := 5;
x := 123;
y := 123;
end;
Here is the relevant (I hope) part of the plsql-mode's code:
;;;_ + Align
;; Should I make so that anything that is highlighted will line up?
;; Should we make a block anything inside ()?
(eval-and-compile
(defcustom plsql-align-rules-list '() ""
:group 'plsql
:type 'align-rules-list-type)
;; Should I make so that anything that is highlighted will line up?
;; Should we make a block anything inside ()?
(when (condition-case nil
(require 'align)
(error nil))
;; these are way too slow to use with indent before aligning
(unless (and plsql-align-rules-list plsql-debug)
(setq plsql-align-rules-list
'(
(plsql-assignment
(regexp . "\\(\\s-*\\):=\\(\\s-*\\)")
(group . (1 2))
(modes . '(plsql-mode))
(repeat t)
(tab-stop . nil))
(plsql-arrorw
(regexp . "\\(\\s-*\\)=>\\(\\s-*\\)")
(group . (1 2))
(modes . '(plsql-mode))
(repeat t)
(tab-stop . nil))
(plsql-equals ;; exclude the previous two cases
(regexp . "\\(\\s-*[^:]\\)=\\([^>]\\s-*\\)")
(group . (1 2))
(repeat t)
(tab-stop . nil)
(modes . '(plsql-mode)))
(plsql-operator ;; watch out for comments
(regexp . "\\(\\s-*\\)[-+/]{1}\\(\\s-*\\)")
(group . (1 2))
(repeat t)
(tab-stop . nil)
(modes . '(plsql-mode)))
(plsql-keywords
(regexp . "\\(\\s-+\\)\\(in\\|default\\|number\\|varchar2\\|blob\\|raw\\)\\b")
(group 1)
(repeat t)
(case-fold t)
(tab-stop . nil)
(modes . '(plsql-mode)))
)
))
(put 'plsql-align-rules-list 'risky-local-variable t)
(add-to-list 'align-c++-modes 'plsql-mode) ;; eg expression functions ...
(add-to-list 'align-sq-string-modes 'plsql-mode)
(add-to-list 'align-open-comment-modes 'plsql-mode)
;; Should we re-bind new-line-and-indent to align the current
;; region? That sounds expensive.
))
And later in defun plsql-mode ():
(set (make-local-variable 'align-mode-rules-list) 'plsql-align-rules-list)
How the plsql-mode should be modified to get align working ? My best work-around so far is to use align-regexp (inspired by this answer):
(defun my-align ()
""
(interactive)
(align-regexp
(region-beginning) (region-end)
"\\(\\s-*\\):=" 1 1 nil))
This is fine except it doesn't modify the right-hand side.
The author doesn't use the mode anymore. I'm using emacs 23.2.1.

As far as I can understand it, the function plsql-mode should contain:
(set (make-local-variable 'indent-line-function) 'plsql-indent)
(set (make-local-variable 'indent-region-function) 'plsql-indent-region)
(set (make-local-variable 'align-mode-rules-list) plsql-align-rules-list)
Since the first two buffer local variables are indeed references to functions, their argument should be a quoted symbol.
Since the third one should use the value contained in the variable plsql-align-rules-list, this variable should NOT be quoted.
HTH
)jack(

Related

Context-sensitive font-locking in emacs

Basically, I'm trying to syntax highlight the following piece of coffeescript code the way I want it. Explanation of the syntax of coffeescript functions can be found here.
nameHere = (tstamp, moo, boo) ->
...
The names tstamp, moo and boo should be colored pink (and nothing else, not the commas and not the brackets) because they are parameters to a lambda function.
highOrderFun ((x) -> x * x) someList
Here it is the first x that is the parameter. Parameters can have default arguments:
class Foo
meth: (msg = "Hello", bar = "foo") ->
....
Default arguments can be variables themselves:
defColor = "red"
print = (msg, color = defColor) ->
...
So msg and color above should be highlighted, but not defColor. An even trickier case is functions with default arguments that themselves are functions. I think that is to hard for emacs' font-lock to highlight correctly, but I'm including it anyway:
funTakingFuns = (f1 = ((a, b) -> a*b), f2 = ((c, d) -> c/d)) ->
...
This appears to be pretty complicated to achieve in emacs because you want the highlighting to be context sensitive. I've read up on the documentation on font-lock but haven't been able to figure it out.
I'd be grateful if someone could show me what to set font-lock-defaults to make it syntax highlight the way I want it.
Update Showing more coffeescript syntax examples.
font-lock-keywords allows function values in the MATCHER field:
where MATCHER can be either the regexp to search for, or the function name to
call to make the search (called with one argument, the limit of the search;
it should return non-nil, move point, and set match-data appropriately if
it succeeds; like re-search-forward would).
So we need to write a function that would search for the next function argument in the buffer.
Something like this:
(defun coffee-match-next-argument (limit)
(let ((start (point)))
;; Look for the arrow.
(when (re-search-forward ") *->" limit t)
;; Save the position of the closing paren.
(let ((stop (point)))
(goto-char (match-beginning 0))
;; Go to the opening paren.
(goto-char (nth 1 (syntax-ppss)))
;; If we're before our initial position, go forward.
;; We don't want to find the same symbols again.
(when (> start (point))
(goto-char start))
;; Look for the next symbol until the arrow.
(or (re-search-forward "\\((\\|,\\) *\\(\\(\\sw\\|_\\)+\\)" stop 'mv)
(coffee-match-next-argument limit))))))
And the setup, to use with existing coffee-mode:
(font-lock-add-keywords
'coffee-mode
'((coffee-match-next-argument 2 font-lock-variable-name-face)))
You can also use this in font-lock-defaults, of course.
This will likely use some other color than pink, but that's easy to change.
This is more kind of a hack, it's far from optimal (as I am not familiar at all with coffeescript), but perhaps with a little tweaking yourself, you can get this done.
All the ingredients are there.
The triggering of the commands/functions are based on the assumption that you use coffee-mode.
If you do not, this is not a big trouble, you'll just have to hook these things differently.
Put the following line in your .emacs:
(eval-after-load 'coffee '(load "/PATH/custom-coffee-font-lock.el"))
You can just save the below text as a file, and it will:
(1) Font lock when you trigger coffee-mode
(2) Font lock current line when you type the ">" as part of "->"
(3) Allow to font-lock the buffer by running M-x coffee-init-font-lock
;;;; custom-coffee-font-lock
;; Firstly, create a new font for this.
(make-face 'font-lock-coffeescript-face)
(set-face-foreground 'font-lock-coffeescript-face "pink")
;; Next, one function that should be ran after a file is identified as
;; a coffeescript file. It will do the font-locking you want on
;; the whole buffer. It is also possible to run it manually.
(defun coffee-init-font-lock ()
(interactive)
(save-excursion
(goto-char 1)
(while (search-forward-regexp "=.+->" nil t)
(search-backward-regexp "(")
(forward-char 1)
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp ")" nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(move-end-of-line 1)))
)
;; This actually runs that function.
(coffee-init-font-lock)
;; This advice will be ran everytime you write something. It will check
;; whether "->" is before it, so when you type the final ">", it will
;; do the font locking for the current line (it also checks for your mode).
(defadvice self-insert-command (after coffee-font-lock activate)
(when (and (looking-back "->") (eq major-mode 'coffee-mode))
(save-excursion
(search-backward-regexp "(")
(forward-char 1)
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp "," nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))
(add-text-properties
(point) (- (search-forward-regexp ")" nil nil) 1)
'(font-lock-face font-lock-coffeescript-face))))
)
(provide 'custom-coffee-font-lock)
;;; custom-coffee-font-lock.el
If you have any requests, let me know. Like I said, I do not use CoffeeScript, so this might throw huge errors your way. At the very least it should help with some basic ideas.
Result:

Emacs cond, possible to have things happen between clauses?

I programmed some months ago some code with a lot of if statements. If region-active-p, if beginning-of-line, those kind of things.
Having learned about the cond lisp, I was wondering if I could improve my code a lot.
The problem is that this cond is only doing things when "true" as far as I see it, while I actually need the move back-to-indentation in between these checks.
In order to properly skip the last clause, I even have to set variable values.
(defun uncomment-mode-specific ()
"Uncomment region OR uncomment beginning of line comment OR uncomment end"
(interactive)
(let ((scvar 0) (scskipvar 0))
(save-excursion
(if (region-active-p)
(progn (uncomment-region (region-beginning) (region-end))
(setq scskipvar 1))
(back-to-indentation)) ; this is that "else" part that doesn't fit in cond
(while (string= (byte-to-string (following-char)) comment-start)
(delete-char 1)
(setq scskipvar 1))
(indent-for-tab-command)
(when (= scskipvar 0)
(search-forward comment-start nil t)
(backward-char 1)
(kill-line))
)))
)
So basically my question is, I would kind of like to have some consequences of not giving "true" to a clause, before the check of another clause. Is this possible? If not, what would be the best thing to do?
EDIT: Since we are using this as the example case for a solution, I wrote it down so it is easier to understand.
If region is active, remove comments from region. If not, move point to intendation.
For as long as the following character is a comment character, delete it. Afterwards, indent this line.
If it didn't do any of the above, search forward for a comment character, and kill that line.
(defun delete-on-this-line (regex)
(replace-regexp regex "" nil (line-beginning-position) (line-end-position)))
(defun delete-leading-comment-chars ()
(delete-on-this-line (eval `(rx bol (* space) (group (+ ,comment-start))))))
(defun delete-trailing-comment-chars ()
(delete-on-this-line (eval `(rx (group (+ ,comment-end)) (* space) eol))))
(defun delete-trailing-comment ()
(delete-on-this-line (eval `(rx (group (+ ,comment-start) (* anything) eol)))))
(defun uncomment-dwim ()
(interactive)
(save-excursion
(if (region-active-p)
(uncomment-region (region-beginning) (region-end))
(or (delete-leading-comment-chars)
(delete-trailing-comment-chars)
(delete-trailing-comment)))))
Edit: A little explanation:
It's a lot easier to do regex replacements than manage loops to do deletion, so that gets rid of the state. And the steps are all mutually exclusive, so you can just use or for each option.
The rx macro is a little DSL that compiles down to valid regexes, and it's also amenable to lispy syntax transforms, so I can dynamically build a regex using the comment chars for the current mode.
(defmacro fcond (&rest body)
(labels ((%substitute-last-or-fail
(new old seq)
(loop for elt on seq
nconc
(if (eql (car elt) old)
(when (cdr elt)
(error "`%S' must be the last experssion in the clause"
(car elt)))
(list new)
(list (car elt))))))
(loop with matched = (gensym)
with catcher = (gensym)
for (head . rest) in body
collect
`(when (or ,head ,matched)
(setq ,matched t)
,#(%substitute-last-or-fail `(throw ',catcher nil) 'return rest))
into clauses
finally
(return `(let (,matched) (catch ',catcher ,#clauses))))))
(macroexpand '(fcond
((= 1 2) (message "1 = 2"))
((= 1 1) (message "1 = 1"))
((= 1 3) (message "1 = 3") return)
((= 1 4) (message "1 = 4"))))
(let (G36434)
(catch (quote G36435)
(when (or (= 1 2) G36434)
(setq G36434 t)
(message "1 = 2"))
(when (or (= 1 1) G36434)
(setq G36434 t)
(message "1 = 1"))
(when (or (= 1 3) G36434)
(setq G36434 t)
(message "1 = 3")
(throw (quote G36435) nil))
(when (or (= 1 4) G36434)
(setq G36434 t)
(message "1 = 4"))))
Here's something quick to do, what I think you may be after, i.e. something that would mimic the behaviour switch in C.
The idea is that all clauses are tested sequentially for equality, and if one matches, then all following clauses are executed, until the return keyword (it would be break in C, but Lisp uses return for the similar purpose in the loop, so I thought that return would be better). The code above thus will print:
1 = 1
1 = 3
Technically, this is not how switch works in C, but it will produce the same effect.
One thing I did here for simplicity, which you want to avoid / solve differently - the use of return keyword, you probably want to impose stricter rules on how it should be searched for.
cond
Cond evaluates a series of conditions in a list, each item in a list can be a condition, and then executable instructions.
The example in the Emacs Lisp manual is adequate to demonstrate how it works, I've annotated it here to help you understand how it works.
(cond ((numberp x) x) ;; is x a number? return x
((stringp x) x) ;; is x a string? return x
((bufferp x) ;; is x a buffer?
(setq temporary-hack x) ;; set temporary-hack to buffer x
(buffer-name x)) ;; return the buffer-name for buffer x
((symbolp x) (symbol-value x))) ;; is x a symbol? return the value of x
Each part of the condition can be evaluated any way you like, the fact x above is in each condition is coincidental.
For example:
(cond ((eq 1 2) "Omg equality borked!") ;; Will never be true
(t "default")) ;; always true
So comparisons with switch are a bit limited, it's essentially a list of if statements, that executes/returns the first true condition's body list.
Hopefully this helps you understand cond a bit better.
(cond (condition body ... ) ;; execute body of 1st passing
(condition body ... ) ;; condition and return result
(condition body ... ) ;; of the final evaluation.
;; etc
)
OR
You can do things similar to switch with OR, depending on how you structure the code.
This isn't functional style, because it relies on side-effects to do what you want, then returns a boolean value for flow control, here's an example in pseudo lisp.
(or)
(or
(lambda() (do something)
(evaluate t or nil) ; nil to continue; t to quit.
)
(lambda() (do something)
(evaluate t or nil) ; nil to continue; t to quit.
)
(lambda() (do something)
(evaluate t or nil) ; nil to continue; t to quit.
)
(lambda() (do something)
(evaluate t or nil) ; nil to continue; t to quit.
)
)
Here's working example of a switch like structure using or
(or
(when (= 1 1)
(progn
(insert "hello\n")
nil))
(when (= 1 2) ;; condition fails.
(progn
(insert "hello\n")
nil)) ;; returns false (nil)
(when (= 1 1)
(progn
(insert "hello\n")
t)) ;; returns true, so we bail.
(when (= 1 1)
(progn
(insert "hello\n")
nil))
)
Inserts :
hello
hello
(and)
The and operator (not just in Lisp) is also very useful, instead of evaluating everything until true, it evaluates conditions that are true, until a false is evaluated.
Both or & and can be used to build useful logic trees.
This is how I did it now according to Chris' idea that breaking it down into seperate functions would make it easier.
EDIT: Now also applied the or knowledge gained in this thread gained from Slomojo (no more variables!)
(defun sc-uncomment ()
(interactive)
(or
(if (region-active-p)
(uncomment-region (region-beginning) (region-end))
(back-to-indentation)
nil)
(if (string= (byte-to-string (following-char)) comment-start)
(sc-check-start)
(sc-end))))
(defun sc-check-start ()
(interactive)
(while (string= (byte-to-string (following-char)) comment-start)
(delete-char 1))
)
(defun sc-end ()
(interactive)
(search-forward comment-start nil t)
(backward-char 1)
(kill-line))
)

define your own tag in org-mode

There are Tags as in #+AUTHOR or #+LATEX in org-mode - are they called tags? I'd like to define my own tag which calls a function to preprocess the data and then outputs it - if the export target is LaTeX.
My solution was defining an own language, qtree, for SRC blocks.
#+BEGIN_SRC qtree
[.CP [.TP [.NP [] [.N' [.N Syntax] []]] [.VP [] [.V' [.V sucks] []]]]]
#+END_SRC
And process it accordingly. I even added a qtree-mode with paredit.
And a landscape parameter if the trees grow big. https://github.com/Tass/emacs-starter-kit/blob/master/vendor/assorted/org-babel-qtree.el
(require 'org)
(defun org-babel-execute:qtree (body params)
"Reformat a block of lisp-edited tree to one tikz-qtree likes."
(let (( tree
(concat "\\begin{tikzpicture}
\\tikzset{every tree node/.style={align=center, anchor=north}}
\\Tree "
(replace-regexp-in-string
" \\_<\\w+\\_>" (lambda (x) (concat "\\\\\\\\" (substring x 1)))
(replace-regexp-in-string
(regexp-quote "]") " ]" ; qtree needs a space
; before every closing
; bracket.
(replace-regexp-in-string
(regexp-quote "[]") "[.{}]" body)) ; empty leaf
; nodes, see
; http://tex.stackexchange.com/questions/75915
) ; For
; http://tex.stackexchange.com/questions/75217
"\n\\end{tikzpicture}"
)))
(if (assoc :landscape params)
(concat "\\begin{landscape}\n" tree "\n\\end{landscape}")
tree)))
(setq org-babel-default-header-args:qtree '((:results . "latex") (:exports . "results")))
(add-to-list 'org-src-lang-modes '("qtree" . qtree))
(define-generic-mode
'qtree-mode ;; name of the mode to create
'("%") ;; comments start with '%'
'() ;; no keywords
'(("[." . 'font-lock-operator) ;; some operators
("]" . 'font-lock-operator))
'() ;; files for which to activate this mode
'(paredit-mode) ;; other functions to call
"A mode for qtree edits" ;; doc string for this mode
)
They seem to be called keywords for in-buffer settings no more. Whatever they're called, they don't seem to be user-definable.
What you want to do is extremely related to a common way of handling whereas to export with xelatex or pdflatex as described on Worg.
The relevant part would be :
;; Originally taken from Bruno Tavernier: http://thread.gmane.org/gmane.emacs.orgmode/31150/focus=31432
(defun my-auto-tex-cmd ()
(if (string-match "YOUR_TAG: value1" (buffer-string))
(do something))
(if (string-match "YOUR_TAG: value2" (buffer-string))
(do something else))
(add-hook 'org-export-latex-after-initial-vars-hook 'my-auto-tex-cmd)

emacs query-replace-regexp inverted

Is there an existing package that targets subexps for replacement during
query-replace-regexp?
For example given the following
var foo1 = blah( properties, property_id);
var foo2 = blah(properties, property_id );
var foo3 = blah( properties, property_id );
I want to remove the padding around braces.
Normally, the way is to subgroup the bits you want to keep and assemble a replacement.
search:
\(var .* = blah\s-*(\)\s-*\(.*?\)\s-*\()\)
replace:
\1\2\3
However, it seems much easier to some up with a regexp that groups the bits I
want to delete than the otherway around. Like this one:
var .* = blah\s-*(\(\s-*\).*?\(\s-*\))
I'll get two subgroups out of this. How can I target them for replacement?
EDIT: I'm asking for an interactive way to "invert" the given regexp. So the interface would be similar to query-replace-regexp
enter regexp
enter replacement for group 1
enter replacement for group 2
I think some variation of this should work:
(defun remove-padding ()
(interactive)
(while (search-forward-regexp
"var .* = [a-zA-Z_]+\\s-*(\\(\\s-*\\).*?\\(\\s-*\\))"
nil t)
;; Replace the 2 subexpressions with nothing
(replace-match "" nil t nil 2)
(replace-match "" nil t nil 1)))
However, you might also consider using a tool like indent depending on what your use cases are.
EDIT: Below is a very minimal interactive version. The function query-replace-regexp is very complex and I have made no attempt to reproduce all of it's functionality.
(require 're-builder)
(defun query-replace-subexpressions (regexp replacements)
"REPLACEMENTS need to be in reverse order if passed from lisp!"
;; Read the correct number of subexpressions
(interactive
(let* ((re (read-from-minibuffer "Query replace subexps: "))
(num-subexps (reb-count-subexps re))
(replacement-list nil)
(replacements (dotimes (rep num-subexps)
(setq replacement-list
(cons
(read-from-minibuffer
(format "Replace subexpression %s with: " rep))
replacement-list)))))
(list re replacement-list)))
;; Search
(let ((len (length replacements)))
(while (search-forward-regexp regexp nil t)
(replace-highlight (match-beginning 0) (match-end 0)
(point-min) (point-max) regexp
t case-fold-search)
;; Query
(when (save-match-data (y-or-n-p "Replace this occurrence? "))
;; Make all the replacements
(dotimes (i len)
(replace-match (nth i replacements) nil nil nil (- len i)))))
(replace-dehighlight)))
;; Test it out below
(query-replace-subexpressions
"var .* = [a-zA-Z_]+\\s-*(\\(\\s-*\\).*?\\(\\s-*\\))"
'("" ""))
var foo1 = blah(properties, property_id );
var foo2 = blah (properties, property_id );
var foo3 = blah( properties, property_id );
I've made it hooking into query-replace-regexp on github
Here is a paste in case of link rot:
;; -*- lexical-binding: t -*-
(provide inverted-replace)
(require 're-builder)
(require 'parallel-replace)
(defun inverted-replace-generate-replacement (from to)
"invert result of current match (match-string 0)"
(let ((string (match-string 0))
(count (reb-count-subexps from))
(replacements (parallel-replace-read-list to)))
(save-match-data
(string-match from string)
(dotimes (i count)
(setq string (replace-match (nth i replacements) nil nil string (- count i)))))
string))
(defun inverted-replace-regexp (from to)
(interactive (destructuring-bind (from to _)
(query-replace-read-args "inverted-replace-regexp: " t)
(list from to)))
(query-replace-regexp from
(quote (replace-eval-replacement
replace-quote
(inverted-replace-generate-replacement from to)))
nil (and (and transient-mark-mode mark-active)
(region-beginning))
(and (and transient-mark-mode mark-active) (region-end))))

macro for making a template

I am new to emacs and trying to figure out if there is an "easy" way to write a macro that will create a template for a standard function specification (see lines with # below). For example, I would like to execute a command to extract the input and output variables and place them in this standard format above the function (using the R language):
#This function does something
#Input:
# var1 - h
# var2 -
# var3 -
# var4 -
# Output:
# myoutput -
MyFunction <- function(var1,var2,var3=13,var4=NULL){
...
...
return(myoutput)
}
I don't know R so I'm just guessing how it looks from your one example. Add this to your Emacs init file (and evaluate it or restart), go to a function definition line and M-x my-r-insert-function-template:
(defun my-r-insert-function-template ()
"Insert a function template."
(interactive)
(let (name inputs output pos)
(beginning-of-line)
(save-excursion
(when (re-search-forward "\\([a-zA-Z0-9_\\.]+\\)\\s-*<-\\s-*function\\s-*(" nil t)
(setq name (match-string-no-properties 1))
(backward-char)
(forward-sexp)
(setq pos (1- (point)))
(backward-sexp)
(while (re-search-forward "[a-zA-Z0-9_\\.]+" pos 'go)
(push (match-string-no-properties 0) inputs)
(search-forward "," pos 'go))
(search-forward "{")
(setq pos (point))
(backward-char)
(forward-sexp)
(when (re-search-backward "return\\s-*(\\s-*\\([a-zA-Z0-9\\.]+\\)" pos t)
(setq output (match-string-no-properties 1)))))
(when name
(insert "# " name " : This function does something\n")
(when inputs
(insert "# Input:\n")
(setq inputs (nreverse inputs))
(dolist (input inputs)
(insert "# " input " -\n")))
(when output
(insert "# Output:\n")
(insert "# " output " -\n")))))
I don't use R but it looks like ESSr-autoyas could be used to do what you want. It makes use of YASnippet (a template package for Emacs).