config

Personal configuration.
git clone git://code.dwrz.net/config
Log | Files | Refs

sql-indent-left.el (12306B)


      1 ;;; sql-indent-left.el --- configuration options to indent sql -*- lexical-binding: t -*-
      2 
      3 ;; Copyright (C) 2017  Free Software Foundation, Inc
      4 
      5 ;; Filename: sql-indent-left.el
      6 ;; Description:
      7 ;; Author: pierre.techoueyres@free.fr
      8 ;; Maintainer: pierre.techoueyres@free.fr
      9 ;; Created:
     10 ;; Version: pierre.techoueyres@free.fr
     11 ;; Last-Updated:
     12 ;;           By:
     13 ;;     Update #: 0
     14 ;; URL:
     15 ;; Keywords: language sql indentation
     16 ;; Compatibility:
     17 ;;
     18 ;; Features that might be required by this library:
     19 ;;
     20 ;;   None
     21 
     22 ;; This program is free software; you can redistribute it and/or modify
     23 ;; it under the terms of the GNU General Public License as published by
     24 ;; the Free Software Foundation; either version 3 of the License, or
     25 ;; (at your option) any later version.
     26 ;;
     27 ;; This program is distributed in the hope that it will be useful,
     28 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     29 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     30 ;; GNU General Public License for more details.
     31 ;;
     32 ;; You should have received a copy of the GNU General Public License
     33 ;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.
     34 
     35 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     36 ;;
     37 ;;; Commentary:
     38 ;;
     39 ;; Set configuration options to indent sql my way.
     40 ;;
     41 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     42 ;;
     43 ;;; Change log:
     44 ;;
     45 ;;
     46 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     47 ;;
     48 ;; This program is free software; you can redistribute it and/or
     49 ;; modify it under the terms of the GNU General Public License as
     50 ;; published by the Free Software Foundation; either version 3, or
     51 ;; (at your option) any later version.
     52 ;;
     53 ;; This program is distributed in the hope that it will be useful,
     54 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
     55 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     56 ;; General Public License for more details.
     57 ;;
     58 ;; You should have received a copy of the GNU General Public License
     59 ;; along with this program; see the file COPYING.  If not, write to
     60 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth
     61 ;; Floor, Boston, MA 02110-1301, USA.
     62 ;;
     63 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     64 ;;
     65 ;;; Code:
     66 
     67 (require 'sql-indent)
     68 
     69 (defun indent-case-statement-items (syntax base-indentation)
     70   "Look for a SYNTAX of ((block-start when) (in-block case \"\") ...)
     71 or ((block-start else) (in-block case \"\") ...)."
     72   (let ((outer (sqlind-outer-context syntax)))
     73     (if (and (eq 'in-block (sqlind-syntax-symbol outer))
     74              (eq 'case (sqlind-syntax-keyword outer))
     75              (eq 'block-start (sqlind-syntax-symbol syntax))
     76              (memq (sqlind-syntax-keyword syntax) '(when else)))
     77         (+ base-indentation sqlind-basic-offset)
     78       base-indentation)))
     79 
     80 (defvar sqlind-indentation-right-offsets-alist
     81   `((select-column-continuation sqlind-indent-select-column
     82                                 sqlind-adjust-operator
     83                                 sqlind-lone-semicolon)
     84     (in-select-clause sqlind-lineup-to-clause-end
     85                       sqlind-adjust-operator
     86 		      sqlind-right-justify-logical-operator
     87 		      sqlind-lone-semicolon)
     88     (in-delete-clause sqlind-lineup-to-clause-end
     89                       sqlind-adjust-operator
     90 		      sqlind-right-justify-logical-operator
     91 		      sqlind-lone-semicolon)
     92     (in-insert-clause sqlind-lineup-to-clause-end
     93                       sqlind-adjust-operator
     94 		      sqlind-right-justify-logical-operator
     95 		      sqlind-lone-semicolon)
     96     (in-update-clause sqlind-lineup-to-clause-end
     97                       sqlind-adjust-operator
     98 		      sqlind-right-justify-logical-operator
     99 		      sqlind-lone-semicolon)
    100     ;; mandatory
    101     (select-table-continuation sqlind-indent-select-table +
    102                                sqlind-lone-semicolon)
    103     ;; rest picked up from the original indentation offsets
    104     ,@sqlind-default-indentation-offsets-alist)
    105   "Align sql code like this :
    106 
    107 clear columns
    108 set linesize 2500
    109 set trimout on trimspool on
    110 
    111 select atc.column_name,
    112        atc.data_type,
    113        data_length,
    114        data_precision,
    115        nullable,
    116        data_scale,
    117        nvl(substr(comments, 1, 100), atc.column_name) comments
    118   from   all_tab_columns atc,
    119          all_col_comments acc
    120  where  atc.owner       = acc.owner
    121     and    atc.table_name  = acc.table_name
    122     and    atc.column_name = acc.column_name
    123     and    atc.owner       = user
    124     and    atc.table_name  = 'MY_TABLE'
    125     and    atc.column_name = p_column_name
    126     and    not exists (select 1
    127                          from   all_tab_columns atc1,
    128                                 all_col_comments acc1
    129                         where  atc1.owner       = acc1.owner
    130                            and    atc1.table_name  = acc1.table_name
    131                            and    atc1.column_name = acc1.column_name
    132                            and    atc1.owner       = atc.owner
    133                            and    atc1.table_name  = atc.table_name
    134                            and    acc1.column_name = acc.column_name)
    135  ;
    136 
    137 delete from my_table mt
    138  where col_1 = v_col1
    139    and  (   col_2 = v_col2
    140          or col_3 = v_col3)
    141    and   col_42 = '42'
    142  ;
    143 
    144 update my_table
    145    set    col1_has_a_long_name = value1,
    146           col2_is_short        = value2
    147  where cond1 is not null
    148    and  (   col_2 = v_col2
    149          or col_3 = v_col3)
    150    and   col_42 = '42'
    151  ;
    152 
    153 insert into xyzxx
    154           ( aaa, xxx, bbb, ccc,
    155           ddd, eee, fff, ggg,
    156           hhh )
    157 select aaa,
    158        xxx,
    159        max (m.b1) as bbb,
    160        min (m.b1) as ccc,
    161        coalesce (max (n.c2), 0)  as ddd,
    162        coalesce (min (n.c2), 0)  as eee,
    163        max (m.b1) over ( partition by c2
    164                         order by aaa desc ) as fff,
    165        min (m.b1) over ( partition by c2
    166                         order by aaa desc ) as ggg,
    167        avg (n.c2) as hhh
    168   from  (select * from (select aaa,
    169                                jjj + kkk  as b1,
    170                                row_number () over ( partition by qqq
    171                                                    order by rrr,
    172                                                    sss ) as rn
    173                           from mno)
    174           where rn = 1) m
    175           inner join (select aaa,
    176                              nnn + ooo as c2
    177                         from   pqr) n
    178           using (aaa),
    179  group by aaa,
    180           xxx
    181  order by xxx desc,
    182           aaa asc
    183  ;")
    184 
    185 (defvar sqlind-indentation-left-offsets-alist
    186   `((select-clause 0)
    187     (insert-clause 0)
    188     (delete-clause 0)
    189     (update-clause 0)
    190     (case-clause-item-cont 0)
    191     (block-start indent-case-statement-items)
    192     (begin-block 0)
    193     (case-clause +)
    194     (package +)
    195     (package-body +)
    196     (statement-continuation + sqlind-adjust-operator)
    197     (nested-statement-open         1)
    198     (nested-statement-continuation 1)
    199     (nested-statement-close        sqlind-use-anchor-indentation)
    200     (string-continuation 0) ;; or should it be a beginning of line or aligned with the previous block ?
    201                             ;; Anyway. It's really *BAD* to continue a string across lines.
    202     (select-column sqlind-indent-select-column-alt
    203 		   sqlind-adjust-operator
    204 		   sqlind-lone-semicolon)
    205     (select-column-continuation sqlind-indent-select-column-alt
    206                                 sqlind-adjust-operator
    207                                 sqlind-lone-semicolon)
    208     (in-select-clause sqlind-lineup-to-clause-end
    209                       sqlind-adjust-operator
    210 		      sqlind-left-justify-logical-operator
    211                       sqlind-lone-semicolon)
    212     (in-delete-clause sqlind-lineup-to-clause-end
    213                       sqlind-adjust-operator
    214 		      sqlind-left-justify-logical-operator
    215                       sqlind-lone-semicolon)
    216     (in-insert-clause +
    217                       sqlind-adjust-operator
    218 		      sqlind-left-justify-logical-operator
    219                       sqlind-lone-semicolon)
    220     (in-update-clause sqlind-lineup-to-clause-end
    221                       sqlind-adjust-operator
    222 		      sqlind-left-justify-logical-operator
    223                       sqlind-lone-semicolon)
    224     (select-table-continuation + sqlind-lone-semicolon)
    225     ;; rest picked up from the original indentation offsets
    226     ,@sqlind-default-indentation-offsets-alist)
    227   "Align sql code like this :
    228 
    229 clear columns
    230 set linesize 2500
    231 set trimout on trimspool on
    232 
    233 select DISTINCT
    234        atc.column_name,
    235        atc.data_type,
    236        data_length,
    237        data_precision,
    238        nullable,
    239        data_scale,
    240        nvl(substr(comments, 1, 100), atc.column_name) comments
    241 from   all_tab_columns atc,
    242        all_col_comments acc
    243 where  atc.owner       = acc.owner
    244 and    atc.table_name  = acc.table_name
    245 and    atc.column_name = acc.column_name
    246 and    atc.owner       = user
    247 and    atc.table_name  = 'MY_TABLE'
    248 and    atc.column_name = p_column_name
    249 and    not exists (select 1
    250                    from   all_tab_columns atc1,
    251                           all_col_comments acc1
    252                    where  atc1.owner       = acc1.owner
    253                    and    atc1.table_name  = acc1.table_name
    254                    and    atc1.column_name = acc1.column_name
    255                    and    atc1.owner       = atc.owner
    256                    and    atc1.table_name  = atc.table_name
    257                    and    acc1.column_name = acc.column_name)
    258 ;
    259 
    260 delete from my_table mt
    261 where col_1 = v_col1
    262 and  (   col_2 = v_col2
    263        or col_3 = v_col3)
    264 and   col_42 = '42'
    265 ;
    266 
    267 update my_table
    268 set    col1_has_a_long_name = value1,
    269        col2_is_short        = value2
    270 where cond1 is not null
    271 and  (   col_2 = v_col2
    272        or col_3 = v_col3)
    273 and   col_42 = '42'
    274 ;
    275 
    276 insert into xyzxx
    277           ( aaa, xxx, bbb, ccc,
    278             ddd, eee, fff, ggg,
    279             hhh )
    280 select aaa,
    281        xxx,
    282        max (m.b1) as bbb,
    283        min (m.b1) as ccc,
    284        coalesce (max (n.c2), 0)  as ddd,
    285        coalesce (min (n.c2), 0)  as eee,
    286        max (m.b1) over ( partition by c2
    287                          order by aaa desc ) as fff,
    288        min (m.b1) over ( partition by c2
    289                          order by aaa desc ) as ggg,
    290        avg (n.c2) as hhh
    291 from  (select * from (select aaa,
    292                              jjj + kkk  as b1,
    293                              row_number () over ( partition by qqq
    294                                                   order by rrr,
    295                                                   sss ) as rn
    296                       from mno)
    297        where rn = 1) m
    298         inner join (select aaa,
    299                            nnn + ooo as c2
    300                     from   pqr) n
    301         using (aaa),
    302 group by aaa,
    303          xxx
    304 order by xxx desc,
    305          aaa asc
    306 ;")
    307 
    308 (defun sqlind-indent-select-column-alt (syntax base-indentation)
    309   "Return the indentation for a column after a SELECT DISTINCT clause.
    310 
    311 SYNTAX is the syntax of the current line, BASE-INDENTATION is the
    312 current indentation, which we need to update.
    313 
    314 Like `sqlind-indent-select-column' but we try to align to the KEYWORD,
    315 but if we are the first column after the SELECT clause we simply
    316 add `sqlind-basic-offset'."
    317   (save-excursion
    318     (goto-char (sqlind-anchor-point syntax))
    319     (when (looking-at "select\\s *\\(top\\s +[0-9]+\\|distinct\\|unique\\)?")
    320       (if (match-beginning 1)
    321 	  (goto-char (match-beginning 1))
    322 	(goto-char (match-end 0))))
    323     (skip-syntax-forward " ")
    324     (if (or (looking-at sqlind-comment-start-skip)
    325 	    (looking-at "$"))
    326 	(+ base-indentation sqlind-basic-offset)
    327       (current-column))))
    328 
    329 ;;;###autoload
    330 (defun sqlind-setup-style-left ()
    331   "Define an sql-indentation style where keywords are left aligned."
    332   (interactive)
    333   (setq sqlind-indentation-offsets-alist sqlind-indentation-left-offsets-alist))
    334 
    335 ;;;###autoload
    336 (defun sqlind-setup-style-right ()
    337   "Define an sql-indentation style where keywords are right aligned."
    338   (interactive)
    339   (setq sqlind-indentation-offsets-alist sqlind-indentation-right-offsets-alist))
    340 
    341 
    342 ;;;###autoload
    343 (defun sqlind-setup-style-default ()
    344   "Define an sql-indentation style where keywords are right aligned."
    345   (interactive)
    346   (setq sqlind-indentation-offsets-alist sqlind-default-indentation-offsets-alist))
    347 
    348 
    349 (provide 'sql-indent-left)
    350 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    351 ;;; sql-indent-left.el ends here