I want to make emacs indent ruby method calls like:
foo(
:blah => 'bar',
:shibby => 'baz'
)
The closest I can get is:
foo(
:blah => 'bar',
:shibby => 'baz'
)
This is using ruby-deep-indent-paren, ruby-deep-indent-paren-style, ruby-deep-arglist all set to nil.
Hashes indent how I like... if I could just make method calls indent like hashes I would be happy. Any ideas?
Dmitry Gutov has posted this fix, using advice, which seems to work:
(defadvice ruby-indent-line (after unindent-closing-paren activate)
(let ((column (current-column))
indent offset)
(save-excursion
(back-to-indentation)
(let ((state (syntax-ppss)))
(setq offset (- column (current-column)))
(when (and (eq (char-after) ?\))
(not (zerop (car state))))
(goto-char (cadr state))
(setq indent (current-indentation)))))
(when indent
(indent-line-to indent)
(when (> offset 0) (forward-char offset)))))
Ruby indentation in the current Emacs trunk (to be released as 24.4) works like you're asking without any additional tweaks.
I believe there is a key sequence like C-c o, that you could press with the cursor on that closing paren that would show what variable is used and let you type in a new value (like 0 or +). Try that!
Related
I'm trying to add completion at point for frame-local variables from backtrace-frames during invocations of read--expression by debugger-eval-expression or edebug-eval-expression.
I constructed the following completion table to add frame-local variables to the already available table for local elisp variables,
;; completion table for locals in current frame
(defvar my-backtrace-locals-completion-table
(completion-table-in-turn
(completion-table-dynamic
(lambda (_string)
(when-let* ((idx (backtrace-get-index)) ;backtrace.el
(frame (nth idx backtrace-frames)))
(backtrace-frame-locals frame)))
'do-switch-buffer)
elisp--local-variables-completion-table)) ;elisp-mode.el
which seems to work fine, eg. to reproduce
(1) evaluate
;; debug-on-error = t
(let ((my-local-var '(1 2))) (mapcan #'car this-local-var))
(2) from debugger's second frame, evaluate with eval-expression
(funcall my-backtrace-locals-completion-table "my-" nil t)
returns expected ("my-local-var").
The problem is following the above steps, but calling instead calling debugger-eval-expression doesn't work. The environment where the table is evaluated isn't finding a backtrace-frame (with or without do-switch-buffer).
How can I define the table to be evaluated in the proper buffer?
emacs v27.0.50
The completion table above doesn't quite return the expected candidates for debugger-eval-expression. The environment where the expression is evaluated has locals from frames higher than, but not including, the one at point in the Backtrace buffer.
So, the available locals should be only those from higher frames, eg.
(eval-when-compile (require 'dash))
(defvar my-backtrace-locals-completion-table
(completion-table-dynamic
(lambda (_string)
(when backtrace-frames
(--mapcat
(-some->> (backtrace-frame-locals it) (--map (car it)))
(nthcdr (1+ (backtrace-get-index)) backtrace-frames))))
'do-switch-buffer))
Then, redefining debugger-eval-expression's interactive spec to use the new locals table in place of the normal elisp table provides the correct completions (passing the 'do-switch-buffer arg completion-table-dynamic to find completions in the original buffer).
(defun my-backtrace#eval (orig-fn exp &optional nframe)
(interactive
(let ((elisp--local-variables-completion-table
my-backtrace-locals-completion-table))
(list (read--expression "[my] Eval in stack frame: "))))
(apply orig-fn (list exp nframe)))
(advice-add 'debugger-eval-expression :around #'my-backtrace#eval)
So I am trying to get a grip on Emacs 24.5 running on Mac Os 10.10.4.
I have a German keyboard and decided to keep the alt -key as Meta. As I still have to use it for some essential characters such as [ , | and } (resembling alt-5, alt-6 and alt-9) it decided to go with this solution:
(global-set-key "\M-5" (lambda () (interactive) (insert “[“)))
(global-set-key "\M-6" (lambda () (interactive) (insert “]”)))
(global-set-key "\M-7" (lambda () (interactive) (insert “|”)))
...
When I am enabling electric pair mode in the init-file with (electric-pair-mode 1) , it works just fine with ( ) and " ", but not with [ ], { } and ' '.
I then tried a different appraoch by using this code to swap the keys:
(defun redefine-key (key char)
(define-key function-key-map key char)
(global-unset-key key))
(redefine-key "\M-5" "[")
(redefine-key "\M-6" "]")
...
Interestingly, the pair feature now works for the square brackets [ ], but not the curly ones { }. Although the ' key on the German keyboard is not even related to the alt-key (it's accessed by the shift-key), it doesn't work at all. Same results for the autopair package, btw.
Please, anyone? Thanks so much!
The way electric-pair-mode works is by installing a callback function ("hook") called electric-pair-post-self-insert-function. As the name suggests, this hook gets invoked by Emacs after the function self-insert-command runs -- which is after you type a key.
And that's your problem here: calling insert is not the same as typing a key. It does not invoke self-insert-command and consequently, the above hook function never gets called. Even worse, you cannot simply invoke self-insert-command programmatically because, unlike insert, it doesn't take a parameter for the character to insert. You have to jump through hoops a bit, but you could try the following:
(global-set-key "\M-5" (lambda (&optional N) (interactive "P") (insert-as-self ?\[ N)))
(global-set-key "\M-6" (lambda (&optional N) (interactive "P") (insert-as-self ?\] N)))
(global-set-key "\M-7" (lambda (&optional N) (interactive "P") (insert-as-self ?\| N)))
(defun insert-as-self (CHAR N)
(let ((last-command-event CHAR)
(repeat (if N N 1)))
(self-insert-command repeat)))
Here, we locally set the special variable last-command-event to "fake" a key stroke before calling self-insert-command.
For curly braces and quotes to work, you have to do two things: First, add the respective (global-set-key ...) definitions to your .emacs file, similar to the ones above. Then let electric-pair-mode know that you want quotes and curlies to be handled by it by adding the following line to your .emacs file:
(setq electric-pair-pairs '((?\' . ?\') (?\" . ?\") (?\{ . ?\}))) –
Let's call this function "dynamic-define".
Basically I want to write a macro or lambda that works like this:
$ (dynamic-define "variable" 123)
$ variable
$ => 123
I tried it:
(define-syntax dynamic-define
(syntax-rules ()
((_ string <body>)
(eval `(define ,(string->symbol string) <body>)))))
and it works as expected but doesn't seem to be a good solution.
I tried to use without eval like this:
(define-syntax dynamic-define
(syntax-rules ()
((_ string <body>)
(define (string->symbol string) <body>))))
But when I try to use I get this error:
Error: invalid syntax (define (string->symbol "variable") 123)
What should I do?
(PLEASE: edit this question to fit native English and erase this line please)
You're running against a fundamental problem: you cannot do a real dynamic define in a "clean" way, hence your attempt using eval. Note that the two solutions above are both not dynamic -- all they give you is the ability to write "foo" instead of foo. As I said elsewhere, using eval is usually bad, and in this case it's worse since it's eval that is used from a macro which makes it very weird. This is in addition to having an implicit quasi-quote in your macro that makes things even more confusing. You could just as well define the whole thing as a plain function:
(define (dynamic-define string <body>)
(eval `(define ,(string->symbol string) ,<body>)))
If you really need this to work, then it's best to take a step back and think about what it is that you need, exactly. On one hand, the above solutions are not dynamic since they require using the macro with a string syntax
(dynamic-define "foo" 123) ; instead of (define foo 123)
but how would it look to have a real dynamic definition that takes in a string? You'd probably expect this to define b:
(define a "b")
(dynamic-define a 123)
but this only becomes more confusing when you consider how it interacts with other bindings. For example:
(define y 123)
(define (foo s)
(define x 456)
(dynamic-define s 789)
(+ x y))
Now, assuming that dynamic-define does what you want it to do, think about what you'd get with (foo "x") and (foo "y"). Worse, consider (foo "s") and (foo "+"). And even worse, what about
(foo (random-element '("x" "y" "s" "+" "define")))
? Clearly, if this dynamic-define really does some dynamic definition, then there is no sense that you can make of this code without knowing ahead of time what name foo will be called with. Without being able to make such sense, compilation goes out the window -- but much more importantly, correctness (or generally, the meaning of your code) dies.
In my experience, this kind of pattern is much better handled with hash tables and similar devices.
using define-macro
#> (define-macro (dynamic-define varstr val)
`(define ,(string->symbol varstr) ,val))
#> (dynamic-define "variable" 123)
#> variable
123
using syntax-case
#> (define-syntax dynamic-define
(lambda (stx)
(syntax-case stx ()
((k varstr val)
(with-syntax ([var (datum->syntax-object
#'k
(string->symbol (syntax-object->datum #'varstr)))])
#'(define var val))))))
#> (dynamic-define "variable" 123)
#> variable
123
How could I use the sort-regexp-fields to emulate the sort-numeric-fields. I tried like this:
123
345
90
80
1999
M-x sort-regexp-fields
Regexp specifying records to sort: \ ([0-9]+\)
Regexp specifying key within record: \, \#1
But it can’t work.
what I really want to sort is something like this:
foo index: 123
index: 345 boo
…
the question is: I want to sort the lines by the number after the word “index”, but the number is not in the same field, they just have a word “index” before it. what should I do to complete this? anybody can help me?
sort-regexp-fields doesn't do lexicographical compare, and there's no trivial way to get it to do that. That said, we can use a trick of defining our own command, and using that command to signal to some advice to shoe-horn in a lexicographical compare.
The following command does what you want, provided you mark the region around the lines you want to compare:
(defun my-line-sort (begin end)
(interactive "r")
(sort-regexp-fields nil "^.*: +\\([0-9]+\\).*$" "\\1" begin end))
(defun compare-buffer-substrings-lexigraphically (b1 b2)
(< (string-to-number (buffer-substring-no-properties (car b1) (cdr b1)))
(string-to-number (buffer-substring-no-properties (car b2) (cdr b2)))))
(defadvice sort-subr (before sort-subr-lexical-compare activate)
"In special case, force predicate to be a lexical compare"
(when (eq this-command 'my-line-sort)
(ad-set-arg 5 'compare-buffer-substrings-lexigraphically)))
If I understand your situation correctly, this will do what you want:
M-xsort-regexp-fieldsRETindex: \([0-9]+\)RET\1RET
probably an easy question: I want to wrap the "(format ..)" function of Scheme in order to handle my debugging output (including the wrapping of the format-string).
As "format" takes a variable number of arguments my wrapper would need to do that too yielding the question on how I tell scheme to have an ellipsis-parameter and how to reference it.
I thought of something like this:
(define debugPrint
(lambda (formatString ELLIPSIS_PARAMETER)
(if debug
(format #t (string-append "<!--" formatString "-->") ELLIPSIS_PARAMETER)
()
)
)
)
Thank You for your help in advance!
There is dot notation for this:
(define (debugPrint formatString . params)
(if debug
(apply format #t (string-append "<!--" formatString "-->") params)
'()))
Take note on apply as dot notation wraps all parameters in list and when you use (debugPrint "~a: ~a" key name), the formatString will be bound to "~a: ~a" and params will be bound to (key name) (sure the values of key and name, not symbols ;).