zoukankan      html  css  js  c++  java
  • 用Emacs编写mybatis

    用Emacs编写mybatis

    用Emacs编写mybatis

    Table of Contents

    1 效果图

    screenshot_2017-12-16_22-01-27.png

    2 配置

    现在web开发,最流行的orm框架非mybatis莫属了,它功能强大,编写简单灵活,可以直接编写SQL,也可以添加条件控制。但是,正是因为mybatis采用xml作为结构语言,所以,难免会有大量的xml和sql混杂在一起的代码,对这些代码对语法高亮以及自动缩减就是一个问题。
    在Emacs中对xml有web-mode对其提供了非常好的支持,无论是缩进、跳转、剪切、拷贝、折叠等等操作都非常简单高效,远超各种IDE。对SQL也有很好的支持。但是对于mybatis却没有任何支持,用web-mode则sql无法高亮和缩进,用sql则基础xml结构缩减有问题。网上关于Emacs中编写mybatis的也甚少有涉及的,说明用Emacs来进行java开发的还是很少的。于是,只能本人自己思考解决方案了。
    我记得之前Purcell大神写了一个mmm-mode,说是可以把多个mode放到一起,不知是作何用,说不定可以让web-mode支持sql语句。于是就在package管理中安装了mmm-mode。然后,配置了web-mode中对sql-mode的支持:

    (mmm-add-classes
     '((web-sql-select :submode sql-mode
                       :front "<select[^>]*>[ 	]*
    " :back "[ 	]*</select>")
       (web-sql-insert :submode sql-mode
                       :front "<insert[^>]*>[ 	]*
    " :back "[ 	]*</insert>")
       (web-sql-update :submode sql-mode
                       :front "<update[^>]*>[ 	]*
    " :back "[ 	]*</update>")
       (web-sql-delete :submode sql-mode
                       :front "<delete[^>]*>[ 	]*
    " :back "[ 	]*</delete>")
       ))
    
    (mmm-add-mode-ext-class 'web-mode nil 'web-sql-select)
    (mmm-add-mode-ext-class 'web-mode nil 'web-sql-insert)
    (mmm-add-mode-ext-class 'web-mode nil 'web-sql-update)
    (mmm-add-mode-ext-class 'web-mode nil 'web-sql-delete)
    

    其实就是根据正则表达式来确定哪些代码是属于指定的submode的,对于mybatis中的sql语句而言,很简单就可以找出哪些是sql语句了。

    然后,比较难的是对齐,因为两种语言混杂在一起,用其中任一一种都有问题。经过仔细的思考和试验之后,发现一种配置是相对合理,且实现简单的:

    (defun mmm-indent-line-web-sql-submode ()
      (web-mode-propertize)
      (let (cur-type prev-type)
        (save-excursion
          (back-to-indentation)
          (setq cur-type (get-text-property (point) 'tag-type)))
        (save-excursion
          (previous-line)
          (back-to-indentation)
          (setq prev-type (get-text-property (point) 'tag-type)))
        (if (or
             (not (or prev-type cur-type))                   ; both lines sql
             (and (not prev-type) (eq cur-type 'start)) ; sql -> xml
             )
            (sql-indent-line)
          (web-mode-indent-line))))
    
    (defun mmm-indent-line-web-sql ()
      (interactive)
      (funcall
       (save-excursion
         (back-to-indentation)
         (mmm-update-submode-region)
         (if (and mmm-current-overlay
                  (> (overlay-end mmm-current-overlay) (point)))
             'mmm-indent-line-web-sql-submode
           'web-mode-indent-line))))
    
    (setq mmm-indent-line-function 'mmm-indent-line-web-sql)
    

    如此,只使用mmm-mode用来支持mybatis的话,再加上一些其他的小配置,比如更新之后自动刷新语法高亮等,就很简单了:

    (setq mmm-parse-when-idle t)
    (setq mmm-global-classes nil)
    (setq mmm-classes-alist nil)
    (setq mmm-mode-ext-classes-alist nil)
    

    总的配置,可以去我的github上查看,也可以直接拷贝下面的代码:

    ;;; init-mmm.el --- Summary
    ;;; Commentary:
    ;; comments
    
    ;;; Code:
    (use-package mmm-mode
      ;; :hook ((web-mode . mmm-mode))
      :commands mmm-mode
      :config
      (defun mmm-indent-line-web-sql-submode ()
        (web-mode-propertize)
        (let (cur-type prev-type)
          (save-excursion
            (back-to-indentation)
            (setq cur-type (get-text-property (point) 'tag-type)))
          (save-excursion
            (previous-line)
            (back-to-indentation)
            (setq prev-type (get-text-property (point) 'tag-type)))
          (if (or
               (not (or prev-type cur-type))                   ; both lines sql
               (and (not prev-type) (eq cur-type 'start)) ; sql -> xml
               )
              (sql-indent-line)
            (web-mode-indent-line))))
    
      (defun mmm-indent-line-web-sql ()
        (interactive)
        (funcall
         (save-excursion
           (back-to-indentation)
           (mmm-update-submode-region)
           (if (and mmm-current-overlay
                    (> (overlay-end mmm-current-overlay) (point)))
               'mmm-indent-line-web-sql-submode
             'web-mode-indent-line))))
    
      (setq mmm-parse-when-idle t)
      (setq mmm-global-classes nil)
      (setq mmm-classes-alist nil)
      (setq mmm-mode-ext-classes-alist nil)
      (setq mmm-indent-line-function 'mmm-indent-line-web-sql)
    
      (mmm-add-classes
       '((web-sql-select :submode sql-mode
                         :front "<select[^>]*>[ 	]*
    " :back "[ 	]*</select>")
         (web-sql-insert :submode sql-mode
                         :front "<insert[^>]*>[ 	]*
    " :back "[ 	]*</insert>")
         (web-sql-update :submode sql-mode
                         :front "<update[^>]*>[ 	]*
    " :back "[ 	]*</update>")
         (web-sql-delete :submode sql-mode
                         :front "<delete[^>]*>[ 	]*
    " :back "[ 	]*</delete>")
         ))
    
      (mmm-add-mode-ext-class 'web-mode nil 'web-sql-select)
      (mmm-add-mode-ext-class 'web-mode nil 'web-sql-insert)
      (mmm-add-mode-ext-class 'web-mode nil 'web-sql-update)
      (mmm-add-mode-ext-class 'web-mode nil 'web-sql-delete)
      )
    
    (provide 'init-mmm)
    ;;; init-mmm.el ends here
    

    Date: 2017-12-16 21:17

    Author: WEN YANG

    Created: 2017-12-16 Sat 22:02

    Emacs 25.3.1 (Org mode 8.2.10)

    Validate

  • 相关阅读:
    [NOIP2018]:旅行(数据加强版)(基环树+搜索+乱搞) HEOI
    关于微服务网关
    管理 API 时要问的关键问题
    如何构建成功的微服务架构
    后端老是不写接口文档?说自己很忙?
    Nginx配置文件详解
    Keepalived 高可用
    Jenkins 调用 Shell 脚本
    Supervisor
    Harbor高可用实现基于haproxy
  • 原文地址:https://www.cnblogs.com/yangwen0228/p/8047805.html
Copyright © 2011-2022 走看看