diff options
author | Christian Clason <c.clason@uni-graz.at> | 2022-08-25 00:49:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-25 00:49:33 +0200 |
commit | d3cd79709b6491a5806c67ea52c19f244164954e (patch) | |
tree | 1b696646bf21a68d458038df567d9a2d9dbef349 | |
parent | 6b9ff5491d4a15c7ec92d70a769b3cc35ea06da9 (diff) | |
download | rneovim-d3cd79709b6491a5806c67ea52c19f244164954e.tar.gz rneovim-d3cd79709b6491a5806c67ea52c19f244164954e.tar.bz2 rneovim-d3cd79709b6491a5806c67ea52c19f244164954e.zip |
vim-patch:fd999452adaf (#19929)
Update runtime files
https://github.com/vim/vim/commit/fd999452adaf529a30d78844b5fbee355943da29
-rw-r--r-- | runtime/autoload/python.vim | 40 | ||||
-rw-r--r-- | runtime/doc/builtin.txt | 6 | ||||
-rw-r--r-- | runtime/doc/indent.txt | 27 | ||||
-rw-r--r-- | runtime/doc/windows.txt | 2 | ||||
-rw-r--r-- | runtime/indent/testdir/python.in | 18 | ||||
-rw-r--r-- | runtime/indent/testdir/python.ok | 18 | ||||
-rw-r--r-- | runtime/plugin/matchparen.vim | 5 | ||||
-rw-r--r-- | runtime/syntax/plsql.vim | 87 |
8 files changed, 146 insertions, 57 deletions
diff --git a/runtime/autoload/python.vim b/runtime/autoload/python.vim index e45dbd9db8..1eaad09ef5 100644 --- a/runtime/autoload/python.vim +++ b/runtime/autoload/python.vim @@ -3,13 +3,19 @@ let s:keepcpo= &cpo set cpo&vim -" searchpair() can be slow, limit the time to 150 msec or what is put in -" g:pyindent_searchpair_timeout -let s:searchpair_timeout = get(g:, 'pyindent_searchpair_timeout', 150) - -" Identing inside parentheses can be very slow, regardless of the searchpair() -" timeout, so let the user disable this feature if he doesn't need it -let s:disable_parentheses_indenting = get(g:, 'pyindent_disable_parentheses_indenting', v:false) +" need to inspect some old g:pyindent_* variables to be backward compatible +let g:python_indent = extend(get(g:, 'python_indent', {}), #{ + \ closed_paren_align_last_line: v:true, + \ open_paren: get(g:, 'pyindent_open_paren', 'shiftwidth() * 2'), + \ nested_paren: get(g:, 'pyindent_nested_paren', 'shiftwidth()'), + \ continue: get(g:, 'pyindent_continue', 'shiftwidth() * 2'), + "\ searchpair() can be slow, limit the time to 150 msec or what is put in + "\ g:python_indent.searchpair_timeout + \ searchpair_timeout: get(g:, 'pyindent_searchpair_timeout', 150), + "\ Identing inside parentheses can be very slow, regardless of the searchpair() + "\ timeout, so let the user disable this feature if he doesn't need it + \ disable_parentheses_indenting: get(g:, 'pyindent_disable_parentheses_indenting', v:false), + \ }, 'keep') let s:maxoff = 50 " maximum number of lines to look backwards for () @@ -18,7 +24,7 @@ function s:SearchBracket(fromlnum, flags) \ {-> synstack('.', col('.')) \ ->map({_, id -> id->synIDattr('name')}) \ ->match('\%(Comment\|Todo\|String\)$') >= 0}, - \ [0, a:fromlnum - s:maxoff]->max(), s:searchpair_timeout) + \ [0, a:fromlnum - s:maxoff]->max(), g:python_indent.searchpair_timeout) endfunction " See if the specified line is already user-dedented from the expected value. @@ -38,7 +44,7 @@ function python#GetIndent(lnum, ...) if a:lnum > 1 && getline(a:lnum - 2) =~ '\\$' return indent(a:lnum - 1) endif - return indent(a:lnum - 1) + (exists("g:pyindent_continue") ? eval(g:pyindent_continue) : (shiftwidth() * 2)) + return indent(a:lnum - 1) + get(g:, 'pyindent_continue', g:python_indent.continue)->eval() endif " If the start of the line is in a string don't change the indent. @@ -55,7 +61,7 @@ function python#GetIndent(lnum, ...) return 0 endif - if s:disable_parentheses_indenting == 1 + if g:python_indent.disable_parentheses_indenting == 1 let plindent = indent(plnum) let plnumstart = plnum else @@ -70,8 +76,12 @@ function python#GetIndent(lnum, ...) " 100, 200, 300, 400) call cursor(a:lnum, 1) let [parlnum, parcol] = s:SearchBracket(a:lnum, 'nbW') - if parlnum > 0 && parcol != col([parlnum, '$']) - 1 - return parcol + if parlnum > 0 + if parcol != col([parlnum, '$']) - 1 + return parcol + elseif getline(a:lnum) =~ '^\s*[])}]' && !g:python_indent.closed_paren_align_last_line + return indent(parlnum) + endif endif call cursor(plnum, 1) @@ -123,9 +133,11 @@ function python#GetIndent(lnum, ...) " When the start is inside parenthesis, only indent one 'shiftwidth'. let [pp, _] = s:SearchBracket(a:lnum, 'bW') if pp > 0 - return indent(plnum) + (exists("g:pyindent_nested_paren") ? eval(g:pyindent_nested_paren) : shiftwidth()) + return indent(plnum) + \ + get(g:, 'pyindent_nested_paren', g:python_indent.nested_paren)->eval() endif - return indent(plnum) + (exists("g:pyindent_open_paren") ? eval(g:pyindent_open_paren) : (shiftwidth() * 2)) + return indent(plnum) + \ + get(g:, 'pyindent_open_paren', g:python_indent.open_paren)->eval() endif if plnumstart == p return indent(plnum) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index df00c67082..f99da3443e 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -6425,8 +6425,10 @@ search({pattern} [, {flags} [, {stopline} [, {timeout} [, {skip}]]]]) starts in column zero and then matches before the cursor are skipped. When the 'c' flag is present in 'cpo' the next search starts after the match. Without the 'c' flag the next - search starts one column further. This matters for - overlapping matches. + search starts one column after the start of the match. This + matters for overlapping matches. See |cpo-c|. You can also + insert "\ze" to change where the match ends, see |/\ze|. + When searching backwards and the 'z' flag is given then the search starts in column zero, thus no match in the current line will be found (unless wrapping around the end of the diff --git a/runtime/doc/indent.txt b/runtime/doc/indent.txt index 1a1d8e30b0..c5411b5f16 100644 --- a/runtime/doc/indent.txt +++ b/runtime/doc/indent.txt @@ -979,25 +979,38 @@ indentation: > PYTHON *ft-python-indent* The amount of indent can be set for the following situations. The examples -given are the defaults. Note that the variables are set to an expression, so -that you can change the value of 'shiftwidth' later. +given are the defaults. Note that the dictionary values are set to an +expression, so that you can change the value of 'shiftwidth' later. Indent after an open paren: > - let g:pyindent_open_paren = 'shiftwidth() * 2' + let g:python_indent.open_paren = 'shiftwidth() * 2' Indent after a nested paren: > - let g:pyindent_nested_paren = 'shiftwidth()' + let g:python_indent.nested_paren = 'shiftwidth()' Indent for a continuation line: > - let g:pyindent_continue = 'shiftwidth() * 2' + let g:python_indent.continue = 'shiftwidth() * 2' + +By default, the closing paren on a multiline construct lines up under the first +non-whitespace character of the previous line. +If you prefer that it's lined up under the first character of the line that +starts the multiline construct, reset this key: > + let g:python_indent.closed_paren_align_last_line = v:false The method uses |searchpair()| to look back for unclosed parentheses. This can sometimes be slow, thus it timeouts after 150 msec. If you notice the indenting isn't correct, you can set a larger timeout in msec: > - let g:pyindent_searchpair_timeout = 500 + let g:python_indent.searchpair_timeout = 500 If looking back for unclosed parenthesis is still too slow, especially during a copy-paste operation, or if you don't need indenting inside multi-line parentheses, you can completely disable this feature: > - let g:pyindent_disable_parentheses_indenting = 1 + let g:python_indent.disable_parentheses_indenting = 1 + +For backward compatibility, these variables are also supported: > + g:pyindent_open_paren + g:pyindent_nested_paren + g:pyindent_continue + g:pyindent_searchpair_timeout + g:pyindent_disable_parentheses_indenting R *ft-r-indent* diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 7355cec522..2627068a14 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -163,6 +163,8 @@ CTRL-W v *CTRL-W_v* 3. 'eadirection' isn't "ver", and 4. one of the other windows is wider than the current or new window. + If N was given make the new window N columns wide, if + possible. Note: In other places CTRL-Q does the same as CTRL-V, but here it doesn't! diff --git a/runtime/indent/testdir/python.in b/runtime/indent/testdir/python.in index e6f05f22bc..57719ee430 100644 --- a/runtime/indent/testdir/python.in +++ b/runtime/indent/testdir/python.in @@ -1,6 +1,24 @@ # vim: set ft=python sw=4 et: # START_INDENT +dict = { +'a': 1, +'b': 2, +'c': 3, +} +# END_INDENT + +# START_INDENT +# INDENT_EXE let [g:python_indent.open_paren, g:python_indent.closed_paren_align_last_line] = ['shiftwidth()', v:false] +dict = { +'a': 1, +'b': 2, +'c': 3, +} +# END_INDENT + +# START_INDENT +# INDENT_EXE let g:python_indent.open_paren = 'shiftwidth() * 2' # INDENT_EXE syntax match pythonFoldMarkers /{{{\d*/ contained containedin=pythonComment # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {{{1 diff --git a/runtime/indent/testdir/python.ok b/runtime/indent/testdir/python.ok index df3de8f186..f5ebbc2285 100644 --- a/runtime/indent/testdir/python.ok +++ b/runtime/indent/testdir/python.ok @@ -1,6 +1,24 @@ # vim: set ft=python sw=4 et: # START_INDENT +dict = { + 'a': 1, + 'b': 2, + 'c': 3, + } +# END_INDENT + +# START_INDENT +# INDENT_EXE let [g:python_indent.open_paren, g:python_indent.closed_paren_align_last_line] = ['shiftwidth()', v:false] +dict = { + 'a': 1, + 'b': 2, + 'c': 3, +} +# END_INDENT + +# START_INDENT +# INDENT_EXE let g:python_indent.open_paren = 'shiftwidth() * 2' # INDENT_EXE syntax match pythonFoldMarkers /{{{\d*/ contained containedin=pythonComment # xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx {{{1 diff --git a/runtime/plugin/matchparen.vim b/runtime/plugin/matchparen.vim index cc4f38f669..ce2225c5f8 100644 --- a/runtime/plugin/matchparen.vim +++ b/runtime/plugin/matchparen.vim @@ -5,8 +5,7 @@ " Exit quickly when: " - this plugin was already loaded (or disabled) " - when 'compatible' is set -" - the "CursorMoved" autocmd event is not available. -if exists("g:loaded_matchparen") || &cp || !exists("##CursorMoved") +if exists("g:loaded_matchparen") || &cp finish endif let g:loaded_matchparen = 1 @@ -20,7 +19,7 @@ endif augroup matchparen " Replace all matchparen autocommands - autocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair() + autocmd! CursorMoved,CursorMovedI,WinEnter,WinScrolled * call s:Highlight_Matching_Pair() autocmd! WinLeave * call s:Remove_Matches() if exists('##TextChanged') autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair() diff --git a/runtime/syntax/plsql.vim b/runtime/syntax/plsql.vim index 7b36c0a180..21681d59e4 100644 --- a/runtime/syntax/plsql.vim +++ b/runtime/syntax/plsql.vim @@ -4,12 +4,13 @@ " Previous Maintainer: Jeff Lanzarotta (jefflanzarotta at yahoo dot com) " Previous Maintainer: C. Laurence Gonsalves (clgonsal@kami.com) " URL: https://github.com/lee-lindley/vim_plsql_syntax -" Last Change: April 28, 2022 +" Last Change: Aug 21, 2022 " History Lee Lindley (lee dot lindley at gmail dot com) +" use get with default 0 instead of exists per Bram suggestion +" make procedure folding optional " updated to 19c keywords. refined quoting. " separated reserved, non-reserved keywords and functions -" revised folding, giving up on procedure folding due to issue -" with multiple ways to enter <begin>. +" revised folding " Eugene Lysyonok (lysyonok at inbox ru) " Added folding. " Geoff Evans & Bill Pribyl (bill at plnet dot org) @@ -23,12 +24,19 @@ " To enable folding (It does setlocal foldmethod=syntax) " let plsql_fold = 1 " +" To disable folding procedure/functions (recommended if you habitually +" do not put the method name on the END statement) +" let plsql_disable_procedure_fold = 1 +" " From my vimrc file -- turn syntax and syntax folding on, " associate file suffixes as plsql, open all the folds on file open +" syntax enable " let plsql_fold = 1 " au BufNewFile,BufRead *.sql,*.pls,*.tps,*.tpb,*.pks,*.pkb,*.pkg,*.trg set filetype=plsql " au BufNewFile,BufRead *.sql,*.pls,*.tps,*.tpb,*.pks,*.pkb,*.pkg,*.trg syntax on " au Syntax plsql normal zR +" au Syntax plsql set foldcolumn=2 "optional if you want to see choosable folds on the left + if exists("b:current_syntax") finish @@ -49,12 +57,12 @@ syn match plsqlIdentifier "[a-z][a-z0-9$_#]*" syn match plsqlHostIdentifier ":[a-z][a-z0-9$_#]*" " When wanted, highlight the trailing whitespace. -if exists("plsql_space_errors") - if !exists("plsql_no_trail_space_error") +if get(g:,"plsql_space_errors",0) == 1 + if get(g:,"plsql_no_trail_space_error",0) == 0 syn match plsqlSpaceError "\s\+$" endif - if !exists("plsql_no_tab_space_error") + if get(g:,"plsql_no_tab_space_error",0) == 0 syn match plsqlSpaceError " \+\t"me=e-1 endif endif @@ -134,7 +142,8 @@ syn keyword plsqlKeyword CPU_TIME CRASH CREATE_FILE_DEST CREATE_STORED_OUTLINES syn keyword plsqlKeyword CREDENTIALS CRITICAL CROSS CROSSEDITION CSCONVERT CUBE CUBE_AJ CUBE_GB CUBE_SJ syn keyword plsqlKeyword CUME_DIST CUME_DISTM CURRENT CURRENTV CURRENT_DATE CURRENT_INSTANCE CURRENT_PARTSET_KEY syn keyword plsqlKeyword CURRENT_SCHEMA CURRENT_SHARD_KEY CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER -syn keyword plsqlKeyword CURSOR CURSOR_SHARING_EXACT CURSOR_SPECIFIC_SEGMENT CV CYCLE DAGG_OPTIM_GSETS +syn match plsqlKeyword "\<CURSOR\>" +syn keyword plsqlKeyword CURSOR_SHARING_EXACT CURSOR_SPECIFIC_SEGMENT CV CYCLE DAGG_OPTIM_GSETS syn keyword plsqlKeyword DANGLING DATA DATABASE DATABASES DATAFILE DATAFILES DATAMOVEMENT DATAOBJNO syn keyword plsqlKeyword DATAOBJ_TO_MAT_PARTITION DATAOBJ_TO_PARTITION DATAPUMP DATASTORE DATA_LINK_DML syn keyword plsqlKeyword DATA_SECURITY_REWRITE_LIMIT DATA_VALIDATE DATE_MODE DAYS DBA DBA_RECYCLEBIN @@ -515,7 +524,7 @@ syn match plsqlFunction "\.DELETE\>"hs=s+1 syn match plsqlFunction "\.PREV\>"hs=s+1 syn match plsqlFunction "\.NEXT\>"hs=s+1 -if exists("plsql_legacy_sql_keywords") +if get(g:,"plsql_legacy_sql_keywords",0) == 1 " Some of Oracle's SQL keywords. syn keyword plsqlSQLKeyword ABORT ACCESS ACCESSED ADD AFTER ALL ALTER AND ANY syn keyword plsqlSQLKeyword ASC ATTRIBUTE AUDIT AUTHORIZATION AVG BASE_TABLE @@ -565,7 +574,7 @@ syn keyword plsqlException SUBSCRIPT_OUTSIDE_LIMIT SYS_INVALID_ROWID syn keyword plsqlException TIMEOUT_ON_RESOURCE TOO_MANY_ROWS VALUE_ERROR syn keyword plsqlException ZERO_DIVIDE -if exists("plsql_highlight_triggers") +if get(g:,"plsql_highlight_triggers",0) == 1 syn keyword plsqlTrigger INSERTING UPDATING DELETING endif @@ -576,7 +585,7 @@ syn match plsqlISAS "\<\(IS\|AS\)\>" " Various types of comments. syntax region plsqlCommentL start="--" skip="\\$" end="$" keepend extend contains=@plsqlCommentGroup,plsqlSpaceError -if exists("plsql_fold") +if get(g:,"plsql_fold",0) == 1 syntax region plsqlComment \ start="/\*" end="\*/" \ extend @@ -612,7 +621,7 @@ syn region plsqlQuotedIdentifier matchgroup=plsqlOperator start=+n\?"+ end=+ syn cluster plsqlIdentifiers contains=plsqlIdentifier,plsqlQuotedIdentifier " quoted string literals -if exists("plsql_fold") +if get(g:,"plsql_fold",0) == 1 syn region plsqlStringLiteral matchgroup=plsqlOperator start=+n\?'+ skip=+''+ end=+'+ fold keepend extend syn region plsqlStringLiteral matchgroup=plsqlOperator start=+n\?q'\z([^[(<{]\)+ end=+\z1'+ fold keepend extend syn region plsqlStringLiteral matchgroup=plsqlOperator start=+n\?q'<+ end=+>'+ fold keepend extend @@ -639,10 +648,10 @@ syn match plsqlAttribute "%\(BULK_EXCEPTIONS\|BULK_ROWCOUNT\|ISOPEN\|FOUND\|NOTF " This'll catch mis-matched close-parens. syn cluster plsqlParenGroup contains=plsqlParenError,@plsqlCommentGroup,plsqlCommentSkip,plsqlIntLiteral,plsqlFloatLiteral,plsqlNumbersCom -if exists("plsql_bracket_error") +if get(g:,"plsql_bracket_error",0) == 1 " I suspect this code was copied from c.vim and never properly considered. Do " we even use braces or brackets in sql or pl/sql? - if exists("plsql_fold") + if get(g:,"plsql_fold",0) == 1 syn region plsqlParen start='(' end=')' contains=ALLBUT,@plsqlParenGroup,plsqlErrInBracket fold keepend extend transparent else syn region plsqlParen transparent start='(' end=')' contains=ALLBUT,@plsqlParenGroup,plsqlErrInBracket @@ -652,7 +661,7 @@ if exists("plsql_bracket_error") syn region plsqlBracket transparent start='\[' end=']' contains=ALLBUT,@plsqlParenGroup,plsqlErrInParen syn match plsqlErrInBracket contained "[);{}]" else - if exists("plsql_fold") + if get(g:,"plsql_fold",0) == 1 syn region plsqlParen start='(' end=')' contains=ALLBUT,@plsqlParenGroup,plsqlErrInParen fold keepend extend transparent else syn region plsqlParen transparent start='(' end=')' contains=ALLBUT,@plsqlParenGroup,plsqlErrInParen @@ -673,12 +682,12 @@ syn match plsqlConditional "\<END\>\_s\+\<IF\>" syn match plsqlCase "\<END\>\_s\+\<CASE\>" syn match plsqlCase "\<CASE\>" -if exists("plsql_fold") +if get(g:,"plsql_fold",0) == 1 setlocal foldmethod=syntax syn sync fromstart syn cluster plsqlProcedureGroup contains=plsqlProcedure - syn cluster plsqlOnlyGroup contains=@plsqlProcedure,plsqlConditionalBlock,plsqlLoopBlock,plsqlBlock + syn cluster plsqlOnlyGroup contains=@plsqlProcedure,plsqlConditionalBlock,plsqlLoopBlock,plsqlBlock,plsqlCursor syntax region plsqlUpdateSet \ start="\(\<update\>\_s\+\(\<set\>\)\@![a-z][a-z0-9$_#]*\_s\+\(\(\<set\>\)\@![a-z][a-z0-9$_#]*\_s\+\)\?\)\|\(\<when\>\_s\+\<matched\>\_s\+\<then\>\_s\+\<update\>\_s\+\)\<set\>" @@ -698,24 +707,40 @@ if exists("plsql_fold") \ transparent \ contains=ALLBUT,@plsqlOnlyGroup,plsqlUpdateSet - " this is brute force and requires you have the procedure/function name in the END - " statement. ALthough Oracle makes it optional, we cannot. If you do not - " have it, then you can fold the BEGIN/END block of the procedure but not - " the specification of it (other than a paren group). You also cannot fold - " BEGIN/END blocks in the procedure body. Local procedures will fold as - " long as the END statement includes the procedure/function name. - " As for why we cannot make it work any other way, I don't know. It is - " something to do with both plsqlBlock and plsqlProcedure both consuming BEGIN and END, - " even if we use a lookahead for one of them. - syntax region plsqlProcedure - "\ start="\(create\(\_s\+or\_s\+replace\)\?\_s\+\)\?\<\(procedure\|function\)\>\_s\+\z([a-z][a-z0-9$_#]*\)" - \ start="\<\(procedure\|function\)\>\_s\+\(\z([a-z][a-z0-9$_#]*\)\)\([^;]\|\n\)\{-}\<\(is\|as\)\>\_.\{-}\(\<end\>\_s\+\2\_s*;\)\@=" - \ end="\<end\>\_s\+\z1\_s*;" + if get(g:,"plsql_disable_procedure_fold",0) == 0 + " this is brute force and requires you have the procedure/function name in the END + " statement. ALthough Oracle makes it optional, we cannot. If you do not + " have it, then you can fold the BEGIN/END block of the procedure but not + " the specification of it (other than a paren group). You also cannot fold + " BEGIN/END blocks in the procedure body. Local procedures will fold as + " long as the END statement includes the procedure/function name. + " As for why we cannot make it work any other way, I don't know. It is + " something to do with both plsqlBlock and plsqlProcedure both consuming BEGIN and END, + " even if we use a lookahead for one of them. + " + " If you habitualy do not put the method name in the END statement, + " this can be expensive because it searches to end of file on every + " procedure/function declaration + " + "\ start="\(create\(\_s\+or\_s\+replace\)\?\_s\+\)\?\<\(procedure\|function\)\>\_s\+\z([a-z][a-z0-9$_#]*\)" + syntax region plsqlProcedure + \ start="\<\(procedure\|function\)\>\_s\+\(\z([a-z][a-z0-9$_#]*\)\)\([^;]\|\n\)\{-}\<\(is\|as\)\>\_.\{-}\(\<end\>\_s\+\2\_s*;\)\@=" + \ end="\<end\>\_s\+\z1\_s*;" + \ fold + \ keepend + \ extend + \ transparent + \ contains=ALLBUT,plsqlBlock + endif + + syntax region plsqlCursor + \ start="\<cursor\>\_s\+[a-z][a-z0-9$_#]*\(\_s*([^)]\+)\)\?\(\_s\+return\_s\+\S\+\)\?\_s\+is" + \ end=";" \ fold \ keepend \ extend \ transparent - \ contains=ALLBUT,plsqlBlock + \ contains=ALLBUT,@plsqlOnlyGroup syntax region plsqlBlock \ start="\<begin\>" @@ -802,7 +827,7 @@ hi def link plsqlTrigger Function hi def link plsqlTypeAttribute StorageClass hi def link plsqlTodo Todo " to be able to change them after loading, need override whether defined or not -if exists("plsql_legacy_sql_keywords") +if get(g:,"plsql_legacy_sql_keywords",0) == 1 hi link plsqlSQLKeyword Function hi link plsqlSymbol Normal hi link plsqlParen Normal |