Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

verilog-sk-* skeletons activated automatically as I type #1102

Closed
veripoolbot opened this issue Nov 5, 2016 · 8 comments
Closed

verilog-sk-* skeletons activated automatically as I type #1102

veripoolbot opened this issue Nov 5, 2016 · 8 comments

Comments

@veripoolbot
Copy link
Collaborator


Author Name: Slava Yuzhaninov
Original Redmine Issue: 1102 from https://www.veripool.org

Original Assignee: Slava Yuzhaninov


Hi.

When I code in verilog in Emacs, the verilog-mode +automatically+ expands various skeletons like loops, condition statements, etc. (part of Statements menu tab). The skeletons are great of course, but the problem is that they are expanded even if I'm in the middle of a comment. For example writing "for", "if", "case", "task" words leads to activation of the skeleton, breaking the typing process.

I didn't find a way to disable this automatic behaviour in the "Customise Verilog-mode" nor inside the verilog-mode.el itself. Any suggestions?

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Slava Yuzhaninov
Original Date: 2016-11-05T16:20:14Z


+After some investigation:+
It happens because these keywords are defined as part of @verilog-mode-abbrev-table@. I have a globally set @abbrev-mode@, thus verilog-mode inherits this variable and automatically evokes the corresponding skeletons. In my opinion, the summoning of the skeletons should be conditional, i.e. not part of a comment.

Tried to do something like that:

(verilog-define-abbrev verilog-mode-abbrev-table "if" "" (unless (inside-comment-q) 'verilog-sk-if))
</code>

Where @inside-comment-q@ is (seems to work fine):

(defun inside-comment-q ()
  (interactive)
  (let ((result (nth 4 (syntax-ppss))))
     (message "%s" result)
     result))
</code>

Didn't work... It's still evoking the skeleton.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2016-11-14T17:59:27Z


I can see how this would be useful. Alas the skeletons use the standard Emacs packages, rather than code in verilog-mode itself. I looked at a few modes and none seem to stop expansion on comments, nor could I find an easy way to provide this; all I could find was one forum post which showed a very complicated way which wouldn't be maintainable. If you find a way to cleanly solve this please let us know and we'll look at adding the code to verilog-mode. Sorry.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Slava Yuzhaninov
Original Date: 2016-12-24T19:42:32Z


Wilson Snyder wrote:

I can see how this would be useful. Alas the skeletons use the standard Emacs packages, rather than code in verilog-mode itself. I looked at a few modes and none seem to stop expansion on comments, nor could I find an easy way to provide this; all I could find was one forum post which showed a very complicated way which wouldn't be maintainable. If you find a way to cleanly solve this please let us know and we'll look at adding the code to verilog-mode. Sorry.

Hi.

I had some time to play a bit with the conditional skeleton expansion and I think that there is a reasonble solution:

  1. I modified the verilog-define-abbrev entry for example:
    ```(verilog-define-abbrev verilog-mode-abbrev-table "if" "" `context-abbrev-verilog-sk-if)
Instead of the former:
```<code class="clojure">(verilog-define-abbrev verilog-mode-abbrev-table "if" "" `verilog-sk-if)</code>
  1. Defined a contextual intermediate function context-abbrev-verilog-sk-if:
(defun context-abbrev-verilog-sk-if ()
  (if (or (inside-comment-q) (inside-string-q)) (unexpand-abbrev) (verilog-sk-if)))
</code>
``` which rolls back the abbreviation expansion if the position is inside a comment or inside a string, otherwise the expansion skeleton is called as before.



3. The *inside-comment-q* and *inside-string-q* functions are (referenced from @http://ergoemacs.org/emacs/elisp_determine_cursor_inside_string_or_comment.html@):

```<code class="clojure">
(defun inside-comment-q ()
  "Returns non-nil if inside comment, else nil. Result depends on syntax table's comment CHAR."
  (interactive)
  (let ((result (nth 4 (syntax-ppss)))) result))

(defun inside-string-q ()
  "Returns non-nil if inside string, else nil. Result depends syntax table's string quote CHAR."
  (interactive)
  (let ((result (nth 3 (syntax-ppss)))) result))
</code>
  1. The solution is not 100%, because the abbreviation rolling back disrupts the cursor position. Thus additional treatment to restore the old position is required. I guess that the LISP's dedicated save-excursion function could be used, but I'm not so great in LISP.

What do you think?
Thanks...

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2017-01-05T00:11:00Z


Seems a reasonable track.

Functions in verilog-mode have to start with verilog, so e.g. instead of context-abbrev-verilog-sk-if use verilog-context-abbrev-sk-if

You can try using verilog-inside-comment-or-string-p instead of the other functions, which should not move the point.

Please also make a new defvar, e.g. verilog-sk-inside-comments which is used inside your function to select if the function simply behaves as before (t), or checks for comments (nil). That way if something breaks it can be easily disabled.

If you get it all working, please put it into a patch file and I'll review and we can get it merged upstream, thanks for experimenting.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Slava Yuzhaninov
Original Date: 2017-01-28T23:22:32Z


Hi.

Here is my "primitive" version of the skeleton wrapper function, which works fine:

(defun verilog-context-abbrev-sk-if ()
  "Wrapper function for conditional `if keyword abreviation
  expansion, which ignored when the cursor is inside a
  comment/string."
  ;;  Save the last expanded abbreviation text, before nullified by the 'unexpand-abbrev function:
  (setq last-expand-abbrev-text-backup (symbol-value 'last-abbrev-text))
  (if (verilog-in-comment-or-string-p)
       ;; Inside a comment/string ==> Unreal source-code:
       (progn
         (unexpand-abbrev)                                       ;Roll back the abbreviation expansion
         (forward-char (length last-expand-abbrev-text-backup))) ;Correct cursor position
     ;; Real source-code:
     (verilog-sk-if)))
</code>

Few points:

  1. I used the verilog-mode built-in @verilog-in-comment-or-string-p@ function rather than new custom functions.
  2. All the functions (for each keyword) look almost the same, so maybe the wrapper function might be generalized to get the skeleton as an input argument.
  3. The relevant section of the modified code is attached as a verilog-context-abbrev-sk-patch.el file.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2017-02-09T22:18:12Z


If you'd like your patch merged in, could you please make your patch relative to the latest verilog-mode.el (from git or download here) and I'll try to merge it in.

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Slava Yuzhaninov
Original Date: 2017-02-10T17:40:11Z


Wilson Snyder wrote:

please make your patch relative to the latest verilog-mode.el (from git or download here) and I'll try to merge it in.

Here is the latest verilog-mode.el with the aforementioned additions

@veripoolbot
Copy link
Collaborator Author


Original Redmine Comment
Author Name: Wilson Snyder (@wsnyder)
Original Date: 2017-02-12T23:28:53Z


Fixed in git and verilog-mode-2017-02-12-224d7a2-vpo

Attached is the patch I cleaned up if it's historically valuable. But then I found out there was a global way to suppress expansion starting in Emacs 23.1 which is what it now calls. Sorry I didn't know about this earlier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant