Skip to content

Latest commit

 

History

History
282 lines (255 loc) · 13.5 KB

todo.org

File metadata and controls

282 lines (255 loc) · 13.5 KB

Todo

vim-plug -> minpac

wincent configs

loupe

toggle to disable the timeout, something smart that extends it while using cgn to replace occurences

projectionist

colorcolumn focus autocommands

statusline

fzf

handle space like ivy does

C-s during search to goto next match

reconcile various bindings within / search

C-L (use C-Y)

make it start at current char? (map / h/)

C-G (use C-N)

C-T (use C-P)

help

quickfix

netrw

consider vim-test

neovim-remote

Readlist

fzf

EasyAlign

minpac

vim-plug

Done

figure out what’s up with my Escape key (delay, international characters, etc.)

This started showing up when I configured iTerm to send +Esc for the left-option key, in order to get Meta keys working in Neovim. This also meant changing the way I defined option-key bindings from hard-coding the special character macOS was sending, e.g.

nnoremap  :cnext<CR>

to a more universal form

nnoremap <M-j> :cnext<CR>

That was enough to get Meta keys working in Neovim, but for Vim I had to configure it to recognize the escape sequences being sent by iTerm:

set  <F21>=^[j
map  <F21> <M-j>
map! <F21> <M-j>

That put me at the mercy of ttimeoutlen, which I had set to 100 milliseconds. When I hit esc j quickly from Insert mode, Vim recognized this as ^[j (were I in Normal mode it would’ve mapped to <M-j>).

The solution was to reduce `ttimeoutlen` considerably (to 5 milliseconds).

recompute folds

I’ve noticed that with ‘foldmethod’ set to syntax, folds don’t automatically recompute as I edit the file. This is probably fine, as I’d rather not waste lots of cycles recomputing folds constantly, but I would like to manually trigger recomputing of folds from time to time. How can I do this?

zx

sh: { expression-group; } syntax recognition

I recently discovered this construct in shell-scripting:

{ # Prevent execution if this script was only partially downloaded
  foo() {
    :
  }
}

I’ve since found that in addition to providing I/O redirection en-masse, an { expression-group; } can be a nice way of organizing code.

Given a snippet like the example above, with ‘foldmethod’ set to syntax, I want to be able to fold like so,

{ # <- fold here
  foo() { # <- and here
    :
  }
}

The root of the problem lies in the runtime file that defines shell syntax, $VIMRUNTIME/syntax/sh.vim, but before tackling the main problem, set a couple variables that script looks for:

let g:is_bash=1
let g:sh_fold_enabled=1

The first, g:is_bash is self-explanatory. sh.vim checks for a few different shells, and some of the syntax definitions vary accordingly.

The second, g:sh_fold_enabled, should be a number from 0 to 7. It’s treated as a bitmask that determines which syntax groups are defined with folding.

 ┌────── if/do/for
 │  ┌─── heredocs
 │  │  ┌ functions
 2² 2¹ 2⁰
(4)(2)(1)

To enable folds for functions and if/do/for constructs, you’d set it to 5 (i.e. 1+4). I’ve found that enabling folds for if/do/for leads to more folds than I want, and feels cluttered. And while I like the idea of folding heredocs, in practice I prefer to just fold function definitions. Thus g:sh_fold_enabled=1.

To ensure that shell files always use syntax-based folding regardless what’s in your vimrc, put the following in $HOME/.vim/ftplugin/sh.vim

setlocal foldmethod=syntax

Now to get Vim to recognize the { expression-group; } and functions nested within it. Actually, Vim already recognizes expression-groups, and has a shExpr syntax item defined:

syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 nextgroup=shSpecialNxt

There’s a lot going on there, but the main things to focus on are contains=@shExprList2 and the lack of any mention of folding. The contains argument specifies which syntax groups can nest within this one. It takes a comma-separated list of groups, but to avoid a lot of repetition, you can “cluster” a list of syntax groups under a single name and refer to it with a @ prefix. So, contains=@shExprList2 refers to a cluster defined earlier in the file,

syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest

This in turn references the previously-defined shExprList1

syn cluster shExprList1 contains=shCharClass,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq

None of the shell function syntax groups are included in the above clusters, so Vim won’t recognize a shell function that’s nested within an expression-group. Fortunately it’s easy to add to an existing cluster:

syn cluster shExprList2 add=shFunctionOne,shFunctionTwo,shFunctionThree,shFunctionFour

This is a safe modification to make because shExpr is the only syntax item that references shExprList2.

Vim now recognizes the nested functions, and with g:sh_fold_enabled set to 1 (or any odd number), you can fold them:

{
+---  3 lines: foo() {
}

To fold the command-group itself, redefine shExpr, passing it the fold argument:

syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 nextgroup=shSpecialNxt fold

Like magic:

+--  5 lines: {

Now that you know what modifications you need to make, where do you put them?

You don’t want to modify the runtime file directly, as you’d lose your changes when updating. You could copy it to $HOME/.vim/syntax/sh.vim and modify that, but that would shadow the orignal file, since Vim only loads the first syntax file found (assuming it sets b:current_syntax), and your user runtime directory ($HOME/.vim/) is earlier in the runtimepath than $VIMRUNTIME is), so you’d lose the benefit of any future updates it receives.

Instead, use put just the relevant modifications in $HOME/.vim/after/syntax/sh.vim

" Recognize functions nested within an { expression-group; }
syn cluster shExprList2 add=shFunctionOne,shFunctionTwo,shFunctionThree,shFunctionFour

" Allow { expression-list; } to fold
syn region shExpr transparent matchgroup=shExprRegion start="{" end="}" contains=@shExprList2 nextgroup=shSpecialNxt fold

This will get sourced after $VIMRUNTIME/syntax/sh.vim, applying just the necessary modifications to the syntax groups the original file defined.

Ideally, these modifications could be merged into the original. I’ve emailed the following patches to the original file’s maintainer, and hope to hear back.

From fb65475d2449838fc3c84dc7c80512794bc99e71 Mon Sep 17 00:00:00 2001
From: ivanbrennan <[email protected]>
Date: Mon, 3 Jul 2017 13:21:17 -0400
Subject: [PATCH 1/2] runtime sh syntax: { expression-list; } folding

Add support for folding compound expressions, for example:

  { # <- fold here
    echo 'Inside a compound group'
    echo 'doing more stuff...'
  }
---
 runtime/doc/syntax.txt |  1 +
 runtime/syntax/sh.vim  | 11 ++++++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt
index 6606524ab..022c3d117 100644
--- a/runtime/doc/syntax.txt
+++ b/runtime/doc/syntax.txt
@@ -2908,6 +2908,7 @@ The syntax/sh.vim file provides several levels of syntax-based folding: >
 	let g:sh_fold_enabled= 1     (enable function folding)
 	let g:sh_fold_enabled= 2     (enable heredoc folding)
 	let g:sh_fold_enabled= 4     (enable if/do/for folding)
+	let g:sh_fold_enabled= 8     (enable { expression-list; } folding)
 >
 then various syntax items (ie. HereDocuments and function bodies) become
 syntax-foldable (see |:syn-fold|).  You also may add these together
diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index f97299cde..7c6e12f5c 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -81,6 +81,9 @@ endif
 if !exists("s:sh_fold_ifdofor")
  let s:sh_fold_ifdofor  = and(g:sh_fold_enabled,4)
 endif
+if !exists("s:sh_fold_expressions")
+ let s:sh_fold_expressions = and(g:sh_fold_enabled,8)
+endif
 if g:sh_fold_enabled && &fdm == "manual"
  " Given that	the	user provided g:sh_fold_enabled
  " 	AND	g:sh_fold_enabled is manual (usual default)
@@ -114,6 +117,11 @@ if s:sh_fold_ifdofor
 else
  com! -nargs=* ShFoldIfDoFor <args>
 endif
+if s:sh_fold_expressions
+ com! -nargs=* ShFoldExpr <args> fold
+else
+ com! -nargs=* ShFoldExpr <args>
+endif
 
 " sh syntax is case sensitive {{{1
 syn case match
@@ -213,7 +221,7 @@ syn match   shPattern	"\<\S\+\())\)\@="	contained contains=shExSingleQuote,shSin
 
 " Subshells: {{{1
 " ==========
-syn region shExpr  transparent matchgroup=shExprRegion  start="{" end="}"		contains=@shExprList2 nextgroup=shSpecialNxt
+ShFoldExpr syn region shExpr  transparent matchgroup=shExprRegion  start="{" end="}"	contains=@shExprList2 nextgroup=shSpecialNxt
 syn region shSubSh transparent matchgroup=shSubShRegion start="[^(]\zs(" end=")"	contains=@shSubShList nextgroup=shSpecialNxt
 
 " Tests: {{{1
@@ -711,6 +719,7 @@ endif
 delc ShFoldFunctions
 delc ShFoldHereDoc
 delc ShFoldIfDoFor
+delc ShFoldExpr
 
 " Set Current Syntax: {{{1
 " ===================
-- 
2.11.1
From 1631f02d2dd84c3cf337e4d6f9a743710b315547 Mon Sep 17 00:00:00 2001
From: ivanbrennan <[email protected]>
Date: Mon, 3 Jul 2017 13:30:39 -0400
Subject: [PATCH 2/2] sh.vim syntax: let shExpr contain shFunction

Allow functions nested within a { expression-list; } to be recognized as
such. For example,

  { # Prevent execution if this script was only partially downloaded
    foo() {
      ...
    }
    bar() {
      ...
    }
  }
---
 runtime/syntax/sh.vim | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/runtime/syntax/sh.vim b/runtime/syntax/sh.vim
index 7c6e12f5c..ab1dc2df5 100644
--- a/runtime/syntax/sh.vim
+++ b/runtime/syntax/sh.vim
@@ -143,7 +143,7 @@ syn cluster shDerefList	contains=shDeref,shDerefSimple,shDerefVar,shDerefSpecial
 syn cluster shDerefVarList	contains=shDerefOff,shDerefOp,shDerefVarArray,shDerefOpError
 syn cluster shEchoList	contains=shArithmetic,shCommandSub,shDeref,shDerefSimple,shEscape,shExpr,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shCtrlSeq,shEchoQuote
 syn cluster shExprList1	contains=shCharClass,shNumber,shOperator,shExSingleQuote,shExDoubleQuote,shSingleQuote,shDoubleQuote,shExpr,shDblBrace,shDeref,shDerefSimple,shCtrlSeq
-syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest
+syn cluster shExprList2	contains=@shExprList1,@shCaseList,shTest,shFunctionOne,shFunctionTwo,shFunctionThree,shFunctionFour
 syn cluster shFunctionList	contains=@shCommandSubList,shCaseEsac,shColon,shCommandSub,shComment,shDo,shEcho,shExpr,shFor,shHereDoc,shIf,shOption,shHereString,shRedir,shSetList,shSource,shStatement,shVariable,shOperator,shCtrlSeq
 if exists("b:is_kornshell") || exists("b:is_bash")
  syn cluster shFunctionList	add=shRepeat
-- 
2.11.1

italics in the terminal

fix tw in gitcommits `gq`

see commit 7fbd337de1a854a014b05648c713cb8e12068cdb

bind q to quit certain modes

Ruby tag lookups with ! and ? suffixes

Ruby allows method names to end in ! and ? characters. If I use command-line mode to search for such a method’s tag (i.e. :tag mymethod!), Vim finds it correctly, but if I try to use the <C-]> normal-mode command (jump to the tag for the word under cursor), Vim omits the trailing punctuation char from its tag search. How can I fix this?

I initially tried set iskeyword+=!, but this causes other problems, such as including a leading ! in tag lookups.

Instead, a better workaround is to put the following in ~/.vim/ftplugin/ruby.vim:

nnoremap <buffer><silent>  <C-]> :<C-U>exe v:count1."tag <Plug><cword>"<CR>
nnoremap <buffer><silent>     g] :<C-U>tselect <Plug><cword><CR>
nnoremap <buffer><silent> g<C-]> :<C-U>tjump <Plug><cword><CR>

This makes use of a <Plug><cword> mapping provided by vim-ruby (and included in Vim’s runtime files by default) provides to correctly identify the Ruby cursor identifierr. See: https://github.com/vim-ruby/vim-ruby/commit/deb3490a0ecca3d2163863bb49e5a3adff875387 https://github.com/vim-ruby/vim-ruby/commit/2322c368736156413b7fac9f13521ed0e851fe70 https://github.com/vim-ruby/vim-ruby/commit/37ab22005b44605c1c5385d6551644c49199b691 https://github.com/vim-ruby/vim-ruby/blob/master/ftplugin/ruby.vim https://github.com/vim/vim/blob/master/runtime/ftplugin/ruby.vim

ruby indentation of multiline method chain (can you align the dots?)

realign.vim (in progress)